From 6460692171661516f950eaa4c46781e56cc152da Mon Sep 17 00:00:00 2001 From: Per Cederqvist <ceder@lysator.liu.se> Date: Fri, 11 Jul 2014 09:34:31 +0200 Subject: [PATCH] Imported Bugzilla 3.0. --- .cvsignore | 1 + Bugzilla.pm | 420 +- Bugzilla/Attachment.pm | 484 +- Bugzilla/Attachment/CVS/Entries | 2 + Bugzilla/Attachment/CVS/Repository | 1 + .../Login/WWW/CGI => Attachment}/CVS/Root | 0 Bugzilla/Attachment/CVS/Tag | 1 + Bugzilla/Attachment/PatchReader.pm | 273 + Bugzilla/Auth.pm | 545 +- Bugzilla/Auth/CVS/Entries | 4 +- Bugzilla/Auth/CVS/Tag | 2 +- Bugzilla/Auth/Login.pm | 125 + Bugzilla/Auth/Login/CGI.pm | 81 + Bugzilla/Auth/Login/CVS/Entries | 7 +- Bugzilla/Auth/Login/CVS/Tag | 2 +- Bugzilla/Auth/Login/Cookie.pm | 96 + Bugzilla/Auth/Login/Env.pm | 52 + Bugzilla/Auth/Login/Stack.pm | 87 + Bugzilla/Auth/Login/WWW.pm | 111 - Bugzilla/Auth/Login/WWW/CGI.pm | 275 - Bugzilla/Auth/Login/WWW/CGI/CVS/Entries | 2 - Bugzilla/Auth/Login/WWW/CGI/CVS/Repository | 1 - Bugzilla/Auth/Login/WWW/CGI/CVS/Tag | 1 - Bugzilla/Auth/Login/WWW/CGI/Cookie.pm | 113 - Bugzilla/Auth/Login/WWW/CVS/Entries | 3 - Bugzilla/Auth/Login/WWW/CVS/Repository | 1 - Bugzilla/Auth/Login/WWW/CVS/Tag | 1 - Bugzilla/Auth/Login/WWW/Env.pm | 192 - Bugzilla/Auth/Persist/CVS/Entries | 2 + Bugzilla/Auth/Persist/CVS/Repository | 1 + Bugzilla/Auth/{Login/WWW => Persist}/CVS/Root | 0 Bugzilla/Auth/Persist/CVS/Tag | 1 + Bugzilla/Auth/Persist/Cookie.pm | 151 + Bugzilla/Auth/README | 132 - Bugzilla/Auth/Verify.pm | 236 + Bugzilla/Auth/Verify/CVS/Entries | 5 +- Bugzilla/Auth/Verify/CVS/Tag | 2 +- Bugzilla/Auth/Verify/DB.pm | 96 +- Bugzilla/Auth/Verify/LDAP.pm | 237 +- Bugzilla/Auth/Verify/Stack.pm | 81 + Bugzilla/Bug.pm | 1415 +- Bugzilla/BugMail.pm | 623 +- Bugzilla/CGI.pm | 102 +- Bugzilla/CVS/Entries | 62 +- Bugzilla/CVS/Tag | 2 +- Bugzilla/Chart.pm | 21 +- Bugzilla/Classification.pm | 12 +- Bugzilla/Component.pm | 166 +- Bugzilla/Config.pm | 411 +- Bugzilla/Config/Attachment.pm | 5 + Bugzilla/Config/Auth.pm | 2 +- Bugzilla/Config/BugFields.pm | 19 +- Bugzilla/Config/CVS/Entries | 34 +- Bugzilla/Config/CVS/Tag | 2 +- Bugzilla/Config/Common.pm | 113 +- Bugzilla/Config/Core.pm | 30 + Bugzilla/Config/GroupSecurity.pm | 35 +- Bugzilla/Config/L10n.pm | 5 +- Bugzilla/Config/LDAP.pm | 6 + Bugzilla/Config/MTA.pm | 121 +- Bugzilla/Constants.pm | 194 +- Bugzilla/DB.pm | 1778 +- Bugzilla/DB/CVS/Entries | 6 +- Bugzilla/DB/CVS/Tag | 2 +- Bugzilla/DB/Mysql.pm | 136 +- Bugzilla/DB/Pg.pm | 66 +- Bugzilla/DB/Schema.pm | 327 +- Bugzilla/DB/Schema/CVS/Entries | 4 +- Bugzilla/DB/Schema/CVS/Tag | 2 +- Bugzilla/DB/Schema/Mysql.pm | 14 +- Bugzilla/DB/Schema/Pg.pm | 101 +- Bugzilla/Error.pm | 37 +- Bugzilla/Field.pm | 778 +- Bugzilla/Flag.pm | 1092 +- Bugzilla/FlagType.pm | 513 +- Bugzilla/Group.pm | 221 +- Bugzilla/Hook.pm | 190 + Bugzilla/Install.pm | 428 + Bugzilla/Install/CVS/Entries | 5 + Bugzilla/Install/CVS/Repository | 1 + Bugzilla/Install/CVS/Root | 1 + Bugzilla/Install/CVS/Tag | 1 + Bugzilla/Install/DB.pm | 2848 ++ Bugzilla/Install/Filesystem.pm | 667 + Bugzilla/Install/Localconfig.pm | 471 + Bugzilla/Install/Requirements.pm | 698 + Bugzilla/Keyword.pm | 189 + Bugzilla/Mailer.pm | 116 + Bugzilla/Milestone.pm | 75 +- Bugzilla/Object.pm | 595 + Bugzilla/Product.pm | 190 +- Bugzilla/Search.pm | 315 +- Bugzilla/Search/CVS/Entries | 3 +- Bugzilla/Search/CVS/Tag | 2 +- Bugzilla/Search/Quicksearch.pm | 100 +- Bugzilla/Search/Saved.pm | 265 + Bugzilla/Series.pm | 28 +- Bugzilla/Template.pm | 457 +- Bugzilla/Template/CVS/Tag | 2 +- Bugzilla/Template/Plugin/CVS/Entries | 6 +- Bugzilla/Template/Plugin/CVS/Tag | 2 +- Bugzilla/Template/Plugin/Hook.pm | 60 +- Bugzilla/Token.pm | 234 +- Bugzilla/Update.pm | 224 + Bugzilla/User.pm | 1275 +- Bugzilla/User/CVS/Entries | 4 +- Bugzilla/User/CVS/Tag | 2 +- Bugzilla/User/Setting.pm | 84 +- Bugzilla/User/Setting/CVS/Entries | 2 + Bugzilla/User/Setting/CVS/Repository | 1 + Bugzilla/User/Setting/CVS/Root | 1 + Bugzilla/User/Setting/CVS/Tag | 1 + Bugzilla/User/Setting/Skin.pm | 80 + Bugzilla/Util.pm | 152 +- Bugzilla/Version.pm | 180 +- Bugzilla/WebService.pm | 134 + Bugzilla/WebService/Bug.pm | 459 + Bugzilla/WebService/Bugzilla.pm | 96 + Bugzilla/WebService/CVS/Entries | 6 + Bugzilla/WebService/CVS/Repository | 1 + Bugzilla/WebService/CVS/Root | 1 + Bugzilla/WebService/CVS/Tag | 1 + Bugzilla/WebService/Constants.pm | 112 + Bugzilla/WebService/Product.pm | 182 + Bugzilla/WebService/User.pm | 298 + CVS/Entries | 134 +- CVS/Tag | 2 +- QUICKSTART | 12 +- attachment.cgi | 1000 +- buglist.cgi | 297 +- bugzilla.dtd | 9 +- chart.cgi | 29 +- checksetup.pl | 4824 +-- colchange.cgi | 30 +- collectstats.pl | 361 +- config.cgi | 66 +- contrib/BugzillaEmail.pm | 84 - contrib/CVS/Entries | 32 +- contrib/CVS/Tag | 2 +- contrib/README.Mailif | 80 - contrib/bug_email.pl | 1225 - contrib/bugmail_help.html | 223 - contrib/bugzilla-submit/CVS/Entries | 8 +- contrib/bugzilla-submit/CVS/Tag | 2 +- contrib/bugzilla.procmailrc | 30 - contrib/bugzilla_email_append.pl | 197 - contrib/bz_webservice_demo.pl | 322 + contrib/bzdbcopy.pl | 72 +- contrib/cmdline/CVS/Entries | 14 +- contrib/cmdline/CVS/Tag | 2 +- contrib/gnats2bz.pl | 4 +- contrib/gnatsparse/CVS/Entries | 8 +- contrib/gnatsparse/CVS/Tag | 2 +- contrib/merge-users.pl | 13 +- contrib/recode.pl | 385 + contrib/sendbugmail.pl | 14 +- contrib/sendunsentbugmail.pl | 22 +- contrib/syncLDAP.pl | 90 +- createaccount.cgi | 37 +- describecomponents.cgi | 78 +- describekeywords.cgi | 19 +- docs/.cvsignore | 1 - docs/CVS/Entries | 10 +- docs/CVS/Tag | 2 +- docs/html/.cvsignore | 1 + docs/html/Bugzilla-Guide.html | 2491 +- docs/html/CVS/Entries | 2 + docs/html/CVS/Repository | 1 + docs/html/CVS/Root | 1 + docs/html/CVS/Tag | 1 + docs/html/about.html | 12 +- docs/html/administration.html | 69 +- docs/html/api/.cvsignore | 3 + docs/html/api/Bugzilla.html | 213 + docs/html/api/Bugzilla/Attachment.html | 253 + docs/html/api/Bugzilla/Auth.html | 394 + docs/html/api/Bugzilla/Auth/Login.html | 120 + docs/html/api/Bugzilla/Auth/Verify.html | 142 + docs/html/api/Bugzilla/CGI.html | 112 + docs/html/api/Bugzilla/Classification.html | 133 + docs/html/api/Bugzilla/Component.html | 175 + docs/html/api/Bugzilla/Config.html | 100 + docs/html/api/Bugzilla/Config/Common.html | 63 + docs/html/api/Bugzilla/DB.html | 1326 + docs/html/api/Bugzilla/DB/Mysql.html | 40 + docs/html/api/Bugzilla/DB/Pg.html | 40 + docs/html/api/Bugzilla/DB/Schema.html | 676 + docs/html/api/Bugzilla/Error.html | 83 + docs/html/api/Bugzilla/Field.html | 325 + docs/html/api/Bugzilla/Flag.html | 254 + docs/html/api/Bugzilla/FlagType.html | 211 + docs/html/api/Bugzilla/Group.html | 101 + docs/html/api/Bugzilla/Hook.html | 169 + docs/html/api/Bugzilla/Install.html | 87 + docs/html/api/Bugzilla/Install/DB.html | 86 + .../html/api/Bugzilla/Install/Filesystem.html | 79 + .../api/Bugzilla/Install/Localconfig.html | 101 + .../api/Bugzilla/Install/Requirements.html | 140 + docs/html/api/Bugzilla/Keyword.html | 84 + docs/html/api/Bugzilla/Milestone.html | 100 + docs/html/api/Bugzilla/Object.html | 370 + docs/html/api/Bugzilla/Product.html | 193 + docs/html/api/Bugzilla/Search/Saved.html | 118 + docs/html/api/Bugzilla/Template.html | 121 + .../Bugzilla/Template/Plugin/Bugzilla.html | 45 + .../api/Bugzilla/Template/Plugin/Hook.html | 46 + .../api/Bugzilla/Template/Plugin/User.html | 45 + docs/html/api/Bugzilla/Token.html | 233 + docs/html/api/Bugzilla/Update.html | 66 + docs/html/api/Bugzilla/User.html | 501 + docs/html/api/Bugzilla/User/Setting.html | 171 + docs/html/api/Bugzilla/User/Setting/Skin.html | 54 + docs/html/api/Bugzilla/Util.html | 421 + docs/html/api/Bugzilla/Version.html | 139 + docs/html/api/Bugzilla/WebService.html | 109 + docs/html/api/Bugzilla/WebService/Bug.html | 383 + .../api/Bugzilla/WebService/Bugzilla.html | 97 + .../html/api/Bugzilla/WebService/Product.html | 178 + docs/html/api/Bugzilla/WebService/User.html | 275 + docs/html/api/CVS/Entries | 3 + docs/html/api/CVS/Repository | 1 + docs/html/api/CVS/Root | 1 + docs/html/api/CVS/Tag | 1 + docs/html/api/checksetup.html | 250 + docs/html/api/contrib/bz_webservice_demo.html | 236 + docs/html/api/contrib/bzdbcopy.html | 54 + docs/html/api/contrib/merge-users.html | 46 + docs/html/api/contrib/recode.html | 102 + docs/html/api/email_in.html | 152 + docs/html/api/importxml.html | 93 + docs/html/api/index.html | 236 + docs/html/api/style.css | 107 + docs/html/attachments.html | 29 +- docs/html/bug_page.html | 13 +- docs/html/bugreports.html | 25 +- docs/html/classifications.html | 6 +- docs/html/cmdline-bugmail.html | 6 +- docs/html/cmdline.html | 8 +- docs/html/components.html | 6 +- docs/html/configuration.html | 451 +- docs/html/conventions.html | 8 +- docs/html/copyright.html | 6 +- docs/html/credits.html | 6 +- docs/html/cust-change-permissions.html | 74 +- docs/html/cust-hooks.html | 268 +- docs/html/{dbmodify.html => cust-skins.html} | 103 +- docs/html/cust-templates.html | 40 +- docs/html/custom-fields.html | 301 + docs/html/customization.html | 48 +- docs/html/disclaimer.html | 6 +- docs/html/edit-values.html | 27 +- docs/html/extraconfig.html | 58 +- docs/html/faq.html | 322 +- docs/html/flags-overview.html | 16 +- docs/html/flags.html | 6 +- docs/html/general-advice.html | 6 +- docs/html/gfdl-0.html | 6 +- docs/html/gfdl-1.html | 6 +- docs/html/gfdl-10.html | 6 +- docs/html/gfdl-2.html | 6 +- docs/html/gfdl-3.html | 6 +- docs/html/gfdl-4.html | 6 +- docs/html/gfdl-5.html | 6 +- docs/html/gfdl-6.html | 6 +- docs/html/gfdl-7.html | 6 +- docs/html/gfdl-8.html | 6 +- docs/html/gfdl-9.html | 6 +- docs/html/gfdl-howto.html | 8 +- docs/html/gfdl.html | 8 +- docs/html/glossary.html | 18 +- docs/html/groups.html | 36 +- docs/html/hintsandtips.html | 8 +- docs/html/index.html | 54 +- docs/html/install-perlmodules-manual.html | 6 +- docs/html/installation.html | 209 +- docs/html/installing-bugzilla.html | 29 +- docs/html/integration.html | 20 +- docs/html/lifecycle.html | 6 +- docs/html/milestones.html | 6 +- docs/html/modules-manual-download.html | 90 +- docs/html/modules-manual-instructions.html | 6 +- docs/html/modules-manual-optional.html | 6 +- docs/html/myaccount.html | 146 +- docs/html/newversions.html | 12 +- docs/html/nonroot.html | 30 +- docs/html/os-specific.html | 14 +- docs/html/parameters.html | 31 +- docs/html/paranoid-security.html | 16 +- docs/html/patches.html | 6 +- docs/html/products.html | 6 +- docs/html/query.html | 94 +- docs/html/quips.html | 8 +- docs/html/reporting.html | 10 +- docs/html/security-bugzilla.html | 6 +- docs/html/security-mysql.html | 6 +- docs/html/security-os.html | 6 +- docs/html/security-webserver.html | 6 +- docs/html/security.html | 6 +- docs/html/timetracking.html | 6 +- docs/html/trbl-dbdsponge.html | 6 +- docs/html/trbl-index.html | 8 +- docs/html/trbl-passwd-encryption.html | 8 +- docs/html/trbl-perlmodule.html | 6 +- docs/html/trbl-relogin-everyone.html | 22 +- docs/html/trbl-relogin-some.html | 8 +- docs/html/trbl-testserver.html | 6 +- docs/html/trouble-filetemp.html | 218 - docs/html/troubleshooting.html | 17 +- docs/html/upgrading.html | 130 +- docs/html/useradmin.html | 26 +- docs/html/userpreferences.html | 8 +- docs/html/using-intro.html | 6 +- docs/html/using.html | 14 +- docs/html/versions.html | 6 +- docs/html/voting.html | 8 +- docs/html/whining.html | 34 +- docs/html/{x763.html => x834.html} | 8 +- docs/images/CVS/Entries | 12 +- docs/images/CVS/Tag | 2 +- docs/images/bzLifecycle.png | Bin 55019 -> 74447 bytes docs/images/bzLifecycle.xml | 4 +- docs/images/callouts/CVS/Entries | 6 +- docs/images/callouts/CVS/Tag | 2 +- docs/lib/CVS/Entries | 1 + docs/lib/CVS/Repository | 1 + docs/lib/CVS/Root | 1 + docs/lib/CVS/Tag | 1 + docs/lib/Pod/CVS/Entries | 1 + docs/lib/Pod/CVS/Repository | 1 + docs/lib/Pod/CVS/Root | 1 + docs/lib/Pod/CVS/Tag | 1 + docs/lib/Pod/Simple/CVS/Entries | 2 + docs/lib/Pod/Simple/CVS/Repository | 1 + docs/lib/Pod/Simple/CVS/Root | 1 + docs/lib/Pod/Simple/CVS/Tag | 1 + docs/lib/Pod/Simple/HTML/Bugzilla.pm | 78 + docs/lib/Pod/Simple/HTML/CVS/Entries | 2 + docs/lib/Pod/Simple/HTML/CVS/Repository | 1 + docs/lib/Pod/Simple/HTML/CVS/Root | 1 + docs/lib/Pod/Simple/HTML/CVS/Tag | 1 + docs/lib/Pod/Simple/HTMLBatch/Bugzilla.pm | 107 + docs/lib/Pod/Simple/HTMLBatch/CVS/Entries | 2 + docs/lib/Pod/Simple/HTMLBatch/CVS/Repository | 1 + docs/lib/Pod/Simple/HTMLBatch/CVS/Root | 1 + docs/lib/Pod/Simple/HTMLBatch/CVS/Tag | 1 + docs/makedocs.pl | 122 +- docs/pdf/Bugzilla-Guide.pdf | 34211 ++++++++-------- docs/rel_notes.txt | 53 +- docs/txt/Bugzilla-Guide.txt | 1059 +- docs/xml/.cvsignore | 1 + docs/xml/Bugzilla-Guide.xml | 51 +- docs/xml/CVS/Entries | 41 +- docs/xml/CVS/Tag | 2 +- docs/xml/about.xml | 6 +- docs/xml/administration.xml | 252 +- docs/xml/bugzilla.ent | 36 + docs/xml/customization.xml | 299 +- docs/xml/faq.xml | 184 +- docs/xml/glossary.xml | 4 +- docs/xml/installation.xml | 498 +- docs/xml/introduction.xml | 2 +- docs/xml/modules.xml | 36 - docs/xml/patches.xml | 2 +- docs/xml/requiredsoftware.xml | 4 - docs/xml/security.xml | 2 +- docs/xml/troubleshooting.xml | 45 +- docs/xml/using.xml | 196 +- duplicates.cgi | 26 +- editclassifications.cgi | 60 +- editcomponents.cgi | 153 +- editfields.cgi | 122 + editflagtypes.cgi | 368 +- editgroups.cgi | 117 +- editkeywords.cgi | 187 +- editmilestones.cgi | 96 +- editparams.cgi | 50 +- editproducts.cgi | 284 +- editsettings.cgi | 6 +- editusers.cgi | 232 +- editvalues.cgi | 95 +- editversions.cgi | 160 +- editwhines.cgi | 10 +- email_in.pl | 530 + enter_bug.cgi | 417 +- globals.pl | 804 - images/CVS/Entries | 2 +- images/CVS/Tag | 2 +- importxml.pl | 219 +- index.cgi | 31 +- js/CVS/Entries | 8 +- js/CVS/Tag | 2 +- js/attachment.js | 106 + js/expanding-tree.js | 157 + mod_perl.pl | 114 + page.cgi | 3 +- post_bug.cgi | 582 +- process_bug.cgi | 1259 +- query.cgi | 199 +- quips.cgi | 14 +- relogin.cgi | 13 +- report.cgi | 21 +- reports.cgi | 225 +- request.cgi | 77 +- sanitycheck.cgi | 300 +- search_plugin.cgi | 33 + show_activity.cgi | 4 +- show_bug.cgi | 38 +- showattachment.cgi | 2 +- showdependencygraph.cgi | 24 +- showdependencytree.cgi | 107 +- sidebar.cgi | 5 +- skins/.cvsignore | 2 + skins/CVS/Entries | 1 + skins/CVS/Tag | 2 +- skins/standard/CVS/Entries | 27 +- skins/standard/CVS/Tag | 2 +- skins/standard/IE-fixes.css | 33 + skins/standard/buglist.css | 12 +- skins/standard/create_attachment.css | 36 + skins/standard/dependency-tree.css | 94 + skins/standard/dependency-tree/CVS/Entries | 5 + skins/standard/dependency-tree/CVS/Repository | 1 + skins/standard/dependency-tree/CVS/Root | 1 + skins/standard/dependency-tree/CVS/Tag | 1 + skins/standard/dependency-tree/bug-item.png | Bin 0 -> 1279 bytes .../standard/dependency-tree/tree-closed.png | Bin 0 -> 1129 bytes skins/standard/dependency-tree/tree-open.png | Bin 0 -> 1130 bytes skins/standard/dependency-tree/tree.png | Bin 0 -> 961 bytes skins/standard/global.css | 423 +- skins/standard/global/CVS/Entries | 4 +- skins/standard/global/CVS/Tag | 2 +- skins/standard/index.css | 26 +- skins/standard/index/CVS/Entries | 2 +- skins/standard/index/CVS/Tag | 2 +- skins/standard/params.css | 6 + skins/standard/release-notes.css | 35 + skins/standard/show_multiple.css | 49 + summarize_time.cgi | 14 +- t/001compile.t | 14 +- t/004template.t | 2 +- t/007util.t | 19 +- t/008filter.t | 6 +- t/009bugwords.t | 6 +- t/010dependencies.t | 108 + t/012throwables.t | 38 +- t/CVS/Entries | 23 +- t/CVS/Tag | 2 +- t/Support/CVS/Entries | 6 +- t/Support/CVS/Tag | 2 +- t/Support/Files.pm | 2 + template/CVS/Entries | 2 +- template/CVS/Tag | 2 +- template/en/CVS/Entries | 2 +- template/en/CVS/Tag | 2 +- template/en/default/CVS/Entries | 11 +- template/en/default/CVS/Tag | 2 +- template/en/default/account/CVS/Entries | 8 +- template/en/default/account/CVS/Tag | 2 +- template/en/default/account/auth/CVS/Entries | 5 +- template/en/default/account/auth/CVS/Tag | 2 +- .../default/account/auth/ldap-error.html.tmpl | 50 - .../account/auth/login-small.html.tmpl | 36 +- .../en/default/account/auth/login.html.tmpl | 54 +- .../en/default/account/cancel-token.txt.tmpl | 31 +- template/en/default/account/create.html.tmpl | 34 +- template/en/default/account/created.html.tmpl | 22 +- template/en/default/account/email/CVS/Entries | 8 +- template/en/default/account/email/CVS/Tag | 2 +- .../default/account/email/change-new.txt.tmpl | 7 +- .../default/account/email/change-old.txt.tmpl | 9 +- .../account/email/confirm-new.html.tmpl | 64 + .../default/account/email/confirm.html.tmpl | 2 +- .../account/email/request-new.txt.tmpl | 45 + .../en/default/account/password/CVS/Entries | 4 +- template/en/default/account/password/CVS/Tag | 2 +- .../password/forgotten-password.txt.tmpl | 3 +- .../password/set-forgotten-password.html.tmpl | 2 +- template/en/default/account/prefs/CVS/Entries | 12 +- template/en/default/account/prefs/CVS/Tag | 2 +- .../default/account/prefs/account.html.tmpl | 29 +- .../en/default/account/prefs/email.html.tmpl | 26 +- .../account/prefs/permissions.html.tmpl | 23 +- .../en/default/account/prefs/prefs.html.tmpl | 41 +- .../account/prefs/saved-searches.html.tmpl | 92 +- .../default/account/prefs/settings.html.tmpl | 2 +- .../account/profile-activity.html.tmpl | 86 + template/en/default/admin/CVS/Entries | 7 +- template/en/default/admin/CVS/Tag | 2 +- .../default/admin/classifications/CVS/Entries | 16 +- .../en/default/admin/classifications/CVS/Tag | 2 +- .../admin/classifications/add.html.tmpl | 14 +- .../admin/classifications/del.html.tmpl | 8 +- .../admin/classifications/edit.html.tmpl | 14 +- .../classifications/reclassify.html.tmpl | 4 + .../admin/classifications/select.html.tmpl | 4 +- .../admin/classifications/update.html.tmpl | 4 + .../en/default/admin/components/CVS/Entries | 18 +- template/en/default/admin/components/CVS/Tag | 2 +- .../admin/components/confirm-delete.html.tmpl | 33 +- .../default/admin/components/create.html.tmpl | 42 +- .../admin/components/created.html.tmpl | 13 +- .../admin/components/deleted.html.tmpl | 26 +- .../default/admin/components/edit.html.tmpl | 43 +- .../default/admin/components/footer.html.tmpl | 27 +- .../default/admin/components/list.html.tmpl | 22 +- .../admin/components/select-product.html.tmpl | 2 - .../admin/components/updated.html.tmpl | 52 +- .../default/admin/custom_fields/CVS/Entries | 4 + .../admin/custom_fields/CVS/Repository | 1 + .../en/default/admin/custom_fields/CVS/Root | 1 + .../en/default/admin/custom_fields/CVS/Tag | 1 + .../admin/custom_fields/create.html.tmpl | 114 + .../admin/custom_fields/edit.html.tmpl | 109 + .../admin/custom_fields/list.html.tmpl | 84 + .../en/default/admin/fieldvalues/CVS/Entries | 18 +- template/en/default/admin/fieldvalues/CVS/Tag | 2 +- .../fieldvalues/confirm-delete.html.tmpl | 6 +- .../admin/fieldvalues/create.html.tmpl | 8 +- .../admin/fieldvalues/created.html.tmpl | 2 - .../admin/fieldvalues/deleted.html.tmpl | 2 - .../default/admin/fieldvalues/edit.html.tmpl | 15 +- .../admin/fieldvalues/footer.html.tmpl | 6 +- .../default/admin/fieldvalues/list.html.tmpl | 41 +- .../admin/fieldvalues/select-field.html.tmpl | 2 - .../admin/fieldvalues/updated.html.tmpl | 4 +- .../en/default/admin/flag-type/CVS/Entries | 6 +- template/en/default/admin/flag-type/CVS/Tag | 2 +- .../admin/flag-type/confirm-delete.html.tmpl | 4 +- .../en/default/admin/flag-type/edit.html.tmpl | 44 +- .../en/default/admin/flag-type/list.html.tmpl | 68 +- template/en/default/admin/groups/CVS/Entries | 16 +- template/en/default/admin/groups/CVS/Tag | 2 +- .../en/default/admin/groups/create.html.tmpl | 13 +- .../en/default/admin/groups/delete.html.tmpl | 22 +- .../en/default/admin/groups/edit.html.tmpl | 26 +- .../en/default/admin/groups/list.html.tmpl | 16 +- .../en/default/admin/groups/remove.html.tmpl | 2 +- .../en/default/admin/keywords/CVS/Entries | 12 +- template/en/default/admin/keywords/CVS/Tag | 2 +- .../admin/keywords/confirm-delete.html.tmpl | 16 +- .../default/admin/keywords/create.html.tmpl | 12 +- .../en/default/admin/keywords/edit.html.tmpl | 28 +- .../en/default/admin/keywords/list.html.tmpl | 4 +- .../admin/keywords/rebuild-cache.html.tmpl | 5 +- .../en/default/admin/milestones/CVS/Entries | 18 +- template/en/default/admin/milestones/CVS/Tag | 2 +- .../admin/milestones/confirm-delete.html.tmpl | 37 +- .../default/admin/milestones/create.html.tmpl | 17 +- .../admin/milestones/created.html.tmpl | 18 +- .../admin/milestones/deleted.html.tmpl | 24 +- .../default/admin/milestones/edit.html.tmpl | 25 +- .../default/admin/milestones/footer.html.tmpl | 32 +- .../default/admin/milestones/list.html.tmpl | 20 +- .../admin/milestones/select-product.html.tmpl | 2 - .../admin/milestones/updated.html.tmpl | 25 +- template/en/default/admin/params/CVS/Entries | 38 +- template/en/default/admin/params/CVS/Tag | 2 +- .../default/admin/params/attachment.html.tmpl | 4 + .../en/default/admin/params/core.html.tmpl | 53 +- .../default/admin/params/editparams.html.tmpl | 14 +- .../admin/params/groupsecurity.html.tmpl | 3 + .../en/default/admin/params/ldap.html.tmpl | 17 +- .../en/default/admin/params/mta.html.tmpl | 59 +- .../admin/params/patchviewer.html.tmpl | 4 +- .../en/default/admin/products/CVS/Entries | 20 +- template/en/default/admin/products/CVS/Tag | 2 +- .../admin/products/confirm-delete.html.tmpl | 9 +- .../admin/products/edit-common.html.tmpl | 27 +- .../en/default/admin/products/edit.html.tmpl | 3 + .../default/admin/products/footer.html.tmpl | 10 +- .../admin/products/groupcontrol/CVS/Entries | 6 +- .../admin/products/groupcontrol/CVS/Tag | 2 +- .../groupcontrol/confirm-edit.html.tmpl | 2 +- .../products/groupcontrol/edit.html.tmpl | 42 +- .../products/list-classifications.html.tmpl | 2 - .../en/default/admin/products/list.html.tmpl | 4 +- .../default/admin/products/updated.html.tmpl | 12 +- .../en/default/admin/settings/CVS/Entries | 4 +- template/en/default/admin/settings/CVS/Tag | 2 +- .../en/default/admin/settings/edit.html.tmpl | 4 +- template/en/default/admin/sudo.html.tmpl | 18 +- template/en/default/admin/users/CVS/Entries | 14 +- template/en/default/admin/users/CVS/Tag | 2 +- .../admin/users/confirm-delete.html.tmpl | 54 +- .../en/default/admin/users/create.html.tmpl | 2 +- .../en/default/admin/users/edit.html.tmpl | 10 +- .../en/default/admin/users/list.html.tmpl | 6 + .../en/default/admin/users/search.html.tmpl | 11 +- .../en/default/admin/users/userdata.html.tmpl | 31 +- .../en/default/admin/versions/CVS/Entries | 18 +- template/en/default/admin/versions/CVS/Tag | 2 +- .../admin/versions/confirm-delete.html.tmpl | 47 +- .../default/admin/versions/create.html.tmpl | 17 +- .../default/admin/versions/created.html.tmpl | 19 +- .../default/admin/versions/deleted.html.tmpl | 16 +- .../en/default/admin/versions/edit.html.tmpl | 21 +- .../default/admin/versions/footer.html.tmpl | 32 +- .../en/default/admin/versions/list.html.tmpl | 19 +- .../admin/versions/select-product.html.tmpl | 2 - .../default/admin/versions/updated.html.tmpl | 26 +- template/en/default/attachment/CVS/Entries | 25 +- template/en/default/attachment/CVS/Tag | 2 +- .../en/default/attachment/choose.html.tmpl | 6 +- .../attachment/confirm-delete.html.tmpl | 91 + .../en/default/attachment/create.html.tmpl | 227 +- .../en/default/attachment/created.html.tmpl | 54 +- .../attachment/createformcontents.html.tmpl | 100 + .../default/attachment/delete_reason.txt.tmpl | 33 + .../default/attachment/diff-header.html.tmpl | 6 +- template/en/default/attachment/edit.html.tmpl | 94 +- template/en/default/attachment/list.html.tmpl | 134 +- .../attachment/show-multiple.html.tmpl | 25 +- .../en/default/attachment/updated.html.tmpl | 29 +- template/en/default/bug/CVS/Entries | 25 +- template/en/default/bug/CVS/Tag | 2 +- template/en/default/bug/activity/CVS/Entries | 4 +- template/en/default/bug/activity/CVS/Tag | 2 +- .../en/default/bug/activity/show.html.tmpl | 4 +- .../en/default/bug/activity/table.html.tmpl | 13 +- template/en/default/bug/choose.html.tmpl | 2 +- template/en/default/bug/comments.html.tmpl | 34 +- template/en/default/bug/create/CVS/Entries | 15 +- template/en/default/bug/create/CVS/Tag | 2 +- .../bug/create/comment-guided.txt.tmpl | 2 +- .../bug/create/confirm-create-dupe.html.tmpl | 58 + .../bug/create/create-guided.html.tmpl | 111 +- .../en/default/bug/create/create.html.tmpl | 267 +- .../bug/create/make-template.html.tmpl | 2 +- .../en/default/bug/dependency-graph.html.tmpl | 8 +- .../en/default/bug/dependency-tree.html.tmpl | 249 +- template/en/default/bug/edit.html.tmpl | 831 +- template/en/default/bug/field.html.tmpl | 63 + template/en/default/bug/knob.html.tmpl | 115 +- template/en/default/bug/navigate.html.tmpl | 3 - template/en/default/bug/process/CVS/Entries | 12 +- template/en/default/bug/process/CVS/Tag | 2 +- .../en/default/bug/process/bugmail.html.tmpl | 16 +- .../bug/process/confirm-duplicate.html.tmpl | 20 +- .../en/default/bug/process/header.html.tmpl | 11 +- .../en/default/bug/process/midair.html.tmpl | 10 +- .../en/default/bug/process/results.html.tmpl | 45 +- .../bug/process/verify-new-product.html.tmpl | 34 +- .../en/default/bug/show-multiple.html.tmpl | 359 +- template/en/default/bug/show.html.tmpl | 9 +- template/en/default/bug/show.xml.tmpl | 22 +- .../en/default/bug/summarize-time.html.tmpl | 38 +- template/en/default/bug/votes/CVS/Entries | 6 +- template/en/default/bug/votes/CVS/Tag | 2 +- .../en/default/bug/votes/delete-all.html.tmpl | 2 +- .../default/bug/votes/list-for-bug.html.tmpl | 2 +- .../default/bug/votes/list-for-user.html.tmpl | 13 +- template/en/default/config.js.tmpl | 2 +- template/en/default/config.rdf.tmpl | 2 +- template/en/default/email/CVS/Entries | 5 +- template/en/default/email/CVS/Tag | 2 +- .../en/default/email/newchangedmail.txt.tmpl | 77 + template/en/default/email/sudo.txt.tmpl | 3 +- .../votes-removed.txt.tmpl} | 31 +- template/en/default/email/whine.txt.tmpl | 66 + template/en/default/filterexceptions.pl | 107 +- template/en/default/flag/CVS/Entries | 2 +- template/en/default/flag/CVS/Tag | 2 +- template/en/default/flag/list.html.tmpl | 76 +- template/en/default/global/CVS/Entries | 52 +- template/en/default/global/CVS/Tag | 2 +- template/en/default/global/banner.html.tmpl | 15 +- .../global/choose-classification.html.tmpl | 13 +- .../default/global/choose-product.html.tmpl | 45 +- .../en/default/global/code-error.html.tmpl | 186 +- .../en/default/global/common-links.html.tmpl | 105 + .../global/confirm-user-match.html.tmpl | 14 +- .../en/default/global/docslinks.html.tmpl | 53 + .../en/default/global/field-descs.none.tmpl | 19 +- template/en/default/global/footer.html.tmpl | 3 + template/en/default/global/header.html.tmpl | 184 +- .../en/default/global/hidden-fields.html.tmpl | 22 +- .../en/default/global/js-products.html.tmpl | 33 + template/en/default/global/message.txt.tmpl | 2 +- template/en/default/global/messages.html.tmpl | 153 +- .../default/global/per-bug-queries.html.tmpl | 98 +- .../en/default/global/select-menu.html.tmpl | 5 +- .../en/default/global/setting-descs.none.tmpl | 10 +- .../default/global/site-navigation.html.tmpl | 19 +- template/en/default/global/tabs.html.tmpl | 24 +- template/en/default/global/textarea.html.tmpl | 49 + .../en/default/global/useful-links.html.tmpl | 190 +- .../en/default/global/user-error.html.tmpl | 348 +- .../en/default/global/variables.none.tmpl | 2 +- template/en/default/index.html.tmpl | 68 +- template/en/default/list/CVS/Entries | 24 +- template/en/default/list/CVS/Tag | 2 +- .../en/default/list/change-columns.html.tmpl | 5 +- .../en/default/list/edit-multiple.html.tmpl | 28 +- template/en/default/list/list.html.tmpl | 18 +- template/en/default/list/list.ics.tmpl | 10 +- template/en/default/list/quips.html.tmpl | 10 +- template/en/default/list/table.html.tmpl | 9 +- template/en/default/pages/CVS/Entries | 17 +- template/en/default/pages/CVS/Tag | 2 +- .../en/default/pages/bug-writing.html.tmpl | 293 +- template/en/default/pages/fields.html.tmpl | 14 +- template/en/default/pages/linkify.html.tmpl | 8 +- .../en/default/pages/quicksearch.html.tmpl | 2 +- .../default/pages/quicksearchhack.html.tmpl | 4 +- .../en/default/pages/release-notes.html.tmpl | 763 + template/en/default/pages/voting.html.tmpl | 15 +- template/en/default/reports/CVS/Entries | 45 +- template/en/default/reports/CVS/Tag | 2 +- template/en/default/reports/chart.html.tmpl | 2 +- template/en/default/reports/chart.png.tmpl | 2 +- .../en/default/reports/components.html.tmpl | 68 +- .../en/default/reports/create-chart.html.tmpl | 66 +- .../reports/duplicates-table.html.tmpl | 3 +- .../en/default/reports/duplicates.html.tmpl | 5 +- .../en/default/reports/edit-series.html.tmpl | 2 +- .../en/default/reports/keywords.html.tmpl | 21 +- template/en/default/reports/menu.html.tmpl | 2 +- .../en/default/reports/old-charts.html.tmpl | 69 + .../en/default/reports/report-bar.png.tmpl | 4 +- .../en/default/reports/report-line.png.tmpl | 4 +- .../en/default/reports/report-pie.png.tmpl | 2 +- .../default/reports/report-simple.html.tmpl | 2 +- .../en/default/reports/report-table.csv.tmpl | 4 +- .../en/default/reports/report-table.html.tmpl | 9 +- template/en/default/reports/report.html.tmpl | 12 +- .../default/reports/series-common.html.tmpl | 32 +- template/en/default/reports/series.html.tmpl | 7 +- template/en/default/request/CVS/Entries | 4 +- template/en/default/request/CVS/Tag | 2 +- template/en/default/request/email.txt.tmpl | 22 +- template/en/default/request/queue.html.tmpl | 25 +- template/en/default/search/CVS/Entries | 23 +- template/en/default/search/CVS/Tag | 2 +- .../default/search/boolean-charts.html.tmpl | 17 +- template/en/default/search/form.html.tmpl | 195 +- template/en/default/search/knob.html.tmpl | 16 +- .../default/search/search-advanced.html.tmpl | 7 +- .../en/default/search/search-help.html.tmpl | 2 +- .../en/default/search/search-plugin.xml.tmpl | 25 + .../search/search-report-graph.html.tmpl | 3 +- .../search/search-report-table.html.tmpl | 7 +- .../default/search/search-specific.html.tmpl | 17 +- template/en/default/search/tabs.html.tmpl | 6 +- template/en/default/sidebar.xul.tmpl | 5 +- template/en/default/welcome-admin.html.tmpl | 90 + template/en/default/whine/CVS/Entries | 8 +- template/en/default/whine/CVS/Tag | 2 +- template/en/default/whine/mail.html.tmpl | 2 +- template/en/default/whine/mail.txt.tmpl | 2 +- template/en/default/whine/schedule.html.tmpl | 49 +- template/en/extension/CVS/Entries | 2 +- template/en/extension/CVS/Tag | 2 +- template/en/extension/filterexceptions.pl | 2 +- testagent.cgi | 2 +- testserver.pl | 38 +- token.cgi | 97 +- userprefs.cgi | 198 +- votes.cgi | 135 +- whine.pl | 43 +- whineatnews.pl | 56 +- xmlrpc.cgi | 39 + 761 files changed, 65312 insertions(+), 40764 deletions(-) create mode 100644 Bugzilla/Attachment/CVS/Entries create mode 100644 Bugzilla/Attachment/CVS/Repository rename Bugzilla/{Auth/Login/WWW/CGI => Attachment}/CVS/Root (100%) create mode 100644 Bugzilla/Attachment/CVS/Tag create mode 100644 Bugzilla/Attachment/PatchReader.pm create mode 100644 Bugzilla/Auth/Login.pm create mode 100644 Bugzilla/Auth/Login/CGI.pm create mode 100644 Bugzilla/Auth/Login/Cookie.pm create mode 100644 Bugzilla/Auth/Login/Env.pm create mode 100644 Bugzilla/Auth/Login/Stack.pm delete mode 100644 Bugzilla/Auth/Login/WWW.pm delete mode 100644 Bugzilla/Auth/Login/WWW/CGI.pm delete mode 100644 Bugzilla/Auth/Login/WWW/CGI/CVS/Entries delete mode 100644 Bugzilla/Auth/Login/WWW/CGI/CVS/Repository delete mode 100644 Bugzilla/Auth/Login/WWW/CGI/CVS/Tag delete mode 100644 Bugzilla/Auth/Login/WWW/CGI/Cookie.pm delete mode 100644 Bugzilla/Auth/Login/WWW/CVS/Entries delete mode 100644 Bugzilla/Auth/Login/WWW/CVS/Repository delete mode 100644 Bugzilla/Auth/Login/WWW/CVS/Tag delete mode 100644 Bugzilla/Auth/Login/WWW/Env.pm create mode 100644 Bugzilla/Auth/Persist/CVS/Entries create mode 100644 Bugzilla/Auth/Persist/CVS/Repository rename Bugzilla/Auth/{Login/WWW => Persist}/CVS/Root (100%) create mode 100644 Bugzilla/Auth/Persist/CVS/Tag create mode 100644 Bugzilla/Auth/Persist/Cookie.pm delete mode 100644 Bugzilla/Auth/README create mode 100644 Bugzilla/Auth/Verify.pm create mode 100644 Bugzilla/Auth/Verify/Stack.pm create mode 100644 Bugzilla/Hook.pm create mode 100644 Bugzilla/Install.pm create mode 100644 Bugzilla/Install/CVS/Entries create mode 100644 Bugzilla/Install/CVS/Repository create mode 100644 Bugzilla/Install/CVS/Root create mode 100644 Bugzilla/Install/CVS/Tag create mode 100644 Bugzilla/Install/DB.pm create mode 100644 Bugzilla/Install/Filesystem.pm create mode 100644 Bugzilla/Install/Localconfig.pm create mode 100644 Bugzilla/Install/Requirements.pm create mode 100644 Bugzilla/Keyword.pm create mode 100644 Bugzilla/Mailer.pm create mode 100644 Bugzilla/Object.pm create mode 100644 Bugzilla/Search/Saved.pm create mode 100644 Bugzilla/Update.pm create mode 100644 Bugzilla/User/Setting/CVS/Entries create mode 100644 Bugzilla/User/Setting/CVS/Repository create mode 100644 Bugzilla/User/Setting/CVS/Root create mode 100644 Bugzilla/User/Setting/CVS/Tag create mode 100755 Bugzilla/User/Setting/Skin.pm create mode 100755 Bugzilla/WebService.pm create mode 100755 Bugzilla/WebService/Bug.pm create mode 100755 Bugzilla/WebService/Bugzilla.pm create mode 100644 Bugzilla/WebService/CVS/Entries create mode 100644 Bugzilla/WebService/CVS/Repository create mode 100644 Bugzilla/WebService/CVS/Root create mode 100644 Bugzilla/WebService/CVS/Tag create mode 100755 Bugzilla/WebService/Constants.pm create mode 100755 Bugzilla/WebService/Product.pm create mode 100755 Bugzilla/WebService/User.pm delete mode 100644 contrib/BugzillaEmail.pm delete mode 100644 contrib/README.Mailif delete mode 100755 contrib/bug_email.pl delete mode 100644 contrib/bugmail_help.html delete mode 100644 contrib/bugzilla.procmailrc delete mode 100755 contrib/bugzilla_email_append.pl create mode 100755 contrib/bz_webservice_demo.pl create mode 100755 contrib/recode.pl create mode 100644 docs/html/.cvsignore create mode 100644 docs/html/CVS/Entries create mode 100644 docs/html/CVS/Repository create mode 100644 docs/html/CVS/Root create mode 100644 docs/html/CVS/Tag create mode 100644 docs/html/api/.cvsignore create mode 100644 docs/html/api/Bugzilla.html create mode 100644 docs/html/api/Bugzilla/Attachment.html create mode 100644 docs/html/api/Bugzilla/Auth.html create mode 100644 docs/html/api/Bugzilla/Auth/Login.html create mode 100644 docs/html/api/Bugzilla/Auth/Verify.html create mode 100644 docs/html/api/Bugzilla/CGI.html create mode 100644 docs/html/api/Bugzilla/Classification.html create mode 100644 docs/html/api/Bugzilla/Component.html create mode 100644 docs/html/api/Bugzilla/Config.html create mode 100644 docs/html/api/Bugzilla/Config/Common.html create mode 100644 docs/html/api/Bugzilla/DB.html create mode 100644 docs/html/api/Bugzilla/DB/Mysql.html create mode 100644 docs/html/api/Bugzilla/DB/Pg.html create mode 100644 docs/html/api/Bugzilla/DB/Schema.html create mode 100644 docs/html/api/Bugzilla/Error.html create mode 100644 docs/html/api/Bugzilla/Field.html create mode 100644 docs/html/api/Bugzilla/Flag.html create mode 100644 docs/html/api/Bugzilla/FlagType.html create mode 100644 docs/html/api/Bugzilla/Group.html create mode 100644 docs/html/api/Bugzilla/Hook.html create mode 100644 docs/html/api/Bugzilla/Install.html create mode 100644 docs/html/api/Bugzilla/Install/DB.html create mode 100644 docs/html/api/Bugzilla/Install/Filesystem.html create mode 100644 docs/html/api/Bugzilla/Install/Localconfig.html create mode 100644 docs/html/api/Bugzilla/Install/Requirements.html create mode 100644 docs/html/api/Bugzilla/Keyword.html create mode 100644 docs/html/api/Bugzilla/Milestone.html create mode 100644 docs/html/api/Bugzilla/Object.html create mode 100644 docs/html/api/Bugzilla/Product.html create mode 100644 docs/html/api/Bugzilla/Search/Saved.html create mode 100644 docs/html/api/Bugzilla/Template.html create mode 100644 docs/html/api/Bugzilla/Template/Plugin/Bugzilla.html create mode 100644 docs/html/api/Bugzilla/Template/Plugin/Hook.html create mode 100644 docs/html/api/Bugzilla/Template/Plugin/User.html create mode 100644 docs/html/api/Bugzilla/Token.html create mode 100644 docs/html/api/Bugzilla/Update.html create mode 100644 docs/html/api/Bugzilla/User.html create mode 100644 docs/html/api/Bugzilla/User/Setting.html create mode 100644 docs/html/api/Bugzilla/User/Setting/Skin.html create mode 100644 docs/html/api/Bugzilla/Util.html create mode 100644 docs/html/api/Bugzilla/Version.html create mode 100644 docs/html/api/Bugzilla/WebService.html create mode 100644 docs/html/api/Bugzilla/WebService/Bug.html create mode 100644 docs/html/api/Bugzilla/WebService/Bugzilla.html create mode 100644 docs/html/api/Bugzilla/WebService/Product.html create mode 100644 docs/html/api/Bugzilla/WebService/User.html create mode 100644 docs/html/api/CVS/Entries create mode 100644 docs/html/api/CVS/Repository create mode 100644 docs/html/api/CVS/Root create mode 100644 docs/html/api/CVS/Tag create mode 100644 docs/html/api/checksetup.html create mode 100644 docs/html/api/contrib/bz_webservice_demo.html create mode 100644 docs/html/api/contrib/bzdbcopy.html create mode 100644 docs/html/api/contrib/merge-users.html create mode 100644 docs/html/api/contrib/recode.html create mode 100644 docs/html/api/email_in.html create mode 100644 docs/html/api/importxml.html create mode 100644 docs/html/api/index.html create mode 100644 docs/html/api/style.css rename docs/html/{dbmodify.html => cust-skins.html} (50%) create mode 100644 docs/html/custom-fields.html delete mode 100644 docs/html/trouble-filetemp.html rename docs/html/{x763.html => x834.html} (97%) create mode 100644 docs/lib/CVS/Entries create mode 100644 docs/lib/CVS/Repository create mode 100644 docs/lib/CVS/Root create mode 100644 docs/lib/CVS/Tag create mode 100644 docs/lib/Pod/CVS/Entries create mode 100644 docs/lib/Pod/CVS/Repository create mode 100644 docs/lib/Pod/CVS/Root create mode 100644 docs/lib/Pod/CVS/Tag create mode 100644 docs/lib/Pod/Simple/CVS/Entries create mode 100644 docs/lib/Pod/Simple/CVS/Repository create mode 100644 docs/lib/Pod/Simple/CVS/Root create mode 100644 docs/lib/Pod/Simple/CVS/Tag create mode 100644 docs/lib/Pod/Simple/HTML/Bugzilla.pm create mode 100644 docs/lib/Pod/Simple/HTML/CVS/Entries create mode 100644 docs/lib/Pod/Simple/HTML/CVS/Repository create mode 100644 docs/lib/Pod/Simple/HTML/CVS/Root create mode 100644 docs/lib/Pod/Simple/HTML/CVS/Tag create mode 100644 docs/lib/Pod/Simple/HTMLBatch/Bugzilla.pm create mode 100644 docs/lib/Pod/Simple/HTMLBatch/CVS/Entries create mode 100644 docs/lib/Pod/Simple/HTMLBatch/CVS/Repository create mode 100644 docs/lib/Pod/Simple/HTMLBatch/CVS/Root create mode 100644 docs/lib/Pod/Simple/HTMLBatch/CVS/Tag create mode 100644 docs/xml/.cvsignore create mode 100644 docs/xml/bugzilla.ent create mode 100644 editfields.cgi create mode 100644 email_in.pl delete mode 100644 globals.pl create mode 100644 js/attachment.js create mode 100644 js/expanding-tree.js create mode 100644 mod_perl.pl create mode 100644 search_plugin.cgi create mode 100644 skins/.cvsignore create mode 100755 skins/standard/IE-fixes.css create mode 100644 skins/standard/create_attachment.css create mode 100644 skins/standard/dependency-tree.css create mode 100644 skins/standard/dependency-tree/CVS/Entries create mode 100644 skins/standard/dependency-tree/CVS/Repository create mode 100644 skins/standard/dependency-tree/CVS/Root create mode 100644 skins/standard/dependency-tree/CVS/Tag create mode 100644 skins/standard/dependency-tree/bug-item.png create mode 100644 skins/standard/dependency-tree/tree-closed.png create mode 100644 skins/standard/dependency-tree/tree-open.png create mode 100644 skins/standard/dependency-tree/tree.png create mode 100644 skins/standard/release-notes.css create mode 100644 t/010dependencies.t delete mode 100644 template/en/default/account/auth/ldap-error.html.tmpl create mode 100644 template/en/default/account/email/confirm-new.html.tmpl create mode 100644 template/en/default/account/email/request-new.txt.tmpl create mode 100644 template/en/default/account/profile-activity.html.tmpl create mode 100644 template/en/default/admin/custom_fields/CVS/Entries create mode 100644 template/en/default/admin/custom_fields/CVS/Repository create mode 100644 template/en/default/admin/custom_fields/CVS/Root create mode 100644 template/en/default/admin/custom_fields/CVS/Tag create mode 100644 template/en/default/admin/custom_fields/create.html.tmpl create mode 100644 template/en/default/admin/custom_fields/edit.html.tmpl create mode 100644 template/en/default/admin/custom_fields/list.html.tmpl create mode 100644 template/en/default/attachment/confirm-delete.html.tmpl create mode 100644 template/en/default/attachment/createformcontents.html.tmpl create mode 100644 template/en/default/attachment/delete_reason.txt.tmpl create mode 100644 template/en/default/bug/create/confirm-create-dupe.html.tmpl create mode 100644 template/en/default/bug/field.html.tmpl create mode 100644 template/en/default/email/newchangedmail.txt.tmpl rename template/en/default/{account/exists.html.tmpl => email/votes-removed.txt.tmpl} (57%) create mode 100644 template/en/default/email/whine.txt.tmpl create mode 100644 template/en/default/global/common-links.html.tmpl create mode 100644 template/en/default/global/docslinks.html.tmpl create mode 100644 template/en/default/global/js-products.html.tmpl create mode 100644 template/en/default/global/textarea.html.tmpl create mode 100644 template/en/default/pages/release-notes.html.tmpl create mode 100644 template/en/default/reports/old-charts.html.tmpl create mode 100644 template/en/default/search/search-plugin.xml.tmpl create mode 100644 template/en/default/welcome-admin.html.tmpl create mode 100755 xmlrpc.cgi diff --git a/.cvsignore b/.cvsignore index cba381bab..1d378db06 100644 --- a/.cvsignore +++ b/.cvsignore @@ -4,3 +4,4 @@ data localconfig index.html old-params.txt +extensions diff --git a/Bugzilla.pm b/Bugzilla.pm index 84857041b..679695bf2 100644 --- a/Bugzilla.pm +++ b/Bugzilla.pm @@ -20,23 +20,30 @@ # Contributor(s): Bradley Baetz <bbaetz@student.usyd.edu.au> # Erik Stambaugh <erik@dasbistro.com> # A. Karl Kornel <karl@kornel.name> +# Marc Schumann <wurblzap@gmail.com> package Bugzilla; use strict; -use Bugzilla::Auth; -use Bugzilla::Auth::Login::WWW; -use Bugzilla::CGI; use Bugzilla::Config; use Bugzilla::Constants; +use Bugzilla::Auth; +use Bugzilla::Auth::Persist::Cookie; +use Bugzilla::CGI; use Bugzilla::DB; +use Bugzilla::Install::Localconfig qw(read_localconfig); use Bugzilla::Template; use Bugzilla::User; use Bugzilla::Error; use Bugzilla::Util; +use Bugzilla::Field; use File::Basename; +use Safe; + +# This creates the request cache for non-mod_perl installations. +our $_request_cache = {}; ##################################################################### # Constants @@ -46,6 +53,7 @@ use File::Basename; use constant SHUTDOWNHTML_EXEMPT => [ 'editparams.cgi', 'checksetup.pl', + 'recode.pl', ]; # Non-cgi scripts that should silently exit. @@ -57,91 +65,131 @@ use constant SHUTDOWNHTML_EXIT_SILENTLY => [ # Global Code ##################################################################### -# If Bugzilla is shut down, do not allow anything to run, just display a -# message to the user about the downtime and log out. Scripts listed in -# SHUTDOWNHTML_EXEMPT are exempt from this message. +# The following subroutine is for debugging purposes only. +# Uncommenting this sub and the $::SIG{__DIE__} trap underneath it will +# cause any fatal errors to result in a call stack trace to help track +# down weird errors. # -# Because this is code which is run live from perl "use" commands of other -# scripts, we're skipping this part if we get here during a perl syntax check -# -- runtests.pl compiles scripts without running them, so we need to make sure -# that this check doesn't apply to 'perl -c' calls. -# -# This code must go here. It cannot go anywhere in Bugzilla::CGI, because -# it uses Template, and that causes various dependency loops. -if (!$^C - && Param("shutdownhtml") - && lsearch(SHUTDOWNHTML_EXEMPT, basename($0)) == -1) -{ - # Allow non-cgi scripts to exit silently (without displaying any - # message), if desired. At this point, no DBI call has been made - # yet, and no error will be returned if the DB is inaccessible. - if (lsearch(SHUTDOWNHTML_EXIT_SILENTLY, basename($0)) > -1 - && !i_am_cgi()) +#sub die_with_dignity { +# use Carp (); +# my ($err_msg) = @_; +# print $err_msg; +# Carp::confess($err_msg); +#} +#$::SIG{__DIE__} = \&Bugzilla::die_with_dignity; + +sub init_page { + + # Some environment variables are not taint safe + delete @::ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; + # Some modules throw undefined errors (notably File::Spec::Win32) if + # PATH is undefined. + $ENV{'PATH'} = ''; + + # If Bugzilla is shut down, do not allow anything to run, just display a + # message to the user about the downtime and log out. Scripts listed in + # SHUTDOWNHTML_EXEMPT are exempt from this message. + # + # Because this is code which is run live from perl "use" commands of other + # scripts, we're skipping this part if we get here during a perl syntax + # check -- runtests.pl compiles scripts without running them, so we + # need to make sure that this check doesn't apply to 'perl -c' calls. + # + # This code must go here. It cannot go anywhere in Bugzilla::CGI, because + # it uses Template, and that causes various dependency loops. + if (!$^C && Bugzilla->params->{"shutdownhtml"} + && lsearch(SHUTDOWNHTML_EXEMPT, basename($0)) == -1) { - exit; - } + # Allow non-cgi scripts to exit silently (without displaying any + # message), if desired. At this point, no DBI call has been made + # yet, and no error will be returned if the DB is inaccessible. + if (lsearch(SHUTDOWNHTML_EXIT_SILENTLY, basename($0)) > -1 + && !i_am_cgi()) + { + exit; + } - # For security reasons, log out users when Bugzilla is down. - # Bugzilla->login() is required to catch the logincookie, if any. - my $user = Bugzilla->login(LOGIN_OPTIONAL); - my $userid = $user->id; - Bugzilla->logout(); - - my $template = Bugzilla->template; - my $vars = {}; - $vars->{'message'} = 'shutdown'; - $vars->{'userid'} = $userid; - # Generate and return a message about the downtime, appropriately - # for if we're a command-line script or a CGI script. - my $extension; - if (i_am_cgi() && (!Bugzilla->cgi->param('ctype') - || Bugzilla->cgi->param('ctype') eq 'html')) { - $extension = 'html'; - } - else { - $extension = 'txt'; + # For security reasons, log out users when Bugzilla is down. + # Bugzilla->login() is required to catch the logincookie, if any. + my $user = Bugzilla->login(LOGIN_OPTIONAL); + my $userid = $user->id; + Bugzilla->logout(); + + my $template = Bugzilla->template; + my $vars = {}; + $vars->{'message'} = 'shutdown'; + $vars->{'userid'} = $userid; + # Generate and return a message about the downtime, appropriately + # for if we're a command-line script or a CGI script. + my $extension; + if (i_am_cgi() && (!Bugzilla->cgi->param('ctype') + || Bugzilla->cgi->param('ctype') eq 'html')) { + $extension = 'html'; + } + else { + $extension = 'txt'; + } + print Bugzilla->cgi->header() if i_am_cgi(); + my $t_output; + $template->process("global/message.$extension.tmpl", $vars, \$t_output) + || ThrowTemplateError($template->error); + print $t_output . "\n"; + exit; } - print Bugzilla->cgi->header() if i_am_cgi(); - my $t_output; - $template->process("global/message.$extension.tmpl", $vars, \$t_output) - || ThrowTemplateError($template->error); - print $t_output . "\n"; - exit; } +init_page() if !$ENV{MOD_PERL}; + ##################################################################### # Subroutines and Methods ##################################################################### -my $_template; sub template { my $class = shift; - $_template ||= Bugzilla::Template->create(); - return $_template; + request_cache()->{language} = ""; + request_cache()->{template} ||= Bugzilla::Template->create(); + return request_cache()->{template}; +} + +sub template_inner { + my ($class, $lang) = @_; + $lang = defined($lang) ? $lang : (request_cache()->{language} || ""); + request_cache()->{language} = $lang; + request_cache()->{"template_inner_$lang"} ||= Bugzilla::Template->create(); + return request_cache()->{"template_inner_$lang"}; } -my $_cgi; sub cgi { my $class = shift; - $_cgi ||= new Bugzilla::CGI(); - return $_cgi; + request_cache()->{cgi} ||= new Bugzilla::CGI(); + return request_cache()->{cgi}; } -my $_user; -sub user { +sub localconfig { + request_cache()->{localconfig} ||= read_localconfig(); + return request_cache()->{localconfig}; +} + +sub params { my $class = shift; + request_cache()->{params} ||= Bugzilla::Config::read_param_file(); + return request_cache()->{params}; +} - if (not defined $_user) { - $_user = new Bugzilla::User; - } +sub user { + my $class = shift; + request_cache()->{user} ||= new Bugzilla::User; + return request_cache()->{user}; +} - return $_user; +sub set_user { + my ($class, $user) = @_; + $class->request_cache->{user} = $user; } -my $_sudoer; sub sudoer { my $class = shift; - return $_sudoer; + return request_cache()->{sudoer}; } sub sudo_request { @@ -149,8 +197,8 @@ sub sudo_request { my $new_user = shift; my $new_sudoer = shift; - $_user = $new_user; - $_sudoer = $new_sudoer; + request_cache()->{user} = $new_user; + request_cache()->{sudoer} = $new_sudoer; # NOTE: If you want to log the start of an sudo session, do it here. @@ -159,7 +207,15 @@ sub sudo_request { sub login { my ($class, $type) = @_; - my $authenticated_user = Bugzilla::Auth::Login::WWW->login($type); + + return Bugzilla->user if Bugzilla->user->id; + + my $authorizer = new Bugzilla::Auth(); + $type = LOGIN_REQUIRED if Bugzilla->cgi->param('GoAheadAndLogIn'); + if (!defined $type || $type == LOGIN_NORMAL) { + $type = Bugzilla->params->{'requirelogin'} ? LOGIN_REQUIRED : LOGIN_NORMAL; + } + my $authenticated_user = $authorizer->login($type); # At this point, we now know if a real person is logged in. # We must now check to see if an sudo session is in progress. @@ -180,16 +236,19 @@ sub login { !($sudo_target->in_group('bz_sudo_protect')) ) { - $_user = $sudo_target; - $_sudoer = $authenticated_user; + Bugzilla->set_user($sudo_target); + request_cache()->{sudoer} = $authenticated_user; + # And make sure that both users have the same Auth object, + # since we never call Auth::login for the sudo target. + $sudo_target->set_authorizer($authenticated_user->authorizer); # NOTE: If you want to do any special logging, do it here. } else { - $_user = $authenticated_user; + Bugzilla->set_user($authenticated_user); } - return $_user; + return Bugzilla->user; } sub logout { @@ -199,14 +258,15 @@ sub logout { return unless user->id; $option = LOGOUT_CURRENT unless defined $option; - Bugzilla::Auth::Login::WWW->logout($_user, $option); + Bugzilla::Auth::Persist::Cookie->logout({type => $option}); + Bugzilla->logout_request() unless $option eq LOGOUT_KEEP_CURRENT; } sub logout_user { my ($class, $user) = @_; # When we're logging out another user we leave cookies alone, and # therefore avoid calling Bugzilla->logout() directly. - Bugzilla::Auth::Login::WWW->logout($user, LOGOUT_ALL); + Bugzilla::Auth::Persist::Cookie->logout({user => $user}); } # just a compatibility front-end to logout_user that gets a user by id @@ -218,50 +278,94 @@ sub logout_user_by_id { # hack that invalidates credentials for a single request sub logout_request { - undef $_user; - undef $_sudoer; + delete request_cache()->{user}; + delete request_cache()->{sudoer}; # We can't delete from $cgi->cookie, so logincookie data will remain # there. Don't rely on it: use Bugzilla->user->login instead! } -my $_dbh; -my $_dbh_main; -my $_dbh_shadow; sub dbh { my $class = shift; # If we're not connected, then we must want the main db - if (!$_dbh) { - $_dbh = $_dbh_main = Bugzilla::DB::connect_main(); - } + request_cache()->{dbh} ||= request_cache()->{dbh_main} + = Bugzilla::DB::connect_main(); - return $_dbh; + return request_cache()->{dbh}; } -my $_batch; -sub batch { +sub error_mode { my $class = shift; my $newval = shift; if (defined $newval) { - $_batch = $newval; + request_cache()->{error_mode} = $newval; + } + return request_cache()->{error_mode} + || Bugzilla::Constants::ERROR_MODE_WEBPAGE; +} + +sub usage_mode { + my $class = shift; + my $newval = shift; + if (defined $newval) { + if ($newval == USAGE_MODE_BROWSER) { + $class->error_mode(ERROR_MODE_WEBPAGE); + } + elsif ($newval == USAGE_MODE_CMDLINE) { + $class->error_mode(ERROR_MODE_DIE); + } + elsif ($newval == USAGE_MODE_WEBSERVICE) { + $class->error_mode(ERROR_MODE_DIE_SOAP_FAULT); + } + elsif ($newval == USAGE_MODE_EMAIL) { + $class->error_mode(ERROR_MODE_DIE); + } + else { + ThrowCodeError('usage_mode_invalid', + {'invalid_usage_mode', $newval}); + } + request_cache()->{usage_mode} = $newval; + } + return request_cache()->{usage_mode} + || Bugzilla::Constants::USAGE_MODE_BROWSER; +} + +sub installation_mode { + my ($class, $newval) = @_; + ($class->request_cache->{installation_mode} = $newval) if defined $newval; + return $class->request_cache->{installation_mode} + || INSTALLATION_MODE_INTERACTIVE; +} + +sub installation_answers { + my ($class, $filename) = @_; + if ($filename) { + my $s = new Safe; + $s->rdo($filename); + + die "Error reading $filename: $!" if $!; + die "Error evaluating $filename: $@" if $@; + + # Now read the param back out from the sandbox + $class->request_cache->{installation_answers} = $s->varglob('answer'); } - return $_batch || 0; + return $class->request_cache->{installation_answers} || {}; } sub switch_to_shadow_db { my $class = shift; - if (!$_dbh_shadow) { - if (Param('shadowdb')) { - $_dbh_shadow = Bugzilla::DB::connect_shadow(); + if (!request_cache()->{dbh_shadow}) { + if (Bugzilla->params->{'shadowdb'}) { + request_cache()->{dbh_shadow} = Bugzilla::DB::connect_shadow(); } else { - $_dbh_shadow = $_dbh_main; + request_cache()->{dbh_shadow} = request_cache()->{dbh_main}; } } - $_dbh = $_dbh_shadow; - # we have to return $class->dbh instead of $_dbh as - # $_dbh_shadow may be undefined if no shadow DB is used + request_cache()->{dbh} = request_cache()->{dbh_shadow}; + # we have to return $class->dbh instead of {dbh} as + # {dbh_shadow} may be undefined if no shadow DB is used # and no connection to the main DB has been established yet. return $class->dbh; } @@ -269,41 +373,59 @@ sub switch_to_shadow_db { sub switch_to_main_db { my $class = shift; - $_dbh = $_dbh_main; - # We have to return $class->dbh instead of $_dbh as - # $_dbh_main may be undefined if no connection to the main DB + request_cache()->{dbh} = request_cache()->{dbh_main}; + # We have to return $class->dbh instead of {dbh} as + # {dbh_main} may be undefined if no connection to the main DB # has been established yet. return $class->dbh; } +sub get_fields { + my $class = shift; + my $criteria = shift; + # This function may be called during installation, and Field::match + # may fail at that time. so we want to return an empty list in that + # case. + my $fields = eval { Bugzilla::Field->match($criteria) } || []; + return @$fields; +} + +sub custom_field_names { + # Get a list of custom fields and convert it into a list of their names. + return map($_->{name}, + @{Bugzilla::Field->match({ custom=>1, obsolete=>0 })}); +} + +sub hook_args { + my ($class, $args) = @_; + $class->request_cache->{hook_args} = $args if $args; + return $class->request_cache->{hook_args}; +} + +sub request_cache { + if ($ENV{MOD_PERL}) { + require Apache2::RequestUtil; + return Apache2::RequestUtil->request->pnotes(); + } + return $_request_cache; +} + # Private methods # Per process cleanup sub _cleanup { - undef $_cgi; - undef $_user; - - # See bug 192531. If we don't clear the possibly active statement handles, - # then when this is called from the END block, it happens _before_ the - # destructors in Bugzilla::DB have happened. - # See http://rt.perl.org/rt2/Ticket/Display.html?id=17450#38810 - # Without disconnecting explicitly here, noone notices, because DBI::END - # ends up calling DBD::mysql's $drh->disconnect_all, which is a noop. - # This code is evil, but it needs to be done, at least until SendSQL and - # friends can be removed - @Bugzilla::DB::SQLStateStack = (); - undef $Bugzilla::DB::_current_sth; # When we support transactions, need to ->rollback here - $_dbh_main->disconnect if $_dbh_main; - $_dbh_shadow->disconnect if $_dbh_shadow and Param("shadowdb"); - undef $_dbh_main; - undef $_dbh_shadow; - undef $_dbh; + my $main = request_cache()->{dbh_main}; + my $shadow = request_cache()->{dbh_shadow}; + $main->disconnect if $main; + $shadow->disconnect if $shadow && Bugzilla->params->{"shadowdb"}; + undef $_request_cache; } sub END { - _cleanup(); + # Bugzilla.pm cannot compile in mod_perl.pl if this runs. + _cleanup() unless $ENV{MOD_PERL}; } 1; @@ -341,7 +463,7 @@ with mod_perl =item * -Everything is in one central place, so its easy to access, modify, and maintain +Everything is in one central place, so it's easy to access, modify, and maintain =item * @@ -375,6 +497,14 @@ that. The current C<Template> object, to be used for output +=item C<template_inner> + +If you ever need a L<Bugzilla::Template> object while you're already +processing a template, use this. Also use it if you want to specify +the language to use. If no argument is passed, it uses the last +language set. If the argument is "" (empty string), the language is +reset to the current one (the one used by Bugzilla->template). + =item C<cgi> The current C<cgi> object. Note that modules should B<not> be using this in @@ -388,6 +518,12 @@ yet been run. If an sudo session is in progress, the C<Bugzilla::User> corresponding to the person who is being impersonated. If no session is in progress, the current C<Bugzilla::User>. +=item C<set_user> + +Allows you to directly set what L</user> will return. You can use this +if you want to bypass L</login> for some reason and directly "log in" +a specific L<Bugzilla::User>. Be careful with it, though! + =item C<sudoer> C<undef> if there is no currently logged in user, the currently logged in user @@ -432,12 +568,45 @@ Essentially, causes calls to C<Bugzilla-E<gt>user> to return C<undef>. This has effect of logging out a user for the current request only; cookies and database sessions are left intact. -=item C<batch> +=item C<error_mode> + +Call either C<Bugzilla->error_mode(Bugzilla::Constants::ERROR_MODE_DIE)> +or C<Bugzilla->error_mode(Bugzilla::Constants::ERROR_MODE_DIE_SOAP_FAULT)> to +change this flag's default of C<Bugzilla::Constants::ERROR_MODE_WEBPAGE> and to +indicate that errors should be passed to error mode specific error handlers +rather than being sent to a browser and finished with an exit(). + +This is useful, for example, to keep C<eval> blocks from producing wild HTML +on errors, making it easier for you to catch them. +(Remember to reset the error mode to its previous value afterwards, though.) + +C<Bugzilla->error_mode> will return the current state of this flag. + +Note that C<Bugzilla->error_mode> is being called by C<Bugzilla->usage_mode> on +usage mode changes. + +=item C<usage_mode> -Set to true, by calling Bugzilla->batch(1), to indicate that Bugzilla is -being called in a non-interactive manner and errors should be passed to -die() rather than being sent to a browser and finished with an exit(). -Bugzilla->batch will return the current state of this flag. +Call either C<Bugzilla->usage_mode(Bugzilla::Constants::USAGE_MODE_CMDLINE)> +or C<Bugzilla->usage_mode(Bugzilla::Constants::USAGE_MODE_WEBSERVICE)> near the +beginning of your script to change this flag's default of +C<Bugzilla::Constants::USAGE_MODE_BROWSER> and to indicate that Bugzilla is +being called in a non-interactive manner. +This influences error handling because on usage mode changes, C<usage_mode> +calls C<Bugzilla->error_mode> to set an error mode which makes sense for the +usage mode. + +C<Bugzilla->usage_mode> will return the current state of this flag. + +=item C<installation_mode> + +Determines whether or not installation should be silent. See +L<Bugzilla::Constants> for the C<INSTALLATION_MODE> constants. + +=item C<installation_answers> + +Returns a hashref representing any "answers" file passed to F<checksetup.pl>, +used to automatically answer or skip prompts. =item C<dbh> @@ -451,4 +620,15 @@ Switch from using the main database to using the shadow database. Change the database object to refer to the main database. +=item C<params> + +The current Parameters of Bugzilla, as a hashref. If C<data/params> +does not exist, then we return an empty hashref. If C<data/params> +is unreadable or is not valid perl, we C<die>. + +=item C<hook_args> + +If you are running inside a code hook (see L<Bugzilla::Hook>) this +is how you get the arguments passed to the hook. + =back diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm index 6cd539c9c..cf4f475f6 100644 --- a/Bugzilla/Attachment.pm +++ b/Bugzilla/Attachment.pm @@ -19,6 +19,8 @@ # # Contributor(s): Terry Weissman <terry@mozilla.org> # Myk Melez <myk@mozilla.org> +# Marc Schumann <wurblzap@gmail.com> +# Frédéric Buclin <LpSolit@gmail.com> use strict; @@ -46,12 +48,12 @@ that users upload to the Bugzilla server. =cut -# This module requires that its caller have said "require globals.pl" -# to import relevant functions from that script. - +use Bugzilla::Constants; +use Bugzilla::Error; use Bugzilla::Flag; -use Bugzilla::Config qw(:locations); use Bugzilla::User; +use Bugzilla::Util; +use Bugzilla::Field; sub get { my $invocant = shift; @@ -310,7 +312,7 @@ sub data { close(AH); } } - + return $self->{data}; } @@ -339,16 +341,16 @@ sub datasize { # If we have already retrieved the data, return its size. return length($self->{data}) if exists $self->{data}; - ($self->{datasize}) = + $self->{datasize} = Bugzilla->dbh->selectrow_array("SELECT LENGTH(thedata) FROM attach_data WHERE id = ?", - undef, - $self->{id}); + undef, $self->{id}) || 0; - # If there's no attachment data in the database, the attachment - # is stored in a local file, so retrieve its size from the file. - if ($self->{datasize} == 0) { + # If there's no attachment data in the database, either the attachment + # is stored in a local file, and so retrieve its size from the file, + # or the attachment has been deleted. + unless ($self->{datasize}) { if (open(AH, $self->_get_local_filename())) { binmode AH; $self->{datasize} = (stat(AH))[7]; @@ -373,19 +375,97 @@ sub flags { my $self = shift; return $self->{flags} if exists $self->{flags}; - $self->{flags} = Bugzilla::Flag::match({ attach_id => $self->id, - is_active => 1 }); + $self->{flags} = Bugzilla::Flag::match({ 'attach_id' => $self->id }); return $self->{flags}; } -# Instance methods; no POD documentation here yet because the only one so far -# is private. +# Instance methods; no POD documentation here yet because the only ones so far +# are private. sub _get_local_filename { my $self = shift; my $hash = ($self->id % 100) + 100; $hash =~ s/.*(\d\d)$/group.$1/; - return "$attachdir/$hash/attachment." . $self->id; + return bz_locations()->{'attachdir'} . "/$hash/attachment." . $self->id; +} + +sub _validate_filename { + my ($throw_error) = @_; + my $cgi = Bugzilla->cgi; + defined $cgi->upload('data') + || ($throw_error ? ThrowUserError("file_not_specified") : return 0); + + my $filename = $cgi->upload('data'); + + # Remove path info (if any) from the file name. The browser should do this + # for us, but some are buggy. This may not work on Mac file names and could + # mess up file names with slashes in them, but them's the breaks. We only + # use this as a hint to users downloading attachments anyway, so it's not + # a big deal if it munges incorrectly occasionally. + $filename =~ s/^.*[\/\\]//; + + # Truncate the filename to 100 characters, counting from the end of the + # string to make sure we keep the filename extension. + $filename = substr($filename, -100, 100); + + return $filename; +} + +sub _validate_data { + my ($throw_error, $hr_vars) = @_; + my $cgi = Bugzilla->cgi; + my $maxsize = $cgi->param('ispatch') ? Bugzilla->params->{'maxpatchsize'} + : Bugzilla->params->{'maxattachmentsize'}; + $maxsize *= 1024; # Convert from K + my $fh; + # Skip uploading into a local variable if the user wants to upload huge + # attachments into local files. + if (!$cgi->param('bigfile')) { + $fh = $cgi->upload('data'); + } + my $data; + + # We could get away with reading only as much as required, except that then + # we wouldn't have a size to print to the error handler below. + if (!$cgi->param('bigfile')) { + # enable 'slurp' mode + local $/; + $data = <$fh>; + } + + $data + || ($cgi->param('bigfile')) + || ($throw_error ? ThrowUserError("zero_length_file") : return 0); + + # Windows screenshots are usually uncompressed BMP files which + # makes for a quick way to eat up disk space. Let's compress them. + # We do this before we check the size since the uncompressed version + # could easily be greater than maxattachmentsize. + if (Bugzilla->params->{'convert_uncompressed_images'} + && $cgi->param('contenttype') eq 'image/bmp') { + require Image::Magick; + my $img = Image::Magick->new(magick=>'bmp'); + $img->BlobToImage($data); + $img->set(magick=>'png'); + my $imgdata = $img->ImageToBlob(); + $data = $imgdata; + $cgi->param('contenttype', 'image/png'); + $$hr_vars->{'convertedbmp'} = 1; + } + + # Make sure the attachment does not exceed the maximum permitted size + my $len = $data ? length($data) : 0; + if ($maxsize && $len > $maxsize) { + my $vars = { filesize => sprintf("%.0f", $len/1024) }; + if ($cgi->param('ispatch')) { + $throw_error ? ThrowUserError("patch_too_large", $vars) : return 0; + } + else { + $throw_error ? ThrowUserError("file_too_large", $vars) : return 0; + } + } + + return $data || ''; } =pod @@ -404,8 +484,6 @@ Params: C<$bug_id> - integer - the ID of the bug for which Returns: a reference to an array of attachment objects. -=back - =cut sub get_attachments_by_bug { @@ -430,4 +508,374 @@ sub get_attachments_by_bug { return $attachments; } +=pod + +=item C<validate_is_patch()> + +Description: validates the "patch" flag passed in by CGI. + +Returns: 1 on success. + +=cut + +sub validate_is_patch { + my ($class, $throw_error) = @_; + my $cgi = Bugzilla->cgi; + + # Set the ispatch flag to zero if it is undefined, since the UI uses + # an HTML checkbox to represent this flag, and unchecked HTML checkboxes + # do not get sent in HTML requests. + $cgi->param('ispatch', $cgi->param('ispatch') ? 1 : 0); + + # Set the content type to text/plain if the attachment is a patch. + $cgi->param('contenttype', 'text/plain') if $cgi->param('ispatch'); + + return 1; +} + +=pod + +=item C<validate_description()> + +Description: validates the description passed in by CGI. + +Returns: 1 on success. + +=cut + +sub validate_description { + my ($class, $throw_error) = @_; + my $cgi = Bugzilla->cgi; + + $cgi->param('description') + || ($throw_error ? ThrowUserError("missing_attachment_description") : return 0); + + return 1; +} + +=pod + +=item C<validate_content_type()> + +Description: validates the content type passed in by CGI. + +Returns: 1 on success. + +=cut + +sub validate_content_type { + my ($class, $throw_error) = @_; + my $cgi = Bugzilla->cgi; + + if (!defined $cgi->param('contenttypemethod')) { + $throw_error ? ThrowUserError("missing_content_type_method") : return 0; + } + elsif ($cgi->param('contenttypemethod') eq 'autodetect') { + my $contenttype = + $cgi->uploadInfo($cgi->param('data'))->{'Content-Type'}; + # The user asked us to auto-detect the content type, so use the type + # specified in the HTTP request headers. + if ( !$contenttype ) { + $throw_error ? ThrowUserError("missing_content_type") : return 0; + } + $cgi->param('contenttype', $contenttype); + } + elsif ($cgi->param('contenttypemethod') eq 'list') { + # The user selected a content type from the list, so use their + # selection. + $cgi->param('contenttype', $cgi->param('contenttypeselection')); + } + elsif ($cgi->param('contenttypemethod') eq 'manual') { + # The user entered a content type manually, so use their entry. + $cgi->param('contenttype', $cgi->param('contenttypeentry')); + } + else { + $throw_error ? + ThrowCodeError("illegal_content_type_method", + { contenttypemethod => $cgi->param('contenttypemethod') }) : + return 0; + } + + if ( $cgi->param('contenttype') !~ + /^(application|audio|image|message|model|multipart|text|video)\/.+$/ ) { + $throw_error ? + ThrowUserError("invalid_content_type", + { contenttype => $cgi->param('contenttype') }) : + return 0; + } + + return 1; +} + +=pod + +=item C<validate_can_edit($attachment, $product_id)> + +Description: validates if the user is allowed to view and edit the attachment. + Only the submitter or someone with editbugs privs can edit it. + Only the submitter and users in the insider group can view + private attachments. + +Params: $attachment - the attachment object being edited. + $product_id - the product ID the attachment belongs to. + +Returns: 1 on success. Else an error is thrown. + +=cut + +sub validate_can_edit { + my ($attachment, $product_id) = @_; + my $dbh = Bugzilla->dbh; + my $user = Bugzilla->user; + + # Bug 97729 - the submitter can edit their attachments. + return if ($attachment->attacher->id == $user->id); + + # Only users in the insider group can view private attachments. + if ($attachment->isprivate && !$user->is_insider) { + ThrowUserError('illegal_attachment_edit', {attach_id => $attachment->id}); + } + + # Users with editbugs privs can edit all attachments. + return if $user->in_group('editbugs', $product_id); + + # If we come here, then this attachment cannot be seen by the user. + ThrowUserError('illegal_attachment_edit', { attach_id => $attachment->id }); +} + +=item C<validate_obsolete($bug)> + +Description: validates if attachments the user wants to mark as obsolete + really belong to the given bug and are not already obsolete. + Moreover, a user cannot mark an attachment as obsolete if + he cannot view it (due to restrictions on it). + +Params: $bug - The bug object obsolete attachments should belong to. + +Returns: 1 on success. Else an error is thrown. + +=cut + +sub validate_obsolete { + my ($class, $bug) = @_; + my $cgi = Bugzilla->cgi; + + # Make sure the attachment id is valid and the user has permissions to view + # the bug to which it is attached. Make sure also that the user can view + # the attachment itself. + my @obsolete_attachments; + foreach my $attachid ($cgi->param('obsolete')) { + my $vars = {}; + $vars->{'attach_id'} = $attachid; + + detaint_natural($attachid) + || ThrowCodeError('invalid_attach_id_to_obsolete', $vars); + + my $attachment = Bugzilla::Attachment->get($attachid); + + # Make sure the attachment exists in the database. + ThrowUserError('invalid_attach_id', $vars) unless $attachment; + + # Check that the user can view and edit this attachment. + $attachment->validate_can_edit($bug->product_id); + + $vars->{'description'} = $attachment->description; + + if ($attachment->bug_id != $bug->bug_id) { + $vars->{'my_bug_id'} = $bug->bug_id; + $vars->{'attach_bug_id'} = $attachment->bug_id; + ThrowCodeError('mismatched_bug_ids_on_obsolete', $vars); + } + + if ($attachment->isobsolete) { + ThrowCodeError('attachment_already_obsolete', $vars); + } + + push(@obsolete_attachments, $attachment); + } + return @obsolete_attachments; +} + + +=pod + +=item C<insert_attachment_for_bug($throw_error, $bug, $user, $timestamp, $hr_vars)> + +Description: inserts an attachment from CGI input for the given bug. + +Params: C<$bug> - Bugzilla::Bug object - the bug for which to insert + the attachment. + C<$user> - Bugzilla::User object - the user we're inserting an + attachment for. + C<$timestamp> - scalar - timestamp of the insert as returned + by SELECT NOW(). + C<$hr_vars> - hash reference - reference to a hash of template + variables. + +Returns: the ID of the new attachment. + +=back + +=cut + +sub insert_attachment_for_bug { + my ($class, $throw_error, $bug, $user, $timestamp, $hr_vars) = @_; + + my $cgi = Bugzilla->cgi; + my $dbh = Bugzilla->dbh; + my $attachurl = $cgi->param('attachurl') || ''; + my $data; + my $filename; + my $contenttype; + my $isurl; + $class->validate_is_patch($throw_error) || return 0; + $class->validate_description($throw_error) || return 0; + + if (Bugzilla->params->{'allow_attach_url'} + && ($attachurl =~ /^(http|https|ftp):\/\/\S+/) + && !defined $cgi->upload('data')) + { + $filename = ''; + $data = $attachurl; + $isurl = 1; + $contenttype = 'text/plain'; + $cgi->param('ispatch', 0); + $cgi->delete('bigfile'); + } + else { + $filename = _validate_filename($throw_error) || return 0; + # need to validate content type before data as + # we now check the content type for image/bmp in _validate_data() + unless ($cgi->param('ispatch')) { + $class->validate_content_type($throw_error) || return 0; + } + $data = _validate_data($throw_error, $hr_vars); + # If the attachment is stored locally, $data eq ''. + # If an error is thrown, $data eq '0'. + ($data ne '0') || return 0; + $contenttype = $cgi->param('contenttype'); + + # These are inserted using placeholders so no need to panic + trick_taint($filename); + trick_taint($contenttype); + $isurl = 0; + } + + # Check attachments the user tries to mark as obsolete. + my @obsolete_attachments; + if ($cgi->param('obsolete')) { + @obsolete_attachments = $class->validate_obsolete($bug); + } + + # The order of these function calls is important, as Flag::validate + # assumes User::match_field has ensured that the + # values in the requestee fields are legitimate user email addresses. + my $match_status = Bugzilla::User::match_field($cgi, { + '^requestee(_type)?-(\d+)$' => { 'type' => 'multi' }, + }, MATCH_SKIP_CONFIRM); + + $$hr_vars->{'match_field'} = 'requestee'; + if ($match_status == USER_MATCH_FAILED) { + $$hr_vars->{'message'} = 'user_match_failed'; + } + elsif ($match_status == USER_MATCH_MULTIPLE) { + $$hr_vars->{'message'} = 'user_match_multiple'; + } + + # Escape characters in strings that will be used in SQL statements. + my $description = $cgi->param('description'); + trick_taint($description); + my $isprivate = $cgi->param('isprivate') ? 1 : 0; + + # Insert the attachment into the database. + my $sth = $dbh->do( + "INSERT INTO attachments + (bug_id, creation_ts, filename, description, + mimetype, ispatch, isurl, isprivate, submitter_id) + VALUES (?,?,?,?,?,?,?,?,?)", undef, ($bug->bug_id, $timestamp, $filename, + $description, $contenttype, $cgi->param('ispatch'), + $isurl, $isprivate, $user->id)); + # Retrieve the ID of the newly created attachment record. + my $attachid = $dbh->bz_last_key('attachments', 'attach_id'); + + # We only use $data here in this INSERT with a placeholder, + # so it's safe. + $sth = $dbh->prepare("INSERT INTO attach_data + (id, thedata) VALUES ($attachid, ?)"); + trick_taint($data); + $sth->bind_param(1, $data, $dbh->BLOB_TYPE); + $sth->execute(); + + # If the file is to be stored locally, stream the file from the webserver + # to the local file without reading it into a local variable. + if ($cgi->param('bigfile')) { + my $attachdir = bz_locations()->{'attachdir'}; + my $fh = $cgi->upload('data'); + my $hash = ($attachid % 100) + 100; + $hash =~ s/.*(\d\d)$/group.$1/; + mkdir "$attachdir/$hash", 0770; + chmod 0770, "$attachdir/$hash"; + open(AH, ">$attachdir/$hash/attachment.$attachid"); + binmode AH; + my $sizecount = 0; + my $limit = (Bugzilla->params->{"maxlocalattachment"} * 1048576); + while (<$fh>) { + print AH $_; + $sizecount += length($_); + if ($sizecount > $limit) { + close AH; + close $fh; + unlink "$attachdir/$hash/attachment.$attachid"; + $throw_error ? ThrowUserError("local_file_too_large") : return 0; + } + } + close AH; + close $fh; + } + + # Make existing attachments obsolete. + my $fieldid = get_field_id('attachments.isobsolete'); + + foreach my $obsolete_attachment (@obsolete_attachments) { + # If the obsolete attachment has request flags, cancel them. + # This call must be done before updating the 'attachments' table. + Bugzilla::Flag::CancelRequests($bug, $obsolete_attachment, $timestamp); + + $dbh->do('UPDATE attachments SET isobsolete = 1 WHERE attach_id = ?', + undef, $obsolete_attachment->id); + + $dbh->do('INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, + fieldid, removed, added) + VALUES (?,?,?,?,?,?,?)', + undef, ($bug->bug_id, $obsolete_attachment->id, $user->id, + $timestamp, $fieldid, 0, 1)); + } + + my $attachment = Bugzilla::Attachment->get($attachid); + + # 1. Add flags, if any. To avoid dying if something goes wrong + # while processing flags, we will eval() flag validation. + # This requires errors to die(). + # XXX: this can go away as soon as flag validation is able to + # fail without dying. + # + # 2. Flag::validate() should not detect any reference to existing flags + # when creating a new attachment. Setting the third param to -1 will + # force this function to check this point. + my $error_mode_cache = Bugzilla->error_mode; + Bugzilla->error_mode(ERROR_MODE_DIE); + eval { + Bugzilla::Flag::validate($cgi, $bug->bug_id, -1, SKIP_REQUESTEE_ON_ERROR); + Bugzilla::Flag::process($bug, $attachment, $timestamp, $cgi); + }; + Bugzilla->error_mode($error_mode_cache); + if ($@) { + $$hr_vars->{'message'} = 'flag_creation_failed'; + $$hr_vars->{'flag_creation_error'} = $@; + } + + # Return the ID of the new attachment. + return $attachid; +} + 1; diff --git a/Bugzilla/Attachment/CVS/Entries b/Bugzilla/Attachment/CVS/Entries new file mode 100644 index 000000000..f2ad21887 --- /dev/null +++ b/Bugzilla/Attachment/CVS/Entries @@ -0,0 +1,2 @@ +/PatchReader.pm/1.4/Sat Dec 30 01:58:28 2006//TBUGZILLA-3_0 +D diff --git a/Bugzilla/Attachment/CVS/Repository b/Bugzilla/Attachment/CVS/Repository new file mode 100644 index 000000000..758f7a950 --- /dev/null +++ b/Bugzilla/Attachment/CVS/Repository @@ -0,0 +1 @@ +mozilla/webtools/bugzilla/Bugzilla/Attachment diff --git a/Bugzilla/Auth/Login/WWW/CGI/CVS/Root b/Bugzilla/Attachment/CVS/Root similarity index 100% rename from Bugzilla/Auth/Login/WWW/CGI/CVS/Root rename to Bugzilla/Attachment/CVS/Root diff --git a/Bugzilla/Attachment/CVS/Tag b/Bugzilla/Attachment/CVS/Tag new file mode 100644 index 000000000..efdc1ff3e --- /dev/null +++ b/Bugzilla/Attachment/CVS/Tag @@ -0,0 +1 @@ +NBUGZILLA-3_0 diff --git a/Bugzilla/Attachment/PatchReader.pm b/Bugzilla/Attachment/PatchReader.pm new file mode 100644 index 000000000..5dbffb5c9 --- /dev/null +++ b/Bugzilla/Attachment/PatchReader.pm @@ -0,0 +1,273 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): John Keiser <john@johnkeiser.com> +# Frédéric Buclin <LpSolit@gmail.com> + +use strict; + +package Bugzilla::Attachment::PatchReader; + +use Bugzilla::Error; +use Bugzilla::Attachment; + + +sub process_diff { + my ($attachment, $format, $context) = @_; + my $dbh = Bugzilla->dbh; + my $cgi = Bugzilla->cgi; + my $lc = Bugzilla->localconfig; + my $vars = {}; + + my ($reader, $last_reader) = setup_patch_readers(undef, $context); + + if ($format eq 'raw') { + require PatchReader::DiffPrinter::raw; + $last_reader->sends_data_to(new PatchReader::DiffPrinter::raw()); + # Actually print out the patch. + print $cgi->header(-type => 'text/plain', + -expires => '+3M'); + + $reader->iterate_string('Attachment ' . $attachment->id, $attachment->data); + } + else { + my @other_patches = (); + if ($lc->{interdiffbin} && $lc->{diffpath}) { + # Get the list of attachments that the user can view in this bug. + my @attachments = + @{Bugzilla::Attachment->get_attachments_by_bug($attachment->bug_id)}; + # Extract patches only. + @attachments = grep {$_->ispatch == 1} @attachments; + # We want them sorted from newer to older. + @attachments = sort { $b->id <=> $a->id } @attachments; + + # Ignore the current patch, but select the one right before it + # chronologically. + my $select_next_patch = 0; + foreach my $attach (@attachments) { + if ($attach->id == $attachment->id) { + $select_next_patch = 1; + } + else { + push(@other_patches, { 'id' => $attach->id, + 'desc' => $attach->description, + 'selected' => $select_next_patch }); + $select_next_patch = 0; + } + } + } + + $vars->{'bugid'} = $attachment->bug_id; + $vars->{'attachid'} = $attachment->id; + $vars->{'description'} = $attachment->description; + $vars->{'other_patches'} = \@other_patches; + + setup_template_patch_reader($last_reader, $format, $context, $vars); + # Actually print out the patch. + $reader->iterate_string('Attachment ' . $attachment->id, $attachment->data); + } +} + +sub process_interdiff { + my ($old_attachment, $new_attachment, $format, $context) = @_; + my $cgi = Bugzilla->cgi; + my $lc = Bugzilla->localconfig; + my $vars = {}; + + # Get old patch data. + my ($old_filename, $old_file_list) = get_unified_diff($old_attachment); + # Get new patch data. + my ($new_filename, $new_file_list) = get_unified_diff($new_attachment); + + my $warning = warn_if_interdiff_might_fail($old_file_list, $new_file_list); + + # Send through interdiff, send output directly to template. + # Must hack path so that interdiff will work. + $ENV{'PATH'} = $lc->{diffpath}; + open my $interdiff_fh, "$lc->{interdiffbin} $old_filename $new_filename|"; + binmode $interdiff_fh; + my ($reader, $last_reader) = setup_patch_readers("", $context); + + if ($format eq 'raw') { + require PatchReader::DiffPrinter::raw; + $last_reader->sends_data_to(new PatchReader::DiffPrinter::raw()); + # Actually print out the patch. + print $cgi->header(-type => 'text/plain', + -expires => '+3M'); + } + else { + $vars->{'warning'} = $warning if $warning; + $vars->{'bugid'} = $new_attachment->bug_id; + $vars->{'oldid'} = $old_attachment->id; + $vars->{'old_desc'} = $old_attachment->description; + $vars->{'newid'} = $new_attachment->id; + $vars->{'new_desc'} = $new_attachment->description; + + setup_template_patch_reader($last_reader, $format, $context, $vars); + } + $reader->iterate_fh($interdiff_fh, 'interdiff #' . $old_attachment->id . + ' #' . $new_attachment->id); + close $interdiff_fh; + $ENV{'PATH'} = ''; + + # Delete temporary files. + unlink($old_filename) or warn "Could not unlink $old_filename: $!"; + unlink($new_filename) or warn "Could not unlink $new_filename: $!"; +} + +###################### +# Internal routines +###################### + +sub get_unified_diff { + my $attachment = shift; + + # Bring in the modules we need. + require PatchReader::Raw; + require PatchReader::FixPatchRoot; + require PatchReader::DiffPrinter::raw; + require PatchReader::PatchInfoGrabber; + require File::Temp; + + $attachment->ispatch + || ThrowCodeError('must_be_patch', { 'attach_id' => $attachment->id }); + + # Reads in the patch, converting to unified diff in a temp file. + my $reader = new PatchReader::Raw; + my $last_reader = $reader; + + # Fixes patch root (makes canonical if possible). + if (Bugzilla->params->{'cvsroot'}) { + my $fix_patch_root = + new PatchReader::FixPatchRoot(Bugzilla->params->{'cvsroot'}); + $last_reader->sends_data_to($fix_patch_root); + $last_reader = $fix_patch_root; + } + + # Grabs the patch file info. + my $patch_info_grabber = new PatchReader::PatchInfoGrabber(); + $last_reader->sends_data_to($patch_info_grabber); + $last_reader = $patch_info_grabber; + + # Prints out to temporary file. + my ($fh, $filename) = File::Temp::tempfile(); + my $raw_printer = new PatchReader::DiffPrinter::raw($fh); + $last_reader->sends_data_to($raw_printer); + $last_reader = $raw_printer; + + # Iterate! + $reader->iterate_string($attachment->id, $attachment->data); + + return ($filename, $patch_info_grabber->patch_info()->{files}); +} + +sub warn_if_interdiff_might_fail { + my ($old_file_list, $new_file_list) = @_; + + # Verify that the list of files diffed is the same. + my @old_files = sort keys %{$old_file_list}; + my @new_files = sort keys %{$new_file_list}; + if (@old_files != @new_files + || join(' ', @old_files) ne join(' ', @new_files)) + { + return 'interdiff1'; + } + + # Verify that the revisions in the files are the same. + foreach my $file (keys %{$old_file_list}) { + if ($old_file_list->{$file}{old_revision} ne + $new_file_list->{$file}{old_revision}) + { + return 'interdiff2'; + } + } + return undef; +} + +sub setup_patch_readers { + my ($diff_root, $context) = @_; + + # Parameters: + # format=raw|html + # context=patch|file|0-n + # collapsed=0|1 + # headers=0|1 + + # Define the patch readers. + # The reader that reads the patch in (whatever its format). + require PatchReader::Raw; + my $reader = new PatchReader::Raw; + my $last_reader = $reader; + # Fix the patch root if we have a cvs root. + if (Bugzilla->params->{'cvsroot'}) { + require PatchReader::FixPatchRoot; + $last_reader->sends_data_to(new PatchReader::FixPatchRoot(Bugzilla->params->{'cvsroot'})); + $last_reader->sends_data_to->diff_root($diff_root) if defined($diff_root); + $last_reader = $last_reader->sends_data_to; + } + + # Add in cvs context if we have the necessary info to do it + if ($context ne 'patch' && Bugzilla->localconfig->{cvsbin} + && Bugzilla->params->{'cvsroot_get'}) + { + require PatchReader::AddCVSContext; + # We need to set $cvsbin as global, because PatchReader::CVSClient + # needs it in order to find 'cvs'. + $main::cvsbin = Bugzilla->localconfig->{cvsbin}; + $last_reader->sends_data_to( + new PatchReader::AddCVSContext($context, Bugzilla->params->{'cvsroot_get'})); + $last_reader = $last_reader->sends_data_to; + } + + return ($reader, $last_reader); +} + +sub setup_template_patch_reader { + my ($last_reader, $format, $context, $vars) = @_; + my $cgi = Bugzilla->cgi; + my $template = Bugzilla->template; + + require PatchReader::DiffPrinter::template; + + # Define the vars for templates. + if (defined $cgi->param('headers')) { + $vars->{'headers'} = $cgi->param('headers'); + } + else { + $vars->{'headers'} = 1 if !defined $cgi->param('headers'); + } + + $vars->{'collapsed'} = $cgi->param('collapsed'); + $vars->{'context'} = $context; + $vars->{'do_context'} = Bugzilla->localconfig->{cvsbin} + && Bugzilla->params->{'cvsroot_get'} && !$vars->{'newid'}; + + # Print everything out. + print $cgi->header(-type => 'text/html', + -expires => '+3M'); + + $last_reader->sends_data_to(new PatchReader::DiffPrinter::template($template, + "attachment/diff-header.$format.tmpl", + "attachment/diff-file.$format.tmpl", + "attachment/diff-footer.$format.tmpl", + { %{$vars}, + bonsai_url => Bugzilla->params->{'bonsai_url'}, + lxr_url => Bugzilla->params->{'lxr_url'}, + lxr_root => Bugzilla->params->{'lxr_root'}, + })); +} + +1; + +__END__ diff --git a/Bugzilla/Auth.pm b/Bugzilla/Auth.pm index 4ea3d5bd6..74678afa8 100644 --- a/Bugzilla/Auth.pm +++ b/Bugzilla/Auth.pm @@ -19,113 +19,172 @@ # # Contributor(s): Bradley Baetz <bbaetz@acm.org> # Erik Stambaugh <erik@dasbistro.com> +# Max Kanat-Alexander <mkanat@bugzilla.org> package Bugzilla::Auth; use strict; +use fields qw( + _info_getter + _verifier + _persister +); -use Bugzilla::Config; use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::Auth::Login::Stack; +use Bugzilla::Auth::Verify::Stack; +use Bugzilla::Auth::Persist::Cookie; + +sub new { + my ($class, $params) = @_; + my $self = fields::new($class); + + $params ||= {}; + $params->{Login} ||= Bugzilla->params->{'user_info_class'} . ',Cookie'; + $params->{Verify} ||= Bugzilla->params->{'user_verify_class'}; + + $self->{_info_getter} = new Bugzilla::Auth::Login::Stack($params->{Login}); + $self->{_verifier} = new Bugzilla::Auth::Verify::Stack($params->{Verify}); + # If we ever have any other login persistence methods besides cookies, + # this could become more configurable. + $self->{_persister} = new Bugzilla::Auth::Persist::Cookie(); + + return $self; +} -# The verification method that was successfully used upon login, if any -my $current_verify_class = undef; +sub login { + my ($self, $type) = @_; + my $dbh = Bugzilla->dbh; -# 'inherit' from the main verify method -BEGIN { - for my $verifyclass (split /,\s*/, Param("user_verify_class")) { - if ($verifyclass =~ /^([A-Za-z0-9_\.\-]+)$/) { - $verifyclass = $1; - } else { - die "Badly-named user_verify_class '$verifyclass'"; - } - require "Bugzilla/Auth/Verify/" . $verifyclass . ".pm"; - } -} + # Get login info from the cookie, form, environment variables, etc. + my $login_info = $self->{_info_getter}->get_login_info(); -# PRIVATE + if ($login_info->{failure}) { + return $self->_handle_login_result($login_info, $type); + } -# A number of features, like password change requests, require the DB -# verification method to be on the list. -sub has_db { - for (split (/[\s,]+/, Param("user_verify_class"))) { - if (/^DB$/) { - return 1; + # Now verify his username and password against the DB, LDAP, etc. + if ($self->{_info_getter}->{successful}->requires_verification) { + $login_info = $self->{_verifier}->check_credentials($login_info); + if ($login_info->{failure}) { + return $self->_handle_login_result($login_info, $type); } + $login_info = + $self->{_verifier}->{successful}->create_or_update_user($login_info); + } + else { + $login_info = $self->{_verifier}->create_or_update_user($login_info); } - return 0; -} -# Returns the network address for a given IP -sub get_netaddr { - my $ipaddr = shift; + if ($login_info->{failure}) { + return $self->_handle_login_result($login_info, $type); + } - # Check for a valid IPv4 addr which we know how to parse - if (!$ipaddr || $ipaddr !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { - return undef; + # Make sure the user isn't disabled. + my $user = $login_info->{user}; + if ($user->disabledtext) { + return $self->_handle_login_result({ failure => AUTH_DISABLED, + user => $user }, $type); } + $user->set_authorizer($self); + + return $self->_handle_login_result($login_info, $type); +} - my $addr = unpack("N", pack("CCCC", split(/\./, $ipaddr))); +sub can_change_password { + my ($self) = @_; + my $verifier = $self->{_verifier}->{successful}; + $verifier ||= $self->{_verifier}; + my $getter = $self->{_info_getter}->{successful}; + $getter = $self->{_info_getter} + if (!$getter || $getter->isa('Bugzilla::Auth::Login::Cookie')); + return $verifier->can_change_password && + $getter->user_can_create_account; +} - my $maskbits = Param('loginnetmask'); +sub can_login { + my ($self) = @_; + my $getter = $self->{_info_getter}->{successful}; + $getter = $self->{_info_getter} + if (!$getter || $getter->isa('Bugzilla::Auth::Login::Cookie')); + return $getter->can_login; +} - # Make Bugzilla ignore the IP address if loginnetmask is set to 0 - return "0.0.0.0" if ($maskbits == 0); +sub can_logout { + my ($self) = @_; + my $getter = $self->{_info_getter}->{successful}; + # If there's no successful getter, we're not logged in, so of + # course we can't log out! + return 0 unless $getter; + return $getter->can_logout; +} + +sub user_can_create_account { + my ($self) = @_; + my $verifier = $self->{_verifier}->{successful}; + $verifier ||= $self->{_verifier}; + my $getter = $self->{_info_getter}->{successful}; + $getter = $self->{_info_getter} + if (!$getter || $getter->isa('Bugzilla::Auth::Login::Cookie')); + return $verifier->user_can_create_account + && $getter->user_can_create_account; +} - $addr >>= (32-$maskbits); - $addr <<= (32-$maskbits); - return join(".", unpack("CCCC", pack("N", $addr))); +sub can_change_email { + return $_[0]->user_can_create_account; } -# This is a replacement for the inherited authenticate function -# go through each of the available methods for each function -sub authenticate { - my $class = shift; - my @args = @_; - my @firstresult = (); - my @result = (); - my $current_verify_method; - for my $method (split /,\s*/, Param("user_verify_class")) { - $current_verify_method = $method; - $method = "Bugzilla::Auth::Verify::" . $method; - @result = $method->authenticate(@args); - @firstresult = @result unless @firstresult; - - if (($result[0] != AUTH_NODATA)&&($result[0] != AUTH_LOGINFAILED)) { - unshift @result, ($current_verify_method); - return @result; +sub _handle_login_result { + my ($self, $result, $login_type) = @_; + my $dbh = Bugzilla->dbh; + + my $user = $result->{user}; + my $fail_code = $result->{failure}; + + if (!$fail_code) { + if ($self->{_info_getter}->{successful}->requires_persistence) { + $self->{_persister}->persist_login($user); } } - @result = @firstresult; - # no auth match - - # see if we can set $current to the first verify method that - # will allow a new login - - my $chosen_verify_method; - for my $method (split /,\s*/, Param("user_verify_class")) { - $current_verify_method = $method; - $method = "Bugzilla::Auth::Verify::" . $method; - if ($method->can_edit('new')) { - $chosen_verify_method = $method; + elsif ($fail_code == AUTH_ERROR) { + ThrowCodeError($result->{error}, $result->{details}); + } + elsif ($fail_code == AUTH_NODATA) { + if ($login_type == LOGIN_REQUIRED) { + # This seems like as good as time as any to get rid of + # old crufty junk in the logincookies table. Get rid + # of any entry that hasn't been used in a month. + $dbh->do("DELETE FROM logincookies WHERE " . + $dbh->sql_to_days('NOW()') . " - " . + $dbh->sql_to_days('lastused') . " > 30"); + $self->{_info_getter}->fail_nodata($self); } + # Otherwise, we just return the "default" user. + $user = Bugzilla->user; } - - unshift @result, $chosen_verify_method; - return @result; -} - -sub can_edit { - my ($class, $type) = @_; - if ($current_verify_class) { - return $current_verify_class->can_edit($type); + # The username/password may be wrong + # Don't let the user know whether the username exists or whether + # the password was just wrong. (This makes it harder for a cracker + # to find account names by brute force) + elsif (($fail_code == AUTH_LOGINFAILED) || ($fail_code == AUTH_NO_SUCH_USER)) { + ThrowUserError("invalid_username_or_password"); + } + # The account may be disabled + elsif ($fail_code == AUTH_DISABLED) { + $self->{_persister}->logout(); + # XXX This is NOT a good way to do this, architecturally. + $self->{_persister}->clear_browser_cookies(); + # and throw a user error + ThrowUserError("account_disabled", + {'disabled_reason' => $result->{user}->disabledtext}); } - # $current_verify_class will not be set if the user isn't logged in. That - # happens when the user is trying to create a new account, which (for now) - # is hard-coded to work with DB. - elsif (has_db) { - return Bugzilla::Auth::Verify::DB->can_edit($type); + # If we get here, then we've run out of options, which shouldn't happen. + else { + ThrowCodeError("authres_unhandled", { value => $fail_code }); } - return 0; + + return $user; } 1; @@ -134,192 +193,274 @@ __END__ =head1 NAME -Bugzilla::Auth - Authentication handling for Bugzilla users +Bugzilla::Auth - An object that authenticates the login credentials for + a user. =head1 DESCRIPTION Handles authentication for Bugzilla users. Authentication from Bugzilla involves two sets of modules. One set is -used to obtain the data (from CGI, email, etc), and the other set uses -this data to authenticate against the datasource (the Bugzilla DB, LDAP, -cookies, etc). +used to obtain the username/password (from CGI, email, etc), and the +other set uses this data to authenticate against the datasource +(the Bugzilla DB, LDAP, PAM, etc.). + +Modules for obtaining the username/password are subclasses of +L<Bugzilla::Auth::Login>, and modules for authenticating are subclasses +of L<Bugzilla::Auth::Verify>. + +=head1 AUTHENTICATION ERROR CODES + +Whenever a method in the C<Bugzilla::Auth> family fails in some way, +it will return a hashref containing at least a single key called C<failure>. +C<failure> will point to an integer error code, and depending on the error +code the hashref may contain more data. + +The error codes are explained here below. + +=head2 C<AUTH_NODATA> + +Insufficient login data was provided by the user. This may happen in several +cases, such as cookie authentication when the cookie is not present. + +=head2 C<AUTH_ERROR> + +An error occurred when trying to use the login mechanism. + +The hashref will also contain an C<error> element, which is the name +of an error from C<template/en/default/global/code-error.html> -- +the same type of error that would be thrown by +L<Bugzilla::Error::ThrowCodeError>. + +The hashref *may* contain an element called C<details>, which is a hashref +that should be passed to L<Bugzilla::Error::ThrowCodeError> as the +various fields to be used in the error message. + +=head2 C<AUTH_LOGINFAILED> + +An incorrect username or password was given. + +=head2 C<AUTH_NO_SUCH_USER> + +This is an optional more-specific version of C<AUTH_LOGINFAILED>. +Modules should throw this error when they discover that the +requested user account actually does not exist, according to them. -Modules for obtaining the data are located under L<Bugzilla::Auth::Login>, and -modules for authenticating are located in L<Bugzilla::Auth::Verify>. +That is, for example, L<Bugzilla::Auth::Verify::LDAP> would throw +this if the user didn't exist in LDAP. + +The difference between C<AUTH_NO_SUCH_USER> and C<AUTH_LOGINFAILED> +should never be communicated to the user, for security reasons. + +=head2 C<AUTH_DISABLED> + +The user successfully logged in, but their account has been disabled. +Usually this is throw only by C<Bugzilla::Auth::login>. + +=head1 LOGIN TYPES + +The C<login> function (below) can do different types of login, depending +on what constant you pass into it: + +=head2 C<LOGIN_OPTIONAL> + +A login is never required to access this data. Attempting to login is +still useful, because this allows the page to be personalised. Note that +an incorrect login will still trigger an error, even though the lack of +a login will be OK. + +=head2 C<LOGIN_NORMAL> + +A login may or may not be required, depending on the setting of the +I<requirelogin> parameter. This is the default if you don't specify a +type. + +=head2 C<LOGIN_REQUIRED> + +A login is always required to access this data. =head1 METHODS -C<Bugzilla::Auth> contains several helper methods to be used by -authentication or login modules. +These are methods that can be called on a C<Bugzilla::Auth> object +itself. + +=head2 Login =over 4 -=item C<Bugzilla::Auth::get_netaddr($ipaddr)> +=item C<login($type)> -Given an ip address, this returns the associated network address, using -C<Param('loginnetmask')> as the netmask. This can be used to obtain data -in order to restrict weak authentication methods (such as cookies) to -only some addresses. +Description: Logs a user in. For more details on how this works + internally, see the section entitled "STRUCTURE." +Params: $type - One of the Login Types from above. +Returns: An authenticated C<Bugzilla::User>. Or, if the type was + not C<LOGIN_REQUIRED>, then we return an + empty C<Bugzilla::User> if no login data was passed in. =back -=head1 AUTHENTICATION - -Authentication modules check a user's credentials (username, password, -etc) to verify who the user is. The methods that C<Bugzilla::Auth> uses for -authentication are wrappers that check all configured modules (via the -C<Param('user_info_class')> and C<Param('user_verify_class')>) in sequence. +=head2 Info Methods -=head2 METHODS +These are methods that give information about the Bugzilla::Auth object. =over 4 -=item C<authenticate($username, $pass)> +=item C<can_change_password> -This method is passed a username and a password, and returns a list -containing up to four return values, depending on the results of the -authentication. +Description: Tells you whether or not the current login system allows + changing passwords. +Params: None +Returns: C<true> if users and administrators should be allowed to + change passwords, C<false> otherwise. -The first return value is the name of the class that generated the results -constined in the remaining return values. The second return value is one of -the status codes defined in L<Bugzilla::Constants|Bugzilla::Constants> and -described below. The rest of the return values are status code-specific -and are explained in the status code descriptions. +=item C<can_login> -=item C<AUTH_OK> +Description: Tells you whether or not the current login system allows + users to log in through the web interface. +Params: None +Returns: C<true> if users can log in through the web interface, + C<false> otherwise. -Authentication succeeded. The third variable is the userid of the new -user. +=item C<can_logout> -=item C<AUTH_NODATA> +Description: Tells you whether or not the current login system allows + users to log themselves out. +Params: None +Returns: C<true> if users can log themselves out, C<false> otherwise. + If a user isn't logged in, we always return C<false>. -Insufficient login data was provided by the user. This may happen in several -cases, such as cookie authentication when the cookie is not present. +=item C<user_can_create_account> -=item C<AUTH_ERROR> +Description: Tells you whether or not users are allowed to manually create + their own accounts, based on the current login system in use. + Note that this doesn't check the C<createemailregexp> + parameter--you have to do that by yourself in your code. +Params: None +Returns: C<true> if users are allowed to create new Bugzilla accounts, + C<false> otherwise. -An error occurred when trying to use the login mechanism. The third return -value may contain the Bugzilla userid, but will probably be C<undef>, -signifiying that the userid is unknown. The fourth value is a tag describing -the error used by the authentication error templates to print a description -to the user. The optional fifth argument is a hashref of values used as part -of the tag's error descriptions. +=item C<can_change_email> -This error template must have a name/location of -I<account/auth/C<lc(authentication-type)>-error.html.tmpl>. +Description: Whether or not the current login system allows users to + change their own email address. +Params: None +Returns: C<true> if users can change their own email address, + C<false> otherwise. -=item C<AUTH_LOGINFAILED> +=back -An incorrect username or password was given. Note that for security reasons, -both cases return the same error code. However, in the case of a valid -username, the third argument may be the userid. The authentication -mechanism may not always be able to discover the userid if the password is -not known, so whether or not this argument is present is implementation -specific. For security reasons, the presence or lack of a userid value should -not be communicated to the user. +=head1 STRUCTURE -The fourth argument is an optional tag from the authentication server -describing the error. The tag can be used by a template to inform the user -about the error. Similar to C<AUTH_ERROR>, an optional hashref may be -present as a fifth argument, to be used by the tag to give more detailed -information. +This section is mostly interesting to developers who want to implement +a new authentication type. It describes the general structure of the +Bugzilla::Auth family, and how the C<login> function works. -=item C<AUTH_DISABLED> +A C<Bugzilla::Auth> object is essentially a collection of a few other +objects: the "Info Getter," the "Verifier," and the "Persistence +Mechanism." -The user successfully logged in, but their account has been disabled. -The third argument in the returned array is the userid, and the fourth -is some text explaining why the account was disabled. This text would -typically come from the C<disabledtext> field in the C<profiles> table. -Note that this argument is a string, not a tag. +They are used inside the C<login> function in the following order: -=item C<current_verify_class> +=head2 The Info Getter -This scalar gets populated with the full name (eg., -C<Bugzilla::Auth::Verify::DB>) of the verification method being used by the -current user. If no user is logged in, it will contain the name of the first -method that allows new users, if any. Otherwise, it carries an undefined -value. +This is a C<Bugzilla::Auth::Login> object. Basically, it gets the +username and password from the user, somehow. Or, it just gets enough +information to uniquely identify a user, and passes that on down the line. +(For example, a C<user_id> is enough to uniquely identify a user, +even without a username and password.) -=item C<can_edit> +Some Info Getters don't require any verification. For example, if we got +the C<user_id> from a Cookie, we don't need to check the username and +password. -This determines if the user's account details can be modified. It returns a -reference to a hash with the keys C<userid>, C<login_name>, and C<realname>, -which determine whether their respective profile values may be altered, and -C<new>, which determines if new accounts may be created. +If an Info Getter returns only a C<user_id> and no username/password, +then it MUST NOT require verification. If an Info Getter requires +verfication, then it MUST return at least a C<username>. -Each user verification method (chosen with C<Param('user_verify_class')> has -its own set of can_edit values. Calls to can_edit return the appropriate -values for the current user's login method. +=head2 The Verifier -If a user is not logged in, C<can_edit> will contain the values of the first -verify method that allows new users to be created, if available. Otherwise it -returns an empty hash. +This verifies that the username and password are valid. -=back +It's possible that some methods of verification don't require a password. -=head1 LOGINS +=head2 The Persistence Mechanism -A login module can be used to try to log in a Bugzilla user in a -particular way. For example, -L<Bugzilla::Auth::Login::WWW::CGI|Bugzilla::Auth::Login::WWW::CGI> -logs in users from CGI scripts, first by using form variables, and then -by trying cookies as a fallback. +This makes it so that the user doesn't have to log in on every page. +Normally this object just sends a cookie to the user's web browser, +as that's the most common method of "login persistence." -The login interface consists of the following methods: +=head2 Other Things We Do -=over 4 +After we verify the username and password, sometimes we automatically +create an account in the Bugzilla database, for certain authentication +types. We use the "Account Source" to get data about the user, and +create them in the database. (Or, if their data has changed since the +last time they logged in, their data gets updated.) -=item C<login>, which takes a C<$type> argument, using constants found in -C<Bugzilla::Constants>. +=head2 The C<$login_data> Hash -The login method may use various authentication modules (described -above) to try to authenticate a user, and should return the userid on -success, or C<undef> on failure. +All of the C<Bugzilla::Auth::Login> and C<Bugzilla::Auth::Verify> +methods take an argument called C<$login_data>. This is basically +a hash that becomes more and more populated as we go through the +C<login> function. -When a login is required, but data is not present, it is the job of the -login method to prompt the user for this data. +All C<Bugzilla::Auth::Login> and C<Bugzilla::Auth::Verify> methods +also *return* the C<$login_data> structure, when they succeed. They +may have added new data to it. -The constants accepted by C<login> include the following: +For all C<Bugzilla::Auth::Login> and C<Bugzilla::Auth::Verify> methods, +the rule is "you must return the same hashref you were passed in." You can +modify the hashref all you want, but you can't create a new one. The only +time you can return a new one is if you're returning some error code +instead of the C<$login_data> structure. -=item C<LOGIN_OPTIONAL> +Each C<Bugzilla::Auth::Login> or C<Bugzilla::Auth::Verify> method +explains in its documentation which C<$login_data> elements are +required by it, and which are set by it. -A login is never required to access this data. Attempting to login is -still useful, because this allows the page to be personalised. Note that -an incorrect login will still trigger an error, even though the lack of -a login will be OK. +Here are all of the elements that *may* be in C<$login_data>: -=item C<LOGIN_NORMAL> +=over 4 -A login may or may not be required, depending on the setting of the -I<requirelogin> parameter. +=item C<user_id> -=item C<LOGIN_REQUIRED> +A Bugzilla C<user_id> that uniquely identifies a user. -A login is always required to access this data. +=item C<username> -=item C<logout>, which takes a C<Bugzilla::User> argument for the user -being logged out, and an C<$option> argument. Possible values for -C<$option> include: +The username that was provided by the user. -=item C<LOGOUT_CURRENT> +=item C<bz_username> -Log out the user and invalidate his currently registered session. +The username of this user inside of Bugzilla. Sometimes this differs from +C<username>. -=item C<LOGOUT_ALL> +=item C<password> -Log out the user, and invalidate all sessions the user has registered in -Bugzilla. +The password provided by the user. -=item C<LOGOUT_KEEP_CURRENT> +=item C<realname> -Invalidate all sessions the user has registered excluding his current -session; this option should leave the user logged in. This is useful for -user-performed password changes. +The real name of the user. -=back +=item C<extern_id> + +Some string that uniquely identifies the user in an external account +source. If this C<extern_id> already exists in the database with +a different username, the username will be *changed* to be the +username specified in this C<$login_data>. -=head1 SEE ALSO +That is, let's my extern_id is C<mkanat>. I already have an account +in Bugzilla with the username of C<mkanat@foo.com>. But this time, +when I log in, I have an extern_id of C<mkanat> and a C<username> +of C<mkanat@bar.org>. So now, Bugzilla will automatically change my +username to C<mkanat@bar.org> instead of C<mkanat@foo.com>. + +=item C<user> + +A L<Bugzilla::User> object representing the authenticated user. +Note that C<Bugzilla::Auth::login> may modify this object at various points. + +=back -L<Bugzilla::Auth::Login::WWW::CGI>, L<Bugzilla::Auth::Login::WWW::CGI::Cookie>, L<Bugzilla::Auth::Verify::DB> diff --git a/Bugzilla/Auth/CVS/Entries b/Bugzilla/Auth/CVS/Entries index 32cfd9e73..efeb60dba 100644 --- a/Bugzilla/Auth/CVS/Entries +++ b/Bugzilla/Auth/CVS/Entries @@ -1,3 +1,5 @@ -/README/1.2/Thu Jul 29 02:45:38 2004//TBUGZILLA-2_22_3 +/Login.pm/1.1/Fri May 12 02:41:05 2006//TBUGZILLA-3_0 +/Verify.pm/1.6/Fri Oct 20 18:52:24 2006//TBUGZILLA-3_0 D/Login//// +D/Persist//// D/Verify//// diff --git a/Bugzilla/Auth/CVS/Tag b/Bugzilla/Auth/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/Bugzilla/Auth/CVS/Tag +++ b/Bugzilla/Auth/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/Bugzilla/Auth/Login.pm b/Bugzilla/Auth/Login.pm new file mode 100644 index 000000000..4a4c5f26d --- /dev/null +++ b/Bugzilla/Auth/Login.pm @@ -0,0 +1,125 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + +package Bugzilla::Auth::Login; + +use strict; +use fields qw(); + +# Determines whether or not a user can logout. It's really a subroutine, +# but we implement it here as a constant. Override it in subclasses if +# that particular type of login method cannot log out. +use constant can_logout => 1; +use constant can_login => 1; +use constant requires_persistence => 1; +use constant requires_verification => 1; +use constant user_can_create_account => 0; + +sub new { + my ($class) = @_; + my $self = fields::new($class); + return $self; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Auth::Login - Gets username/password data from the user. + +=head1 DESCRIPTION + +Bugzilla::Auth::Login is used to get information that uniquely identifies +a user and allows us to authorize their Bugzilla access. + +It is mostly an abstract class, requiring subclasses to implement +most methods. + +Note that callers outside of the C<Bugzilla::Auth> package should never +create this object directly. Just create a C<Bugzilla::Auth> object +and call C<login> on it. + +=head1 LOGIN METHODS + +These are methods that have to do with getting the actual login data +from the user or handling a login somehow. + +These methods are abstract -- they MUST be implemented by a subclass. + +=over 4 + +=item C<get_login_info()> + +Description: Gets a username/password from the user, or some other + information that uniquely identifies them. +Params: None +Returns: A C<$login_data> hashref. (See L<Bugzilla::Auth> for details.) + The hashref MUST contain: C<user_id> *or* C<username> + If this is a login method that requires verification, + the hashref MUST contain C<password>. + The hashref MAY contain C<realname> and C<extern_id>. + +=item C<fail_nodata()> + +Description: This function is called when Bugzilla doesn't get + a username/password and the login type is C<LOGIN_REQUIRED> + (See L<Bugzilla::Auth> for a description of C<LOGIN_REQUIRED>). + That is, this handles C<AUTH_NODATA> in that situation. + + This function MUST stop CGI execution when it is complete. + That is, it must call C<exit> or C<ThrowUserError> or some + such thing. +Params: None +Returns: Never Returns. + +=back + +=head1 INFO METHODS + +These are methods that describe the capabilities of this +C<Bugzilla::Auth::Login> object. These are all no-parameter +methods that return either C<true> or C<false>. + +=over 4 + +=item C<can_logout> + +Whether or not users can log out if they logged in using this +object. Defaults to C<true>. + +=item C<can_login> + +Whether or not users can log in through the web interface using +this object. Defaults to C<true>. + +=item C<requires_persistence> + +Whether or not we should send the user a cookie if they logged in with +this method. Defaults to C<true>. + +=item C<requires_verification> + +Whether or not we should check the username/password that we +got from this login method. Defaults to C<true>. + +=item C<user_can_create_account> + +Whether or not users can create accounts, if this login method is +currently being used by the system. Defaults to C<false>. + +=back diff --git a/Bugzilla/Auth/Login/CGI.pm b/Bugzilla/Auth/Login/CGI.pm new file mode 100644 index 000000000..2a61a54f7 --- /dev/null +++ b/Bugzilla/Auth/Login/CGI.pm @@ -0,0 +1,81 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): Terry Weissman <terry@mozilla.org> +# Dan Mosedale <dmose@mozilla.org> +# Joe Robins <jmrobins@tgix.com> +# Dave Miller <justdave@syndicomm.com> +# Christopher Aillon <christopher@aillon.com> +# Gervase Markham <gerv@gerv.net> +# Christian Reis <kiko@async.com.br> +# Bradley Baetz <bbaetz@acm.org> +# Erik Stambaugh <erik@dasbistro.com> +# Max Kanat-Alexander <mkanat@bugzilla.org> + +package Bugzilla::Auth::Login::CGI; +use strict; +use base qw(Bugzilla::Auth::Login); +use constant user_can_create_account => 1; + +use Bugzilla::Constants; +use Bugzilla::WebService::Constants; +use Bugzilla::Util; +use Bugzilla::Error; + +sub get_login_info { + my ($self) = @_; + my $cgi = Bugzilla->cgi; + + my $username = trim($cgi->param("Bugzilla_login")); + my $password = $cgi->param("Bugzilla_password"); + + $cgi->delete('Bugzilla_login', 'Bugzilla_password'); + + if (!defined $username || !defined $password) { + return { failure => AUTH_NODATA }; + } + + return { username => $username, password => $password }; +} + +sub fail_nodata { + my ($self) = @_; + my $cgi = Bugzilla->cgi; + my $template = Bugzilla->template; + + if (Bugzilla->error_mode == Bugzilla::Constants::ERROR_MODE_DIE_SOAP_FAULT) { + die SOAP::Fault + ->faultcode(ERROR_AUTH_NODATA) + ->faultstring('Login Required'); + } + + # Redirect to SSL if required + if (Bugzilla->params->{'sslbase'} ne '' + and Bugzilla->params->{'ssl'} ne 'never') + { + $cgi->require_https(Bugzilla->params->{'sslbase'}); + } + print $cgi->header(); + $template->process("account/auth/login.html.tmpl", + { 'target' => $cgi->url(-relative=>1) }) + || ThrowTemplateError($template->error()); + exit; +} + +1; diff --git a/Bugzilla/Auth/Login/CVS/Entries b/Bugzilla/Auth/Login/CVS/Entries index 01737fb34..40b741702 100644 --- a/Bugzilla/Auth/Login/CVS/Entries +++ b/Bugzilla/Auth/Login/CVS/Entries @@ -1,2 +1,5 @@ -/WWW.pm/1.8/Sun Oct 30 21:31:29 2005//TBUGZILLA-2_22_3 -D/WWW//// +/CGI.pm/1.7/Sat Aug 19 17:20:23 2006//TBUGZILLA-3_0 +/Cookie.pm/1.5/Wed Jul 5 23:42:47 2006//TBUGZILLA-3_0 +/Env.pm/1.4/Mon Jul 3 21:42:46 2006//TBUGZILLA-3_0 +/Stack.pm/1.1/Fri May 12 02:41:06 2006//TBUGZILLA-3_0 +D diff --git a/Bugzilla/Auth/Login/CVS/Tag b/Bugzilla/Auth/Login/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/Bugzilla/Auth/Login/CVS/Tag +++ b/Bugzilla/Auth/Login/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/Bugzilla/Auth/Login/Cookie.pm b/Bugzilla/Auth/Login/Cookie.pm new file mode 100644 index 000000000..e2cd8f5ee --- /dev/null +++ b/Bugzilla/Auth/Login/Cookie.pm @@ -0,0 +1,96 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Bradley Baetz <bbaetz@acm.org> +# Max Kanat-Alexander <mkanat@bugzilla.org> + +package Bugzilla::Auth::Login::Cookie; +use strict; +use base qw(Bugzilla::Auth::Login); + +use Bugzilla::Constants; +use Bugzilla::Util; + +use List::Util qw(first); + +use constant requires_persistence => 0; +use constant requires_verification => 0; +use constant can_login => 0; + +# Note that Cookie never consults the Verifier, it always assumes +# it has a valid DB account or it fails. +sub get_login_info { + my ($self) = @_; + my $cgi = Bugzilla->cgi; + my $dbh = Bugzilla->dbh; + + my $ip_addr = $cgi->remote_addr(); + my $net_addr = get_netaddr($ip_addr); + my $login_cookie = $cgi->cookie("Bugzilla_logincookie"); + my $user_id = $cgi->cookie("Bugzilla_login"); + + # If cookies cannot be found, this could mean that they haven't + # been made available yet. In this case, look at Bugzilla_cookie_list. + unless ($login_cookie) { + my $cookie = first {$_->name eq 'Bugzilla_logincookie'} + @{$cgi->{'Bugzilla_cookie_list'}}; + $login_cookie = $cookie->value if $cookie; + } + unless ($user_id) { + my $cookie = first {$_->name eq 'Bugzilla_login'} + @{$cgi->{'Bugzilla_cookie_list'}}; + $user_id = $cookie->value if $cookie; + } + + if ($login_cookie && $user_id) { + # Anything goes for these params - they're just strings which + # we're going to verify against the db + trick_taint($ip_addr); + trick_taint($login_cookie); + detaint_natural($user_id); + + my $query = "SELECT userid + FROM logincookies + WHERE logincookies.cookie = ? + AND logincookies.userid = ? + AND (logincookies.ipaddr = ?"; + + # If we have a network block that's allowed to use this cookie, + # as opposed to just a single IP. + my @params = ($login_cookie, $user_id, $ip_addr); + if (defined $net_addr) { + trick_taint($net_addr); + $query .= " OR logincookies.ipaddr = ?"; + push(@params, $net_addr); + } + $query .= ")"; + + # If the cookie is valid, return a valid username. + if ($dbh->selectrow_array($query, undef, @params)) { + # If we logged in successfully, then update the lastused + # time on the login cookie + $dbh->do("UPDATE logincookies SET lastused = NOW() + WHERE cookie = ?", undef, $login_cookie); + return { user_id => $user_id }; + } + } + + # Either the he cookie is invalid, or we got no cookie. We don't want + # to ever return AUTH_LOGINFAILED, because we don't want Bugzilla to + # actually throw an error when it gets a bad cookie. It should just + # look like there was no cookie to begin with. + return { failure => AUTH_NODATA }; +} + +1; diff --git a/Bugzilla/Auth/Login/Env.pm b/Bugzilla/Auth/Login/Env.pm new file mode 100644 index 000000000..180e79ba7 --- /dev/null +++ b/Bugzilla/Auth/Login/Env.pm @@ -0,0 +1,52 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): Erik Stambaugh <erik@dasbistro.com> +# Max Kanat-Alexander <mkanat@bugzilla.org> + +package Bugzilla::Auth::Login::Env; +use strict; +use base qw(Bugzilla::Auth::Login); + +use Bugzilla::Constants; +use Bugzilla::Error; + +use constant can_logout => 0; +use constant can_login => 0; +use constant requires_verification => 0; + +sub get_login_info { + my ($self) = @_; + my $dbh = Bugzilla->dbh; + + my $env_id = $ENV{Bugzilla->params->{"auth_env_id"}} || ''; + my $env_email = $ENV{Bugzilla->params->{"auth_env_email"}} || ''; + my $env_realname = $ENV{Bugzilla->params->{"auth_env_realname"}} || ''; + + return { failure => AUTH_NODATA } if !$env_email; + + return { username => $env_email, extern_id => $env_id, + realname => $env_realname }; +} + +sub fail_nodata { + ThrowCodeError('env_no_email'); +} + +1; diff --git a/Bugzilla/Auth/Login/Stack.pm b/Bugzilla/Auth/Login/Stack.pm new file mode 100644 index 000000000..d51003861 --- /dev/null +++ b/Bugzilla/Auth/Login/Stack.pm @@ -0,0 +1,87 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + +package Bugzilla::Auth::Login::Stack; +use strict; +use base qw(Bugzilla::Auth::Login); +use fields qw( + _stack + successful +); + +sub new { + my $class = shift; + my $self = $class->SUPER::new(@_); + my $list = shift; + $self->{_stack} = []; + foreach my $login_method (split(',', $list)) { + require "Bugzilla/Auth/Login/${login_method}.pm"; + push(@{$self->{_stack}}, + "Bugzilla::Auth::Login::$login_method"->new(@_)); + } + return $self; +} + +sub get_login_info { + my $self = shift; + my $result; + foreach my $object (@{$self->{_stack}}) { + $result = $object->get_login_info(@_); + $self->{successful} = $object; + last if !$result->{failure}; + # So that if none of them succeed, it's undef. + $self->{successful} = undef; + } + return $result; +} + +sub fail_nodata { + my $self = shift; + # We fail from the bottom of the stack. + my @reverse_stack = reverse @{$self->{_stack}}; + foreach my $object (@reverse_stack) { + # We pick the first object that actually has the method + # implemented. + if ($object->can('fail_nodata')) { + $object->fail_nodata(@_); + } + } +} + +sub can_login { + my ($self) = @_; + # We return true if any method can log in. + foreach my $object (@{$self->{_stack}}) { + return 1 if $object->can_login; + } + return 0; +} + +sub user_can_create_account { + my ($self) = @_; + # We return true if any method allows users to create accounts. + foreach my $object (@{$self->{_stack}}) { + return 1 if $object->user_can_create_account; + } + return 0; +} + +1; diff --git a/Bugzilla/Auth/Login/WWW.pm b/Bugzilla/Auth/Login/WWW.pm deleted file mode 100644 index 29cc7fced..000000000 --- a/Bugzilla/Auth/Login/WWW.pm +++ /dev/null @@ -1,111 +0,0 @@ -# -*- Mode: perl; indent-tabs-mode: nil -*- -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Bugzilla Bug Tracking System. -# -# The Initial Developer of the Original Code is Netscape Communications -# Corporation. Portions created by Netscape are -# Copyright (C) 1998 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): Erik Stambaugh <erik@dasbistro.com> - -package Bugzilla::Auth::Login::WWW; - -use strict; - -use Bugzilla::Constants; -use Bugzilla::Config; - -# $current_login_class stores the name of the login style that succeeded. -my $current_login_class = undef; -sub login_class { - my ($class, $type) = @_; - if ($type) { - $current_login_class = $type; - } - return $current_login_class; -} - -# can_logout determines if a user may log out -sub can_logout { - return 1 if (login_class && login_class->can_logout); - return 0; -} - -sub login { - my ($class, $type) = @_; - - my $user = Bugzilla->user; - - # Avoid double-logins, which may confuse the auth code - # (double cookies, odd compat code settings, etc) - return $user if $user->id; - - $type = LOGIN_REQUIRED if Bugzilla->cgi->param('GoAheadAndLogIn'); - $type = LOGIN_NORMAL unless defined $type; - - # Log in using whatever methods are defined in user_info_class. - # Please note the particularly strange way require() and the function - # calls are being done, because we're calling a module that's named in - # a string. I assure you it works, and it avoids the need for an eval(). - my $userid; - for my $login_class (split(/,\s*/, Param('user_info_class'))) { - require "Bugzilla/Auth/Login/WWW/" . $login_class . ".pm"; - $userid = "Bugzilla::Auth::Login::WWW::$login_class"->login($type); - if ($userid) { - $class->login_class("Bugzilla::Auth::Login::WWW::$login_class"); - last; - } - } - - if ($userid) { - $user = new Bugzilla::User($userid); - - # Redirect to SSL if required - if (Param('sslbase') ne '' and Param('ssl') ne 'never') { - Bugzilla->cgi->require_https(Param('sslbase')); - } - $user->set_flags('can_logout' => $class->can_logout); - } else { - Bugzilla->logout_request(); - } - return $user; -} - -sub logout { - my ($class, $user, $option) = @_; - if (can_logout) { - $class->login_class->logout($user, $option); - } -} - -1; - - -__END__ - -=head1 NAME - -Bugzilla::Auth::Login::WWW - WWW login information gathering module - -=head1 METHODS - -=over - -=item C<login> - -Passes C<login> calls to each class defined in the param C<user_info_class> -and returns a C<Bugzilla::User> object from the first one that successfully -gathers user login information. - -=back diff --git a/Bugzilla/Auth/Login/WWW/CGI.pm b/Bugzilla/Auth/Login/WWW/CGI.pm deleted file mode 100644 index a697a623f..000000000 --- a/Bugzilla/Auth/Login/WWW/CGI.pm +++ /dev/null @@ -1,275 +0,0 @@ -# -*- Mode: perl; indent-tabs-mode: nil -*- -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Bugzilla Bug Tracking System. -# -# The Initial Developer of the Original Code is Netscape Communications -# Corporation. Portions created by Netscape are -# Copyright (C) 1998 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): Terry Weissman <terry@mozilla.org> -# Dan Mosedale <dmose@mozilla.org> -# Joe Robins <jmrobins@tgix.com> -# Dave Miller <justdave@syndicomm.com> -# Christopher Aillon <christopher@aillon.com> -# Gervase Markham <gerv@gerv.net> -# Christian Reis <kiko@async.com.br> -# Bradley Baetz <bbaetz@acm.org> -# Erik Stambaugh <erik@dasbistro.com> - -package Bugzilla::Auth::Login::WWW::CGI; - -use strict; - -use Bugzilla::Config; -use Bugzilla::Constants; -use Bugzilla::Error; -use Bugzilla::Util; -use Bugzilla::Token; - -sub login { - my ($class, $type) = @_; - - # 'NORMAL' logins depend on the 'requirelogin' param - if ($type == LOGIN_NORMAL) { - $type = Param('requirelogin') ? LOGIN_REQUIRED : LOGIN_OPTIONAL; - } - - my $cgi = Bugzilla->cgi; - my $dbh = Bugzilla->dbh; - - # First, try the actual login method against form variables - my $username = $cgi->param("Bugzilla_login"); - my $passwd = $cgi->param("Bugzilla_password"); - - $cgi->delete('Bugzilla_login', 'Bugzilla_password'); - - # Perform the actual authentication, get the method name from the class name - my ($authmethod, $authres, $userid, $extra, $info) = - Bugzilla::Auth->authenticate($username, $passwd); - - if ($authres == AUTH_OK) { - # Login via username/password was correct and valid, so create - # and send out the login cookies - my $ipaddr = $cgi->remote_addr; - unless ($cgi->param('Bugzilla_restrictlogin') || - Param('loginnetmask') == 32) { - $ipaddr = Bugzilla::Auth::get_netaddr($ipaddr); - } - - # The IP address is valid, at least for comparing with itself in a - # subsequent login - trick_taint($ipaddr); - - my $logincookie = Bugzilla::Token::GenerateUniqueToken('logincookies', 'cookie'); - - $dbh->do("INSERT INTO logincookies (cookie, userid, ipaddr, lastused) - VALUES (?, ?, ?, NOW())", - undef, - $logincookie, $userid, $ipaddr); - - # Remember cookie only if admin has told so - # or admin didn't forbid it and user told to remember. - if ((Param('rememberlogin') eq 'on') || - ((Param('rememberlogin') ne 'off') && - $cgi->param('Bugzilla_remember') && - ($cgi->param('Bugzilla_remember') eq 'on'))) { - $cgi->send_cookie(-name => 'Bugzilla_login', - -value => $userid, - -expires => 'Fri, 01-Jan-2038 00:00:00 GMT'); - $cgi->send_cookie(-name => 'Bugzilla_logincookie', - -value => $logincookie, - -expires => 'Fri, 01-Jan-2038 00:00:00 GMT'); - - } - else { - $cgi->send_cookie(-name => 'Bugzilla_login', - -value => $userid); - $cgi->send_cookie(-name => 'Bugzilla_logincookie', - -value => $logincookie); - } - } - elsif ($authres == AUTH_NODATA) { - # No data from the form, so try to login via cookies - $username = $cgi->cookie("Bugzilla_login"); - $passwd = $cgi->cookie("Bugzilla_logincookie"); - - require Bugzilla::Auth::Login::WWW::CGI::Cookie; - my $authmethod = "Cookie"; - - ($authres, $userid, $extra) = - Bugzilla::Auth::Login::WWW::CGI::Cookie->authenticate($username, $passwd); - - # If the data for the cookie was incorrect, then treat that as - # NODATA. This could occur if the user's IP changed, for example. - # Give them un-loggedin access if allowed (checked below) - $authres = AUTH_NODATA if $authres == AUTH_LOGINFAILED; - } - - # Now check the result - - # An error may have occurred with the login mechanism - if ($authres == AUTH_ERROR) { - ThrowCodeError("auth_err", - { authmethod => lc($authmethod), - userid => $userid, - auth_err_tag => $extra, - info => $info - }); - } - - # We can load the page if the login was ok, or there was no data - # but a login wasn't required - if ($authres == AUTH_OK || - ($authres == AUTH_NODATA && $type == LOGIN_OPTIONAL)) { - - # login succeded, so we're done - return $userid; - } - - # No login details were given, but we require a login if the - # page does - if ($authres == AUTH_NODATA && $type == LOGIN_REQUIRED) { - - # Redirect to SSL if required - if (Param('sslbase') ne '' and Param('ssl') ne 'never') { - $cgi->require_https(Param('sslbase')); - } - - # Throw up the login page - - print Bugzilla->cgi->header(); - - my $template = Bugzilla->template; - $template->process("account/auth/login.html.tmpl", - { 'target' => $cgi->url(-relative=>1), - 'caneditaccount' => Bugzilla::Auth->can_edit('new'), - 'has_db' => Bugzilla::Auth->has_db, - } - ) - || ThrowTemplateError($template->error()); - - # This seems like as good as time as any to get rid of old - # crufty junk in the logincookies table. Get rid of any entry - # that hasn't been used in a month. - $dbh->do("DELETE FROM logincookies WHERE " . - $dbh->sql_to_days('NOW()') . " - " . - $dbh->sql_to_days('lastused') . " > 30"); - - exit; - } - - # The username/password may be wrong - # Don't let the user know whether the username exists or whether - # the password was just wrong. (This makes it harder for a cracker - # to find account names by brute force) - if ($authres == AUTH_LOGINFAILED) { - ThrowUserError("invalid_username_or_password"); - } - - # The account may be disabled - if ($authres == AUTH_DISABLED) { - clear_browser_cookies(); - # and throw a user error - ThrowUserError("account_disabled", - {'disabled_reason' => $extra}); - } - - # If we get here, then we've run out of options, which shouldn't happen - ThrowCodeError("authres_unhandled", { authres => $authres, - type => $type }); -} - -# This auth style allows the user to log out. -sub can_logout { return 1; } - -# Logs user out, according to the option provided; this consists of -# removing entries from logincookies for the specified $user. -sub logout { - my ($class, $user, $option) = @_; - my $dbh = Bugzilla->dbh; - my $cgi = Bugzilla->cgi; - $option = LOGOUT_ALL unless defined $option; - - if ($option == LOGOUT_ALL) { - $dbh->do("DELETE FROM logincookies WHERE userid = ?", - undef, $user->id); - return; - } - - # The LOGOUT_*_CURRENT options require the current login cookie. - # If a new cookie has been issued during this run, that's the current one. - # If not, it's the one we've received. - my $cookie; - foreach (@{$cgi->{'Bugzilla_cookie_list'}}) { - if ($_->name() eq 'Bugzilla_logincookie') { - $cookie = $_->value(); - last; - } - } - $cookie ||= $cgi->cookie("Bugzilla_logincookie"); - trick_taint($cookie); - - # These queries use both the cookie ID and the user ID as keys. Even - # though we know the userid must match, we still check it in the SQL - # as a sanity check, since there is no locking here, and if the user - # logged out from two machines simultaneously, while someone else - # logged in and got the same cookie, we could be logging the other - # user out here. Yes, this is very very very unlikely, but why take - # chances? - bbaetz - if ($option == LOGOUT_KEEP_CURRENT) { - $dbh->do("DELETE FROM logincookies WHERE cookie != ? AND userid = ?", - undef, $cookie, $user->id); - } elsif ($option == LOGOUT_CURRENT) { - $dbh->do("DELETE FROM logincookies WHERE cookie = ? AND userid = ?", - undef, $cookie, $user->id); - } else { - die("Invalid option $option supplied to logout()"); - } - - if ($option != LOGOUT_KEEP_CURRENT) { - clear_browser_cookies(); - Bugzilla->logout_request(); - } -} - -sub clear_browser_cookies { - my $cgi = Bugzilla->cgi; - $cgi->remove_cookie('Bugzilla_login'); - $cgi->remove_cookie('Bugzilla_logincookie'); -} - -1; - -__END__ - -=head1 NAME - -Bugzilla::Auth::Login::WWW::CGI - CGI-based logins for Bugzilla - -=head1 SUMMARY - -This is a L<login module|Bugzilla::Auth/"LOGIN"> for Bugzilla. Users connecting -from a CGI script use this module to authenticate. Logouts are also handled here. - -=head1 BEHAVIOUR - -Users are first authenticated against the default authentication handler, -using the CGI parameters I<Bugzilla_login> and I<Bugzilla_password>. - -If no data is present for that, then cookies are tried, using -L<Bugzilla::Auth::Login::WWW::CGI::Cookie>. - -=head1 SEE ALSO - -L<Bugzilla::Auth> diff --git a/Bugzilla/Auth/Login/WWW/CGI/CVS/Entries b/Bugzilla/Auth/Login/WWW/CGI/CVS/Entries deleted file mode 100644 index 771377cc4..000000000 --- a/Bugzilla/Auth/Login/WWW/CGI/CVS/Entries +++ /dev/null @@ -1,2 +0,0 @@ -/Cookie.pm/1.3/Tue Mar 22 22:41:07 2005//TBUGZILLA-2_22_3 -D diff --git a/Bugzilla/Auth/Login/WWW/CGI/CVS/Repository b/Bugzilla/Auth/Login/WWW/CGI/CVS/Repository deleted file mode 100644 index 53e03edcc..000000000 --- a/Bugzilla/Auth/Login/WWW/CGI/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -mozilla/webtools/bugzilla/Bugzilla/Auth/Login/WWW/CGI diff --git a/Bugzilla/Auth/Login/WWW/CGI/CVS/Tag b/Bugzilla/Auth/Login/WWW/CGI/CVS/Tag deleted file mode 100644 index cb27bf8df..000000000 --- a/Bugzilla/Auth/Login/WWW/CGI/CVS/Tag +++ /dev/null @@ -1 +0,0 @@ -NBUGZILLA-2_22_3 diff --git a/Bugzilla/Auth/Login/WWW/CGI/Cookie.pm b/Bugzilla/Auth/Login/WWW/CGI/Cookie.pm deleted file mode 100644 index c2244d15d..000000000 --- a/Bugzilla/Auth/Login/WWW/CGI/Cookie.pm +++ /dev/null @@ -1,113 +0,0 @@ -# -*- Mode: perl; indent-tabs-mode: nil -*- -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Bugzilla Bug Tracking System. -# -# The Initial Developer of the Original Code is Netscape Communications -# Corporation. Portions created by Netscape are -# Copyright (C) 1998 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): Terry Weissman <terry@mozilla.org> -# Dan Mosedale <dmose@mozilla.org> -# Joe Robins <jmrobins@tgix.com> -# Dave Miller <justdave@syndicomm.com> -# Christopher Aillon <christopher@aillon.com> -# Gervase Markham <gerv@gerv.net> -# Christian Reis <kiko@async.com.br> -# Bradley Baetz <bbaetz@acm.org> - -package Bugzilla::Auth::Login::WWW::CGI::Cookie; - -use strict; - -use Bugzilla::Auth; -use Bugzilla::Config; -use Bugzilla::Constants; -use Bugzilla::Util; - -sub authenticate { - my ($class, $login, $login_cookie) = @_; - - return (AUTH_NODATA) unless defined $login && defined $login_cookie; - - my $cgi = Bugzilla->cgi; - - my $ipaddr = $cgi->remote_addr(); - my $netaddr = Bugzilla::Auth::get_netaddr($ipaddr); - - # Anything goes for these params - they're just strings which - # we're going to verify against the db - trick_taint($login); - trick_taint($login_cookie); - trick_taint($ipaddr); - - my $query = "SELECT profiles.userid, profiles.disabledtext " . - "FROM logincookies, profiles " . - "WHERE logincookies.cookie=? AND " . - " logincookies.userid=profiles.userid AND " . - " logincookies.userid=? AND " . - " (logincookies.ipaddr=?"; - my @params = ($login_cookie, $login, $ipaddr); - if (defined $netaddr) { - trick_taint($netaddr); - $query .= " OR logincookies.ipaddr=?"; - push(@params, $netaddr); - } - $query .= ")"; - - my $dbh = Bugzilla->dbh; - my ($userid, $disabledtext) = $dbh->selectrow_array($query, undef, @params); - - return (AUTH_DISABLED, $userid, $disabledtext) - if ($disabledtext); - - if ($userid) { - # If we logged in successfully, then update the lastused time on the - # login cookie - $dbh->do("UPDATE logincookies SET lastused=NOW() WHERE cookie=?", - undef, - $login_cookie); - - return (AUTH_OK, $userid); - } - - # If we get here, then the login failed. - return (AUTH_LOGINFAILED); -} - -1; - -__END__ - -=head1 NAME - -Bugzilla::Auth::Login::WWW::CGI::Cookie - cookie authentication for Bugzilla - -=head1 SUMMARY - -This is an L<authentication module|Bugzilla::Auth/"AUTHENTICATION"> for -Bugzilla, which logs the user in using a persistent cookie stored in the -C<logincookies> table. - -The actual password is not stored in the cookie; only the userid and a -I<logincookie> (which is used to reverify the login without requiring the -password to be sent over the network) are. These I<logincookies> are -restricted to certain IP addresses as a security meaure. The exact -restriction can be specified by the admin via the C<loginnetmask> parameter. - -This module does not ever send a cookie (It has no way of knowing when a user -is successfully logged in). Instead L<Bugzilla::Auth::Login::WWW::CGI> handles this. - -=head1 SEE ALSO - -L<Bugzilla::Auth>, L<Bugzilla::Auth::Login::WWW::CGI> diff --git a/Bugzilla/Auth/Login/WWW/CVS/Entries b/Bugzilla/Auth/Login/WWW/CVS/Entries deleted file mode 100644 index 4645c7ae2..000000000 --- a/Bugzilla/Auth/Login/WWW/CVS/Entries +++ /dev/null @@ -1,3 +0,0 @@ -/CGI.pm/1.16/Mon Jan 9 19:07:25 2006//TBUGZILLA-2_22_3 -/Env.pm/1.6.2.1/Tue Feb 21 16:15:41 2006//TBUGZILLA-2_22_3 -D/CGI//// diff --git a/Bugzilla/Auth/Login/WWW/CVS/Repository b/Bugzilla/Auth/Login/WWW/CVS/Repository deleted file mode 100644 index 0dedce912..000000000 --- a/Bugzilla/Auth/Login/WWW/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -mozilla/webtools/bugzilla/Bugzilla/Auth/Login/WWW diff --git a/Bugzilla/Auth/Login/WWW/CVS/Tag b/Bugzilla/Auth/Login/WWW/CVS/Tag deleted file mode 100644 index cb27bf8df..000000000 --- a/Bugzilla/Auth/Login/WWW/CVS/Tag +++ /dev/null @@ -1 +0,0 @@ -NBUGZILLA-2_22_3 diff --git a/Bugzilla/Auth/Login/WWW/Env.pm b/Bugzilla/Auth/Login/WWW/Env.pm deleted file mode 100644 index f1f72ca30..000000000 --- a/Bugzilla/Auth/Login/WWW/Env.pm +++ /dev/null @@ -1,192 +0,0 @@ -# -*- Mode: perl; indent-tabs-mode: nil -*- -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Bugzilla Bug Tracking System. -# -# The Initial Developer of the Original Code is Netscape Communications -# Corporation. Portions created by Netscape are -# Copyright (C) 1998 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): Erik Stambaugh <erik@dasbistro.com> - -package Bugzilla::Auth::Login::WWW::Env; - -use strict; - -use Bugzilla::Config; -use Bugzilla::Error; -use Bugzilla::Util; -use Bugzilla::User; - -sub login { - my ($class, $type) = @_; - - # XXX This does not currently work correctly with Param('requirelogin'). - # Bug 253636 will hopefully see that param's needs taken care of in a - # parent module, but for the time being, this module does not honor - # the param in the way that CGI.pm does. - - my $matched_userid = ''; - my $matched_extern_id = ''; - my $disabledtext = ''; - my $new_login_name = 0; - - my $dbh = Bugzilla->dbh; - my $sth; - - # Gather the environment variables - my $env_id = $ENV{Param("auth_env_id")}; - my $env_email = $ENV{Param("auth_env_email")}; - my $env_realname = $ENV{Param("auth_env_realname")}; - - # allow undefined values to work with trick_taint - for ($env_id, $env_email, $env_realname) { $_ ||= '' }; - # make sure the email field contains only a valid email address - my $emailregexp = Param("emailregexp"); - if ($env_email =~ /($emailregexp)/) { - $env_email = $1; - } - else { - return undef; - } - # untaint the remaining values - trick_taint($env_id); - trick_taint($env_realname); - - if ($env_id || $env_email) { - # Look in the DB for the extern_id - if ($env_id) { - - # Not having the email address defined but having an ID isn't - # allowed. - return undef unless $env_email; - - $sth = $dbh->prepare("SELECT userid, disabledtext " . - "FROM profiles WHERE extern_id=?"); - $sth->execute($env_id); - my $fetched = $sth->fetch; - if ($fetched) { - $matched_userid = $fetched->[0]; - $disabledtext = $fetched->[1]; - } - } - - unless ($matched_userid) { - # There was either no match for the external ID given, or one was - # not present. - # - # Check to see if the email address is in there and has no - # external id assigned. We test for both the login name (which we - # also sent), and the id, so that we have a way of telling that we - # got something instead of a bunch of NULLs - $sth = $dbh->prepare("SELECT extern_id, userid, disabledtext " . - "FROM profiles WHERE " . - $dbh->sql_istrcmp('login_name', '?')); - $sth->execute($env_email); - - $sth->execute(); - my $fetched = $sth->fetch(); - if ($fetched) { - ($matched_extern_id, $matched_userid, $disabledtext) = @{$fetched}; - } - if ($matched_userid) { - if ($matched_extern_id) { - # someone with a different external ID has that address! - ThrowUserError("extern_id_conflict"); - } - else - { - # someone with no external ID used that address, time to - # add the ID! - $sth = $dbh->prepare("UPDATE profiles " . - "SET extern_id=? WHERE userid=?"); - $sth->execute($env_id, $matched_userid); - } - } - else - { - # Need to create a new user with that email address. Note - # that cryptpassword has been filled in with '*', since the - # user has no DB password. - insert_new_user($env_email, $env_realname, '*'); - my $new_user = Bugzilla::User->new_from_login($env_email); - $matched_userid = $new_user->id; - $new_login_name = $matched_userid; - } - } - } - - # now that we hopefully have a username, we need to see if the data - # has to be updated - if ($matched_userid) { - $sth = $dbh->prepare("SELECT login_name, realname " . - "FROM profiles " . - "WHERE userid=?"); - $sth->execute($matched_userid); - my $fetched = $sth->fetch; - my $username = $fetched->[0]; - my $this_realname = $fetched->[1]; - if ( ($username ne $env_email) || - ($this_realname ne $env_realname) ) { - - $sth = $dbh->prepare("UPDATE profiles " . - "SET login_name=?, " . - "realname=? " . - "WHERE userid=?"); - $sth->execute($env_email, - ($env_realname || $this_realname), - $matched_userid); - $sth->execute; - $new_login_name = $matched_userid; - } - } - - # If the login name may be new, make sure the regexp groups are current - if ($new_login_name) { - my $userprofile = new Bugzilla::User($matched_userid); - $userprofile->derive_regexp_groups; - } - - # Now we throw an error if the user has been disabled - if ($disabledtext) { - ThrowUserError("account_disabled", - {'disabled_reason' => $disabledtext}); - } - - return $matched_userid; - -} - -# This auth style does not allow the user to log out. -sub can_logout { return 0; } - -1; - -__END__ - -=head1 NAME - -Bugzilla::Auth::Env - Environment Variable Authentication - -=head1 DESCRIPTION - -Many external user authentication systems supply login information to CGI -programs via environment variables. This module checks to see if those -variables are populated and, if so, assumes authentication was successful and -returns the user's ID, having automatically created a new profile if -necessary. - -=head1 SEE ALSO - -L<Bugzilla::Auth> - diff --git a/Bugzilla/Auth/Persist/CVS/Entries b/Bugzilla/Auth/Persist/CVS/Entries new file mode 100644 index 000000000..0d795ef3c --- /dev/null +++ b/Bugzilla/Auth/Persist/CVS/Entries @@ -0,0 +1,2 @@ +/Cookie.pm/1.5/Mon Jul 3 21:42:46 2006//TBUGZILLA-3_0 +D diff --git a/Bugzilla/Auth/Persist/CVS/Repository b/Bugzilla/Auth/Persist/CVS/Repository new file mode 100644 index 000000000..63e425d24 --- /dev/null +++ b/Bugzilla/Auth/Persist/CVS/Repository @@ -0,0 +1 @@ +mozilla/webtools/bugzilla/Bugzilla/Auth/Persist diff --git a/Bugzilla/Auth/Login/WWW/CVS/Root b/Bugzilla/Auth/Persist/CVS/Root similarity index 100% rename from Bugzilla/Auth/Login/WWW/CVS/Root rename to Bugzilla/Auth/Persist/CVS/Root diff --git a/Bugzilla/Auth/Persist/CVS/Tag b/Bugzilla/Auth/Persist/CVS/Tag new file mode 100644 index 000000000..efdc1ff3e --- /dev/null +++ b/Bugzilla/Auth/Persist/CVS/Tag @@ -0,0 +1 @@ +NBUGZILLA-3_0 diff --git a/Bugzilla/Auth/Persist/Cookie.pm b/Bugzilla/Auth/Persist/Cookie.pm new file mode 100644 index 000000000..3faa892ae --- /dev/null +++ b/Bugzilla/Auth/Persist/Cookie.pm @@ -0,0 +1,151 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): Terry Weissman <terry@mozilla.org> +# Dan Mosedale <dmose@mozilla.org> +# Joe Robins <jmrobins@tgix.com> +# Dave Miller <justdave@syndicomm.com> +# Christopher Aillon <christopher@aillon.com> +# Gervase Markham <gerv@gerv.net> +# Christian Reis <kiko@async.com.br> +# Bradley Baetz <bbaetz@acm.org> +# Erik Stambaugh <erik@dasbistro.com> +# Max Kanat-Alexander <mkanat@bugzilla.org> + +package Bugzilla::Auth::Persist::Cookie; +use strict; +use fields qw(); + +use Bugzilla::Constants; +use Bugzilla::Util; +use Bugzilla::Token; + +use List::Util qw(first); + +sub new { + my ($class) = @_; + my $self = fields::new($class); + return $self; +} + +sub persist_login { + my ($self, $user) = @_; + my $dbh = Bugzilla->dbh; + my $cgi = Bugzilla->cgi; + + my $ip_addr = $cgi->remote_addr; + unless ($cgi->param('Bugzilla_restrictlogin') || + Bugzilla->params->{'loginnetmask'} == 32) + { + $ip_addr = get_netaddr($ip_addr); + } + + # The IP address is valid, at least for comparing with itself in a + # subsequent login + trick_taint($ip_addr); + + my $login_cookie = + Bugzilla::Token::GenerateUniqueToken('logincookies', 'cookie'); + + $dbh->do("INSERT INTO logincookies (cookie, userid, ipaddr, lastused) + VALUES (?, ?, ?, NOW())", + undef, $login_cookie, $user->id, $ip_addr); + + # Remember cookie only if admin has told so + # or admin didn't forbid it and user told to remember. + if ( Bugzilla->params->{'rememberlogin'} eq 'on' || + (Bugzilla->params->{'rememberlogin'} ne 'off' && + $cgi->param('Bugzilla_remember') && + $cgi->param('Bugzilla_remember') eq 'on') ) + { + $cgi->send_cookie(-name => 'Bugzilla_login', + -value => $user->id, + -expires => 'Fri, 01-Jan-2038 00:00:00 GMT'); + $cgi->send_cookie(-name => 'Bugzilla_logincookie', + -value => $login_cookie, + -expires => 'Fri, 01-Jan-2038 00:00:00 GMT'); + + } + else { + $cgi->send_cookie(-name => 'Bugzilla_login', + -value => $user->id); + $cgi->send_cookie(-name => 'Bugzilla_logincookie', + -value => $login_cookie); + } +} + +sub logout { + my ($self, $param) = @_; + + my $dbh = Bugzilla->dbh; + my $cgi = Bugzilla->cgi; + $param = {} unless $param; + my $user = $param->{user} || Bugzilla->user; + my $type = $param->{type} || LOGOUT_ALL; + + if ($type == LOGOUT_ALL) { + $dbh->do("DELETE FROM logincookies WHERE userid = ?", + undef, $user->id); + return; + } + + # The LOGOUT_*_CURRENT options require the current login cookie. + # If a new cookie has been issued during this run, that's the current one. + # If not, it's the one we've received. + my $cookie = first {$_->name eq 'Bugzilla_logincookie'} + @{$cgi->{'Bugzilla_cookie_list'}}; + my $login_cookie; + if ($cookie) { + $login_cookie = $cookie->value; + } + else { + $login_cookie = $cgi->cookie("Bugzilla_logincookie"); + } + trick_taint($login_cookie); + + # These queries use both the cookie ID and the user ID as keys. Even + # though we know the userid must match, we still check it in the SQL + # as a sanity check, since there is no locking here, and if the user + # logged out from two machines simultaneously, while someone else + # logged in and got the same cookie, we could be logging the other + # user out here. Yes, this is very very very unlikely, but why take + # chances? - bbaetz + if ($type == LOGOUT_KEEP_CURRENT) { + $dbh->do("DELETE FROM logincookies WHERE cookie != ? AND userid = ?", + undef, $login_cookie, $user->id); + } elsif ($type == LOGOUT_CURRENT) { + $dbh->do("DELETE FROM logincookies WHERE cookie = ? AND userid = ?", + undef, $login_cookie, $user->id); + } else { + die("Invalid type $type supplied to logout()"); + } + + if ($type != LOGOUT_KEEP_CURRENT) { + clear_browser_cookies(); + } + +} + +sub clear_browser_cookies { + my $cgi = Bugzilla->cgi; + $cgi->remove_cookie('Bugzilla_login'); + $cgi->remove_cookie('Bugzilla_logincookie'); +} + +1; diff --git a/Bugzilla/Auth/README b/Bugzilla/Auth/README deleted file mode 100644 index e573e2c0b..000000000 --- a/Bugzilla/Auth/README +++ /dev/null @@ -1,132 +0,0 @@ -How Auth Works -============== -Christian Reis <kiko@async.com.br> - -Overview --------- - -Authentication in Bugzilla is handled by a collection of modules that live in -the Bugzilla::Auth package. These modules are organized hierarchically based -upon their responsibility. - -The authentication scheme is divided in two tasks: Login and Verify. Login -involves gathering credentials from a user, while Verify validates them -against an authentication service. - -The Bugzilla parameters user_info_class and user_verify_class contain a -list of Login and Verify modules, respectively. - -Task: Login ------------ - -This task obtains user credentials based on a request. Examples of requests -include CGI access from the Bugzilla web interface, email submissions and -credentials supplied by standalone scripts. - -Each type of Bugzilla front-end should have its own package. For instance, -access via the Bugzilla web pages should go through Bugzilla::Auth::WWW. -These packages would contain modules of their own to perform whatever extra -functions are needed, like the CGI and Cookie modules in the case of WWW. - -Task: Verify ------------- - -This task validates user credentials against a user authentication service. - -The default service in Bugzilla has been the database, which stores the -login_name and cryptpasswd fields in the profiles table. An alternative means -of validation, LDAP, is already supported, and other contributions would be -appreciated. - -The module layout is similar to the Login package, but there is no need for a -sub-level as there is with Login request types. - -Params ------- - -There are two params that define behaviour for each authentication task. Each -of them defines a comma-separated list of modules to be tried in order. - - - user_info_class determines the module(s) used to obtain user - credentials. This param is specific to the requests from Bugzilla web - pages, so all of the listed modules live under - Bugzilla::Auth::Login::WWW - - - user_verify_class determines the module(s) used to verify credentials. - This param is general and concerns the whole Bugzilla instance, since - the same back end should be used regardless of what front end is used. - -Responsibilities ----------------- - -Bugzilla::Auth - - This module is responsible for abstracting away as much as possible the - login and logout tasks in Bugzilla. - - It offers login() and logout() methods that are proxied to the selected - login and verify packages. - -Bugzilla::Auth::Login - - This is a container to hold the various modules for each request type. - -Bugzilla::Auth::Login::WWW - - This module is responsible for abstracting away details of which web-based - login modules exist and are in use. It offers login() and logout() methods - that proxy through to whatever specific modules - -Bugzilla::Auth::Verify - - This module is responsible for abstracting away details of which - credential verification modules exist, and should proxy calls through to - them. There is a method that is particularly important, and which should - be proxied through to the specific: - - can_edit($type) - - This method takes an argument that specifies what sort of change - is being requested; the specific module should return 1 or 0 based - on the fact that it implements or not the required change. - - Current values for $type are "new" for new accounts, and "userid", - "login_name", "realname" for their respective fields. - -Specific Login Modules ----------------------- - - WWW - - The main authentication frontend; regular pages (CGIs) should use only - this module. It offers a convenient frontend to the main functionality - that CGIs need, using form parameters and cookies. - - - Cookie - - Implements part of the backend code that deals with browser - cookies. It's actually tied in to DB.pm, so Cookie logins that use - LDAP won't work at all. - - LDAP - - The other authentication module is LDAP-based; it is *only* used for - password authentication and not for any other login-related task (it - actually relies on the database to handle the profile information). - -Legacy ------- - -Bugzilla.pm - - There is glue code that currently lives in the top-level module - Bugzilla.pm; this module handles backwards-compatibility data that is used - in a number of CGIs. This data has been slowly removed from the Bugzilla - pages and eventually should go away completely, at which point Bugzilla.pm - will be just a wrapper to conveniently offer template, cgi, dbh and user - variables. - - This module is meant to be used only by Bugzilla pages, and in the case of - a reorganization which moves CGI-specific code to a subdirectory, - Bugzilla.pm should go with it. - diff --git a/Bugzilla/Auth/Verify.pm b/Bugzilla/Auth/Verify.pm new file mode 100644 index 000000000..deb5f4e95 --- /dev/null +++ b/Bugzilla/Auth/Verify.pm @@ -0,0 +1,236 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + +package Bugzilla::Auth::Verify; + +use strict; +use fields qw(); + +use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::User; +use Bugzilla::Util; + +use constant user_can_create_account => 1; + +sub new { + my ($class, $login_type) = @_; + my $self = fields::new($class); + return $self; +} + +sub can_change_password { + return $_[0]->can('change_password'); +} + +sub create_or_update_user { + my ($self, $params) = @_; + my $dbh = Bugzilla->dbh; + + my $extern_id = $params->{extern_id}; + my $username = $params->{bz_username} || $params->{username}; + my $password = $params->{password} || '*'; + my $real_name = $params->{realname} || ''; + my $user_id = $params->{user_id}; + + # A passed-in user_id always overrides anything else, for determining + # what account we should return. + if (!$user_id) { + my $username_user_id = login_to_id($username || ''); + my $extern_user_id; + if ($extern_id) { + trick_taint($extern_id); + $extern_user_id = $dbh->selectrow_array('SELECT userid + FROM profiles WHERE extern_id = ?', undef, $extern_id); + } + + # If we have both a valid extern_id and a valid username, and they are + # not the same id, then we have a conflict. + if ($username_user_id && $extern_user_id + && $username_user_id ne $extern_user_id) + { + my $extern_name = Bugzilla::User->new($extern_user_id)->login; + return { failure => AUTH_ERROR, error => "extern_id_conflict", + details => {extern_id => $extern_id, + extern_user => $extern_name, + username => $username} }; + } + + # If we have a valid username, but no valid id, + # then we have to create the user. This happens when we're + # passed only a username, and that username doesn't exist already. + if ($username && !$username_user_id && !$extern_user_id) { + validate_email_syntax($username) + || return { failure => AUTH_ERROR, + error => 'auth_invalid_email', + details => {addr => $username} }; + # Usually we'd call validate_password, but external authentication + # systems might follow different standards than ours. So in this + # place here, we call trick_taint without checks. + trick_taint($password); + + # XXX Theoretically this could fail with an error, but the fix for + # that is too involved to be done right now. + my $user = Bugzilla::User->create({ + login_name => $username, + cryptpassword => $password, + realname => $real_name}); + $username_user_id = $user->id; + } + + # If we have a valid username id and an extern_id, but no valid + # extern_user_id, then we have to set the user's extern_id. + if ($extern_id && $username_user_id && !$extern_user_id) { + $dbh->do('UPDATE profiles SET extern_id = ? WHERE userid = ?', + undef, $extern_id, $username_user_id); + } + + # Finally, at this point, one of these will give us a valid user id. + $user_id = $extern_user_id || $username_user_id; + } + + # If we still don't have a valid user_id, then we weren't passed + # enough information in $params, and we should die right here. + ThrowCodeError('bad_arg', {argument => 'params', function => + 'Bugzilla::Auth::Verify::create_or_update_user'}) + unless $user_id; + + my $user = new Bugzilla::User($user_id); + + # Now that we have a valid User, we need to see if any data has to be + # updated. + if ($username && lc($user->login) ne lc($username)) { + validate_email_syntax($username) + || return { failure => AUTH_ERROR, error => 'auth_invalid_email', + details => {addr => $username} }; + $dbh->do('UPDATE profiles SET login_name = ? WHERE userid = ?', + undef, $username, $user->id); + } + if ($real_name && $user->name ne $real_name) { + # $real_name is more than likely tainted, but we only use it + # in a placeholder and we never use it after this. + trick_taint($real_name); + $dbh->do('UPDATE profiles SET realname = ? WHERE userid = ?', + undef, $real_name, $user->id); + } + + return { user => $user }; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Auth::Verify - An object that verifies usernames and passwords. + +=head1 DESCRIPTION + +Bugzilla::Auth::Verify provides the "Verifier" part of the Bugzilla +login process. (For details, see the "STRUCTURE" section of +L<Bugzilla::Auth>.) + +It is mostly an abstract class, requiring subclasses to implement +most methods. + +Note that callers outside of the C<Bugzilla::Auth> package should never +create this object directly. Just create a C<Bugzilla::Auth> object +and call C<login> on it. + +=head1 VERIFICATION METHODS + +These are the methods that have to do with the actual verification. + +Subclasses MUST implement these methods. + +=over 4 + +=item C<check_credentials($login_data)> + +Description: Checks whether or not a username is valid. +Params: $login_data - A C<$login_data> hashref, as described in + L<Bugzilla::Auth>. + This C<$login_data> hashref MUST contain + C<username>, and SHOULD also contain + C<password>. +Returns: A C<$login_data> hashref with C<bz_username> set. This + method may also set C<realname>. It must avoid changing + anything that is already set. + +=back + +=head1 MODIFICATION METHODS + +These are methods that change data in the actual authentication backend. + +These methods are optional, they do not have to be implemented by +subclasses. + +=over 4 + +=item C<create_or_update_user($login_data)> + +Description: Automatically creates a user account in the database + if it doesn't already exist, or updates the account + data if C<$login_data> contains newer information. + +Params: $login_data - A C<$login_data> hashref, as described in + L<Bugzilla::Auth>. + This C<$login_data> hashref MUST contain + either C<user_id>, C<bz_username>, or + C<username>. If both C<username> and C<bz_username> + are specified, C<bz_username> is used as the + login name of the user to create in the database. + It MAY also contain C<extern_id>, in which + case it still MUST contain C<bz_username> or + C<username>. + It MAY contain C<password> and C<realname>. + +Returns: A hashref with one element, C<user>, which is a + L<Bugzilla::User> object. May also return a login error + as described in L<Bugzilla::Auth>. + +Note: This method is not abstract, it is actually implemented + and creates accounts in the Bugzilla database. Subclasses + should probably all call the C<Bugzilla::Auth::Verify> + version of this function at the end of their own + C<create_or_update_user>. + +=item C<change_password($user, $password)> + +Description: Modifies the user's password in the authentication backend. +Params: $user - A L<Bugzilla::User> object representing the user + whose password we want to change. + $password - The user's new password. +Returns: Nothing. + +=back + +=head1 INFO METHODS + +These are methods that describe the capabilities of this object. +These are all no-parameter methods that return either C<true> or +C<false>. + +=over 4 + +=item C<user_can_create_account> + +Whether or not users can manually create accounts in this type of +account source. Defaults to C<true>. + +=back diff --git a/Bugzilla/Auth/Verify/CVS/Entries b/Bugzilla/Auth/Verify/CVS/Entries index bf7f12f2f..6adbd6866 100644 --- a/Bugzilla/Auth/Verify/CVS/Entries +++ b/Bugzilla/Auth/Verify/CVS/Entries @@ -1,3 +1,4 @@ -/DB.pm/1.6/Wed Jul 13 03:57:02 2005//TBUGZILLA-2_22_3 -/LDAP.pm/1.6.4.1/Fri Mar 3 12:21:20 2006//TBUGZILLA-2_22_3 +/DB.pm/1.7/Fri May 12 02:41:14 2006//TBUGZILLA-3_0 +/LDAP.pm/1.14/Tue Jul 11 00:42:57 2006//TBUGZILLA-3_0 +/Stack.pm/1.1/Fri May 12 02:41:14 2006//TBUGZILLA-3_0 D diff --git a/Bugzilla/Auth/Verify/CVS/Tag b/Bugzilla/Auth/Verify/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/Bugzilla/Auth/Verify/CVS/Tag +++ b/Bugzilla/Auth/Verify/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/Bugzilla/Auth/Verify/DB.pm b/Bugzilla/Auth/Verify/DB.pm index 405a737b8..88ad78d54 100644 --- a/Bugzilla/Auth/Verify/DB.pm +++ b/Bugzilla/Auth/Verify/DB.pm @@ -28,97 +28,51 @@ # Erik Stambaugh <erik@dasbistro.com> package Bugzilla::Auth::Verify::DB; - use strict; +use base qw(Bugzilla::Auth::Verify); -use Bugzilla::Config; use Bugzilla::Constants; +use Bugzilla::Token; use Bugzilla::Util; use Bugzilla::User; -my $edit_options = { - 'new' => 1, - 'userid' => 0, - 'login_name' => 1, - 'realname' => 1, -}; +sub check_credentials { + my ($self, $login_data) = @_; + my $dbh = Bugzilla->dbh; -sub can_edit { - my ($class, $type) = @_; - return $edit_options->{$type}; -} + my $username = $login_data->{username}; + my $user_id = login_to_id($username); -sub authenticate { - my ($class, $username, $passwd) = @_; + return { failure => AUTH_NO_SUCH_USER } unless $user_id; - return (AUTH_NODATA) unless defined $username && defined $passwd; + $login_data->{bz_username} = $username; + my $password = $login_data->{password}; - my $userid = Bugzilla::User::login_to_id($username); - return (AUTH_LOGINFAILED) unless $userid; + trick_taint($username); + my ($real_password_crypted) = $dbh->selectrow_array( + "SELECT cryptpassword FROM profiles WHERE userid = ?", + undef, $user_id); - return (AUTH_LOGINFAILED, $userid) - unless $class->check_password($userid, $passwd); + # Using the internal crypted password as the salt, + # crypt the password the user entered. + my $entered_password_crypted = crypt($password, $real_password_crypted); + + return { failure => AUTH_LOGINFAILED } + if $entered_password_crypted ne $real_password_crypted; # The user's credentials are okay, so delete any outstanding # password tokens they may have generated. - require Bugzilla::Token; - Bugzilla::Token::DeletePasswordTokens($userid, "user_logged_in"); - - # Account may have been disabled - my $disabledtext = $class->get_disabled($userid); - return (AUTH_DISABLED, $userid, $disabledtext) - if $disabledtext ne ''; - - return (AUTH_OK, $userid); -} - -sub get_disabled { - my ($class, $userid) = @_; - my $dbh = Bugzilla->dbh; - my $sth = $dbh->prepare_cached("SELECT disabledtext FROM profiles " . - "WHERE userid=?"); - my ($text) = $dbh->selectrow_array($sth, undef, $userid); - return $text; -} - -sub check_password { - my ($class, $userid, $passwd) = @_; - my $dbh = Bugzilla->dbh; - my $sth = $dbh->prepare_cached("SELECT cryptpassword FROM profiles " . - "WHERE userid=?"); - my ($realcryptpwd) = $dbh->selectrow_array($sth, undef, $userid); - - # Get the salt from the user's crypted password. - my $salt = $realcryptpwd; - - # Using the salt, crypt the password the user entered. - my $enteredCryptedPassword = crypt($passwd, $salt); + Bugzilla::Token::DeletePasswordTokens($user_id, "user_logged_in"); - return $enteredCryptedPassword eq $realcryptpwd; + return $login_data; } sub change_password { - my ($class, $userid, $password) = @_; + my ($self, $user, $password) = @_; my $dbh = Bugzilla->dbh; my $cryptpassword = bz_crypt($password); - $dbh->do("UPDATE profiles SET cryptpassword = ? WHERE userid = ?", - undef, $cryptpassword, $userid); + $dbh->do("UPDATE profiles SET cryptpassword = ? WHERE userid = ?", + undef, $cryptpassword, $user->id); } 1; - -__END__ - -=head1 NAME - -Bugzilla::Auth::Verify::DB - database authentication for Bugzilla - -=head1 SUMMARY - -This is an L<authentication module|Bugzilla::Auth/"AUTHENTICATION"> for -Bugzilla, which logs the user in using the password stored in the C<profiles> -table. This is the most commonly used authentication module. - -=head1 SEE ALSO - -L<Bugzilla::Auth> diff --git a/Bugzilla/Auth/Verify/LDAP.pm b/Bugzilla/Auth/Verify/LDAP.pm index e8e744971..343f7952c 100644 --- a/Bugzilla/Auth/Verify/LDAP.pm +++ b/Bugzilla/Auth/Verify/LDAP.pm @@ -26,39 +26,26 @@ # Christian Reis <kiko@async.com.br> # Bradley Baetz <bbaetz@acm.org> # Erik Stambaugh <erik@dasbistro.com> +# Max Kanat-Alexander <mkanat@bugzilla.org> package Bugzilla::Auth::Verify::LDAP; - use strict; +use base qw(Bugzilla::Auth::Verify); +use fields qw( + ldap +); -use Bugzilla::Config; use Bugzilla::Constants; -use Bugzilla::User; +use Bugzilla::Error; use Net::LDAP; -my $edit_options = { - 'new' => 0, - 'userid' => 0, - 'login_name' => 0, - 'realname' => 0, -}; - -sub can_edit { - my ($class, $type) = @_; - return $edit_options->{$type}; -} +use constant admin_can_create_account => 0; +use constant user_can_create_account => 0; -sub authenticate { - my ($class, $username, $passwd) = @_; - - # If no password was provided, then fail the authentication. - # While it may be valid to not have an LDAP password, when you - # bind without a password (regardless of the binddn value), you - # will get an anonymous bind. I do not know of a way to determine - # whether a bind is anonymous or not without making changes to the - # LDAP access control settings - return (AUTH_NODATA) unless $username && $passwd; +sub check_credentials { + my ($self, $params) = @_; + my $dbh = Bugzilla->dbh; # We need to bind anonymously to the LDAP server. This is # because we need to get the Distinguished Name of the user trying @@ -67,132 +54,100 @@ sub authenticate { # just appending the Base DN to the uid isn't sufficient to get the # user's DN. For servers which don't work this way, there will still # be no harm done. - my $LDAPserver = Param("LDAPserver"); - if ($LDAPserver eq "") { - return (AUTH_ERROR, undef, "server_not_defined"); - } - - my $LDAPport = "389"; # default LDAP port - if($LDAPserver =~ /:/) { - ($LDAPserver, $LDAPport) = split(":",$LDAPserver); - } - my $LDAPconn = Net::LDAP->new($LDAPserver, port => $LDAPport, version => 3); - if(!$LDAPconn) { - return (AUTH_ERROR, undef, "connect_failed"); - } - - my $mesg; - if (Param("LDAPbinddn")) { - my ($LDAPbinddn,$LDAPbindpass) = split(":",Param("LDAPbinddn")); - $mesg = $LDAPconn->bind($LDAPbinddn, password => $LDAPbindpass); - } - else { - $mesg = $LDAPconn->bind(); - } - if($mesg->code) { - return (AUTH_ERROR, undef, - "connect_failed", - { errstr => $mesg->error }); - } + $self->_bind_ldap_anonymously(); + + # Now, we verify that the user exists, and get a LDAP Distinguished + # Name for the user. + my $username = $params->{username}; + my $dn_result = $self->ldap->search(_bz_search_params($username), + attrs => ['dn']); + return { failure => AUTH_ERROR, error => "ldap_search_error", + details => {errstr => $dn_result->error, username => $username} + } if $dn_result->code; + + return { failure => AUTH_NO_SUCH_USER } if !$dn_result->count; + + my $dn = $dn_result->shift_entry->dn; + + # Check the password. + my $pw_result = $self->ldap->bind($dn, password => $params->{password}); + return { failure => AUTH_LOGINFAILED } if $pw_result->code; + + # And now we fill in the user's details. + my $detail_result = $self->ldap->search(_bz_search_params($username)); + return { failure => AUTH_ERROR, error => "ldap_search_error", + details => {errstr => $detail_result->error, username => $username} + } if $detail_result->code; + + my $user_entry = $detail_result->shift_entry; + + my $mail_attr = Bugzilla->params->{"LDAPmailattribute"}; + if ($mail_attr) { + if (!$user_entry->exists($mail_attr)) { + return { failure => AUTH_ERROR, + error => "ldap_cannot_retreive_attr", + details => {attr => $mail_attr} }; + } - # We've got our anonymous bind; let's look up this user. - $mesg = $LDAPconn->search( base => Param("LDAPBaseDN"), - scope => "sub", - filter => '(&(' . Param("LDAPuidattribute") . "=$username)" . Param("LDAPfilter") . ')', - attrs => ['dn'], - ); - return (AUTH_LOGINFAILED, undef, "lookup_failure") - unless $mesg->count; - - # Now we get the DN from this search. - my $userDN = $mesg->shift_entry->dn; - - # Now we attempt to bind as the specified user. - $mesg = $LDAPconn->bind( $userDN, password => $passwd); - - return (AUTH_LOGINFAILED) if $mesg->code; - - # And now we're going to repeat the search, so that we can get the - # mail attribute for this user. - $mesg = $LDAPconn->search( base => Param("LDAPBaseDN"), - scope => "sub", - filter => '(&(' . Param("LDAPuidattribute") . "=$username)" . Param("LDAPfilter") . ')', - ); - my $user_entry = $mesg->shift_entry if !$mesg->code && $mesg->count; - if(!$user_entry || !$user_entry->exists(Param("LDAPmailattribute"))) { - return (AUTH_ERROR, undef, - "cannot_retreive_attr", - { attr => Param("LDAPmailattribute") }); + $params->{bz_username} = $user_entry->get_value($mail_attr); + } else { + $params->{bz_username} = $username; } - # get the mail attribute - $username = $user_entry->get_value(Param("LDAPmailattribute")); - # OK, so now we know that the user is valid. Lets try finding them in the - # Bugzilla database + $params->{realname} ||= $user_entry->get_value("displayName"); + $params->{realname} ||= $user_entry->get_value("cn"); - # XXX - should this part be made more generic, and placed in - # Bugzilla::Auth? Lots of login mechanisms may have to do this, although - # until we actually get some more, its hard to know - BB + return $params; +} - my $dbh = Bugzilla->dbh; - my $sth = $dbh->prepare_cached("SELECT userid, disabledtext " . - "FROM profiles " . - "WHERE " . - $dbh->sql_istrcmp('login_name', '?')); - my ($userid, $disabledtext) = - $dbh->selectrow_array($sth, - undef, - $username); - - # If the user doesn't exist, then they need to be added - unless ($userid) { - # We'll want the user's name for this. - my $userRealName = $user_entry->get_value("displayName"); - if($userRealName eq "") { - $userRealName = $user_entry->get_value("cn"); - } - insert_new_user($username, $userRealName); +sub _bz_search_params { + my ($username) = @_; + return (base => Bugzilla->params->{"LDAPBaseDN"}, + scope => "sub", + filter => '(&(' . Bugzilla->params->{"LDAPuidattribute"} + . "=$username)" + . Bugzilla->params->{"LDAPfilter"} . ')'); +} - ($userid, $disabledtext) = $dbh->selectrow_array($sth, - undef, - $username); - return (AUTH_ERROR, $userid, "no_userid") - unless $userid; +sub _bind_ldap_anonymously { + my ($self) = @_; + my $bind_result; + if (Bugzilla->params->{"LDAPbinddn"}) { + my ($LDAPbinddn,$LDAPbindpass) = + split(":",Bugzilla->params->{"LDAPbinddn"}); + $bind_result = + $self->ldap->bind($LDAPbinddn, password => $LDAPbindpass); } + else { + $bind_result = $self->ldap->bind(); + } + ThrowCodeError("ldap_bind_failed", {errstr => $bind_result->error}) + if $bind_result->code; +} - # we're done, so disconnect - $LDAPconn->unbind; - - # Test for disabled account - return (AUTH_DISABLED, $userid, $disabledtext) - if $disabledtext ne ''; +# We can't just do this in new(), because we're not allowed to throw any +# error from anywhere under Bugzilla::Auth::new -- otherwise we +# could create a situation where the admin couldn't get to editparams +# to fix his mistake. (Because Bugzilla->login always calls +# Bugzilla::Auth->new, and almost every page calls Bugzilla->login.) +sub ldap { + my ($self) = @_; + return $self->{ldap} if $self->{ldap}; + + my $server = Bugzilla->params->{"LDAPserver"}; + ThrowCodeError("ldap_server_not_defined") unless $server; + + $self->{ldap} = new Net::LDAP($server) + || ThrowCodeError("ldap_connect_failed", { server => $server }); + + # try to start TLS if needed + if (Bugzilla->params->{"LDAPstarttls"}) { + my $mesg = $self->{ldap}->start_tls(); + ThrowCodeError("ldap_start_tls_failed", { error => $mesg->error() }) + if $mesg->code(); + } - # If we get to here, then the user is allowed to login, so we're done! - return (AUTH_OK, $userid); + return $self->{ldap}; } 1; - -__END__ - -=head1 NAME - -Bugzilla::Auth::Verify::LDAP - LDAP based authentication for Bugzilla - -This is an L<authentication module|Bugzilla::Auth/"AUTHENTICATION"> for -Bugzilla, which logs the user in using an LDAP directory. - -=head1 DISCLAIMER - -B<This module is experimental>. It is poorly documented, and not very flexible. -Search L<http:E<sol>E<sol>bugzilla.mozilla.orgE<sol>> for a list of known LDAP bugs. - -None of the core Bugzilla developers, nor any of the large installations, use -this module, and so it has received less testing. (In fact, this iteration -hasn't been tested at all) - -Patches are accepted. - -=head1 SEE ALSO - -L<Bugzilla::Auth> diff --git a/Bugzilla/Auth/Verify/Stack.pm b/Bugzilla/Auth/Verify/Stack.pm new file mode 100644 index 000000000..577b5a22f --- /dev/null +++ b/Bugzilla/Auth/Verify/Stack.pm @@ -0,0 +1,81 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + +package Bugzilla::Auth::Verify::Stack; +use strict; +use base qw(Bugzilla::Auth::Verify); +use fields qw( + _stack + successful +); + +sub new { + my $class = shift; + my $list = shift; + my $self = $class->SUPER::new(@_); + $self->{_stack} = []; + foreach my $verify_method (split(',', $list)) { + require "Bugzilla/Auth/Verify/${verify_method}.pm"; + push(@{$self->{_stack}}, + "Bugzilla::Auth::Verify::$verify_method"->new(@_)); + } + return $self; +} + +sub can_change_password { + my ($self) = @_; + # We return true if any method can change passwords. + foreach my $object (@{$self->{_stack}}) { + return 1 if $object->can_change_password; + } + return 0; +} + +sub check_credentials { + my $self = shift; + my $result; + foreach my $object (@{$self->{_stack}}) { + $result = $object->check_credentials(@_); + $self->{successful} = $object; + last if !$result->{failure}; + # So that if none of them succeed, it's undef. + $self->{successful} = undef; + } + # Returns the result at the bottom of the stack if they all fail. + return $result; +} + +sub create_or_update_user { + my $self = shift; + my $result; + foreach my $object (@{$self->{_stack}}) { + $result = $object->create_or_update_user(@_); + last if !$result->{failure}; + } + # Returns the result at the bottom of the stack if they all fail. + return $result; +} + +sub user_can_create_account { + my ($self) = @_; + # We return true if any method allows the user to create an account. + foreach my $object (@{$self->{_stack}}) { + return 1 if $object->user_can_create_account; + } + return 0; +} + +1; diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index 73dd59491..8591a2f89 100755 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -30,34 +30,115 @@ package Bugzilla::Bug; use strict; -use vars qw($legal_keywords @legal_platform - @legal_priority @legal_severity @legal_opsys @legal_bug_status - @settable_resolution %components %versions %target_milestone - @enterable_products %milestoneurl %prodmaxvotes); - use Bugzilla::Attachment; -use Bugzilla::BugMail; -use Bugzilla::Config; use Bugzilla::Constants; use Bugzilla::Field; use Bugzilla::Flag; use Bugzilla::FlagType; +use Bugzilla::Keyword; use Bugzilla::User; use Bugzilla::Util; use Bugzilla::Error; +use Bugzilla::Product; +use Bugzilla::Component; +use Bugzilla::Group; + +use List::Util qw(min); -use base qw(Exporter); +use base qw(Bugzilla::Object Exporter); @Bugzilla::Bug::EXPORT = qw( AppendComment ValidateComment bug_alias_to_id ValidateBugAlias ValidateBugID RemoveVotes CheckIfVotedConfirmed LogActivityEntry + is_open_state + editable_bug_fields ); ##################################################################### # Constants ##################################################################### +use constant DB_TABLE => 'bugs'; +use constant ID_FIELD => 'bug_id'; +use constant NAME_FIELD => 'alias'; +use constant LIST_ORDER => ID_FIELD; + +# This is a sub because it needs to call other subroutines. +sub DB_COLUMNS { + my $dbh = Bugzilla->dbh; + return qw( + alias + bug_file_loc + bug_id + bug_severity + bug_status + cclist_accessible + component_id + delta_ts + estimated_time + everconfirmed + op_sys + priority + product_id + remaining_time + rep_platform + reporter_accessible + resolution + short_desc + status_whiteboard + target_milestone + version + ), + 'assigned_to AS assigned_to_id', + 'reporter AS reporter_id', + 'qa_contact AS qa_contact_id', + $dbh->sql_date_format('creation_ts', '%Y.%m.%d %H:%i') . ' AS creation_ts', + $dbh->sql_date_format('deadline', '%Y-%m-%d') . ' AS deadline', + Bugzilla->custom_field_names; +} + +use constant REQUIRED_CREATE_FIELDS => qw( + bug_severity + comment + component + op_sys + priority + product + rep_platform + short_desc + version +); + +# There are also other, more complex validators that are called +# from run_create_validators. +sub VALIDATORS { + my $validators = { + alias => \&_check_alias, + bug_file_loc => \&_check_bug_file_loc, + bug_severity => \&_check_bug_severity, + comment => \&_check_comment, + commentprivacy => \&_check_commentprivacy, + deadline => \&_check_deadline, + estimated_time => \&_check_estimated_time, + op_sys => \&_check_op_sys, + priority => \&_check_priority, + product => \&_check_product, + remaining_time => \&_check_remaining_time, + rep_platform => \&_check_rep_platform, + short_desc => \&_check_short_desc, + status_whiteboard => \&_check_status_whiteboard, + }; + + my @select_fields = Bugzilla->get_fields({custom => 1, obsolete => 0, + type => FIELD_TYPE_SINGLE_SELECT}); + + foreach my $field (@select_fields) { + $validators->{$field->name} = \&_check_select_field; + } + return $validators; +}; + # Used in LogActivityEntry(). Gives the max length of lines in the # activity table. use constant MAX_LINE_LENGTH => 254; @@ -65,173 +146,255 @@ use constant MAX_LINE_LENGTH => 254; # Used in ValidateComment(). Gives the max length allowed for a comment. use constant MAX_COMMENT_LENGTH => 65535; -##################################################################### +# The statuses that are valid on enter_bug.cgi and post_bug.cgi. +# The order is important--see _check_bug_status +use constant VALID_ENTRY_STATUS => qw( + UNCONFIRMED + NEW + ASSIGNED +); -sub fields { - # Keep this ordering in sync with bugzilla.dtd - my @fields = qw(bug_id alias creation_ts short_desc delta_ts - reporter_accessible cclist_accessible - classification_id classification - product component version rep_platform op_sys - bug_status resolution - bug_file_loc status_whiteboard keywords - priority bug_severity target_milestone - dependson blocked votes everconfirmed - reporter assigned_to cc - ); +##################################################################### - if (Param('useqacontact')) { - push @fields, "qa_contact"; +sub new { + my $invocant = shift; + my $class = ref($invocant) || $invocant; + my $param = shift; + + # If we get something that looks like a word (not a number), + # make it the "name" param. + if (!defined $param || (!ref($param) && $param !~ /^\d+$/)) { + # But only if aliases are enabled. + if (Bugzilla->params->{'usebugaliases'} && $param) { + $param = { name => $param }; + } + else { + # Aliases are off, and we got something that's not a number. + my $error_self = {}; + bless $error_self, $class; + $error_self->{'bug_id'} = $param; + $error_self->{'error'} = 'InvalidBugId'; + return $error_self; + } } - if (Param('timetrackinggroup')) { - push @fields, qw(estimated_time remaining_time actual_time deadline); + unshift @_, $param; + my $self = $class->SUPER::new(@_); + + # Bugzilla::Bug->new always returns something, but sets $self->{error} + # if the bug wasn't found in the database. + if (!$self) { + my $error_self = {}; + bless $error_self, $class; + $error_self->{'bug_id'} = ref($param) ? $param->{name} : $param; + $error_self->{'error'} = 'NotFound'; + return $error_self; } - return @fields; -} + # XXX At some point these should be moved into accessors. + # They only are here because this is how Bugzilla::Bug + # originally did things, before it was a Bugzilla::Object. + $self->{'isunconfirmed'} = ($self->{bug_status} eq 'UNCONFIRMED'); + $self->{'isopened'} = is_open_state($self->{bug_status}); -my %ok_field; -foreach my $key (qw(error groups - longdescs milestoneurl attachments - isopened isunconfirmed - flag_types num_attachment_flag_types - show_attachment_flags use_keywords any_flags_requesteeble - ), - fields()) { - $ok_field{$key}++; + return $self; } -# create a new empty bug +# Docs for create() (there's no POD in this file yet, but we very +# much need this documented right now): # -sub new { - my $type = shift(); - my %bug; - - # create a ref to an empty hash and bless it - # - my $self = {%bug}; - bless $self, $type; - - # construct from a hash containing a bug's info - # - if ($#_ == 1) { - $self->initBug(@_); - } else { - confess("invalid number of arguments \($#_\)($_)"); - } +# The same as Bugzilla::Object->create. Parameters are only required +# if they say so below. +# +# Params: +# +# C<product> - B<Required> The name of the product this bug is being +# filed against. +# C<component> - B<Required> The name of the component this bug is being +# filed against. +# +# C<bug_severity> - B<Required> The severity for the bug, a string. +# C<creation_ts> - B<Required> A SQL timestamp for when the bug was created. +# C<short_desc> - B<Required> A summary for the bug. +# C<op_sys> - B<Required> The OS the bug was found against. +# C<priority> - B<Required> The initial priority for the bug. +# C<rep_platform> - B<Required> The platform the bug was found against. +# C<version> - B<Required> The version of the product the bug was found in. +# +# C<alias> - An alias for this bug. Will be ignored if C<usebugaliases> +# is off. +# C<target_milestone> - When this bug is expected to be fixed. +# C<status_whiteboard> - A string. +# C<bug_status> - The initial status of the bug, a string. +# C<bug_file_loc> - The URL field. +# +# C<assigned_to> - The full login name of the user who the bug is +# initially assigned to. +# C<qa_contact> - The full login name of the QA Contact for this bug. +# Will be ignored if C<useqacontact> is off. +# +# C<estimated_time> - For time-tracking. Will be ignored if +# C<timetrackinggroup> is not set, or if the current +# user is not a member of the timetrackinggroup. +# C<deadline> - For time-tracking. Will be ignored for the same +# reasons as C<estimated_time>. +sub create { + my $class = shift; + my $dbh = Bugzilla->dbh; - # bless as a Bug - # - return $self; + $class->check_required_create_fields(@_); + my $params = $class->run_create_validators(@_); + + # These are not a fields in the bugs table, so we don't pass them to + # insert_create_data. + my $cc_ids = $params->{cc}; + delete $params->{cc}; + my $groups = $params->{groups}; + delete $params->{groups}; + my $depends_on = $params->{dependson}; + delete $params->{dependson}; + my $blocked = $params->{blocked}; + delete $params->{blocked}; + my ($comment, $privacy) = ($params->{comment}, $params->{commentprivacy}); + delete $params->{comment}; + delete $params->{commentprivacy}; + + # Set up the keyword cache for bug creation. + my $keywords = $params->{keywords}; + $params->{keywords} = join(', ', sort {lc($a) cmp lc($b)} + map($_->name, @$keywords)); + + # We don't want the bug to appear in the system until it's correctly + # protected by groups. + my $timestamp = $params->{creation_ts}; + delete $params->{creation_ts}; + + $dbh->bz_lock_tables('bugs WRITE', 'bug_group_map WRITE', + 'longdescs WRITE', 'cc WRITE', 'keywords WRITE', 'dependencies WRITE', + 'bugs_activity WRITE', 'fielddefs READ'); + + my $bug = $class->insert_create_data($params); + + # Add the group restrictions + my $sth_group = $dbh->prepare( + 'INSERT INTO bug_group_map (bug_id, group_id) VALUES (?, ?)'); + foreach my $group_id (@$groups) { + $sth_group->execute($bug->bug_id, $group_id); + } + + $dbh->do('UPDATE bugs SET creation_ts = ? WHERE bug_id = ?', undef, + $timestamp, $bug->bug_id); + # Update the bug instance as well + $bug->{creation_ts} = $timestamp; + + # Add the CCs + my $sth_cc = $dbh->prepare('INSERT INTO cc (bug_id, who) VALUES (?,?)'); + foreach my $user_id (@$cc_ids) { + $sth_cc->execute($bug->bug_id, $user_id); + } + + # Add in keywords + my $sth_keyword = $dbh->prepare( + 'INSERT INTO keywords (bug_id, keywordid) VALUES (?, ?)'); + foreach my $keyword_id (map($_->id, @$keywords)) { + $sth_keyword->execute($bug->bug_id, $keyword_id); + } + + # Set up dependencies (blocked/dependson) + my $sth_deps = $dbh->prepare( + 'INSERT INTO dependencies (blocked, dependson) VALUES (?, ?)'); + my $sth_bug_time = $dbh->prepare('UPDATE bugs SET delta_ts = ? WHERE bug_id = ?'); + + foreach my $depends_on_id (@$depends_on) { + $sth_deps->execute($bug->bug_id, $depends_on_id); + # Log the reverse action on the other bug. + LogActivityEntry($depends_on_id, 'blocked', '', $bug->bug_id, + $bug->{reporter_id}, $timestamp); + $sth_bug_time->execute($timestamp, $depends_on_id); + } + foreach my $blocked_id (@$blocked) { + $sth_deps->execute($blocked_id, $bug->bug_id); + # Log the reverse action on the other bug. + LogActivityEntry($blocked_id, 'dependson', '', $bug->bug_id, + $bug->{reporter_id}, $timestamp); + $sth_bug_time->execute($timestamp, $blocked_id); + } + + # And insert the comment. We always insert a comment on bug creation, + # but sometimes it's blank. + my @columns = qw(bug_id who bug_when thetext); + my @values = ($bug->bug_id, $bug->{reporter_id}, $timestamp, $comment); + # We don't include the "isprivate" column unless it was specified. + # This allows it to fall back to its database default. + if (defined $privacy) { + push(@columns, 'isprivate'); + push(@values, $privacy); + } + my $qmarks = "?," x @columns; + chop($qmarks); + $dbh->do('INSERT INTO longdescs (' . join(',', @columns) . ") + VALUES ($qmarks)", undef, @values); + + $dbh->bz_unlock_tables(); + + return $bug; } -# dump info about bug into hash unless user doesn't have permission -# user_id 0 is used when person is not logged in. -# -sub initBug { - my $self = shift(); - my ($bug_id, $user_id) = (@_); - my $dbh = Bugzilla->dbh; - $bug_id = trim($bug_id); +sub run_create_validators { + my $class = shift; + my $params = $class->SUPER::run_create_validators(@_); - my $old_bug_id = $bug_id; + my $product = $params->{product}; + $params->{product_id} = $product->id; + delete $params->{product}; - # If the bug ID isn't numeric, it might be an alias, so try to convert it. - $bug_id = bug_alias_to_id($bug_id) if $bug_id !~ /^0*[1-9][0-9]*$/; + ($params->{bug_status}, $params->{everconfirmed}) + = $class->_check_bug_status($product, $params->{bug_status}); - if ((! defined $bug_id) || (!$bug_id) || (!detaint_natural($bug_id))) { - # no bug number given or the alias didn't match a bug - $self->{'bug_id'} = $old_bug_id; - $self->{'error'} = "InvalidBugId"; - return $self; - } + $params->{target_milestone} = $class->_check_target_milestone($product, + $params->{target_milestone}); - # If the user is not logged in, sets $user_id to 0. - # Else gets $user_id from the user login name if this - # argument is not numeric. - my $stored_user_id = $user_id; - if (!defined $user_id) { - $user_id = 0; - } elsif (!detaint_natural($user_id)) { - $user_id = login_to_id($stored_user_id); - } + $params->{version} = $class->_check_version($product, $params->{version}); - $self->{'who'} = new Bugzilla::User($user_id); - - my $query = " - SELECT - bugs.bug_id, alias, products.classification_id, classifications.name, - bugs.product_id, products.name, version, - rep_platform, op_sys, bug_status, resolution, priority, - bug_severity, bugs.component_id, components.name, - assigned_to AS assigned_to_id, reporter AS reporter_id, - bug_file_loc, short_desc, target_milestone, - qa_contact AS qa_contact_id, status_whiteboard, " . - $dbh->sql_date_format('creation_ts', '%Y.%m.%d %H:%i') . ", - delta_ts, COALESCE(SUM(votes.vote_count), 0), everconfirmed, - reporter_accessible, cclist_accessible, - estimated_time, remaining_time, " . - $dbh->sql_date_format('deadline', '%Y-%m-%d') . " - FROM bugs - LEFT JOIN votes - ON bugs.bug_id = votes.bug_id - INNER JOIN components - ON components.id = bugs.component_id - INNER JOIN products - ON products.id = bugs.product_id - INNER JOIN classifications - ON classifications.id = products.classification_id - WHERE bugs.bug_id = ? " . - $dbh->sql_group_by('bugs.bug_id', 'alias, products.classification_id, - classifications.name, bugs.product_id, products.name, version, - rep_platform, op_sys, bug_status, resolution, priority, - bug_severity, bugs.component_id, components.name, assigned_to, - reporter, bug_file_loc, short_desc, target_milestone, - qa_contact, status_whiteboard, everconfirmed, creation_ts, - delta_ts, reporter_accessible, cclist_accessible, - estimated_time, remaining_time, deadline'); - - my $bug_sth = $dbh->prepare($query); - $bug_sth->execute($bug_id); - my @row; - - if ((@row = $bug_sth->fetchrow_array()) - && $self->{'who'}->can_see_bug($bug_id)) { - my $count = 0; - my %fields; - foreach my $field ("bug_id", "alias", "classification_id", "classification", - "product_id", "product", "version", - "rep_platform", "op_sys", "bug_status", "resolution", - "priority", "bug_severity", "component_id", "component", - "assigned_to_id", "reporter_id", - "bug_file_loc", "short_desc", - "target_milestone", "qa_contact_id", "status_whiteboard", - "creation_ts", "delta_ts", "votes", "everconfirmed", - "reporter_accessible", "cclist_accessible", - "estimated_time", "remaining_time", "deadline") - { - $fields{$field} = shift @row; - if (defined $fields{$field}) { - $self->{$field} = $fields{$field}; - } - $count++; - } - } elsif (@row) { - $self->{'bug_id'} = $bug_id; - $self->{'error'} = "NotPermitted"; - return $self; - } else { - $self->{'bug_id'} = $bug_id; - $self->{'error'} = "NotFound"; - return $self; - } + $params->{keywords} = $class->_check_keywords($product, $params->{keywords}); + + $params->{groups} = $class->_check_groups($product, + $params->{groups}); + + my $component = $class->_check_component($product, $params->{component}); + $params->{component_id} = $component->id; + delete $params->{component}; + + $params->{assigned_to} = + $class->_check_assigned_to($component, $params->{assigned_to}); + $params->{qa_contact} = + $class->_check_qa_contact($component, $params->{qa_contact}); + $params->{cc} = $class->_check_cc($component, $params->{cc}); + + # Callers cannot set Reporter, currently. + $params->{reporter} = Bugzilla->user->id; + + $params->{creation_ts} ||= Bugzilla->dbh->selectrow_array('SELECT NOW()'); + $params->{delta_ts} = $params->{creation_ts}; + + if ($params->{estimated_time}) { + $params->{remaining_time} = $params->{estimated_time}; + } + + $class->_check_strict_isolation($product, $params->{cc}, + $params->{assigned_to}, $params->{qa_contact}); - $self->{'isunconfirmed'} = ($self->{bug_status} eq 'UNCONFIRMED'); - $self->{'isopened'} = &::IsOpenedState($self->{bug_status}); - - return $self; + ($params->{dependson}, $params->{blocked}) = + $class->_check_dependencies($product, $params->{dependson}, $params->{blocked}); + + # You can't set these fields on bug creation (or sometimes ever). + delete $params->{resolution}; + delete $params->{votes}; + delete $params->{lastdiffed}; + delete $params->{bug_id}; + + return $params; } # This is the correct way to delete bugs from the DB. @@ -304,7 +467,404 @@ sub remove_from_db { } ##################################################################### -# Accessors +# Validators +##################################################################### + +sub _check_alias { + my ($invocant, $alias) = @_; + $alias = trim($alias); + return undef if (!Bugzilla->params->{'usebugaliases'} || !$alias); + ValidateBugAlias($alias); + return $alias; +} + +sub _check_assigned_to { + my ($invocant, $component, $name) = @_; + my $user = Bugzilla->user; + + $name = trim($name); + # Default assignee is the component owner. + my $id; + if (!$user->in_group('editbugs', $component->product_id) || !$name) { + $id = $component->default_assignee->id; + } else { + $id = login_to_id($name, THROW_ERROR); + } + return $id; +} + +sub _check_bug_file_loc { + my ($invocant, $url) = @_; + # If bug_file_loc is "http://", the default, use an empty value instead. + $url = '' if (!defined($url) || $url eq 'http://'); + return $url; +} + +sub _check_bug_severity { + my ($invocant, $severity) = @_; + $severity = trim($severity); + check_field('bug_severity', $severity); + return $severity; +} + +sub _check_bug_status { + my ($invocant, $product, $status) = @_; + my $user = Bugzilla->user; + + my @valid_statuses = VALID_ENTRY_STATUS; + + if ($user->in_group('editbugs', $product->id) + || $user->in_group('canconfirm', $product->id)) { + # Default to NEW if the user with privs hasn't selected another status. + $status ||= 'NEW'; + } + elsif (!$product->votes_to_confirm) { + # Without privs, products that don't support UNCONFIRMED default to + # NEW. + $status = 'NEW'; + } + else { + $status = 'UNCONFIRMED'; + } + + # UNCONFIRMED becomes an invalid status if votes_to_confirm is 0, + # even if you are in editbugs. + shift @valid_statuses if !$product->votes_to_confirm; + + check_field('bug_status', $status, \@valid_statuses); + return ($status, $status eq 'UNCONFIRMED' ? 0 : 1); +} + +sub _check_cc { + my ($invocant, $component, $ccs) = @_; + return [] unless $ccs; + + my %cc_ids; + foreach my $person (@$ccs) { + next unless $person; + my $id = login_to_id($person, THROW_ERROR); + $cc_ids{$id} = 1; + } + + # Enforce Default CC + $cc_ids{$_->id} = 1 foreach (@{$component->initial_cc}); + + return [keys %cc_ids]; +} + +sub _check_comment { + my ($invocant, $comment) = @_; + + $comment = '' unless defined $comment; + + # Remove any trailing whitespace. Leading whitespace could be + # a valid part of the comment. + $comment =~ s/\s*$//s; + $comment =~ s/\r\n?/\n/g; # Get rid of \r. + + ValidateComment($comment); + + if (Bugzilla->params->{"commentoncreate"} && !$comment) { + ThrowUserError("description_required"); + } + + # On creation only, there must be a single-space comment, or + # email will be supressed. + $comment = ' ' if $comment eq '' && !ref($invocant); + + return $comment; +} + +sub _check_commentprivacy { + my ($invocant, $comment_privacy) = @_; + my $insider_group = Bugzilla->params->{"insidergroup"}; + return ($insider_group && Bugzilla->user->in_group($insider_group) + && $comment_privacy) ? 1 : 0; +} + +sub _check_component { + my ($invocant, $product, $name) = @_; + $name = trim($name); + $name || ThrowUserError("require_component"); + my $obj = Bugzilla::Component::check_component($product, $name); + return $obj; +} + +sub _check_deadline { + my ($invocant, $date) = @_; + $date = trim($date); + my $tt_group = Bugzilla->params->{"timetrackinggroup"}; + return undef unless $date && $tt_group + && Bugzilla->user->in_group($tt_group); + validate_date($date) + || ThrowUserError('illegal_date', { date => $date, + format => 'YYYY-MM-DD' }); + return $date; +} + +# Takes two comma/space-separated strings and returns arrayrefs +# of valid bug IDs. +sub _check_dependencies { + my ($invocant, $product, $depends_on, $blocks) = @_; + + # Only editbugs users can set dependencies on bug entry. + return ([], []) unless Bugzilla->user->in_group('editbugs', $product->id); + + $depends_on ||= ''; + $blocks ||= ''; + + # Make sure all the bug_ids are valid. + my @results; + foreach my $string ($depends_on, $blocks) { + my @array = split(/[\s,]+/, $string); + # Eliminate nulls + @array = grep($_, @array); + # $field is not passed to ValidateBugID to prevent adding new + # dependencies on inaccessible bugs. + ValidateBugID($_) foreach (@array); + push(@results, \@array); + } + + # dependson blocks + my %deps = ValidateDependencies($results[0], $results[1]); + + return ($deps{'dependson'}, $deps{'blocked'}); +} + +sub _check_estimated_time { + return $_[0]->_check_time($_[1], 'estimated_time'); +} + +sub _check_groups { + my ($invocant, $product, $group_ids) = @_; + + my $user = Bugzilla->user; + + my %add_groups; + my $controls = $product->group_controls; + + foreach my $id (@$group_ids) { + my $group = new Bugzilla::Group($id) + || ThrowUserError("invalid_group_ID"); + + # This can only happen if somebody hacked the enter_bug form. + ThrowCodeError("inactive_group", { name => $group->name }) + unless $group->is_active; + + my $membercontrol = $controls->{$id} + && $controls->{$id}->{membercontrol}; + my $othercontrol = $controls->{$id} + && $controls->{$id}->{othercontrol}; + + my $permit = ($membercontrol && $user->in_group($group->name)) + || $othercontrol; + + $add_groups{$id} = 1 if $permit; + } + + foreach my $id (keys %$controls) { + next unless $controls->{$id}->{'group'}->is_active; + my $membercontrol = $controls->{$id}->{membercontrol} || 0; + my $othercontrol = $controls->{$id}->{othercontrol} || 0; + + # Add groups required + if ($membercontrol == CONTROLMAPMANDATORY + || ($othercontrol == CONTROLMAPMANDATORY + && !$user->in_group_id($id))) + { + # User had no option, bug needs to be in this group. + $add_groups{$id} = 1; + } + } + + my @add_groups = keys %add_groups; + return \@add_groups; +} + +sub _check_keywords { + my ($invocant, $product, $keyword_string) = @_; + $keyword_string = trim($keyword_string); + return [] if (!$keyword_string + || !Bugzilla->user->in_group('editbugs', $product->id)); + + my %keywords; + foreach my $keyword (split(/[\s,]+/, $keyword_string)) { + next unless $keyword; + my $obj = new Bugzilla::Keyword({ name => $keyword }); + ThrowUserError("unknown_keyword", { keyword => $keyword }) if !$obj; + $keywords{$obj->id} = $obj; + } + return [values %keywords]; +} + +sub _check_product { + my ($invocant, $name) = @_; + # Check that the product exists and that the user + # is allowed to enter bugs into this product. + Bugzilla->user->can_enter_product($name, THROW_ERROR); + # can_enter_product already does everything that check_product + # would do for us, so we don't need to use it. + my $obj = new Bugzilla::Product({ name => $name }); + return $obj; +} + +sub _check_op_sys { + my ($invocant, $op_sys) = @_; + $op_sys = trim($op_sys); + check_field('op_sys', $op_sys); + return $op_sys; +} + +sub _check_priority { + my ($invocant, $priority) = @_; + if (!Bugzilla->params->{'letsubmitterchoosepriority'}) { + $priority = Bugzilla->params->{'defaultpriority'}; + } + $priority = trim($priority); + check_field('priority', $priority); + + return $priority; +} + +sub _check_remaining_time { + return $_[0]->_check_time($_[1], 'remaining_time'); +} + +sub _check_rep_platform { + my ($invocant, $platform) = @_; + $platform = trim($platform); + check_field('rep_platform', $platform); + return $platform; +} + +sub _check_short_desc { + my ($invocant, $short_desc) = @_; + # Set the parameter to itself, but cleaned up + $short_desc = clean_text($short_desc) if $short_desc; + + if (!defined $short_desc || $short_desc eq '') { + ThrowUserError("require_summary"); + } + return $short_desc; +} + +sub _check_status_whiteboard { return defined $_[1] ? $_[1] : ''; } + +# Unlike other checkers, this one doesn't return anything. +sub _check_strict_isolation { + my ($invocant, $product, $cc_ids, $assignee_id, $qa_contact_id) = @_; + + return unless Bugzilla->params->{'strict_isolation'}; + + my @related_users = @$cc_ids; + push(@related_users, $assignee_id); + + if (Bugzilla->params->{'useqacontact'} && $qa_contact_id) { + push(@related_users, $qa_contact_id); + } + + # For each unique user in @related_users...(assignee and qa_contact + # could be duplicates of users in the CC list) + my %unique_users = map {$_ => 1} @related_users; + my @blocked_users; + foreach my $pid (keys %unique_users) { + my $related_user = Bugzilla::User->new($pid); + if (!$related_user->can_edit_product($product->id)) { + push (@blocked_users, $related_user->login); + } + } + if (scalar(@blocked_users)) { + ThrowUserError("invalid_user_group", + {'users' => \@blocked_users, + 'new' => 1, + 'product' => $product->name}); + } +} + +sub _check_target_milestone { + my ($invocant, $product, $target) = @_; + $target = trim($target); + $target = $product->default_milestone if !defined $target; + check_field('target_milestone', $target, + [map($_->name, @{$product->milestones})]); + return $target; +} + +sub _check_time { + my ($invocant, $time, $field) = @_; + my $tt_group = Bugzilla->params->{"timetrackinggroup"}; + return 0 unless $tt_group && Bugzilla->user->in_group($tt_group); + $time = trim($time) || 0; + ValidateTime($time, $field); + return $time; +} + +sub _check_qa_contact { + my ($invocant, $component, $name) = @_; + my $user = Bugzilla->user; + + return undef unless Bugzilla->params->{'useqacontact'}; + + $name = trim($name); + + my $id; + if (!$user->in_group('editbugs', $component->product_id) || !$name) { + # We want to insert NULL into the database if we get a 0. + $id = $component->default_qa_contact->id || undef; + } else { + $id = login_to_id($name, THROW_ERROR); + } + + return $id; +} + +sub _check_version { + my ($invocant, $product, $version) = @_; + $version = trim($version); + check_field('version', $version, [map($_->name, @{$product->versions})]); + return $version; +} + +sub _check_select_field { + my ($invocant, $value, $field) = @_; + $value = trim($value); + check_field($field, $value); + return $value; +} + +##################################################################### +# Class Accessors +##################################################################### + +sub fields { + my $class = shift; + + return ( + # Standard Fields + # Keep this ordering in sync with bugzilla.dtd. + qw(bug_id alias creation_ts short_desc delta_ts + reporter_accessible cclist_accessible + classification_id classification + product component version rep_platform op_sys + bug_status resolution dup_id + bug_file_loc status_whiteboard keywords + priority bug_severity target_milestone + dependson blocked votes everconfirmed + reporter assigned_to cc), + + # Conditional Fields + Bugzilla->params->{'useqacontact'} ? "qa_contact" : (), + Bugzilla->params->{'timetrackinggroup'} ? + qw(estimated_time remaining_time actual_time deadline) : (), + + # Custom Fields + Bugzilla->custom_field_names + ); +} + + +##################################################################### +# Instance Accessors ##################################################################### # These subs are in alphabetical order, as much as possible. @@ -340,7 +900,7 @@ sub actual_time { return $self->{'actual_time'} if exists $self->{'actual_time'}; if ( $self->{'error'} || - !Bugzilla->user->in_group(Param("timetrackinggroup")) ) { + !Bugzilla->user->in_group(Bugzilla->params->{"timetrackinggroup"}) ) { $self->{'actual_time'} = undef; return $self->{'actual_time'}; } @@ -412,6 +972,36 @@ sub cc { return $self->{'cc'}; } +sub component { + my ($self) = @_; + return $self->{component} if exists $self->{component}; + return '' if $self->{error}; + ($self->{component}) = Bugzilla->dbh->selectrow_array( + 'SELECT name FROM components WHERE id = ?', + undef, $self->{component_id}); + return $self->{component}; +} + +sub classification_id { + my ($self) = @_; + return $self->{classification_id} if exists $self->{classification_id}; + return 0 if $self->{error}; + ($self->{classification_id}) = Bugzilla->dbh->selectrow_array( + 'SELECT classification_id FROM products WHERE id = ?', + undef, $self->{product_id}); + return $self->{classification_id}; +} + +sub classification { + my ($self) = @_; + return $self->{classification} if exists $self->{classification}; + return '' if $self->{error}; + ($self->{classification}) = Bugzilla->dbh->selectrow_array( + 'SELECT name FROM classifications WHERE id = ?', + undef, $self->classification_id); + return $self->{classification}; +} + sub dependson { my ($self) = @_; return $self->{'dependson'} if exists $self->{'dependson'}; @@ -437,8 +1027,7 @@ sub flag_types { $flag_type->{'flags'} = Bugzilla::Flag::match( { 'bug_id' => $self->bug_id, 'type_id' => $flag_type->{'id'}, - 'target_type' => 'bug', - 'is_active' => 1 }); + 'target_type' => 'bug' }); } $self->{'flag_types'} = $flag_types; @@ -476,16 +1065,28 @@ sub milestoneurl { my ($self) = @_; return $self->{'milestoneurl'} if exists $self->{'milestoneurl'}; return '' if $self->{'error'}; - $self->{'milestoneurl'} = $::milestoneurl{$self->{product}}; + + $self->{'prod_obj'} ||= new Bugzilla::Product({name => $self->product}); + $self->{'milestoneurl'} = $self->{'prod_obj'}->milestone_url; return $self->{'milestoneurl'}; } +sub product { + my ($self) = @_; + return $self->{product} if exists $self->{product}; + return '' if $self->{error}; + ($self->{product}) = Bugzilla->dbh->selectrow_array( + 'SELECT name FROM products WHERE id = ?', + undef, $self->{product_id}); + return $self->{product}; +} + sub qa_contact { my ($self) = @_; return $self->{'qa_contact'} if exists $self->{'qa_contact'}; return undef if $self->{'error'}; - if (Param('useqacontact') && $self->{'qa_contact_id'}) { + if (Bugzilla->params->{'useqacontact'} && $self->{'qa_contact_id'}) { $self->{'qa_contact'} = new Bugzilla::User($self->{'qa_contact_id'}); } else { # XXX - This is somewhat inconsistent with the assignee/reporter @@ -521,8 +1122,7 @@ sub show_attachment_flags { 'component_id' => $self->{'component_id'} }); my $num_attachment_flags = Bugzilla::Flag::count( { 'target_type' => 'attachment', - 'bug_id' => $self->bug_id, - 'is_active' => 1 }); + 'bug_id' => $self->bug_id }); $self->{'show_attachment_flags'} = ($num_attachment_flag_types || $num_attachment_flags); @@ -530,17 +1130,14 @@ sub show_attachment_flags { return $self->{'show_attachment_flags'}; } - -sub use_keywords { - return @::legal_keywords; -} - sub use_votes { my ($self) = @_; return 0 if $self->{'error'}; - return Param('usevotes') - && $::prodmaxvotes{$self->{product}} > 0; + $self->{'prod_obj'} ||= new Bugzilla::Product({name => $self->product}); + + return Bugzilla->params->{'usevotes'} + && $self->{'prod_obj'}->votes_per_user > 0; } sub groups { @@ -615,23 +1212,18 @@ sub user { return {} if $self->{'error'}; my $user = Bugzilla->user; - my $canmove = Param('move-enabled') && $user->is_mover; - - # In the below, if the person hasn't logged in, then we treat them - # as if they can do anything. That's because we don't know why they - # haven't logged in; it may just be because they don't use cookies. - # Display everything as if they have all the permissions in the - # world; their permissions will get checked when they log in and - # actually try to make the change. - my $unknown_privileges = !$user->id - || $user->in_group("editbugs"); + my $canmove = Bugzilla->params->{'move-enabled'} && $user->is_mover; + + my $prod_id = $self->{'product_id'}; + + my $unknown_privileges = $user->in_group('editbugs', $prod_id); my $canedit = $unknown_privileges || $user->id == $self->{assigned_to_id} - || (Param('useqacontact') + || (Bugzilla->params->{'useqacontact'} && $self->{'qa_contact_id'} && $user->id == $self->{qa_contact_id}); my $canconfirm = $unknown_privileges - || $user->in_group("canconfirm"); + || $user->in_group('canconfirm', $prod_id); my $isreporter = $user->id && $user->id == $self->{reporter_id}; @@ -647,61 +1239,67 @@ sub choices { return $self->{'choices'} if exists $self->{'choices'}; return {} if $self->{'error'}; - &::GetVersionTable(); - $self->{'choices'} = {}; + $self->{prod_obj} ||= new Bugzilla::Product({name => $self->product}); - # Fiddle the product list. - my $seen_curr_prod; - my @prodlist; - - foreach my $product (@::enterable_products) { - if ($product eq $self->{'product'}) { - # if it's the product the bug is already in, it's ALWAYS in - # the popup, period, whether the user can see it or not, and - # regardless of the disallownew setting. - $seen_curr_prod = 1; - push(@prodlist, $product); - next; - } - - if (!Bugzilla->user->can_enter_product($product)) { - # If we're using bug groups to restrict entry on products, and - # this product has an entry group, and the user is not in that - # group, we don't want to include that product in this list. - next; - } - - push(@prodlist, $product); - } - + my @prodlist = map {$_->name} @{Bugzilla->user->get_enterable_products}; # The current product is part of the popup, even if new bugs are no longer # allowed for that product - if (!$seen_curr_prod) { - push (@prodlist, $self->{'product'}); + if (lsearch(\@prodlist, $self->product) < 0) { + push(@prodlist, $self->product); @prodlist = sort @prodlist; } # Hack - this array contains "". See bug 106589. - my @res = grep ($_, @::settable_resolution); + my @res = grep ($_, @{settable_resolutions()}); $self->{'choices'} = { 'product' => \@prodlist, - 'rep_platform' => \@::legal_platform, - 'priority' => \@::legal_priority, - 'bug_severity' => \@::legal_severity, - 'op_sys' => \@::legal_opsys, - 'bug_status' => \@::legal_bug_status, - 'resolution' => \@res, - 'component' => $::components{$self->{product}}, - 'version' => $::versions{$self->{product}}, - 'target_milestone' => $::target_milestone{$self->{product}}, + 'rep_platform' => get_legal_field_values('rep_platform'), + 'priority' => get_legal_field_values('priority'), + 'bug_severity' => get_legal_field_values('bug_severity'), + 'op_sys' => get_legal_field_values('op_sys'), + 'bug_status' => get_legal_field_values('bug_status'), + 'resolution' => \@res, + 'component' => [map($_->name, @{$self->{prod_obj}->components})], + 'version' => [map($_->name, @{$self->{prod_obj}->versions})], + 'target_milestone' => [map($_->name, @{$self->{prod_obj}->milestones})], }; return $self->{'choices'}; } +# List of resolutions that may be set directly by hand in the bug form. +# 'MOVED' and 'DUPLICATE' are excluded from the list because setting +# bugs to those resolutions requires a special process. +sub settable_resolutions { + my $resolutions = get_legal_field_values('resolution'); + my $pos = lsearch($resolutions, 'DUPLICATE'); + if ($pos >= 0) { + splice(@$resolutions, $pos, 1); + } + $pos = lsearch($resolutions, 'MOVED'); + if ($pos >= 0) { + splice(@$resolutions, $pos, 1); + } + return $resolutions; +} + +sub votes { + my ($self) = @_; + return 0 if $self->{error}; + return $self->{votes} if defined $self->{votes}; + + my $dbh = Bugzilla->dbh; + $self->{votes} = $dbh->selectrow_array( + 'SELECT SUM(vote_count) FROM votes + WHERE bug_id = ? ' . $dbh->sql_group_by('bug_id'), + undef, $self->bug_id); + $self->{votes} ||= 0; + return $self->{votes}; +} + # Convenience Function. If you need speed, use this. If you need # other Bug fields in addition to this, just create a new Bug with # the alias. @@ -709,7 +1307,7 @@ sub choices { # the ID of the bug if it exists or the undefined value if it doesn't. sub bug_alias_to_id { my ($alias) = @_; - return undef unless Param("usebugaliases"); + return undef unless Bugzilla->params->{"usebugaliases"}; my $dbh = Bugzilla->dbh; trick_taint($alias); return $dbh->selectrow_array( @@ -721,12 +1319,16 @@ sub bug_alias_to_id { ##################################################################### sub AppendComment { - my ($bugid, $whoid, $comment, $isprivate, $timestamp, $work_time) = @_; + my ($bugid, $whoid, $comment, $isprivate, $timestamp, $work_time, + $type, $extra_data) = @_; $work_time ||= 0; + $type ||= CMT_NORMAL; my $dbh = Bugzilla->dbh; ValidateTime($work_time, "work_time") if $work_time; trick_taint($work_time); + detaint_natural($type) + || ThrowCodeError('bad_arg', {argument => 'type', function => 'AppendComment'}); # Use the date/time we were given if possible (allowing calling code # to synchronize the comment's timestamp with those of other records). @@ -735,7 +1337,7 @@ sub AppendComment { $comment =~ s/\r\n/\n/g; # Handle Windows-style line endings. $comment =~ s/\r/\n/g; # Handle Mac-style line endings. - if ($comment =~ /^\s*$/) { # Nothin' but whitespace + if ($comment =~ /^\s*$/ && !$type) { # Nothin' but whitespace return; } @@ -744,13 +1346,60 @@ sub AppendComment { trick_taint($comment); my $privacyval = $isprivate ? 1 : 0 ; $dbh->do(q{INSERT INTO longdescs - (bug_id, who, bug_when, thetext, isprivate, work_time) - VALUES (?,?,?,?,?,?)}, undef, - ($bugid, $whoid, $timestamp, $comment, $privacyval, $work_time)); + (bug_id, who, bug_when, thetext, isprivate, work_time, + type, extra_data) + VALUES (?, ?, ?, ?, ?, ?, ?, ?)}, undef, + ($bugid, $whoid, $timestamp, $comment, $privacyval, $work_time, + $type, $extra_data)); $dbh->do("UPDATE bugs SET delta_ts = ? WHERE bug_id = ?", undef, $timestamp, $bugid); } +sub update_comment { + my ($self, $comment_id, $new_comment) = @_; + + # Some validation checks. + if ($self->{'error'}) { + ThrowCodeError("bug_error", { bug => $self }); + } + detaint_natural($comment_id) + || ThrowCodeError('bad_arg', {argument => 'comment_id', function => 'update_comment'}); + + # The comment ID must belong to this bug. + my @current_comment_obj = grep {$_->{'id'} == $comment_id} @{$self->longdescs}; + scalar(@current_comment_obj) + || ThrowCodeError('bad_arg', {argument => 'comment_id', function => 'update_comment'}); + + # If the new comment is undefined, then there is nothing to update. + # To delete a comment, an empty string should be passed. + return unless defined $new_comment; + $new_comment =~ s/\s*$//s; # Remove trailing whitespaces. + $new_comment =~ s/\r\n?/\n/g; # Handle Windows and Mac-style line endings. + trick_taint($new_comment); + + # We assume ValidateComment() has already been called earlier. + Bugzilla->dbh->do('UPDATE longdescs SET thetext = ? WHERE comment_id = ?', + undef, ($new_comment, $comment_id)); + + # Update the comment object with this new text. + $current_comment_obj[0]->{'body'} = $new_comment; +} + +# Represents which fields from the bugs table are handled by process_bug.cgi. +sub editable_bug_fields { + my @fields = Bugzilla->dbh->bz_table_columns('bugs'); + # Obsolete custom fields are not editable. + my @obsolete_fields = Bugzilla->get_fields({obsolete => 1, custom => 1}); + @obsolete_fields = map { $_->name } @obsolete_fields; + foreach my $remove ("bug_id", "creation_ts", "delta_ts", "lastdiffed", @obsolete_fields) { + my $location = lsearch(\@fields, $remove); + splice(@fields, $location, 1); + } + # Sorted because the old @::log_columns variable, which this replaces, + # was sorted. + return sort(@fields); +} + # XXX - When Bug::update() will be implemented, we should make this routine # a private method. sub EmitDependList { @@ -763,6 +1412,12 @@ sub EmitDependList { return $list_ref; } +# Tells you whether or not the argument is a valid "open" state. +sub is_open_state { + my ($state) = @_; + return (grep($_ eq $state, BUG_STATE_OPEN) ? 1 : 0); +} + sub ValidateTime { my ($time, $field) = @_; @@ -787,30 +1442,44 @@ sub ValidateTime { } sub GetComments { - my ($id, $comment_sort_order) = (@_); + my ($id, $comment_sort_order, $start, $end, $raw) = @_; + my $dbh = Bugzilla->dbh; + $comment_sort_order = $comment_sort_order || Bugzilla->user->settings->{'comment_sort_order'}->{'value'}; my $sort_order = ($comment_sort_order eq "oldest_to_newest") ? 'asc' : 'desc'; - my $dbh = Bugzilla->dbh; + my @comments; - my $sth = $dbh->prepare( - "SELECT profiles.realname AS name, profiles.login_name AS email, - " . $dbh->sql_date_format('longdescs.bug_when', '%Y.%m.%d %H:%i:%s') . " - AS time, longdescs.thetext AS body, longdescs.work_time, - isprivate, already_wrapped - FROM longdescs, profiles - WHERE profiles.userid = longdescs.who - AND longdescs.bug_id = ? - ORDER BY longdescs.bug_when $sort_order"); - $sth->execute($id); + my @args = ($id); + + my $query = 'SELECT longdescs.comment_id AS id, profiles.realname AS name, + profiles.login_name AS email, ' . + $dbh->sql_date_format('longdescs.bug_when', '%Y.%m.%d %H:%i:%s') . + ' AS time, longdescs.thetext AS body, longdescs.work_time, + isprivate, already_wrapped, type, extra_data + FROM longdescs + INNER JOIN profiles + ON profiles.userid = longdescs.who + WHERE longdescs.bug_id = ?'; + if ($start) { + $query .= ' AND longdescs.bug_when > ? + AND longdescs.bug_when <= ?'; + push(@args, ($start, $end)); + } + $query .= " ORDER BY longdescs.bug_when $sort_order"; + my $sth = $dbh->prepare($query); + $sth->execute(@args); while (my $comment_ref = $sth->fetchrow_hashref()) { my %comment = %$comment_ref; - $comment{'email'} .= Param('emailsuffix'); + $comment{'email'} .= Bugzilla->params->{'emailsuffix'}; $comment{'name'} = $comment{'name'} || $comment{'email'}; + # If raw data is requested, do not format 'special' comments. + $comment{'body'} = format_comment(\%comment) unless $raw; + push (@comments, \%comment); } @@ -821,6 +1490,32 @@ sub GetComments { return \@comments; } +# Format language specific comments. This routine must not update +# $comment{'body'} itself, see BugMail::prepare_comments(). +sub format_comment { + my $comment = shift; + my $body; + + if ($comment->{'type'} == CMT_DUPE_OF) { + $body = $comment->{'body'} . "\n\n" . + get_text('bug_duplicate_of', { dupe_of => $comment->{'extra_data'} }); + } + elsif ($comment->{'type'} == CMT_HAS_DUPE) { + $body = get_text('bug_has_duplicate', { dupe => $comment->{'extra_data'} }); + } + elsif ($comment->{'type'} == CMT_POPULAR_VOTES) { + $body = get_text('bug_confirmed_by_votes'); + } + elsif ($comment->{'type'} == CMT_MOVED_TO) { + $body = $comment->{'body'} . "\n\n" . + get_text('bug_moved_to', { login => $comment->{'extra_data'} }); + } + else { + $body = $comment->{'body'}; + } + return $body; +} + # Get the activity of a bug, starting from $starttime (if given). # This routine assumes ValidateBugID has been previously called. sub GetBugActivity { @@ -841,7 +1536,9 @@ sub GetBugActivity { # Only includes attachments the user is allowed to see. my $suppjoins = ""; my $suppwhere = ""; - if (Param("insidergroup") && !UserInGroup(Param('insidergroup'))) { + if (Bugzilla->params->{"insidergroup"} + && !Bugzilla->user->in_group(Bugzilla->params->{'insidergroup'})) + { $suppjoins = "LEFT JOIN attachments ON attachments.attach_id = bugs_activity.attach_id"; $suppwhere = "AND COALESCE(attachments.isprivate, 0) = 0"; @@ -860,7 +1557,7 @@ sub GetBugActivity { FROM bugs_activity $suppjoins LEFT JOIN fielddefs - ON bugs_activity.fieldid = fielddefs.fieldid + ON bugs_activity.fieldid = fielddefs.id INNER JOIN profiles ON profiles.userid = bugs_activity.who WHERE bugs_activity.bug_id = ? @@ -886,7 +1583,8 @@ sub GetBugActivity { || $fieldname eq 'work_time' || $fieldname eq 'deadline') { - $activity_visible = UserInGroup(Param('timetrackinggroup')) ? 1 : 0; + $activity_visible = + Bugzilla->user->in_group(Bugzilla->params->{'timetrackinggroup'}) ? 1 : 0; } else { $activity_visible = 1; } @@ -984,7 +1682,7 @@ sub CountOpenDependencies { "FROM bugs, dependencies " . "WHERE blocked IN (" . (join "," , @bug_list) . ") " . "AND bug_id = dependson " . - "AND bug_status IN ('" . (join "','", &::OpenStates()) . "') " . + "AND bug_status IN ('" . (join "','", BUG_STATE_OPEN) . "') " . $dbh->sql_group_by('blocked')); $sth->execute(); @@ -1025,6 +1723,11 @@ sub RemoveVotes { while (my ($name, $userid, $oldvotes, $votesperuser, $maxvotesperbug) = $sth->fetchrow_array()) { push(@list, [$name, $userid, $oldvotes, $votesperuser, $maxvotesperbug]); } + + # @messages stores all emails which have to be sent, if any. + # This array is passed to the caller which will send these emails itself. + my @messages = (); + if (scalar(@list)) { foreach my $ref (@list) { my ($name, $userid, $oldvotes, $votesperuser, $maxvotesperbug) = (@$ref); @@ -1068,24 +1771,27 @@ sub RemoveVotes { # Now lets send the e-mail to alert the user to the fact that their votes have # been reduced or removed. - my %substs; + my $vars = { - $substs{"to"} = $name . Param('emailsuffix'); - $substs{"bugid"} = $id; - $substs{"reason"} = $reason; + 'to' => $name . Bugzilla->params->{'emailsuffix'}, + 'bugid' => $id, + 'reason' => $reason, - $substs{"votesremoved"} = $removedvotes; - $substs{"votesold"} = $oldvotes; - $substs{"votesnew"} = $newvotes; + 'votesremoved' => $removedvotes, + 'votesold' => $oldvotes, + 'votesnew' => $newvotes, - $substs{"votesremovedtext"} = $removedvotestext; - $substs{"votesoldtext"} = $oldvotestext; - $substs{"votesnewtext"} = $newvotestext; + 'votesremovedtext' => $removedvotestext, + 'votesoldtext' => $oldvotestext, + 'votesnewtext' => $newvotestext, - $substs{"count"} = $removedvotes . "\n " . $newvotestext; + 'count' => $removedvotes . "\n " . $newvotestext + }; - my $msg = perform_substs(Param("voteremovedmail"), \%substs); - Bugzilla::BugMail::MessageToMTA($msg); + my $msg; + my $template = Bugzilla->template; + $template->process("email/votes-removed.txt.tmpl", $vars, \$msg); + push(@messages, $msg); } my $votes = $dbh->selectrow_array("SELECT SUM(vote_count) " . "FROM votes WHERE bug_id = ?", @@ -1093,6 +1799,8 @@ sub RemoveVotes { $dbh->do("UPDATE bugs SET votes = ? WHERE bug_id = ?", undef, ($votes, $id)); } + # Now return the array containing emails to be sent. + return \@messages; } # If a user votes for a bug, or the number of votes required to @@ -1132,15 +1840,145 @@ sub CheckIfVotedConfirmed { "VALUES (?, ?, ?, ?, ?, ?)", undef, ($id, $who, $timestamp, $fieldid, '0', '1')); - AppendComment($id, $who, - "*** This bug has been confirmed by popular vote. ***", - 0, $timestamp); + AppendComment($id, $who, "", 0, $timestamp, 0, CMT_POPULAR_VOTES); $ret = 1; } return $ret; } +################################################################################ +# check_can_change_field() defines what users are allowed to change. You +# can add code here for site-specific policy changes, according to the +# instructions given in the Bugzilla Guide and below. Note that you may also +# have to update the Bugzilla::Bug::user() function to give people access to the +# options that they are permitted to change. +# +# check_can_change_field() returns true if the user is allowed to change this +# field, and false if they are not. +# +# The parameters to this method are as follows: +# $field - name of the field in the bugs table the user is trying to change +# $oldvalue - what they are changing it from +# $newvalue - what they are changing it to +# $PrivilegesRequired - return the reason of the failure, if any +# $data - hash containing relevant parameters, e.g. from the CGI object +################################################################################ +sub check_can_change_field { + my $self = shift; + my ($field, $oldvalue, $newvalue, $PrivilegesRequired, $data) = (@_); + my $user = Bugzilla->user; + + $oldvalue = defined($oldvalue) ? $oldvalue : ''; + $newvalue = defined($newvalue) ? $newvalue : ''; + + # Return true if they haven't changed this field at all. + if ($oldvalue eq $newvalue) { + return 1; + } elsif (trim($oldvalue) eq trim($newvalue)) { + return 1; + # numeric fields need to be compared using == + } elsif (($field eq 'estimated_time' || $field eq 'remaining_time') + && $newvalue ne $data->{'dontchange'} + && $oldvalue == $newvalue) + { + return 1; + } + + # Allow anyone to change comments. + if ($field =~ /^longdesc/) { + return 1; + } + + # Ignore the assigned_to field if the bug is not being reassigned + if ($field eq 'assigned_to' + && $data->{'knob'} ne 'reassignbycomponent' + && $data->{'knob'} ne 'reassign') + { + return 1; + } + + # If the user isn't allowed to change a field, we must tell him who can. + # We store the required permission set into the $PrivilegesRequired + # variable which gets passed to the error template. + # + # $PrivilegesRequired = 0 : no privileges required; + # $PrivilegesRequired = 1 : the reporter, assignee or an empowered user; + # $PrivilegesRequired = 2 : the assignee or an empowered user; + # $PrivilegesRequired = 3 : an empowered user. + + # Allow anyone with (product-specific) "editbugs" privs to change anything. + if ($user->in_group('editbugs', $self->{'product_id'})) { + return 1; + } + + # *Only* users with (product-specific) "canconfirm" privs can confirm bugs. + if ($field eq 'canconfirm' + || ($field eq 'bug_status' + && $oldvalue eq 'UNCONFIRMED' + && is_open_state($newvalue))) + { + $$PrivilegesRequired = 3; + return $user->in_group('canconfirm', $self->{'product_id'}); + } + + # Make sure that a valid bug ID has been given. + if (!$self->{'error'}) { + # Allow the assignee to change anything else. + if ($self->{'assigned_to_id'} == $user->id) { + return 1; + } + + # Allow the QA contact to change anything else. + if (Bugzilla->params->{'useqacontact'} + && $self->{'qa_contact_id'} + && ($self->{'qa_contact_id'} == $user->id)) + { + return 1; + } + } + + # At this point, the user is either the reporter or an + # unprivileged user. We first check for fields the reporter + # is not allowed to change. + + # The reporter may not: + # - reassign bugs, unless the bugs are assigned to him; + # in that case we will have already returned 1 above + # when checking for the assignee of the bug. + if ($field eq 'assigned_to') { + $$PrivilegesRequired = 2; + return 0; + } + # - change the QA contact + if ($field eq 'qa_contact') { + $$PrivilegesRequired = 2; + return 0; + } + # - change the target milestone + if ($field eq 'target_milestone') { + $$PrivilegesRequired = 2; + return 0; + } + # - change the priority (unless he could have set it originally) + if ($field eq 'priority' + && !Bugzilla->params->{'letsubmitterchoosepriority'}) + { + $$PrivilegesRequired = 2; + return 0; + } + + # The reporter is allowed to change anything else. + if (!$self->{'error'} && $self->{'reporter_id'} == $user->id) { + return 1; + } + + # If we haven't returned by this point, then the user doesn't + # have the necessary permissions to change this field. + $$PrivilegesRequired = 1; + return 0; +} + # # Field Validation # @@ -1154,9 +1992,11 @@ sub ValidateBugID { my $dbh = Bugzilla->dbh; my $user = Bugzilla->user; - # Get rid of white-space around the ID. + # Get rid of leading '#' (number) mark, if present. + $id =~ s/^\s*#//; + # Remove whitespace $id = trim($id); - + # If the ID isn't a number, it might be an alias, so try to convert it. my $alias = $id; if (!detaint_natural($id)) { @@ -1219,7 +2059,7 @@ sub ValidateBugAlias { my $vars = {}; $vars->{'alias'} = $alias; if ($id) { - $vars->{'bug_link'} = &::GetBugLink($id, $id); + $vars->{'bug_id'} = $id; ThrowUserError("alias_in_use", $vars); } @@ -1239,6 +2079,7 @@ sub ValidateBugAlias { # Validate and return a hash of dependencies sub ValidateDependencies { my $fields = {}; + # These can be arrayrefs or they can be strings. $fields->{'dependson'} = shift; $fields->{'blocked'} = shift; my $id = shift || 0; @@ -1259,7 +2100,9 @@ sub ValidateDependencies { next unless $fields->{$target}; my %seen; - foreach my $i (split('[\s,]+', $fields->{$target})) { + my $target_array = ref($fields->{$target}) ? $fields->{$target} + : [split(/[\s,]+/, $fields->{$target})]; + foreach my $i (@$target_array) { if ($id == $i) { ThrowUserError("dependency_loop_single"); } @@ -1292,30 +2135,56 @@ sub ValidateDependencies { my @deps = @{$deptree{'dependson'}}; my @blocks = @{$deptree{'blocked'}}; - my @union = (); - my @isect = (); my %union = (); my %isect = (); foreach my $b (@deps, @blocks) { $union{$b}++ && $isect{$b}++ } - @union = keys %union; - @isect = keys %isect; + my @isect = keys %isect; if (scalar(@isect) > 0) { - my $both = ""; - foreach my $i (@isect) { - $both .= &::GetBugLink($i, "#" . $i) . " "; - } - ThrowUserError("dependency_loop_multi", { both => $both }); + ThrowUserError("dependency_loop_multi", {'deps' => \@isect}); } return %deps; } + +##################################################################### +# Autoloaded Accessors +##################################################################### + +# Determines whether an attribute access trapped by the AUTOLOAD function +# is for a valid bug attribute. Bug attributes are properties and methods +# predefined by this module as well as bug fields for which an accessor +# can be defined by AUTOLOAD at runtime when the accessor is first accessed. +# +# XXX Strangely, some predefined attributes are on the list, but others aren't, +# and the original code didn't specify why that is. Presumably the only +# attributes that need to be on this list are those that aren't predefined; +# we should verify that and update the list accordingly. +# +sub _validate_attribute { + my ($attribute) = @_; + + my @valid_attributes = ( + # Miscellaneous properties and methods. + qw(error groups product_id component_id + longdescs milestoneurl attachments + isopened isunconfirmed + flag_types num_attachment_flag_types + show_attachment_flags any_flags_requesteeble), + + # Bug fields. + Bugzilla::Bug->fields + ); + + return grep($attribute eq $_, @valid_attributes) ? 1 : 0; +} + sub AUTOLOAD { use vars qw($AUTOLOAD); my $attr = $AUTOLOAD; $attr =~ s/.*:://; return unless $attr=~ /[^A-Z]/; - if (!$ok_field{$attr}) { + if (!_validate_attribute($attr)) { require Carp; Carp::confess("invalid bug attribute $attr"); } diff --git a/Bugzilla/BugMail.pm b/Bugzilla/BugMail.pm index 3fd821be6..8b6f7678b 100644 --- a/Bugzilla/BugMail.pm +++ b/Bugzilla/BugMail.pm @@ -32,47 +32,31 @@ use strict; package Bugzilla::BugMail; +use Bugzilla::Error; use Bugzilla::User; use Bugzilla::Constants; -use Bugzilla::Config qw(:DEFAULT $datadir); use Bugzilla::Util; +use Bugzilla::Bug; +use Bugzilla::Product; +use Bugzilla::Component; +use Bugzilla::Mailer; use Date::Parse; use Date::Format; -use Mail::Mailer; -use Mail::Header; -use MIME::Base64; -use MIME::QuotedPrint; -use MIME::Parser; -use Mail::Address; + +use constant BIT_DIRECT => 1; +use constant BIT_WATCHING => 2; # We need these strings for the X-Bugzilla-Reasons header # Note: this hash uses "," rather than "=>" to avoid auto-quoting of the LHS. -my %rel_names = (REL_ASSIGNEE , "AssignedTo", - REL_REPORTER , "Reporter", - REL_QA , "QAcontact", - REL_CC , "CC", - REL_VOTER , "Voter"); - -# This code is really ugly. It was a commandline interface, then it was moved. -# This really needs to be cleaned at some point. - -my %nomail; - -my $sitespec = '@'.Param('urlbase'); -$sitespec =~ s/:\/\//\./; # Make the protocol look like part of the domain -$sitespec =~ s/^([^:\/]+):(\d+)/$1/; # Remove a port number, to relocate -if ($2) { - $sitespec = "-$2$sitespec"; # Put the port number back in, before the '@' -} - -# This is run when we load the package -if (open(NOMAIL, '<', "$datadir/nomail")) { - while (<NOMAIL>) { - $nomail{trim($_)} = 1; - } - close(NOMAIL); -} +use constant REL_NAMES => { + REL_ASSIGNEE , "AssignedTo", + REL_REPORTER , "Reporter", + REL_QA , "QAcontact", + REL_CC , "CC", + REL_VOTER , "Voter", + REL_GLOBAL_WATCHER, "GlobalWatcher" +}; sub FormatTriple { my ($a, $b, $c) = (@_); @@ -108,16 +92,6 @@ END sub Send { my ($id, $forced) = (@_); - # This only works in a sub. Probably something to do with the - # require abuse we do. - &::GetVersionTable(); - - return ProcessOneBug($id, $forced); -} - -sub ProcessOneBug { - my ($id, $forced) = (@_); - my @headerlist; my %defmailhead; my %fielddescription; @@ -125,25 +99,26 @@ sub ProcessOneBug { my $msg = ""; my $dbh = Bugzilla->dbh; - - my $fields = $dbh->selectall_arrayref('SELECT name, description, mailhead - FROM fielddefs ORDER BY sortkey'); - - foreach my $fielddef (@$fields) { - my ($field, $description, $mailhead) = @$fielddef; - push(@headerlist, $field); - $defmailhead{$field} = $mailhead; - $fielddescription{$field} = $description; + + # XXX - These variables below are useless. We could use field object + # methods directly. But we first have to implement a cache in + # Bugzilla->get_fields to avoid querying the DB all the time. + foreach my $field (Bugzilla->get_fields({obsolete => 0})) { + push(@headerlist, $field->name); + $defmailhead{$field->name} = $field->in_new_bugmail; + $fielddescription{$field->name} = $field->description; } my %values = %{$dbh->selectrow_hashref( - 'SELECT ' . join(',', @::log_columns) . ', + 'SELECT ' . join(',', editable_bug_fields()) . ', lastdiffed AS start, LOCALTIMESTAMP(0) AS end FROM bugs WHERE bug_id = ?', undef, $id)}; - - $values{product} = &::get_product_name($values{product_id}); - $values{component} = &::get_component_name($values{component_id}); + + my $product = new Bugzilla::Product($values{product_id}); + $values{product} = $product->name; + my $component = new Bugzilla::Component($values{component_id}); + $values{component} = $component->name; my ($start, $end) = ($values{start}, $values{end}); @@ -173,24 +148,29 @@ sub ProcessOneBug { # At this point, we don't care if there are duplicates in these arrays. my $changer = $forced->{'changer'}; if ($forced->{'owner'}) { - push (@assignees, &::DBNameToIdAndCheck($forced->{'owner'})); + push (@assignees, login_to_id($forced->{'owner'}, THROW_ERROR)); } if ($forced->{'qacontact'}) { - push (@qa_contacts, &::DBNameToIdAndCheck($forced->{'qacontact'})); + push (@qa_contacts, login_to_id($forced->{'qacontact'}, THROW_ERROR)); } if ($forced->{'cc'}) { foreach my $cc (@{$forced->{'cc'}}) { - push(@ccs, &::DBNameToIdAndCheck($cc)); + push(@ccs, login_to_id($cc, THROW_ERROR)); } } # Convert to names, for later display - $values{'assigned_to'} = &::DBID_to_name($values{'assigned_to'}); - $values{'reporter'} = &::DBID_to_name($values{'reporter'}); + $values{'changer'} = $changer; + # If no changer is specified, then it has no name. + if ($changer) { + $values{'changername'} = Bugzilla::User->new({name => $changer})->name; + } + $values{'assigned_to'} = user_id_to_login($values{'assigned_to'}); + $values{'reporter'} = user_id_to_login($values{'reporter'}); if ($values{'qa_contact'}) { - $values{'qa_contact'} = &::DBID_to_name($values{'qa_contact'}); + $values{'qa_contact'} = user_id_to_login($values{'qa_contact'}); } $values{'cc'} = join(', ', @cc_login_names); $values{'estimated_time'} = format_time_decimal($values{'estimated_time'}); @@ -223,28 +203,33 @@ sub ProcessOneBug { } my $diffs = $dbh->selectall_arrayref( - "SELECT profiles.login_name, fielddefs.description, + "SELECT profiles.login_name, profiles.realname, fielddefs.description, bugs_activity.bug_when, bugs_activity.removed, bugs_activity.added, bugs_activity.attach_id, fielddefs.name FROM bugs_activity INNER JOIN fielddefs - ON fielddefs.fieldid = bugs_activity.fieldid + ON fielddefs.id = bugs_activity.fieldid INNER JOIN profiles ON profiles.userid = bugs_activity.who WHERE bugs_activity.bug_id = ? $when_restriction ORDER BY bugs_activity.bug_when", undef, @args); + my @new_depbugs; my $difftext = ""; my $diffheader = ""; my @diffparts; my $lastwho = ""; + my $fullwho; + my @changedfields; foreach my $ref (@$diffs) { - my ($who, $what, $when, $old, $new, $attachid, $fieldname) = (@$ref); + my ($who, $whoname, $what, $when, $old, $new, $attachid, $fieldname) = (@$ref); my $diffpart = {}; if ($who ne $lastwho) { $lastwho = $who; - $diffheader = "\n$who" . Param('emailsuffix') . " changed:\n\n"; + $fullwho = $whoname ? "$whoname <$who" . Bugzilla->params->{'emailsuffix'} . ">" : + "$who" . Bugzilla->params->{'emailsuffix'}; + $diffheader = "\n$fullwho changed:\n\n"; $diffheader .= FormatTriple("What ", "Removed", "Added"); $diffheader .= ('-' x 76) . "\n"; } @@ -254,6 +239,9 @@ sub ProcessOneBug { $old = format_time_decimal($old); $new = format_time_decimal($new); } + if ($fieldname eq 'dependson') { + push(@new_depbugs, grep {$_ =~ /^\d+$/} split(/[\s,]+/, $new)); + } if ($attachid) { ($diffpart->{'isprivate'}) = $dbh->selectrow_array( 'SELECT isprivate FROM attachments WHERE attach_id = ?', @@ -264,11 +252,23 @@ sub ProcessOneBug { $diffpart->{'fieldname'} = $fieldname; $diffpart->{'text'} = $difftext; push(@diffparts, $diffpart); + push(@changedfields, $what); } + $values{'changed_fields'} = join(' ', @changedfields); + my @depbugs; my $deptext = ""; + # Do not include data about dependent bugs when they have just been added. + # Completely skip checking for dependent bugs on bug creation as all + # dependencies bugs will just have been added. + if ($start) { + my $dep_restriction = ""; + if (scalar @new_depbugs) { + $dep_restriction = "AND bugs_activity.bug_id NOT IN (" . + join(", ", @new_depbugs) . ")"; + } - my $dependency_diffs = $dbh->selectall_arrayref( + my $dependency_diffs = $dbh->selectall_arrayref( "SELECT bugs_activity.bug_id, bugs.short_desc, fielddefs.name, bugs_activity.removed, bugs_activity.added FROM bugs_activity @@ -277,56 +277,56 @@ sub ProcessOneBug { INNER JOIN dependencies ON bugs_activity.bug_id = dependencies.dependson INNER JOIN fielddefs - ON fielddefs.fieldid = bugs_activity.fieldid + ON fielddefs.id = bugs_activity.fieldid WHERE dependencies.blocked = ? AND (fielddefs.name = 'bug_status' OR fielddefs.name = 'resolution') $when_restriction + $dep_restriction ORDER BY bugs_activity.bug_when, bugs.bug_id", undef, @args); - my $thisdiff = ""; - my $lastbug = ""; - my $interestingchange = 0; - my @depbugs; - foreach my $dependency_diff (@$dependency_diffs) { - my ($depbug, $summary, $what, $old, $new) = @$dependency_diff; + my $thisdiff = ""; + my $lastbug = ""; + my $interestingchange = 0; + foreach my $dependency_diff (@$dependency_diffs) { + my ($depbug, $summary, $what, $old, $new) = @$dependency_diff; - if ($depbug ne $lastbug) { - if ($interestingchange) { - $deptext .= $thisdiff; + if ($depbug ne $lastbug) { + if ($interestingchange) { + $deptext .= $thisdiff; + } + $lastbug = $depbug; + my $urlbase = Bugzilla->params->{"urlbase"}; + $thisdiff = + "\nBug $id depends on bug $depbug, which changed state.\n\n" . + "Bug $depbug Summary: $summary\n" . + "${urlbase}show_bug.cgi?id=$depbug\n\n"; + $thisdiff .= FormatTriple("What ", "Old Value", "New Value"); + $thisdiff .= ('-' x 76) . "\n"; + $interestingchange = 0; } - $lastbug = $depbug; - my $urlbase = Param("urlbase"); - $thisdiff = - "\nBug $id depends on bug $depbug, which changed state.\n\n" . - "Bug $depbug Summary: $summary\n" . - "${urlbase}show_bug.cgi?id=$depbug\n\n"; - $thisdiff .= FormatTriple("What ", "Old Value", "New Value"); - $thisdiff .= ('-' x 76) . "\n"; - $interestingchange = 0; - } - $thisdiff .= FormatTriple($fielddescription{$what}, $old, $new); - if ($what eq 'bug_status' && &::IsOpenedState($old) ne &::IsOpenedState($new)) { - $interestingchange = 1; + $thisdiff .= FormatTriple($fielddescription{$what}, $old, $new); + if ($what eq 'bug_status' + && Bugzilla::Bug::is_open_state($old) ne Bugzilla::Bug::is_open_state($new)) + { + $interestingchange = 1; + } + push(@depbugs, $depbug); } - - push(@depbugs, $depbug); - } - - if ($interestingchange) { - $deptext .= $thisdiff; - } - $deptext = trim($deptext); + if ($interestingchange) { + $deptext .= $thisdiff; + } + $deptext = trim($deptext); - if ($deptext) { - my $diffpart = {}; - $diffpart->{'text'} = "\n" . trim("\n\n" . $deptext); - push(@diffparts, $diffpart); + if ($deptext) { + my $diffpart = {}; + $diffpart->{'text'} = "\n" . trim("\n\n" . $deptext); + push(@diffparts, $diffpart); + } } - - my ($newcomments, $anyprivate) = get_comments_by_bug($id, $start, $end); + my ($raw_comments, $anyprivate, $count) = get_comments_by_bug($id, $start, $end); ########################################################################### # Start of email filtering code @@ -334,6 +334,7 @@ sub ProcessOneBug { # A user_id => roles hash to keep track of people. my %recipients; + my %watching; # Now we work out all the people involved with this bug, and note all of # the relationships in a hash. The keys are userids, the values are an @@ -343,29 +344,29 @@ sub ProcessOneBug { my $voters = $dbh->selectcol_arrayref( "SELECT who FROM votes WHERE bug_id = ?", undef, ($id)); - push(@{$recipients{$_}}, REL_VOTER) foreach (@$voters); + $recipients{$_}->{+REL_VOTER} = BIT_DIRECT foreach (@$voters); # CCs - push(@{$recipients{$_}}, REL_CC) foreach (@ccs); + $recipients{$_}->{+REL_CC} = BIT_DIRECT foreach (@ccs); # Reporter (there's only ever one) - push(@{$recipients{$reporter}}, REL_REPORTER); + $recipients{$reporter}->{+REL_REPORTER} = BIT_DIRECT; # QA Contact - if (Param('useqacontact')) { + if (Bugzilla->params->{'useqacontact'}) { foreach (@qa_contacts) { # QA Contact can be blank; ignore it if so. - push(@{$recipients{$_}}, REL_QA) if $_; + $recipients{$_}->{+REL_QA} = BIT_DIRECT if $_; } } # Assignee - push(@{$recipients{$_}}, REL_ASSIGNEE) foreach (@assignees); + $recipients{$_}->{+REL_ASSIGNEE} = BIT_DIRECT foreach (@assignees); # The last relevant set of people are those who are being removed from # their roles in this change. We get their names out of the diffs. foreach my $ref (@$diffs) { - my ($who, $what, $when, $old, $new) = (@$ref); + my ($who, $whoname, $what, $when, $old, $new) = (@$ref); if ($old) { # You can't stop being the reporter, and mail isn't sent if you # remove your vote. @@ -373,77 +374,102 @@ sub ProcessOneBug { if ($what eq "CC") { foreach my $cc_user (split(/[\s,]+/, $old)) { my $uid = login_to_id($cc_user); - push(@{$recipients{$uid}}, REL_CC) if $uid; + $recipients{$uid}->{+REL_CC} = BIT_DIRECT if $uid; } } elsif ($what eq "QAContact") { my $uid = login_to_id($old); - push(@{$recipients{$uid}}, REL_QA) if $uid; + $recipients{$uid}->{+REL_QA} = BIT_DIRECT if $uid; } elsif ($what eq "AssignedTo") { my $uid = login_to_id($old); - push(@{$recipients{$uid}}, REL_ASSIGNEE) if $uid; + $recipients{$uid}->{+REL_ASSIGNEE} = BIT_DIRECT if $uid; } } } - if (Param("supportwatchers")) { + if (Bugzilla->params->{"supportwatchers"}) { # Find all those user-watching anyone on the current list, who is not # on it already themselves. my $involved = join(",", keys %recipients); my $userwatchers = $dbh->selectall_arrayref("SELECT watcher, watched FROM watch - WHERE watched IN ($involved) - AND watcher NOT IN ($involved)"); + WHERE watched IN ($involved)"); # Mark these people as having the role of the person they are watching foreach my $watch (@$userwatchers) { - $recipients{$watch->[0]} = $recipients{$watch->[1]}; + while (my ($role, $bits) = each %{$recipients{$watch->[1]}}) { + $recipients{$watch->[0]}->{$role} |= BIT_WATCHING + if $bits & BIT_DIRECT; + } + push (@{$watching{$watch->[0]}}, $watch->[1]); } } - + + # Global watcher + my @watchers = split(/[,\s]+/, Bugzilla->params->{'globalwatchers'}); + foreach (@watchers) { + my $watcher_id = login_to_id($_); + next unless $watcher_id; + $recipients{$watcher_id}->{+REL_GLOBAL_WATCHER} = BIT_DIRECT; + } + # We now have a complete set of all the users, and their relationships to # the bug in question. However, we are not necessarily going to mail them # all - there are preferences, permissions checks and all sorts to do yet. my @sent; my @excluded; + # Some comments are language specific. We cache them here. + my %comments; + foreach my $user_id (keys %recipients) { - my @rels_which_want; + my %rels_which_want; my $sent_mail = 0; my $user = new Bugzilla::User($user_id); # Deleted users must be excluded. next unless $user; - if ($user->can_see_bug($id)) - { + # What's the language chosen by this user for email? + my $lang = $user->settings->{'lang'}->{'value'}; + + if ($user->can_see_bug($id)) { + # It's time to format language specific comments. + unless (exists $comments{$lang}) { + Bugzilla->template_inner($lang); + $comments{$lang} = prepare_comments($raw_comments, $count); + Bugzilla->template_inner(""); + } + # Go through each role the user has and see if they want mail in # that role. - foreach my $relationship (@{$recipients{$user_id}}) { + foreach my $relationship (keys %{$recipients{$user_id}}) { if ($user->wants_bug_mail($id, $relationship, $diffs, - $newcomments, + $comments{$lang}, + $deptext, $changer, !$start)) { - push(@rels_which_want, $relationship); + $rels_which_want{$relationship} = + $recipients{$user_id}->{$relationship}; } } } - if (scalar(@rels_which_want)) { + if (scalar(%rels_which_want)) { # So the user exists, can see the bug, and wants mail in at least # one role. But do we want to send it to them? # If we are using insiders, and the comment is private, only send # to insiders my $insider_ok = 1; - $insider_ok = 0 if (Param("insidergroup") && + $insider_ok = 0 if (Bugzilla->params->{"insidergroup"} && ($anyprivate != 0) && - (!$user->groups->{Param("insidergroup")})); + (!$user->groups->{Bugzilla->params->{"insidergroup"}})); # We shouldn't send mail if this is a dependency mail (i.e. there # is something in @depbugs), and any of the depending bugs are not @@ -459,22 +485,24 @@ sub ProcessOneBug { # Make sure the user isn't in the nomail list, and the insider and # dep checks passed. - if ((!$nomail{$user->login}) && + if ($user->email_enabled && $insider_ok && $dep_ok) { # OK, OK, if we must. Email the user. $sent_mail = sendMail($user, \@headerlist, - \@rels_which_want, + \%rels_which_want, \%values, \%defmailhead, \%fielddescription, \@diffparts, - $newcomments, + $comments{$lang}, $anyprivate, $start, - $id); + $id, + exists $watching{$user_id} ? + $watching{$user_id} : undef); } } @@ -495,7 +523,7 @@ sub ProcessOneBug { sub sendMail { my ($user, $hlRef, $relRef, $valueRef, $dmhRef, $fdRef, $diffRef, $newcomments, $anyprivate, $start, - $id) = @_; + $id, $watchingRef) = @_; my %values = %$valueRef; my @headerlist = @$hlRef; @@ -513,7 +541,7 @@ sub sendMail { } # Only send estimated_time if it is enabled and the user is in the group if (($f ne 'estimated_time' && $f ne 'deadline') || - $user->groups->{Param('timetrackinggroup')}) { + $user->groups->{Bugzilla->params->{'timetrackinggroup'}}) { my $desc = $fielddescription{$f}; $head .= FormatDouble($desc, $value); @@ -534,12 +562,12 @@ sub sendMail { $diff->{'fieldname'} eq 'remaining_time' || $diff->{'fieldname'} eq 'work_time' || $diff->{'fieldname'} eq 'deadline')){ - if ($user->groups->{Param("timetrackinggroup")}) { + if ($user->groups->{Bugzilla->params->{"timetrackinggroup"}}) { $add_diff = 1; } } elsif (($diff->{'isprivate'}) - && Param('insidergroup') - && !($user->groups->{Param('insidergroup')}) + && Bugzilla->params->{'insidergroup'} + && !($user->groups->{Bugzilla->params->{'insidergroup'}}) ) { $add_diff = 0; } else { @@ -561,246 +589,86 @@ sub sendMail { return 0; } - # XXX: This needs making localisable, probably by passing the role to - # the email template and letting it choose the text. - my $reasonsbody = "------- You are receiving this mail because: -------\n"; - - foreach my $relationship (@$relRef) { - if ($relationship == REL_ASSIGNEE) { - $reasonsbody .= "You are the assignee for the bug, or are watching the assignee.\n"; - } elsif ($relationship == REL_REPORTER) { - $reasonsbody .= "You reported the bug, or are watching the reporter.\n"; - } elsif ($relationship == REL_QA) { - $reasonsbody .= "You are the QA contact for the bug, or are watching the QA contact.\n"; - } elsif ($relationship == REL_CC) { - $reasonsbody .= "You are on the CC list for the bug, or are watching someone who is.\n"; - } elsif ($relationship == REL_VOTER) { - $reasonsbody .= "You are a voter for the bug, or are watching someone who is.\n"; - } - } - my $isnew = !$start; - my %substs; - # If an attachment was created, then add an URL. (Note: the 'g'lobal # replace should work with comments with multiple attachments.) if ( $newcomments =~ /Created an attachment \(/ ) { my $showattachurlbase = - Param('urlbase') . "attachment.cgi?id="; + Bugzilla->params->{'urlbase'} . "attachment.cgi?id="; - $newcomments =~ s/(Created an attachment \(id=([0-9]+)\))/$1\n --> \(${showattachurlbase}$2&action=view\)/g; + $newcomments =~ s/(Created an attachment \(id=([0-9]+)\))/$1\n --> \(${showattachurlbase}$2\)/g; } - $substs{"neworchanged"} = $isnew ? 'New: ' : ''; - $substs{"to"} = $user->email; - $substs{"cc"} = ''; - $substs{"bugid"} = $id; + my $diffs = $difftext . "\n\n" . $newcomments; if ($isnew) { - $substs{"diffs"} = $head . "\n\n" . $newcomments; - } else { - $substs{"diffs"} = $difftext . "\n\n" . $newcomments; + $diffs = $head . ($difftext ? "\n\n" : "") . $diffs; } - $substs{"product"} = $values{'product'}; - $substs{"component"} = $values{'component'}; - $substs{"keywords"} = $values{'keywords'}; - $substs{"severity"} = $values{'bug_severity'}; - $substs{"summary"} = $values{'short_desc'}; - $substs{"reasonsheader"} = join(" ", map { $rel_names{$_} } @$relRef); - $substs{"reasonsbody"} = $reasonsbody; - $substs{"space"} = " "; - if ($isnew) { - $substs{'threadingmarker'} = "Message-ID: <bug-$id-" . - $user->id . "$sitespec>"; - } else { - $substs{'threadingmarker'} = "In-Reply-To: <bug-$id-" . - $user->id . "$sitespec>"; - } - - my $template = Param("newchangedmail"); - - my $msg = perform_substs($template, \%substs); - - MessageToMTA($msg); - - return 1; -} - -sub MessageToMTA { - my ($msg) = (@_); - return if (Param('mail_delivery_method') eq "none"); - my ($header, $body) = $msg =~ /(.*?\n)\n(.*)/s ? ($1, $2) : ('', $msg); - my $headers; - - if (Param('utf8') and (!is_7bit_clean($header) or !is_7bit_clean($body))) { - ($headers, $body) = encode_message($msg); - } else { - my @header_lines = split(/\n/, $header); - $headers = new Mail::Header \@header_lines, Modify => 0; + my (@reasons, @reasons_watch); + while (my ($relationship, $bits) = each %{$relRef}) { + push(@reasons, $relationship) if ($bits & BIT_DIRECT); + push(@reasons_watch, $relationship) if ($bits & BIT_WATCHING); } - # Use trim to remove any whitespace (incl. newlines) - my $from = trim($headers->get('from')); - - if (Param("mail_delivery_method") eq "sendmail" && $^O =~ /MSWin32/i) { - my $cmd = '|' . SENDMAIL_EXE . ' -t -i'; - if ($from) { - # We're on Windows, thus no danger of command injection - # via $from. In other words, it is safe to embed $from. - $cmd .= qq# -f"$from"#; - } - open(SENDMAIL, $cmd) || - die "Failed to execute " . SENDMAIL_EXE . ": $!\n"; - print SENDMAIL $headers->as_string; - print SENDMAIL "\n"; - print SENDMAIL $body; - close SENDMAIL; - return; - } + my @headerrel = map { REL_NAMES->{$_} } @reasons; + my @watchingrel = map { REL_NAMES->{$_} } @reasons_watch; + push(@headerrel, 'None') unless @headerrel; + push(@watchingrel, 'None') unless @watchingrel; + push @watchingrel, map { user_id_to_login($_) } @$watchingRef; - my @args; - if (Param("mail_delivery_method") eq "sendmail") { - push @args, "-i"; - if ($from) { - push(@args, "-f$from"); - } + my $sitespec = '@' . Bugzilla->params->{'urlbase'}; + $sitespec =~ s/:\/\//\./; # Make the protocol look like part of the domain + $sitespec =~ s/^([^:\/]+):(\d+)/$1/; # Remove a port number, to relocate + if ($2) { + $sitespec = "-$2$sitespec"; # Put the port number back in, before the '@' } - if (Param("mail_delivery_method") eq "sendmail" && !Param("sendmailnow")) { - push @args, "-ODeliveryMode=deferred"; - } - if (Param("mail_delivery_method") eq "smtp") { - push @args, Server => Param("smtpserver"); - if ($from) { - $ENV{'MAILADDRESS'} = $from; - } - } - my $mailer = new Mail::Mailer Param("mail_delivery_method"), @args; - if (Param("mail_delivery_method") eq "testfile") { - $Mail::Mailer::testfile::config{outfile} = "$datadir/mailer.testfile"; + my $threadingmarker; + if ($isnew) { + $threadingmarker = "Message-ID: <bug-$id-" . $user->id . "$sitespec>"; + } else { + $threadingmarker = "In-Reply-To: <bug-$id-" . $user->id . "$sitespec>"; } - $mailer->open($headers->header_hashref); - print $mailer $body; - $mailer->close; -} -sub encode_qp_words { - my ($line) = (@_); - my @encoded; - foreach my $word (split / /, $line) { - if (!is_7bit_clean($word)) { - push @encoded, '=?UTF-8?Q?_' . encode_qp($word, '') . '?='; - } else { - push @encoded, $word; - } - } - return join(' ', @encoded); -} - -sub encode_message { - my ($msg) = @_; - - my $parser = MIME::Parser->new; - $parser->output_to_core(1); - $parser->tmp_to_core(1); - my $entity = $parser->parse_data($msg); - $entity = encode_message_entity($entity); - - my @header_lines = split(/\n/, $entity->header_as_string); - my $head = new Mail::Header \@header_lines, Modify => 0; - - my $body = $entity->body_as_string; - - return ($head, $body); -} + my $vars = { + neworchanged => $isnew ? 'New: ' : '', + to => $user->email, + bugid => $id, + product => $values{'product'}, + comp => $values{'component'}, + keywords => $values{'keywords'}, + severity => $values{'bug_severity'}, + status => $values{'bug_status'}, + priority => $values{'priority'}, + assignedto => $values{'assigned_to'}, + targetmilestone => $values{'target_milestone'}, + changedfields => $values{'changed_fields'}, + summary => $values{'short_desc'}, + reasons => \@reasons, + reasons_watch => \@reasons_watch, + reasonsheader => join(" ", @headerrel), + reasonswatchheader => join(" ", @watchingrel), + changer => $values{'changer'}, + changername => $values{'changername'}, + diffs => $diffs, + threadingmarker => $threadingmarker + }; + + my $msg; + my $template = Bugzilla->template_inner($user->settings->{'lang'}->{'value'}); + $template->process("email/newchangedmail.txt.tmpl", $vars, \$msg) + || ThrowTemplateError($template->error()); + Bugzilla->template_inner(""); -sub encode_message_entity { - my ($entity) = @_; - - my $head = $entity->head; - - # encode the subject - - my $subject = $head->get('subject'); - if (defined $subject && !is_7bit_clean($subject)) { - $subject =~ s/[\r\n]+$//; - $head->replace('subject', encode_qp_words($subject)); - } - - # encode addresses - - foreach my $field (qw(from to cc reply-to sender errors-to)) { - my $high = $head->count($field) - 1; - foreach my $index (0..$high) { - my $value = $head->get($field, $index); - my @addresses; - my $changed = 0; - foreach my $addr (Mail::Address->parse($value)) { - my $phrase = $addr->phrase; - if (is_7bit_clean($phrase)) { - push @addresses, $addr->format; - } else { - push @addresses, encode_qp_phrase($phrase) . - ' <' . $addr->address . '>'; - $changed = 1; - } - } - $changed && $head->replace($field, join(', ', @addresses), $index); - } - } - - # process the body - - if (scalar($entity->parts)) { - my $newparts = []; - foreach my $part ($entity->parts) { - my $newpart = encode_message_entity($part); - push @$newparts, $newpart; - } - $entity->parts($newparts); - } - else { - # Extract the body from the entity, for examination - # At this point, we can rely on MIME::Tools to do our encoding for us! - my $bodyhandle = $entity->bodyhandle; - my $body = $bodyhandle->as_string; - if (!is_7bit_clean($body)) { - # count number of 7-bit chars, and use quoted-printable if more - # than half the message is 7-bit clean - my $count = ($body =~ tr/\x20-\x7E\x0A\x0D//); - if ($count > length($body) / 2) { - $head->mime_attr('Content-Transfer-Encoding' => 'quoted-printable'); - } else { - $head->mime_attr('Content-Transfer-Encoding' => 'base64'); - } - } - - # Set the content/type and charset of the part, if not set - $head->mime_attr('Content-Type' => 'text/plain') - unless defined $head->mime_attr('content-type'); - $head->mime_attr('Content-Type.charset' => 'UTF-8'); - } - - $head->mime_attr('MIME-Version' => '1.0'); - $head->fold(75); - return $entity; -} - -# Send the login name and password of the newly created account to the user. -sub MailPassword { - my ($login, $password) = (@_); - my $template = Param("passwordmail"); - my $msg = perform_substs($template, - {"mailaddress" => $login . Param('emailsuffix'), - "login" => $login, - "password" => $password}); MessageToMTA($msg); + + return 1; } -# Get bug comments for the given period and format them to be used in emails. +# Get bug comments for the given period. sub get_comments_by_bug { my ($id, $start, $end) = @_; my $dbh = Bugzilla->dbh; @@ -809,17 +677,6 @@ sub get_comments_by_bug { my $count = 0; my $anyprivate = 0; - my $query = 'SELECT profiles.login_name, ' . - $dbh->sql_date_format('longdescs.bug_when', '%Y.%m.%d %H:%i') . ', - longdescs.thetext, longdescs.isprivate, - longdescs.already_wrapped - FROM longdescs - INNER JOIN profiles - ON profiles.userid = longdescs.who - WHERE longdescs.bug_id = ? '; - - my @args = ($id); - # $start will be undef for new bugs, and defined for pre-existing bugs. if ($start) { # If $start is not NULL, obtain the count-index @@ -827,29 +684,41 @@ sub get_comments_by_bug { $count = $dbh->selectrow_array('SELECT COUNT(*) FROM longdescs WHERE bug_id = ? AND bug_when <= ?', undef, ($id, $start)); + } - $query .= ' AND longdescs.bug_when > ? - AND longdescs.bug_when <= ? '; - push @args, ($start, $end); + my $raw = 1; # Do not format comments which are not of type CMT_NORMAL. + my $comments = Bugzilla::Bug::GetComments($id, "oldest_to_newest", $start, $end, $raw); + + if (Bugzilla->params->{'insidergroup'}) { + $anyprivate = 1 if scalar(grep {$_->{'isprivate'} > 0} @$comments); } - $query .= ' ORDER BY longdescs.bug_when'; - my $comments = $dbh->selectall_arrayref($query, undef, @args); + return ($comments, $anyprivate, $count); +} + +# Prepare comments for the given language. +sub prepare_comments { + my ($raw_comments, $count) = @_; - foreach (@$comments) { - my ($who, $when, $text, $isprivate, $already_wrapped) = @$_; + my $result = ""; + foreach my $comment (@$raw_comments) { if ($count) { - $result .= "\n\n------- Comment #$count from $who" . - Param('emailsuffix'). " " . format_time($when) . - " -------\n"; - } - if ($isprivate > 0 && Param('insidergroup')) { - $anyprivate = 1; + $result .= "\n\n--- Comment #$count from "; + if ($comment->{'name'} eq $comment->{'email'}) { + $result .= $comment->{'email'}; + } else { + $result .= $comment->{'name'} . " <" . $comment->{'email'} . ">"; + } + $result .= " " . format_time($comment->{'time'}) . " ---\n"; } - $result .= ($already_wrapped ? $text : wrap_comment($text)); + # Format language specific comments. We don't update $comment->{'body'} + # directly, otherwise it would grow everytime you call format_comment() + # with a different language as some text may be appended to the existing one. + my $body = Bugzilla::Bug::format_comment($comment); + $result .= ($comment->{'already_wrapped'} ? $body : wrap_comment($body)); $count++; } - return ($result, $anyprivate); + return $result; } 1; diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm index b84f18da6..7b76f6af0 100644 --- a/Bugzilla/CGI.pm +++ b/Bugzilla/CGI.pm @@ -37,13 +37,19 @@ use CGI qw(-no_xhtml -oldstyle_urls :private_tempfiles :unique_headers SERVER_PU use base qw(CGI); +use Bugzilla::Constants; use Bugzilla::Error; use Bugzilla::Util; -use Bugzilla::Config; # We need to disable output buffering - see bug 179174 $| = 1; +# Ignore SIGTERM and SIGPIPE - this prevents DB corruption. If the user closes +# their browser window while a script is running, the webserver sends these +# signals, and we don't want to die half way through a write. +$::SIG{TERM} = 'IGNORE'; +$::SIG{PIPE} = 'IGNORE'; + # CGI.pm uses AUTOLOAD, but explicitly defines a DESTROY sub. # We need to do so, too, otherwise perl dies when the object is destroyed # and we don't have a DESTROY method (because CGI.pm's AUTOLOAD will |die| @@ -56,20 +62,25 @@ sub new { my $self = $class->SUPER::new(@args); - # This happens here so that command-line scripts don't spit out - # their errors in HTML format. - require CGI::Carp; - import CGI::Carp qw(fatalsToBrowser); + if (Bugzilla->error_mode eq ERROR_MODE_WEBPAGE) { + # This happens here so that command-line scripts don't spit out + # their errors in HTML format. + require CGI::Carp; + import CGI::Carp qw(fatalsToBrowser); + } # Make sure our outgoing cookie list is empty on each invocation $self->{Bugzilla_cookie_list} = []; # Send appropriate charset - $self->charset(Param('utf8') ? 'UTF-8' : ''); + $self->charset(Bugzilla->params->{'utf8'} ? 'UTF-8' : ''); # Redirect to SSL if required - if (Param('sslbase') ne '' and Param('ssl') eq 'always' and i_am_cgi()) { - $self->require_https(Param('sslbase')); + if (Bugzilla->params->{'sslbase'} ne '' + && Bugzilla->params->{'ssl'} eq 'always' + && i_am_cgi()) + { + $self->require_https(Bugzilla->params->{'sslbase'}); } # Check for errors @@ -79,13 +90,6 @@ sub new { my $err = $self->cgi_error; if ($err) { - # XXX - under mod_perl we can use the request object to - # enable the apache ErrorDocument stuff, which is localisable - # (and localised by default under apache2). - # This doesn't appear to be possible under mod_cgi. - # Under mod_perl v2, though, this happens automatically, and the - # message body is ignored. - # Note that this error block is only triggered by CGI.pm for malformed # multipart requests, and so should never happen unless there is a # browser bug. @@ -131,6 +135,31 @@ sub canonicalise_query { return join("&", @parameters); } +sub clean_search_url { + my $self = shift; + # Delete any empty URL parameter + my @cgi_params = $self->param; + + foreach my $param (@cgi_params) { + if (defined $self->param($param) && $self->param($param) eq '') { + $self->delete($param); + $self->delete("${param}_type"); + } + + # Boolean Chart stuff is empty if it's "noop" + if ($param =~ /\d-\d-\d/ && defined $self->param($param) + && $self->param($param) eq 'noop') + { + $self->delete($param); + } + } + + # Delete certain parameters if the associated parameter is empty. + $self->delete('bugidtype') if !$self->param('bug_id'); + $self->delete('emailtype1') if !$self->param('email1'); + $self->delete('emailtype2') if !$self->param('email2'); +} + # Overwrite to ensure nph doesn't get set, and unset HEADERS_ONCE sub multipart_init { my $self = shift; @@ -154,14 +183,39 @@ sub multipart_init { # CGI.pm's header() sets nph according to a param or $CGI::NPH, which # is the desired behaviour. - # Allow multiple calls to $cgi->header() - $CGI::HEADERS_ONCE = 0; - return $self->header( %param, ) . "WARNING: YOUR BROWSER DOESN'T SUPPORT THIS SERVER-PUSH TECHNOLOGY." . $self->multipart_end; } +# Have to add the cookies in. +sub multipart_start { + my $self = shift; + + my %args = @_; + + # CGI.pm::multipart_start doesn't accept a -charset parameter, so + # we do it ourselves here + if (defined $args{-charset} && defined $args{-type}) { + # Remove any existing charset specifier + $args{-type} =~ s/;.*$//; + # and add the specified one + $args{-type} .= "; charset=$args{-charset}"; + } + + my $headers = $self->SUPER::multipart_start(%args); + # Eliminate the one extra CRLF at the end. + $headers =~ s/$CGI::CRLF$//; + # Add the cookies. We have to do it this way instead of + # passing them to multpart_start, because CGI.pm's multipart_start + # doesn't understand a '-cookie' argument pointing to an arrayref. + foreach my $cookie (@{$self->{Bugzilla_cookie_list}}) { + $headers .= "Set-Cookie: ${cookie}${CGI::CRLF}"; + } + $headers .= $CGI::CRLF; + return $headers; +} + # Override header so we can add the cookies in sub header { my $self = shift; @@ -179,13 +233,6 @@ sub header { return $self->SUPER::header(@_) || ""; } -# Override multipart_start to ensure our cookies are added and avoid bad quoting of -# CGI's multipart_start (bug 275108) -sub multipart_start { - my $self = shift; - return $self->header(@_); -} - # The various parts of Bugzilla which create cookies don't want to have to # pass them around to all of the callers. Instead, store them locally here, # and then output as required from |header|. @@ -207,8 +254,9 @@ sub send_cookie { } # Add the default path and the domain in. - $paramhash{'-path'} = Param('cookiepath'); - $paramhash{'-domain'} = Param('cookiedomain') if Param('cookiedomain'); + $paramhash{'-path'} = Bugzilla->params->{'cookiepath'}; + $paramhash{'-domain'} = Bugzilla->params->{'cookiedomain'} + if Bugzilla->params->{'cookiedomain'}; # Move the param list back into an array for the call to cookie(). foreach (keys(%paramhash)) { diff --git a/Bugzilla/CVS/Entries b/Bugzilla/CVS/Entries index b172ca01a..5dc35d9df 100644 --- a/Bugzilla/CVS/Entries +++ b/Bugzilla/CVS/Entries @@ -1,32 +1,42 @@ -/.cvsignore/1.1/Mon Aug 26 22:24:55 2002//TBUGZILLA-2_22_3 -/Attachment.pm/1.30.2.1/Sat Oct 14 21:07:19 2006//TBUGZILLA-2_22_3 -/Auth.pm/1.12.2.1/Tue Feb 21 13:48:25 2006//TBUGZILLA-2_22_3 -/Bug.pm/1.104.2.6/Mon Nov 27 17:59:13 2006//TBUGZILLA-2_22_3 -/BugMail.pm/1.62.2.3/Fri Sep 22 23:00:32 2006//TBUGZILLA-2_22_3 -/CGI.pm/1.20.2.3/Tue Jul 25 23:23:49 2006//TBUGZILLA-2_22_3 -/Chart.pm/1.11.2.1/Mon Feb 19 22:22:03 2007//TBUGZILLA-2_22_3 -/Classification.pm/1.9/Fri Oct 28 10:33:18 2005//TBUGZILLA-2_22_3 -/Component.pm/1.9.2.1/Fri Mar 3 12:21:19 2006//TBUGZILLA-2_22_3 -/Config.pm/1.51.2.10/Thu Aug 23 18:45:15 2007//TBUGZILLA-2_22_3 -/Constants.pm/1.34.2.1/Sat Oct 14 20:30:54 2006//TBUGZILLA-2_22_3 -/DB.pm/1.71.2.5/Mon Aug 20 18:09:48 2007//TBUGZILLA-2_22_3 -/Error.pm/1.15.2.1/Sun Jul 22 22:25:16 2007//TBUGZILLA-2_22_3 -/Field.pm/1.9/Fri Jan 6 14:38:36 2006//TBUGZILLA-2_22_3 -/Flag.pm/1.59.2.2/Fri Jun 2 23:00:55 2006//TBUGZILLA-2_22_3 -/FlagType.pm/1.23.2.2/Thu Aug 24 21:49:38 2006//TBUGZILLA-2_22_3 -/Group.pm/1.10.2.1/Mon Oct 30 23:51:53 2006//TBUGZILLA-2_22_3 -/Milestone.pm/1.7/Thu Oct 6 18:45:46 2005//TBUGZILLA-2_22_3 -/Product.pm/1.15/Fri Oct 28 10:33:18 2005//TBUGZILLA-2_22_3 -/Search.pm/1.121.2.4/Thu Nov 9 21:58:53 2006//TBUGZILLA-2_22_3 -/Series.pm/1.11/Fri Sep 23 14:24:35 2005//TBUGZILLA-2_22_3 -/Template.pm/1.41.2.4/Wed Jul 4 22:58:18 2007//TBUGZILLA-2_22_3 -/Token.pm/1.39.2.2/Mon Nov 20 19:03:40 2006//TBUGZILLA-2_22_3 -/User.pm/1.101.2.5/Sat Oct 14 21:07:19 2006//TBUGZILLA-2_22_3 -/Util.pm/1.45.2.5/Sat Oct 14 20:30:54 2006//TBUGZILLA-2_22_3 -/Version.pm/1.7/Thu Oct 6 18:45:46 2005//TBUGZILLA-2_22_3 +/.cvsignore/1.1/Mon Aug 26 22:24:55 2002//TBUGZILLA-3_0 +/Attachment.pm/1.45/Sun Feb 4 15:36:46 2007//TBUGZILLA-3_0 +/Auth.pm/1.20/Wed Jul 12 11:51:43 2006//TBUGZILLA-3_0 +/Bug.pm/1.171/Sun Jan 28 21:19:12 2007//TBUGZILLA-3_0 +/BugMail.pm/1.104.2.1/Wed Feb 28 14:42:22 2007//TBUGZILLA-3_0 +/CGI.pm/1.31/Mon Nov 13 03:07:57 2006//TBUGZILLA-3_0 +/Chart.pm/1.15/Mon Feb 19 22:20:09 2007//TBUGZILLA-3_0 +/Classification.pm/1.11/Tue Dec 19 08:38:49 2006//TBUGZILLA-3_0 +/Component.pm/1.15/Fri Dec 22 18:10:21 2006//TBUGZILLA-3_0 +/Config.pm/1.70/Sat Dec 9 11:51:34 2006//TBUGZILLA-3_0 +/Constants.pm/1.68.2.3/Wed May 9 22:47:17 2007//TBUGZILLA-3_0 +/DB.pm/1.93.2.2/Thu Apr 19 13:01:03 2007//TBUGZILLA-3_0 +/Error.pm/1.19/Wed Oct 4 20:20:59 2006//TBUGZILLA-3_0 +/Field.pm/1.24.2.1/Sun Apr 15 01:34:57 2007//TBUGZILLA-3_0 +/Flag.pm/1.83/Fri Feb 23 19:19:24 2007//TBUGZILLA-3_0 +/FlagType.pm/1.37/Thu Aug 24 15:56:39 2006//TBUGZILLA-3_0 +/Group.pm/1.19/Fri Nov 3 23:16:47 2006//TBUGZILLA-3_0 +/Hook.pm/1.7/Tue Dec 19 06:43:10 2006//TBUGZILLA-3_0 +/Install.pm/1.12/Thu Dec 28 18:16:42 2006//TBUGZILLA-3_0 +/Keyword.pm/1.7/Tue Sep 5 19:18:26 2006//TBUGZILLA-3_0 +/Mailer.pm/1.7/Sun Feb 4 15:41:10 2007//TBUGZILLA-3_0 +/Milestone.pm/1.8/Tue Dec 19 10:35:42 2006//TBUGZILLA-3_0 +/Object.pm/1.11/Tue Dec 19 06:39:28 2006//TBUGZILLA-3_0 +/Product.pm/1.24/Tue Dec 19 10:35:42 2006//TBUGZILLA-3_0 +/Search.pm/1.145/Mon Jan 22 04:49:35 2007//TBUGZILLA-3_0 +/Series.pm/1.14/Mon Sep 4 16:21:47 2006//TBUGZILLA-3_0 +/Template.pm/1.68.2.1/Sat Mar 10 11:43:14 2007//TBUGZILLA-3_0 +/Token.pm/1.52.2.1/Mon Mar 26 08:00:21 2007//TBUGZILLA-3_0 +/Update.pm/1.5.2.3/Tue Apr 24 23:13:02 2007//TBUGZILLA-3_0 +/User.pm/1.148/Mon Feb 5 21:34:20 2007//TBUGZILLA-3_0 +/Util.pm/1.56.2.1/Fri Mar 16 23:17:34 2007//TBUGZILLA-3_0 +/Version.pm/1.12/Tue Feb 20 22:53:33 2007//TBUGZILLA-3_0 +/WebService.pm/1.5.2.1/Mon Mar 26 07:57:32 2007//TBUGZILLA-3_0 +D/Attachment//// D/Auth//// D/Config//// D/DB//// +D/Install//// D/Search//// D/Template//// D/User//// +D/WebService//// diff --git a/Bugzilla/CVS/Tag b/Bugzilla/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/Bugzilla/CVS/Tag +++ b/Bugzilla/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/Bugzilla/Chart.pm b/Bugzilla/Chart.pm index f591d6c59..9701f7b32 100644 --- a/Bugzilla/Chart.pm +++ b/Bugzilla/Chart.pm @@ -32,10 +32,13 @@ use lib "."; # the same points. package Bugzilla::Chart; +use Bugzilla::Error; use Bugzilla::Util; use Bugzilla::Series; use Date::Format; +use Date::Parse; +use List::Util qw(max); sub new { my $invocant = shift; @@ -74,7 +77,7 @@ sub init { if ($param =~ /^line(\d+)$/) { foreach my $series_id ($cgi->param($param)) { detaint_natural($series_id) - || &::ThrowCodeError("invalid_series_id"); + || ThrowCodeError("invalid_series_id"); my $series = new Bugzilla::Series($series_id); push(@{$self->{'lines'}[$1]}, $series) if $series; } @@ -99,8 +102,8 @@ sub init { # Make sure the dates are ones we are able to interpret foreach my $date ('datefrom', 'dateto') { if ($self->{$date}) { - $self->{$date} = &::str2time($self->{$date}) - || &::ThrowUserError("illegal_date", { date => $self->{$date}}); + $self->{$date} = str2time($self->{$date}) + || ThrowUserError("illegal_date", { date => $self->{$date}}); } } @@ -108,7 +111,7 @@ sub init { if ($self->{'datefrom'} && $self->{'dateto'} && $self->{'datefrom'} > $self->{'dateto'}) { - &::ThrowUserError("misarranged_dates", + ThrowUserError("misarranged_dates", {'datefrom' => $cgi->param('datefrom'), 'dateto' => $cgi->param('dateto')}); } @@ -225,7 +228,7 @@ sub readData { my $datefrom = $dbh->selectrow_array("SELECT MIN(series_date) " . "FROM series_data " . "WHERE series_id IN ($series_ids)"); - $datefrom = &::str2time($datefrom); + $datefrom = str2time($datefrom); if ($self->{'datefrom'} && $self->{'datefrom'} > $datefrom) { $datefrom = $self->{'datefrom'}; @@ -234,7 +237,7 @@ sub readData { my $dateto = $dbh->selectrow_array("SELECT MAX(series_date) " . "FROM series_data " . "WHERE series_id IN ($series_ids)"); - $dateto = &::str2time($dateto); + $dateto = str2time($dateto); if ($self->{'dateto'} && $self->{'dateto'} < $dateto) { $dateto = $self->{'dateto'}; @@ -313,10 +316,10 @@ sub readData { my $datediff = shift @datediff_total; push @processed_datediff, $datediff if defined($datediff); } - $self->{'y_max_value'} = Bugzilla::Util::max(@processed_datediff); + $self->{'y_max_value'} = max(@processed_datediff); } else { - $self->{'y_max_value'} = Bugzilla::Util::max(@maxvals); + $self->{'y_max_value'} = max(@maxvals); } $self->{'y_max_value'} |= 1; # For log() @@ -422,7 +425,7 @@ sub generateDateProgression { $dateto += (2 * $oneday) / 3; while ($datefrom < $dateto) { - push (@progression, &::time2str("%Y-%m-%d", $datefrom)); + push (@progression, time2str("%Y-%m-%d", $datefrom)); $datefrom += $oneday; } diff --git a/Bugzilla/Classification.pm b/Bugzilla/Classification.pm index 63a826dc3..37ae3a0cc 100644 --- a/Bugzilla/Classification.pm +++ b/Bugzilla/Classification.pm @@ -31,6 +31,7 @@ use constant DB_COLUMNS => qw( classifications.id classifications.name classifications.description + classifications.sortkey ); our $columns = join(", ", DB_COLUMNS); @@ -105,12 +106,8 @@ sub products { SELECT id FROM products WHERE classification_id = ? ORDER BY name}, undef, $self->id); - - my @products; - foreach my $product_id (@$product_ids) { - push (@products, new Bugzilla::Product($product_id)); - } - $self->{'products'} = \@products; + + $self->{'products'} = Bugzilla::Product->new_from_list($product_ids); } return $self->{'products'}; } @@ -122,6 +119,7 @@ sub products { sub id { return $_[0]->{'id'}; } sub name { return $_[0]->{'name'}; } sub description { return $_[0]->{'description'}; } +sub sortkey { return $_[0]->{'sortkey'}; } ############################### #### Subroutines #### @@ -131,7 +129,7 @@ sub get_all_classifications { my $dbh = Bugzilla->dbh; my $ids = $dbh->selectcol_arrayref(q{ - SELECT id FROM classifications ORDER BY name}); + SELECT id FROM classifications ORDER BY sortkey, name}); my @classifications; foreach my $id (@$ids) { diff --git a/Bugzilla/Component.pm b/Bugzilla/Component.pm index 827be789d..a615e7ae5 100644 --- a/Bugzilla/Component.pm +++ b/Bugzilla/Component.pm @@ -13,82 +13,70 @@ # The Original Code is the Bugzilla Bug Tracking System. # # Contributor(s): Tiago R. Mello <timello@async.com.br> -# +# Frédéric Buclin <LpSolit@gmail.com> +# Max Kanat-Alexander <mkanat@bugzilla.org> +# Akamai Technologies <bugzilla-dev@akamai.com> use strict; package Bugzilla::Component; +use base qw(Bugzilla::Object); + use Bugzilla::Util; use Bugzilla::Error; use Bugzilla::User; +use Bugzilla::FlagType; ############################### #### Initialization #### ############################### +use constant DB_TABLE => 'components'; + use constant DB_COLUMNS => qw( - components.id - components.name - components.product_id - components.initialowner - components.initialqacontact - components.description + id + name + product_id + initialowner + initialqacontact + description ); -our $columns = join(", ", DB_COLUMNS); - ############################### #### Methods #### ############################### sub new { - my $invocant = shift; - my $class = ref($invocant) || $invocant; - my $self = {}; - bless($self, $class); - return $self->_init(@_); -} - -sub _init { - my $self = shift; - my ($param) = (@_); + my $class = shift; + my $param = shift; my $dbh = Bugzilla->dbh; - my $id = $param unless (ref $param eq 'HASH'); - my $component; - - if (defined $id) { - detaint_natural($id) - || ThrowCodeError('param_must_be_numeric', - {function => 'Bugzilla::Component::_init'}); - - $component = $dbh->selectrow_hashref(qq{ - SELECT $columns FROM components - WHERE id = ?}, undef, $id); - - } elsif (defined $param->{'product_id'} - && detaint_natural($param->{'product_id'}) - && defined $param->{'name'}) { - - trick_taint($param->{'name'}); - - $component = $dbh->selectrow_hashref(qq{ - SELECT $columns FROM components - WHERE name = ? AND product_id = ?}, undef, - ($param->{'name'}, $param->{'product_id'})); - } else { - ThrowCodeError('bad_arg', - {argument => 'param', - function => 'Bugzilla::Component::_init'}); + my $product; + if (ref $param) { + $product = $param->{product}; + my $name = $param->{name}; + if (!defined $product) { + ThrowCodeError('bad_arg', + {argument => 'product', + function => "${class}::new"}); + } + if (!defined $name) { + ThrowCodeError('bad_arg', + {argument => 'name', + function => "${class}::new"}); + } + + my $condition = 'product_id = ? AND name = ?'; + my @values = ($product->id, $name); + $param = { condition => $condition, values => \@values }; } - return undef unless (defined $component); - - foreach my $field (keys %$component) { - $self->{$field} = $component->{$field}; - } - return $self; + unshift @_, $param; + my $component = $class->SUPER::new(@_); + # Add the product object as attribute only if the component exists. + $component->{product} = $product if ($component && $product); + return $component; } sub bug_count { @@ -135,6 +123,48 @@ sub default_qa_contact { return $self->{'default_qa_contact'}; } +sub flag_types { + my $self = shift; + + if (!defined $self->{'flag_types'}) { + $self->{'flag_types'} = {}; + $self->{'flag_types'}->{'bug'} = + Bugzilla::FlagType::match({ 'target_type' => 'bug', + 'product_id' => $self->product_id, + 'component_id' => $self->id }); + + $self->{'flag_types'}->{'attachment'} = + Bugzilla::FlagType::match({ 'target_type' => 'attachment', + 'product_id' => $self->product_id, + 'component_id' => $self->id }); + } + return $self->{'flag_types'}; +} + +sub initial_cc { + my $self = shift; + + my $dbh = Bugzilla->dbh; + + if (!defined $self->{'initial_cc'}) { + my $cc_ids = $dbh->selectcol_arrayref( + "SELECT user_id FROM component_cc WHERE component_id = ?", + undef, $self->id); + my $initial_cc = Bugzilla::User->new_from_list($cc_ids); + $self->{'initial_cc'} = $initial_cc; + } + return $self->{'initial_cc'}; +} + +sub product { + my $self = shift; + if (!defined $self->{'product'}) { + require Bugzilla::Product; # We cannot |use| it. + $self->{'product'} = new Bugzilla::Product($self->product_id); + } + return $self->{'product'}; +} + ############################### #### Accessors #### ############################### @@ -159,8 +189,8 @@ sub check_component { } my $component = - new Bugzilla::Component({product_id => $product->id, - name => $comp_name}); + new Bugzilla::Component({product => $product, + name => $comp_name}); unless ($component) { ThrowUserError('component_not_valid', {'product' => $product->name, @@ -182,8 +212,8 @@ Bugzilla::Component - Bugzilla product component class. use Bugzilla::Component; my $component = new Bugzilla::Component(1); - my $component = new Bugzilla::Component({product_id => 1, - name => 'AcmeComp'}); + my $component = new Bugzilla::Component({product => $product, + name => 'AcmeComp'}); my $bug_count = $component->bug_count(); my $bug_ids = $component->bug_ids(); @@ -193,6 +223,10 @@ Bugzilla::Component - Bugzilla product component class. my $product_id = $component->product_id; my $default_assignee = $component->default_assignee; my $default_qa_contact = $component->default_qa_contact; + my $initial_cc = $component->initial_cc; + my $product = $component->product; + my $bug_flag_types = $component->flag_types->{'bug'}; + my $attach_flag_types = $component->flag_types->{'attachment'}; my $component = Bugzilla::Component::check_component($product, 'AcmeComp'); @@ -252,6 +286,28 @@ Component.pm represents a Product Component object. Returns: A Bugzilla::User object. +=item C<initial_cc> + +Returns an arrayref of L<Bugzilla::User> objects representing the +Initial CC List. + +=item C<flag_types()> + + Description: Returns all bug and attachment flagtypes available for + the component. + + Params: none. + + Returns: Two references to an array of flagtype objects. + +=item C<product()> + + Description: Returns the product the component belongs to. + + Params: none. + + Returns: A Bugzilla::Product object. + =back =head1 SUBROUTINES diff --git a/Bugzilla/Config.pm b/Bugzilla/Config.pm index 59d161bb3..85c9d6dec 100644 --- a/Bugzilla/Config.pm +++ b/Bugzilla/Config.pm @@ -27,173 +27,60 @@ # Christopher Aillon <christopher@aillon.com> # Erik Stambaugh <erik@dasbistro.com> # Frédéric Buclin <LpSolit@gmail.com> -# Guzman Braso <gbn@hqso.net> package Bugzilla::Config; use strict; use base qw(Exporter); - -# Under mod_perl, get this from a .htaccess config variable, -# and/or default from the current 'real' dir -# At some stage after this, it may be possible for these dir locations -# to go into localconfig. localconfig can't be specified in a config file, -# except possibly with mod_perl. If you move localconfig, you need to change -# the define here. -# $libpath is really only for mod_perl; its not yet possible to move the -# .pms elsewhere. -# $webdotdir must be in the webtree somewhere. Even if you use a local dot, -# we output images to there. Also, if $webdot dir is not relative to the -# bugzilla root directory, you'll need to change showdependencygraph.cgi to -# set image_url to the correct location. -# The script should really generate these graphs directly... -# Note that if $libpath is changed, some stuff will break, notably dependency -# graphs (since the path will be wrong in the HTML). This will be fixed at -# some point. - -# constant paths -our $libpath = '.'; - -# importxml.pl, when run by a mail daemon, sets the bugzilla path explicitly. -# This then mucks it up, so if we are coming from importxml.pl, set $libpath -# back to the way it was. -if ($::path) { - $libpath = $::path; -} - -our $templatedir = "$libpath/template"; - -# variable paths -our $project; -our $localconfig; -our $datadir; -if ($ENV{'PROJECT'} && $ENV{'PROJECT'} =~ /^(\w+)$/) { - $project = $1; - $localconfig = "$libpath/localconfig.$project"; - $datadir = "$libpath/data/$project"; -} else { - $localconfig = "$libpath/localconfig"; - $datadir = "$libpath/data"; -} -our $attachdir = "$datadir/attachments"; -our $webdotdir = "$datadir/webdot"; - -our @parampanels = (); - -# Module stuff -@Bugzilla::Config::EXPORT = qw(Param); +use Bugzilla::Constants; +use Data::Dumper; +use File::Temp; # Don't export localvars by default - people should have to explicitly # ask for it, as a (probably futile) attempt to stop code using it # when it shouldn't -# ChmodDataFile is here until that stuff all moves out of globals.pl -# into this file -@Bugzilla::Config::EXPORT_OK = qw(ChmodDataFile); - %Bugzilla::Config::EXPORT_TAGS = ( - admin => [qw(UpdateParams SetParam WriteParams)], - db => [qw($db_driver $db_host $db_port $db_name $db_user $db_pass $db_sock)], - locations => [qw($libpath $localconfig $attachdir $datadir $templatedir - $webdotdir $project)], - params => [qw(@parampanels)], + admin => [qw(update_params SetParam write_params)], ); -Exporter::export_ok_tags('admin', 'db', 'locations', 'params'); - -# Bugzilla version -$Bugzilla::Config::VERSION = "2.22.3"; - -use Safe; +Exporter::export_ok_tags('admin'); use vars qw(@param_list); -# Data::Dumper is required as needed, below. The problem is that then when -# the code locally sets $Data::Dumper::Foo, this triggers 'used only once' -# warnings. -# We can't predeclare another package's vars, though, so just use them -{ - local $Data::Dumper::Sortkeys; - local $Data::Dumper::Terse; - local $Data::Dumper::Indent; -} - -my %param; - # INITIALISATION CODE - -# XXX - mod_perl - need to register Apache init handler for params -sub _load_datafiles { - # read in localconfig variables - do $localconfig; - - if (-e "$datadir/params") { - # Handle reading old param files by munging the symbol table - # Don't have to do this if we use safe mode, since its evaled - # in a sandbox where $foo is in the same module as $::foo - #local *::param = \%param; - - # Note that checksetup.pl sets file permissions on '$datadir/params' - - # Using Safe mode is _not_ a guarantee of safety if someone does - # manage to write to the file. However, it won't hurt... - # See bug 165144 for not needing to eval this at all - my $s = new Safe; - - $s->rdo("$datadir/params"); - die "Error reading $datadir/params: $!" if $!; - die "Error evaluating $datadir/params: $@" if $@; - - # Now read the param back out from the sandbox - %param = %{$s->varglob('param')}; - } -} - -# Load in the datafiles -_load_datafiles(); - -# Stick the params into a hash -my %params; - +# Perl throws a warning if we use bz_locations() directly after do. +our %params; # Load in the param definitions -foreach my $item ((glob "$libpath/Bugzilla/Config/*.pm")) { - $item =~ m#/([^/]+)\.pm$#; - my $module = $1; - next if ($module eq 'Common'); - require "Bugzilla/Config/$module.pm"; - my @new_param_list = "Bugzilla::Config::$module"->get_param_list(); - foreach my $item (@new_param_list) { - $params{$item->{'name'}} = $item; +sub _load_params { + foreach my $module (param_panels()) { + eval("require Bugzilla::Config::$module") || die $@; + my @new_param_list = "Bugzilla::Config::$module"->get_param_list(); + foreach my $item (@new_param_list) { + $params{$item->{'name'}} = $item; + } + push(@param_list, @new_param_list); } - push(@parampanels, $module); - push(@param_list, @new_param_list); } - # END INIT CODE # Subroutines go here -sub Param { - my ($param) = @_; - - # By this stage, the param must be in the hash - die "Can't find param named $param" unless (exists $params{$param}); - - # When module startup code runs (which is does even via -c, when using - # |use|), we may try to grab params which don't exist yet. This affects - # tests, so have this as a fallback for the -c case - return $params{$param}->{default} if ($^C && not exists $param{$param}); - - # If we have a value for the param, return it - return $param{$param} if exists $param{$param}; - - # Else error out - die "No value for param $param (try running checksetup.pl again)"; +sub param_panels { + my @param_panels; + my $libpath = bz_locations()->{'libpath'}; + foreach my $item ((glob "$libpath/Bugzilla/Config/*.pm")) { + $item =~ m#/([^/]+)\.pm$#; + my $module = $1; + push(@param_panels, $module) unless $module eq 'Common'; + } + return @param_panels; } sub SetParam { my ($name, $value) = @_; + _load_params unless %params; die "Unknown param $name" unless (exists $params{$name}); my $entry = $params{$name}; @@ -208,120 +95,190 @@ sub SetParam { die "Param $name is not valid: $err" unless $err eq ''; } - $param{$name} = $value; + Bugzilla->params->{$name} = $value; } -sub UpdateParams { - # --- PARAM CONVERSION CODE --- +sub update_params { + my ($params) = @_; + my $answer = Bugzilla->installation_answers; + + my $param = read_param_file(); - # Note that this isn't particularly 'clean' in terms of separating - # the backend code (ie this) from the actual params. - # We don't care about that, though + # If we didn't return any param values, then this is a new installation. + my $new_install = !(keys %$param); + + # --- UPDATE OLD PARAMS --- # Old Bugzilla versions stored the version number in the params file # We don't want it, so get rid of it - delete $param{'version'}; + delete $param->{'version'}; # Change from usebrowserinfo to defaultplatform/defaultopsys combo - if (exists $param{'usebrowserinfo'}) { - if (!$param{'usebrowserinfo'}) { - if (!exists $param{'defaultplatform'}) { - $param{'defaultplatform'} = 'Other'; + if (exists $param->{'usebrowserinfo'}) { + if (!$param->{'usebrowserinfo'}) { + if (!exists $param->{'defaultplatform'}) { + $param->{'defaultplatform'} = 'Other'; } - if (!exists $param{'defaultopsys'}) { - $param{'defaultopsys'} = 'Other'; + if (!exists $param->{'defaultopsys'}) { + $param->{'defaultopsys'} = 'Other'; } } - delete $param{'usebrowserinfo'}; + delete $param->{'usebrowserinfo'}; } # Change from a boolean for quips to multi-state - if (exists $param{'usequip'} && !exists $param{'enablequips'}) { - $param{'enablequips'} = $param{'usequip'} ? 'on' : 'off'; - delete $param{'usequip'}; + if (exists $param->{'usequip'} && !exists $param->{'enablequips'}) { + $param->{'enablequips'} = $param->{'usequip'} ? 'on' : 'off'; + delete $param->{'usequip'}; } # Change from old product groups to controls for group_control_map # 2002-10-14 bug 147275 bugreport@peshkin.net - if (exists $param{'usebuggroups'} && !exists $param{'makeproductgroups'}) { - $param{'makeproductgroups'} = $param{'usebuggroups'}; + if (exists $param->{'usebuggroups'} && + !exists $param->{'makeproductgroups'}) + { + $param->{'makeproductgroups'} = $param->{'usebuggroups'}; } - if (exists $param{'usebuggroupsentry'} - && !exists $param{'useentrygroupdefault'}) { - $param{'useentrygroupdefault'} = $param{'usebuggroupsentry'}; + if (exists $param->{'usebuggroupsentry'} + && !exists $param->{'useentrygroupdefault'}) { + $param->{'useentrygroupdefault'} = $param->{'usebuggroupsentry'}; } # Modularise auth code - if (exists $param{'useLDAP'} && !exists $param{'loginmethod'}) { - $param{'loginmethod'} = $param{'useLDAP'} ? "LDAP" : "DB"; + if (exists $param->{'useLDAP'} && !exists $param->{'loginmethod'}) { + $param->{'loginmethod'} = $param->{'useLDAP'} ? "LDAP" : "DB"; } # set verify method to whatever loginmethod was - if (exists $param{'loginmethod'} && !exists $param{'user_verify_class'}) { - $param{'user_verify_class'} = $param{'loginmethod'}; - delete $param{'loginmethod'}; + if (exists $param->{'loginmethod'} + && !exists $param->{'user_verify_class'}) + { + $param->{'user_verify_class'} = $param->{'loginmethod'}; + delete $param->{'loginmethod'}; } # Remove quip-display control from parameters # and give it to users via User Settings (Bug 41972) - if ( exists $param{'enablequips'} - && !exists $param{'quip_list_entry_control'}) + if ( exists $param->{'enablequips'} + && !exists $param->{'quip_list_entry_control'}) { my $new_value; - ($param{'enablequips'} eq 'on') && do {$new_value = 'open';}; - ($param{'enablequips'} eq 'approved') && do {$new_value = 'moderated';}; - ($param{'enablequips'} eq 'frozen') && do {$new_value = 'closed';}; - ($param{'enablequips'} eq 'off') && do {$new_value = 'closed';}; - $param{'quip_list_entry_control'} = $new_value; - delete $param{'enablequips'}; + ($param->{'enablequips'} eq 'on') && do {$new_value = 'open';}; + ($param->{'enablequips'} eq 'approved') && do {$new_value = 'moderated';}; + ($param->{'enablequips'} eq 'frozen') && do {$new_value = 'closed';}; + ($param->{'enablequips'} eq 'off') && do {$new_value = 'closed';}; + $param->{'quip_list_entry_control'} = $new_value; + delete $param->{'enablequips'}; + } + + # Old mail_delivery_method choices contained no uppercase characters + if (exists $param->{'mail_delivery_method'} + && $param->{'mail_delivery_method'} !~ /[A-Z]/) { + my $method = $param->{'mail_delivery_method'}; + my %translation = ( + 'sendmail' => 'Sendmail', + 'smtp' => 'SMTP', + 'qmail' => 'Qmail', + 'testfile' => 'Test', + 'none' => 'None'); + $param->{'mail_delivery_method'} = $translation{$method}; } # --- DEFAULTS FOR NEW PARAMS --- + _load_params unless %params; foreach my $item (@param_list) { my $name = $item->{'name'}; - $param{$name} = $item->{'default'} unless exists $param{$name}; + unless (exists $param->{$name}) { + print "New parameter: $name\n" unless $new_install; + $param->{$name} = $answer->{$name} || $item->{'default'}; + } } - # --- REMOVE OLD PARAMS --- + $param->{'utf8'} = 1 if $new_install; - my @oldparams = (); + # --- REMOVE OLD PARAMS --- - # Remove any old params - foreach my $item (keys %param) { + my @oldparams; + # Remove any old params, put them in old-params.txt + foreach my $item (keys %$param) { if (!grep($_ eq $item, map ($_->{'name'}, @param_list))) { - require Data::Dumper; - - local $Data::Dumper::Terse = 1; + local $Data::Dumper::Terse = 1; local $Data::Dumper::Indent = 0; - push (@oldparams, [$item, Data::Dumper->Dump([$param{$item}])]); - delete $param{$item}; + push (@oldparams, [$item, Data::Dumper->Dump([$param->{$item}])]); + delete $param->{$item}; } } - return @oldparams; + if (@oldparams) { + my $op_file = new IO::File('old-params.txt', '>>', 0600) + || die "old-params.txt: $!"; + + print "The following parameters are no longer used in Bugzilla,", + " and so have been\nmoved from your parameters file into", + " old-params.txt:\n"; + + foreach my $p (@oldparams) { + my ($item, $value) = @$p; + print $op_file "\n\n$item:\n$value\n"; + print $item; + print ", " unless $item eq $oldparams[$#oldparams]->[0]; + } + print "\n"; + $op_file->close; + } + + if (ON_WINDOWS && !-e SENDMAIL_EXE + && $param->{'mail_delivery_method'} eq 'Sendmail') + { + my $smtp = $answer->{'SMTP_SERVER'}; + if (!$smtp) { + print "\nBugzilla requires an SMTP server to function on", + " Windows.\nPlease enter your SMTP server's hostname: "; + $smtp = <STDIN>; + chomp $smtp; + if ($smtp) { + $param->{'smtpserver'} = $smtp; + } + else { + print "\nWarning: No SMTP Server provided, defaulting to", + " localhost\n"; + } + } + + $param->{'mail_delivery_method'} = 'SMTP'; + } + + write_params($param); } -sub WriteParams { - require Data::Dumper; +sub write_params { + my ($param_data) = @_; + $param_data ||= Bugzilla->params; + + my $datadir = bz_locations()->{'datadir'}; + my $param_file = "$datadir/params"; # This only has an affect for Data::Dumper >= 2.12 (ie perl >= 5.8.0) # Its just cosmetic, though, so that doesn't matter local $Data::Dumper::Sortkeys = 1; - require File::Temp; my ($fh, $tmpname) = File::Temp::tempfile('params.XXXXX', DIR => $datadir ); - print $fh (Data::Dumper->Dump([ \%param ], [ '*param' ])) + print $fh (Data::Dumper->Dump([$param_data], ['*param'])) || die "Can't write param file: $!"; close $fh; - rename $tmpname, "$datadir/params" - || die "Can't rename $tmpname to $datadir/params: $!"; + rename $tmpname, $param_file + || die "Can't rename $tmpname to $param_file: $!"; - ChmodDataFile("$datadir/params", 0666); + ChmodDataFile($param_file, 0666); + + # And now we have to reset the params cache so that Bugzilla will re-read + # them. + delete Bugzilla->request_cache->{params}; } # Some files in the data directory must be world readable if and only if @@ -333,13 +290,34 @@ sub WriteParams { sub ChmodDataFile { my ($file, $mask) = @_; my $perm = 0770; - if ((stat($datadir))[2] & 0002) { + if ((stat(bz_locations()->{'datadir'}))[2] & 0002) { $perm = 0777; } $perm = $perm & $mask; chmod $perm,$file; } +sub read_param_file { + my %params; + my $datadir = bz_locations()->{'datadir'}; + if (-e "$datadir/params") { + # Note that checksetup.pl sets file permissions on '$datadir/params' + + # Using Safe mode is _not_ a guarantee of safety if someone does + # manage to write to the file. However, it won't hurt... + # See bug 165144 for not needing to eval this at all + my $s = new Safe; + + $s->rdo("$datadir/params"); + die "Error reading $datadir/params: $!" if $!; + die "Error evaluating $datadir/params: $@" if $@; + + # Now read the param back out from the sandbox + %params = %{$s->varglob('param')}; + } + return \%params; +} + 1; __END__ @@ -350,21 +328,12 @@ Bugzilla::Config - Configuration parameters for Bugzilla =head1 SYNOPSIS - # Getting parameters - use Bugzilla::Config; - - my $fooSetting = Param('foo'); - # Administration functions use Bugzilla::Config qw(:admin); - my @removed_params = UpgradeParams(); + update_params(); SetParam($param, $value); - WriteParams(); - - # Localconfig variables may also be imported - use Bugzilla::Config qw(:db); - print "Connecting to $db_name as $db_user with $db_pass\n"; + write_params(); =head1 DESCRIPTION @@ -378,40 +347,40 @@ Parameters can be set, retrieved, and updated. =over 4 -=item C<Param($name)> - -Returns the Param with the specified name. Either a string, or, in the case -of multiple-choice parameters, an array reference. - =item C<SetParam($name, $value)> Sets the param named $name to $value. Values are checked using the checker function for the given param if one exists. -=item C<UpdateParams()> +=item C<update_params()> Updates the parameters, by transitioning old params to new formats, setting -defaults for new params, and removing obsolete ones. +defaults for new params, and removing obsolete ones. Used by F<checksetup.pl> +in the process of an installation or upgrade. -Any removed params are returned in a list, with elements [$item, $oldvalue] -where $item is the entry in the param list. +Prints out information about what it's doing, if it makes any changes. -=item C<WriteParams()> +May prompt the user for input, if certain required parameters are not +specified. -Writes the parameters to disk. +=item C<write_params($params)> -=back +Description: Writes the parameters to disk. -=over +Params: C<$params> (optional) - A hashref to write to the disk + instead of C<Bugzilla->params>. Used only by + C<update_params>. -=item * +Returns: nothing -The new value for the parameter +=item C<read_param_file()> -=item * +Description: Most callers should never need this. This is used + by C<Bugzilla->params> to directly read C<$datadir/params> + and load it into memory. Use C<Bugzilla->params> instead. -A reference to the entry in the param list for this parameter +Params: none -Functions should return error text, or the empty string if there was no error. +Returns: A hashref containing the current params in C<$datadir/params>. =back diff --git a/Bugzilla/Config/Attachment.pm b/Bugzilla/Config/Attachment.pm index 449908528..bbaaaa63d 100644 --- a/Bugzilla/Config/Attachment.pm +++ b/Bugzilla/Config/Attachment.pm @@ -41,6 +41,11 @@ sub get_param_list { my $class = shift; my @param_list = ( { + name => 'allow_attachment_deletion', + type => 'b', + default => 0 + }, + { name => 'allow_attach_url', type => 'b', default => 0 diff --git a/Bugzilla/Config/Auth.pm b/Bugzilla/Config/Auth.pm index 6b0cf7683..65ebc1b79 100644 --- a/Bugzilla/Config/Auth.pm +++ b/Bugzilla/Config/Auth.pm @@ -93,7 +93,7 @@ sub get_param_list { { name => 'loginnetmask', type => 't', - default => '32', + default => '0', checker => \&check_netmask }, diff --git a/Bugzilla/Config/BugFields.pm b/Bugzilla/Config/BugFields.pm index 17b79941d..ef0f340f1 100644 --- a/Bugzilla/Config/BugFields.pm +++ b/Bugzilla/Config/BugFields.pm @@ -34,11 +34,18 @@ package Bugzilla::Config::BugFields; use strict; use Bugzilla::Config::Common; +use Bugzilla::Field; $Bugzilla::Config::BugFields::sortkey = "04"; sub get_param_list { my $class = shift; + + my @legal_priorities = @{get_legal_field_values('priority')}; + my @legal_severities = @{get_legal_field_values('bug_severity')}; + my @legal_platforms = @{get_legal_field_values('rep_platform')}; + my @legal_OS = @{get_legal_field_values('op_sys')}; + my @param_list = ( { name => 'useclassification', @@ -85,23 +92,23 @@ sub get_param_list { { name => 'defaultpriority', type => 's', - choices => \@::legal_priority, - default => $::legal_priority[-1], + choices => \@legal_priorities, + default => $legal_priorities[-1], checker => \&check_priority }, { name => 'defaultseverity', type => 's', - choices => \@::legal_severity, - default => $::legal_severity[-1], + choices => \@legal_severities, + default => $legal_severities[-1], checker => \&check_severity }, { name => 'defaultplatform', type => 's', - choices => ['', @::legal_platform], + choices => ['', @legal_platforms], default => '', checker => \&check_platform }, @@ -109,7 +116,7 @@ sub get_param_list { { name => 'defaultopsys', type => 's', - choices => ['', @::legal_opsys], + choices => ['', @legal_OS], default => '', checker => \&check_opsys } ); diff --git a/Bugzilla/Config/CVS/Entries b/Bugzilla/Config/CVS/Entries index 204c330bb..b95976f91 100644 --- a/Bugzilla/Config/CVS/Entries +++ b/Bugzilla/Config/CVS/Entries @@ -1,18 +1,18 @@ -/Admin.pm/1.2/Thu Oct 13 09:04:04 2005//TBUGZILLA-2_22_3 -/Attachment.pm/1.2/Wed Oct 19 20:16:13 2005//TBUGZILLA-2_22_3 -/Auth.pm/1.1/Wed Oct 12 08:51:53 2005//TBUGZILLA-2_22_3 -/BugChange.pm/1.2/Fri Oct 14 17:54:56 2005//TBUGZILLA-2_22_3 -/BugFields.pm/1.3/Tue Oct 18 18:47:08 2005//TBUGZILLA-2_22_3 -/BugMove.pm/1.1/Wed Oct 12 08:51:53 2005//TBUGZILLA-2_22_3 -/Common.pm/1.2.2.2/Mon Jun 19 14:43:41 2006//TBUGZILLA-2_22_3 -/Core.pm/1.1.2.1/Thu Feb 23 01:46:45 2006//TBUGZILLA-2_22_3 -/DependencyGraph.pm/1.1/Wed Oct 12 08:51:53 2005//TBUGZILLA-2_22_3 -/GroupSecurity.pm/1.2/Mon Oct 17 21:19:01 2005//TBUGZILLA-2_22_3 -/L10n.pm/1.1/Wed Oct 12 08:51:53 2005//TBUGZILLA-2_22_3 -/LDAP.pm/1.1/Wed Oct 12 08:51:53 2005//TBUGZILLA-2_22_3 -/MTA.pm/1.3/Mon Feb 20 23:32:08 2006//TBUGZILLA-2_22_3 -/PatchViewer.pm/1.1/Wed Oct 12 08:51:53 2005//TBUGZILLA-2_22_3 -/Query.pm/1.3/Mon Feb 20 23:32:08 2006//TBUGZILLA-2_22_3 -/ShadowDB.pm/1.1/Wed Oct 12 08:51:53 2005//TBUGZILLA-2_22_3 -/UserMatch.pm/1.1/Wed Oct 12 08:51:53 2005//TBUGZILLA-2_22_3 +/Admin.pm/1.2/Thu Oct 13 09:04:04 2005//TBUGZILLA-3_0 +/Attachment.pm/1.3/Mon Apr 17 20:19:35 2006//TBUGZILLA-3_0 +/Auth.pm/1.2/Sat Nov 11 09:18:55 2006//TBUGZILLA-3_0 +/BugChange.pm/1.2/Fri Oct 14 17:54:56 2005//TBUGZILLA-3_0 +/BugFields.pm/1.4/Mon Jun 19 20:15:18 2006//TBUGZILLA-3_0 +/BugMove.pm/1.1/Wed Oct 12 08:51:53 2005//TBUGZILLA-3_0 +/Common.pm/1.14/Mon Nov 27 18:31:36 2006//TBUGZILLA-3_0 +/Core.pm/1.7.2.1/Wed Apr 18 00:15:14 2007//TBUGZILLA-3_0 +/DependencyGraph.pm/1.1/Wed Oct 12 08:51:53 2005//TBUGZILLA-3_0 +/GroupSecurity.pm/1.8/Mon Aug 7 23:05:00 2006//TBUGZILLA-3_0 +/L10n.pm/1.2/Mon Jun 19 20:15:18 2006//TBUGZILLA-3_0 +/LDAP.pm/1.2/Fri Jun 2 11:52:48 2006//TBUGZILLA-3_0 +/MTA.pm/1.14/Sat Dec 9 16:39:18 2006//TBUGZILLA-3_0 +/PatchViewer.pm/1.1/Wed Oct 12 08:51:53 2005//TBUGZILLA-3_0 +/Query.pm/1.3/Mon Feb 20 23:32:08 2006//TBUGZILLA-3_0 +/ShadowDB.pm/1.1/Wed Oct 12 08:51:53 2005//TBUGZILLA-3_0 +/UserMatch.pm/1.1/Wed Oct 12 08:51:53 2005//TBUGZILLA-3_0 D diff --git a/Bugzilla/Config/CVS/Tag b/Bugzilla/Config/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/Bugzilla/Config/CVS/Tag +++ b/Bugzilla/Config/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/Bugzilla/Config/Common.pm b/Bugzilla/Config/Common.pm index c72e4b8f5..0d6db5257 100644 --- a/Bugzilla/Config/Common.pm +++ b/Bugzilla/Config/Common.pm @@ -29,42 +29,26 @@ # Frédéric Buclin <LpSolit@gmail.com> # -# This file defines all the parameters that we have a GUI to edit within -# Bugzilla. - -# ATTENTION!!!! THIS FILE ONLY CONTAINS THE DEFAULTS. -# You cannot change your live settings by editing this file. -# Only adding new parameters is done here. Once the parameter exists, you -# must use %baseurl%/editparams.cgi from the web to edit the settings. - -# This file is included via |do|, mainly because of circular dependency issues -# (such as globals.pl -> Bugzilla::Config -> this -> Bugzilla::Config) -# which preclude compile time loading. - -# Those issues may go away at some point, and the contents of this file -# moved somewhere else. Please try to avoid more dependencies from here -# to other code - -# (Note that these aren't just added directly to Bugzilla::Config, because -# the backend prefs code is separate to this...) - package Bugzilla::Config::Common; use strict; use Socket; +use Time::Zone; -use Bugzilla::Config qw(:DEFAULT $templatedir $webdotdir); use Bugzilla::Util; use Bugzilla::Constants; +use Bugzilla::Field; +use Bugzilla::Group; use base qw(Exporter); @Bugzilla::Config::Common::EXPORT = - qw(check_multi check_numeric check_regexp + qw(check_multi check_numeric check_regexp check_url check_group check_sslbase check_priority check_severity check_platform check_opsys check_shadowdb check_urlbase check_webdotbase check_netmask check_user_verify_class check_image_converter - check_languages check_mail_delivery_method + check_languages check_mail_delivery_method check_notification + check_timezone check_utf8 ); # Checking functions for the various values @@ -130,42 +114,64 @@ sub check_sslbase { return ""; } +sub check_utf8 { + my $utf8 = shift; + # You cannot turn off the UTF-8 parameter if you've already converted + # your tables to utf-8. + my $dbh = Bugzilla->dbh; + if ($dbh->isa('Bugzilla::DB::Mysql') && $dbh->bz_db_is_utf8 && !$utf8) { + return "You cannot disable UTF-8 support, because your MySQL database" + . " is encoded in UTF-8"; + } + return ""; +} + sub check_priority { my ($value) = (@_); - &::GetVersionTable(); - if (lsearch(\@::legal_priority, $value) < 0) { + my $legal_priorities = get_legal_field_values('priority'); + if (lsearch($legal_priorities, $value) < 0) { return "Must be a legal priority value: one of " . - join(", ", @::legal_priority); + join(", ", @$legal_priorities); } return ""; } sub check_severity { my ($value) = (@_); - &::GetVersionTable(); - if (lsearch(\@::legal_severity, $value) < 0) { + my $legal_severities = get_legal_field_values('bug_severity'); + if (lsearch($legal_severities, $value) < 0) { return "Must be a legal severity value: one of " . - join(", ", @::legal_severity); + join(", ", @$legal_severities); } return ""; } sub check_platform { my ($value) = (@_); - &::GetVersionTable(); - if (lsearch(['', @::legal_platform], $value) < 0) { + my $legal_platforms = get_legal_field_values('rep_platform'); + if (lsearch(['', @$legal_platforms], $value) < 0) { return "Must be empty or a legal platform value: one of " . - join(", ", @::legal_platform); + join(", ", @$legal_platforms); } return ""; } sub check_opsys { my ($value) = (@_); - &::GetVersionTable(); - if (lsearch(['', @::legal_opsys], $value) < 0) { + my $legal_OS = get_legal_field_values('op_sys'); + if (lsearch(['', @$legal_OS], $value) < 0) { return "Must be empty or a legal operating system value: one of " . - join(", ", @::legal_opsys); + join(", ", @$legal_OS); + } + return ""; +} + +sub check_group { + my $group_name = shift; + return "" unless $group_name; + my $group = new Bugzilla::Group({'name' => $group_name}); + unless (defined $group) { + return "Must be an existing group name"; } return ""; } @@ -177,7 +183,7 @@ sub check_shadowdb { return ""; } - if (!Param('shadowdbhost')) { + if (!Bugzilla->params->{'shadowdbhost'}) { return "You need to specify a host when using a shadow database"; } @@ -195,6 +201,15 @@ sub check_urlbase { return ""; } +sub check_url { + my ($url) = (@_); + return '' if $url eq ''; # Allow empty URLs + if ($url !~ m:/$:) { + return 'must be a legal URL, absolute or relative, ending with a slash.'; + } + return ''; +} + sub check_webdotbase { my ($value) = (@_); $value = trim($value); @@ -206,6 +221,7 @@ sub check_webdotbase { return "The file path \"$value\" is not a valid executable. Please specify the complete file path to 'dot' if you intend to generate graphs locally."; } # Check .htaccess allows access to generated images + my $webdotdir = bz_locations()->{'webdotdir'}; if(-e "$webdotdir/.htaccess") { open HTACCESS, "$webdotdir/.htaccess"; if(! grep(/ \\\.png\$/,<HTACCESS>)) { @@ -250,8 +266,8 @@ sub check_user_verify_class { } elsif ($class eq 'LDAP') { eval "require Net::LDAP"; return "Error requiring Net::LDAP: '$@'" if $@; - return "LDAP servername is missing" unless Param("LDAPserver"); - return "LDAPBaseDN is empty" unless Param("LDAPBaseDN"); + return "LDAP servername is missing" unless Bugzilla->params->{"LDAPserver"}; + return "LDAPBaseDN is empty" unless Bugzilla->params->{"LDAPBaseDN"}; } else { return "Unknown user_verify_class '$class' in check_user_verify_class"; } @@ -273,6 +289,7 @@ sub check_languages { if(!scalar(@languages)) { return "You need to specify a language tag." } + my $templatedir = bz_locations()->{'templatedir'}; foreach my $language (@languages) { if( ! -d "$templatedir/$language/custom" && ! -d "$templatedir/$language/default") { @@ -294,6 +311,28 @@ sub check_mail_delivery_method { return ""; } +sub check_notification { + my $option = shift; + my @current_version = + (BUGZILLA_VERSION =~ m/^(\d+)\.(\d+)(?:(rc|\.)(\d+))?\+?$/); + if ($current_version[1] % 2 && $option eq 'stable_branch_release') { + return "You are currently running a development snapshot, and so your " . + "installation is not based on a branch. If you want to be notified " . + "about the next stable release, you should select " . + "'latest_stable_release' instead"; + } + return ""; +} + +sub check_timezone { + my $tz = shift; + unless (defined(tz_offset($tz))) { + return "must be empty or a legal timezone name, such as PDT or JST"; + } + return ""; +} + + # OK, here are the parameter definitions themselves. # # Each definition is a hash with keys: diff --git a/Bugzilla/Config/Core.pm b/Bugzilla/Config/Core.pm index 541a48c69..a0aca9c9b 100644 --- a/Bugzilla/Config/Core.pm +++ b/Bugzilla/Config/Core.pm @@ -53,6 +53,13 @@ sub get_param_list { checker => \&check_urlbase }, + { + name => 'docs_urlbase', + type => 't', + default => 'docs/html/', + checker => \&check_url + }, + { name => 'sslbase', type => 't', @@ -84,18 +91,41 @@ sub get_param_list { name => 'timezone', type => 't', default => '', + checker => \&check_timezone }, { name => 'utf8', type => 'b', default => '0', + checker => \&check_utf8 }, { name => 'shutdownhtml', type => 'l', default => '' + }, + + { + name => 'announcehtml', + type => 'l', + default => '' + }, + + { + name => 'proxy_url', + type => 't', + default => '' + }, + + { + name => 'upgrade_notification', + type => 's', + choices => ['development_snapshot', 'latest_stable_release', + 'stable_branch_release', 'disabled'], + default => 'latest_stable_release', + checker => \&check_notification } ); return @param_list; } diff --git a/Bugzilla/Config/GroupSecurity.pm b/Bugzilla/Config/GroupSecurity.pm index bd1aa3829..0a238f209 100644 --- a/Bugzilla/Config/GroupSecurity.pm +++ b/Bugzilla/Config/GroupSecurity.pm @@ -34,11 +34,13 @@ package Bugzilla::Config::GroupSecurity; use strict; use Bugzilla::Config::Common; +use Bugzilla::Group; $Bugzilla::Config::GroupSecurity::sortkey = "07"; sub get_param_list { my $class = shift; + my @param_list = ( { name => 'makeproductgroups', @@ -54,20 +56,34 @@ sub get_param_list { { name => 'chartgroup', - type => 't', - default => 'editbugs' + type => 's', + choices => \&_get_all_group_names, + default => 'editbugs', + checker => \&check_group }, - + { name => 'insidergroup', - type => 't', - default => '' + type => 's', + choices => \&_get_all_group_names, + default => '', + checker => \&check_group }, { name => 'timetrackinggroup', - type => 't', - default => '' + type => 's', + choices => \&_get_all_group_names, + default => 'editbugs', + checker => \&check_group + }, + + { + name => 'querysharegroup', + type => 's', + choices => \&_get_all_group_names, + default => 'editbugs', + checker => \&check_group }, { @@ -84,4 +100,9 @@ sub get_param_list { return @param_list; } +sub _get_all_group_names { + my @group_names = map {$_->name} Bugzilla::Group->get_all; + unshift(@group_names, ''); + return \@group_names; +} 1; diff --git a/Bugzilla/Config/L10n.pm b/Bugzilla/Config/L10n.pm index 6fed0ed70..957dce786 100644 --- a/Bugzilla/Config/L10n.pm +++ b/Bugzilla/Config/L10n.pm @@ -35,7 +35,7 @@ use strict; use File::Spec; # for find_languages -use Bugzilla::Config qw($templatedir); +use Bugzilla::Constants; use Bugzilla::Config::Common; $Bugzilla::Config::L10n::sortkey = "08"; @@ -62,7 +62,8 @@ sub get_param_list { sub find_languages { my @languages = (); - opendir(DIR, $templatedir) || return "Can't open 'template' directory: $!"; + opendir(DIR, bz_locations()->{'templatedir'}) + || return "Can't open 'template' directory: $!"; foreach my $dir (readdir(DIR)) { next unless $dir =~ /^([a-z-]+)$/i; my $lang = $1; diff --git a/Bugzilla/Config/LDAP.pm b/Bugzilla/Config/LDAP.pm index 3f123243b..a9b46382e 100644 --- a/Bugzilla/Config/LDAP.pm +++ b/Bugzilla/Config/LDAP.pm @@ -46,6 +46,12 @@ sub get_param_list { default => '' }, + { + name => 'LDAPstarttls', + type => 'b', + default => 0 + }, + { name => 'LDAPbinddn', type => 't', diff --git a/Bugzilla/Config/MTA.pm b/Bugzilla/Config/MTA.pm index 50aa8c85d..3415677f3 100644 --- a/Bugzilla/Config/MTA.pm +++ b/Bugzilla/Config/MTA.pm @@ -34,6 +34,7 @@ package Bugzilla::Config::MTA; use strict; use Bugzilla::Config::Common; +use Email::Send; $Bugzilla::Config::MTA::sortkey = "10"; @@ -43,13 +44,19 @@ sub get_param_list { { name => 'mail_delivery_method', type => 's', - choices => $^O =~ /MSWin32/i - ? ['smtp', 'testfile', 'sendmail', 'none'] - : ['sendmail', 'smtp', 'qmail', 'testfile', 'none'], - default => 'sendmail', + # Bugzilla is not ready yet to send mails to newsgroups, and 'IO' + # is of no use for now as we already have our own 'Test' mode. + choices => [grep {$_ ne 'NNTP' && $_ ne 'IO'} Email::Send->new()->all_mailers(), 'None'], + default => 'Sendmail', checker => \&check_mail_delivery_method }, + { + name => 'mailfrom', + type => 't', + default => 'bugzilla-daemon' + }, + { name => 'sendmailnow', type => 'b', @@ -62,114 +69,18 @@ sub get_param_list { default => 'localhost' }, - { - name => 'passwordmail', - type => 'l', - default => 'From: bugzilla-daemon -To: %mailaddress% -Subject: Your Bugzilla password. - -To use the wonders of Bugzilla, you can use the following: - - E-mail address: %login% - Password: %password% - - To change your password, go to: - %urlbase%userprefs.cgi -' - }, - - { - name => 'newchangedmail', - type => 'l', - default => 'From: bugzilla-daemon -To: %to% -Subject: [Bug %bugid%] %neworchanged%%summary% -%threadingmarker% -X-Bugzilla-Reason: %reasonsheader% -X-Bugzilla-Product: %product% -X-Bugzilla-Component: %component% -X-Bugzilla-Keywords: %keywords% -X-Bugzilla-Severity: %severity% - -%urlbase%show_bug.cgi?id=%bugid% - -%diffs% - ---%space% -Configure bugmail: %urlbase%userprefs.cgi?tab=email -%reasonsbody%' - }, - { name => 'whinedays', type => 't', default => 7, checker => \&check_numeric }, - + { - name => 'whinemail', - type => 'l', - default => 'From: %maintainer% -To: %email% -Subject: Your Bugzilla buglist needs attention. - -[This e-mail has been automatically generated.] - -You have one or more bugs assigned to you in the Bugzilla -bugsystem (%urlbase%) that require -attention. - -All of these bugs are in the NEW or REOPENED state, and have not -been touched in %whinedays% days or more. You need to take a look -at them, and decide on an initial action. - -Generally, this means one of three things: - -(1) You decide this bug is really quick to deal with (like, it\'s INVALID), - and so you get rid of it immediately. -(2) You decide the bug doesn\'t belong to you, and you reassign it to someone - else. (Hint: if you don\'t know who to reassign it to, make sure that - the Component field seems reasonable, and then use the "Reassign bug to - default assignee of selected component" option.) -(3) You decide the bug belongs to you, but you can\'t solve it this moment. - Just use the "Accept bug" command. - -To get a list of all NEW/REOPENED bugs, you can use this URL (bookmark -it if you like!): - - %urlbase%buglist.cgi?bug_status=NEW&bug_status=REOPENED&assigned_to=%userid% - -Or, you can use the general query page, at -%urlbase%query.cgi - -Appended below are the individual URLs to get to all of your NEW bugs that -haven\'t been touched for a week or more. - -You will get this message once a day until you\'ve dealt with these bugs! - -' - }, - - { - name => 'voteremovedmail', - type => 'l', - default => 'From: bugzilla-daemon -To: %to% -Subject: [Bug %bugid%] Some or all of your votes have been removed. - -Some or all of your votes have been removed from bug %bugid%. - -%votesoldtext% - -%votesnewtext% - -Reason: %reason% - -%urlbase%show_bug.cgi?id=%bugid% -' - } ); + name => 'globalwatchers', + type => 't', + default => '', + }, ); return @param_list; } diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm index 9baebf065..2a4dd9264 100644 --- a/Bugzilla/Constants.pm +++ b/Bugzilla/Constants.pm @@ -27,12 +27,19 @@ # Christopher Aillon <christopher@aillon.com> # Shane H. W. Travis <travis@sedsystems.ca> # Max Kanat-Alexander <mkanat@bugzilla.org> +# Marc Schumann <wurblzap@gmail.com> package Bugzilla::Constants; use strict; use base qw(Exporter); +# For bz_locations +use File::Basename; + @Bugzilla::Constants::EXPORT = qw( + BUGZILLA_VERSION + + bz_locations CONTROLMAPNA CONTROLMAPSHOWN CONTROLMAPDEFAULT @@ -43,6 +50,10 @@ use base qw(Exporter); AUTH_ERROR AUTH_LOGINFAILED AUTH_DISABLED + AUTH_NO_SUCH_USER + + USER_PASSWORD_MIN_LENGTH + USER_PASSWORD_MAX_LENGTH LOGIN_OPTIONAL LOGIN_NORMAL @@ -70,10 +81,17 @@ use base qw(Exporter); COMMENT_COLS + CMT_NORMAL + CMT_DUPE_OF + CMT_HAS_DUPE + CMT_POPULAR_VOTES + CMT_MOVED_TO + UNLOCK_ABORT + THROW_ERROR RELATIONSHIPS - REL_ASSIGNEE REL_QA REL_REPORTER REL_CC REL_VOTER + REL_ASSIGNEE REL_QA REL_REPORTER REL_CC REL_VOTER REL_GLOBAL_WATCHER REL_ANY POS_EVENTS @@ -89,15 +107,47 @@ use base qw(Exporter); FULLTEXT_BUGLIST_LIMIT ADMIN_GROUP_NAME + PER_PRODUCT_PRIVILEGES SENDMAIL_EXE + SENDMAIL_PATH + + FIELD_TYPE_UNKNOWN + FIELD_TYPE_FREETEXT + FIELD_TYPE_SINGLE_SELECT + + BUG_STATE_OPEN + + USAGE_MODE_BROWSER + USAGE_MODE_CMDLINE + USAGE_MODE_WEBSERVICE + USAGE_MODE_EMAIL + + ERROR_MODE_WEBPAGE + ERROR_MODE_DIE + ERROR_MODE_DIE_SOAP_FAULT + + INSTALLATION_MODE_INTERACTIVE + INSTALLATION_MODE_NON_INTERACTIVE + + DB_MODULE + ROOT_USER + ON_WINDOWS + + MAX_TOKEN_AGE SAFE_PROTOCOLS + + MAX_LEN_QUERY_NAME ); @Bugzilla::Constants::EXPORT_OK = qw(contenttypes); # CONSTANTS +# +# Bugzilla version +use constant BUGZILLA_VERSION => "3.0"; + # # ControlMap constants for group_control_map. # membercontol:othercontrol => meaning @@ -137,6 +187,11 @@ use constant AUTH_NODATA => 1; use constant AUTH_ERROR => 2; use constant AUTH_LOGINFAILED => 3; use constant AUTH_DISABLED => 4; +use constant AUTH_NO_SUCH_USER => 5; + +# The minimum and maximum lengths a password must have. +use constant USER_PASSWORD_MIN_LENGTH => 3; +use constant USER_PASSWORD_MAX_LENGTH => 16; use constant LOGIN_OPTIONAL => 0; use constant LOGIN_NORMAL => 1; @@ -171,7 +226,7 @@ use constant MAILTO_GROUP => 1; # The default list of columns for buglist.cgi use constant DEFAULT_COLUMN_LIST => ( "bug_severity", "priority", "op_sys","assigned_to", - "bug_status", "resolution", "short_short_desc" + "bug_status", "resolution", "short_desc" ); # Used by query.cgi and buglist.cgi as the named-query name @@ -185,18 +240,30 @@ use constant LIST_OF_BUGS => 1; # The column length for displayed (and wrapped) bug comments. use constant COMMENT_COLS => 80; +# The type of bug comments. +use constant CMT_NORMAL => 0; +use constant CMT_DUPE_OF => 1; +use constant CMT_HAS_DUPE => 2; +use constant CMT_POPULAR_VOTES => 3; +use constant CMT_MOVED_TO => 4; + # used by Bugzilla::DB to indicate that tables are being unlocked # because of error use constant UNLOCK_ABORT => 1; +# Determine whether a validation routine should return 0 or throw +# an error when the validation fails. +use constant THROW_ERROR => 1; + use constant REL_ASSIGNEE => 0; use constant REL_QA => 1; use constant REL_REPORTER => 2; use constant REL_CC => 3; use constant REL_VOTER => 4; +use constant REL_GLOBAL_WATCHER => 5; use constant RELATIONSHIPS => REL_ASSIGNEE, REL_QA, REL_REPORTER, REL_CC, - REL_VOTER; + REL_VOTER, REL_GLOBAL_WATCHER; # Used for global events like EVT_FLAG_REQUESTED use constant REL_ANY => 100; @@ -242,12 +309,133 @@ use constant FULLTEXT_BUGLIST_LIMIT => 200; # Default administration group name. use constant ADMIN_GROUP_NAME => 'admin'; +# Privileges which can be per-product. +use constant PER_PRODUCT_PRIVILEGES => ('editcomponents', 'editbugs', 'canconfirm'); + # Path to sendmail.exe (Windows only) use constant SENDMAIL_EXE => '/usr/lib/sendmail.exe'; +# Paths to search for the sendmail binary (non-Windows) +use constant SENDMAIL_PATH => '/usr/lib:/usr/sbin:/usr/ucblib'; + +# Field types. Match values in fielddefs.type column. These are purposely +# not named after database column types, since Bugzilla fields comprise not +# only storage but also logic. For example, we might add a "user" field type +# whose values are stored in an integer column in the database but for which +# we do more than we would do for a standard integer type (f.e. we might +# display a user picker). + +use constant FIELD_TYPE_UNKNOWN => 0; +use constant FIELD_TYPE_FREETEXT => 1; +use constant FIELD_TYPE_SINGLE_SELECT => 2; + +# The maximum number of days a token will remain valid. +use constant MAX_TOKEN_AGE => 3; # Protocols which are considered as safe. use constant SAFE_PROTOCOLS => ('afs', 'cid', 'ftp', 'gopher', 'http', 'https', 'irc', 'mid', 'news', 'nntp', 'prospero', 'telnet', 'view-source', 'wais'); +# States that are considered to be "open" for bugs. +use constant BUG_STATE_OPEN => ('NEW', 'REOPENED', 'ASSIGNED', + 'UNCONFIRMED'); + +# Usage modes. Default USAGE_MODE_BROWSER. Use with Bugzilla->usage_mode. +use constant USAGE_MODE_BROWSER => 0; +use constant USAGE_MODE_CMDLINE => 1; +use constant USAGE_MODE_WEBSERVICE => 2; +use constant USAGE_MODE_EMAIL => 3; + +# Error modes. Default set by Bugzilla->usage_mode (so ERROR_MODE_WEBPAGE +# usually). Use with Bugzilla->error_mode. +use constant ERROR_MODE_WEBPAGE => 0; +use constant ERROR_MODE_DIE => 1; +use constant ERROR_MODE_DIE_SOAP_FAULT => 2; + +# The various modes that checksetup.pl can run in. +use constant INSTALLATION_MODE_INTERACTIVE => 0; +use constant INSTALLATION_MODE_NON_INTERACTIVE => 1; + +# Data about what we require for different databases. +use constant DB_MODULE => { + 'mysql' => {db => 'Bugzilla::DB::Mysql', db_version => '4.1.2', + dbd => { + package => 'DBD-mysql', + module => 'DBD::mysql', + version => '2.9003', + # Certain versions are broken, development versions are + # always disallowed. + blacklist => ['^3\.000[3-6]', '_'], + }, + name => 'MySQL'}, + 'pg' => {db => 'Bugzilla::DB::Pg', db_version => '8.00.0000', + dbd => { + package => 'DBD-Pg', + module => 'DBD::Pg', + version => '1.45', + }, + name => 'PostgreSQL'}, +}; + +# The user who should be considered "root" when we're giving +# instructions to Bugzilla administrators. +use constant ROOT_USER => $^O =~ /MSWin32/i ? 'Administrator' : 'root'; + +# True if we're on Win32. +use constant ON_WINDOWS => ($^O =~ /MSWin32/i); + +# The longest that a saved search name can be. +use constant MAX_LEN_QUERY_NAME => 64; + +sub bz_locations { + # We know that Bugzilla/Constants.pm must be in %INC at this point. + # So the only question is, what's the name of the directory + # above it? This is the most reliable way to get our current working + # directory under both mod_cgi and mod_perl. We call dirname twice + # to get the name of the directory above the "Bugzilla/" directory. + # + # Calling dirname twice like that won't work on VMS or AmigaOS + # but I doubt anybody runs Bugzilla on those. + # + # On mod_cgi this will be a relative path. On mod_perl it will be an + # absolute path. + my $libpath = dirname(dirname($INC{'Bugzilla/Constants.pm'})); + # We have to detaint $libpath, but we can't use Bugzilla::Util here. + $libpath =~ /(.*)/; + $libpath = $1; + + my ($project, $localconfig, $datadir); + if ($ENV{'PROJECT'} && $ENV{'PROJECT'} =~ /^(\w+)$/) { + $project = $1; + $localconfig = "localconfig.$project"; + $datadir = "data/$project"; + } else { + $localconfig = "localconfig"; + $datadir = "data"; + } + + # We have to return absolute paths for mod_perl. + # That means that if you modify these paths, they must be absolute paths. + return { + 'libpath' => $libpath, + # If you put the libraries in a different location than the CGIs, + # make sure this still points to the CGIs. + 'cgi_path' => $libpath, + 'templatedir' => "$libpath/template", + 'project' => $project, + 'localconfig' => "$libpath/$localconfig", + 'datadir' => "$libpath/$datadir", + 'attachdir' => "$libpath/$datadir/attachments", + 'skinsdir' => "$libpath/skins/contrib", + # $webdotdir must be in the webtree somewhere. Even if you use a + # local dot, we output images to there. Also, if $webdotdir is + # not relative to the bugzilla root directory, you'll need to + # change showdependencygraph.cgi to set image_url to the correct + # location. + # The script should really generate these graphs directly... + 'webdotdir' => "$libpath/$datadir/webdot", + 'extensionsdir' => "$libpath/extensions", + }; +} + 1; diff --git a/Bugzilla/DB.pm b/Bugzilla/DB.pm index 7a617caeb..4bfb3ae43 100644 --- a/Bugzilla/DB.pm +++ b/Bugzilla/DB.pm @@ -32,146 +32,75 @@ use strict; use DBI; -# Inherit the DB class from DBI::db and Exporter -# Note that we inherit from Exporter just to allow the old, deprecated -# interface to work. If it gets removed, the Exporter class can be removed -# from this list. -use base qw(Exporter DBI::db); - -%Bugzilla::DB::EXPORT_TAGS = - ( - deprecated => [qw(SendSQL SqlQuote - MoreSQLData FetchSQLData FetchOneColumn - PushGlobalSQLState PopGlobalSQLState) - ], -); -Exporter::export_ok_tags('deprecated'); - -use Bugzilla::Config qw(:DEFAULT :db); +# Inherit the DB class from DBI::db. +use base qw(DBI::db); + +use Bugzilla::Constants; +use Bugzilla::Install::Requirements; +use Bugzilla::Install::Localconfig; use Bugzilla::Util; use Bugzilla::Error; use Bugzilla::DB::Schema; +use List::Util qw(max); + ##################################################################### # Constants ##################################################################### use constant BLOB_TYPE => DBI::SQL_BLOB; -##################################################################### -# Deprecated Functions -##################################################################### - -# All this code is backwards compat fu. As such, its a bit ugly. Note the -# circular dependencies on Bugzilla.pm -# This is old cruft which will be removed, so there's not much use in -# having a separate package for it, or otherwise trying to avoid the circular -# dependency - -# XXX - mod_perl -# These use |our| instead of |my| because they need to be cleared from -# Bugzilla.pm. See bug 192531 for details. -our $_current_sth; -our @SQLStateStack = (); - -my $_fetchahead; - -sub SendSQL { - my ($str) = @_; - - $_current_sth = Bugzilla->dbh->prepare($str); - - $_current_sth->execute; - - # This is really really ugly, but its what we get for not doing - # error checking for 5 years. See bug 189446 and bug 192531 - $_current_sth->{RaiseError} = 0; - - undef $_fetchahead; -} - -# Its much much better to use bound params instead of this -sub SqlQuote { - my ($str) = @_; - - # Backwards compat code - return "''" if not defined $str; - - my $res = Bugzilla->dbh->quote($str); - - trick_taint($res); - - return $res; -} - -sub MoreSQLData { - return 1 if defined $_fetchahead; - - if ($_fetchahead = $_current_sth->fetchrow_arrayref()) { - return 1; - } - return 0; -} - -sub FetchSQLData { - if (defined $_fetchahead) { - my @result = @$_fetchahead; - undef $_fetchahead; - return @result; - } - - return $_current_sth->fetchrow_array; -} - -sub FetchOneColumn { - my @row = FetchSQLData(); - return $row[0]; -} - -sub PushGlobalSQLState { - push @SQLStateStack, $_current_sth; - push @SQLStateStack, $_fetchahead; -} - -sub PopGlobalSQLState { - die ("PopGlobalSQLState: stack underflow") if ( scalar(@SQLStateStack) < 1 ); - $_fetchahead = pop @SQLStateStack; - $_current_sth = pop @SQLStateStack; -} - -# MODERN CODE BELOW +# Set default values for what used to be the enum types. These values +# are no longer stored in localconfig. If we are upgrading from a +# Bugzilla with enums to a Bugzilla without enums, we use the +# enum values. +# +# The values that you see here are ONLY DEFAULTS. They are only used +# the FIRST time you run checksetup.pl, IF you are NOT upgrading from a +# Bugzilla with enums. After that, they are either controlled through +# the Bugzilla UI or through the DB. +use constant ENUM_DEFAULTS => { + bug_severity => ['blocker', 'critical', 'major', 'normal', + 'minor', 'trivial', 'enhancement'], + priority => ["P1","P2","P3","P4","P5"], + op_sys => ["All","Windows","Mac OS","Linux","Other"], + rep_platform => ["All","PC","Macintosh","Other"], + bug_status => ["UNCONFIRMED","NEW","ASSIGNED","REOPENED","RESOLVED", + "VERIFIED","CLOSED"], + resolution => ["","FIXED","INVALID","WONTFIX", "DUPLICATE","WORKSFORME", + "MOVED"], +}; ##################################################################### # Connection Methods ##################################################################### sub connect_shadow { - die "Tried to connect to non-existent shadowdb" unless Param('shadowdb'); + my $params = Bugzilla->params; + die "Tried to connect to non-existent shadowdb" + unless $params->{'shadowdb'}; + + my $lc = Bugzilla->localconfig; - return _connect($db_driver, Param("shadowdbhost"), - Param('shadowdb'), Param("shadowdbport"), - Param("shadowdbsock"), $db_user, $db_pass); + return _connect($lc->{db_driver}, $params->{"shadowdbhost"}, + $params->{'shadowdb'}, $params->{"shadowdbport"}, + $params->{"shadowdbsock"}, $lc->{db_user}, $lc->{db_pass}); } sub connect_main { - my ($no_db_name) = @_; - my $connect_to_db = $db_name; - $connect_to_db = "" if $no_db_name; - return _connect($db_driver, $db_host, $connect_to_db, $db_port, - $db_sock, $db_user, $db_pass); + my $lc = Bugzilla->localconfig; + return _connect($lc->{db_driver}, $lc->{db_host}, $lc->{db_name}, $lc->{db_port}, + $lc->{db_sock}, $lc->{db_user}, $lc->{db_pass}); } sub _connect { my ($driver, $host, $dbname, $port, $sock, $user, $pass) = @_; - # DB specific module have the same name as DB driver, here we - # just make sure we are not case sensitive - (my $db_module = $driver) =~ s/(\w+)/\u\L$1/g; - my $pkg_module = "Bugzilla::DB::" . $db_module; + my $pkg_module = DB_MODULE->{lc($driver)}->{db}; # do the actual import eval ("require $pkg_module") - || die ("'$db_module' is not a valid choice for \$db_driver in " + || die ("'$driver' is not a valid choice for \$db_driver in " . " localconfig: " . $@); # instantiate the correct DB specific module @@ -190,6 +119,154 @@ sub _handle_error { return 0; # Now let DBI handle raising the error } +sub bz_check_requirements { + my ($output) = @_; + + my $lc = Bugzilla->localconfig; + my $db = DB_MODULE->{lc($lc->{db_driver})}; + # Only certain values are allowed for $db_driver. + if (!defined $db) { + die "$lc->{db_driver} is not a valid choice for \$db_driver in" + . bz_locations()->{'localconfig'}; + } + + die("It is not safe to run Bugzilla inside the 'mysql' database.\n" + . "Please pick a different value for \$db_name in localconfig.") + if $lc->{db_name} eq 'mysql'; + + # Check the existence and version of the DBD that we need. + my $dbd = $db->{dbd}; + my $sql_server = $db->{name}; + my $sql_want = $db->{db_version}; + unless (have_vers($dbd, $output)) { + my $command = install_command($dbd); + my $root = ROOT_USER; + my $dbd_mod = $dbd->{module}; + my $dbd_ver = $dbd->{version}; + my $version = $dbd_ver ? " $dbd_ver or higher" : ''; + print <<EOT; + +For $sql_server, Bugzilla requires that perl's $dbd_mod $dbd_ver or later be +installed. To install this module, run the following command (as $root): + + $command + +EOT + exit; + } + + # We don't try to connect to the actual database if $db_check is + # disabled. + unless ($lc->{db_check}) { + print "\n" if $output; + return; + } + + # And now check the version of the database server itself. + my $dbh = _get_no_db_connection(); + + printf("Checking for %15s %-9s ", $sql_server, "(v$sql_want)") + if $output; + my $sql_vers = $dbh->bz_server_version; + $dbh->disconnect; + + # Check what version of the database server is installed and let + # the user know if the version is too old to be used with Bugzilla. + if ( vers_cmp($sql_vers,$sql_want) > -1 ) { + print "ok: found v$sql_vers\n" if $output; + } else { + print <<EOT; + +Your $sql_server v$sql_vers is too old. Bugzilla requires version +$sql_want or later of $sql_server. Please download and install a +newer version. + +EOT + exit; + } + + print "\n" if $output; +} + +# Note that this function requires that localconfig exist and +# be valid. +sub bz_create_database { + my $dbh; + # See if we can connect to the actual Bugzilla database. + my $conn_success = eval { $dbh = connect_main(); }; + my $db_name = Bugzilla->localconfig->{db_name}; + + if (!$conn_success) { + $dbh = _get_no_db_connection(); + print "Creating database $db_name...\n"; + + # Try to create the DB, and if we fail print a friendly error. + my $success = eval { + my @sql = $dbh->_bz_schema->get_create_database_sql($db_name); + # This ends with 1 because this particular do doesn't always + # return something. + $dbh->do($_) foreach @sql; 1; + }; + if (!$success) { + my $error = $dbh->errstr || $@; + chomp($error); + print STDERR "The '$db_name' database could not be created.", + " The error returned was:\n\n $error\n\n", + _bz_connect_error_reasons(); + exit; + } + } + + $dbh->disconnect; +} + +# A helper for bz_create_database and bz_check_requirements. +sub _get_no_db_connection { + my ($sql_server) = @_; + my $dbh; + my $lc = Bugzilla->localconfig; + my $conn_success = eval { + $dbh = _connect($lc->{db_driver}, $lc->{db_host}, '', $lc->{db_port}, + $lc->{db_sock}, $lc->{db_user}, $lc->{db_pass}); + }; + if (!$conn_success) { + my $sql_server = DB_MODULE->{lc($lc->{db_driver})}->{name}; + # Can't use $dbh->errstr because $dbh is undef. + my $error = $DBI::errstr || $@; + chomp($error); + print STDERR "There was an error connecting to $sql_server:\n\n", + " $error\n\n", _bz_connect_error_reasons(); + exit; + } + return $dbh; +} + +# Just a helper because we have to re-use this text. +# We don't use this in db_new because it gives away the database +# username, and db_new errors can show up on CGIs. +sub _bz_connect_error_reasons { + my $lc_file = bz_locations()->{'localconfig'}; + my $lc = Bugzilla->localconfig; + my $db = DB_MODULE->{lc($lc->{db_driver})}; + my $server = $db->{name}; + +return <<EOT; +This might have several reasons: + +* $server is not running. +* $server is running, but there is a problem either in the + server configuration or the database access rights. Read the Bugzilla + Guide in the doc directory. The section about database configuration + should help. +* Your password for the '$lc->{db_user}' user, specified in \$db_pass, is + incorrect, in '$lc_file'. +* There is a subtle problem with Perl, DBI, or $server. Make + sure all settings in '$lc_file' are correct. If all else fails, set + '\$db_check' to 0. + +EOT +} + # List of abstract methods we are checking the derived class implements our @_abstract_methods = qw(REQUIRED_VERSION PROGRAM_NAME DBD_VERSION new sql_regexp sql_not_regexp sql_limit sql_to_days @@ -244,7 +321,7 @@ sub sql_group_by { my ($self, $needed_columns, $optional_columns) = @_; my $expression = "GROUP BY $needed_columns"; - $expression .= ", " . $optional_columns if $optional_columns; + $expression .= ", " . $optional_columns if defined($optional_columns); return $expression; } @@ -295,14 +372,15 @@ sub bz_server_version { sub bz_last_key { my ($self, $table, $column) = @_; - return $self->last_insert_id($db_name, undef, $table, $column); + return $self->last_insert_id(Bugzilla->localconfig->{db_name}, undef, + $table, $column); } sub bz_get_field_defs { my ($self) = @_; my $extra = ""; - if (!Bugzilla->user->in_group(Param('timetrackinggroup'))) { + if (!Bugzilla->user->in_group(Bugzilla->params->{'timetrackinggroup'})) { $extra = "AND name NOT IN ('estimated_time', 'remaining_time', " . "'work_time', 'percentage_complete', 'deadline')"; } @@ -336,11 +414,18 @@ sub bz_setup_database { } } -# The default implementation just returns what you passed-in. This function -# really exists just to be overridden in Bugzilla::DB::Mysql. +# This really just exists to get overridden in Bugzilla::DB::Mysql. sub bz_enum_initial_values { - my ($self, $enum_defaults) = @_; - return $enum_defaults; + return ENUM_DEFAULTS; +} + +sub bz_populate_enum_tables { + my ($self) = @_; + + my $enum_values = $self->bz_enum_initial_values(); + while (my ($table, $values) = each %$enum_values) { + $self->_bz_populate_enum_table($table, $values); + } } ##################################################################### @@ -357,9 +442,8 @@ sub bz_add_column { if ( $new_def->{NOTNULL} && !exists $new_def->{DEFAULT} && !defined $init_value && $new_def->{TYPE} !~ /SERIAL/) { - die "Failed adding the column ${table}.${name}:\n You cannot add" - . " a NOT NULL column with no default to an existing table,\n" - . " unless you specify something for \$init_value." + ThrowCodeError('column_not_null_without_default', + { name => "$table.$name" }); } my $current_def = $self->bz_column_info($table, $name); @@ -368,7 +452,9 @@ sub bz_add_column { my @statements = $self->_bz_real_schema->get_add_column_ddl( $table, $name, $new_def, defined $init_value ? $self->quote($init_value) : undef); - print "Adding new column $name to table $table ...\n"; + print get_text('install_column_add', + { column => $name, table => $table }) . "\n" + if Bugzilla->usage_mode == USAGE_MODE_CMDLINE; foreach my $sql (@statements) { $self->do($sql); } @@ -392,12 +478,8 @@ sub bz_alter_column { # Check for NULLs my $any_nulls = $self->selectrow_array( "SELECT 1 FROM $table WHERE $name IS NULL"); - if ($any_nulls) { - die "You cannot alter the ${table}.${name} column to be" - . " NOT NULL without\nspecifying a default or" - . " something for \$set_nulls_to, because" - . " there are\nNULL values currently in it."; - } + ThrowCodeError('column_not_null_no_default_alter', + { name => "$table.$name" }) if ($any_nulls); } $self->bz_alter_column_raw($table, $name, $new_def, $current_def, $set_nulls_to); @@ -509,10 +591,27 @@ sub bz_add_table { sub _bz_add_table_raw { my ($self, $name) = @_; my @statements = $self->_bz_schema->get_table_ddl($name); - print "Adding new table $name ...\n"; + print "Adding new table $name ...\n" unless i_am_cgi(); $self->do($_) foreach (@statements); } +sub bz_add_field_table { + my ($self, $name) = @_; + my $table_schema = $self->_bz_schema->FIELD_TABLE_SCHEMA; + # We do nothing if the table already exists. + return if $self->bz_table_info($name); + my $indexes = $table_schema->{INDEXES}; + # $indexes is an arrayref, not a hash. In order to fix the keys, + # we have to fix every other item. + for (my $i = 0; $i < scalar @$indexes; $i++) { + next if ($i % 2 && $i != 0); # We skip 1, 3, 5, 7, etc. + $indexes->[$i] = $name . "_" . $indexes->[$i]; + } + # We add this to the abstract schema so that bz_add_table can find it. + $self->_bz_schema->add_table($name, $table_schema); + $self->bz_add_table($name); +} + sub bz_drop_column { my ($self, $table, $column) = @_; @@ -521,7 +620,9 @@ sub bz_drop_column { if ($current_def) { my @statements = $self->_bz_real_schema->get_drop_column_ddl( $table, $column); - print "Deleting unused column $column from table $table ...\n"; + print get_text('install_column_drop', + { table => $table, column => $column }) . "\n" + if Bugzilla->usage_mode == USAGE_MODE_CMDLINE; foreach my $sql (@statements) { # Because this is a deletion, we don't want to die hard if # we fail because of some local customization. If something @@ -581,7 +682,8 @@ sub bz_drop_table { if ($table_exists) { my @statements = $self->_bz_schema->get_drop_table_ddl($name); - print "Dropping table $name...\n"; + print get_text('install_table_drop', { name => $name }) . "\n" + if Bugzilla->usage_mode == USAGE_MODE_CMDLINE; foreach my $sql (@statements) { # Because this is a deletion, we don't want to die hard if # we fail because of some local customization. If something @@ -600,13 +702,16 @@ sub bz_rename_column { if ($old_col_exists) { my $already_renamed = $self->bz_column_info($table, $new_name); - die "Name conflict: Cannot rename ${table}.${old_name} to" - . " ${table}.${new_name},\nbecause ${table}.${new_name}" - . " already exists." if $already_renamed; + ThrowCodeError('db_rename_conflict', + { old => "$table.$old_name", + new => "$table.$new_name" }) if $already_renamed; my @statements = $self->_bz_real_schema->get_rename_column_ddl( $table, $old_name, $new_name); - print "Changing column $old_name in table $table to" - . " be named $new_name...\n"; + + print get_text('install_column_rename', + { old => "$table.$old_name", new => "$table.$new_name" }) + . "\n" if Bugzilla->usage_mode == USAGE_MODE_CMDLINE; + foreach my $sql (@statements) { $self->do($sql); } @@ -615,6 +720,23 @@ sub bz_rename_column { } } +sub bz_rename_table { + my ($self, $old_name, $new_name) = @_; + my $old_table = $self->bz_table_info($old_name); + return if !$old_table; + + my $new = $self->bz_table_info($new_name); + ThrowCodeError('db_rename_conflict', { old => $old_name, + new => $new_name }) if $new; + my @sql = $self->_bz_real_schema->get_rename_table_sql($old_name, $new_name); + print get_text('install_table_rename', + { old => $old_name, new => $new_name }) . "\n" + if Bugzilla->usage_mode == USAGE_MODE_CMDLINE; + $self->do($_) foreach @sql; + $self->_bz_real_schema->rename_table($old_name, $new_name); + $self->_bz_store_real_schema; +} + ##################################################################### # Schema Information Methods ##################################################################### @@ -622,8 +744,9 @@ sub bz_rename_column { sub _bz_schema { my ($self) = @_; return $self->{private_bz_schema} if exists $self->{private_bz_schema}; - $self->{private_bz_schema} = - Bugzilla::DB::Schema->new($self->MODULE_NAME); + my @module_parts = split('::', ref $self); + my $module_name = pop @module_parts; + $self->{private_bz_schema} = Bugzilla::DB::Schema->new($module_name); return $self->{private_bz_schema}; } @@ -668,6 +791,17 @@ sub bz_table_columns { return $self->_bz_real_schema->get_table_columns($table); } +sub bz_table_indexes { + my ($self, $table) = @_; + my $indexes = $self->_bz_real_schema->get_table_indexes_abstract($table); + my %return_indexes; + # We do this so that they're always hashes. + foreach my $name (keys %$indexes) { + $return_indexes{$name} = $self->bz_index_info($table, $name); + } + return \%return_indexes; +} + ##################################################################### # Protected "Real Database" Schema Information Methods ##################################################################### @@ -919,6 +1053,30 @@ sub _bz_store_real_schema { $sth->execute(); } +# For bz_populate_enum_tables +sub _bz_populate_enum_table { + my ($self, $table, $valuelist) = @_; + + my $sql_table = $self->quote_identifier($table); + + # Check if there are any table entries + my $table_size = $self->selectrow_array("SELECT COUNT(*) FROM $sql_table"); + + # If the table is empty... + if (!$table_size) { + my $insert = $self->prepare( + "INSERT INTO $sql_table (value,sortkey) VALUES (?,?)"); + print "Inserting values into the '$table' table:\n"; + my $sortorder = 0; + my $maxlen = max(map(length($_), @$valuelist)) + 2; + foreach my $value (@$valuelist) { + $sortorder += 100; + printf "%-${maxlen}s sortkey: $sortorder\n", "'$value'"; + $insert->execute($value, $sortorder); + } + } +} + 1; __END__ @@ -973,10 +1131,6 @@ functionality which is different between databases allowing for easy customization for particular database via inheritance. These methods should be always preffered over hard-coding SQL commands. -Access to the old SendSQL-based database routines are also provided by -importing the C<:deprecated> tag. These routines should not be used in new -code. - =head1 CONSTANTS Subclasses of Bugzilla::DB are required to define certain constants. These @@ -989,88 +1143,152 @@ constants are required to be subroutines or "use constant" variables. The C<\%attr> argument that must be passed to bind_param in order to correctly escape a C<LONGBLOB> type. -=item C<REQUIRED_VERSION> +=back + + +=head1 CONNECTION + +A new database handle to the required database can be created using this +module. This is normally done by the L<Bugzilla> module, and so these routines +should not be called from anywhere else. + +=head2 Functions + +=over -This is the minimum required version of the database server that the -Bugzilla::DB subclass requires. It should be in a format suitable for -passing to vers_cmp during installation. +=item C<connect_main> -=item C<PROGRAM_NAME> +=over -The human-readable name of this database. For example, for MySQL, this -would be 'MySQL.' You should not depend on this variable to know what -type of database you are running on; this is intended merely for displaying -to the admin to let them know what DB they're running. +=item B<Description> -=item C<MODULE_NAME> +Function to connect to the main database, returning a new database handle. -The name of the Bugzilla::DB module that we are. For example, for the MySQL -Bugzilla::DB module, this would be "Mysql." For PostgreSQL it would be "Pg." +=item B<Params> -=item C<DBD_VERSION> +=over -The minimum version of the DBD module that we require for this database. +=item C<$no_db_name> (optional) - If true, connect to the database +server, but don't connect to a specific database. This is only used +when creating a database. After you create the database, you should +re-create a new Bugzilla::DB object without using this parameter. =back +=item B<Returns> -=head1 CONNECTION +New instance of the DB class -A new database handle to the required database can be created using this -module. This is normally done by the L<Bugzilla> module, and so these routines -should not be called from anywhere else. +=back -=head2 Functions +=item C<connect_shadow> -=over 4 +=over -=item C<connect_main> +=item B<Description> - Description: Function to connect to the main database, returning a new - database handle. - Params: $no_db_name (optional) - If true, Connect to the database - server, but don't connect to a specific database. This - is only used when creating a database. After you create - the database, you should re-create a new Bugzilla::DB object - without using this parameter. - Returns: new instance of the DB class +Function to connect to the shadow database, returning a new database handle. +This routine C<die>s if no shadow database is configured. -=item C<connect_shadow> +=item B<Params> (none) - Description: Function to connect to the shadow database, returning a new - database handle. - This routine C<die>s if no shadow database is configured. - Params: none - Returns: new instance of the DB class +=item B<Returns> + +A new instance of the DB class + +=back + +=item C<bz_check_requirements> + +=over + +=item B<Description> + +Checks to make sure that you have the correct DBD and database version +installed for the database that Bugzilla will be using. Prints a message +and exits if you don't pass the requirements. + +If C<$db_check> is false (from F<localconfig>), we won't check the +database version. + +=item B<Params> + +=over + +=item C<$output> - C<true> if the function should display informational +output about what it's doing, such as versions found. + +=back + +=item B<Returns> (nothing) + +=back + + +=item C<bz_create_database> + +=over + +=item B<Description> + +Creates an empty database with the name C<$db_name>, if that database +doesn't already exist. Prints an error message and exits if we can't +create the database. + +=item B<Params> (none) + +=item B<Returns> (nothing) + +=back =item C<_connect> - Description: Internal function, creates and returns a new, connected - instance of the correct DB class. - This routine C<die>s if no driver is specified. - Params: $driver = name of the database driver to use - $host = host running the database we are connecting to - $dbname = name of the database to connect to - $port = port the database is listening on - $sock = socket the database is listening on - $user = username used to log in to the database - $pass = password used to log in to the database - Returns: new instance of the DB class +=over + +=item B<Description> + +Internal function, creates and returns a new, connected instance of the +correct DB class. This routine C<die>s if no driver is specified. + +=item B<Params> + +=over + +=item C<$driver> - name of the database driver to use + +=item C<$host> - host running the database we are connecting to + +=item C<$dbname> - name of the database to connect to + +=item C<$port> - port the database is listening on + +=item C<$sock> - socket the database is listening on + +=item C<$user> - username used to log in to the database + +=item C<$pass> - password used to log in to the database + +=back + +=item B<Returns> + +A new instance of the DB class + +=back =item C<_handle_error> - Description: Function passed to the DBI::connect call for error handling. - It shortens the error for printing. +Function passed to the DBI::connect call for error handling. It shortens the +error for printing. =item C<import> - Description: Overrides the standard import method to check that derived class - implements all required abstract methods. Also calls original - implementation in its super class. +Overrides the standard import method to check that derived class +implements all required abstract methods. Also calls original implementation +in its super class. =back - =head1 ABSTRACT METHODS Note: Methods which can be implemented generically for all DBs are implemented in @@ -1080,477 +1298,949 @@ be implemented for all supported databases separately. To avoid confusion with standard DBI methods, all methods returning string with formatted SQL command have prefix C<sql_>. All other methods have prefix C<bz_>. -=over 4 +=head2 Constructor + +=over =item C<new> - Description: Constructor - Abstract method, should be overridden by database specific code. - Params: $user = username used to log in to the database - $pass = password used to log in to the database - $host = host running the database we are connecting to - $dbname = name of the database to connect to - $port = port the database is listening on - $sock = socket the database is listening on - Returns: new instance of the DB class - Note: The constructor should create a DSN from the parameters provided and - then call C<db_new()> method of its super class to create a new - class instance. See C<db_new> description in this module. As per - DBI documentation, all class variables must be prefixed with - "private_". See L<DBI>. +=over -=item C<sql_regexp> +=item B<Description> + +Constructor. Abstract method, should be overridden by database specific +code. - Description: Outputs SQL regular expression operator for POSIX regex - searches (case insensitive) in format suitable for a given - database. - Abstract method, should be overridden by database specific code. - Params: $expr = SQL expression for the text to be searched (scalar) - $pattern = the regular expression to search for (scalar) - Returns: formatted SQL for regular expression search (e.g. REGEXP) - (scalar) +=item B<Params> -=item C<sql_not_regexp> +=over - Description: Outputs SQL regular expression operator for negative POSIX - regex searches (case insensitive) in format suitable for a given - database. - Abstract method, should be overridden by database specific code. - Params: $expr = SQL expression for the text to be searched (scalar) - $pattern = the regular expression to search for (scalar) - Returns: formatted SQL for negative regular expression search - (e.g. NOT REGEXP) (scalar) +=item C<$user> - username used to log in to the database -=item C<sql_limit> +=item C<$pass> - password used to log in to the database - Description: Returns SQL syntax for limiting results to some number of rows - with optional offset if not starting from the begining. - Abstract method, should be overridden by database specific code. - Params: $limit = number of rows to return from query (scalar) - $offset = number of rows to skip prior counting (scalar) - Returns: formatted SQL for limiting number of rows returned from query - with optional offset (e.g. LIMIT 1, 1) (scalar) +=item C<$host> - host running the database we are connecting to -=item C<sql_from_days> +=item C<$dbname> - name of the database to connect to - Description: Outputs SQL syntax for converting Julian days to date. - Abstract method, should be overridden by database specific code. - Params: $days = days to convert to date - Returns: formatted SQL for returning Julian days in dates. (scalar) +=item C<$port> - port the database is listening on -=item C<sql_to_days> +=item C<$sock> - socket the database is listening on - Description: Outputs SQL syntax for converting date to Julian days. - Abstract method, should be overridden by database specific code. - Params: $date = date to convert to days - Returns: formatted SQL for returning date fields in Julian days. (scalar) +=back -=item C<sql_date_format> +=item B<Returns> - Description: Outputs SQL syntax for formatting dates. - Abstract method, should be overridden by database specific code. - Params: $date = date or name of date type column (scalar) - $format = format string for date output (scalar) - (%Y = year, four digits, %y = year, two digits, %m = month, - %d = day, %a = weekday name, 3 letters, %H = hour 00-23, - %i = minute, %s = second) - Returns: formatted SQL for date formatting (scalar) +A new instance of the DB class -=item C<sql_interval> +=item B<Note> - Description: Outputs proper SQL syntax for a time interval function. - Abstract method, should be overridden by database specific code. - Params: $interval - the time interval requested (e.g. '30') (integer) - $units - the units the interval is in (e.g. 'MINUTE') (string) - Returns: formatted SQL for interval function (scalar) +The constructor should create a DSN from the parameters provided and +then call C<db_new()> method of its super class to create a new +class instance. See L<db_new> description in this module. As per +DBI documentation, all class variables must be prefixed with +"private_". See L<DBI>. -=item C<sql_position> +=back - Description: Outputs proper SQL syntax determinig position of a substring - (fragment) withing a string (text). Note: if the substring or - text are string constants, they must be properly quoted - (e.g. "'pattern'"). - Params: $fragment = the string fragment we are searching for (scalar) - $text = the text to search (scalar) - Returns: formatted SQL for substring search (scalar) +=back -=item C<sql_group_by> +=head2 SQL Generation - Description: Outputs proper SQL syntax for grouping the result of a query. - For ANSI SQL databases, we need to group by all columns we are - querying for (except for columns used in aggregate functions). - Some databases require (or even allow) to specify only one - or few columns if the result is uniquely defined. For those - databases, the default implementation needs to be overloaded. - Params: $needed_columns = string with comma separated list of columns - we need to group by to get expected result (scalar) - $optional_columns = string with comma separated list of all - other columns we are querying for, but which are not in the - required list. - Returns: formatted SQL for row grouping (scalar) +=over -=item C<sql_string_concat> +=item C<sql_regexp> - Description: Returns SQL syntax for concatenating multiple strings (constants - or values from table columns) together. - Params: @params = array of column names or strings to concatenate - Returns: formatted SQL for concatenating specified strings +=over -=item C<sql_fulltext_search> +=item B<Description> - Description: Returns SQL syntax for performing a full text search for - specified text on a given column. - There is a ANSI SQL version of this method implemented using - LIKE operator, but it's not a real full text search. DB specific - modules should override this, as this generic implementation will - be always much slower. This generic implementation returns - 'relevance' as 0 for no match, or 1 for a match. - Params: $column = name of column to search (scalar) - $text = text to search for (scalar) - Returns: formatted SQL for full text search +Outputs SQL regular expression operator for POSIX regex +searches (case insensitive) in format suitable for a given +database. -=item C<sql_istrcmp> +Abstract method, should be overridden by database specific code. - Description: Returns SQL for a case-insensitive string comparison. - Params: $left - What should be on the left-hand-side of the - operation. - $right - What should be on the right-hand-side of the - operation. - $op (optional) - What the operation is. Should be a - valid ANSI SQL comparison operator, like "=", "<", - "LIKE", etc. Defaults to "=" if not specified. - Returns: A SQL statement that will run the comparison in - a case-insensitive fashion. - Note: Uses sql_istring, so it has the same performance concerns. - Try to avoid using this function unless absolutely necessary. - Subclass Implementors: Override sql_istring instead of this - function, most of the time (this function uses sql_istring). +=item B<Params> -=item C<sql_istring> +=over - Description: Returns SQL syntax "preparing" a string or text column for - case-insensitive comparison. - Params: $string - string to convert (scalar) - Returns: formatted SQL making the string case insensitive - Note: The default implementation simply calls LOWER on the parameter. - If this is used to search on a text column with index, the index - will not be usually used unless it was created as LOWER(column). +=item C<$expr> - SQL expression for the text to be searched (scalar) -=item C<bz_lock_tables> +=item C<$pattern> - the regular expression to search for (scalar) - Description: Performs a table lock operation on specified tables. - If the underlying database supports transactions, it should also - implicitly start a new transaction. - Abstract method, should be overridden by database specific code. - Params: @tables = list of names of tables to lock in MySQL - notation (ex. 'bugs AS bugs2 READ', 'logincookies WRITE') - Returns: none +=back -=item C<bz_unlock_tables> +=item B<Returns> - Description: Performs a table unlock operation - If the underlying database supports transactions, it should also - implicitly commit or rollback the transaction. - Also, this function should allow to be called with the abort flag - set even without locking tables first without raising an error - to simplify error handling. - Abstract method, should be overridden by database specific code. - Params: $abort = UNLOCK_ABORT (true, 1) if the operation on locked tables - failed (if transactions are supported, the action will be rolled - back). False (0) or no param if the operation succeeded. - Returns: none +Formatted SQL for regular expression search (e.g. REGEXP) (scalar) =back +=item C<sql_not_regexp> -=head1 IMPLEMENTED METHODS +=over -These methods are implemented in Bugzilla::DB, and only need -to be implemented in subclasses if you need to override them for -database-compatibility reasons. +=item B<Description> -=head2 General Information Methods +Outputs SQL regular expression operator for negative POSIX +regex searches (case insensitive) in format suitable for a given +database. -These methods return information about data in the database. +Abstract method, should be overridden by database specific code. -=over 4 +=item B<Params> -=item C<bz_last_key> +=over + +=item C<$expr> - SQL expression for the text to be searched (scalar) - Description: Returns the last serial number, usually from a previous INSERT. - Must be executed directly following the relevant INSERT. - This base implementation uses DBI->last_insert_id. If the - DBD supports it, it is the preffered way to obtain the last - serial index. If it is not supported, the DB specific code - needs to override it with DB specific code. - Params: $table = name of table containing serial column (scalar) - $column = name of column containing serial data type (scalar) - Returns: Last inserted ID (scalar) +=item C<$pattern> - the regular expression to search for (scalar) =back +=item B<Returns> -=head2 Database Setup Methods +Formatted SQL for negative regular expression search (e.g. NOT REGEXP) +(scalar) -These methods are used by the Bugzilla installation programs to set up -the database. +=back -=over 4 +=item C<sql_limit> -=item C<bz_enum_initial_values(\%enum_defaults)> +=over - Description: For an upgrade or an initial installation, provides - what the values should be for the "enum"-type fields, - such as version, op_sys, rep_platform, etc. - Params: \%enum_defaults - The default initial list of values for - each enum field. A hash, with the field - names pointing to an arrayref of values. - Returns: A hashref with the correct initial values for the enum fields. +=item B<Description> -=back +Returns SQL syntax for limiting results to some number of rows +with optional offset if not starting from the begining. +Abstract method, should be overridden by database specific code. -=head2 Schema Modification Methods +=item B<Params> -These methods modify the current Bugzilla Schema. +=over -Where a parameter says "Abstract index/column definition", it returns/takes -information in the formats defined for indexes and columns in -C<Bugzilla::DB::Schema::ABSTRACT_SCHEMA>. +=item C<$limit> - number of rows to return from query (scalar) -=over 4 +=item C<$offset> - number of rows to skip prior counting (scalar) -=item C<bz_add_column($table, $name, \%definition, $init_value)> - - Description: Adds a new column to a table in the database. Prints out - a brief statement that it did so, to stdout. - Note that you cannot add a NOT NULL column that has no - default -- the database won't know what to set all - the NOT NULL values to. - Params: $table = the table where the column is being added - $name = the name of the new column - \%definition = Abstract column definition for the new column - $init_value = (optional) An initial value to set the column - to. Required if your column is NOT NULL and has - no DEFAULT set. - Returns: nothing +=back -=item C<bz_add_index($table, $name, $definition)> +=item B<Returns> - Description: Adds a new index to a table in the database. Prints - out a brief statement that it did so, to stdout. - If the index already exists, we will do nothing. - Params: $table - The table the new index is on. - $name - A name for the new index. - $definition - An abstract index definition. - Either a hashref or an arrayref. - Returns: nothing +Formatted SQL for limiting number of rows returned from query +with optional offset (e.g. LIMIT 1, 1) (scalar) -=item C<bz_add_table($name)> +=back - Description: Creates a new table in the database, based on the - definition for that table in the abstract schema. - Note that unlike the other 'add' functions, this does - not take a definition, but always creates the table - as it exists in the ABSTRACT_SCHEMA. - If a table with that name already exists, then this - function returns silently. - Params: $name - The name of the table you want to create. - Returns: nothing +=item C<sql_from_days> -=item C<bz_drop_index($table, $name)> +=over - Description: Removes an index from the database. Prints out a brief - statement that it did so, to stdout. If the index - doesn't exist, we do nothing. - Params: $table - The table that the index is on. - $name - The name of the index that you want to drop. - Returns: nothing +=item B<Description> -=item C<bz_drop_table($name)> +Outputs SQL syntax for converting Julian days to date. - Description: Drops a table from the database. If the table - doesn't exist, we just return silently. - Params: $name - The name of the table to drop. - Returns: nothing +Abstract method, should be overridden by database specific code. -=item C<bz_alter_column($table, $name, \%new_def, $set_nulls_to)> - - Description: Changes the data type of a column in a table. Prints out - the changes being made to stdout. If the new type is the - same as the old type, the function returns without changing - anything. - Params: $table = the table where the column is - $name = the name of the column you want to change - $new_def = An abstract column definition for the new - data type of the columm - $set_nulls_to = (Optional) If you are changing the column - to be NOT NULL, you probably also want to - set any existing NULL columns to a particular - value. Specify that value here. - NOTE: The value should not already be SQL-quoted. - Returns: nothing +=item B<Params> -=item C<bz_drop_column($table, $column)> - - Description: Removes a column from a database table. If the column - doesn't exist, we return without doing anything. If we do - anything, we print a short message to stdout about the change. - Params: $table = The table where the column is - $column = The name of the column you want to drop - Returns: none - -=item C<bz_rename_column($table, $old_name, $new_name)> - - Description: Renames a column in a database table. If the C<$old_name> - column doesn't exist, we return without doing anything. - If C<$old_name> and C<$new_name> both already exist in the - table specified, we fail. - Params: $table = The table containing the column - that you want to rename - $old_name = The current name of the column that - you want to rename - $new_name = The new name of the column - Returns: nothing +=over + +=item C<$days> - days to convert to date =back +=item B<Returns> -=head2 Schema Information Methods +Formatted SQL for returning Julian days in dates. (scalar) -These methods return information about the current Bugzilla database -schema, as it currently exists on the disk. +=back -Where a parameter says "Abstract index/column definition", it returns/takes -information in the formats defined for indexes and columns in -C<Bugzilla::DB::Schema::ABSTRACT_SCHEMA>. +=item C<sql_to_days> -=over 4 +=over -=item C<bz_column_info($table, $column)> +=item B<Description> - Description: Get abstract column definition. - Params: $table - The name of the table the column is in. - $column - The name of the column. - Returns: An abstract column definition for that column. - If the table or column does not exist, we return undef. +Outputs SQL syntax for converting date to Julian days. -=item C<bz_index_info($table, $index)> +Abstract method, should be overridden by database specific code. - Description: Get abstract index definition. - Params: $table - The table the index is on. - $index - The name of the index. - Returns: An abstract index definition for that index, - always in hashref format. The hashref will - always contain the TYPE element, but it will - be an empty string if it's just a normal index. - If the index does not exist, we return undef. +=item B<Params> -=back +=over +=item C<$date> - date to convert to days -=head2 Deprecated Schema Information Methods +=back -These methods return info about the current Bugzilla database, for -MySQL only. +=item B<Returns> -=over 4 +Formatted SQL for returning date fields in Julian days. (scalar) -=item C<bz_get_field_defs> +=back - Description: Returns a list of all the "bug" fields in Bugzilla. The list - contains hashes, with a 'name' key and a 'description' key. - Params: none - Returns: List of all the "bug" fields +=item C<sql_date_format> -=back +=over +=item B<Description> -=head2 Transaction Methods +Outputs SQL syntax for formatting dates. -These methods deal with the starting and stopping of transactions -in the database. +Abstract method, should be overridden by database specific code. -=over 4 +=item B<Params> -=item C<bz_start_transaction> +=over - Description: Starts a transaction if supported by the database being used - Params: none - Returns: none +=item C<$date> - date or name of date type column (scalar) -=item C<bz_commit_transaction> +=item C<$format> - format string for date output (scalar) +(C<%Y> = year, four digits, C<%y> = year, two digits, C<%m> = month, +C<%d> = day, C<%a> = weekday name, 3 letters, C<%H> = hour 00-23, +C<%i> = minute, C<%s> = second) - Description: Ends a transaction, commiting all changes, if supported by - the database being used - Params: none - Returns: none +=back -=item C<bz_rollback_transaction> +=item B<Returns> - Description: Ends a transaction, rolling back all changes, if supported by - the database being used - Params: none - Returns: none +Formatted SQL for date formatting (scalar) =back +=item C<sql_interval> -=head1 SUBCLASS HELPERS - -Methods in this class are intended to be used by subclasses to help them -with their functions. +=over -=over 4 +=item B<Description> -=item C<db_new> +Outputs proper SQL syntax for a time interval function. - Description: Constructor - Params: $dsn = database connection string - $user = username used to log in to the database - $pass = password used to log in to the database - $attributes = set of attributes for DB connection (optional) - Returns: new instance of the DB class - Note: the name of this constructor is not new, as that would make - our check for implementation of new() by derived class useles. +Abstract method, should be overridden by database specific code. -=back +=item B<Params> +=over -=head1 DEPRECATED ROUTINES +=item C<$interval> - the time interval requested (e.g. '30') (integer) -Several database routines are deprecated. They should not be used in new code, -and so are not documented. +=item C<$units> - the units the interval is in (e.g. 'MINUTE') (string) -=over 4 +=back -=item * +=item B<Returns> -SendSQL +Formatted SQL for interval function (scalar) -=item * +=back -SqlQuote +=item C<sql_position> -=item * +=over -MoreSQLData +=item B<Description> -=item * +Outputs proper SQL syntax determinig position of a substring +(fragment) withing a string (text). Note: if the substring or +text are string constants, they must be properly quoted (e.g. "'pattern'"). -FetchSQLData +=item B<Params> -=item * +=over -FetchOneColumn +=item C<$fragment> - the string fragment we are searching for (scalar) -=item * +=item C<$text> - the text to search (scalar) -PushGlobalSQLState +=back -=item * +=item B<Returns> -PopGlobalSQLState +Formatted SQL for substring search (scalar) + +=back + +=item C<sql_group_by> + +=over + +=item B<Description> + +Outputs proper SQL syntax for grouping the result of a query. + +For ANSI SQL databases, we need to group by all columns we are +querying for (except for columns used in aggregate functions). +Some databases require (or even allow) to specify only one +or few columns if the result is uniquely defined. For those +databases, the default implementation needs to be overloaded. + +=item B<Params> + +=over + +=item C<$needed_columns> - string with comma separated list of columns +we need to group by to get expected result (scalar) + +=item C<$optional_columns> - string with comma separated list of all +other columns we are querying for, but which are not in the required list. + +=back + +=item B<Returns> + +Formatted SQL for row grouping (scalar) + +=back + +=item C<sql_string_concat> + +=over + +=item B<Description> + +Returns SQL syntax for concatenating multiple strings (constants +or values from table columns) together. + +=item B<Params> + +=over + +=item C<@params> - array of column names or strings to concatenate + +=back + +=item B<Returns> + +Formatted SQL for concatenating specified strings + +=back + +=item C<sql_fulltext_search> + +=over + +=item B<Description> + +Returns SQL syntax for performing a full text search for specified text +on a given column. + +There is a ANSI SQL version of this method implemented using LIKE operator, +but it's not a real full text search. DB specific modules should override +this, as this generic implementation will be always much slower. This +generic implementation returns 'relevance' as 0 for no match, or 1 for a +match. + +=item B<Params> + +=over + +=item C<$column> - name of column to search (scalar) + +=item C<$text> - text to search for (scalar) + +=back + +=item B<Returns> + +Formatted SQL for full text search + +=back + +=item C<sql_istrcmp> + +=over + +=item B<Description> + +Returns SQL for a case-insensitive string comparison. + +=item B<Params> + +=over + +=item C<$left> - What should be on the left-hand-side of the operation. + +=item C<$right> - What should be on the right-hand-side of the operation. + +=item C<$op> (optional) - What the operation is. Should be a valid ANSI +SQL comparison operator, such as C<=>, C<E<lt>>, C<LIKE>, etc. Defaults +to C<=> if not specified. + +=back + +=item B<Returns> + +A SQL statement that will run the comparison in a case-insensitive fashion. + +=item B<Note> + +Uses L</sql_istring>, so it has the same performance concerns. +Try to avoid using this function unless absolutely necessary. + +Subclass Implementors: Override sql_istring instead of this +function, most of the time (this function uses sql_istring). + +=back + +=item C<sql_istring> + +=over + +=item B<Description> + +Returns SQL syntax "preparing" a string or text column for case-insensitive +comparison. + +=item B<Params> + +=over + +=item C<$string> - string to convert (scalar) + +=back + +=item B<Returns> + +Formatted SQL making the string case insensitive. + +=item B<Note> + +The default implementation simply calls LOWER on the parameter. +If this is used to search on a text column with index, the index +will not be usually used unless it was created as LOWER(column). + +=back + +=item C<bz_lock_tables> + +=over + +=item B<Description> + +Performs a table lock operation on specified tables. If the underlying +database supports transactions, it should also implicitly start a new +transaction. + +Abstract method, should be overridden by database specific code. + +=item B<Params> + +=over + +=item C<@tables> - list of names of tables to lock in MySQL +notation (ex. 'bugs AS bugs2 READ', 'logincookies WRITE') + +=back + +=item B<Returns> (nothing) + +=back + +=item C<bz_unlock_tables> + +=over + +=item B<Description> + +Performs a table unlock operation. + +If the underlying database supports transactions, it should also implicitly +commit or rollback the transaction. + +Also, this function should allow to be called with the abort flag +set even without locking tables first without raising an error +to simplify error handling. + +Abstract method, should be overridden by database specific code. + +=item B<Params> + +=over + +=item C<$abort> - C<UNLOCK_ABORT> if the operation on locked tables +failed (if transactions are supported, the action will be rolled +back). No param if the operation succeeded. This is only used by +L<Bugzilla::Error/throw_error>. + +=back + +=item B<Returns> (none) + +=back + +=back + + +=head1 IMPLEMENTED METHODS + +These methods are implemented in Bugzilla::DB, and only need +to be implemented in subclasses if you need to override them for +database-compatibility reasons. + +=head2 General Information Methods + +These methods return information about data in the database. + +=over + +=item C<bz_last_key> + +=over + +=item B<Description> + +Returns the last serial number, usually from a previous INSERT. + +Must be executed directly following the relevant INSERT. +This base implementation uses L<DBI/last_insert_id>. If the +DBD supports it, it is the preffered way to obtain the last +serial index. If it is not supported, the DB-specific code +needs to override this function. + +=item B<Params> + +=over + +=item C<$table> - name of table containing serial column (scalar) + +=item C<$column> - name of column containing serial data type (scalar) + +=back + +=item B<Returns> + +Last inserted ID (scalar) + +=back + +=item C<bz_get_field_defs> + +=over + +=item B<Description> + +Returns a list of all the "bug" fields in Bugzilla. The list +contains hashes, with a C<name> key and a C<description> key. + +=item B<Params> (none) + +=item B<Returns> + +List of all the "bug" fields + +=back + +=back + +=head2 Database Setup Methods + +These methods are used by the Bugzilla installation programs to set up +the database. + +=over + +=item C<bz_populate_enum_tables> + +=over + +=item B<Description> + +For an upgrade or an initial installation, populates the tables that hold +the legal values for the old "enum" fields: C<bug_severity>, +C<resolution>, etc. Prints out information if it inserts anything into the +DB. + +=item B<Params> (none) + +=item B<Returns> (nothing) + +=back + +=back + + +=head2 Schema Modification Methods + +These methods modify the current Bugzilla Schema. + +Where a parameter says "Abstract index/column definition", it returns/takes +information in the formats defined for indexes and columns in +C<Bugzilla::DB::Schema::ABSTRACT_SCHEMA>. + +=over + +=item C<bz_add_column> + +=over + +=item B<Description> + +Adds a new column to a table in the database. Prints out a brief statement +that it did so, to stdout. Note that you cannot add a NOT NULL column that +has no default -- the database won't know what to set all the NULL +values to. + +=item B<Params> + +=over + +=item C<$table> - the table where the column is being added + +=item C<$name> - the name of the new column + +=item C<\%definition> - Abstract column definition for the new column + +=item C<$init_value> (optional) - An initial value to set the column +to. Required if your column is NOT NULL and has no DEFAULT set. + +=back + +=item B<Returns> (nothing) + +=back + +=item C<bz_add_index> + +=over + +=item B<Description> + +Adds a new index to a table in the database. Prints out a brief statement +that it did so, to stdout. If the index already exists, we will do nothing. + +=item B<Params> + +=over + +=item C<$table> - The table the new index is on. + +=item C<$name> - A name for the new index. + +=item C<$definition> - An abstract index definition. Either a hashref +or an arrayref. + +=back + +=item B<Returns> (nothing) + +=back + +=item C<bz_add_table> + +=over + +=item B<Description> + +Creates a new table in the database, based on the definition for that +table in the abstract schema. + +Note that unlike the other 'add' functions, this does not take a +definition, but always creates the table as it exists in +L<Bugzilla::DB::Schema/ABSTRACT_SCHEMA>. + +If a table with that name already exists, then this function returns +silently. + +=item B<Params> + +=over + +=item C<$name> - The name of the table you want to create. + +=back + +=item B<Returns> (nothing) + +=back + +=item C<bz_drop_index> + +=over + +=item B<Description> + +Removes an index from the database. Prints out a brief statement that it +did so, to stdout. If the index doesn't exist, we do nothing. + +=item B<Params> + +=over + +=item C<$table> - The table that the index is on. + +=item C<$name> - The name of the index that you want to drop. + +=back + +=item B<Returns> (nothing) + +=back + +=item C<bz_drop_table> + +=over + +=item B<Description> + +Drops a table from the database. If the table doesn't exist, we just +return silently. + +=item B<Params> + +=over + +=item C<$name> - The name of the table to drop. + +=back + +=item B<Returns> (nothing) + +=back + +=item C<bz_alter_column> + +=over + +=item B<Description> + +Changes the data type of a column in a table. Prints out the changes +being made to stdout. If the new type is the same as the old type, +the function returns without changing anything. + +=item B<Params> + +=over + +=item C<$table> - the table where the column is + +=item C<$name> - the name of the column you want to change + +=item C<\%new_def> - An abstract column definition for the new +data type of the columm + +=item C<$set_nulls_to> (Optional) - If you are changing the column +to be NOT NULL, you probably also want to set any existing NULL columns +to a particular value. Specify that value here. B<NOTE>: The value should +not already be SQL-quoted. + +=back + +=item B<Returns> (nothing) + +=back + +=item C<bz_drop_column> + +=over + +=item B<Description> + +Removes a column from a database table. If the column doesn't exist, we +return without doing anything. If we do anything, we print a short +message to C<stdout> about the change. + +=item B<Params> + +=over + +=item C<$table> - The table where the column is + +=item C<$column> - The name of the column you want to drop + +=back + +=item B<Returns> (nothing) + +=back + +=item C<bz_rename_column> + +=over + +=item B<Description> + +Renames a column in a database table. If the C<$old_name> column +doesn't exist, we return without doing anything. If C<$old_name> +and C<$new_name> both already exist in the table specified, we fail. + +=item B<Params> + +=over + +=item C<$table> - The name of the table containing the column +that you want to rename + +=item C<$old_name> - The current name of the column that you want to rename + +=item C<$new_name> - The new name of the column + +=back + +=item B<Returns> (nothing) + +=back + +=item C<bz_rename_table> + +=over + +=item B<Description> + +Renames a table in the database. Does nothing if the table doesn't exist. + +Throws an error if the old table exists and there is already a table +with the new name. + +=item B<Params> + +=over + +=item C<$old_name> - The current name of the table. + +=item C<$new_name> - What you're renaming the table to. + +=back + +=item B<Returns> (nothing) + +=back + +=back + +=head2 Schema Information Methods + +These methods return information about the current Bugzilla database +schema, as it currently exists on the disk. + +Where a parameter says "Abstract index/column definition", it returns/takes +information in the formats defined for indexes and columns for +L<Bugzilla::DB::Schema/ABSTRACT_SCHEMA>. + +=over + +=item C<bz_column_info> + +=over + +=item B<Description> + +Get abstract column definition. + +=item B<Params> + +=over + +=item C<$table> - The name of the table the column is in. + +=item C<$column> - The name of the column. + +=back + +=item B<Returns> + +An abstract column definition for that column. If the table or column +does not exist, we return C<undef>. + +=back + +=item C<bz_index_info> + +=over + +=item B<Description> + +Get abstract index definition. + +=item B<Params> + +=over + +=item C<$table> - The table the index is on. + +=item C<$index> - The name of the index. + +=back + +=item B<Returns> + +An abstract index definition for that index, always in hashref format. +The hashref will always contain the C<TYPE> element, but it will +be an empty string if it's just a normal index. + +If the index does not exist, we return C<undef>. + +=back + +=back + + +=head2 Transaction Methods + +These methods deal with the starting and stopping of transactions +in the database. + +=over + +=item C<bz_start_transaction> + +Starts a transaction if supported by the database being used. Returns nothing +and takes no parameters. + +=item C<bz_commit_transaction> + +Ends a transaction, commiting all changes, if supported by the database +being used. Returns nothing and takes no parameters. + +=item C<bz_rollback_transaction> + +Ends a transaction, rolling back all changes, if supported by the database +being used. Returns nothing and takes no parameters. + +=back + + +=head1 SUBCLASS HELPERS + +Methods in this class are intended to be used by subclasses to help them +with their functions. + +=over + +=item C<db_new> + +=over + +=item B<Description> + +Constructor + +=item B<Params> + +=over + +=item C<$dsn> - database connection string + +=item C<$user> - username used to log in to the database + +=item C<$pass> - password used to log in to the database + +=item C<\%attributes> - set of attributes for DB connection (optional) + +=back + +=item B<Returns> + +A new instance of the DB class + +=item B<Note> + +The name of this constructor is not C<new>, as that would make +our check for implementation of C<new> by derived class useless. + +=back =back @@ -1559,4 +2249,4 @@ PopGlobalSQLState L<DBI> -=cut +L<Bugzilla::Constants/DB_MODULE> diff --git a/Bugzilla/DB/CVS/Entries b/Bugzilla/DB/CVS/Entries index 81a890074..cfc0053af 100644 --- a/Bugzilla/DB/CVS/Entries +++ b/Bugzilla/DB/CVS/Entries @@ -1,4 +1,4 @@ -/Mysql.pm/1.36.2.5/Fri Nov 17 00:18:46 2006//TBUGZILLA-2_22_3 -/Pg.pm/1.18.2.1/Mon Nov 20 04:29:55 2006//TBUGZILLA-2_22_3 -/Schema.pm/1.45.2.3/Mon Nov 20 04:36:25 2006//TBUGZILLA-2_22_3 +/Mysql.pm/1.49/Sun Feb 4 16:59:30 2007//TBUGZILLA-3_0 +/Pg.pm/1.23/Mon Nov 20 04:28:01 2006//TBUGZILLA-3_0 +/Schema.pm/1.80.2.2/Thu Apr 19 13:01:04 2007//TBUGZILLA-3_0 D/Schema//// diff --git a/Bugzilla/DB/CVS/Tag b/Bugzilla/DB/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/Bugzilla/DB/CVS/Tag +++ b/Bugzilla/DB/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/Bugzilla/DB/Mysql.pm b/Bugzilla/DB/Mysql.pm index 116e66353..9b4102eb6 100644 --- a/Bugzilla/DB/Mysql.pm +++ b/Bugzilla/DB/Mysql.pm @@ -43,17 +43,13 @@ package Bugzilla::DB::Mysql; use strict; +use Bugzilla::Constants; use Bugzilla::Util; use Bugzilla::Error; # This module extends the DB interface via inheritance use base qw(Bugzilla::DB); -use constant REQUIRED_VERSION => '4.0.14'; -use constant PROGRAM_NAME => 'MySQL'; -use constant MODULE_NAME => 'Mysql'; -use constant DBD_VERSION => '2.9003'; - sub new { my ($class, $user, $pass, $host, $dbname, $port, $sock) = @_; @@ -64,6 +60,10 @@ sub new { my $self = $class->db_new($dsn, $user, $pass); + # This makes sure that if the tables are encoded as UTF-8, we + # return their data correctly. + $self->do("SET NAMES utf8") if Bugzilla->params->{'utf8'}; + # all class local variables stored in DBI derived class needs to have # a prefix 'private_'. See DBI documentation. $self->{private_bz_tables_locked} = ""; @@ -180,14 +180,10 @@ sub sql_position { my ($self, $fragment, $text) = @_; # mysql 4.0.1 and lower do not support CAST - # mysql 3.*.* had a case-sensitive INSTR # (checksetup has a check for unsupported versions) + my $server_version = $self->bz_server_version; - if ($server_version =~ /^3\./) { - return "INSTR($text, $fragment)"; - } else { - return "INSTR(CAST($text AS BINARY), CAST($fragment AS BINARY))"; - } + return "INSTR(CAST($text AS BINARY), CAST($fragment AS BINARY))"; } sub sql_group_by { @@ -354,7 +350,7 @@ sub bz_setup_database { . "If you would like to cancel, press Ctrl-C now..." . " (Waiting 45 seconds...)\n\n"; # Wait 45 seconds for them to respond. - sleep(45); + sleep(45) unless Bugzilla->installation_answers->{NO_PAUSE}; } print "Renaming indexes...\n"; @@ -554,12 +550,115 @@ sub bz_setup_database { MAX_ROWS=100000"); } + # Convert the database to UTF-8 if the utf8 parameter is on. + if (Bugzilla->params->{'utf8'} && !$self->bz_db_is_utf8) { + print <<EOT; + +WARNING: We are about to convert your table storage format to UTF8. This + allows Bugzilla to correctly store and sort international characters. + However, if you have any non-UTF-8 data in your database, + it ***WILL BE DELETED*** by this process. So, before + you continue with checksetup.pl, if you have any non-UTF-8 + data (or even if you're not sure) you should press Ctrl-C now + to interrupt checksetup.pl, and run contrib/recode.pl to make all + the data in your database into UTF-8. You should also back up your + database before continuing. This will affect every single table + in the database, even non-Bugzilla tables. + + If you ever used a version of Bugzilla before 2.22, we STRONGLY + recommend that you stop checksetup.pl NOW and run contrib/recode.pl. + +EOT + + if (!Bugzilla->installation_answers->{NO_PAUSE}) { + if (Bugzilla->installation_mode == + INSTALLATION_MODE_NON_INTERACTIVE) + { + print <<EOT; + Re-run checksetup.pl in interactive mode (without an 'answers' file) + to continue. +EOT + exit; + } + else { + print " Press Enter to continue or Ctrl-C to exit..."; + getc; + } + } + + print "Converting table storage format to UTF-8. This may take a", + " while.\n"; + foreach my $table ($self->bz_table_list_real) { + my $info_sth = $self->prepare("SHOW FULL COLUMNS FROM $table"); + $info_sth->execute(); + while (my $column = $info_sth->fetchrow_hashref) { + # Our conversion code doesn't work on enum fields, but they + # all go away later in checksetup anyway. + next if $column->{Type} =~ /enum/i; + + # If this particular column isn't stored in utf-8 + if ($column->{Collation} + && $column->{Collation} ne 'NULL' + && $column->{Collation} !~ /utf8/) + { + my $name = $column->{Field}; + + # The code below doesn't work on a field with a FULLTEXT + # index. So we drop it. The upgrade code will re-create + # it later. + if ($table eq 'longdescs' && $name eq 'thetext') { + $self->bz_drop_index('longdescs', + 'longdescs_thetext_idx'); + } + if ($table eq 'bugs' && $name eq 'short_desc') { + $self->bz_drop_index('bugs', 'bugs_short_desc_idx'); + } + + print "Converting $table.$name to be stored as UTF-8...\n"; + my $col_info = + $self->bz_column_info_real($table, $name); + + # CHANGE COLUMN doesn't take PRIMARY KEY + delete $col_info->{PRIMARYKEY}; + + my $sql_def = $self->_bz_schema->get_type_ddl($col_info); + # We don't want MySQL to actually try to *convert* + # from our current charset to UTF-8, we just want to + # transfer the bytes directly. This is how we do that. + + # The CHARACTER SET part of the definition has to come + # right after the type, which will always come first. + my ($binary, $utf8) = ($sql_def, $sql_def); + my $type = $self->_bz_schema->convert_type($col_info->{TYPE}); + $binary =~ s/(\Q$type\E)/$1 CHARACTER SET binary/; + $utf8 =~ s/(\Q$type\E)/$1 CHARACTER SET utf8/; + $self->do("ALTER TABLE $table CHANGE COLUMN $name $name + $binary"); + $self->do("ALTER TABLE $table CHANGE COLUMN $name $name + $utf8"); + } + } + + $self->do("ALTER TABLE $table DEFAULT CHARACTER SET utf8"); + } # foreach my $table (@tables) + + my $db_name = Bugzilla->localconfig->{db_name}; + $self->do("ALTER DATABASE $db_name CHARACTER SET utf8"); + } +} + +sub bz_db_is_utf8 { + my $self = shift; + my $db_collation = $self->selectrow_arrayref( + "SHOW VARIABLES LIKE 'character_set_database'"); + # First column holds the variable name, second column holds the value. + return $db_collation->[1] =~ /utf8/ ? 1 : 0; } sub bz_enum_initial_values { - my ($self, $enum_defaults) = @_; - my %enum_values = %$enum_defaults; + my ($self) = @_; + my %enum_values = %{$self->ENUM_DEFAULTS}; # Get a complete description of the 'bugs' table; with DBD::MySQL # there isn't a column-by-column way of doing this. Could use # $dbh->column_info, but it would go slower and we would have to @@ -662,23 +761,16 @@ sub bz_index_info_real { # 6 = Cardinality. Either a number or undef. # 7 = sub_part. Usually undef. Sometimes 1. # 8 = "packed". Usually undef. - # MySQL 3 - # ------- - # 9 = comments. Usually an empty string. Sometimes 'FULLTEXT'. - # MySQL 4 - # ------- # 9 = Null. Sometimes undef, sometimes 'YES'. # 10 = Index_type. The type of the index. Usually either 'BTREE' or 'FULLTEXT' # 11 = 'Comment.' Usually undef. - my $is_mysql3 = ($self->bz_server_version() =~ /^3/); - my $index_type_loc = $is_mysql3 ? 9 : 10; while (my $raw_def = $sth->fetchrow_arrayref) { if ($raw_def->[2] eq $index) { push(@fields, $raw_def->[4]); # No index can be both UNIQUE and FULLTEXT, that's why # this is written this way. $index_type = $raw_def->[1] ? '' : 'UNIQUE'; - $index_type = $raw_def->[$index_type_loc] eq 'FULLTEXT' + $index_type = $raw_def->[10] eq 'FULLTEXT' ? 'FULLTEXT' : $index_type; } } diff --git a/Bugzilla/DB/Pg.pm b/Bugzilla/DB/Pg.pm index 34fe66a02..f6a520936 100644 --- a/Bugzilla/DB/Pg.pm +++ b/Bugzilla/DB/Pg.pm @@ -50,10 +50,6 @@ use DBD::Pg; use base qw(Bugzilla::DB); use constant BLOB_TYPE => { pg_type => DBD::Pg::PG_BYTEA }; -use constant REQUIRED_VERSION => '7.03.0000'; -use constant PROGRAM_NAME => 'PostgreSQL'; -use constant MODULE_NAME => 'Pg'; -use constant DBD_VERSION => '1.31'; sub new { my ($class, $user, $pass, $host, $dbname, $port) = @_; @@ -215,6 +211,15 @@ sub bz_unlock_tables { } } +# Tell us whether or not a particular sequence exists in the DB. +sub bz_sequence_exists { + my ($self, $seq_name) = @_; + my $exists = $self->selectrow_array( + 'SELECT 1 FROM pg_statio_user_sequences WHERE relname = ?', + undef, $seq_name); + return $exists || 0; +} + ##################################################################### # Custom Database Setup ##################################################################### @@ -232,6 +237,59 @@ sub bz_setup_database { # login_name, which we do with sql_istrcmp all over the place. $self->bz_add_index('profiles', 'profiles_login_name_lower_idx', {FIELDS => ['LOWER(login_name)'], TYPE => 'UNIQUE'}); + + # Now that Bugzilla::Object uses sql_istrcmp, other tables + # also need a LOWER() index. + _fix_case_differences('fielddefs', 'name'); + $self->bz_add_index('fielddefs', 'fielddefs_name_lower_idx', + {FIELDS => ['LOWER(name)'], TYPE => 'UNIQUE'}); + _fix_case_differences('keyworddefs', 'name'); + $self->bz_add_index('keyworddefs', 'keyworddefs_name_lower_idx', + {FIELDS => ['LOWER(name)'], TYPE => 'UNIQUE'}); + _fix_case_differences('products', 'name'); + $self->bz_add_index('products', 'products_name_lower_idx', + {FIELDS => ['LOWER(name)'], TYPE => 'UNIQUE'}); + + # bz_rename_column didn't correctly rename the sequence. + if ($self->bz_column_info('fielddefs', 'id') + && $self->bz_sequence_exists('fielddefs_fieldid_seq')) + { + print "Fixing fielddefs_fieldid_seq sequence...\n"; + $self->do("ALTER TABLE fielddefs_fieldid_seq RENAME TO fielddefs_id_seq"); + $self->do("ALTER TABLE fielddefs ALTER COLUMN id + SET DEFAULT NEXTVAL('fielddefs_id_seq')"); + } +} + +# Renames things that differ only in case. +sub _fix_case_differences { + my ($table, $field) = @_; + my $dbh = Bugzilla->dbh; + + my $duplicates = $dbh->selectcol_arrayref( + "SELECT DISTINCT LOWER($field) FROM $table + GROUP BY LOWER($field) HAVING COUNT(LOWER($field)) > 1"); + + foreach my $name (@$duplicates) { + my $dups = $dbh->selectcol_arrayref( + "SELECT $field FROM $table WHERE LOWER($field) = ?", + undef, $name); + my $primary = shift @$dups; + foreach my $dup (@$dups) { + my $new_name = "${dup}_"; + # Make sure the new name isn't *also* a duplicate. + while (1) { + last if (!$dbh->selectrow_array( + "SELECT 1 FROM $table WHERE LOWER($field) = ?", + undef, lc($new_name))); + $new_name .= "_"; + } + print "$table '$primary' and '$dup' have names that differ", + " only in case.\nRenaming '$dup' to '$new_name'...\n"; + $dbh->do("UPDATE $table SET $field = ? WHERE $field = ?", + undef, $new_name, $dup); + } + } } ##################################################################### diff --git a/Bugzilla/DB/Schema.pm b/Bugzilla/DB/Schema.pm index f4dd0a6ec..ff81d9c62 100644 --- a/Bugzilla/DB/Schema.pm +++ b/Bugzilla/DB/Schema.pm @@ -22,6 +22,7 @@ # Max Kanat-Alexander <mkanat@bugzilla.org> # Lance Larsh <lance.larsh@oracle.com> # Dennis Melentyev <dennis.melentyev@infopulse.com.ua> +# Akamai Technologies <bugzilla-dev@akamai.com> package Bugzilla::DB::Schema; @@ -35,8 +36,11 @@ package Bugzilla::DB::Schema; use strict; use Bugzilla::Error; +use Bugzilla::Hook; use Bugzilla::Util; +use Bugzilla::Constants; +use Hash::Util qw(lock_value unlock_hash lock_keys unlock_keys); use Safe; # Historical, needed for SCHEMA_VERSION = '1.00' use Storable qw(dclone freeze thaw); @@ -78,6 +82,13 @@ That means that CGI scripts should never call any function in this module directly, but should instead rely on methods provided by Bugzilla::DB. +=head1 NEW TO SCHEMA.PM? + +If this is your first time looking at Schema.pm, especially if +you are making changes to the database, please take a look at +L<http://www.bugzilla.org/docs/developer.html#sql-schema> to learn +more about how this integrates into the rest of Bugzilla. + =cut #-------------------------------------------------------------------------- @@ -166,7 +177,7 @@ use constant ABSTRACT_SCHEMA => { bug_status => {TYPE => 'varchar(64)', NOTNULL => 1}, creation_ts => {TYPE => 'DATETIME'}, delta_ts => {TYPE => 'DATETIME', NOTNULL => 1}, - short_desc => {TYPE => 'MEDIUMTEXT', NOTNULL => 1}, + short_desc => {TYPE => 'varchar(255)', NOTNULL => 1}, op_sys => {TYPE => 'varchar(64)', NOTNULL => 1}, priority => {TYPE => 'varchar(64)', NOTNULL => 1}, product_id => {TYPE => 'INT2', NOTNULL => 1}, @@ -218,8 +229,6 @@ use constant ABSTRACT_SCHEMA => { bugs_target_milestone_idx => ['target_milestone'], bugs_qa_contact_idx => ['qa_contact'], bugs_votes_idx => ['votes'], - bugs_short_desc_idx => {FIELDS => ['short_desc'], - TYPE => 'FULLTEXT'}, ], }, @@ -255,20 +264,25 @@ use constant ABSTRACT_SCHEMA => { longdescs => { FIELDS => [ + comment_id => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, + PRIMARYKEY => 1}, bug_id => {TYPE => 'INT3', NOTNULL => 1}, who => {TYPE => 'INT3', NOTNULL => 1}, bug_when => {TYPE => 'DATETIME', NOTNULL => 1}, work_time => {TYPE => 'decimal(5,2)', NOTNULL => 1, DEFAULT => '0'}, - thetext => {TYPE => 'MEDIUMTEXT'}, + thetext => {TYPE => 'MEDIUMTEXT', NOTNULL => 1}, isprivate => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}, already_wrapped => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}, + type => {TYPE => 'INT2', NOTNULL => 1, + DEFAULT => '0'}, + extra_data => {TYPE => 'varchar(255)'} ], INDEXES => [ longdescs_bug_id_idx => ['bug_id'], - longdescs_who_idx => ['who'], + longdescs_who_idx => [qw(who bug_id)], longdescs_bug_when_idx => ['bug_when'], longdescs_thetext_idx => {FIELDS => ['thetext'], TYPE => 'FULLTEXT'}, @@ -343,7 +357,7 @@ use constant ABSTRACT_SCHEMA => { keyworddefs => { FIELDS => [ - id => {TYPE => 'INT2', NOTNULL => 1, + id => {TYPE => 'SMALLSERIAL', NOTNULL => 1, PRIMARYKEY => 1}, name => {TYPE => 'varchar(64)', NOTNULL => 1}, description => {TYPE => 'MEDIUMTEXT'}, @@ -372,7 +386,7 @@ use constant ABSTRACT_SCHEMA => { # "flags" stores one record for each flag on each bug/attachment. flags => { FIELDS => [ - id => {TYPE => 'INT3', NOTNULL => 1, + id => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1}, type_id => {TYPE => 'INT2', NOTNULL => 1}, status => {TYPE => 'char(1)', NOTNULL => 1}, @@ -382,8 +396,6 @@ use constant ABSTRACT_SCHEMA => { modification_date => {TYPE => 'DATETIME'}, setter_id => {TYPE => 'INT3'}, requestee_id => {TYPE => 'INT3'}, - is_active => {TYPE => 'BOOLEAN', NOTNULL => 1, - DEFAULT => 'TRUE'}, ], INDEXES => [ flags_bug_id_idx => [qw(bug_id attach_id)], @@ -396,7 +408,7 @@ use constant ABSTRACT_SCHEMA => { # "flagtypes" defines the types of flags that can be set. flagtypes => { FIELDS => [ - id => {TYPE => 'INT2', NOTNULL => 1, + id => {TYPE => 'SMALLSERIAL', NOTNULL => 1, PRIMARYKEY => 1}, name => {TYPE => 'varchar(50)', NOTNULL => 1}, description => {TYPE => 'TEXT'}, @@ -450,15 +462,21 @@ use constant ABSTRACT_SCHEMA => { fielddefs => { FIELDS => [ - fieldid => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, + id => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1}, name => {TYPE => 'varchar(64)', NOTNULL => 1}, + type => {TYPE => 'INT2', NOTNULL => 1, + DEFAULT => FIELD_TYPE_UNKNOWN}, + custom => {TYPE => 'BOOLEAN', NOTNULL => 1, + DEFAULT => 'FALSE'}, description => {TYPE => 'MEDIUMTEXT', NOTNULL => 1}, mailhead => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}, sortkey => {TYPE => 'INT2', NOTNULL => 1}, obsolete => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}, + enter_bug => {TYPE => 'BOOLEAN', NOTNULL => 1, + DEFAULT => 'FALSE'}, ], INDEXES => [ fielddefs_name_idx => {FIELDS => ['name'], @@ -472,6 +490,8 @@ use constant ABSTRACT_SCHEMA => { versions => { FIELDS => [ + id => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, + PRIMARYKEY => 1}, value => {TYPE => 'varchar(64)', NOTNULL => 1}, product_id => {TYPE => 'INT2', NOTNULL => 1}, ], @@ -483,6 +503,8 @@ use constant ABSTRACT_SCHEMA => { milestones => { FIELDS => [ + id => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, + PRIMARYKEY => 1}, product_id => {TYPE => 'INT2', NOTNULL => 1}, value => {TYPE => 'varchar(20)', NOTNULL => 1}, sortkey => {TYPE => 'INT2', NOTNULL => 1, @@ -605,11 +627,14 @@ use constant ABSTRACT_SCHEMA => { PRIMARYKEY => 1}, login_name => {TYPE => 'varchar(255)', NOTNULL => 1}, cryptpassword => {TYPE => 'varchar(128)'}, - realname => {TYPE => 'varchar(255)'}, - disabledtext => {TYPE => 'MEDIUMTEXT', NOTNULL => 1}, + realname => {TYPE => 'varchar(255)', NOTNULL => 1, + DEFAULT => "''"}, + disabledtext => {TYPE => 'MEDIUMTEXT', NOTNULL => 1, + DEFAULT => "''"}, + disable_mail => {TYPE => 'BOOLEAN', NOTNULL => 1, + DEFAULT => 'FALSE'}, mybugslink => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'}, - refreshed_when => {TYPE => 'DATETIME', NOTNULL => 1}, extern_id => {TYPE => 'varchar(64)'}, ], INDEXES => [ @@ -661,9 +686,10 @@ use constant ABSTRACT_SCHEMA => { namedqueries => { FIELDS => [ + id => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, + PRIMARYKEY => 1}, userid => {TYPE => 'INT3', NOTNULL => 1}, name => {TYPE => 'varchar(64)', NOTNULL => 1}, - linkinfooter => {TYPE => 'BOOLEAN', NOTNULL => 1}, query => {TYPE => 'MEDIUMTEXT', NOTNULL => 1}, query_type => {TYPE => 'BOOLEAN', NOTNULL => 1}, ], @@ -673,6 +699,30 @@ use constant ABSTRACT_SCHEMA => { ], }, + namedqueries_link_in_footer => { + FIELDS => [ + namedquery_id => {TYPE => 'INT3', NOTNULL => 1}, + user_id => {TYPE => 'INT3', NOTNULL => 1}, + ], + INDEXES => [ + namedqueries_link_in_footer_id_idx => {FIELDS => [qw(namedquery_id user_id)], + TYPE => 'UNIQUE'}, + namedqueries_link_in_footer_userid_idx => ['user_id'], + ], + }, + + component_cc => { + + FIELDS => [ + user_id => {TYPE => 'INT3', NOTNULL => 1}, + component_id => {TYPE => 'INT2', NOTNULL => 1}, + ], + INDEXES => [ + component_cc_user_id_idx => {FIELDS => [qw(component_id user_id)], + TYPE => 'UNIQUE'}, + ], + }, + # Authentication # -------------- @@ -694,7 +744,7 @@ use constant ABSTRACT_SCHEMA => { # for these changes. tokens => { FIELDS => [ - userid => {TYPE => 'INT3', NOTNULL => 1} , + userid => {TYPE => 'INT3'}, issuedate => {TYPE => 'DATETIME', NOTNULL => 1} , token => {TYPE => 'varchar(16)', NOTNULL => 1, PRIMARYKEY => 1}, @@ -716,7 +766,6 @@ use constant ABSTRACT_SCHEMA => { name => {TYPE => 'varchar(255)', NOTNULL => 1}, description => {TYPE => 'TEXT', NOTNULL => 1}, isbuggroup => {TYPE => 'BOOLEAN', NOTNULL => 1}, - last_changed => {TYPE => 'DATETIME', NOTNULL => 1}, userregexp => {TYPE => 'TINYTEXT', NOTNULL => 1, DEFAULT => "''"}, isactive => {TYPE => 'BOOLEAN', NOTNULL => 1, @@ -735,6 +784,12 @@ use constant ABSTRACT_SCHEMA => { membercontrol => {TYPE => 'BOOLEAN', NOTNULL => 1}, othercontrol => {TYPE => 'BOOLEAN', NOTNULL => 1}, canedit => {TYPE => 'BOOLEAN', NOTNULL => 1}, + editcomponents => {TYPE => 'BOOLEAN', NOTNULL => 1, + DEFAULT => 'FALSE'}, + editbugs => {TYPE => 'BOOLEAN', NOTNULL => 1, + DEFAULT => 'FALSE'}, + canconfirm => {TYPE => 'BOOLEAN', NOTNULL => 1, + DEFAULT => 'FALSE'}, ], INDEXES => [ group_control_map_product_id_idx => @@ -757,7 +812,7 @@ use constant ABSTRACT_SCHEMA => { isbless => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}, grant_type => {TYPE => 'INT1', NOTNULL => 1, - DEFAULT => '0'}, + DEFAULT => GRANT_DIRECT}, ], INDEXES => [ user_group_map_user_id_idx => @@ -778,7 +833,7 @@ use constant ABSTRACT_SCHEMA => { member_id => {TYPE => 'INT3', NOTNULL => 1}, grantor_id => {TYPE => 'INT3', NOTNULL => 1}, grant_type => {TYPE => 'INT1', NOTNULL => 1, - DEFAULT => '0'}, + DEFAULT => GROUP_MEMBERSHIP}, ], INDEXES => [ group_group_map_member_id_idx => @@ -801,6 +856,20 @@ use constant ABSTRACT_SCHEMA => { ], }, + # This table determines which groups a user must be a member of + # in order to see a named query somebody else shares. + namedquery_group_map => { + FIELDS => [ + namedquery_id => {TYPE => 'INT3', NOTNULL => 1}, + group_id => {TYPE => 'INT3', NOTNULL => 1}, + ], + INDEXES => [ + namedquery_group_map_namedquery_id_idx => + {FIELDS => [qw(namedquery_id)], TYPE => 'UNIQUE'}, + namedquery_group_map_group_id_idx => ['group_id'], + ], + }, + category_group_map => { FIELDS => [ category_id => {TYPE => 'INT2', NOTNULL => 1}, @@ -822,6 +891,7 @@ use constant ABSTRACT_SCHEMA => { PRIMARYKEY => 1}, name => {TYPE => 'varchar(64)', NOTNULL => 1}, description => {TYPE => 'MEDIUMTEXT'}, + sortkey => {TYPE => 'INT2', NOTNULL => 1, DEFAULT => '0'}, ], INDEXES => [ classifications_name_idx => {FIELDS => ['name'], @@ -837,12 +907,16 @@ use constant ABSTRACT_SCHEMA => { classification_id => {TYPE => 'INT2', NOTNULL => 1, DEFAULT => '1'}, description => {TYPE => 'MEDIUMTEXT'}, - milestoneurl => {TYPE => 'TINYTEXT', NOTNULL => 1}, - disallownew => {TYPE => 'BOOLEAN', NOTNULL => 1}, - votesperuser => {TYPE => 'INT2', NOTNULL => 1}, + milestoneurl => {TYPE => 'TINYTEXT', NOTNULL => 1, + DEFAULT => "''"}, + disallownew => {TYPE => 'BOOLEAN', NOTNULL => 1, + DEFAULT => 0}, + votesperuser => {TYPE => 'INT2', NOTNULL => 1, + DEFAULT => 0}, maxvotesperbug => {TYPE => 'INT2', NOTNULL => 1, DEFAULT => '10000'}, - votestoconfirm => {TYPE => 'INT2', NOTNULL => 1}, + votestoconfirm => {TYPE => 'INT2', NOTNULL => 1, + DEFAULT => 0}, defaultmilestone => {TYPE => 'varchar(20)', NOTNULL => 1, DEFAULT => "'---'"}, ], @@ -876,7 +950,7 @@ use constant ABSTRACT_SCHEMA => { FIELDS => [ series_id => {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1}, - creator => {TYPE => 'INT3', NOTNULL => 1}, + creator => {TYPE => 'INT3'}, category => {TYPE => 'INT2', NOTNULL => 1}, subcategory => {TYPE => 'INT2', NOTNULL => 1}, name => {TYPE => 'varchar(64)', NOTNULL => 1}, @@ -1001,6 +1075,7 @@ use constant ABSTRACT_SCHEMA => { default_value => {TYPE => 'varchar(32)', NOTNULL => 1}, is_enabled => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'}, + subclass => {TYPE => 'varchar(32)'}, ], }, @@ -1041,6 +1116,23 @@ use constant ABSTRACT_SCHEMA => { }, }; + +use constant FIELD_TABLE_SCHEMA => { + FIELDS => [ + id => {TYPE => 'SMALLSERIAL', NOTNULL => 1, + PRIMARYKEY => 1}, + value => {TYPE => 'varchar(64)', NOTNULL => 1}, + sortkey => {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0}, + isactive => {TYPE => 'BOOLEAN', NOTNULL => 1, + DEFAULT => 'TRUE'}, + ], + # Note that bz_add_field_table should prepend the table name + # to these index names. + INDEXES => [ + value_idx => {FIELDS => ['value'], TYPE => 'UNIQUE'}, + sortkey_idx => ['sortkey', 'value'], + ], +}; #-------------------------------------------------------------------------- =head1 METHODS @@ -1121,6 +1213,15 @@ sub _initialize { $abstract_schema ||= ABSTRACT_SCHEMA; + # Let extensions add tables, but make sure they can't modify existing + # tables. If we don't lock/unlock keys, lock_value complains. + lock_keys(%$abstract_schema); + lock_value(%$abstract_schema, $_) foreach (keys %$abstract_schema); + unlock_keys(%$abstract_schema); + Bugzilla::Hook::process('db_schema-abstract_schema', + { schema => $abstract_schema }); + unlock_hash(%$abstract_schema); + $self->{schema} = dclone($abstract_schema); # While ABSTRACT_SCHEMA cannot be modified, # $self->{abstract_schema} can be. So, we dclone it to prevent @@ -1208,7 +1309,7 @@ sub get_type_ddl { } my $fkref = $self->{enable_references} ? $finfo->{REFERENCES} : undef; - my $type_ddl = $self->{db_specific}{$type} || $type; + my $type_ddl = $self->convert_type($type); # DEFAULT attribute must appear before any column constraints # (e.g., NOT NULL), for Oracle $type_ddl .= " DEFAULT $default" if (defined($default)); @@ -1219,7 +1320,19 @@ sub get_type_ddl { return($type_ddl); } #eosub--get_type_ddl -#-------------------------------------------------------------------------- + +sub convert_type { + +=item C<convert_type> + +Converts a TYPE from the L</ABSTRACT_SCHEMA> format into the real SQL type. + +=cut + + my ($self, $type) = @_; + return $self->{db_specific}->{$type} || $type; +} + sub get_column { =item C<get_column($table, $column)> @@ -1289,7 +1402,19 @@ sub get_table_columns { return @columns; } #eosub--get_table_columns -#-------------------------------------------------------------------------- + +sub get_table_indexes_abstract { + my ($self, $table) = @_; + my $table_def = $self->get_table_abstract($table); + my %indexes = @{$table_def->{INDEXES} || []}; + return \%indexes; +} + +sub get_create_database_sql { + my ($self, $name) = @_; + return ("CREATE DATABASE $name"); +} + sub get_table_ddl { =item C<get_table_ddl> @@ -1478,43 +1603,10 @@ sub get_alter_column_ddl { my $old_def = $self->get_column_abstract($table, $column); my $specific = $self->{db_specific}; - my $typechange = 0; # If the types have changed, we have to deal with that. if (uc(trim($old_def->{TYPE})) ne uc(trim($new_def->{TYPE}))) { - $typechange = 1; - my $type = $new_def->{TYPE}; - $type = $specific->{$type} if exists $specific->{$type}; - # Make sure we can CAST from the old type to the new without an error. - push(@statements, "SELECT CAST($column AS $type) FROM $table LIMIT 1"); - # Add a new temporary column of the new type - push(@statements, "ALTER TABLE $table ADD COLUMN ${column}_ALTERTEMP" - . " $type"); - # UPDATE the temp column to have the same values as the old column - push(@statements, "UPDATE $table SET ${column}_ALTERTEMP = " - . " CAST($column AS $type)"); - - # Some databases drop a whole index when a column is dropped, - # some only remove that column from an index. For consistency, - # we manually drop all indexes on the column before dropping the - # column. - my %col_idx = $self->get_indexes_on_column_abstract($table, $column); - foreach my $idx_name (keys %col_idx) { - push(@statements, $self->get_drop_index_ddl($table, $idx_name)); - } - - # DROP the old column - push(@statements, "ALTER TABLE $table DROP COLUMN $column"); - # And rename the temp column to be the new one. - push(@statements, "ALTER TABLE $table RENAME COLUMN " - . " ${column}_ALTERTEMP TO $column"); - - # And now, we have to regenerate any indexes that got - # dropped, except for the PK index which will be handled - # below. - foreach my $idx_name (keys %col_idx) { - push(@statements, - $self->get_add_index_ddl($table, $idx_name, $col_idx{$idx_name})); - } + push(@statements, $self->_get_alter_type_sql($table, $column, + $new_def, $old_def)); } my $default = $new_def->{DEFAULT}; @@ -1528,21 +1620,17 @@ sub get_alter_column_ddl { push(@statements, "ALTER TABLE $table ALTER COLUMN $column" . " DROP DEFAULT"); } - # If we went from no default to a default, or we changed the default, - # or we have a default and we changed the data type of the field + # If we went from no default to a default, or we changed the default. elsif ( (defined $default && !defined $default_old) || - ($default ne $default_old) || - ($typechange && defined $new_def->{DEFAULT}) ) { + ($default ne $default_old) ) + { $default = $specific->{$default} if exists $specific->{$default}; push(@statements, "ALTER TABLE $table ALTER COLUMN $column " . " SET DEFAULT $default"); } - # If we went from NULL to NOT NULL - # OR if we changed the type and we are NOT NULL - if ( (!$old_def->{NOTNULL} && $new_def->{NOTNULL}) || - ($typechange && $new_def->{NOTNULL}) ) - { + # If we went from NULL to NOT NULL. + if (!$old_def->{NOTNULL} && $new_def->{NOTNULL}) { my $setdefault; # Handle any fields that were NULL before, if we have a default, $setdefault = $new_def->{DEFAULT} if exists $new_def->{DEFAULT}; @@ -1563,10 +1651,8 @@ sub get_alter_column_ddl { . " DROP NOT NULL"); } - # If we went from not being a PRIMARY KEY to being a PRIMARY KEY, - # or if we changed types and we are a PK. - if ( (!$old_def->{PRIMARYKEY} && $new_def->{PRIMARYKEY}) || - ($typechange && $new_def->{PRIMARYKEY}) ) { + # If we went from not being a PRIMARY KEY to being a PRIMARY KEY. + if (!$old_def->{PRIMARYKEY} && $new_def->{PRIMARYKEY}) { push(@statements, "ALTER TABLE $table ADD PRIMARY KEY ($column)"); } # If we went from being a PK to not being a PK @@ -1642,6 +1728,37 @@ sub get_rename_column_ddl { . " has not implemented a method."; } + +sub get_rename_table_sql { + +=item C<get_rename_table_sql> + +=over + +=item B<Description> + +Gets SQL to rename a table in the database. + +=item B<Params> + +=over + +=item C<$old_name> - The current name of the table. + +=item C<$new_name> - The new name of the table. + +=back + +=item B<Returns>: An array of SQL statements to rename a table. + +=back + +=cut + + my ($self, $old_name, $new_name) = @_; + return ("ALTER TABLE $old_name RENAME TO $new_name"); +} + =item C<delete_table($name)> Description: Deletes a table from this Schema object. @@ -1793,6 +1910,23 @@ sub add_table { } } + + +sub rename_table { + +=item C<rename_table> + +Renames a table from C<$old_name> to C<$new_name> in this Schema object. + +=cut + + + my ($self, $old_name, $new_name) = @_; + my $table = $self->get_table_abstract($old_name); + $self->delete_table($old_name); + $self->add_table($new_name, $table); +} + sub delete_column { =item C<delete_column($table, $column)> @@ -2072,36 +2206,75 @@ __END__ =head1 ABSTRACT DATA TYPES -The following abstract data types are used: +The size and range data provided here is only +intended as a guide. See your database's Bugzilla +module (in this directory) for the most up-to-date +values for these data types. The following +abstract data types are used: =over 4 =item C<BOOLEAN> +Logical value 0 or 1 where 1 is true, 0 is false. + =item C<INT1> +Integer values (-128 - 127 or 0 - 255 unsigned). + =item C<INT2> +Integer values (-32,768 - 32767 or 0 - 65,535 unsigned). + =item C<INT3> +Integer values (-8,388,608 - 8,388,607 or 0 - 16,777,215 unsigned) + =item C<INT4> +Integer values (-2,147,483,648 - 2,147,483,647 or 0 - 4,294,967,295 +unsigned) + =item C<SMALLSERIAL> +An auto-increment L</INT1> + =item C<MEDIUMSERIAL> +An auto-increment L</INT3> + =item C<INTSERIAL> +An auto-increment L</INT4> + =item C<TINYTEXT> +Variable length string of characters up to 255 (2^8 - 1) characters wide +or more depending on the character set used. + =item C<MEDIUMTEXT> +Variable length string of characters up to 16M (2^24 - 1) characters wide +or more depending on the character set used. + =item C<TEXT> +Variable length string of characters up to 64K (2^16 - 1) characters wide +or more depending on the character set used. + =item C<LONGBLOB> +Variable length string of binary data up to 4M (2^32 - 1) bytes wide + =item C<DATETIME> +DATETIME support varies from database to database, however, it's generally +safe to say that DATETIME entries support all date/time combinations greater +than 1900-01-01 00:00:00. Note that the format used is C<YYYY-MM-DD hh:mm:ss> +to be safe, though it's possible that your database may not require +leading zeros. For greatest compatibility, however, please make sure dates +are formatted as above for queries to guarantee consistent results. + =back Database-specific subclasses should define the implementation for these data @@ -2123,4 +2296,6 @@ database-specific basis: L<Bugzilla::DB> +L<http://www.bugzilla.org/docs/developer.html#sql-schema> + =cut diff --git a/Bugzilla/DB/Schema/CVS/Entries b/Bugzilla/DB/Schema/CVS/Entries index bb4acfd66..bb5468649 100644 --- a/Bugzilla/DB/Schema/CVS/Entries +++ b/Bugzilla/DB/Schema/CVS/Entries @@ -1,3 +1,3 @@ -/Mysql.pm/1.12.2.1/Mon Jun 19 14:57:14 2006//TBUGZILLA-2_22_3 -/Pg.pm/1.9/Wed Jun 15 03:54:59 2005//TBUGZILLA-2_22_3 +/Mysql.pm/1.14/Sat Nov 18 15:10:11 2006//TBUGZILLA-3_0 +/Pg.pm/1.13.2.1/Sun Apr 15 01:34:58 2007//TBUGZILLA-3_0 D diff --git a/Bugzilla/DB/Schema/CVS/Tag b/Bugzilla/DB/Schema/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/Bugzilla/DB/Schema/CVS/Tag +++ b/Bugzilla/DB/Schema/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/Bugzilla/DB/Schema/Mysql.pm b/Bugzilla/DB/Schema/Mysql.pm index 0069dcc7f..d7cd708a2 100644 --- a/Bugzilla/DB/Schema/Mysql.pm +++ b/Bugzilla/DB/Schema/Mysql.pm @@ -129,7 +129,9 @@ sub _get_create_table_ddl { my($self, $table) = @_; - return($self->SUPER::_get_create_table_ddl($table) . ' TYPE = MYISAM'); + my $charset = Bugzilla->dbh->bz_db_is_utf8 ? "CHARACTER SET utf8" : ''; + return($self->SUPER::_get_create_table_ddl($table) + . " ENGINE = MYISAM $charset"); } #eosub--_get_create_table_ddl #------------------------------------------------------------------------------ @@ -150,6 +152,16 @@ sub _get_create_index_ddl { } #eosub--_get_create_index_ddl #-------------------------------------------------------------------- +sub get_create_database_sql { + my ($self, $name) = @_; + # We only create as utf8 if we have no params (meaning we're doing + # a new installation) or if the utf8 param is on. + my $create_utf8 = Bugzilla->params->{'utf8'} + || !defined Bugzilla->params->{'utf8'}; + my $charset = $create_utf8 ? "CHARACTER SET utf8" : ''; + return ("CREATE DATABASE $name $charset"); +} + # MySQL has a simpler ALTER TABLE syntax than ANSI. sub get_alter_column_ddl { my ($self, $table, $column, $new_def, $set_nulls_to) = @_; diff --git a/Bugzilla/DB/Schema/Pg.pm b/Bugzilla/DB/Schema/Pg.pm index 09636186d..7a951e2db 100644 --- a/Bugzilla/DB/Schema/Pg.pm +++ b/Bugzilla/DB/Schema/Pg.pm @@ -30,8 +30,8 @@ package Bugzilla::DB::Schema::Pg; ############################################################################### use strict; - use base qw(Bugzilla::DB::Schema); +use Storable qw(dclone); #------------------------------------------------------------------------------ sub _initialize { @@ -90,54 +90,77 @@ sub _initialize { } #eosub--_initialize #-------------------------------------------------------------------- -# Overridden because Pg has such weird ALTER TABLE problems. -sub get_add_column_ddl { - my ($self, $table, $column, $definition, $init_value) = @_; +sub get_rename_column_ddl { + my ($self, $table, $old_name, $new_name) = @_; + if (lc($old_name) eq lc($new_name)) { + # if the only change is a case change, return an empty list, since Pg + # is case-insensitive and will return an error about a duplicate name + return (); + } + my @sql = ("ALTER TABLE $table RENAME COLUMN $old_name TO $new_name"); + my $def = $self->get_column_abstract($table, $old_name); + if ($def->{TYPE} =~ /SERIAL/i) { + # We have to rename the series also, and fix the default of the series. + push(@sql, "ALTER TABLE ${table}_${old_name}_seq + RENAME TO ${table}_${new_name}_seq"); + push(@sql, "ALTER TABLE $table ALTER COLUMN $new_name + SET DEFAULT NEXTVAL('${table}_${new_name}_seq')"); + } + return @sql; +} - my @statements; - my $specific = $self->{db_specific}; - - my $type = $definition->{TYPE}; - $type = $specific->{$type} if exists $specific->{$type}; - push(@statements, "ALTER TABLE $table ADD COLUMN $column $type"); - - my $default = $definition->{DEFAULT}; - if (defined $default) { - # Replace any abstract default value (such as 'TRUE' or 'FALSE') - # with its database-specific implementation. - $default = $specific->{$default} if exists $specific->{$default}; - push(@statements, "ALTER TABLE $table ALTER COLUMN $column " - . " SET DEFAULT $default"); +sub get_rename_table_sql { + my ($self, $old_name, $new_name) = @_; + if (lc($old_name) eq lc($new_name)) { + # if the only change is a case change, return an empty list, since Pg + # is case-insensitive and will return an error about a duplicate name + return (); } + return ("ALTER TABLE $old_name RENAME TO $new_name"); +} + +sub _get_alter_type_sql { + my ($self, $table, $column, $new_def, $old_def) = @_; + my @statements; + + my $type = $new_def->{TYPE}; + $type = $self->{db_specific}->{$type} + if exists $self->{db_specific}->{$type}; - if (defined $init_value) { - push(@statements, "UPDATE $table SET $column = $init_value"); + if ($type =~ /serial/i && $old_def->{TYPE} !~ /serial/i) { + die("You cannot specify a DEFAULT on a SERIAL-type column.") + if $new_def->{DEFAULT}; + $type =~ s/serial/integer/i; } - if ($definition->{NOTNULL}) { - # Handle rows that were NULL when we added the column. - # We *must* have a DEFAULT. This check is usually handled - # at a higher level than this code, but I figure it can't - # hurt to have it here. - die "NOT NULL columns must have a DEFAULT or an init_value." - unless (exists $definition->{DEFAULT} || defined $init_value); - push(@statements, "UPDATE $table SET $column = $default"); - push(@statements, "ALTER TABLE $table ALTER COLUMN $column " - . " SET NOT NULL"); + # On Pg, you don't need UNIQUE if you're a PK--it creates + # two identical indexes otherwise. + $type =~ s/unique//i if $new_def->{PRIMARYKEY}; + + push(@statements, "ALTER TABLE $table ALTER COLUMN $column + TYPE $type"); + + if ($new_def->{TYPE} =~ /serial/i && $old_def->{TYPE} !~ /serial/i) { + push(@statements, "CREATE SEQUENCE ${table}_${column}_seq"); + push(@statements, "SELECT setval('${table}_${column}_seq', + MAX($table.$column)) + FROM $table"); + push(@statements, "ALTER TABLE $table ALTER COLUMN $column + SET DEFAULT nextval('${table}_${column}_seq')"); } - if ($definition->{PRIMARYKEY}) { - push(@statements, "ALTER TABLE $table ALTER COLUMN " - . " ADD PRIMARY KEY ($column)"); + # If this column is no longer SERIAL, we need to drop the sequence + # that went along with it. + if ($old_def->{TYPE} =~ /serial/i && $new_def->{TYPE} !~ /serial/i) { + push(@statements, "ALTER TABLE $table ALTER COLUMN $column + DROP DEFAULT"); + # XXX Pg actually won't let us drop the sequence, even though it's + # no longer in use. So we harmlessly leave behind a sequence + # that does nothing. + #push(@statements, "DROP SEQUENCE ${table}_${column}_seq"); } return @statements; } -sub get_rename_column_ddl { - my ($self, $table, $old_name, $new_name) = @_; - - return ("ALTER TABLE $table RENAME COLUMN $old_name TO $new_name"); -} - 1; diff --git a/Bugzilla/Error.pm b/Bugzilla/Error.pm index 32ef465ce..95088850e 100644 --- a/Bugzilla/Error.pm +++ b/Bugzilla/Error.pm @@ -18,6 +18,7 @@ # Rights Reserved. # # Contributor(s): Bradley Baetz <bbaetz@acm.org> +# Marc Schumann <wurblzap@gmail.com> package Bugzilla::Error; @@ -26,8 +27,8 @@ use base qw(Exporter); @Bugzilla::Error::EXPORT = qw(ThrowCodeError ThrowTemplateError ThrowUserError); -use Bugzilla::Config qw($datadir); use Bugzilla::Constants; +use Bugzilla::WebService::Constants; use Bugzilla::Util; use Date::Format; @@ -42,6 +43,7 @@ sub _throw_error { # and the transaction is rolled back (if supported) Bugzilla->dbh->bz_unlock_tables(UNLOCK_ABORT); + my $datadir = bz_locations()->{'datadir'}; # If a writable $datadir/errorlog exists, log error details there. if (-w "$datadir/errorlog") { require Data::Dumper; @@ -74,16 +76,27 @@ sub _throw_error { } my $template = Bugzilla->template; - if (Bugzilla->batch) { - my $message; - $template->process($name, $vars, \$message) - || ThrowTemplateError($template->error()); - die("$message"); - } else { + if (Bugzilla->error_mode == ERROR_MODE_WEBPAGE) { print Bugzilla->cgi->header(); $template->process($name, $vars) || ThrowTemplateError($template->error()); } + else { + my $message; + $template->process($name, $vars, \$message) + || ThrowTemplateError($template->error()); + if (Bugzilla->error_mode == ERROR_MODE_DIE) { + die("$message\n"); + } + elsif (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT) { + my $code = WS_ERROR_CODE->{$error}; + if (!$code) { + $code = ERROR_UNKNOWN_FATAL if $name =~ /code/i; + $code = ERROR_UNKNOWN_TRANSIENT if $name =~ /user/i; + } + die SOAP::Fault->faultcode($code)->faultstring($message); + } + } exit; } @@ -103,7 +116,7 @@ sub ThrowTemplateError { Bugzilla->dbh->bz_unlock_tables(UNLOCK_ABORT); my $vars = {}; - if (Bugzilla->batch) { + if (Bugzilla->error_mode == ERROR_MODE_DIE) { die("error: template error: $template_err"); } @@ -115,9 +128,9 @@ sub ThrowTemplateError { # Try a template first; but if this one fails too, fall back # on plain old print statements. if (!$template->process("global/code-error.html.tmpl", $vars)) { - my $maintainer = Bugzilla::Config::Param('maintainer'); - my $error = Bugzilla::Util::html_quote($vars->{'template_error_msg'}); - my $error2 = Bugzilla::Util::html_quote($template->error()); + my $maintainer = Bugzilla->params->{'maintainer'}; + my $error = html_quote($vars->{'template_error_msg'}); + my $error2 = html_quote($template->error()); print <<END; <tt> <p> @@ -160,7 +173,7 @@ Bugzilla::Error - Error handling utilities for Bugzilla Various places throughout the Bugzilla codebase need to report errors to the user. The C<Throw*Error> family of functions allow this to be done in a -generic and localizable manner. +generic and localisable manner. These functions automatically unlock the database tables, if there were any locked. They will also roll back the transaction, if it is supported by diff --git a/Bugzilla/Field.pm b/Bugzilla/Field.pm index 09c4731ac..9177ae423 100644 --- a/Bugzilla/Field.pm +++ b/Bugzilla/Field.pm @@ -13,119 +13,777 @@ # The Original Code is the Bugzilla Bug Tracking System. # # Contributor(s): Dan Mosedale <dmose@mozilla.org> -# Fr�d�ric Buclin <LpSolit@gmail.com> +# Frédéric Buclin <LpSolit@gmail.com> +# Myk Melez <myk@mozilla.org> + +=head1 NAME + +Bugzilla::Field - a particular piece of information about bugs + and useful routines for form field manipulation + +=head1 SYNOPSIS + + use Bugzilla; + use Data::Dumper; + + # Display information about all fields. + print Dumper(Bugzilla->get_fields()); + + # Display information about non-obsolete custom fields. + print Dumper(Bugzilla->get_fields({ obsolete => 1, custom => 1 })); + + # Display a list of the names of non-obsolete custom fields. + print Bugzilla->custom_field_names; + + use Bugzilla::Field; + + # Display information about non-obsolete custom fields. + # Bugzilla->get_fields() is a wrapper around Bugzilla::Field->match(), + # so both methods take the same arguments. + print Dumper(Bugzilla::Field->match({ obsolete => 1, custom => 1 })); + + # Create or update a custom field or field definition. + my $field = Bugzilla::Field->create( + {name => 'cf_silly', description => 'Silly', custom => 1}); + + # Instantiate a Field object for an existing field. + my $field = new Bugzilla::Field({name => 'qacontact_accessible'}); + if ($field->obsolete) { + print $field->description . " is obsolete\n"; + } + + # Validation Routines + check_field($name, $value, \@legal_values, $no_warn); + $fieldid = get_field_id($fieldname); + +=head1 DESCRIPTION + +Field.pm defines field objects, which represent the particular pieces +of information that Bugzilla stores about bugs. + +This package also provides functions for dealing with CGI form fields. + +C<Bugzilla::Field> is an implementation of L<Bugzilla::Object>, and +so provides all of the methods available in L<Bugzilla::Object>, +in addition to what is documented here. + +=cut package Bugzilla::Field; use strict; -use base qw(Exporter); -@Bugzilla::Field::EXPORT = qw(check_form_field check_form_field_defined - get_field_id); +use base qw(Exporter Bugzilla::Object); +@Bugzilla::Field::EXPORT = qw(check_field get_field_id get_legal_field_values); use Bugzilla::Util; +use Bugzilla::Constants; use Bugzilla::Error; +############################### +#### Initialization #### +############################### + +use constant DB_TABLE => 'fielddefs'; +use constant LIST_ORDER => 'sortkey, name'; + +use constant DB_COLUMNS => ( + 'id', + 'name', + 'description', + 'type', + 'custom', + 'mailhead', + 'sortkey', + 'obsolete', + 'enter_bug', +); + +use constant REQUIRED_CREATE_FIELDS => qw(name description); + +use constant VALIDATORS => { + custom => \&_check_custom, + description => \&_check_description, + enter_bug => \&_check_enter_bug, + mailhead => \&_check_mailhead, + obsolete => \&_check_obsolete, + sortkey => \&_check_sortkey, + type => \&_check_type, +}; + +use constant UPDATE_COLUMNS => qw( + description + mailhead + sortkey + obsolete + enter_bug +); + +# How various field types translate into SQL data definitions. +use constant SQL_DEFINITIONS => { + # Using commas because these are constants and they shouldn't + # be auto-quoted by the "=>" operator. + FIELD_TYPE_FREETEXT, { TYPE => 'varchar(255)' }, + FIELD_TYPE_SINGLE_SELECT, { TYPE => 'varchar(64)', NOTNULL => 1, + DEFAULT => "'---'" }, +}; + +# Field definitions for the fields that ship with Bugzilla. +# These are used by populate_field_definitions to populate +# the fielddefs table. +use constant DEFAULT_FIELDS => ( + {name => 'bug_id', desc => 'Bug #', in_new_bugmail => 1}, + {name => 'short_desc', desc => 'Summary', in_new_bugmail => 1}, + {name => 'classification', desc => 'Classification', in_new_bugmail => 1}, + {name => 'product', desc => 'Product', in_new_bugmail => 1}, + {name => 'version', desc => 'Version', in_new_bugmail => 1}, + {name => 'rep_platform', desc => 'Platform', in_new_bugmail => 1}, + {name => 'bug_file_loc', desc => 'URL', in_new_bugmail => 1}, + {name => 'op_sys', desc => 'OS/Version', in_new_bugmail => 1}, + {name => 'bug_status', desc => 'Status', in_new_bugmail => 1}, + {name => 'status_whiteboard', desc => 'Status Whiteboard', + in_new_bugmail => 1}, + {name => 'keywords', desc => 'Keywords', in_new_bugmail => 1}, + {name => 'resolution', desc => 'Resolution'}, + {name => 'bug_severity', desc => 'Severity', in_new_bugmail => 1}, + {name => 'priority', desc => 'Priority', in_new_bugmail => 1}, + {name => 'component', desc => 'Component', in_new_bugmail => 1}, + {name => 'assigned_to', desc => 'AssignedTo', in_new_bugmail => 1}, + {name => 'reporter', desc => 'ReportedBy', in_new_bugmail => 1}, + {name => 'votes', desc => 'Votes'}, + {name => 'qa_contact', desc => 'QAContact', in_new_bugmail => 1}, + {name => 'cc', desc => 'CC', in_new_bugmail => 1}, + {name => 'dependson', desc => 'Depends on', in_new_bugmail => 1}, + {name => 'blocked', desc => 'Blocks', in_new_bugmail => 1}, + + {name => 'attachments.description', desc => 'Attachment description'}, + {name => 'attachments.filename', desc => 'Attachment filename'}, + {name => 'attachments.mimetype', desc => 'Attachment mime type'}, + {name => 'attachments.ispatch', desc => 'Attachment is patch'}, + {name => 'attachments.isobsolete', desc => 'Attachment is obsolete'}, + {name => 'attachments.isprivate', desc => 'Attachment is private'}, + {name => 'attachments.submitter', desc => 'Attachment creator'}, + + {name => 'target_milestone', desc => 'Target Milestone'}, + {name => 'creation_ts', desc => 'Creation date', in_new_bugmail => 1}, + {name => 'delta_ts', desc => 'Last changed date', in_new_bugmail => 1}, + {name => 'longdesc', desc => 'Comment'}, + {name => 'longdescs.isprivate', desc => 'Comment is private'}, + {name => 'alias', desc => 'Alias'}, + {name => 'everconfirmed', desc => 'Ever Confirmed'}, + {name => 'reporter_accessible', desc => 'Reporter Accessible'}, + {name => 'cclist_accessible', desc => 'CC Accessible'}, + {name => 'bug_group', desc => 'Group'}, + {name => 'estimated_time', desc => 'Estimated Hours', in_new_bugmail => 1}, + {name => 'remaining_time', desc => 'Remaining Hours'}, + {name => 'deadline', desc => 'Deadline', in_new_bugmail => 1}, + {name => 'commenter', desc => 'Commenter'}, + {name => 'flagtypes.name', desc => 'Flag'}, + {name => 'requestees.login_name', desc => 'Flag Requestee'}, + {name => 'setters.login_name', desc => 'Flag Setter'}, + {name => 'work_time', desc => 'Hours Worked'}, + {name => 'percentage_complete', desc => 'Percentage Complete'}, + {name => 'content', desc => 'Content'}, + {name => 'attach_data.thedata', desc => 'Attachment data'}, + {name => 'attachments.isurl', desc => 'Attachment is a URL'}, + {name => "owner_idle_time", desc => "Time Since Assignee Touched"}, +); + +############## +# Validators # +############## + +sub _check_custom { return $_[1] ? 1 : 0; } + +sub _check_description { + my ($invocant, $desc) = @_; + $desc = clean_text($desc); + $desc || ThrowUserError('field_missing_description'); + return $desc; +} -sub check_form_field { - my ($cgi, $fieldname, $legalsRef) = @_; - my $dbh = Bugzilla->dbh; +sub _check_enter_bug { return $_[1] ? 1 : 0; } + +sub _check_mailhead { return $_[1] ? 1 : 0; } + +sub _check_name { + my ($invocant, $name, $is_custom) = @_; + $name = lc(clean_text($name)); + $name || ThrowUserError('field_missing_name'); + + # Don't want to allow a name that might mess up SQL. + my $name_regex = qr/^[\w\.]+$/; + # Custom fields have more restrictive name requirements than + # standard fields. + $name_regex = qr/^\w+$/ if $is_custom; + # Custom fields can't be named just "cf_", and there is no normal + # field named just "cf_". + ($name =~ $name_regex && $name ne "cf_") + || ThrowUserError('field_invalid_name', { name => $name }); + + # If it's custom, prepend cf_ to the custom field name to distinguish + # it from standard fields. + if ($name !~ /^cf_/ && $is_custom) { + $name = 'cf_' . $name; + } - if (!defined $cgi->param($fieldname) - || trim($cgi->param($fieldname)) eq "" - || (defined($legalsRef) - && lsearch($legalsRef, $cgi->param($fieldname)) < 0)) - { - trick_taint($fieldname); - my ($result) = $dbh->selectrow_array("SELECT description FROM fielddefs - WHERE name = ?", undef, $fieldname); - - my $field = $result || $fieldname; - ThrowCodeError("illegal_field", { field => $field }); + # Assure the name is unique. Names can't be changed, so we don't have + # to worry about what to do on updates. + my $field = new Bugzilla::Field({ name => $name }); + ThrowUserError('field_already_exists', {'field' => $field }) if $field; + + return $name; +} + +sub _check_obsolete { return $_[1] ? 1 : 0; } + +sub _check_sortkey { + my ($invocant, $sortkey) = @_; + my $skey = $sortkey; + if (!defined $skey || $skey eq '') { + ($sortkey) = Bugzilla->dbh->selectrow_array( + 'SELECT MAX(sortkey) + 100 FROM fielddefs') || 100; } + detaint_natural($sortkey) + || ThrowUserError('field_invalid_sortkey', { sortkey => $skey }); + return $sortkey; } -sub check_form_field_defined { - my ($cgi, $fieldname) = @_; +sub _check_type { + my ($invocant, $type) = @_; + my $saved_type = $type; + # FIELD_TYPE_SINGLE_SELECT here should be updated every time a new, + # higher field type is added. + (detaint_natural($type) && $type <= FIELD_TYPE_SINGLE_SELECT) + || ThrowCodeError('invalid_customfield_type', { type => $saved_type }); + return $type; +} + +=pod + +=head2 Instance Properties + +=over + +=item C<name> + +the name of the field in the database; begins with "cf_" if field +is a custom field, but test the value of the boolean "custom" property +to determine if a given field is a custom field; + +=item C<description> + +a short string describing the field; displayed to Bugzilla users +in several places within Bugzilla's UI, f.e. as the form field label +on the "show bug" page; + +=back + +=cut + +sub description { return $_[0]->{description} } + +=over + +=item C<type> + +an integer specifying the kind of field this is; values correspond to +the FIELD_TYPE_* constants in Constants.pm + +=back + +=cut + +sub type { return $_[0]->{type} } + +=over + +=item C<custom> + +a boolean specifying whether or not the field is a custom field; +if true, field name should start "cf_", but use this property to determine +which fields are custom fields; + +=back + +=cut + +sub custom { return $_[0]->{custom} } + +=over + +=item C<in_new_bugmail> + +a boolean specifying whether or not the field is displayed in bugmail +for newly-created bugs; + +=back + +=cut + +sub in_new_bugmail { return $_[0]->{mailhead} } + +=over + +=item C<sortkey> + +an integer specifying the sortkey of the field. + +=back + +=cut + +sub sortkey { return $_[0]->{sortkey} } + +=over + +=item C<obsolete> + +a boolean specifying whether or not the field is obsolete; + +=back + +=cut + +sub obsolete { return $_[0]->{obsolete} } + +=over + +=item C<enter_bug> + +A boolean specifying whether or not this field should appear on +enter_bug.cgi + +=back + +=cut + +sub enter_bug { return $_[0]->{enter_bug} } - if (!defined $cgi->param($fieldname)) { - ThrowCodeError("undefined_field", { field => $fieldname }); +=over + +=item C<legal_values> + +A reference to an array with valid active values for this field. + +=back + +=cut + +sub legal_values { + my $self = shift; + + if (!defined $self->{'legal_values'}) { + $self->{'legal_values'} = get_legal_field_values($self->name); } + return $self->{'legal_values'}; } -sub get_field_id { - my ($name) = @_; +=pod + +=head2 Instance Mutators + +These set the particular field that they are named after. + +They take a single value--the new value for that field. + +They will throw an error if you try to set the values to something invalid. + +=over + +=item C<set_description> + +=item C<set_enter_bug> + +=item C<set_obsolete> + +=item C<set_sortkey> + +=item C<set_in_new_bugmail> + +=back + +=cut + +sub set_description { $_[0]->set('description', $_[1]); } +sub set_enter_bug { $_[0]->set('enter_bug', $_[1]); } +sub set_obsolete { $_[0]->set('obsolete', $_[1]); } +sub set_sortkey { $_[0]->set('sortkey', $_[1]); } +sub set_in_new_bugmail { $_[0]->set('mailhead', $_[1]); } + +=pod + +=head2 Class Methods + +=over + +=item C<create> + +Just like L<Bugzilla::Object/create>. Takes the following parameters: + +=over + +=item C<name> B<Required> - The name of the field. + +=item C<description> B<Required> - The field label to display in the UI. + +=item C<mailhead> - boolean - Whether this field appears at the +top of the bugmail for a newly-filed bug. Defaults to 0. + +=item C<custom> - boolean - True if this is a Custom Field. The field +will be added to the C<bugs> table if it does not exist. Defaults to 0. + +=item C<sortkey> - integer - The sortkey of the field. Defaults to 0. + +=item C<enter_bug> - boolean - Whether this field is +editable on the bug creation form. Defaults to 0. + +C<obsolete> - boolean - Whether this field is obsolete. Defaults to 0. + +=back + +=back + +=cut + +sub create { + my $class = shift; + my $field = $class->SUPER::create(@_); + my $dbh = Bugzilla->dbh; + if ($field->custom) { + my $name = $field->name; + my $type = $field->type; + # Create the database column that stores the data for this field. + $dbh->bz_add_column('bugs', $name, SQL_DEFINITIONS->{$type}); + + if ($type == FIELD_TYPE_SINGLE_SELECT) { + # Create the table that holds the legal values for this field. + $dbh->bz_add_field_table($name); + # And insert a default value of "---" into it. + $dbh->do("INSERT INTO $name (value) VALUES ('---')"); + } + } - trick_taint($name); - my $id = $dbh->selectrow_array('SELECT fieldid FROM fielddefs - WHERE name = ?', undef, $name); + return $field; +} - ThrowCodeError('invalid_field_name', {field => $name}) unless $id; - return $id +sub run_create_validators { + my $class = shift; + my $dbh = Bugzilla->dbh; + my $params = $class->SUPER::run_create_validators(@_); + + $params->{name} = $class->_check_name($params->{name}, $params->{custom}); + if (!exists $params->{sortkey}) { + $params->{sortkey} = $dbh->selectrow_array( + "SELECT MAX(sortkey) + 100 FROM fielddefs") || 100; + } + + return $params; } -1; -__END__ +=pod -=head1 NAME +=over -Bugzilla::Field - Useful routines for fields manipulation +=item C<match> -=head1 SYNOPSIS +=over - use Bugzilla::Field; +=item B<Description> - # Validation Routines - check_form_field($cgi, $fieldname, \@legal_values); - check_form_field_defined($cgi, $fieldname); - $fieldid = get_field_id($fieldname); +Returns a list of fields that match the specified criteria. -=head1 DESCRIPTION +You should be using L<Bugzilla/get_fields> and +L<Bugzilla/get_custom_field_names> instead of this function. + +=item B<Params> + +Takes named parameters in a hashref: + +=over + +=item C<name> - The name of the field. + +=item C<custom> - Boolean. True to only return custom fields. False +to only return non-custom fields. + +=item C<obsolete> - Boolean. True to only return obsolete fields. +False to not return obsolete fields. + +=item C<type> - The type of the field. A C<FIELD_TYPE> constant from +L<Bugzilla::Constants>. + +=item C<enter_bug> - Boolean. True to only return fields that appear +on F<enter_bug.cgi>. False to only return fields that I<don't> appear +on F<enter_bug.cgi>. + +=back + +=item B<Returns> + +A reference to an array of C<Bugzilla::Field> objects. + +=back + +=back + +=cut + +sub match { + my ($class, $criteria) = @_; + + my @terms; + if (defined $criteria->{name}) { + push(@terms, "name=" . Bugzilla->dbh->quote($criteria->{name})); + } + if (defined $criteria->{custom}) { + push(@terms, "custom=" . ($criteria->{custom} ? "1" : "0")); + } + if (defined $criteria->{obsolete}) { + push(@terms, "obsolete=" . ($criteria->{obsolete} ? "1" : "0")); + } + if (defined $criteria->{enter_bug}) { + push(@terms, "enter_bug=" . ($criteria->{enter_bug} ? '1' : '0')); + } + if (defined $criteria->{type}) { + push(@terms, "type = " . $criteria->{type}); + } + my $where = (scalar(@terms) > 0) ? "WHERE " . join(" AND ", @terms) : ""; -This package provides functions for dealing with CGI form fields. + my $ids = Bugzilla->dbh->selectcol_arrayref( + "SELECT id FROM fielddefs $where", {Slice => {}}); -=head1 FUNCTIONS + return $class->new_from_list($ids); +} + +=pod + +=over + +=item C<get_legal_field_values($field)> + +Description: returns all the legal values for a field that has a + list of legal values, like rep_platform or resolution. + The table where these values are stored must at least have + the following columns: value, isactive, sortkey. + +Params: C<$field> - Name of the table where valid values are. + +Returns: a reference to a list of valid values. -This package provides several types of routines: +=back + +=cut -=head2 Validation +sub get_legal_field_values { + my ($field) = @_; + my $dbh = Bugzilla->dbh; + my $result_ref = $dbh->selectcol_arrayref( + "SELECT value FROM $field + WHERE isactive = ? + ORDER BY sortkey, value", undef, (1)); + return $result_ref; +} =over -=item C<check_form_field($cgi, $fieldname, \@legal_values)> +=item C<populate_field_definitions()> -Description: Makes sure the field $fieldname is defined and its value - is non empty. If @legal_values is defined, this routine - also checks whether its value is one of the legal values - associated with this field. If the test fails, an error - is thrown. +Description: Populates the fielddefs table during an installation + or upgrade. -Params: $cgi - a CGI object - $fieldname - the field name to check - @legal_values - (optional) ref to a list of legal values +Params: none Returns: nothing -=item C<check_form_field_defined($cgi, $fieldname)> +=back -Description: Makes sure the field $fieldname is defined and its value - is non empty. Else an error is thrown. +=cut + +sub populate_field_definitions { + my $dbh = Bugzilla->dbh; + + # ADD and UPDATE field definitions + foreach my $def (DEFAULT_FIELDS) { + my $field = new Bugzilla::Field({ name => $def->{name} }); + if ($field) { + $field->set_description($def->{desc}); + $field->set_in_new_bugmail($def->{in_new_bugmail}); + $field->update(); + } + else { + if (exists $def->{in_new_bugmail}) { + $def->{mailhead} = $def->{in_new_bugmail}; + delete $def->{in_new_bugmail}; + } + $def->{description} = $def->{desc}; + delete $def->{desc}; + Bugzilla::Field->create($def); + } + } + + # DELETE fields which were added only accidentally, or which + # were never tracked in bugs_activity. Note that you can never + # delete fields which are used by bugs_activity. + + # Oops. Bug 163299 + $dbh->do("DELETE FROM fielddefs WHERE name='cc_accessible'"); + # Oops. Bug 215319 + $dbh->do("DELETE FROM fielddefs WHERE name='requesters.login_name'"); + # This field was never tracked in bugs_activity, so it's safe to delete. + $dbh->do("DELETE FROM fielddefs WHERE name='attachments.thedata'"); + + # MODIFY old field definitions + + # 2005-11-13 LpSolit@gmail.com - Bug 302599 + # One of the field names was a fragment of SQL code, which is DB dependent. + # We have to rename it to a real name, which is DB independent. + my $new_field_name = 'days_elapsed'; + my $field_description = 'Days since bug changed'; + + my ($old_field_id, $old_field_name) = + $dbh->selectrow_array('SELECT id, name FROM fielddefs + WHERE description = ?', + undef, $field_description); + + if ($old_field_id && ($old_field_name ne $new_field_name)) { + print "SQL fragment found in the 'fielddefs' table...\n"; + print "Old field name: " . $old_field_name . "\n"; + # We have to fix saved searches first. Queries have been escaped + # before being saved. We have to do the same here to find them. + $old_field_name = url_quote($old_field_name); + my $broken_named_queries = + $dbh->selectall_arrayref('SELECT userid, name, query + FROM namedqueries WHERE ' . + $dbh->sql_istrcmp('query', '?', 'LIKE'), + undef, "%=$old_field_name%"); + + my $sth_UpdateQueries = $dbh->prepare('UPDATE namedqueries SET query = ? + WHERE userid = ? AND name = ?'); + + print "Fixing saved searches...\n" if scalar(@$broken_named_queries); + foreach my $named_query (@$broken_named_queries) { + my ($userid, $name, $query) = @$named_query; + $query =~ s/=\Q$old_field_name\E(&|$)/=$new_field_name$1/gi; + $sth_UpdateQueries->execute($query, $userid, $name); + } + + # We now do the same with saved chart series. + my $broken_series = + $dbh->selectall_arrayref('SELECT series_id, query + FROM series WHERE ' . + $dbh->sql_istrcmp('query', '?', 'LIKE'), + undef, "%=$old_field_name%"); + + my $sth_UpdateSeries = $dbh->prepare('UPDATE series SET query = ? + WHERE series_id = ?'); + + print "Fixing saved chart series...\n" if scalar(@$broken_series); + foreach my $series (@$broken_series) { + my ($series_id, $query) = @$series; + $query =~ s/=\Q$old_field_name\E(&|$)/=$new_field_name$1/gi; + $sth_UpdateSeries->execute($query, $series_id); + } + # Now that saved searches have been fixed, we can fix the field name. + print "Fixing the 'fielddefs' table...\n"; + print "New field name: " . $new_field_name . "\n"; + $dbh->do('UPDATE fielddefs SET name = ? WHERE id = ?', + undef, ($new_field_name, $old_field_id)); + } + + # This field has to be created separately, or the above upgrade code + # might not run properly. + Bugzilla::Field->create({ name => $new_field_name, + description => $field_description }) + unless new Bugzilla::Field({ name => $new_field_name }); + +} -Params: $cgi - a CGI object - $fieldname - the field name to check -Returns: nothing + +=head2 Data Validation + +=over + +=item C<check_field($name, $value, \@legal_values, $no_warn)> + +Description: Makes sure the field $name is defined and its $value + is non empty. If @legal_values is defined, this routine + checks whether its value is one of the legal values + associated with this field, else it checks against + the default valid values for this field obtained by + C<get_legal_field_values($name)>. If the test is successful, + the function returns 1. If the test fails, an error + is thrown (by default), unless $no_warn is true, in which + case the function returns 0. + +Params: $name - the field name + $value - the field value + @legal_values - (optional) list of legal values + $no_warn - (optional) do not throw an error if true + +Returns: 1 on success; 0 on failure if $no_warn is true (else an + error is thrown). + +=back + +=cut + +sub check_field { + my ($name, $value, $legalsRef, $no_warn) = @_; + my $dbh = Bugzilla->dbh; + + # If $legalsRef is undefined, we use the default valid values. + unless (defined $legalsRef) { + $legalsRef = get_legal_field_values($name); + } + + if (!defined($value) + || trim($value) eq "" + || lsearch($legalsRef, $value) < 0) + { + return 0 if $no_warn; # We don't want an error to be thrown; return. + trick_taint($name); + + my $field = new Bugzilla::Field({ name => $name }); + my $field_desc = $field ? $field->description : $name; + ThrowCodeError('illegal_field', { field => $field_desc }); + } + return 1; +} + +=pod + +=over =item C<get_field_id($fieldname)> Description: Returns the ID of the specified field name and throws an error if this field does not exist. -Params: $fieldname - a field name +Params: $name - a field name Returns: the corresponding field ID or an error if the field name does not exist. =back + +=cut + +sub get_field_id { + my ($name) = @_; + my $dbh = Bugzilla->dbh; + + trick_taint($name); + my $id = $dbh->selectrow_array('SELECT id FROM fielddefs + WHERE name = ?', undef, $name); + + ThrowCodeError('invalid_field_name', {field => $name}) unless $id; + return $id +} + +1; + +__END__ diff --git a/Bugzilla/Flag.pm b/Bugzilla/Flag.pm index b812233ea..c3981d92b 100644 --- a/Bugzilla/Flag.pm +++ b/Bugzilla/Flag.pm @@ -21,6 +21,10 @@ # Jouni Heikniemi <jouni@heikniemi.net> # Frédéric Buclin <LpSolit@gmail.com> +use strict; + +package Bugzilla::Flag; + =head1 NAME Bugzilla::Flag - A module to deal with Bugzilla flag values. @@ -36,17 +40,12 @@ See below for more information. =item * -Prior to calling routines in this module, it's assumed that you have -already done a C<require globals.pl>. - -=item * - Import relevant functions from that script. =item * Use of private functions / variables outside this module may lead to -unexpected results after an upgrade. Please avoid usi8ng private +unexpected results after an upgrade. Please avoid using private functions in other files/modules. Private functions are functions whose names start with _ or a re specifically noted as being private. @@ -54,101 +53,140 @@ whose names start with _ or a re specifically noted as being private. =cut -###################################################################### -# Module Initialization -###################################################################### - -# Make it harder for us to do dangerous things in Perl. -use strict; - -# This module implements bug and attachment flags. -package Bugzilla::Flag; - use Bugzilla::FlagType; use Bugzilla::User; -use Bugzilla::Config; use Bugzilla::Util; use Bugzilla::Error; -use Bugzilla::Attachment; -use Bugzilla::BugMail; +use Bugzilla::Mailer; use Bugzilla::Constants; use Bugzilla::Field; -###################################################################### -# Global Variables -###################################################################### +use base qw(Bugzilla::Object Exporter); +@Bugzilla::Flag::EXPORT = qw(SKIP_REQUESTEE_ON_ERROR); -# basic sets of columns and tables for getting flags from the database +############################### +#### Initialization #### +############################### -=begin private +use constant DB_COLUMNS => qw( + flags.id + flags.type_id + flags.bug_id + flags.attach_id + flags.requestee_id + flags.setter_id + flags.status +); + +use constant DB_TABLE => 'flags'; +use constant LIST_ORDER => 'id'; + +use constant SKIP_REQUESTEE_ON_ERROR => 1; -=head1 PRIVATE VARIABLES/CONSTANTS +############################### +#### Accessors ###### +############################### + +=head2 METHODS =over -=item C<@base_columns> +=item C<id> -basic sets of columns and tables for getting flag types from th -database. B<Used by get, match, sqlify_criteria and perlify_record> +Returns the ID of the flag. -=cut +=item C<name> -my @base_columns = - ("is_active", "id", "type_id", "bug_id", "attach_id", "requestee_id", - "setter_id", "status"); +Returns the name of the flagtype the flag belongs to. -=pod +=item C<bug_id> -=item C<@base_tables> +Returns the ID of the bug this flag belongs to. -Which database(s) is the data coming from? +=item C<attach_id> -Note: when adding tables to @base_tables, make sure to include the separator -(i.e. words like "LEFT OUTER JOIN") before the table name, since tables take -multiple separators based on the join type, and therefore it is not possible -to join them later using a single known separator. -B<Used by get, match, sqlify_criteria and perlify_record> +Returns the ID of the attachment this flag belongs to, if any. -=back +=item C<status> -=end private +Returns the status '+', '-', '?' of the flag. + +=back =cut -my @base_tables = ("flags"); +sub id { return $_[0]->{'id'}; } +sub name { return $_[0]->type->name; } +sub bug_id { return $_[0]->{'bug_id'}; } +sub attach_id { return $_[0]->{'attach_id'}; } +sub status { return $_[0]->{'status'}; } -###################################################################### -# Searching/Retrieving Flags -###################################################################### +############################### +#### Methods #### +############################### -=head1 PUBLIC FUNCTIONS +=pod =over -=item C<get($id)> +=item C<type> + +Returns the type of the flag, as a Bugzilla::FlagType object. + +=item C<setter> -Retrieves and returns a flag from the database. +Returns the user who set the flag, as a Bugzilla::User object. + +=item C<requestee> + +Returns the user who has been requested to set the flag, as a +Bugzilla::User object. + +=item C<attachment> + +Returns the attachment object the flag belongs to if the flag +is an attachment flag, else undefined. =back =cut -# !!! Implement a cache for this function! -sub get { - my ($id) = @_; +sub type { + my $self = shift; - my $select_clause = "SELECT " . join(", ", @base_columns); - my $from_clause = "FROM " . join(" ", @base_tables); - - # Execute the query, retrieve the result, and write it into a record. - &::PushGlobalSQLState(); - &::SendSQL("$select_clause $from_clause WHERE flags.id = $id"); - my $flag = perlify_record(&::FetchSQLData()); - &::PopGlobalSQLState(); + $self->{'type'} ||= new Bugzilla::FlagType($self->{'type_id'}); + return $self->{'type'}; +} - return $flag; +sub setter { + my $self = shift; + + $self->{'setter'} ||= new Bugzilla::User($self->{'setter_id'}); + return $self->{'setter'}; +} + +sub requestee { + my $self = shift; + + if (!defined $self->{'requestee'} && $self->{'requestee_id'}) { + $self->{'requestee'} = new Bugzilla::User($self->{'requestee_id'}); + } + return $self->{'requestee'}; +} + +sub attachment { + my $self = shift; + return undef unless $self->attach_id; + + require Bugzilla::Attachment; + $self->{'attachment'} ||= Bugzilla::Attachment->get($self->attach_id); + return $self->{'attachment'}; } +################################ +## Searching/Retrieving Flags ## +################################ + =pod =over @@ -165,25 +203,15 @@ and returns an array of matching records. sub match { my ($criteria) = @_; + my $dbh = Bugzilla->dbh; - my $select_clause = "SELECT " . join(", ", @base_columns); - my $from_clause = "FROM " . join(" ", @base_tables); - my @criteria = sqlify_criteria($criteria); - - my $where_clause = "WHERE " . join(" AND ", @criteria); - - # Execute the query, retrieve the results, and write them into records. - &::PushGlobalSQLState(); - &::SendSQL("$select_clause $from_clause $where_clause"); - my @flags; - while (&::MoreSQLData()) { - my $flag = perlify_record(&::FetchSQLData()); - push(@flags, $flag); - } - &::PopGlobalSQLState(); + $criteria = join(' AND ', @criteria); - return \@flags; + my $flag_ids = $dbh->selectcol_arrayref("SELECT id FROM flags + WHERE $criteria"); + + return Bugzilla::Flag->new_from_list($flag_ids); } =pod @@ -192,7 +220,7 @@ sub match { =item C<count($criteria)> -Queries the database for flags matching the given criteria +Queries the database for flags matching the given criteria (specified as a hash of field names and their matching values) and returns an array of matching records. @@ -202,16 +230,12 @@ and returns an array of matching records. sub count { my ($criteria) = @_; + my $dbh = Bugzilla->dbh; my @criteria = sqlify_criteria($criteria); - - my $where_clause = "WHERE " . join(" AND ", @criteria); - - # Execute the query, retrieve the result, and write it into a record. - &::PushGlobalSQLState(); - &::SendSQL("SELECT COUNT(id) FROM flags $where_clause"); - my $count = &::FetchOneColumn(); - &::PopGlobalSQLState(); + $criteria = join(' AND ', @criteria); + + my $count = $dbh->selectrow_array("SELECT COUNT(*) FROM flags WHERE $criteria"); return $count; } @@ -224,7 +248,7 @@ sub count { =over -=item C<validate($cgi, $bug_id, $attach_id)> +=item C<validate($cgi, $bug_id, $attach_id, $skip_requestee_on_error)> Validates fields containing flag modifications. @@ -236,174 +260,238 @@ to -1 to force its check anyway. =cut sub validate { - my ($cgi, $bug_id, $attach_id) = @_; + my ($cgi, $bug_id, $attach_id, $skip_requestee_on_error) = @_; - my $user = Bugzilla->user; my $dbh = Bugzilla->dbh; # Get a list of flags to validate. Uses the "map" function # to extract flag IDs from form field names by matching fields - # whose name looks like "flag-nnn", where "nnn" is the ID, - # and returning just the ID portion of matching field names. - my @ids = map(/^flag-(\d+)$/ ? $1 : (), $cgi->param()); + # whose name looks like "flag_type-nnn" (new flags) or "flag-nnn" + # (existing flags), where "nnn" is the ID, and returning just + # the ID portion of matching field names. + my @flagtype_ids = map(/^flag_type-(\d+)$/ ? $1 : (), $cgi->param()); + my @flag_ids = map(/^flag-(\d+)$/ ? $1 : (), $cgi->param()); + + return unless (scalar(@flagtype_ids) || scalar(@flag_ids)); - return unless scalar(@ids); - # No flag reference should exist when changing several bugs at once. ThrowCodeError("flags_not_available", { type => 'b' }) unless $bug_id; - # No reference to existing flags should exist when creating a new - # attachment. - if ($attach_id && ($attach_id < 0)) { - ThrowCodeError("flags_not_available", { type => 'a' }); + # We don't check that these new flags are valid for this bug/attachment, + # because the bug may be moved into another product meanwhile. + # This check will be done later when creating new flags, see FormToNewFlags(). + + if (scalar(@flag_ids)) { + # No reference to existing flags should exist when creating a new + # attachment. + if ($attach_id && ($attach_id < 0)) { + ThrowCodeError('flags_not_available', { type => 'a' }); + } + + # Make sure all existing flags belong to the bug/attachment + # they pretend to be. + my $field = ($attach_id) ? "attach_id" : "bug_id"; + my $field_id = $attach_id || $bug_id; + my $not = ($attach_id) ? "" : "NOT"; + + my $invalid_data = + $dbh->selectrow_array("SELECT 1 FROM flags + WHERE id IN (" . join(',', @flag_ids) . ") + AND ($field != ? OR attach_id IS $not NULL) " . + $dbh->sql_limit(1), + undef, $field_id); + + if ($invalid_data) { + ThrowCodeError('invalid_flag_association', + { bug_id => $bug_id, + attach_id => $attach_id }); + } } - # Make sure all flags belong to the bug/attachment they pretend to be. - my $field = ($attach_id) ? "attach_id" : "bug_id"; - my $field_id = $attach_id || $bug_id; - my $not = ($attach_id) ? "" : "NOT"; - - my $invalid_data = - $dbh->selectrow_array("SELECT 1 FROM flags - WHERE id IN (" . join(',', @ids) . ") - AND ($field != ? OR attach_id IS $not NULL) " . - $dbh->sql_limit(1), - undef, $field_id); - - if ($invalid_data) { - ThrowCodeError("invalid_flag_association", - { bug_id => $bug_id, - attach_id => $attach_id }); + # Validate new flags. + foreach my $id (@flagtype_ids) { + my $status = $cgi->param("flag_type-$id"); + my @requestees = $cgi->param("requestee_type-$id"); + my $private_attachment = $cgi->param('isprivate') ? 1 : 0; + + # Don't bother validating types the user didn't touch. + next if $status eq 'X'; + + # Make sure the flag type exists. If it doesn't, FormToNewFlags() + # will ignore it, so it's safe to ignore it here. + my $flag_type = new Bugzilla::FlagType($id); + next unless $flag_type; + + # Make sure the flag type is active. + unless ($flag_type->is_active) { + ThrowCodeError('flag_type_inactive', {'type' => $flag_type->name}); + } + + _validate(undef, $flag_type, $status, undef, \@requestees, $private_attachment, + $bug_id, $attach_id, $skip_requestee_on_error); } - foreach my $id (@ids) { + # Validate existing flags. + foreach my $id (@flag_ids) { my $status = $cgi->param("flag-$id"); my @requestees = $cgi->param("requestee-$id"); - - # Make sure the flag exists. - my $flag = get($id); - $flag || ThrowCodeError("flag_nonexistent", { id => $id }); - - # Note that the deletedness of the flag (is_active or not) is not - # checked here; we do want to allow changes to deleted flags in - # certain cases. Flag::modify() will revive the modified flags. - # See bug 223878 for details. - - # Make sure the user chose a valid status. - grep($status eq $_, qw(X + - ?)) - || ThrowCodeError("flag_status_invalid", - { id => $id, status => $status }); - - # Make sure the user didn't request the flag unless it's requestable. - # If the flag was requested before it became unrequestable, leave it - # as is. - if ($status eq '?' - && $flag->{status} ne '?' - && !$flag->{type}->{is_requestable}) - { - ThrowCodeError("flag_status_invalid", - { id => $id, status => $status }); + my $private_attachment = $cgi->param('isprivate') ? 1 : 0; + + # Make sure the flag exists. If it doesn't, process() will ignore it, + # so it's safe to ignore it here. + my $flag = new Bugzilla::Flag($id); + next unless $flag; + + _validate($flag, $flag->type, $status, undef, \@requestees, $private_attachment, + undef, undef, $skip_requestee_on_error); + } +} + +sub _validate { + my ($flag, $flag_type, $status, $setter, $requestees, $private_attachment, + $bug_id, $attach_id, $skip_requestee_on_error) = @_; + + # By default, the flag setter (or requester) is the current user. + $setter ||= Bugzilla->user; + + my $id = $flag ? $flag->id : $flag_type->id; # Used in the error messages below. + $bug_id ||= $flag->bug_id; + $attach_id ||= $flag->attach_id if $flag; # Maybe it's a bug flag. + + # Make sure the user chose a valid status. + grep($status eq $_, qw(X + - ?)) + || ThrowCodeError('flag_status_invalid', + { id => $id, status => $status }); + + # Make sure the user didn't request the flag unless it's requestable. + # If the flag existed and was requested before it became unrequestable, + # leave it as is. + if ($status eq '?' + && (!$flag || $flag->status ne '?') + && !$flag_type->is_requestable) + { + ThrowCodeError('flag_status_invalid', + { id => $id, status => $status }); + } + + # Make sure the user didn't specify a requestee unless the flag + # is specifically requestable. For existing flags, if the requestee + # was set before the flag became specifically unrequestable, don't + # let the user change the requestee, but let the user remove it by + # entering an empty string for the requestee. + if ($status eq '?' && !$flag_type->is_requesteeble) { + my $old_requestee = ($flag && $flag->requestee) ? + $flag->requestee->login : ''; + my $new_requestee = join('', @$requestees); + if ($new_requestee && $new_requestee ne $old_requestee) { + ThrowCodeError('flag_requestee_disabled', + { type => $flag_type }); } + } - # Make sure the user didn't specify a requestee unless the flag - # is specifically requestable. If the requestee was set before - # the flag became specifically unrequestable, don't let the user - # change the requestee, but let the user remove it by entering - # an empty string for the requestee. - if ($status eq '?' && !$flag->{type}->{is_requesteeble}) { - my $old_requestee = - $flag->{'requestee'} ? $flag->{'requestee'}->login : ''; - my $new_requestee = join('', @requestees); - if ($new_requestee && $new_requestee ne $old_requestee) { - ThrowCodeError("flag_requestee_disabled", - { type => $flag->{type} }); + # Make sure the user didn't enter multiple requestees for a flag + # that can't be requested from more than one person at a time. + if ($status eq '?' + && !$flag_type->is_multiplicable + && scalar(@$requestees) > 1) + { + ThrowUserError('flag_not_multiplicable', { type => $flag_type }); + } + + # Make sure the requestees are authorized to access the bug + # (and attachment, if this installation is using the "insider group" + # feature and the attachment is marked private). + if ($status eq '?' && $flag_type->is_requesteeble) { + my $old_requestee = ($flag && $flag->requestee) ? + $flag->requestee->login : ''; + + my @legal_requestees; + foreach my $login (@$requestees) { + if ($login eq $old_requestee) { + # This requestee was already set. Leave him alone. + push(@legal_requestees, $login); + next; } - } - # Make sure the user didn't enter multiple requestees for a flag - # that can't be requested from more than one person at a time. - if ($status eq '?' - && !$flag->{type}->{is_multiplicable} - && scalar(@requestees) > 1) - { - ThrowUserError("flag_not_multiplicable", { type => $flag->{type} }); - } + # We know the requestee exists because we ran + # Bugzilla::User::match_field before getting here. + my $requestee = new Bugzilla::User({ name => $login }); + + # Throw an error if the user can't see the bug. + # Note that if permissions on this bug are changed, + # can_see_bug() will refer to old settings. + if (!$requestee->can_see_bug($bug_id)) { + next if $skip_requestee_on_error; + ThrowUserError('flag_requestee_unauthorized', + { flag_type => $flag_type, + requestee => $requestee, + bug_id => $bug_id, + attach_id => $attach_id }); + } - # Make sure the requestees are authorized to access the bug. - # (and attachment, if this installation is using the "insider group" - # feature and the attachment is marked private). - if ($status eq '?' && $flag->{type}->{is_requesteeble}) { - my $old_requestee = - $flag->{'requestee'} ? $flag->{'requestee'}->login : ''; - foreach my $login (@requestees) { - next if $login eq $old_requestee; - - # We know the requestee exists because we ran - # Bugzilla::User::match_field before getting here. - my $requestee = Bugzilla::User->new_from_login($login); - - # Throw an error if the user can't see the bug. - # Note that if permissions on this bug are changed, - # can_see_bug() will refer to old settings. - if (!$requestee->can_see_bug($bug_id)) { - ThrowUserError("flag_requestee_unauthorized", - { flag_type => $flag->{'type'}, - requestee => $requestee, - bug_id => $bug_id, - attachment => $flag->{target}->{attachment} - }); - } - - # Throw an error if the target is a private attachment and - # the requestee isn't in the group of insiders who can see it. - if ($flag->{target}->{attachment} - && $cgi->param('isprivate') - && Param("insidergroup") - && !$requestee->in_group(Param("insidergroup"))) - { - ThrowUserError("flag_requestee_unauthorized_attachment", - { flag_type => $flag->{'type'}, - requestee => $requestee, - bug_id => $bug_id, - attachment => $flag->{target}->{attachment} - }); - } + # Throw an error if the target is a private attachment and + # the requestee isn't in the group of insiders who can see it. + if ($attach_id + && $private_attachment + && Bugzilla->params->{'insidergroup'} + && !$requestee->in_group(Bugzilla->params->{'insidergroup'})) + { + next if $skip_requestee_on_error; + ThrowUserError('flag_requestee_unauthorized_attachment', + { flag_type => $flag_type, + requestee => $requestee, + bug_id => $bug_id, + attach_id => $attach_id }); } + + # Throw an error if the user won't be allowed to set the flag. + if (!$requestee->can_set_flag($flag_type)) { + next if $skip_requestee_on_error; + ThrowUserError('flag_requestee_needs_privs', + {'requestee' => $requestee, + 'flagtype' => $flag_type}); + } + + # This requestee can be set. + push(@legal_requestees, $login); } - # Make sure the user is authorized to modify flags, see bug 180879 - # - The flag is unchanged - next if ($status eq $flag->{status}); - - # - User in the $request_gid group can clear pending requests and set flags - # and can rerequest set flags. - next if (($status eq 'X' || $status eq '?') - && (!$flag->{type}->{request_gid} - || $user->in_group(&::GroupIdToName($flag->{type}->{request_gid})))); - - # - User in the $grant_gid group can set/clear flags, - # including "+" and "-" - next if (!$flag->{type}->{grant_gid} - || $user->in_group(&::GroupIdToName($flag->{type}->{grant_gid}))); - - # - Any other flag modification is denied - ThrowUserError("flag_update_denied", - { name => $flag->{type}->{name}, - status => $status, - old_status => $flag->{status} }); + # Update the requestee list for this flag. + if (scalar(@legal_requestees) < scalar(@$requestees)) { + my $field_name = 'requestee_type-' . $flag_type->id; + Bugzilla->cgi->delete($field_name); + Bugzilla->cgi->param(-name => $field_name, -value => \@legal_requestees); + } } + + # Make sure the user is authorized to modify flags, see bug 180879 + # - The flag exists and is unchanged. + return if ($flag && ($status eq $flag->status)); + + # - User in the request_group can clear pending requests and set flags + # and can rerequest set flags. + return if (($status eq 'X' || $status eq '?') + && $setter->can_request_flag($flag_type)); + + # - User in the grant_group can set/clear flags, including "+" and "-". + return if $setter->can_set_flag($flag_type); + + # - Any other flag modification is denied + ThrowUserError('flag_update_denied', + { name => $flag_type->name, + status => $status, + old_status => $flag ? $flag->status : 'X' }); } sub snapshot { my ($bug_id, $attach_id) = @_; my $flags = match({ 'bug_id' => $bug_id, - 'attach_id' => $attach_id, - 'is_active' => 1 }); + 'attach_id' => $attach_id }); my @summaries; foreach my $flag (@$flags) { - my $summary = $flag->{'type'}->{'name'} . $flag->{'status'}; - $summary .= "(" . $flag->{'requestee'}->login . ")" if $flag->{'requestee'}; + my $summary = $flag->type->name . $flag->status; + $summary .= "(" . $flag->requestee->login . ")" if $flag->requestee; push(@summaries, $summary); } return @summaries; @@ -414,50 +502,52 @@ sub snapshot { =over -=item C<process($target, $timestamp, $cgi)> +=item C<process($bug, $attachment, $timestamp, $cgi)> Processes changes to flags. -The target is the bug or attachment this flag is about, the timestamp -is the date/time the bug was last touched (so that changes to the flag -can be stamped with the same date/time), the cgi is the CGI object -used to obtain the flag fields that the user submitted. +The bug and/or the attachment objects are the ones this flag is about, +the timestamp is the date/time the bug was last touched (so that changes +to the flag can be stamped with the same date/time), the cgi is the CGI +object used to obtain the flag fields that the user submitted. =back =cut sub process { - my ($bug_id, $attach_id, $timestamp, $cgi) = @_; - + my ($bug, $attachment, $timestamp, $cgi) = @_; my $dbh = Bugzilla->dbh; - my $target = get_target($bug_id, $attach_id); - # Make sure the target exists. - return unless $target->{'exists'}; + + # Make sure the bug (and attachment, if given) exists and is accessible + # to the current user. Moreover, if an attachment object is passed, + # make sure it belongs to the given bug. + return if ($bug->error || ($attachment && $bug->bug_id != $attachment->bug_id)); + + my $bug_id = $bug->bug_id; + my $attach_id = $attachment ? $attachment->id : undef; # Use the date/time we were given if possible (allowing calling code # to synchronize the comment's timestamp with those of other records). - # XXX - we shouldn't quote the timestamp here, but this would involve - # many changes in this file. - $timestamp = ($timestamp ? &::SqlQuote($timestamp) : "NOW()"); - + $timestamp ||= $dbh->selectrow_array('SELECT NOW()'); + # Take a snapshot of flags before any changes. my @old_summaries = snapshot($bug_id, $attach_id); - + # Cancel pending requests if we are obsoleting an attachment. - if ($attach_id && $cgi->param('isobsolete')) { - CancelRequests($bug_id, $attach_id); + if ($attachment && $cgi->param('isobsolete')) { + CancelRequests($bug, $attachment); } # Create new flags and update existing flags. - my $new_flags = FormToNewFlags($target, $cgi); - foreach my $flag (@$new_flags) { create($flag, $timestamp) } - modify($cgi, $timestamp); - + my $new_flags = FormToNewFlags($bug, $attachment, $cgi); + foreach my $flag (@$new_flags) { create($flag, $bug, $attachment, $timestamp) } + modify($bug, $attachment, $cgi, $timestamp); + # In case the bug's product/component has changed, clear flags that are # no longer valid. my $flag_ids = $dbh->selectcol_arrayref( - "SELECT flags.id + "SELECT DISTINCT flags.id FROM flags INNER JOIN bugs ON flags.bug_id = bugs.bug_id @@ -466,24 +556,30 @@ sub process { AND (bugs.product_id = i.product_id OR i.product_id IS NULL) AND (bugs.component_id = i.component_id OR i.component_id IS NULL) WHERE bugs.bug_id = ? - AND flags.is_active = 1 AND i.type_id IS NULL", undef, $bug_id); - foreach my $flag_id (@$flag_ids) { clear($flag_id) } + my $flags = Bugzilla::Flag->new_from_list($flag_ids); + foreach my $flag (@$flags) { + my $is_retargetted = retarget($flag, $bug); + clear($flag, $bug, $flag->attachment) unless $is_retargetted; + } $flag_ids = $dbh->selectcol_arrayref( - "SELECT flags.id + "SELECT DISTINCT flags.id FROM flags, bugs, flagexclusions e WHERE bugs.bug_id = ? AND flags.bug_id = bugs.bug_id AND flags.type_id = e.type_id - AND flags.is_active = 1 AND (bugs.product_id = e.product_id OR e.product_id IS NULL) AND (bugs.component_id = e.component_id OR e.component_id IS NULL)", undef, $bug_id); - foreach my $flag_id (@$flag_ids) { clear($flag_id) } + $flags = Bugzilla::Flag->new_from_list($flag_ids); + foreach my $flag (@$flags) { + my $is_retargetted = retarget($flag, $bug); + clear($flag, $bug, $flag->attachment) unless $is_retargetted; + } # Take a snapshot of flags after changes. my @new_summaries = snapshot($bug_id, $attach_id); @@ -494,23 +590,20 @@ sub process { sub update_activity { my ($bug_id, $attach_id, $timestamp, $old_summaries, $new_summaries) = @_; my $dbh = Bugzilla->dbh; - my $user_id = Bugzilla->user->id; - $attach_id ||= 'NULL'; $old_summaries = join(", ", @$old_summaries); $new_summaries = join(", ", @$new_summaries); my ($removed, $added) = diff_strings($old_summaries, $new_summaries); if ($removed ne $added) { - my $sql_removed = &::SqlQuote($removed); - my $sql_added = &::SqlQuote($added); my $field_id = get_field_id('flagtypes.name'); - $dbh->do("INSERT INTO bugs_activity + $dbh->do('INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added) - VALUES ($bug_id, $attach_id, $user_id, $timestamp, - $field_id, $sql_removed, $sql_added)"); + VALUES (?, ?, ?, ?, ?, ?, ?)', + undef, ($bug_id, $attach_id, Bugzilla->user->id, + $timestamp, $field_id, $removed, $added)); - $dbh->do("UPDATE bugs SET delta_ts = $timestamp WHERE bug_id = ?", - undef, $bug_id); + $dbh->do('UPDATE bugs SET delta_ts = ? WHERE bug_id = ?', + undef, ($timestamp, $bug_id)); } } @@ -518,7 +611,7 @@ sub update_activity { =over -=item C<create($flag, $timestamp)> +=item C<create($flag, $bug, $attachment, $timestamp)> Creates a flag record in the database. @@ -527,98 +620,66 @@ Creates a flag record in the database. =cut sub create { - my ($flag, $timestamp) = @_; - - # Determine the ID for the flag record by retrieving the last ID used - # and incrementing it. - &::SendSQL("SELECT MAX(id) FROM flags"); - $flag->{'id'} = (&::FetchOneColumn() || 0) + 1; - - # Insert a record for the flag into the flags table. - my $attach_id = - $flag->{target}->{attachment} ? $flag->{target}->{attachment}->{id} - : "NULL"; - my $requestee_id = $flag->{'requestee'} ? $flag->{'requestee'}->id : "NULL"; - &::SendSQL("INSERT INTO flags (id, type_id, - bug_id, attach_id, - requestee_id, setter_id, status, - creation_date, modification_date) - VALUES ($flag->{'id'}, - $flag->{'type'}->{'id'}, - $flag->{'target'}->{'bug'}->{'id'}, - $attach_id, - $requestee_id, - " . $flag->{'setter'}->id . ", - '$flag->{'status'}', - $timestamp, - $timestamp)"); - - # Send an email notifying the relevant parties about the flag creation. - if ($flag->{'requestee'} - && $flag->{'requestee'}->wants_mail([EVT_FLAG_REQUESTED])) - { - $flag->{'addressee'} = $flag->{'requestee'}; - } - - notify($flag, "request/email.txt.tmpl"); -} - -=pod - -=over - -=item C<migrate($old_attach_id, $new_attach_id, $timestamp)> + my ($flag, $bug, $attachment, $timestamp) = @_; + my $dbh = Bugzilla->dbh; -Moves a flag from one attachment to another. Useful for migrating -a flag from an obsolete attachment to the attachment that obsoleted it. + my $attach_id = $attachment ? $attachment->id : undef; + my $requestee_id; + # Be careful! At this point, $flag is *NOT* yet an object! + $requestee_id = $flag->{'requestee'}->id if $flag->{'requestee'}; -=back + $dbh->do('INSERT INTO flags (type_id, bug_id, attach_id, requestee_id, + setter_id, status, creation_date, modification_date) + VALUES (?, ?, ?, ?, ?, ?, ?, ?)', + undef, ($flag->{'type'}->id, $bug->bug_id, + $attach_id, $requestee_id, $flag->{'setter'}->id, + $flag->{'status'}, $timestamp, $timestamp)); -=cut + # Now that the new flag has been added to the DB, create a real flag object. + # This is required to call notify() correctly. + my $flag_id = $dbh->bz_last_key('flags', 'id'); + $flag = new Bugzilla::Flag($flag_id); -sub migrate { - my ($old_attach_id, $new_attach_id, $timestamp) = @_; + # Send an email notifying the relevant parties about the flag creation. + if ($flag->requestee && $flag->requestee->wants_mail([EVT_FLAG_REQUESTED])) { + $flag->{'addressee'} = $flag->requestee; + } - # Use the date/time we were given if possible (allowing calling code - # to synchronize the comment's timestamp with those of other records). - $timestamp = ($timestamp ? &::SqlQuote($timestamp) : "NOW()"); + notify($flag, $bug, $attachment); - # Update the record in the flags table to point to the new attachment. - &::SendSQL("UPDATE flags " . - "SET attach_id = $new_attach_id , " . - " modification_date = $timestamp " . - "WHERE attach_id = $old_attach_id"); + # Return the new flag object. + return $flag; } =pod =over -=item C<modify($cgi, $timestamp)> +=item C<modify($bug, $attachment, $cgi, $timestamp)> Modifies flags in the database when a user changes them. -Note that modified flags are always set active (is_active = 1) - -this will revive deleted flags that get changed through -attachment.cgi midairs. See bug 223878 for details. =back =cut sub modify { - my ($cgi, $timestamp) = @_; + my ($bug, $attachment, $cgi, $timestamp) = @_; my $setter = Bugzilla->user; + my $dbh = Bugzilla->dbh; # Extract a list of flags from the form data. my @ids = map(/^flag-(\d+)$/ ? $1 : (), $cgi->param()); - + # Loop over flags and update their record in the database if necessary. # Two kinds of changes can happen to a flag: it can be set to a different # state, and someone else can be asked to set it. We take care of both # those changes. my @flags; foreach my $id (@ids) { - my $flag = get($id); + my $flag = new Bugzilla::Flag($id); + # If the flag no longer exists, ignore it. + next unless $flag; my $status = $cgi->param("flag-$id"); @@ -630,19 +691,18 @@ sub modify { my $requestee_email; if ($status eq "?" && scalar(@requestees) > 1 - && $flag->{type}->{is_multiplicable}) + && $flag->type->is_multiplicable) { # The first person, for which we'll reuse the existing flag. $requestee_email = shift(@requestees); - + # Create new flags like the existing one for each additional person. foreach my $login (@requestees) { - create({ type => $flag->{type} , - target => $flag->{target} , + create({ type => $flag->type, setter => $setter, status => "?", - requestee => new Bugzilla::User(login_to_id($login)) }, - $timestamp); + requestee => new Bugzilla::User({ name => $login }) }, + $bug, $attachment, $timestamp); } } else { @@ -653,47 +713,44 @@ sub modify { # either the status changes (trivial) or the requestee changes. # Change of either field will cause full update of the flag. - my $status_changed = ($status ne $flag->{'status'}); - + my $status_changed = ($status ne $flag->status); + # Requestee is considered changed, if all of the following apply: # 1. Flag status is '?' (requested) # 2. Flag can have a requestee # 3. The requestee specified on the form is different from the # requestee specified in the db. - - my $old_requestee = - $flag->{'requestee'} ? $flag->{'requestee'}->login : ''; + + my $old_requestee = $flag->requestee ? $flag->requestee->login : ''; my $requestee_changed = ($status eq "?" && - $flag->{'type'}->{'is_requesteeble'} && + $flag->type->is_requesteeble && $old_requestee ne $requestee_email); - + next unless ($status_changed || $requestee_changed); - # Since the status is validated, we know it's safe, but it's still # tainted, so we have to detaint it before using it in a query. - &::trick_taint($status); - + trick_taint($status); + if ($status eq '+' || $status eq '-') { - &::SendSQL("UPDATE flags - SET setter_id = " . $setter->id . ", - requestee_id = NULL , - status = '$status' , - modification_date = $timestamp , - is_active = 1 - WHERE id = $flag->{'id'}"); + $dbh->do('UPDATE flags + SET setter_id = ?, requestee_id = NULL, + status = ?, modification_date = ? + WHERE id = ?', + undef, ($setter->id, $status, $timestamp, $flag->id)); # If the status of the flag was "?", we have to notify # the requester (if he wants to). my $requester; - if ($flag->{'status'} eq '?') { - $requester = $flag->{'setter'}; + if ($flag->status eq '?') { + $requester = $flag->setter; } # Now update the flag object with its new values. $flag->{'setter'} = $setter; $flag->{'requestee'} = undef; + $flag->{'requestee_id'} = undef; $flag->{'status'} = $status; # Send an email notifying the relevant parties about the fulfillment, @@ -702,51 +759,49 @@ sub modify { $flag->{'addressee'} = $requester; } - notify($flag, "request/email.txt.tmpl"); + notify($flag, $bug, $attachment); } elsif ($status eq '?') { # Get the requestee, if any. - my $requestee_id = "NULL"; + my $requestee_id; if ($requestee_email) { $requestee_id = login_to_id($requestee_email); $flag->{'requestee'} = new Bugzilla::User($requestee_id); + $flag->{'requestee_id'} = $requestee_id; } else { # If the status didn't change but we only removed the # requestee, we have to clear the requestee field. $flag->{'requestee'} = undef; + $flag->{'requestee_id'} = undef; } # Update the database with the changes. - &::SendSQL("UPDATE flags - SET setter_id = " . $setter->id . ", - requestee_id = $requestee_id , - status = '$status' , - modification_date = $timestamp , - is_active = 1 - WHERE id = $flag->{'id'}"); + $dbh->do('UPDATE flags + SET setter_id = ?, requestee_id = ?, + status = ?, modification_date = ? + WHERE id = ?', + undef, ($setter->id, $requestee_id, $status, + $timestamp, $flag->id)); # Now update the flag object with its new values. $flag->{'setter'} = $setter; $flag->{'status'} = $status; # Send an email notifying the relevant parties about the request. - if ($flag->{'requestee'} - && $flag->{'requestee'}->wants_mail([EVT_FLAG_REQUESTED])) - { - $flag->{'addressee'} = $flag->{'requestee'}; + if ($flag->requestee && $flag->requestee->wants_mail([EVT_FLAG_REQUESTED])) { + $flag->{'addressee'} = $flag->requestee; } - notify($flag, "request/email.txt.tmpl"); + notify($flag, $bug, $attachment); } - # The user unset the flag; set is_active = 0 elsif ($status eq 'X') { - clear($flag->{'id'}); + clear($flag, $bug, $attachment); } - + push(@flags, $flag); } - + return \@flags; } @@ -754,28 +809,102 @@ sub modify { =over -=item C<clear($id)> +=item C<retarget($flag, $bug)> -Deactivate a flag. +Change the type of the flag, if possible. The new flag type must have +the same name as the current flag type, must exist in the product and +component the bug is in, and the current settings of the flag must pass +validation. If no such flag type can be found, the type remains unchanged. + +Retargetting flags is a good way to keep flags when moving bugs from one +product where a flag type is available to another product where the flag +type is unavailable, but another flag type having the same name exists. +Most of the time, if they have the same name, this means that they have +the same meaning, but with different settings. + +=back + +=cut + +sub retarget { + my ($flag, $bug) = @_; + my $dbh = Bugzilla->dbh; + + # We are looking for flagtypes having the same name as the flagtype + # to which the current flag belongs, and being in the new product and + # component of the bug. + my $flagtypes = Bugzilla::FlagType::match( + {'name' => $flag->name, + 'target_type' => $flag->type->target_type, + 'is_active' => 1, + 'product_id' => $bug->product_id, + 'component_id' => $bug->component_id}); + + # If we found no flagtype, the flag will be deleted. + return 0 unless scalar(@$flagtypes); + + # If we found at least one, change the type of the flag, + # assuming the setter/requester is allowed to set/request flags + # belonging to this flagtype. + my $requestee = $flag->requestee ? [$flag->requestee->login] : []; + my $is_private = ($flag->attachment) ? $flag->attachment->isprivate : 0; + my $is_retargetted = 0; + + foreach my $flagtype (@$flagtypes) { + # Get the number of flags of this type already set for this target. + my $has_flags = count( + { 'type_id' => $flagtype->id, + 'bug_id' => $bug->bug_id, + 'attach_id' => $flag->attach_id }); + + # Do not create a new flag of this type if this flag type is + # not multiplicable and already has a flag set. + next if (!$flagtype->is_multiplicable && $has_flags); + + # Check user privileges. + my $error_mode_cache = Bugzilla->error_mode; + Bugzilla->error_mode(ERROR_MODE_DIE); + eval { + _validate(undef, $flagtype, $flag->status, $flag->setter, + $requestee, $is_private, $bug->bug_id, $flag->attach_id); + }; + Bugzilla->error_mode($error_mode_cache); + # If the validation failed, then we cannot use this flagtype. + next if ($@); + + # Checks are successful, we can retarget the flag to this flagtype. + $dbh->do('UPDATE flags SET type_id = ? WHERE id = ?', + undef, ($flagtype->id, $flag->id)); + + $is_retargetted = 1; + last; + } + return $is_retargetted; +} + +=pod + +=over + +=item C<clear($flag, $bug, $attachment)> + +Remove a flag from the DB. =back =cut sub clear { - my ($id) = @_; - - my $flag = get($id); - - &::PushGlobalSQLState(); - &::SendSQL("UPDATE flags SET is_active = 0 WHERE id = $id"); - &::PopGlobalSQLState(); + my ($flag, $bug, $attachment) = @_; + my $dbh = Bugzilla->dbh; + + $dbh->do('DELETE FROM flags WHERE id = ?', undef, $flag->id); # If we cancel a pending request, we have to notify the requester # (if he wants to). my $requester; - if ($flag->{'status'} eq '?') { - $requester = $flag->{'setter'}; + if ($flag->status eq '?') { + $requester = $flag->setter; } # Now update the flag object to its new values. The last @@ -788,7 +917,7 @@ sub clear { $flag->{'addressee'} = $requester; } - notify($flag, "request/email.txt.tmpl"); + notify($flag, $bug, $attachment); } @@ -800,7 +929,7 @@ sub clear { =over -=item C<FormToNewFlags($target, $cgi)> +=item C<FormToNewFlags($bug, $attachment, $cgi)> Checks whether or not there are new flags to create and returns an array of flag objects. This array is then passed to Flag::create(). @@ -810,7 +939,7 @@ array of flag objects. This array is then passed to Flag::create(). =cut sub FormToNewFlags { - my ($target, $cgi) = @_; + my ($bug, $attachment, $cgi) = @_; my $dbh = Bugzilla->dbh; my $setter = Bugzilla->user; @@ -822,30 +951,28 @@ sub FormToNewFlags { # Get a list of active flag types available for this target. my $flag_types = Bugzilla::FlagType::match( - { 'target_type' => $target->{'type'}, - 'product_id' => $target->{'bug'}->{'product_id'}, - 'component_id' => $target->{'bug'}->{'component_id'}, + { 'target_type' => $attachment ? 'attachment' : 'bug', + 'product_id' => $bug->{'product_id'}, + 'component_id' => $bug->{'component_id'}, 'is_active' => 1 }); my @flags; foreach my $flag_type (@$flag_types) { - my $type_id = $flag_type->{'id'}; + my $type_id = $flag_type->id; # We are only interested in flags the user tries to create. next unless scalar(grep { $_ == $type_id } @type_ids); - # Get the number of active flags of this type already set for this target. + # Get the number of flags of this type already set for this target. my $has_flags = count( { 'type_id' => $type_id, - 'target_type' => $target->{'type'}, - 'bug_id' => $target->{'bug'}->{'id'}, - 'attach_id' => $target->{'attachment'} ? - $target->{'attachment'}->{'id'} : undef, - 'is_active' => 1 }); + 'target_type' => $attachment ? 'attachment' : 'bug', + 'bug_id' => $bug->bug_id, + 'attach_id' => $attachment ? $attachment->id : undef }); # Do not create a new flag of this type if this flag type is - # not multiplicable and already has an active flag set. - next if (!$flag_type->{'is_multiplicable'} && $has_flags); + # not multiplicable and already has a flag set. + next if (!$flag_type->is_multiplicable && $has_flags); my $status = $cgi->param("flag_type-$type_id"); trick_taint($status); @@ -853,18 +980,16 @@ sub FormToNewFlags { my @logins = $cgi->param("requestee_type-$type_id"); if ($status eq "?" && scalar(@logins) > 0) { foreach my $login (@logins) { - my $requestee = new Bugzilla::User(login_to_id($login)); push (@flags, { type => $flag_type , - target => $target , setter => $setter , status => $status , - requestee => $requestee }); - last if !$flag_type->{'is_multiplicable'}; + requestee => + new Bugzilla::User({ name => $login }) }); + last unless $flag_type->is_multiplicable; } } else { push (@flags, { type => $flag_type , - target => $target , setter => $setter , status => $status }); } @@ -878,91 +1003,7 @@ sub FormToNewFlags { =over -=item C<GetBug($id)> - -Returns a hash of information about a target bug. - -=back - -=cut - -# Ideally, we'd use Bug.pm, but it's way too heavyweight, and it can't be -# made lighter without totally rewriting it, so we'll use this function -# until that one gets rewritten. -sub GetBug { - my ($id) = @_; - - my $dbh = Bugzilla->dbh; - - # Save the currently running query (if any) so we do not overwrite it. - &::PushGlobalSQLState(); - - &::SendSQL("SELECT 1, short_desc, product_id, component_id, - COUNT(bug_group_map.group_id) - FROM bugs LEFT JOIN bug_group_map - ON (bugs.bug_id = bug_group_map.bug_id) - WHERE bugs.bug_id = $id " . - $dbh->sql_group_by('bugs.bug_id', - 'short_desc, product_id, component_id')); - - my $bug = { 'id' => $id }; - - ($bug->{'exists'}, $bug->{'summary'}, $bug->{'product_id'}, - $bug->{'component_id'}, $bug->{'restricted'}) = &::FetchSQLData(); - - # Restore the previously running query (if any). - &::PopGlobalSQLState(); - - return $bug; -} - -=pod - -=over - -=item C<get_target($bug_id, $attach_id)> - -Someone please document this function. - -=back - -=cut - -sub get_target { - my ($bug_id, $attach_id) = @_; - - # Create an object representing the target bug/attachment. - my $target = { 'exists' => 0 }; - - if ($attach_id) { - $target->{'attachment'} = Bugzilla::Attachment->get($attach_id); - if ($bug_id) { - # Make sure the bug and attachment IDs correspond to each other - # (i.e. this is the bug to which this attachment is attached). - if (!$target->{'attachment'} - || $target->{'attachment'}->{'bug_id'} != $bug_id) - { - return { 'exists' => 0 }; - } - } - $target->{'bug'} = GetBug($bug_id); - $target->{'exists'} = 1; - $target->{'type'} = "attachment"; - } - elsif ($bug_id) { - $target->{'bug'} = GetBug($bug_id); - $target->{'exists'} = $target->{'bug'}->{'exists'}; - $target->{'type'} = "bug"; - } - - return $target; -} - -=pod - -=over - -=item C<notify($flag, $template_file)> +=item C<notify($flag, $bug, $attachment)> Sends an email notification about a flag being created, fulfilled or deleted. @@ -972,58 +1013,61 @@ or deleted. =cut sub notify { - my ($flag, $template_file) = @_; + my ($flag, $bug, $attachment) = @_; my $template = Bugzilla->template; # There is nobody to notify. - return unless ($flag->{'addressee'} || $flag->{'type'}->{'cc_list'}); + return unless ($flag->{'addressee'} || $flag->type->cc_list); - my $attachment_is_private = $flag->{'target'}->{'attachment'} ? - $flag->{'target'}->{'attachment'}->{'isprivate'} : undef; + my $attachment_is_private = $attachment ? $attachment->isprivate : undef; # If the target bug is restricted to one or more groups, then we need # to make sure we don't send email about it to unauthorized users # on the request type's CC: list, so we have to trawl the list for users # not in those groups or email addresses that don't have an account. - if ($flag->{'target'}->{'bug'}->{'restricted'} || $attachment_is_private) { + my @bug_in_groups = grep {$_->{'ison'} || $_->{'mandatory'}} @{$bug->groups}; + + if (scalar(@bug_in_groups) || $attachment_is_private) { my @new_cc_list; - foreach my $cc (split(/[, ]+/, $flag->{'type'}->{'cc_list'})) { - my $ccuser = Bugzilla::User->new_from_login($cc) || next; + foreach my $cc (split(/[, ]+/, $flag->type->cc_list)) { + my $ccuser = new Bugzilla::User({ name => $cc }) || next; - next if $flag->{'target'}->{'bug'}->{'restricted'} - && !$ccuser->can_see_bug($flag->{'target'}->{'bug'}->{'id'}); + next if (scalar(@bug_in_groups) && !$ccuser->can_see_bug($bug->bug_id)); next if $attachment_is_private - && Param("insidergroup") - && !$ccuser->in_group(Param("insidergroup")); + && Bugzilla->params->{"insidergroup"} + && !$ccuser->in_group(Bugzilla->params->{"insidergroup"}); push(@new_cc_list, $cc); } - $flag->{'type'}->{'cc_list'} = join(", ", @new_cc_list); + $flag->type->{'cc_list'} = join(", ", @new_cc_list); } # If there is nobody left to notify, return. - return unless ($flag->{'addressee'} || $flag->{'type'}->{'cc_list'}); + return unless ($flag->{'addressee'} || $flag->type->cc_list); # Process and send notification for each recipient foreach my $to ($flag->{'addressee'} ? $flag->{'addressee'}->email : '', - split(/[, ]+/, $flag->{'type'}->{'cc_list'})) + split(/[, ]+/, $flag->type->cc_list)) { next unless $to; - my $vars = { 'flag' => $flag, 'to' => $to }; + my $vars = { 'flag' => $flag, + 'to' => $to, + 'bug' => $bug, + 'attachment' => $attachment}; my $message; - my $rv = $template->process($template_file, $vars, \$message); + my $rv = $template->process("request/email.txt.tmpl", $vars, \$message); if (!$rv) { Bugzilla->cgi->header(); ThrowTemplateError($template->error()); } - Bugzilla::BugMail::MessageToMTA($message); + MessageToMTA($message); } } # Cancel all request flags from the attachment being obsoleted. sub CancelRequests { - my ($bug_id, $attach_id, $timestamp) = @_; + my ($bug, $attachment, $timestamp) = @_; my $dbh = Bugzilla->dbh; my $request_ids = @@ -1032,22 +1076,23 @@ sub CancelRequests { LEFT JOIN attachments ON flags.attach_id = attachments.attach_id WHERE flags.attach_id = ? AND flags.status = '?' - AND flags.is_active = 1 AND attachments.isobsolete = 0", - undef, $attach_id); + undef, $attachment->id); return if (!scalar(@$request_ids)); # Take a snapshot of flags before any changes. - my @old_summaries = snapshot($bug_id, $attach_id) if ($timestamp); - foreach my $flag (@$request_ids) { clear($flag) } + my @old_summaries = snapshot($bug->bug_id, $attachment->id) if ($timestamp); + my $flags = Bugzilla::Flag->new_from_list($request_ids); + foreach my $flag (@$flags) { clear($flag, $bug, $attachment) } # If $timestamp is undefined, do not update the activity table return unless ($timestamp); # Take a snapshot of flags after any changes. - my @new_summaries = snapshot($bug_id, $attach_id); - update_activity($bug_id, $attach_id, $timestamp, \@old_summaries, \@new_summaries); + my @new_summaries = snapshot($bug->bug_id, $attachment->id); + update_activity($bug->bug_id, $attachment->id, $timestamp, + \@old_summaries, \@new_summaries); } ###################################################################### @@ -1094,46 +1139,11 @@ sub sqlify_criteria { elsif ($field eq 'requestee_id') { push(@criteria, "requestee_id = $value") } elsif ($field eq 'setter_id') { push(@criteria, "setter_id = $value") } elsif ($field eq 'status') { push(@criteria, "status = '$value'") } - elsif ($field eq 'is_active') { push(@criteria, "is_active = $value") } } return @criteria; } -=pod - -=over - -=item C<perlify_record($exists, $id, $type_id, $bug_id, $attach_id, $requestee_id, $setter_id, $status)> - -Converts a row from the database into a Perl record. - -=back - -=end private - -=cut - -sub perlify_record { - my ($exists, $id, $type_id, $bug_id, $attach_id, - $requestee_id, $setter_id, $status) = @_; - - return undef unless defined($exists); - - my $flag = - { - exists => $exists , - id => $id , - type => Bugzilla::FlagType::get($type_id) , - target => get_target($bug_id, $attach_id) , - requestee => $requestee_id ? new Bugzilla::User($requestee_id) : undef, - setter => new Bugzilla::User($setter_id) , - status => $status , - }; - - return $flag; -} - =head1 SEE ALSO =over @@ -1153,6 +1163,8 @@ sub perlify_record { =item Kevin Benton <kevin.benton@amd.com> +=item Frédéric Buclin <LpSolit@gmail.com> + =back =cut diff --git a/Bugzilla/FlagType.pm b/Bugzilla/FlagType.pm index 6a525fd0e..1504be87d 100644 --- a/Bugzilla/FlagType.pm +++ b/Bugzilla/FlagType.pm @@ -18,6 +18,11 @@ # Rights Reserved. # # Contributor(s): Myk Melez <myk@mozilla.org> +# Frédéric Buclin <LpSolit@gmail.com> + +use strict; + +package Bugzilla::FlagType; =head1 NAME @@ -34,11 +39,6 @@ See below for more information. =item * -Prior to calling routines in this module, it's assumed that you have -already done a C<require globals.pl>. - -=item * - Use of private functions/variables outside this module may lead to unexpected results after an upgrade. Please avoid using private functions in other files/modules. Private functions are functions @@ -48,26 +48,16 @@ whose names start with _ or are specifically noted as being private. =cut -###################################################################### -# Module Initialization -###################################################################### - -# Make it harder for us to do dangerous things in Perl. -use strict; - -# This module implements flag types for the flag tracker. -package Bugzilla::FlagType; - -# Use Bugzilla's User module which contains utilities for handling users. use Bugzilla::User; - use Bugzilla::Error; use Bugzilla::Util; -use Bugzilla::Config; +use Bugzilla::Group; -###################################################################### -# Global Variables -###################################################################### +use base qw(Bugzilla::Object); + +############################### +#### Initialization #### +############################### =begin private @@ -75,35 +65,42 @@ use Bugzilla::Config; =over -=item C<@base_columns> +=item C<DB_COLUMNS> basic sets of columns and tables for getting flag types from the -database. B<Used by get, match, sqlify_criteria and perlify_record> +database. =back =cut -my @base_columns = - ("1", "flagtypes.id", "flagtypes.name", "flagtypes.description", - "flagtypes.cc_list", "flagtypes.target_type", "flagtypes.sortkey", - "flagtypes.is_active", "flagtypes.is_requestable", - "flagtypes.is_requesteeble", "flagtypes.is_multiplicable", - "flagtypes.grant_group_id", "flagtypes.request_group_id"); +use constant DB_COLUMNS => qw( + flagtypes.id + flagtypes.name + flagtypes.description + flagtypes.cc_list + flagtypes.target_type + flagtypes.sortkey + flagtypes.is_active + flagtypes.is_requestable + flagtypes.is_requesteeble + flagtypes.is_multiplicable + flagtypes.grant_group_id + flagtypes.request_group_id +); =pod =over -=item C<@base_tables> +=item C<DB_TABLE> Which database(s) is the data coming from? -Note: when adding tables to @base_tables, make sure to include the separator +Note: when adding tables to DB_TABLE, make sure to include the separator (i.e. words like "LEFT OUTER JOIN") before the table name, since tables take multiple separators based on the join type, and therefore it is not possible to join them later using a single known separator. -B<Used by get, match, sqlify_criteria and perlify_record> =back @@ -111,75 +108,163 @@ B<Used by get, match, sqlify_criteria and perlify_record> =cut -my @base_tables = ("flagtypes"); +use constant DB_TABLE => 'flagtypes'; +use constant LIST_ORDER => 'flagtypes.sortkey, flagtypes.name'; -###################################################################### -# Public Functions -###################################################################### +############################### +#### Accessors ###### +############################### -=head1 PUBLIC FUNCTIONS/METHODS +=head2 METHODS =over -=item C<get($id)> +=item C<id> -Returns a hash of information about a flag type. +Returns the ID of the flagtype. -=back +=item C<name> -=cut +Returns the name of the flagtype. -sub get { - my ($id) = @_; +=item C<description> - my $select_clause = "SELECT " . join(", ", @base_columns); - my $from_clause = "FROM " . join(" ", @base_tables); - - &::PushGlobalSQLState(); - &::SendSQL("$select_clause $from_clause WHERE flagtypes.id = $id"); - my @data = &::FetchSQLData(); - my $type = perlify_record(@data); - &::PopGlobalSQLState(); +Returns the description of the flagtype. - return $type; -} +=item C<cc_list> -=pod +Returns the concatenated CC list for the flagtype, as a single string. -=over +=item C<target_type> + +Returns whether the flagtype applies to bugs or attachments. + +=item C<is_active> + +Returns whether the flagtype is active or disabled. Flags being +in a disabled flagtype are not deleted. It only prevents you from +adding new flags to it. + +=item C<is_requestable> + +Returns whether you can request for the given flagtype +(i.e. whether the '?' flag is available or not). + +=item C<is_requesteeble> -=item C<get_inclusions($id)> +Returns whether you can ask someone specifically or not. -Someone please document this +=item C<is_multiplicable> + +Returns whether you can have more than one flag for the given +flagtype in a given bug/attachment. + +=item C<sortkey> + +Returns the sortkey of the flagtype. =back =cut -sub get_inclusions { - my ($id) = @_; - return get_clusions($id, "in"); -} +sub id { return $_[0]->{'id'}; } +sub name { return $_[0]->{'name'}; } +sub description { return $_[0]->{'description'}; } +sub cc_list { return $_[0]->{'cc_list'}; } +sub target_type { return $_[0]->{'target_type'} eq 'b' ? 'bug' : 'attachment'; } +sub is_active { return $_[0]->{'is_active'}; } +sub is_requestable { return $_[0]->{'is_requestable'}; } +sub is_requesteeble { return $_[0]->{'is_requesteeble'}; } +sub is_multiplicable { return $_[0]->{'is_multiplicable'}; } +sub sortkey { return $_[0]->{'sortkey'}; } + +############################### +#### Methods #### +############################### =pod =over -=item C<get_exclusions($id)> +=item C<grant_group> + +Returns the group (as a Bugzilla::Group object) in which a user +must be in order to grant or deny a request. + +=item C<request_group> + +Returns the group (as a Bugzilla::Group object) in which a user +must be in order to request or clear a flag. + +=item C<flag_count> + +Returns the number of flags belonging to the flagtype. -Someone please document this +=item C<inclusions> + +Return a hash of product/component IDs and names +explicitly associated with the flagtype. + +=item C<exclusions> + +Return a hash of product/component IDs and names +explicitly excluded from the flagtype. =back =cut -sub get_exclusions { - my ($id) = @_; - return get_clusions($id, "ex"); +sub grant_group { + my $self = shift; + + if (!defined $self->{'grant_group'} && $self->{'grant_group_id'}) { + $self->{'grant_group'} = new Bugzilla::Group($self->{'grant_group_id'}); + } + return $self->{'grant_group'}; +} + +sub request_group { + my $self = shift; + + if (!defined $self->{'request_group'} && $self->{'request_group_id'}) { + $self->{'request_group'} = new Bugzilla::Group($self->{'request_group_id'}); + } + return $self->{'request_group'}; } +sub flag_count { + my $self = shift; + + if (!defined $self->{'flag_count'}) { + $self->{'flag_count'} = + Bugzilla->dbh->selectrow_array('SELECT COUNT(*) FROM flags + WHERE type_id = ?', undef, $self->{'id'}); + } + return $self->{'flag_count'}; +} + +sub inclusions { + my $self = shift; + + $self->{'inclusions'} ||= get_clusions($self->id, 'in'); + return $self->{'inclusions'}; +} + +sub exclusions { + my $self = shift; + + $self->{'exclusions'} ||= get_clusions($self->id, 'ex'); + return $self->{'exclusions'}; +} + +###################################################################### +# Public Functions +###################################################################### + =pod +=head1 PUBLIC FUNCTIONS/METHODS + =over =item C<get_clusions($id, $type)> @@ -223,56 +308,28 @@ sub get_clusions { =over -=item C<match($criteria, $include_count)> +=item C<match($criteria)> Queries the database for flag types matching the given criteria -and returns the set of matching types. +and returns a list of matching flagtype objects. =back =cut sub match { - my ($criteria, $include_count) = @_; - - my @tables = @base_tables; - my @columns = @base_columns; + my ($criteria) = @_; my $dbh = Bugzilla->dbh; - # Include a count of the number of flags per type if requested. - if ($include_count) { - push(@columns, "COUNT(flags.id)"); - push(@tables, "LEFT OUTER JOIN flags ON flagtypes.id = flags.type_id"); - } - - # Generate the SQL WHERE criteria. - my @criteria = sqlify_criteria($criteria, \@tables); - - # Build the query, grouping the types if we are counting flags. - # DISTINCT is used in order to count flag types only once when - # they appear several times in the flaginclusions table. - my $select_clause = "SELECT DISTINCT " . join(", ", @columns); - my $from_clause = "FROM " . join(" ", @tables); - my $where_clause = "WHERE " . join(" AND ", @criteria); - - my $query = "$select_clause $from_clause $where_clause"; - $query .= " " . $dbh->sql_group_by('flagtypes.id', - join(', ', @base_columns[2..$#base_columns])) - if $include_count; - $query .= " ORDER BY flagtypes.sortkey, flagtypes.name"; - - # Execute the query and retrieve the results. - &::PushGlobalSQLState(); - &::SendSQL($query); - my @types; - while (&::MoreSQLData()) { - my @data = &::FetchSQLData(); - my $type = perlify_record(@data); - push(@types, $type); - } - &::PopGlobalSQLState(); + # Depending on the criteria, we may have to append additional tables. + my $tables = [DB_TABLE]; + my @criteria = sqlify_criteria($criteria, $tables); + $tables = join(' ', @$tables); + $criteria = join(' AND ', @criteria); + + my $flagtype_ids = $dbh->selectcol_arrayref("SELECT id FROM $tables WHERE $criteria"); - return \@types; + return Bugzilla::FlagType->new_from_list($flagtype_ids); } =pod @@ -289,202 +346,17 @@ Returns the total number of flag types matching the given criteria. sub count { my ($criteria) = @_; - - # Generate query components. - my @tables = @base_tables; - my @criteria = sqlify_criteria($criteria, \@tables); - - # Build the query. - my $select_clause = "SELECT COUNT(flagtypes.id)"; - my $from_clause = "FROM " . join(" ", @tables); - my $where_clause = "WHERE " . join(" AND ", @criteria); - my $query = "$select_clause $from_clause $where_clause"; - - # Execute the query and get the results. - &::PushGlobalSQLState(); - &::SendSQL($query); - my $count = &::FetchOneColumn(); - &::PopGlobalSQLState(); - - return $count; -} - -=pod - -=over - -=item C<validate($cgi, $bug_id, $attach_id)> - -Get a list of flag types to validate. Uses the "map" function -to extract flag type IDs from form field names by matching columns -whose name looks like "flag_type-nnn", where "nnn" is the ID, -and returning just the ID portion of matching field names. - -If the attachment is new, it has no ID yet and $attach_id is set -to -1 to force its check anyway. - -=back - -=cut - -sub validate { - my ($cgi, $bug_id, $attach_id) = @_; - - my $user = Bugzilla->user; my $dbh = Bugzilla->dbh; - my @ids = map(/^flag_type-(\d+)$/ ? $1 : (), $cgi->param()); - - return unless scalar(@ids); - - # No flag reference should exist when changing several bugs at once. - ThrowCodeError("flags_not_available", { type => 'b' }) unless $bug_id; - - # We don't check that these flag types are valid for - # this bug/attachment. This check will be done later when - # processing new flags, see Flag::FormToNewFlags(). - - foreach my $id (@ids) { - my $status = $cgi->param("flag_type-$id"); - my @requestees = $cgi->param("requestee_type-$id"); - - # Don't bother validating types the user didn't touch. - next if $status eq "X"; - - # Make sure the flag type exists. - my $flag_type = get($id); - $flag_type - || ThrowCodeError("flag_type_nonexistent", { id => $id }); - - # Make sure the flag type is active. - $flag_type->{'is_active'} - || ThrowCodeError('flag_type_inactive', {'type' => $flag_type->{'name'}}); - - # Make sure the value of the field is a valid status. - grep($status eq $_, qw(X + - ?)) - || ThrowCodeError("flag_status_invalid", - { id => $id , status => $status }); - - # Make sure the user didn't request the flag unless it's requestable. - if ($status eq '?' && !$flag_type->{is_requestable}) { - ThrowCodeError("flag_status_invalid", - { id => $id , status => $status }); - } - - # Make sure the user didn't specify a requestee unless the flag - # is specifically requestable. - if ($status eq '?' - && !$flag_type->{is_requesteeble} - && scalar(@requestees) > 0) - { - ThrowCodeError("flag_requestee_disabled", { type => $flag_type }); - } - - # Make sure the user didn't enter multiple requestees for a flag - # that can't be requested from more than one person at a time. - if ($status eq '?' - && !$flag_type->{is_multiplicable} - && scalar(@requestees) > 1) - { - ThrowUserError("flag_not_multiplicable", { type => $flag_type }); - } - - # Make sure the requestees are authorized to access the bug - # (and attachment, if this installation is using the "insider group" - # feature and the attachment is marked private). - if ($status eq '?' && $flag_type->{is_requesteeble}) { - foreach my $login (@requestees) { - # We know the requestee exists because we ran - # Bugzilla::User::match_field before getting here. - my $requestee = Bugzilla::User->new_from_login($login); - - # Throw an error if the user can't see the bug. - if (!$requestee->can_see_bug($bug_id)) { - ThrowUserError("flag_requestee_unauthorized", - { flag_type => $flag_type, - requestee => $requestee, - bug_id => $bug_id, - attach_id => $attach_id }); - } - - # Throw an error if the target is a private attachment and - # the requestee isn't in the group of insiders who can see it. - if ($attach_id - && Param("insidergroup") - && $cgi->param('isprivate') - && !$requestee->in_group(Param("insidergroup"))) - { - ThrowUserError("flag_requestee_unauthorized_attachment", - { flag_type => $flag_type, - requestee => $requestee, - bug_id => $bug_id, - attach_id => $attach_id }); - } - } - } - - # Make sure the user is authorized to modify flags, see bug 180879 - # - User in the $grant_gid group can set flags, including "+" and "-" - next if (!$flag_type->{grant_gid} - || $user->in_group(&::GroupIdToName($flag_type->{grant_gid}))); - - # - User in the $request_gid group can request flags - next if ($status eq '?' - && (!$flag_type->{request_gid} - || $user->in_group(&::GroupIdToName($flag_type->{request_gid})))); - - # - Any other flag modification is denied - ThrowUserError("flag_update_denied", - { name => $flag_type->{name}, - status => $status, - old_status => "X" }); - } -} - -=pod - -=over - -=item C<normalize(@ids)> + # Depending on the criteria, we may have to append additional tables. + my $tables = [DB_TABLE]; + my @criteria = sqlify_criteria($criteria, $tables); + $tables = join(' ', @$tables); + $criteria = join(' AND ', @criteria); -Given a list of flag types, checks its flags to make sure they should -still exist after a change to the inclusions/exclusions lists. - -=back - -=cut - -sub normalize { - # A list of IDs of flag types to normalize. - my (@ids) = @_; - - my $ids = join(", ", @ids); - - # Check for flags whose product/component is no longer included. - &::SendSQL(" - SELECT flags.id - FROM (flags INNER JOIN bugs ON flags.bug_id = bugs.bug_id) - LEFT OUTER JOIN flaginclusions AS i - ON (flags.type_id = i.type_id - AND (bugs.product_id = i.product_id OR i.product_id IS NULL) - AND (bugs.component_id = i.component_id OR i.component_id IS NULL)) - WHERE flags.type_id IN ($ids) - AND flags.is_active = 1 - AND i.type_id IS NULL - "); - Bugzilla::Flag::clear(&::FetchOneColumn()) while &::MoreSQLData(); - - &::SendSQL(" - SELECT flags.id - FROM flags, bugs, flagexclusions AS e - WHERE flags.type_id IN ($ids) - AND flags.bug_id = bugs.bug_id - AND flags.type_id = e.type_id - AND flags.is_active = 1 - AND (bugs.product_id = e.product_id OR e.product_id IS NULL) - AND (bugs.component_id = e.component_id OR e.component_id IS NULL) - "); - Bugzilla::Flag::clear(&::FetchOneColumn()) while &::MoreSQLData(); + my $count = $dbh->selectrow_array("SELECT COUNT(flagtypes.id) + FROM $tables WHERE $criteria"); + return $count; } ###################################################################### @@ -510,6 +382,7 @@ by the query. sub sqlify_criteria { my ($criteria, $tables) = @_; + my $dbh = Bugzilla->dbh; # the generated list of SQL criteria; "1=1" is a clever way of making sure # there's something in the list so calling code doesn't have to check list @@ -517,14 +390,16 @@ sub sqlify_criteria { my @criteria = ("1=1"); if ($criteria->{name}) { - push(@criteria, "flagtypes.name = " . &::SqlQuote($criteria->{name})); + my $name = $dbh->quote($criteria->{name}); + trick_taint($name); # Detaint data as we have quoted it. + push(@criteria, "flagtypes.name = $name"); } if ($criteria->{target_type}) { # The target type is stored in the database as a one-character string # ("a" for attachment and "b" for bug), but this function takes complete # names ("attachment" and "bug") for clarity, so we must convert them. - my $target_type = &::SqlQuote(substr($criteria->{target_type}, 0, 1)); - push(@criteria, "flagtypes.target_type = $target_type"); + my $target_type = $criteria->{target_type} eq 'bug'? 'b' : 'a'; + push(@criteria, "flagtypes.target_type = '$target_type'"); } if (exists($criteria->{is_active})) { my $is_active = $criteria->{is_active} ? "1" : "0"; @@ -562,40 +437,6 @@ sub sqlify_criteria { return @criteria; } -=pod - -=over - -=item C<perlify_record()> - -Converts data retrieved from the database into a Perl record. Depends on the -formatting as described in @base_columns. - -=back - -=cut - -sub perlify_record { - my $type = {}; - - $type->{'exists'} = $_[0]; - $type->{'id'} = $_[1]; - $type->{'name'} = $_[2]; - $type->{'description'} = $_[3]; - $type->{'cc_list'} = $_[4]; - $type->{'target_type'} = $_[5] eq "b" ? "bug" : "attachment"; - $type->{'sortkey'} = $_[6]; - $type->{'is_active'} = $_[7]; - $type->{'is_requestable'} = $_[8]; - $type->{'is_requesteeble'} = $_[9]; - $type->{'is_multiplicable'} = $_[10]; - $type->{'grant_gid'} = $_[11]; - $type->{'request_gid'} = $_[12]; - $type->{'flag_count'} = $_[13]; - - return $type; -} - 1; =end private @@ -616,6 +457,8 @@ sub perlify_record { =item Kevin Benton <kevin.benton@amd.com> +=item Frédéric Buclin <LpSolit@gmail.com> + =back =cut diff --git a/Bugzilla/Group.pm b/Bugzilla/Group.pm index b2a5fd5c6..c80d2333c 100644 --- a/Bugzilla/Group.pm +++ b/Bugzilla/Group.pm @@ -20,12 +20,15 @@ # Contributor(s): Joel Peshkin <bugreport@peshkin.net> # Erik Stambaugh <erik@dasbistro.com> # Tiago R. Mello <timello@async.com.br> +# Max Kanat-Alexander <mkanat@bugzilla.org> use strict; package Bugzilla::Group; -use Bugzilla::Config; +use base qw(Bugzilla::Object); + +use Bugzilla::Constants; use Bugzilla::Util; use Bugzilla::Error; @@ -38,69 +41,29 @@ use constant DB_COLUMNS => qw( groups.name groups.description groups.isbuggroup - groups.last_changed groups.userregexp groups.isactive ); -our $columns = join(", ", DB_COLUMNS); - -sub new { - my $invocant = shift; - my $class = ref($invocant) || $invocant; - my $self = {}; - bless($self, $class); - return $self->_init(@_); -} - -sub _init { - my $self = shift; - my ($param) = (@_); - my $dbh = Bugzilla->dbh; - - my $id = $param unless (ref $param eq 'HASH'); - my $group; +use constant DB_TABLE => 'groups'; - if (defined $id) { - detaint_natural($id) - || ThrowCodeError('param_must_be_numeric', - {function => 'Bugzilla::Group::_init'}); - - $group = $dbh->selectrow_hashref(qq{ - SELECT $columns FROM groups - WHERE id = ?}, undef, $id); - - } elsif (defined $param->{'name'}) { - - trick_taint($param->{'name'}); - - $group = $dbh->selectrow_hashref(qq{ - SELECT $columns FROM groups - WHERE name = ?}, undef, $param->{'name'}); - - } else { - ThrowCodeError('bad_arg', - {argument => 'param', - function => 'Bugzilla::Group::_init'}); - } +use constant LIST_ORDER => 'isbuggroup, name'; - return undef unless (defined $group); +use constant VALIDATORS => { + name => \&_check_name, + description => \&_check_description, + userregexp => \&_check_user_regexp, + isbuggroup => \&_check_is_bug_group, +}; - foreach my $field (keys %$group) { - $self->{$field} = $group->{$field}; - } - return $self; -} +use constant REQUIRED_CREATE_FIELDS => qw(name description isbuggroup); ############################### #### Accessors ###### ############################### -sub id { return $_[0]->{'id'}; } -sub name { return $_[0]->{'name'}; } sub description { return $_[0]->{'description'}; } sub is_bug_group { return $_[0]->{'isbuggroup'}; } -sub last_changed { return $_[0]->{'last_changed'}; } sub user_regexp { return $_[0]->{'userregexp'}; } sub is_active { return $_[0]->{'isactive'}; } @@ -113,16 +76,63 @@ sub is_active_bug_group { return $self->is_active && $self->is_bug_group; } +sub _rederive_regexp { + my ($self) = @_; + RederiveRegexp($self->user_regexp, $self->id); +} + +sub members_non_inherited { + my ($self) = @_; + return $self->{members_non_inherited} + if exists $self->{members_non_inherited}; + + my $member_ids = Bugzilla->dbh->selectcol_arrayref( + 'SELECT DISTINCT user_id FROM user_group_map + WHERE isbless = 0 AND group_id = ?', + undef, $self->id) || []; + require Bugzilla::User; + $self->{members_non_inherited} = Bugzilla::User->new_from_list($member_ids); + return $self->{members_non_inherited}; +} + ################################ ##### Module Subroutines ### ################################ +sub create { + my $class = shift; + my ($params) = @_; + my $dbh = Bugzilla->dbh; + + print get_text('install_group_create', { name => $params->{name} }) . "\n" + if Bugzilla->usage_mode == USAGE_MODE_CMDLINE; + + my $group = $class->SUPER::create(@_); + + # Since we created a new group, give the "admin" group all privileges + # initially. + my $admin = new Bugzilla::Group({name => 'admin'}); + # This function is also used to create the "admin" group itself, + # so there's a chance it won't exist yet. + if ($admin) { + my $sth = $dbh->prepare('INSERT INTO group_group_map + (member_id, grantor_id, grant_type) + VALUES (?, ?, ?)'); + $sth->execute($admin->id, $group->id, GROUP_MEMBERSHIP); + $sth->execute($admin->id, $group->id, GROUP_BLESS); + $sth->execute($admin->id, $group->id, GROUP_VISIBLE); + } + + $group->_rederive_regexp() if $group->user_regexp; + return $group; +} + sub ValidateGroupName { my ($name, @users) = (@_); my $dbh = Bugzilla->dbh; my $query = "SELECT id FROM groups " . "WHERE name = ?"; - if (Param('usevisibilitygroups')) { + if (Bugzilla->params->{'usevisibilitygroups'}) { my @visible = (-1); foreach my $user (@users) { $user && push @visible, @{$user->visible_groups_direct}; @@ -136,19 +146,65 @@ sub ValidateGroupName { return $ret; } -sub get_all_groups { +# This sub is not perldoc'ed because we expect it to go away and +# just become the _rederive_regexp private method. +sub RederiveRegexp { + my ($regexp, $gid) = @_; my $dbh = Bugzilla->dbh; + my $sth = $dbh->prepare("SELECT userid, login_name, group_id + FROM profiles + LEFT JOIN user_group_map + ON user_group_map.user_id = profiles.userid + AND group_id = ? + AND grant_type = ? + AND isbless = 0"); + my $sthadd = $dbh->prepare("INSERT INTO user_group_map + (user_id, group_id, grant_type, isbless) + VALUES (?, ?, ?, 0)"); + my $sthdel = $dbh->prepare("DELETE FROM user_group_map + WHERE user_id = ? AND group_id = ? + AND grant_type = ? and isbless = 0"); + $sth->execute($gid, GRANT_REGEXP); + while (my ($uid, $login, $present) = $sth->fetchrow_array()) { + if (($regexp =~ /\S+/) && ($login =~ m/$regexp/i)) + { + $sthadd->execute($uid, $gid, GRANT_REGEXP) unless $present; + } else { + $sthdel->execute($uid, $gid, GRANT_REGEXP) if $present; + } + } +} - my $group_ids = $dbh->selectcol_arrayref('SELECT id FROM groups - ORDER BY isbuggroup, name'); +############################### +### Validators ### +############################### - my @groups; - foreach my $gid (@$group_ids) { - push @groups, new Bugzilla::Group($gid); - } - return @groups; +sub _check_name { + my ($invocant, $name) = @_; + $name = trim($name); + $name || ThrowUserError("empty_group_name"); + my $exists = new Bugzilla::Group({name => $name }); + ThrowUserError("group_exists", { name => $name }) if $exists; + return $name; +} + +sub _check_description { + my ($invocant, $desc) = @_; + $desc = trim($desc); + $desc || ThrowUserError("empty_group_description"); + return $desc; } +sub _check_user_regexp { + my ($invocant, $regex) = @_; + $regex = trim($regex) || ''; + ThrowUserError("invalid_regexp") unless (eval {qr/$regex/}); + return $regex; +} + +sub _check_is_bug_group { + return $_[1] ? 1 : 0; +} 1; __END__ @@ -167,40 +223,29 @@ Bugzilla::Group - Bugzilla group class. my $id = $group->id; my $name = $group->name; my $description = $group->description; - my $last_changed = $group->last_changed; my $user_reg_exp = $group->user_reg_exp; my $is_active = $group->is_active; my $is_active_bug_group = $group->is_active_bug_group; my $group_id = Bugzilla::Group::ValidateGroupName('admin', @users); - my @groups = Bugzilla::get_all_groups(); + my @groups = Bugzilla::Group->get_all; =head1 DESCRIPTION -Group.pm represents a Bugzilla Group object. +Group.pm represents a Bugzilla Group object. It is an implementation +of L<Bugzilla::Object>, and thus has all the methods that L<Bugzilla::Object> +provides, in addition to any methods documented below. -=head1 METHODS +=head1 SUBROUTINES =over -=item C<new($param)> - - Description: The constructor is used to load an existing group - by passing a group id or a hash with the group name. +=item C<create> - Params: $param - If you pass an integer, the integer is the - group id from the database that we want to - read in. If you pass in a hash with 'name' - key, then the value of the name key is the - name of a product from the DB. - - Returns: A Bugzilla::Group object. - -=back - -=head1 SUBROUTINES - -=over +Note that in addition to what L<Bugzilla::Object/create($params)> +normally does, this function also makes the new group be inherited +by the C<admin> group. That is, the C<admin> group will automatically +be a member of this group. =item C<ValidateGroupName($name, @users)> @@ -214,15 +259,17 @@ Group.pm represents a Bugzilla Group object. Returns: It returns the group id if successful and undef otherwise. -=item C<get_all_groups()> +=back + +=head1 METHODS - Description: Returns all groups available, including both - system groups and bug groups. +=over - Params: none +=item C<members_non_inherited> - Returns: An array of group objects. +Returns an arrayref of L<Bugzilla::User> objects representing people who are +"directly" in this group, meaning that they're in it because they match +the group regular expression, or they have been actually added to the +group manually. =back - -=cut diff --git a/Bugzilla/Hook.pm b/Bugzilla/Hook.pm new file mode 100644 index 000000000..3e784bd0e --- /dev/null +++ b/Bugzilla/Hook.pm @@ -0,0 +1,190 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): Zach Lipton <zach@zachlipton.com> +# + +package Bugzilla::Hook; + +use Bugzilla::Constants; +use Bugzilla::Util; +use Bugzilla::Error; + +use strict; + +sub process { + my ($name, $args) = @_; + + # get a list of all extensions + my @extensions = glob(bz_locations()->{'extensionsdir'} . "/*"); + + # check each extension to see if it uses the hook + # if so, invoke the extension source file: + foreach my $extension (@extensions) { + # all of these variables come directly from code or directory names. + # If there's malicious data here, we have much bigger issues to + # worry about, so we can safely detaint them: + trick_taint($extension); + if (-e $extension.'/code/'.$name.'.pl') { + Bugzilla->hook_args($args); + do($extension.'/code/'.$name.'.pl'); + ThrowCodeError('extension_invalid', + { errstr => $@, name => $name, extension => $extension }) if $@; + } + } + +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Hook - Extendible extension hooks for Bugzilla code + +=head1 SYNOPSIS + + use Bugzilla::Hook; + + Bugzilla::Hook::process("hookname", { arg => $value, arg2 => $value2 }); + +=head1 DESCRIPTION + +Bugzilla allows extension modules to drop in and add routines at +arbitrary points in Bugzilla code. These points are refered to as +hooks. When a piece of standard Bugzilla code wants to allow an extension +to perform additional functions, it uses Bugzilla::Hook's L</process> +subroutine to invoke any extension code if installed. + +=head2 How Hooks Work + +When a hook named C<HOOK_NAME> is run, Bugzilla will attempt to invoke any +source files named F<extensions/*/code/HOOK_NAME.pl>. + +So, for example, if your extension is called "testopia", and you +want to have code run during the L</install-update_db> hook, you +would have a file called F<extensions/testopia/code/install-update_db.pl> +that contained perl code to run during that hook. + +=head2 Arguments Passed to Hooks + +Some L<hooks|/HOOKS> have params that are passed to them. + +These params are accessible through L<Bugzilla/hook_args>. +That returns a hashref. Very frequently, if you want your +hook to do anything, you have to modify these variables. + +=head1 SUBROUTINES + +=over + +=item C<process> + +=over + +=item B<Description> + +Invoke any code hooks with a matching name from any installed extensions. + +See C<customization.xml> in the Bugzilla Guide for more information on +Bugzilla's extension mechanism. + +=item B<Params> + +=over + +=item C<$name> - The name of the hook to invoke. + +=item C<$args> - A hashref. The named args to pass to the hook. +They will be accessible to the hook via L<Bugzilla/hook_args>. + +=back + +=item B<Returns> (nothing) + +=back + +=back + +=head1 HOOKS + +This describes what hooks exist in Bugzilla currently. + +=head2 enter_bug-entrydefaultvars + +This happens right before the template is loaded on enter_bug.cgi. + +Params: + +=over + +=item C<vars> - A hashref. The variables that will be passed into the template. + +=back + +=head2 install-requirements + +Because of the way Bugzilla installation works, there can't be a normal +hook during the time that F<checksetup.pl> checks what modules are +installed. (C<Bugzilla::Hook> needs to have those modules installed--it's +a chicken-and-egg problem.) + +So instead of the way hooks normally work, this hook just looks for two +subroutines (or constants, since all constants are just subroutines) in +your file, called C<OPTIONAL_MODULES> and C<REQUIRED_MODULES>, +which should return arrayrefs in the same format as C<OPTIONAL_MODULES> and +C<REQUIRED_MODULES> in L<Bugzilla::Install::Requirements>. + +These subroutines will be passed an arrayref that contains the current +Bugzilla requirements of the same type, in case you want to modify +Bugzilla's requirements somehow. (Probably the most common would be to +alter a version number or the "feature" element of C<OPTIONAL_MODULES>.) + +F<checksetup.pl> will add these requirements to its own. + +Please remember--if you put something in C<REQUIRED_MODULES>, then +F<checksetup.pl> B<cannot complete> unless the user has that module +installed! So use C<OPTIONAL_MODULES> whenever you can. + +=head2 install-update_db + +This happens at the very end of all the tables being updated +during an installation or upgrade. If you need to modify your custom +schema, do it here. No params are passed. + +=head2 db_schema-abstract_schema + +This allows you to add tables to Bugzilla. Note that we recommend that you +prefix the names of your tables with some word, so that they don't conflict +with any future Bugzilla tables. + +If you wish to add new I<columns> to existing Bugzilla tables, do that +in L</install-update_db>. + +Params: + +=over + +=item C<schema> - A hashref, in the format of +L<Bugzilla::DB::Schema/ABSTRACT_SCHEMA>. Add new hash keys to make new table +definitions. F<checksetup.pl> will automatically add these tables to the +database when run. + +=back diff --git a/Bugzilla/Install.pm b/Bugzilla/Install.pm new file mode 100644 index 000000000..36254a9c1 --- /dev/null +++ b/Bugzilla/Install.pm @@ -0,0 +1,428 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + +package Bugzilla::Install; + +# Functions in this this package can assume that the database +# has been set up, params are available, localconfig is +# available, and any module can be used. +# +# If you want to write an installation function that can't +# make those assumptions, then it should go into one of the +# packages under the Bugzilla::Install namespace. + +use strict; + +use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::Group; +use Bugzilla::Product; +use Bugzilla::User; +use Bugzilla::User::Setting; +use Bugzilla::Util qw(get_text); +use Bugzilla::Version; + +sub SETTINGS { + return { + # 2005-03-03 travis@sedsystems.ca -- Bug 41972 + display_quips => { options => ["on", "off"], default => "on" }, + # 2005-03-10 travis@sedsystems.ca -- Bug 199048 + comment_sort_order => { options => ["oldest_to_newest", "newest_to_oldest", + "newest_to_oldest_desc_first"], + default => "oldest_to_newest" }, + # 2005-05-12 bugzilla@glob.com.au -- Bug 63536 + post_bug_submit_action => { options => ["next_bug", "same_bug", "nothing"], + default => "next_bug" }, + # 2005-06-29 wurblzap@gmail.com -- Bug 257767 + csv_colsepchar => { options => [',',';'], default => ',' }, + # 2005-10-26 wurblzap@gmail.com -- Bug 291459 + zoom_textareas => { options => ["on", "off"], default => "on" }, + # 2005-10-21 LpSolit@gmail.com -- Bug 313020 + per_bug_queries => { options => ['on', 'off'], default => 'off' }, + # 2006-05-01 olav@bkor.dhs.org -- Bug 7710 + state_addselfcc => { options => ['always', 'never', 'cc_unless_role'], + default => 'cc_unless_role' }, + # 2006-08-04 wurblzap@gmail.com -- Bug 322693 + skin => { subclass => 'Skin', default => 'standard' }, + # 2006-12-10 LpSolit@gmail.com -- Bug 297186 + lang => { options => [split(/[\s,]+/, Bugzilla->params->{'languages'})], + default => Bugzilla->params->{'defaultlanguage'} } + } +}; + +use constant SYSTEM_GROUPS => ( + { + name => 'admin', + description => 'Administrators' + }, + { + name => 'tweakparams', + description => 'Can change Parameters' + }, + { + name => 'editusers', + description => 'Can edit or disable users' + }, + { + name => 'creategroups', + description => 'Can create and destroy groups' + }, + { + name => 'editclassifications', + description => 'Can create, destroy, and edit classifications' + }, + { + name => 'editcomponents', + description => 'Can create, destroy, and edit components' + }, + { + name => 'editkeywords', + description => 'Can create, destroy, and edit keywords' + }, + { + name => 'editbugs', + description => 'Can edit all bug fields', + userregexp => '.*' + }, + { + name => 'canconfirm', + description => 'Can confirm a bug or mark it a duplicate' + }, + { + name => 'bz_canusewhines', + description => 'User can configure whine reports for self' + }, + { + name => 'bz_sudoers', + description => 'Can perform actions as other users' + }, + # There are also other groups created in update_system_groups. +); + +use constant DEFAULT_CLASSIFICATION => { + name => 'Unclassified', + description => 'Not assigned to any classification' +}; + +use constant DEFAULT_PRODUCT => { + name => 'TestProduct', + description => 'This is a test product.' + . ' This ought to be blown away and replaced with real stuff in a' + . ' finished installation of bugzilla.' +}; + +use constant DEFAULT_COMPONENT => { + name => 'TestComponent', + description => 'This is a test component in the test product database.' + . ' This ought to be blown away and replaced with real stuff in' + . ' a finished installation of Bugzilla.' +}; + +sub update_settings { + my %settings = %{SETTINGS()}; + foreach my $setting (keys %settings) { + add_setting($setting, + $settings{$setting}->{options}, + $settings{$setting}->{default}, + $settings{$setting}->{subclass}); + } +} + +sub update_system_groups { + my $dbh = Bugzilla->dbh; + + # Create most of the system groups + foreach my $definition (SYSTEM_GROUPS) { + my $exists = new Bugzilla::Group({ name => $definition->{name} }); + $definition->{isbuggroup} = 0; + Bugzilla::Group->create($definition) unless $exists; + } + + # Certain groups need something done after they are created. We do + # that here. + + # Make sure people who can whine at others can also whine. + if (!new Bugzilla::Group({name => 'bz_canusewhineatothers'})) { + my $whineatothers = Bugzilla::Group->create({ + name => 'bz_canusewhineatothers', + description => 'Can configure whine reports for other users', + isbuggroup => 0 }); + my $whine = new Bugzilla::Group({ name => 'bz_canusewhines' }); + + $dbh->do('INSERT INTO group_group_map (grantor_id, member_id) + VALUES (?,?)', undef, $whine->id, $whineatothers->id); + } + + # Make sure sudoers are automatically protected from being sudoed. + if (!new Bugzilla::Group({name => 'bz_sudo_protect'})) { + my $sudo_protect = Bugzilla::Group->create({ + name => 'bz_sudo_protect', + description => 'Can not be impersonated by other users', + isbuggroup => 0 }); + my $sudo = new Bugzilla::Group({ name => 'bz_sudoers' }); + $dbh->do('INSERT INTO group_group_map (grantor_id, member_id) + VALUES (?,?)', undef, $sudo_protect->id, $sudo->id); + } + + # Re-evaluate all regexps, to keep them up-to-date. + my $sth = $dbh->prepare( + "SELECT profiles.userid, profiles.login_name, groups.id, + groups.userregexp, user_group_map.group_id + FROM (profiles CROSS JOIN groups) + LEFT JOIN user_group_map + ON user_group_map.user_id = profiles.userid + AND user_group_map.group_id = groups.id + AND user_group_map.grant_type = ? + WHERE userregexp != '' OR user_group_map.group_id IS NOT NULL"); + + my $sth_add = $dbh->prepare( + "INSERT INTO user_group_map (user_id, group_id, isbless, grant_type) + VALUES (?, ?, 0, " . GRANT_REGEXP . ")"); + + my $sth_del = $dbh->prepare( + "DELETE FROM user_group_map + WHERE user_id = ? AND group_id = ? AND isbless = 0 + AND grant_type = " . GRANT_REGEXP); + + $sth->execute(GRANT_REGEXP); + while (my ($uid, $login, $gid, $rexp, $present) = $sth->fetchrow_array()) { + if ($login =~ m/$rexp/i) { + $sth_add->execute($uid, $gid) unless $present; + } else { + $sth_del->execute($uid, $gid) if $present; + } + } + +} + +# This function should be called only after creating the admin user. +sub create_default_product { + my $dbh = Bugzilla->dbh; + + # Make the default Classification if it doesn't already exist. + if (!$dbh->selectrow_array('SELECT 1 FROM classifications')) { + my $class = DEFAULT_CLASSIFICATION; + print get_text('install_default_classification', + { name => $class->{name} }) . "\n"; + $dbh->do('INSERT INTO classifications (name, description) + VALUES (?, ?)', + undef, $class->{name}, $class->{description}); + } + + # And same for the default product/component. + if (!$dbh->selectrow_array('SELECT 1 FROM products')) { + my $default_prod = DEFAULT_PRODUCT; + print get_text('install_default_product', + { name => $default_prod->{name} }) . "\n"; + + $dbh->do(q{INSERT INTO products (name, description) + VALUES (?,?)}, + undef, $default_prod->{name}, $default_prod->{description}); + + my $product = new Bugzilla::Product({name => $default_prod->{name}}); + + # The default version. + Bugzilla::Version::create(Bugzilla::Version::DEFAULT_VERSION, $product); + + # And we automatically insert the default milestone. + $dbh->do(q{INSERT INTO milestones (product_id, value, sortkey) + SELECT id, defaultmilestone, 0 + FROM products}); + + # Get the user who will be the owner of the Product. + # We pick the admin with the lowest id, or we insert + # an invalid "0" into the database, just so that we can + # create the component. + my $admin_group = new Bugzilla::Group({name => 'admin'}); + my ($admin_id) = $dbh->selectrow_array( + 'SELECT user_id FROM user_group_map WHERE group_id = ? + ORDER BY user_id ' . $dbh->sql_limit(1), + undef, $admin_group->id) || 0; + + my $default_comp = DEFAULT_COMPONENT; + + $dbh->do("INSERT INTO components (name, product_id, description, + initialowner) + VALUES (?, ?, ?, ?)", undef, $default_comp->{name}, + $product->id, $default_comp->{description}, $admin_id); + } + +} + +sub create_admin { + my ($params) = @_; + my $dbh = Bugzilla->dbh; + my $template = Bugzilla->template; + + my $admin_group = new Bugzilla::Group({ name => 'admin' }); + my $admin_inheritors = + Bugzilla::User->flatten_group_membership($admin_group->id); + my $admin_group_ids = join(',', @$admin_inheritors); + + my ($admin_count) = $dbh->selectrow_array( + "SELECT COUNT(*) FROM user_group_map + WHERE group_id IN ($admin_group_ids)"); + + return if $admin_count; + + my %answer = %{Bugzilla->installation_answers}; + my $login = $answer{'ADMIN_EMAIL'}; + my $password = $answer{'ADMIN_PASSWORD'}; + my $full_name = $answer{'ADMIN_REALNAME'}; + + if (!$login || !$password || !$full_name) { + print "\n" . get_text('install_admin_setup') . "\n\n"; + } + + while (!$login) { + print get_text('install_admin_get_email') . ' '; + $login = <STDIN>; + chomp $login; + eval { Bugzilla::User->check_login_name_for_creation($login); }; + if ($@) { + print $@ . "\n"; + undef $login; + } + } + + while (!defined $full_name) { + print get_text('install_admin_get_name') . ' '; + $full_name = <STDIN>; + chomp($full_name); + } + + while (!$password) { + # trap a few interrupts so we can fix the echo if we get aborted. + local $SIG{HUP} = \&_create_admin_exit; + local $SIG{INT} = \&_create_admin_exit; + local $SIG{QUIT} = \&_create_admin_exit; + local $SIG{TERM} = \&_create_admin_exit; + + system("stty","-echo") unless ON_WINDOWS; # disable input echoing + + print get_text('install_admin_get_password') . ' '; + $password = <STDIN>; + chomp $password; + print "\n", get_text('install_admin_get_password2') . ' '; + my $pass2 = <STDIN>; + chomp $pass2; + eval { validate_password($password, $pass2); }; + if ($@) { + print "\n$@\n"; + undef $password; + } + system("stty","echo") unless ON_WINDOWS; + } + + my $admin = Bugzilla::User->create({ login_name => $login, + realname => $full_name, + cryptpassword => $password }); + make_admin($admin); +} + +sub make_admin { + my ($user) = @_; + my $dbh = Bugzilla->dbh; + + $user = ref($user) ? $user + : new Bugzilla::User(login_to_id($user, THROW_ERROR)); + + my $admin_group = new Bugzilla::Group({ name => 'admin' }); + + # Admins get explicit membership and bless capability for the admin group + $dbh->selectrow_array("SELECT id FROM groups WHERE name = 'admin'"); + + my $group_insert = $dbh->prepare( + 'INSERT INTO user_group_map (user_id, group_id, isbless, grant_type) + VALUES (?, ?, ?, ?)'); + # These are run in an eval so that we can ignore the error of somebody + # already being granted these things. + eval { + $group_insert->execute($user->id, $admin_group->id, 0, GRANT_DIRECT); + }; + eval { + $group_insert->execute($user->id, $admin_group->id, 1, GRANT_DIRECT); + }; + + # Admins should also have editusers directly, even though they'll usually + # inherit it. People could have changed their inheritance structure. + my $editusers = new Bugzilla::Group({ name => 'editusers' }); + eval { + $group_insert->execute($user->id, $editusers->id, 0, GRANT_DIRECT); + }; + + print "\n", get_text('install_admin_created', { user => $user }), "\n"; +} + +# This is just in case we get interrupted while getting the admin's password. +sub _create_admin_exit { + # re-enable input echoing + system("stty","echo") unless ON_WINDOWS; + exit 1; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Install - Functions and variables having to do with + installation. + +=head1 SYNOPSIS + + use Bugzilla::Install; + Bugzilla::Install::update_settings(); + +=head1 DESCRIPTION + +This module is used primarily by L<checksetup.pl> during installation. +This module contains functions that deal with general installation +issues after the database is completely set up and configured. + +=head1 CONSTANTS + +=over + +=item C<SETTINGS> + +Contains information about Settings, used by L</update_settings()>. + +=back + +=head1 SUBROUTINES + +=over + +=item C<update_settings()> + +Description: Adds and updates Settings for users. + +Params: none + +Returns: nothing. + +=item C<create_default_product()> + +Description: Creates the default product and classification if + they don't exist. + +Params: none + +Returns: nothing + +=back diff --git a/Bugzilla/Install/CVS/Entries b/Bugzilla/Install/CVS/Entries new file mode 100644 index 000000000..7ebfcfb46 --- /dev/null +++ b/Bugzilla/Install/CVS/Entries @@ -0,0 +1,5 @@ +/DB.pm/1.26.2.2/Thu Apr 19 13:01:04 2007//TBUGZILLA-3_0 +/Filesystem.pm/1.18/Sat Dec 9 11:58:14 2006//TBUGZILLA-3_0 +/Localconfig.pm/1.8/Sat Dec 9 11:51:35 2006//TBUGZILLA-3_0 +/Requirements.pm/1.29/Tue Feb 13 00:19:00 2007//TBUGZILLA-3_0 +D diff --git a/Bugzilla/Install/CVS/Repository b/Bugzilla/Install/CVS/Repository new file mode 100644 index 000000000..b6a6b1823 --- /dev/null +++ b/Bugzilla/Install/CVS/Repository @@ -0,0 +1 @@ +mozilla/webtools/bugzilla/Bugzilla/Install diff --git a/Bugzilla/Install/CVS/Root b/Bugzilla/Install/CVS/Root new file mode 100644 index 000000000..cdb6f4a07 --- /dev/null +++ b/Bugzilla/Install/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot diff --git a/Bugzilla/Install/CVS/Tag b/Bugzilla/Install/CVS/Tag new file mode 100644 index 000000000..efdc1ff3e --- /dev/null +++ b/Bugzilla/Install/CVS/Tag @@ -0,0 +1 @@ +NBUGZILLA-3_0 diff --git a/Bugzilla/Install/DB.pm b/Bugzilla/Install/DB.pm new file mode 100644 index 000000000..df8faa094 --- /dev/null +++ b/Bugzilla/Install/DB.pm @@ -0,0 +1,2848 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> +# Noel Cragg <noel@red-bean.com> + +package Bugzilla::Install::DB; + +# NOTE: This package may "use" any modules that it likes, +# localconfig is available, and params are up to date. + +use strict; + +use Bugzilla::Bug qw(is_open_state); +use Bugzilla::Constants; +use Bugzilla::Hook; +use Bugzilla::Util; +use Bugzilla::Series; + +use Date::Parse; +use Date::Format; +use IO::File; + +use base qw(Exporter); +our @EXPORT_OK = qw( + indicate_progress +); + +sub indicate_progress { + my ($params) = @_; + my $current = $params->{current}; + my $total = $params->{total}; + my $every = $params->{every} || 1; + + print "." if !($current % $every); + if ($current % ($every * 60) == 0) { + print "$current/$total (" . int($current * 100 / $total) . "%)\n"; + } +} + +# NOTE: This is NOT the function for general table updates. See +# update_table_definitions for that. This is only for the fielddefs table. +sub update_fielddefs_definition { + my $dbh = Bugzilla->dbh; + + # 2005-02-21 - LpSolit@gmail.com - Bug 279910 + # qacontact_accessible and assignee_accessible field names no longer exist + # in the 'bugs' table. Their corresponding entries in the 'bugs_activity' + # table should therefore be marked as obsolete, meaning that they cannot + # be used anymore when querying the database - they are not deleted in + # order to keep track of these fields in the activity table. + if (!$dbh->bz_column_info('fielddefs', 'obsolete')) { + $dbh->bz_add_column('fielddefs', 'obsolete', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); + print "Marking qacontact_accessible and assignee_accessible as", + " obsolete fields...\n"; + $dbh->do("UPDATE fielddefs SET obsolete = 1 + WHERE name = 'qacontact_accessible' + OR name = 'assignee_accessible'"); + } + + # 2005-08-10 Myk Melez <myk@mozilla.org> bug 287325 + # Record each field's type and whether or not it's a custom field, + # in fielddefs. + $dbh->bz_add_column('fielddefs', 'type', + {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0}); + $dbh->bz_add_column('fielddefs', 'custom', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); + + $dbh->bz_add_column('fielddefs', 'enter_bug', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); + + # Change the name of the fieldid column to id, so that fielddefs + # can use Bugzilla::Object easily. We have to do this up here, because + # otherwise adding these field definitions will fail. + $dbh->bz_rename_column('fielddefs', 'fieldid', 'id'); + + # If the largest fielddefs sortkey is less than 100, then + # we're using the old sorting system, and we should convert + # it to the new one before adding any new definitions. + if (!$dbh->selectrow_arrayref( + 'SELECT COUNT(id) FROM fielddefs WHERE sortkey >= 100')) + { + print "Updating the sortkeys for the fielddefs table...\n"; + my $field_ids = $dbh->selectcol_arrayref( + 'SELECT id FROM fielddefs ORDER BY sortkey'); + my $sortkey = 100; + foreach my $field_id (@$field_ids) { + $dbh->do('UPDATE fielddefs SET sortkey = ? WHERE id = ?', + undef, $sortkey, $field_id); + $sortkey += 100; + } + } + + # Remember, this is not the function for adding general table changes. + # That is below. Add new changes to the fielddefs table above this + # comment. +} + +# Small changes can be put directly into this function. +# However, larger changes (more than three or four lines) should +# go into their own private subroutine, and you should call that +# subroutine from this function. That keeps this function readable. +# +# This function runs in historical order--from upgrades that older +# installations need, to upgrades that newer installations need. +# The order of items inside this function should only be changed if +# absolutely necessary. +# +# The subroutines should have long, descriptive names, so that you +# can easily see what is being done, just by reading this function. +# +# This function is mostly self-documenting. If you're curious about +# what each of the added/removed columns does, you should see the schema +# docs at: +# http://www.ravenbrook.com/project/p4dti/tool/cgi/bugzilla-schema/ +# +# When you add a change, you should only add a comment if you want +# to describe why the change was made. You don't need to describe +# the purpose of a column. +# +sub update_table_definitions { + my $dbh = Bugzilla->dbh; + _update_pre_checksetup_bugzillas(); + + $dbh->bz_add_column('attachments', 'submitter_id', + {TYPE => 'INT3', NOTNULL => 1}, 0); + + $dbh->bz_rename_column('bugs_activity', 'when', 'bug_when'); + + _add_bug_vote_cache(); + _update_product_name_definition(); + _add_bug_keyword_cache(); + + $dbh->bz_add_column('profiles', 'disabledtext', + {TYPE => 'MEDIUMTEXT', NOTNULL => 1}, ''); + + _populate_longdescs(); + _update_bugs_activity_field_to_fieldid(); + + if (!$dbh->bz_column_info('bugs', 'lastdiffed')) { + $dbh->bz_add_column('bugs', 'lastdiffed', {TYPE =>'DATETIME'}); + $dbh->do('UPDATE bugs SET lastdiffed = NOW()'); + } + + _add_unique_login_name_index_to_profiles(); + + $dbh->bz_add_column('profiles', 'mybugslink', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'}); + + _update_component_user_fields_to_ids(); + + $dbh->bz_add_column('bugs', 'everconfirmed', + {TYPE => 'BOOLEAN', NOTNULL => 1}, 1); + + $dbh->bz_add_column('products', 'maxvotesperbug', + {TYPE => 'INT2', NOTNULL => 1, DEFAULT => '10000'}); + $dbh->bz_add_column('products', 'votestoconfirm', + {TYPE => 'INT2', NOTNULL => 1}, 0); + + _populate_milestones_table(); + + # 2000-03-22 Changed the default value for target_milestone to be "---" + # (which is still not quite correct, but much better than what it was + # doing), and made the size of the value field in the milestones table match + # the size of the target_milestone field in the bugs table. + $dbh->bz_alter_column('bugs', 'target_milestone', + {TYPE => 'varchar(20)', NOTNULL => 1, DEFAULT => "'---'"}); + $dbh->bz_alter_column('milestones', 'value', + {TYPE => 'varchar(20)', NOTNULL => 1}); + + _add_products_defaultmilestone(); + + # 2000-03-24 Added unique indexes into the cc and keyword tables. This + # prevents certain database inconsistencies, and, moreover, is required for + # new generalized list code to work. + if (!$dbh->bz_index_info('cc', 'cc_bug_id_idx') + || !$dbh->bz_index_info('cc', 'cc_bug_id_idx')->{TYPE}) + { + $dbh->bz_drop_index('cc', 'cc_bug_id_idx'); + $dbh->bz_add_index('cc', 'cc_bug_id_idx', + {TYPE => 'UNIQUE', FIELDS => [qw(bug_id who)]}); + } + if (!$dbh->bz_index_info('keywords', 'keywords_bug_id_idx') + || !$dbh->bz_index_info('keywords', 'keywords_bug_id_idx')->{TYPE}) + { + $dbh->bz_drop_index('keywords', 'keywords_bug_id_idx'); + $dbh->bz_add_index('keywords', 'keywords_bug_id_idx', + {TYPE => 'UNIQUE', FIELDS => [qw(bug_id keywordid)]}); + } + + _copy_from_comments_to_longdescs(); + _populate_duplicates_table(); + + if (!$dbh->bz_column_info('email_setting', 'user_id')) { + $dbh->bz_add_column('profiles', 'emailflags', {TYPE => 'MEDIUMTEXT'}); + } + + $dbh->bz_add_column('groups', 'isactive', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'}); + + $dbh->bz_add_column('attachments', 'isobsolete', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); + + $dbh->bz_drop_column("profiles", "emailnotification"); + $dbh->bz_drop_column("profiles", "newemailtech"); + + # 2003-11-19; chicks@chicks.net; bug 225973: fix field size to accommodate + # wider algorithms such as Blowfish. Note that this needs to be run + # before recrypting passwords in the following block. + $dbh->bz_alter_column('profiles', 'cryptpassword', + {TYPE => 'varchar(128)'}); + + _recrypt_plaintext_passwords(); + + # 2001-06-15 kiko@async.com.br - Change bug:version size to avoid + # truncates re http://bugzilla.mozilla.org/show_bug.cgi?id=9352 + $dbh->bz_alter_column('bugs', 'version', + {TYPE => 'varchar(64)', NOTNULL => 1}); + + _update_bugs_activity_to_only_record_changes(); + + # bug 90933: Make disabledtext NOT NULL + if (!$dbh->bz_column_info('profiles', 'disabledtext')->{NOTNULL}) { + $dbh->bz_alter_column("profiles", "disabledtext", + {TYPE => 'MEDIUMTEXT', NOTNULL => 1}, ''); + } + + $dbh->bz_add_column("bugs", "reporter_accessible", + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'}); + $dbh->bz_add_column("bugs", "cclist_accessible", + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'}); + + $dbh->bz_add_column("bugs_activity", "attach_id", {TYPE => 'INT3'}); + + _delete_logincookies_cryptpassword_and_handle_invalid_cookies(); + + # qacontact/assignee should always be able to see bugs: bug 97471 + $dbh->bz_drop_column("bugs", "qacontact_accessible"); + $dbh->bz_drop_column("bugs", "assignee_accessible"); + + # 2002-02-20 jeff.hedlund@matrixsi.com - bug 24789 time tracking + $dbh->bz_add_column("longdescs", "work_time", + {TYPE => 'decimal(5,2)', NOTNULL => 1, DEFAULT => '0'}); + $dbh->bz_add_column("bugs", "estimated_time", + {TYPE => 'decimal(5,2)', NOTNULL => 1, DEFAULT => '0'}); + $dbh->bz_add_column("bugs", "remaining_time", + {TYPE => 'decimal(5,2)', NOTNULL => 1, DEFAULT => '0'}); + $dbh->bz_add_column("bugs", "deadline", {TYPE => 'DATETIME'}); + + _use_ip_instead_of_hostname_in_logincookies(); + + $dbh->bz_add_column('longdescs', 'isprivate', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); + $dbh->bz_add_column('attachments', 'isprivate', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); + + $dbh->bz_add_column("bugs", "alias", {TYPE => "varchar(20)"}); + $dbh->bz_add_index('bugs', 'bugs_alias_idx', + {TYPE => 'UNIQUE', FIELDS => [qw(alias)]}); + + _move_quips_into_db(); + + $dbh->bz_drop_column("namedqueries", "watchfordiffs"); + + _use_ids_for_products_and_components(); + _convert_groups_system_from_groupset(); + _convert_attachment_statuses_to_flags(); + _remove_spaces_and_commas_from_flagtypes(); + _setup_usebuggroups_backward_compatibility(); + _remove_user_series_map(); + + # 2006-08-03 remi_zara@mac.com bug 346241, make series.creator nullable + # This must happen before calling _copy_old_charts_into_database(). + if ($dbh->bz_column_info('series', 'creator')->{NOTNULL}) { + $dbh->bz_alter_column('series', 'creator', {TYPE => 'INT3'}); + $dbh->do("UPDATE series SET creator = NULL WHERE creator = 0"); + } + + _copy_old_charts_into_database(); + + _add_user_group_map_grant_type(); + _add_group_group_map_grant_type(); + + $dbh->bz_add_column("profiles", "extern_id", {TYPE => 'varchar(64)'}); + + $dbh->bz_add_column('flagtypes', 'grant_group_id', {TYPE => 'INT3'}); + $dbh->bz_add_column('flagtypes', 'request_group_id', {TYPE => 'INT3'}); + + # mailto is no longer just userids + $dbh->bz_rename_column('whine_schedules', 'mailto_userid', 'mailto'); + $dbh->bz_add_column('whine_schedules', 'mailto_type', + {TYPE => 'INT2', NOTNULL => 1, DEFAULT => '0'}); + + _add_longdescs_already_wrapped(); + + # Moved enum types to separate tables so we need change the old enum + # types to standard varchars in the bugs table. + $dbh->bz_alter_column('bugs', 'bug_status', + {TYPE => 'varchar(64)', NOTNULL => 1}); + # 2005-03-23 Tomas.Kopal@altap.cz - add default value to resolution, + # bug 286695 + $dbh->bz_alter_column('bugs', 'resolution', + {TYPE => 'varchar(64)', NOTNULL => 1, DEFAULT => "''"}); + $dbh->bz_alter_column('bugs', 'priority', + {TYPE => 'varchar(64)', NOTNULL => 1}); + $dbh->bz_alter_column('bugs', 'bug_severity', + {TYPE => 'varchar(64)', NOTNULL => 1}); + $dbh->bz_alter_column('bugs', 'rep_platform', + {TYPE => 'varchar(64)', NOTNULL => 1}, ''); + $dbh->bz_alter_column('bugs', 'op_sys', + {TYPE => 'varchar(64)', NOTNULL => 1}); + + # When migrating quips from the '$datadir/comments' file to the DB, + # the user ID should be NULL instead of 0 (which is an invalid user ID). + if ($dbh->bz_column_info('quips', 'userid')->{NOTNULL}) { + $dbh->bz_alter_column('quips', 'userid', {TYPE => 'INT3'}); + print "Changing owner to NULL for quips where the owner is", + " unknown...\n"; + $dbh->do('UPDATE quips SET userid = NULL WHERE userid = 0'); + } + + # Right now, we only create the "thetext" index on MySQL. + if ($dbh->isa('Bugzilla::DB::Mysql')) { + $dbh->bz_add_index('longdescs', 'longdescs_thetext_idx', + {TYPE => 'FULLTEXT', FIELDS => [qw(thetext)]}); + } + + _convert_attachments_filename_from_mediumtext(); + + $dbh->bz_add_column('quips', 'approved', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'}); + + # 2002-12-20 Bug 180870 - remove manual shadowdb replication code + $dbh->bz_drop_table("shadowlog"); + + _rename_votes_count_and_force_group_refresh(); + + # 2004/02/15 - Summaries shouldn't be null - see bug 220232 + if (!exists $dbh->bz_column_info('bugs', 'short_desc')->{NOTNULL}) { + $dbh->bz_alter_column('bugs', 'short_desc', + {TYPE => 'MEDIUMTEXT', NOTNULL => 1}, ''); + } + + $dbh->bz_add_column('products', 'classification_id', + {TYPE => 'INT2', NOTNULL => 1, DEFAULT => '1'}); + + _fix_group_with_empty_name(); + + $dbh->bz_add_index('bugs_activity', 'bugs_activity_who_idx', [qw(who)]); + + # Add defaults for some fields that should have them but didn't. + $dbh->bz_alter_column('bugs', 'status_whiteboard', + {TYPE => 'MEDIUMTEXT', NOTNULL => 1, DEFAULT => "''"}); + $dbh->bz_alter_column('bugs', 'keywords', + {TYPE => 'MEDIUMTEXT', NOTNULL => 1, DEFAULT => "''"}); + $dbh->bz_alter_column('bugs', 'votes', + {TYPE => 'INT3', NOTNULL => 1, DEFAULT => '0'}); + + $dbh->bz_alter_column('bugs', 'lastdiffed', {TYPE => 'DATETIME'}); + + # 2005-03-09 qa_contact should be NULL instead of 0, bug 285534 + if ($dbh->bz_column_info('bugs', 'qa_contact')->{NOTNULL}) { + $dbh->bz_alter_column('bugs', 'qa_contact', {TYPE => 'INT3'}); + $dbh->do("UPDATE bugs SET qa_contact = NULL WHERE qa_contact = 0"); + } + + # 2005-03-27 initialqacontact should be NULL instead of 0, bug 287483 + if ($dbh->bz_column_info('components', 'initialqacontact')->{NOTNULL}) { + $dbh->bz_alter_column('components', 'initialqacontact', + {TYPE => 'INT3'}); + $dbh->do("UPDATE components SET initialqacontact = NULL " . + "WHERE initialqacontact = 0"); + } + + _migrate_email_prefs_to_new_table(); + _initialize_dependency_tree_changes_email_pref(); + _change_all_mysql_booleans_to_tinyint(); + + # make classification_id field type be consistent with DB:Schema + $dbh->bz_alter_column('products', 'classification_id', + {TYPE => 'INT2', NOTNULL => 1, DEFAULT => '1'}); + + # initialowner was accidentally NULL when we checked-in Schema, + # when it really should be NOT NULL. + $dbh->bz_alter_column('components', 'initialowner', + {TYPE => 'INT3', NOTNULL => 1}, 0); + + # 2005-03-28 - bug 238800 - index flags.type_id for editflagtypes.cgi + $dbh->bz_add_index('flags', 'flags_type_id_idx', [qw(type_id)]); + + # For a short time, the flags_type_id_idx was misnamed in upgraded installs. + $dbh->bz_drop_index('flags', 'type_id'); + + # 2005-04-28 - LpSolit@gmail.com - Bug 7233: add an index to versions + $dbh->bz_alter_column('versions', 'value', + {TYPE => 'varchar(64)', NOTNULL => 1}); + _add_versions_product_id_index(); + + if (!exists $dbh->bz_column_info('milestones', 'sortkey')->{DEFAULT}) { + $dbh->bz_alter_column('milestones', 'sortkey', + {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0}); + } + + # 2005-06-14 - LpSolit@gmail.com - Bug 292544 + $dbh->bz_alter_column('bugs', 'creation_ts', {TYPE => 'DATETIME'}); + + _fix_whine_queries_title_and_op_sys_value(); + _fix_attachments_submitter_id_idx(); + _copy_attachments_thedata_to_attach_data(); + _fix_broken_all_closed_series(); + + # 2005-08-14 bugreport@peshkin.net -- Bug 304583 + # Get rid of leftover DERIVED group permissions + use constant GRANT_DERIVED => 1; + $dbh->do("DELETE FROM user_group_map WHERE grant_type = " . GRANT_DERIVED); + + # PUBLIC is a reserved word in Oracle. + $dbh->bz_rename_column('series', 'public', 'is_public'); + + # 2005-09-28 bugreport@peshkin.net Bug 149504 + $dbh->bz_add_column('attachments', 'isurl', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 0}); + + # 2005-10-21 LpSolit@gmail.com - Bug 313020 + $dbh->bz_add_column('namedqueries', 'query_type', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 0}); + + # 2005-11-04 LpSolit@gmail.com - Bug 305927 + $dbh->bz_alter_column('groups', 'userregexp', + {TYPE => 'TINYTEXT', NOTNULL => 1, DEFAULT => "''"}); + + # 2005-09-26 - olav@bkor.dhs.org - Bug 119524 + $dbh->bz_alter_column('logincookies', 'cookie', + {TYPE => 'varchar(16)', PRIMARYKEY => 1, NOTNULL => 1}); + + _clean_control_characters_from_short_desc(); + + # 2005-12-07 altlst@sonic.net -- Bug 225221 + $dbh->bz_add_column('longdescs', 'comment_id', + {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + + _stop_storing_inactive_flags(); + _change_short_desc_from_mediumtext_to_varchar(); + + # 2006-07-01 wurblzap@gmail.com -- Bug 69000 + $dbh->bz_add_column('namedqueries', 'id', + {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + _move_namedqueries_linkinfooter_to_its_own_table(); + + _add_classifications_sortkey(); + _move_data_nomail_into_db(); + + # The products table lacked sensible defaults. + $dbh->bz_alter_column('products', 'milestoneurl', + {TYPE => 'TINYTEXT', NOTNULL => 1, DEFAULT => "''"}); + $dbh->bz_alter_column('products', 'disallownew', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 0}); + $dbh->bz_alter_column('products', 'votesperuser', + {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0}); + $dbh->bz_alter_column('products', 'votestoconfirm', + {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0}); + + # 2006-08-04 LpSolit@gmail.com - Bug 305941 + $dbh->bz_drop_column('profiles', 'refreshed_when'); + $dbh->bz_drop_column('groups', 'last_changed'); + + # 2006-08-06 LpSolit@gmail.com - Bug 347521 + $dbh->bz_alter_column('flagtypes', 'id', + {TYPE => 'SMALLSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + + $dbh->bz_alter_column('keyworddefs', 'id', + {TYPE => 'SMALLSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + + # 2006-08-19 LpSolit@gmail.com - Bug 87795 + $dbh->bz_alter_column('tokens', 'userid', {TYPE => 'INT3'}); + + $dbh->bz_drop_index('bugs', 'bugs_short_desc_idx'); + + # The profiles table was missing some defaults. + $dbh->bz_alter_column('profiles', 'disabledtext', + {TYPE => 'MEDIUMTEXT', NOTNULL => 1, DEFAULT => "''"}); + $dbh->bz_alter_column('profiles', 'realname', + {TYPE => 'varchar(255)', NOTNULL => 1, DEFAULT => "''"}); + + _update_longdescs_who_index(); + + $dbh->bz_add_column('setting', 'subclass', {TYPE => 'varchar(32)'}); + + $dbh->bz_alter_column('longdescs', 'thetext', + { TYPE => 'MEDIUMTEXT', NOTNULL => 1 }, ''); + + # 2006-10-20 LpSolit@gmail.com - Bug 189627 + $dbh->bz_add_column('group_control_map', 'editcomponents', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); + $dbh->bz_add_column('group_control_map', 'editbugs', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); + $dbh->bz_add_column('group_control_map', 'canconfirm', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); + + # 2006-11-07 LpSolit@gmail.com - Bug 353656 + $dbh->bz_add_column('longdescs', 'type', + {TYPE => 'INT2', NOTNULL => 1, DEFAULT => '0'}); + $dbh->bz_add_column('longdescs', 'extra_data', {TYPE => 'varchar(255)'}); + + $dbh->bz_add_column('versions', 'id', + {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + $dbh->bz_add_column('milestones', 'id', + {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + + _fix_uppercase_custom_field_names(); + _fix_uppercase_index_names(); + + ################################################################ + # New --TABLE-- changes should go *** A B O V E *** this point # + ################################################################ + + Bugzilla::Hook::process('install-update_db'); +} + +# Subroutines should be ordered in the order that they are called. +# Thus, newer subroutines should be at the bottom. + +sub _update_pre_checksetup_bugzillas { + my $dbh = Bugzilla->dbh; + # really old fields that were added before checksetup.pl existed + # but aren't in very old bugzilla's (like 2.1) + # Steve Stock (sstock@iconnect-inc.com) + + $dbh->bz_add_column('bugs', 'target_milestone', + {TYPE => 'varchar(20)', NOTNULL => 1, DEFAULT => "'---'"}); + $dbh->bz_add_column('bugs', 'qa_contact', {TYPE => 'INT3'}); + $dbh->bz_add_column('bugs', 'status_whiteboard', + {TYPE => 'MEDIUMTEXT', NOTNULL => 1, DEFAULT => "''"}); + $dbh->bz_add_column('products', 'disallownew', + {TYPE => 'BOOLEAN', NOTNULL => 1}, 0); + $dbh->bz_add_column('products', 'milestoneurl', + {TYPE => 'TINYTEXT', NOTNULL => 1}, ''); + $dbh->bz_add_column('components', 'initialqacontact', + {TYPE => 'TINYTEXT'}); + $dbh->bz_add_column('components', 'description', + {TYPE => 'MEDIUMTEXT', NOTNULL => 1}, ''); +} + +sub _add_bug_vote_cache { + my $dbh = Bugzilla->dbh; + # 1999-10-11 Restructured voting database to add a cached value in each + # bug recording how many total votes that bug has. While I'm at it, + # I removed the unused "area" field from the bugs database. It is + # distressing to realize that the bugs table has reached the maximum + # number of indices allowed by MySQL (16), which may make future + # enhancements awkward. + # (P.S. All is not lost; it appears that the latest betas of MySQL + # support a new table format which will allow 32 indices.) + + $dbh->bz_drop_column('bugs', 'area'); + if (!$dbh->bz_column_info('bugs', 'votes')) { + $dbh->bz_add_column('bugs', 'votes', {TYPE => 'INT3', NOTNULL => 1, + DEFAULT => 0}); + $dbh->bz_add_index('bugs', 'bugs_votes_idx', [qw(votes)]); + } + $dbh->bz_add_column('products', 'votesperuser', + {TYPE => 'INT2', NOTNULL => 1}, 0); +} + +sub _update_product_name_definition { + my $dbh = Bugzilla->dbh; + # The product name used to be very different in various tables. + # + # It was varchar(16) in bugs + # tinytext in components + # tinytext in products + # tinytext in versions + # + # tinytext is equivalent to varchar(255), which is quite huge, so I change + # them all to varchar(64). + + # Only do this if these fields still exist - they're removed in + # a later change + if ($dbh->bz_column_info('products', 'product')) { + $dbh->bz_alter_column('bugs', 'product', + {TYPE => 'varchar(64)', NOTNULL => 1}); + $dbh->bz_alter_column('components', 'program', {TYPE => 'varchar(64)'}); + $dbh->bz_alter_column('products', 'product', {TYPE => 'varchar(64)'}); + $dbh->bz_alter_column('versions', 'program', + {TYPE => 'varchar(64)', NOTNULL => 1}); + } +} + +sub _add_bug_keyword_cache { + my $dbh = Bugzilla->dbh; + # 2000-01-16 Added a "keywords" field to the bugs table, which + # contains a string copy of the entries of the keywords table for this + # bug. This is so that I can easily sort and display a keywords + # column in bug lists. + + if (!$dbh->bz_column_info('bugs', 'keywords')) { + $dbh->bz_add_column('bugs', 'keywords', + {TYPE => 'MEDIUMTEXT', NOTNULL => 1, DEFAULT => "''"}); + + my @kwords; + print "Making sure 'keywords' field of table 'bugs' is empty...\n"; + $dbh->do("UPDATE bugs SET keywords = '' WHERE keywords != ''"); + print "Repopulating 'keywords' field of table 'bugs'...\n"; + my $sth = $dbh->prepare("SELECT keywords.bug_id, keyworddefs.name " . + "FROM keywords, keyworddefs " . + "WHERE keyworddefs.id = keywords.keywordid " . + "ORDER BY keywords.bug_id, keyworddefs.name"); + $sth->execute; + my @list; + my $bugid = 0; + my @row; + while (1) { + my ($b, $k) = ($sth->fetchrow_array()); + if (!defined $b || $b ne $bugid) { + if (@list) { + $dbh->do("UPDATE bugs SET keywords = " . + $dbh->quote(join(', ', @list)) . + " WHERE bug_id = $bugid"); + } + last if !$b; + $bugid = $b; + @list = (); + } + push(@list, $k); + } + } +} + +# A helper for the function below. +sub _write_one_longdesc { + my ($id, $who, $when, $buffer) = (@_); + my $dbh = Bugzilla->dbh; + $buffer = trim($buffer); + return if !$buffer; + $dbh->do("INSERT INTO longdescs (bug_id, who, bug_when, thetext) + VALUES (?,?,?,?)", undef, $id, $who, + time2str("%Y/%m/%d %H:%M:%S", $when), $buffer); +} + +sub _populate_longdescs { + my $dbh = Bugzilla->dbh; + # 2000-01-20 Added a new "longdescs" table, which is supposed to have + # all the long descriptions in it, replacing the old long_desc field + # in the bugs table. The below hideous code populates this new table + # with things from the old field, with ugly parsing and heuristics. + + if ($dbh->bz_column_info('bugs', 'long_desc')) { + my ($total) = $dbh->selectrow_array("SELECT COUNT(*) FROM bugs"); + + print "Populating new long_desc table. This is slow. There are", + " $total\nbugs to process; a line of dots will be printed", + " for each 50.\n\n"; + local $| = 1; + + $dbh->bz_lock_tables('bugs write', 'longdescs write', 'profiles write', + 'bz_schema WRITE'); + + $dbh->do('DELETE FROM longdescs'); + + my $sth = $dbh->prepare("SELECT bug_id, creation_ts, reporter, + long_desc FROM bugs ORDER BY bug_id"); + $sth->execute(); + my $count = 0; + while (my ($id, $createtime, $reporterid, $desc) = + $sth->fetchrow_array()) + { + $count++; + indicate_progress({ total => $total, current => $count }); + $desc =~ s/\r//g; + my $who = $reporterid; + my $when = str2time($createtime); + my $buffer = ""; + foreach my $line (split(/\n/, $desc)) { + $line =~ s/\s+$//g; # Trim trailing whitespace. + if ($line =~ /^------- Additional Comments From ([^\s]+)\s+(\d.+\d)\s+-------$/) + { + my $name = $1; + my $date = str2time($2); + # Oy, what a hack. The creation time is accurate to the + # second. But the long text only contains things accurate + # to the And so, if someone makes a comment within a + # minute of the original bug creation, then the comment can + # come *before* the bug creation. So, we add 59 seconds to + # the time of all comments, so that they are always + # considered to have happened at the *end* of the given + # minute, not the beginning. + $date += 59; + if ($date >= $when) { + _write_one_longdesc($id, $who, $when, $buffer); + $buffer = ""; + $when = $date; + my $s2 = $dbh->prepare("SELECT userid FROM profiles " . + "WHERE login_name = ?"); + $s2->execute($name); + ($who) = ($s2->fetchrow_array()); + + if (!$who) { + # This username doesn't exist. Maybe someone + # renamed him or something. Invent a new profile + # entry disabled, just to represent him. + $dbh->do("INSERT INTO profiles (login_name, + cryptpassword, disabledtext) + VALUES (?,?,?)", undef, $name, '*', + "Account created only to maintain" + . " database integrity"); + $who = $dbh->bz_last_key('profiles', 'userid'); + } + next; + } + } + $buffer .= $line . "\n"; + } + _write_one_longdesc($id, $who, $when, $buffer); + } # while loop + + print "\n\n"; + $dbh->bz_drop_column('bugs', 'long_desc'); + $dbh->bz_unlock_tables(); + } # main if +} + +sub _update_bugs_activity_field_to_fieldid { + my $dbh = Bugzilla->dbh; + + # 2000-01-18 Added a new table fielddefs that records information about the + # different fields we keep an activity log on. The bugs_activity table + # now has a pointer into that table instead of recording the name directly. + if ($dbh->bz_column_info('bugs_activity', 'field')) { + $dbh->bz_add_column('bugs_activity', 'fieldid', + {TYPE => 'INT3', NOTNULL => 1}, 0); + + $dbh->bz_add_index('bugs_activity', 'bugs_activity_fieldid_idx', + [qw(fieldid)]); + print "Populating new bugs_activity.fieldid field...\n"; + + $dbh->bz_lock_tables('bugs_activity WRITE', 'fielddefs WRITE'); + + + my $ids = $dbh->selectall_arrayref( + 'SELECT DISTINCT fielddefs.id, bugs_activity.field + FROM bugs_activity LEFT JOIN fielddefs + ON bugs_activity.field = fielddefs.name', {Slice=>{}}); + + foreach my $item (@$ids) { + my $id = $item->{id}; + my $field = $item->{field}; + # If the id is NULL + if (!$id) { + $dbh->do("INSERT INTO fielddefs (name, description) VALUES " . + "(?, ?)", undef, $field, $field); + $id = $dbh->bz_last_key('fielddefs', 'id'); + } + $dbh->do("UPDATE bugs_activity SET fieldid = ? WHERE field = ?", + undef, $id, $field); + } + $dbh->bz_unlock_tables(); + + $dbh->bz_drop_column('bugs_activity', 'field'); + } +} + +sub _add_unique_login_name_index_to_profiles { + my $dbh = Bugzilla->dbh; + + # 2000-01-22 The "login_name" field in the "profiles" table was not + # declared to be unique. Sure enough, somehow, I got 22 duplicated entries + # in my database. This code detects that, cleans up the duplicates, and + # then tweaks the table to declare the field to be unique. What a pain. + if (!$dbh->bz_index_info('profiles', 'profiles_login_name_idx') + || !$dbh->bz_index_info('profiles', 'profiles_login_name_idx')->{TYPE}) + { + print "Searching for duplicate entries in the profiles table...\n"; + while (1) { + # This code is weird in that it loops around and keeps doing this + # select again. That's because I'm paranoid about deleting entries + # out from under us in the profiles table. Things get weird if + # there are *three* or more entries for the same user... + my $sth = $dbh->prepare("SELECT p1.userid, p2.userid, p1.login_name + FROM profiles AS p1, profiles AS p2 + WHERE p1.userid < p2.userid + AND p1.login_name = p2.login_name + ORDER BY p1.login_name"); + $sth->execute(); + my ($u1, $u2, $n) = ($sth->fetchrow_array); + last if !$u1; + + print "Both $u1 & $u2 are ids for $n! Merging $u2 into $u1...\n"; + foreach my $i (["bugs", "reporter"], + ["bugs", "assigned_to"], + ["bugs", "qa_contact"], + ["attachments", "submitter_id"], + ["bugs_activity", "who"], + ["cc", "who"], + ["votes", "who"], + ["longdescs", "who"]) { + my ($table, $field) = (@$i); + print " Updating $table.$field...\n"; + $dbh->do("UPDATE $table SET $field = $u1 " . + "WHERE $field = $u2"); + } + $dbh->do("DELETE FROM profiles WHERE userid = $u2"); + } + print "OK, changing index type to prevent duplicates in the", + " future...\n"; + + $dbh->bz_drop_index('profiles', 'profiles_login_name_idx'); + $dbh->bz_add_index('profiles', 'profiles_login_name_idx', + {TYPE => 'UNIQUE', FIELDS => [qw(login_name)]}); + } +} + +sub _update_component_user_fields_to_ids { + my $dbh = Bugzilla->dbh; + + # components.initialowner + my $comp_init_owner = $dbh->bz_column_info('components', 'initialowner'); + if ($comp_init_owner && $comp_init_owner->{TYPE} eq 'TINYTEXT') { + my $sth = $dbh->prepare("SELECT program, value, initialowner + FROM components"); + $sth->execute(); + while (my ($program, $value, $initialowner) = $sth->fetchrow_array()) { + my ($id) = $dbh->selectrow_array( + "SELECT userid FROM profiles WHERE login_name = ?", + undef, $initialowner); + + unless (defined $id) { + print "Warning: You have an invalid default assignee", + " '$initialowner'\n in component '$value' of program", + " '$program'!\n"; + $id = 0; + } + + $dbh->do("UPDATE components SET initialowner = ? + WHERE program = ? AND value = ?", undef, + $id, $program, $value); + } + $dbh->bz_alter_column('components','initialowner',{TYPE => 'INT3'}); + } + + # components.initialqacontact + my $comp_init_qa = $dbh->bz_column_info('components', 'initialqacontact'); + if ($comp_init_qa && $comp_init_qa->{TYPE} eq 'TINYTEXT') { + my $sth = $dbh->prepare("SELECT program, value, initialqacontact + FROM components"); + $sth->execute(); + while (my ($program, $value, $initialqacontact) = + $sth->fetchrow_array()) + { + my ($id) = $dbh->selectrow_array( + "SELECT userid FROM profiles WHERE login_name = ?", + undef, $initialqacontact); + + unless (defined $id) { + if ($initialqacontact) { + print "Warning: You have an invalid default QA contact", + " $initialqacontact' in program '$program',", + " component '$value'!\n"; + } + $id = 0; + } + + $dbh->do("UPDATE components SET initialqacontact = ? + WHERE program = ? AND value = ?", undef, + $id, $program, $value); + } + + $dbh->bz_alter_column('components','initialqacontact',{TYPE => 'INT3'}); + } +} + +sub _populate_milestones_table { + my $dbh = Bugzilla->dbh; + # 2000-03-21 Adding a table for target milestones to + # database - matthew@zeroknowledge.com + # If the milestones table is empty, and we're still back in a Bugzilla + # that has a bugs.product field, that means that we just created + # the milestones table and it needs to be populated. + my $milestones_exist = $dbh->selectrow_array( + "SELECT DISTINCT 1 FROM milestones"); + if (!$milestones_exist && $dbh->bz_column_info('bugs', 'product')) { + print "Replacing blank milestones...\n"; + + $dbh->do("UPDATE bugs + SET target_milestone = '---' + WHERE target_milestone = ' '"); + + # If we are upgrading from 2.8 or earlier, we will have *created* + # the milestones table with a product_id field, but Bugzilla expects + # it to have a "product" field. So we change the field backward so + # other code can run. The change will be reversed later in checksetup. + if ($dbh->bz_column_info('milestones', 'product_id')) { + # Dropping the column leaves us with a milestones_product_id_idx + # index that is only on the "value" column. We need to drop the + # whole index so that it can be correctly re-created later. + $dbh->bz_drop_index('milestones', 'milestones_product_id_idx'); + $dbh->bz_drop_column('milestones', 'product_id'); + $dbh->bz_add_column('milestones', 'product', + {TYPE => 'varchar(64)', NOTNULL => 1}, ''); + } + + # Populate the milestone table with all existing values in the database + my $sth = $dbh->prepare("SELECT DISTINCT target_milestone, product + FROM bugs"); + $sth->execute(); + + print "Populating milestones table...\n"; + + while (my ($value, $product) = $sth->fetchrow_array()) { + # check if the value already exists + my $sortkey = substr($value, 1); + if ($sortkey !~ /^\d+$/) { + $sortkey = 0; + } else { + $sortkey *= 10; + } + my $ms_exists = $dbh->selectrow_array( + "SELECT value FROM milestones + WHERE value = ? AND product = ?", undef, $value, $product); + + if (!$ms_exists) { + $dbh->do("INSERT INTO milestones(value, product, sortkey) + VALUES (?,?,?)", undef, $value, $product, $sortkey); + } + } + } +} + +sub _add_products_defaultmilestone { + my $dbh = Bugzilla->dbh; + + # 2000-03-23 Added a defaultmilestone field to the products table, so that + # we know which milestone to initially assign bugs to. + if (!$dbh->bz_column_info('products', 'defaultmilestone')) { + $dbh->bz_add_column('products', 'defaultmilestone', + {TYPE => 'varchar(20)', NOTNULL => 1, DEFAULT => "'---'"}); + my $sth = $dbh->prepare( + "SELECT product, defaultmilestone FROM products"); + $sth->execute(); + while (my ($product, $default_ms) = $sth->fetchrow_array()) { + my $exists = $dbh->selectrow_array( + "SELECT value FROM milestones + WHERE value = ? AND product = ?", + undef, $default_ms, $product); + if (!$exists) { + $dbh->do("INSERT INTO milestones(value, product) " . + "VALUES (?, ?)", undef, $default_ms, $product); + } + } + } +} + +sub _copy_from_comments_to_longdescs { + my $dbh = Bugzilla->dbh; + # 2000-11-27 For Bugzilla 2.5 and later. Copy data from 'comments' to + # 'longdescs' - the new name of the comments table. + if ($dbh->bz_table_info('comments')) { + my $quoted_when = $dbh->quote_identifier('when'); + $dbh->do("INSERT INTO longdescs (bug_when, bug_id, who, thetext) + SELECT $quoted_when, bug_id, who, comment + FROM comments"); + $dbh->bz_drop_table("comments"); + } +} + +sub _populate_duplicates_table { + my $dbh = Bugzilla->dbh; + # 2000-07-15 Added duplicates table so Bugzilla tracks duplicates in a + # better way than it used to. This code searches the comments to populate + # the table initially. It's executed if the table is empty; if it's + # empty because there are no dupes (as opposed to having just created + # the table) it won't have any effect anyway, so it doesn't matter. + my ($dups_exist) = $dbh->selectrow_array( + "SELECT DISTINCT 1 FROM duplicates"); + # We also check against a schema change that happened later. + if (!$dups_exist && !$dbh->bz_column_info('groups', 'isactive')) { + # populate table + print "Populating duplicates table from comments...\n"; + + my $sth = $dbh->prepare( + "SELECT longdescs.bug_id, thetext + FROM longdescs LEFT JOIN bugs + ON longdescs.bug_id = bugs.bug_id + WHERE (" . $dbh->sql_regexp("thetext", + "'[.*.]{3} This bug has been marked as a duplicate" + . " of [[:digit:]]+ [.*.]{3}'") + . ") + AND resolution = 'DUPLICATE' + ORDER BY longdescs.bug_when"); + $sth->execute(); + + my (%dupes, $key); + # Because of the way hashes work, this loop removes all but the + # last dupe resolution found for a given bug. + while (my ($dupe, $dupe_of) = $sth->fetchrow_array()) { + $dupes{$dupe} = $dupe_of; + } + + foreach $key (keys(%dupes)){ + $dupes{$key} =~ /^.*\*\*\* This bug has been marked as a duplicate of (\d+) \*\*\*$/ms; + $dupes{$key} = $1; + $dbh->do("INSERT INTO duplicates VALUES(?, ?)", undef, + $dupes{$key}, $key); + # BugItsADupeOf Dupe + } + } +} + +sub _recrypt_plaintext_passwords { + my $dbh = Bugzilla->dbh; + # 2001-06-12; myk@mozilla.org; bugs 74032, 77473: + # Recrypt passwords using Perl &crypt instead of the mysql equivalent + # and delete plaintext passwords from the database. + if ($dbh->bz_column_info('profiles', 'password')) { + + print <<ENDTEXT; +Your current installation of Bugzilla stores passwords in plaintext +in the database and uses mysql's encrypt function instead of Perl's +crypt function to crypt passwords. Passwords are now going to be +re-crypted with the Perl function, and plaintext passwords will be +deleted from the database. This could take a while if your +installation has many users. +ENDTEXT + + # Re-crypt everyone's password. + my $sth = $dbh->prepare("SELECT userid, password FROM profiles"); + $sth->execute(); + + my $total = $sth->rows; + my $i = 1; + + print "Fixing passwords...\n"; + while (my ($userid, $password) = $sth->fetchrow_array()) { + my $cryptpassword = $dbh->quote(bz_crypt($password)); + $dbh->do("UPDATE profiles " . + "SET cryptpassword = $cryptpassword " . + "WHERE userid = $userid"); + indicate_progress({ total => $total, current => $i, every => 10 }); + } + print "\n"; + + # Drop the plaintext password field. + $dbh->bz_drop_column('profiles', 'password'); + } +} + +sub _update_bugs_activity_to_only_record_changes { + my $dbh = Bugzilla->dbh; + # 2001-07-20 jake@bugzilla.org - Change bugs_activity to only record changes + # http://bugzilla.mozilla.org/show_bug.cgi?id=55161 + if ($dbh->bz_column_info('bugs_activity', 'oldvalue')) { + $dbh->bz_add_column("bugs_activity", "removed", {TYPE => "TINYTEXT"}); + $dbh->bz_add_column("bugs_activity", "added", {TYPE => "TINYTEXT"}); + + # Need to get field id's for the fields that have multiple values + my @multi; + foreach my $f ("cc", "dependson", "blocked", "keywords") { + my $sth = $dbh->prepare("SELECT id " . + "FROM fielddefs " . + "WHERE name = '$f'"); + $sth->execute(); + my ($fid) = $sth->fetchrow_array(); + push (@multi, $fid); + } + + # Now we need to process the bugs_activity table and reformat the data + print "Fixing activity log...\n"; + my $sth = $dbh->prepare("SELECT bug_id, who, bug_when, fieldid, + oldvalue, newvalue FROM bugs_activity"); + $sth->execute; + my $i = 0; + my $total = $sth->rows; + while (my ($bug_id, $who, $bug_when, $fieldid, $oldvalue, $newvalue) + = $sth->fetchrow_array()) + { + $i++; + indicate_progress({ total => $total, current => $i, every => 10 }); + # Make sure (old|new)value isn't null (to suppress warnings) + $oldvalue ||= ""; + $newvalue ||= ""; + my ($added, $removed) = ""; + if (grep ($_ eq $fieldid, @multi)) { + $oldvalue =~ s/[\s,]+/ /g; + $newvalue =~ s/[\s,]+/ /g; + my @old = split(" ", $oldvalue); + my @new = split(" ", $newvalue); + my (@add, @remove) = (); + # Find values that were "added" + foreach my $value(@new) { + if (! grep ($_ eq $value, @old)) { + push (@add, $value); + } + } + # Find values that were removed + foreach my $value(@old) { + if (! grep ($_ eq $value, @new)) { + push (@remove, $value); + } + } + $added = join (", ", @add); + $removed = join (", ", @remove); + # If we can't determine what changed, put a ? in both fields + unless ($added || $removed) { + $added = "?"; + $removed = "?"; + } + # If the original field (old|new)value was full, then this + # could be incomplete data. + if (length($oldvalue) == 255 || length($newvalue) == 255) { + $added = "? $added"; + $removed = "? $removed"; + } + } else { + $removed = $oldvalue; + $added = $newvalue; + } + $added = $dbh->quote($added); + $removed = $dbh->quote($removed); + $dbh->do("UPDATE bugs_activity + SET removed = $removed, added = $added + WHERE bug_id = $bug_id AND who = $who + AND bug_when = '$bug_when' + AND fieldid = $fieldid"); + } + print "\n"; + $dbh->bz_drop_column("bugs_activity", "oldvalue"); + $dbh->bz_drop_column("bugs_activity", "newvalue"); + } +} + +sub _delete_logincookies_cryptpassword_and_handle_invalid_cookies { + my $dbh = Bugzilla->dbh; + # 2002-02-04 bbaetz@student.usyd.edu.au bug 95732 + # Remove logincookies.cryptpassword, and delete entries which become + # invalid + if ($dbh->bz_column_info("logincookies", "cryptpassword")) { + # We need to delete any cookies which are invalid before dropping the + # column + print "Removing invalid login cookies...\n"; + + # mysql doesn't support DELETE with multi-table queries, so we have + # to iterate + my $sth = $dbh->prepare("SELECT cookie FROM logincookies, profiles " . + "WHERE logincookies.cryptpassword != " . + "profiles.cryptpassword AND " . + "logincookies.userid = profiles.userid"); + $sth->execute(); + while (my ($cookie) = $sth->fetchrow_array()) { + $dbh->do("DELETE FROM logincookies WHERE cookie = $cookie"); + } + + $dbh->bz_drop_column("logincookies", "cryptpassword"); + } +} + +sub _use_ip_instead_of_hostname_in_logincookies { + my $dbh = Bugzilla->dbh; + + # 2002-03-15 bbaetz@student.usyd.edu.au - bug 129466 + # 2002-05-13 preed@sigkill.com - bug 129446 patch backported to the + # BUGZILLA-2_14_1-BRANCH as a security blocker for the 2.14.2 release + # + # Use the ip, not the hostname, in the logincookies table + if ($dbh->bz_column_info("logincookies", "hostname")) { + # We've changed what we match against, so all entries are now invalid + $dbh->do("DELETE FROM logincookies"); + + # Now update the logincookies schema + $dbh->bz_drop_column("logincookies", "hostname"); + $dbh->bz_add_column("logincookies", "ipaddr", + {TYPE => 'varchar(40)', NOTNULL => 1}, ''); + } +} + +sub _move_quips_into_db { + my $dbh = Bugzilla->dbh; + my $datadir = bz_locations->{'datadir'}; + # 2002-07-15 davef@tetsubo.com - bug 67950 + # Move quips to the db. + if (-e "$datadir/comments") { + print "Populating quips table from $datadir/comments...\n"; + my $comments = new IO::File("$datadir/comments", 'r') + || die "$datadir/comments: $!"; + $comments->untaint; + while (<$comments>) { + chomp; + $dbh->do("INSERT INTO quips (quip) VALUES (?)", undef, $_); + } + + print <<EOT; + +Quips are now stored in the database, rather than in an external file. +The quips previously stored in $datadir/comments have been copied into +the database, and that file has been renamed to $datadir/comments.bak +You may delete the renamed file once you have confirmed that all your +quips were moved successfully. + +EOT + $comments->close; + rename("$datadir/comments", "$datadir/comments.bak") + || warn "Failed to rename: $!"; + } +} + +sub _use_ids_for_products_and_components { + my $dbh = Bugzilla->dbh; + # 2002-08-12 jake@bugzilla.org/bbaetz@student.usyd.edu.au - bug 43600 + # Use integer IDs for products and components. + if ($dbh->bz_column_info("products", "product")) { + print "Updating database to use product IDs.\n"; + + # First, we need to remove possible NULL entries + # NULLs may exist, but won't have been used, since all the uses of them + # are in NOT NULL fields in other tables + $dbh->do("DELETE FROM products WHERE product IS NULL"); + $dbh->do("DELETE FROM components WHERE value IS NULL"); + + $dbh->bz_add_column("products", "id", + {TYPE => 'SMALLSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + $dbh->bz_add_column("components", "product_id", + {TYPE => 'INT2', NOTNULL => 1}, 0); + $dbh->bz_add_column("versions", "product_id", + {TYPE => 'INT2', NOTNULL => 1}, 0); + $dbh->bz_add_column("milestones", "product_id", + {TYPE => 'INT2', NOTNULL => 1}, 0); + $dbh->bz_add_column("bugs", "product_id", + {TYPE => 'INT2', NOTNULL => 1}, 0); + + # The attachstatusdefs table was added in version 2.15, but + # removed again in early 2.17. If it exists now, we still need + # to perform this change with product_id because the code later on + # which converts the attachment statuses to flags depends on it. + # But we need to avoid this if the user is upgrading from 2.14 + # or earlier (because it won't be there to convert). + if ($dbh->bz_table_info("attachstatusdefs")) { + $dbh->bz_add_column("attachstatusdefs", "product_id", + {TYPE => 'INT2', NOTNULL => 1}, 0); + } + + my %products; + my $sth = $dbh->prepare("SELECT id, product FROM products"); + $sth->execute; + while (my ($product_id, $product) = $sth->fetchrow_array()) { + if (exists $products{$product}) { + print "Ignoring duplicate product $product\n"; + $dbh->do("DELETE FROM products WHERE id = $product_id"); + next; + } + $products{$product} = 1; + $dbh->do("UPDATE components SET product_id = $product_id " . + "WHERE program = " . $dbh->quote($product)); + $dbh->do("UPDATE versions SET product_id = $product_id " . + "WHERE program = " . $dbh->quote($product)); + $dbh->do("UPDATE milestones SET product_id = $product_id " . + "WHERE product = " . $dbh->quote($product)); + $dbh->do("UPDATE bugs SET product_id = $product_id " . + "WHERE product = " . $dbh->quote($product)); + $dbh->do("UPDATE attachstatusdefs SET product_id = $product_id " . + "WHERE product = " . $dbh->quote($product)) + if $dbh->bz_table_info("attachstatusdefs"); + } + + print "Updating the database to use component IDs.\n"; + + $dbh->bz_add_column("components", "id", + {TYPE => 'SMALLSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + $dbh->bz_add_column("bugs", "component_id", + {TYPE => 'INT2', NOTNULL => 1}, 0); + + my %components; + $sth = $dbh->prepare("SELECT id, value, product_id FROM components"); + $sth->execute; + while (my ($component_id, $component, $product_id) + = $sth->fetchrow_array()) + { + if (exists $components{$component}) { + if (exists $components{$component}{$product_id}) { + print "Ignoring duplicate component $component for", + " product $product_id\n"; + $dbh->do("DELETE FROM components WHERE id = $component_id"); + next; + } + } else { + $components{$component} = {}; + } + $components{$component}{$product_id} = 1; + $dbh->do("UPDATE bugs SET component_id = $component_id " . + "WHERE component = " . $dbh->quote($component) . + " AND product_id = $product_id"); + } + print "Fixing Indexes and Uniqueness.\n"; + $dbh->bz_drop_index('milestones', 'milestones_product_idx'); + + $dbh->bz_add_index('milestones', 'milestones_product_id_idx', + {TYPE => 'UNIQUE', FIELDS => [qw(product_id value)]}); + + $dbh->bz_drop_index('bugs', 'bugs_product_idx'); + $dbh->bz_add_index('bugs', 'bugs_product_id_idx', [qw(product_id)]); + $dbh->bz_drop_index('bugs', 'bugs_component_idx'); + $dbh->bz_add_index('bugs', 'bugs_component_id_idx', [qw(component_id)]); + + print "Removing, renaming, and retyping old product and", + " component fields.\n"; + $dbh->bz_drop_column("components", "program"); + $dbh->bz_drop_column("versions", "program"); + $dbh->bz_drop_column("milestones", "product"); + $dbh->bz_drop_column("bugs", "product"); + $dbh->bz_drop_column("bugs", "component"); + $dbh->bz_drop_column("attachstatusdefs", "product") + if $dbh->bz_table_info("attachstatusdefs"); + $dbh->bz_rename_column("products", "product", "name"); + $dbh->bz_alter_column("products", "name", + {TYPE => 'varchar(64)', NOTNULL => 1}); + $dbh->bz_rename_column("components", "value", "name"); + $dbh->bz_alter_column("components", "name", + {TYPE => 'varchar(64)', NOTNULL => 1}); + + print "Adding indexes for products and components tables.\n"; + $dbh->bz_add_index('products', 'products_name_idx', + {TYPE => 'UNIQUE', FIELDS => [qw(name)]}); + $dbh->bz_add_index('components', 'components_product_id_idx', + {TYPE => 'UNIQUE', FIELDS => [qw(product_id name)]}); + $dbh->bz_add_index('components', 'components_name_idx', [qw(name)]); + } +} + +# Helper for the below function. +# +# _list_bits(arg) returns a list of UNKNOWN<n> if the group +# has been deleted for all bits set in arg. When the activity +# records are converted from groupset numbers to lists of +# group names, _list_bits is used to fill in a list of references +# to groupset bits for groups that no longer exist. +sub _list_bits { + my ($num) = @_; + my $dbh = Bugzilla->dbh; + my @res; + my $curr = 1; + while (1) { + # Convert a big integer to a list of bits + my $sth = $dbh->prepare("SELECT ($num & ~$curr) > 0, + ($num & $curr), + ($num & ~$curr), + $curr << 1"); + $sth->execute; + my ($more, $thisbit, $remain, $nval) = $sth->fetchrow_array; + push @res,"UNKNOWN<$curr>" if ($thisbit); + $curr = $nval; + $num = $remain; + last if !$more; + } + return @res; +} + +sub _convert_groups_system_from_groupset { + my $dbh = Bugzilla->dbh; + # 2002-09-22 - bugreport@peshkin.net - bug 157756 + # + # If the whole groups system is new, but the installation isn't, + # convert all the old groupset groups, etc... + # + # This requires: + # 1) define groups ids in group table + # 2) populate user_group_map with grants from old groupsets + # and blessgroupsets + # 3) populate bug_group_map with data converted from old bug groupsets + # 4) convert activity logs to use group names instead of numbers + # 5) identify the admin from the old all-ones groupset + + # The groups system needs to be converted if groupset exists + if ($dbh->bz_column_info("profiles", "groupset")) { + # Some mysql versions will promote any unique key to primary key + # so all unique keys are removed first and then added back in + $dbh->bz_drop_index('groups', 'groups_bit_idx'); + $dbh->bz_drop_index('groups', 'groups_name_idx'); + my @primary_key = $dbh->primary_key(undef, undef, 'groups'); + if (@primary_key) { + $dbh->do("ALTER TABLE groups DROP PRIMARY KEY"); + } + + $dbh->bz_add_column('groups', 'id', + {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + + $dbh->bz_add_index('groups', 'groups_name_idx', + {TYPE => 'UNIQUE', FIELDS => [qw(name)]}); + + # Convert all existing groupset records to map entries before removing + # groupset fields or removing "bit" from groups. + my $sth = $dbh->prepare("SELECT bit, id FROM groups WHERE bit > 0"); + $sth->execute(); + while (my ($bit, $gid) = $sth->fetchrow_array) { + # Create user_group_map membership grants for old groupsets. + # Get each user with the old groupset bit set + my $sth2 = $dbh->prepare("SELECT userid FROM profiles + WHERE (groupset & $bit) != 0"); + $sth2->execute(); + while (my ($uid) = $sth2->fetchrow_array) { + # Check to see if the user is already a member of the group + # and, if not, insert a new record. + my $query = "SELECT user_id FROM user_group_map + WHERE group_id = $gid AND user_id = $uid + AND isbless = 0"; + my $sth3 = $dbh->prepare($query); + $sth3->execute(); + if ( !$sth3->fetchrow_array() ) { + $dbh->do("INSERT INTO user_group_map + (user_id, group_id, isbless, grant_type) + VALUES ($uid, $gid, 0, " . GRANT_DIRECT . ")"); + } + } + # Create user can bless group grants for old groupsets, but only + # if we're upgrading from a Bugzilla that had blessing. + if($dbh->bz_column_info('profiles', 'blessgroupset')) { + # Get each user with the old blessgroupset bit set + $sth2 = $dbh->prepare("SELECT userid FROM profiles + WHERE (blessgroupset & $bit) != 0"); + $sth2->execute(); + while (my ($uid) = $sth2->fetchrow_array) { + $dbh->do("INSERT INTO user_group_map + (user_id, group_id, isbless, grant_type) + VALUES ($uid, $gid, 1, " . GRANT_DIRECT . ")"); + } + } + # Create bug_group_map records for old groupsets. + # Get each bug with the old group bit set. + $sth2 = $dbh->prepare("SELECT bug_id FROM bugs + WHERE (groupset & $bit) != 0"); + $sth2->execute(); + while (my ($bug_id) = $sth2->fetchrow_array) { + # Insert the bug, group pair into the bug_group_map. + $dbh->do("INSERT INTO bug_group_map (bug_id, group_id) + VALUES ($bug_id, $gid)"); + } + } + # Replace old activity log groupset records with lists of names + # of groups. + $sth = $dbh->prepare("SELECT id FROM fielddefs + WHERE name = " . $dbh->quote('bug_group')); + $sth->execute(); + my ($bgfid) = $sth->fetchrow_array; + # Get the field id for the old groupset field + $sth = $dbh->prepare("SELECT id FROM fielddefs + WHERE name = " . $dbh->quote('groupset')); + $sth->execute(); + my ($gsid) = $sth->fetchrow_array; + # Get all bugs_activity records from groupset changes + if ($gsid) { + $sth = $dbh->prepare("SELECT bug_id, bug_when, who, added, removed + FROM bugs_activity WHERE fieldid = $gsid"); + $sth->execute(); + while (my ($bug_id, $bug_when, $who, $added, $removed) = + $sth->fetchrow_array) + { + $added ||= 0; + $removed ||= 0; + # Get names of groups added. + my $sth2 = $dbh->prepare("SELECT name FROM groups + WHERE (bit & $added) != 0 + AND (bit & $removed) = 0"); + $sth2->execute(); + my @logadd; + while (my ($n) = $sth2->fetchrow_array) { + push @logadd, $n; + } + # Get names of groups removed. + $sth2 = $dbh->prepare("SELECT name FROM groups + WHERE (bit & $removed) != 0 + AND (bit & $added) = 0"); + $sth2->execute(); + my @logrem; + while (my ($n) = $sth2->fetchrow_array) { + push @logrem, $n; + } + # Get list of group bits added that correspond to + # missing groups. + $sth2 = $dbh->prepare("SELECT ($added & ~BIT_OR(bit)) + FROM groups"); + $sth2->execute(); + my ($miss) = $sth2->fetchrow_array; + if ($miss) { + push @logadd, _list_bits($miss); + print "\nWARNING - GROUPSET ACTIVITY ON BUG $bug_id", + " CONTAINS DELETED GROUPS\n"; + } + # Get list of group bits deleted that correspond to + # missing groups. + $sth2 = $dbh->prepare("SELECT ($removed & ~BIT_OR(bit)) + FROM groups"); + $sth2->execute(); + ($miss) = $sth2->fetchrow_array; + if ($miss) { + push @logrem, _list_bits($miss); + print "\nWARNING - GROUPSET ACTIVITY ON BUG $bug_id", + " CONTAINS DELETED GROUPS\n"; + } + my $logr = ""; + my $loga = ""; + $logr = join(", ", @logrem) . '?' if @logrem; + $loga = join(", ", @logadd) . '?' if @logadd; + # Replace to old activity record with the converted data. + $dbh->do("UPDATE bugs_activity SET fieldid = $bgfid, added = " . + $dbh->quote($loga) . ", removed = " . + $dbh->quote($logr) . + " WHERE bug_id = $bug_id AND bug_when = " . + $dbh->quote($bug_when) . + " AND who = $who AND fieldid = $gsid"); + } + # Replace groupset changes with group name changes in + # profiles_activity. Get profiles_activity records for groupset. + $sth = $dbh->prepare( + "SELECT userid, profiles_when, who, newvalue, oldvalue " . + "FROM profiles_activity " . + "WHERE fieldid = $gsid"); + $sth->execute(); + while (my ($uid, $uwhen, $uwho, $added, $removed) = + $sth->fetchrow_array) + { + $added ||= 0; + $removed ||= 0; + # Get names of groups added. + my $sth2 = $dbh->prepare("SELECT name FROM groups + WHERE (bit & $added) != 0 + AND (bit & $removed) = 0"); + $sth2->execute(); + my @logadd; + while (my ($n) = $sth2->fetchrow_array) { + push @logadd, $n; + } + # Get names of groups removed. + $sth2 = $dbh->prepare("SELECT name FROM groups + WHERE (bit & $removed) != 0 + AND (bit & $added) = 0"); + $sth2->execute(); + my @logrem; + while (my ($n) = $sth2->fetchrow_array) { + push @logrem, $n; + } + my $ladd = ""; + my $lrem = ""; + $ladd = join(", ", @logadd) . '?' if @logadd; + $lrem = join(", ", @logrem) . '?' if @logrem; + # Replace profiles_activity record for groupset change + # with group list. + $dbh->do("UPDATE profiles_activity " . + "SET fieldid = $bgfid, newvalue = " . + $dbh->quote($ladd) . ", oldvalue = " . + $dbh->quote($lrem) . + " WHERE userid = $uid AND profiles_when = " . + $dbh->quote($uwhen) . + " AND who = $uwho AND fieldid = $gsid"); + } + } + + # Identify admin group. + my ($admin_gid) = $dbh->selectrow_array( + "SELECT id FROM groups WHERE name = 'admin'"); + if (!$admin_gid) { + $dbh->do(q{INSERT INTO groups (name, description) + VALUES ('admin', 'Administrators')}); + $admin_gid = $dbh->bz_last_key('groups', 'id'); + } + # Find current admins + my @admins; + # Don't lose admins from DBs where Bug 157704 applies + $sth = $dbh->prepare( + "SELECT userid, (groupset & 65536), login_name " . + "FROM profiles " . + "WHERE (groupset | 65536) = 9223372036854775807"); + $sth->execute(); + while ( my ($userid, $iscomplete, $login_name) + = $sth->fetchrow_array() ) + { + # existing administrators are made members of group "admin" + print "\nWARNING - $login_name IS AN ADMIN IN SPITE OF BUG", + " 157704\n\n" if (!$iscomplete); + push(@admins, $userid) unless grep($_ eq $userid, @admins); + } + # Now make all those users admins directly. They were already + # added to every other group, above, because of their groupset. + foreach my $admin_id (@admins) { + $dbh->do("INSERT INTO user_group_map + (user_id, group_id, isbless, grant_type) + VALUES (?, ?, ?, ?)", + undef, $admin_id, $admin_gid, $_, GRANT_DIRECT) + foreach (0, 1); + } + + $dbh->bz_drop_column('profiles','groupset'); + $dbh->bz_drop_column('profiles','blessgroupset'); + $dbh->bz_drop_column('bugs','groupset'); + $dbh->bz_drop_column('groups','bit'); + $dbh->do("DELETE FROM fielddefs WHERE name = " + . $dbh->quote('groupset')); + } +} + +sub _convert_attachment_statuses_to_flags { + my $dbh = Bugzilla->dbh; + + # September 2002 myk@mozilla.org bug 98801 + # Convert the attachment statuses tables into flags tables. + if ($dbh->bz_table_info("attachstatuses") + && $dbh->bz_table_info("attachstatusdefs")) + { + print "Converting attachment statuses to flags...\n"; + + # Get IDs for the old attachment status and new flag fields. + my ($old_field_id) = $dbh->selectrow_array( + "SELECT id FROM fielddefs WHERE name='attachstatusdefs.name'") + || 0; + my ($new_field_id) = $dbh->selectrow_array( + "SELECT id FROM fielddefs WHERE name = 'flagtypes.name'"); + + # Convert attachment status definitions to flag types. If more than one + # status has the same name and description, it is merged into a single + # status with multiple inclusion records. + + my $sth = $dbh->prepare( + "SELECT id, name, description, sortkey, product_id + FROM attachstatusdefs"); + + # status definition IDs indexed by name/description + my $def_ids = {}; + + # merged IDs and the IDs they were merged into. The key is the old ID, + # the value is the new one. This allows us to give statuses the right + # ID when we convert them over to flags. This map includes IDs that + # weren't merged (in this case the old and new IDs are the same), since + # it makes the code simpler. + my $def_id_map = {}; + + $sth->execute(); + while (my ($id, $name, $desc, $sortkey, $prod_id) = + $sth->fetchrow_array()) + { + my $key = $name . $desc; + if (!$def_ids->{$key}) { + $def_ids->{$key} = $id; + my $quoted_name = $dbh->quote($name); + my $quoted_desc = $dbh->quote($desc); + $dbh->do("INSERT INTO flagtypes (id, name, description, + sortkey, target_type) + VALUES ($id, $quoted_name, $quoted_desc, + $sortkey,'a')"); + } + $def_id_map->{$id} = $def_ids->{$key}; + $dbh->do("INSERT INTO flaginclusions (type_id, product_id) + VALUES ($def_id_map->{$id}, $prod_id)"); + } + + # Note: even though we've converted status definitions, we still + # can't drop the table because we need it to convert the statuses + # themselves. + + # Convert attachment statuses to flags. To do this we select + # the statuses from the status table and then, for each one, + # figure out who set it and when they set it from the bugs + # activity table. + my $id = 0; + $sth = $dbh->prepare( + "SELECT attachstatuses.attach_id, attachstatusdefs.id, + attachstatusdefs.name, attachments.bug_id + FROM attachstatuses, attachstatusdefs, attachments + WHERE attachstatuses.statusid = attachstatusdefs.id + AND attachstatuses.attach_id = attachments.attach_id"); + + # a query to determine when the attachment status was set and who set it + my $sth2 = $dbh->prepare("SELECT added, who, bug_when + FROM bugs_activity + WHERE bug_id = ? AND attach_id = ? + AND fieldid = $old_field_id + ORDER BY bug_when DESC"); + + $sth->execute(); + while (my ($attach_id, $def_id, $status, $bug_id) = + $sth->fetchrow_array()) + { + ++$id; + + # Determine when the attachment status was set and who set it. + # We should always be able to find out this info from the bug + # activity, but we fall back to default values just in case. + $sth2->execute($bug_id, $attach_id); + my ($added, $who, $when); + while (($added, $who, $when) = $sth2->fetchrow_array()) { + last if $added =~ /(^|[, ]+)\Q$status\E([, ]+|$)/; + } + $who = $dbh->quote($who); # "NULL" by default if $who is undefined + $when = $when ? $dbh->quote($when) : "NOW()"; + + + $dbh->do("INSERT INTO flags (id, type_id, status, bug_id, + attach_id, creation_date, modification_date, + requestee_id, setter_id) + VALUES ($id, $def_id_map->{$def_id}, '+', $bug_id, + $attach_id, $when, $when, NULL, $who)"); + } + + # Now that we've converted both tables we can drop them. + $dbh->bz_drop_table("attachstatuses"); + $dbh->bz_drop_table("attachstatusdefs"); + + # Convert activity records for attachment statuses into records + # for flags. + $sth = $dbh->prepare("SELECT attach_id, who, bug_when, added, + removed + FROM bugs_activity + WHERE fieldid = $old_field_id"); + $sth->execute(); + while (my ($attach_id, $who, $when, $old_added, $old_removed) = + $sth->fetchrow_array()) + { + my @additions = split(/[, ]+/, $old_added); + @additions = map("$_+", @additions); + my $new_added = $dbh->quote(join(", ", @additions)); + + my @removals = split(/[, ]+/, $old_removed); + @removals = map("$_+", @removals); + my $new_removed = $dbh->quote(join(", ", @removals)); + + $old_added = $dbh->quote($old_added); + $old_removed = $dbh->quote($old_removed); + $who = $dbh->quote($who); + $when = $dbh->quote($when); + + $dbh->do("UPDATE bugs_activity SET fieldid = $new_field_id, " . + "added = $new_added, removed = $new_removed " . + "WHERE attach_id = $attach_id AND who = $who " . + "AND bug_when = $when AND fieldid = $old_field_id " . + "AND added = $old_added AND removed = $old_removed"); + } + + # Remove the attachment status field from the field definitions. + $dbh->do("DELETE FROM fielddefs WHERE name='attachstatusdefs.name'"); + + print "done.\n"; + } +} + +sub _remove_spaces_and_commas_from_flagtypes { + my $dbh = Bugzilla->dbh; + # Get all names and IDs, to find broken ones and to + # check for collisions when renaming. + my $sth = $dbh->prepare("SELECT name, id FROM flagtypes"); + $sth->execute(); + + my %flagtypes; + my @badflagnames; + # find broken flagtype names, and populate a hash table + # to check for collisions. + while (my ($name, $id) = $sth->fetchrow_array()) { + $flagtypes{$name} = $id; + if ($name =~ /[ ,]/) { + push(@badflagnames, $name); + } + } + if (@badflagnames) { + print "Removing spaces and commas from flag names...\n"; + my ($flagname, $tryflagname); + my $sth = $dbh->prepare("UPDATE flagtypes SET name = ? WHERE id = ?"); + foreach $flagname (@badflagnames) { + print " Bad flag type name \"$flagname\" ...\n"; + # find a new name for this flagtype. + ($tryflagname = $flagname) =~ tr/ ,/__/; + # avoid collisions with existing flagtype names. + while (defined($flagtypes{$tryflagname})) { + print " ... can't rename as \"$tryflagname\" ...\n"; + $tryflagname .= "'"; + if (length($tryflagname) > 50) { + my $lastchanceflagname = (substr $tryflagname, 0, 47) . '...'; + if (defined($flagtypes{$lastchanceflagname})) { + print " ... last attempt as \"$lastchanceflagname\" still failed.'\n", + "Rename the flag by hand and run checksetup.pl again.\n"; + die("Bad flag type name $flagname"); + } + $tryflagname = $lastchanceflagname; + } + } + $sth->execute($tryflagname, $flagtypes{$flagname}); + print " renamed flag type \"$flagname\" as \"$tryflagname\"\n"; + $flagtypes{$tryflagname} = $flagtypes{$flagname}; + delete $flagtypes{$flagname}; + } + print "... done.\n"; + } +} + +sub _setup_usebuggroups_backward_compatibility { + my $dbh = Bugzilla->dbh; + # 2002-11-24 - bugreport@peshkin.net - bug 147275 + # + # If group_control_map is empty, backward-compatibility + # usebuggroups-equivalent records should be created. + my $entry = Bugzilla->params->{'useentrygroupdefault'}; + my ($maps_exist) = $dbh->selectrow_array( + "SELECT DISTINCT 1 FROM group_control_map"); + if (!$maps_exist) { + # Initially populate group_control_map. + # First, get all the existing products and their groups. + my $sth = $dbh->prepare("SELECT groups.id, products.id, groups.name, + products.name + FROM groups, products + WHERE isbuggroup != 0"); + $sth->execute(); + while (my ($groupid, $productid, $groupname, $productname) + = $sth->fetchrow_array()) + { + if ($groupname eq $productname) { + # Product and group have same name. + $dbh->do("INSERT INTO group_control_map " . + "(group_id, product_id, entry, membercontrol, " . + "othercontrol, canedit) " . + "VALUES ($groupid, $productid, $entry, " . + CONTROLMAPDEFAULT . ", " . + CONTROLMAPNA . ", 0)"); + } else { + # See if this group is a product group at all. + my $sth2 = $dbh->prepare("SELECT id FROM products + WHERE name = " .$dbh->quote($groupname)); + $sth2->execute(); + my ($id) = $sth2->fetchrow_array(); + if (!$id) { + # If there is no product with the same name as this + # group, then it is permitted for all products. + $dbh->do("INSERT INTO group_control_map " . + "(group_id, product_id, entry, membercontrol, " . + "othercontrol, canedit) " . + "VALUES ($groupid, $productid, 0, " . + CONTROLMAPSHOWN . ", " . + CONTROLMAPNA . ", 0)"); + } + } + } + } +} + +sub _remove_user_series_map { + my $dbh = Bugzilla->dbh; + # 2004-07-17 GRM - Remove "subscriptions" concept from charting, and add + # group-based security instead. + if ($dbh->bz_table_info("user_series_map")) { + # Oracle doesn't like "date" as a column name, and apparently some DBs + # don't like 'value' either. We use the changes to subscriptions as + # something to hang these renamings off. + $dbh->bz_rename_column('series_data', 'date', 'series_date'); + $dbh->bz_rename_column('series_data', 'value', 'series_value'); + + # series_categories.category_id produces a too-long column name for the + # auto-incrementing sequence (Oracle again). + $dbh->bz_rename_column('series_categories', 'category_id', 'id'); + + $dbh->bz_add_column("series", "public", + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); + + # Migrate public-ness across from user_series_map to new field + my $sth = $dbh->prepare("SELECT series_id from user_series_map " . + "WHERE user_id = 0"); + $sth->execute(); + while (my ($public_series_id) = $sth->fetchrow_array()) { + $dbh->do("UPDATE series SET public = 1 " . + "WHERE series_id = $public_series_id"); + } + + $dbh->bz_drop_table("user_series_map"); + } +} + +sub _copy_old_charts_into_database { + my $dbh = Bugzilla->dbh; + my $datadir = bz_locations()->{'datadir'}; + # 2003-06-26 Copy the old charting data into the database, and create the + # queries that will keep it all running. When the old charting system goes + # away, if this code ever runs, it'll just find no files and do nothing. + my $series_exists = $dbh->selectrow_array("SELECT 1 FROM series " . + $dbh->sql_limit(1)); + if (!$series_exists && -d "$datadir/mining" && -e "$datadir/mining/-All-") { + print "Migrating old chart data into database...\n"; + + # We prepare the handle to insert the series data + my $seriesdatasth = $dbh->prepare( + "INSERT INTO series_data (series_id, series_date, series_value) + VALUES (?, ?, ?)"); + + my $deletesth = $dbh->prepare( + "DELETE FROM series_data WHERE series_id = ? AND series_date = ?"); + + my $groupmapsth = $dbh->prepare( + "INSERT INTO category_group_map (category_id, group_id) + VALUES (?, ?)"); + + # Fields in the data file (matches the current collectstats.pl) + my @statuses = + qw(NEW ASSIGNED REOPENED UNCONFIRMED RESOLVED VERIFIED CLOSED); + my @resolutions = + qw(FIXED INVALID WONTFIX LATER REMIND DUPLICATE WORKSFORME MOVED); + my @fields = (@statuses, @resolutions); + + # We have a localisation problem here. Where do we get these values? + my $all_name = "-All-"; + my $open_name = "All Open"; + + my $products = $dbh->selectall_arrayref("SELECT name FROM products"); + + foreach my $product ((map { $_->[0] } @$products), "-All-") { + # First, create the series + my %queries; + my %seriesids; + + my $query_prod = ""; + if ($product ne "-All-") { + $query_prod = "product=" . html_quote($product) . "&"; + } + + # The query for statuses is different to that for resolutions. + $queries{$_} = ($query_prod . "bug_status=$_") foreach (@statuses); + $queries{$_} = ($query_prod . "resolution=$_") + foreach (@resolutions); + + foreach my $field (@fields) { + # Create a Series for each field in this product. + my $series = new Bugzilla::Series(undef, $product, $all_name, + $field, undef, 1, + $queries{$field}, 1); + $series->writeToDatabase(); + $seriesids{$field} = $series->{'series_id'}; + } + + # We also add a new query for "Open", so that migrated products get + # the same set as new products (see editproducts.cgi.) + my @openedstatuses = ("UNCONFIRMED", "NEW", "ASSIGNED", "REOPENED"); + my $query = join("&", map { "bug_status=$_" } @openedstatuses); + my $series = new Bugzilla::Series(undef, $product, $all_name, + $open_name, undef, 1, + $query_prod . $query, 1); + $series->writeToDatabase(); + $seriesids{$open_name} = $series->{'series_id'}; + + # Now, we attempt to read in historical data, if any + # Convert the name in the same way that collectstats.pl does + my $product_file = $product; + $product_file =~ s/\//-/gs; + $product_file = "$datadir/mining/$product_file"; + + # There are many reasons that this might fail (e.g. no stats + # for this product), so we don't worry if it does. + my $in = new IO::File($product_file) or next; + + # The data files should be in a standard format, even for old + # Bugzillas, because of the conversion code further up this file. + my %data; + my $last_date = ""; + + while (<$in>) { + if (/^(\d+\|.*)/) { + my @numbers = split(/\||\r/, $1); + + # Only take the first line for each date; it was possible to + # run collectstats.pl more than once in a day. + next if $numbers[0] eq $last_date; + + for my $i (0 .. $#fields) { + # $numbers[0] is the date + $data{$fields[$i]}{$numbers[0]} = $numbers[$i + 1]; + + # Keep a total of the number of open bugs for this day + if (is_open_state($fields[$i])) { + $data{$open_name}{$numbers[0]} += $numbers[$i + 1]; + } + } + + $last_date = $numbers[0]; + } + } + + $in->close; + + foreach my $field (@fields, $open_name) { + # Insert values into series_data: series_id, date, value + my %fielddata = %{$data{$field}}; + foreach my $date (keys %fielddata) { + # We need to delete in case the text file had duplicate + # entries in it. + $deletesth->execute($seriesids{$field}, $date); + + # We prepared this above + $seriesdatasth->execute($seriesids{$field}, + $date, $fielddata{$date} || 0); + } + } + + # Create the groupsets for the category + my $category_id = + $dbh->selectrow_array("SELECT id FROM series_categories " . + "WHERE name = " . $dbh->quote($product)); + my $product_id = + $dbh->selectrow_array("SELECT id FROM products " . + "WHERE name = " . $dbh->quote($product)); + + if (defined($category_id) && defined($product_id)) { + + # Get all the mandatory groups for this product + my $group_ids = + $dbh->selectcol_arrayref("SELECT group_id " . + "FROM group_control_map " . + "WHERE product_id = $product_id " . + "AND (membercontrol = " . CONTROLMAPMANDATORY . + " OR othercontrol = " . CONTROLMAPMANDATORY . ")"); + + foreach my $group_id (@$group_ids) { + $groupmapsth->execute($category_id, $group_id); + } + } + } + } +} + +sub _add_user_group_map_grant_type { + my $dbh = Bugzilla->dbh; + # 2004-04-12 - Keep regexp-based group permissions up-to-date - Bug 240325 + if ($dbh->bz_column_info("user_group_map", "isderived")) { + $dbh->bz_add_column('user_group_map', 'grant_type', + {TYPE => 'INT1', NOTNULL => 1, DEFAULT => '0'}); + $dbh->do("DELETE FROM user_group_map WHERE isderived != 0"); + $dbh->do("UPDATE user_group_map SET grant_type = " . GRANT_DIRECT); + $dbh->bz_drop_column("user_group_map", "isderived"); + + $dbh->bz_drop_index('user_group_map', 'user_group_map_user_id_idx'); + $dbh->bz_add_index('user_group_map', 'user_group_map_user_id_idx', + {TYPE => 'UNIQUE', + FIELDS => [qw(user_id group_id grant_type isbless)]}); + } +} + +sub _add_group_group_map_grant_type { + my $dbh = Bugzilla->dbh; + # 2004-07-16 - Make it possible to have group-group relationships other than + # membership and bless. + if ($dbh->bz_column_info("group_group_map", "isbless")) { + $dbh->bz_add_column('group_group_map', 'grant_type', + {TYPE => 'INT1', NOTNULL => 1, DEFAULT => '0'}); + $dbh->do("UPDATE group_group_map SET grant_type = " . + "IF(isbless, " . GROUP_BLESS . ", " . + GROUP_MEMBERSHIP . ")"); + $dbh->bz_drop_index('group_group_map', 'group_group_map_member_id_idx'); + $dbh->bz_drop_column("group_group_map", "isbless"); + $dbh->bz_add_index('group_group_map', 'group_group_map_member_id_idx', + {TYPE => 'UNIQUE', + FIELDS => [qw(member_id grantor_id grant_type)]}); + } +} + +sub _add_longdescs_already_wrapped { + my $dbh = Bugzilla->dbh; + # 2005-01-29 - mkanat@bugzilla.org + if (!$dbh->bz_column_info('longdescs', 'already_wrapped')) { + # Old, pre-wrapped comments should not be auto-wrapped + $dbh->bz_add_column('longdescs', 'already_wrapped', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}, 1); + # If an old comment doesn't have a newline in the first 81 characters, + # (or doesn't contain a newline at all) and it contains a space, + # then it's probably a mis-wrapped comment and we should wrap it + # at display-time. + print "Fixing old, mis-wrapped comments...\n"; + $dbh->do(q{UPDATE longdescs SET already_wrapped = 0 + WHERE (} . $dbh->sql_position(q{'\n'}, 'thetext') . q{ > 81 + OR } . $dbh->sql_position(q{'\n'}, 'thetext') . q{ = 0) + AND SUBSTRING(thetext FROM 1 FOR 80) LIKE '% %'}); + } +} + +sub _convert_attachments_filename_from_mediumtext { + my $dbh = Bugzilla->dbh; + # 2002 November, myk@mozilla.org, bug 178841: + # + # Convert the "attachments.filename" column from a ridiculously large + # "mediumtext" to a much more sensible "varchar(100)". Also takes + # the opportunity to remove paths from existing filenames, since they + # shouldn't be there for security. Buggy browsers include them, + # and attachment.cgi now takes them out, but old ones need converting. + my $ref = $dbh->bz_column_info("attachments", "filename"); + if ($ref->{TYPE} ne 'varchar(100)') { + print "Removing paths from filenames in attachments table...\n"; + + my $sth = $dbh->prepare("SELECT attach_id, filename FROM attachments " . + "WHERE " . $dbh->sql_position(q{'/'}, 'filename') . " > 0 OR " . + $dbh->sql_position(q{'\\\\'}, 'filename') . " > 0"); + $sth->execute; + + while (my ($attach_id, $filename) = $sth->fetchrow_array) { + $filename =~ s/^.*[\/\\]//; + my $quoted_filename = $dbh->quote($filename); + $dbh->do("UPDATE attachments SET filename = $quoted_filename " . + "WHERE attach_id = $attach_id"); + } + + print "Done.\n"; + + print "Resizing attachments.filename from mediumtext to", + " varchar(100).\n"; + $dbh->bz_alter_column("attachments", "filename", + {TYPE => 'varchar(100)', NOTNULL => 1}); + } +} + +sub _rename_votes_count_and_force_group_refresh { + my $dbh = Bugzilla->dbh; + # 2003-04-27 - bugzilla@chimpychompy.org (GavinS) + # + # Bug 180086 (http://bugzilla.mozilla.org/show_bug.cgi?id=180086) + # + # Renaming the 'count' column in the votes table because Sybase doesn't + # like it + if ($dbh->bz_column_info('votes', 'count')) { + $dbh->bz_rename_column('votes', 'count', 'vote_count'); + } +} + +sub _fix_group_with_empty_name { + my $dbh = Bugzilla->dbh; + # 2005-01-12 Nick Barnes <nb@ravenbrook.com> bug 278010 + # Rename any group which has an empty name. + # Note that there can be at most one such group (because of + # the SQL index on the name column). + my ($emptygroupid) = $dbh->selectrow_array( + "SELECT id FROM groups where name = ''"); + if ($emptygroupid) { + # There is a group with an empty name; find a name to rename it + # as. Must avoid collisions with existing names. Start with + # group_$gid and add _<n> if necessary. + my $trycount = 0; + my $trygroupname; + my $trygroupsth = $dbh->prepare("SELECT id FROM groups where name = ?"); + do { + $trygroupname = "group_$emptygroupid"; + if ($trycount > 0) { + $trygroupname .= "_$trycount"; + } + $trygroupsth->execute($trygroupname); + if ($trygroupsth->rows > 0) { + $trycount ++; + } + } while ($trygroupsth->rows > 0); + my $sth = $dbh->prepare("UPDATE groups SET name = ? " . + "WHERE id = $emptygroupid"); + $sth->execute($trygroupname); + print "Group $emptygroupid had an empty name; renamed as", + " '$trygroupname'.\n"; + } +} + +# A helper for the emailprefs subs below +sub _clone_email_event { + my ($source, $target) = @_; + my $dbh = Bugzilla->dbh; + + my $sth1 = $dbh->prepare("SELECT user_id, relationship FROM email_setting + WHERE event = $source"); + my $sth2 = $dbh->prepare("INSERT into email_setting " . + "(user_id, relationship, event) VALUES (" . + "?, ?, $target)"); + + $sth1->execute(); + + while (my ($userid, $relationship) = $sth1->fetchrow_array()) { + $sth2->execute($userid, $relationship); + } +} + +sub _migrate_email_prefs_to_new_table { + my $dbh = Bugzilla->dbh; + # 2005-03-29 - gerv@gerv.net - bug 73665. + # Migrate email preferences to new email prefs table. + if ($dbh->bz_column_info("profiles", "emailflags")) { + print "Migrating email preferences to new table...\n"; + + # These are the "roles" and "reasons" from the original code, mapped to + # the new terminology of relationships and events. + my %relationships = ("Owner" => REL_ASSIGNEE, + "Reporter" => REL_REPORTER, + "QAcontact" => REL_QA, + "CClist" => REL_CC, + "Voter" => REL_VOTER); + + my %events = ("Removeme" => EVT_ADDED_REMOVED, + "Comments" => EVT_COMMENT, + "Attachments" => EVT_ATTACHMENT, + "Status" => EVT_PROJ_MANAGEMENT, + "Resolved" => EVT_OPENED_CLOSED, + "Keywords" => EVT_KEYWORD, + "CC" => EVT_CC, + "Other" => EVT_OTHER, + "Unconfirmed" => EVT_UNCONFIRMED); + + # Request preferences + my %requestprefs = ("FlagRequestee" => EVT_FLAG_REQUESTED, + "FlagRequester" => EVT_REQUESTED_FLAG); + + # Select all emailflags flag strings + my $sth = $dbh->prepare("SELECT userid, emailflags FROM profiles"); + $sth->execute(); + my $i = 0; + my $total = $sth->rows; + + while (my ($userid, $flagstring) = $sth->fetchrow_array()) { + $i++; + indicate_progress({ total => $total, current => $i, every => 10 }); + # If the user has never logged in since emailprefs arrived, and the + # temporary code to give them a default string never ran, then + # $flagstring will be null. In this case, they just get all mail. + $flagstring ||= ""; + + # The 255 param is here, because without a third param, split will + # trim any trailing null fields, which causes Perl to eject lots of + # warnings. Any suitably large number would do. + my %emailflags = split(/~/, $flagstring, 255); + + my $sth2 = $dbh->prepare("INSERT into email_setting " . + "(user_id, relationship, event) VALUES (" . + "$userid, ?, ?)"); + foreach my $relationship (keys %relationships) { + foreach my $event (keys %events) { + my $key = "email$relationship$event"; + if (!exists($emailflags{$key}) + || $emailflags{$key} eq 'on') + { + $sth2->execute($relationships{$relationship}, + $events{$event}); + } + } + } + # Note that in the old system, the value of "excludeself" is + # assumed to be off if the preference does not exist in the + # user's list, unlike other preferences whose value is + # assumed to be on if they do not exist. + # + # This preference has changed from global to per-relationship. + if (!exists($emailflags{'ExcludeSelf'}) + || $emailflags{'ExcludeSelf'} ne 'on') + { + foreach my $relationship (keys %relationships) { + $dbh->do("INSERT into email_setting " . + "(user_id, relationship, event) VALUES (" . + $userid . ", " . + $relationships{$relationship}. ", " . + EVT_CHANGED_BY_ME . ")"); + } + } + + foreach my $key (keys %requestprefs) { + if (!exists($emailflags{$key}) || $emailflags{$key} eq 'on') { + $dbh->do("INSERT into email_setting " . + "(user_id, relationship, event) VALUES (" . + $userid . ", " . REL_ANY . ", " . + $requestprefs{$key} . ")"); + } + } + } + print "\n"; + + # EVT_ATTACHMENT_DATA should initially have identical settings to + # EVT_ATTACHMENT. + _clone_email_event(EVT_ATTACHMENT, EVT_ATTACHMENT_DATA); + + $dbh->bz_drop_column("profiles", "emailflags"); + } +} + +sub _initialize_dependency_tree_changes_email_pref { + my $dbh = Bugzilla->dbh; + # Check for any "new" email settings that wouldn't have been ported over + # during the block above. Since these settings would have otherwise + # fallen under EVT_OTHER, we'll just clone those settings. That way if + # folks have already disabled all of that mail, there won't be any change. + my %events = ("Dependency Tree Changes" => EVT_DEPEND_BLOCK); + + foreach my $desc (keys %events) { + my $event = $events{$desc}; + my $sth = $dbh->prepare("SELECT COUNT(*) FROM email_setting + WHERE event = $event"); + $sth->execute(); + if (!($sth->fetchrow_arrayref()->[0])) { + # No settings in the table yet, so we assume that this is the + # first time it's being set. + print "Initializing \"$desc\" email_setting ...\n"; + _clone_email_event(EVT_OTHER, $event); + } + } +} + +sub _change_all_mysql_booleans_to_tinyint { + my $dbh = Bugzilla->dbh; + # 2005-03-27: Standardize all boolean fields to plain "tinyint" + if ( $dbh->isa('Bugzilla::DB::Mysql') ) { + # This is a change to make things consistent with Schema, so we use + # direct-database access methods. + my $quip_info_sth = $dbh->column_info(undef, undef, 'quips', '%'); + my $quips_cols = $quip_info_sth->fetchall_hashref("COLUMN_NAME"); + my $approved_col = $quips_cols->{'approved'}; + if ( $approved_col->{TYPE_NAME} eq 'TINYINT' + and $approved_col->{COLUMN_SIZE} == 1 ) + { + # series.public could have been renamed to series.is_public, + # and so wouldn't need to be fixed manually. + if ($dbh->bz_column_info('series', 'public')) { + $dbh->bz_alter_column_raw('series', 'public', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '0'}); + } + $dbh->bz_alter_column_raw('bug_status', 'isactive', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'}); + $dbh->bz_alter_column_raw('rep_platform', 'isactive', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'}); + $dbh->bz_alter_column_raw('resolution', 'isactive', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'}); + $dbh->bz_alter_column_raw('op_sys', 'isactive', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'}); + $dbh->bz_alter_column_raw('bug_severity', 'isactive', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'}); + $dbh->bz_alter_column_raw('priority', 'isactive', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'}); + $dbh->bz_alter_column_raw('quips', 'approved', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'}); + } + } +} + +# A helper for the below function. +sub _de_dup_version { + my ($product_id, $version) = @_; + my $dbh = Bugzilla->dbh; + print "Fixing duplicate version $version in product_id $product_id...\n"; + $dbh->do('DELETE FROM versions WHERE product_id = ? AND value = ?', + undef, $product_id, $version); + $dbh->do('INSERT INTO versions (product_id, value) VALUES (?,?)', + undef, $product_id, $version); +} + +sub _add_versions_product_id_index { + my $dbh = Bugzilla->dbh; + if (!$dbh->bz_index_info('versions', 'versions_product_id_idx')) { + my $dup_versions = $dbh->selectall_arrayref( + 'SELECT product_id, value FROM versions + GROUP BY product_id, value HAVING COUNT(value) > 1', {Slice=>{}}); + foreach my $dup_version (@$dup_versions) { + _de_dup_version($dup_version->{product_id}, $dup_version->{value}); + } + + $dbh->bz_add_index('versions', 'versions_product_id_idx', + {TYPE => 'UNIQUE', FIELDS => [qw(product_id value)]}); + } +} + +sub _fix_whine_queries_title_and_op_sys_value { + my $dbh = Bugzilla->dbh; + if (!exists $dbh->bz_column_info('whine_queries', 'title')->{DEFAULT}) { + # The below change actually has nothing to do with the whine_queries + # change, it just has to be contained within a schema change so that + # it doesn't run every time we run checksetup. + + # Old Bugzillas have "other" as an OS choice, new ones have "Other" + # (capital O). + print "Setting any 'other' op_sys to 'Other'...\n"; + $dbh->do('UPDATE op_sys SET value = ? WHERE value = ?', + undef, "Other", "other"); + $dbh->do('UPDATE bugs SET op_sys = ? WHERE op_sys = ?', + undef, "Other", "other"); + if (Bugzilla->params->{'defaultopsys'} eq 'other') { + # We can't actually fix the param here, because WriteParams() will + # make $datadir/params unwriteable to the webservergroup. + # It's too much of an ugly hack to copy the permission-fixing code + # down to here. (It would create more potential future bugs than + # it would solve problems.) + print "WARNING: Your 'defaultopsys' param is set to 'other', but" + . " Bugzilla now\n" + . " uses 'Other' (capital O).\n"; + } + + # Add a DEFAULT to whine_queries stuff so that editwhines.cgi + # works on PostgreSQL. + $dbh->bz_alter_column('whine_queries', 'title', {TYPE => 'varchar(128)', + NOTNULL => 1, DEFAULT => "''"}); + } +} + +sub _fix_attachments_submitter_id_idx { + my $dbh = Bugzilla->dbh; + # 2005-06-29 bugreport@peshkin.net, bug 299156 + if ($dbh->bz_index_info('attachments', 'attachments_submitter_id_idx') + && (scalar(@{$dbh->bz_index_info('attachments', + 'attachments_submitter_id_idx' + )->{FIELDS}}) < 2)) + { + $dbh->bz_drop_index('attachments', 'attachments_submitter_id_idx'); + } + $dbh->bz_add_index('attachments', 'attachments_submitter_id_idx', + [qw(submitter_id bug_id)]); +} + +sub _copy_attachments_thedata_to_attach_data { + my $dbh = Bugzilla->dbh; + # 2005-08-25 - bugreport@peshkin.net - Bug 305333 + if ($dbh->bz_column_info("attachments", "thedata")) { + print "Migrating attachment data to its own table...\n"; + print "(This may take a very long time)\n"; + $dbh->do("INSERT INTO attach_data (id, thedata) + SELECT attach_id, thedata FROM attachments"); + $dbh->bz_drop_column("attachments", "thedata"); + } +} + +sub _fix_broken_all_closed_series { + my $dbh = Bugzilla->dbh; + + # 2005-11-26 - wurblzap@gmail.com - Bug 300473 + # Repair broken automatically generated series queries for non-open bugs. + my $broken_series_indicator = + 'field0-0-0=resolution&type0-0-0=notequals&value0-0-0=---'; + my $broken_nonopen_series = + $dbh->selectall_arrayref("SELECT series_id, query FROM series + WHERE query LIKE '$broken_series_indicator%'"); + if (@$broken_nonopen_series) { + print 'Repairing broken series...'; + my $sth_nuke = + $dbh->prepare('DELETE FROM series_data WHERE series_id = ?'); + # This statement is used to repair a series by replacing the broken + # query with the correct one. + my $sth_repair = + $dbh->prepare('UPDATE series SET query = ? WHERE series_id = ?'); + # The corresponding series for open bugs look like one of these two + # variations (bug 225687 changed the order of bug states). + # This depends on the set of bug states representing open bugs not + # to have changed since series creation. + my $open_bugs_query_base_old = + join("&", map { "bug_status=" . url_quote($_) } + ('UNCONFIRMED', 'NEW', 'ASSIGNED', 'REOPENED')); + my $open_bugs_query_base_new = + join("&", map { "bug_status=" . url_quote($_) } BUG_STATE_OPEN); + my $sth_openbugs_series = + $dbh->prepare("SELECT series_id FROM series WHERE query IN (?, ?)"); + # Statement to find the series which has collected the most data. + my $sth_data_collected = + $dbh->prepare('SELECT count(*) FROM series_data + WHERE series_id = ?'); + # Statement to select a broken non-open bugs count data entry. + my $sth_select_broken_nonopen_data = + $dbh->prepare('SELECT series_date, series_value FROM series_data' . + ' WHERE series_id = ?'); + # Statement to select an open bugs count data entry. + my $sth_select_open_data = + $dbh->prepare('SELECT series_value FROM series_data' . + ' WHERE series_id = ? AND series_date = ?'); + # Statement to fix a broken non-open bugs count data entry. + my $sth_fix_broken_nonopen_data = + $dbh->prepare('UPDATE series_data SET series_value = ?' . + ' WHERE series_id = ? AND series_date = ?'); + # Statement to delete an unfixable broken non-open bugs count data + # entry. + my $sth_delete_broken_nonopen_data = + $dbh->prepare('DELETE FROM series_data' . + ' WHERE series_id = ? AND series_date = ?'); + foreach (@$broken_nonopen_series) { + my ($broken_series_id, $nonopen_bugs_query) = @$_; + + # Determine the product-and-component part of the query. + if ($nonopen_bugs_query =~ /^$broken_series_indicator(.*)$/) { + my $prodcomp = $1; + + # If there is more than one series for the corresponding + # open-bugs series, we pick the one with the most data, + # which should be the one which was generated on creation. + # It's a pity we can't do subselects. + $sth_openbugs_series->execute( + $open_bugs_query_base_old . $prodcomp, + $open_bugs_query_base_new . $prodcomp); + + my ($found_open_series_id, $datacount) = (undef, -1); + foreach my $open_ser_id ($sth_openbugs_series->fetchrow_array) { + $sth_data_collected->execute($open_ser_id); + my ($this_datacount) = $sth_data_collected->fetchrow_array; + if ($this_datacount > $datacount) { + $datacount = $this_datacount; + $found_open_series_id = $open_ser_id; + } + } + + if ($found_open_series_id) { + # Move along corrupted series data and correct it. The + # corruption consists of it being the number of all bugs + # instead of the number of non-open bugs, so we calculate + # the correct count by subtracting the number of open bugs. + # If there is no corresponding open-bugs count for some + # reason (shouldn't happen), we drop the data entry. + print " $broken_series_id..."; + $sth_select_broken_nonopen_data->execute($broken_series_id); + while (my $rowref = + $sth_select_broken_nonopen_data->fetchrow_arrayref) + { + my ($date, $broken_value) = @$rowref; + my ($openbugs_value) = + $dbh->selectrow_array($sth_select_open_data, undef, + $found_open_series_id, $date); + if (defined($openbugs_value)) { + $sth_fix_broken_nonopen_data->execute + ($broken_value - $openbugs_value, + $broken_series_id, $date); + } + else { + print <<EOT; + +WARNING - During repairs of series $broken_series_id, the irreparable data +entry for date $date was encountered and is being deleted. + +Continuing repairs... +EOT + $sth_delete_broken_nonopen_data->execute + ($broken_series_id, $date); + } + } + + # Fix the broken query so that it collects correct data + # in the future. + $nonopen_bugs_query =~ + s/^$broken_series_indicator/field0-0-0=resolution&type0-0-0=regexp&value0-0-0=./; + $sth_repair->execute($nonopen_bugs_query, + $broken_series_id); + } + else { + print <<EOT; + +WARNING - Series $broken_series_id was meant to collect non-open bug +counts, but it has counted all bugs instead. It cannot be repaired +automatically because no series that collected open bug counts was found. +You'll probably want to delete or repair collected data for +series $broken_series_id manually + +Continuing repairs... +EOT + } # if ($found_open_series_id) + } # if ($nonopen_bugs_query =~ + } # foreach (@$broken_nonopen_series) + print " done.\n"; + } # if (@$broken_nonopen_series) +} + +sub _clean_control_characters_from_short_desc { + my $dbh = Bugzilla->dbh; + + # Fixup for Bug 101380 + # "Newlines, nulls, leading/trailing spaces are getting into summaries" + + my $controlchar_bugs = + $dbh->selectall_arrayref("SELECT short_desc, bug_id FROM bugs WHERE " . + $dbh->sql_regexp('short_desc', "'[[:cntrl:]]'")); + if (scalar(@$controlchar_bugs)) { + my $msg = 'Cleaning control characters from bug summaries...'; + my $found = 0; + foreach (@$controlchar_bugs) { + my ($short_desc, $bug_id) = @$_; + my $clean_short_desc = clean_text($short_desc); + if ($clean_short_desc ne $short_desc) { + print $msg if !$found; + $found = 1; + print " $bug_id..."; + $dbh->do("UPDATE bugs SET short_desc = ? WHERE bug_id = ?", + undef, $clean_short_desc, $bug_id); + } + } + print " done.\n" if $found; + } +} + +sub _stop_storing_inactive_flags { + my $dbh = Bugzilla->dbh; + # 2006-03-02 LpSolit@gmail.com - Bug 322285 + # Do not store inactive flags in the DB anymore. + if ($dbh->bz_column_info('flags', 'id')->{'TYPE'} eq 'INT3') { + # We first have to remove all existing inactive flags. + if ($dbh->bz_column_info('flags', 'is_active')) { + $dbh->do('DELETE FROM flags WHERE is_active = 0'); + } + + # Now we convert the id column to the auto_increment format. + $dbh->bz_alter_column('flags', 'id', + {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + + # And finally, we remove the is_active column. + $dbh->bz_drop_column('flags', 'is_active'); + } +} + +sub _change_short_desc_from_mediumtext_to_varchar { + my $dbh = Bugzilla->dbh; + # short_desc should not be a mediumtext, fix anything longer than 255 chars. + if($dbh->bz_column_info('bugs', 'short_desc')->{TYPE} eq 'MEDIUMTEXT') { + # Move extremely long summaries into a comment ("from" the Reporter), + # and then truncate the summary. + my $long_summary_bugs = $dbh->selectall_arrayref( + 'SELECT bug_id, short_desc, reporter + FROM bugs WHERE LENGTH(short_desc) > 255'); + + if (@$long_summary_bugs) { + print <<EOT; + +WARNING: Some of your bugs had summaries longer than 255 characters. +They have had their original summary copied into a comment, and then +the summary was truncated to 255 characters. The affected bug numbers were: +EOT + my $comment_sth = $dbh->prepare( + 'INSERT INTO longdescs (bug_id, who, thetext, bug_when) + VALUES (?, ?, ?, NOW())'); + my $desc_sth = $dbh->prepare('UPDATE bugs SET short_desc = ? + WHERE bug_id = ?'); + my @affected_bugs; + foreach my $bug (@$long_summary_bugs) { + my ($bug_id, $summary, $reporter_id) = @$bug; + my $summary_comment = "The original summary for this bug" + . " was longer than 255 characters, and so it was truncated" + . " when Bugzilla was upgraded. The original summary was:" + . "\n\n$summary"; + $comment_sth->execute($bug_id, $reporter_id, $summary_comment); + my $short_summary = substr($summary, 0, 252) . "..."; + $desc_sth->execute($short_summary, $bug_id); + push(@affected_bugs, $bug_id); + } + print join(', ', @affected_bugs) . "\n\n"; + } + + $dbh->bz_alter_column('bugs', 'short_desc', {TYPE => 'varchar(255)', + NOTNULL => 1}); + } +} + +sub _move_namedqueries_linkinfooter_to_its_own_table { + my $dbh = Bugzilla->dbh; + if ($dbh->bz_column_info("namedqueries", "linkinfooter")) { + # Move link-in-footer information into a table of its own. + my $sth_read = $dbh->prepare('SELECT id, userid + FROM namedqueries + WHERE linkinfooter = 1'); + my $sth_write = $dbh->prepare('INSERT INTO namedqueries_link_in_footer + (namedquery_id, user_id) VALUES (?, ?)'); + $sth_read->execute(); + while (my ($id, $userid) = $sth_read->fetchrow_array()) { + $sth_write->execute($id, $userid); + } + $dbh->bz_drop_column("namedqueries", "linkinfooter"); + } +} + +sub _add_classifications_sortkey { + my $dbh = Bugzilla->dbh; + # 2006-07-07 olav@bkor.dhs.org - Bug 277377 + # Add a sortkey to the classifications + if (!$dbh->bz_column_info('classifications', 'sortkey')) { + $dbh->bz_add_column('classifications', 'sortkey', + {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0}); + + my $class_ids = $dbh->selectcol_arrayref( + 'SELECT id FROM classifications ORDER BY name'); + my $sth = $dbh->prepare('UPDATE classifications SET sortkey = ? ' . + 'WHERE id = ?'); + my $sortkey = 0; + foreach my $class_id (@$class_ids) { + $sth->execute($sortkey, $class_id); + $sortkey += 100; + } + } +} + +sub _move_data_nomail_into_db { + my $dbh = Bugzilla->dbh; + my $datadir = bz_locations()->{'datadir'}; + # 2006-07-14 karl@kornel.name - Bug 100953 + # If a nomail file exists, move its contents into the DB + $dbh->bz_add_column('profiles', 'disable_mail', + { TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE' }); + if (-e "$datadir/nomail") { + # We have a data/nomail file, read it in and delete it + my %nomail; + print "Found a data/nomail file. Moving nomail entries into DB...\n"; + my $nomail_file = new IO::File("$datadir/nomail", 'r'); + while (<$nomail_file>) { + $nomail{trim($_)} = 1; + } + $nomail_file->close; + + # Go through each entry read. If a user exists, set disable_mail. + my $query = $dbh->prepare('UPDATE profiles + SET disable_mail = 1 + WHERE userid = ?'); + foreach my $user_to_check (keys %nomail) { + my $uid; + if ($uid = Bugzilla::User::login_to_id($user_to_check)) { + my $user = new Bugzilla::User($uid); + print "\tDisabling email for user ", $user->email, "\n"; + $query->execute($user->id); + delete $nomail{$user->email}; + } + } + + # If there are any nomail entries remaining, move them to nomail.bad + # and say something to the user. + if (scalar(keys %nomail)) { + print <<EOT; + +WARNING: The following users were listed in data/nomail, but do not +have an account here. The unmatched entries have been moved +to $datadir/nomail.bad: +EOT + my $nomail_bad = new IO::File("$datadir/nomail.bad", '>>'); + foreach my $unknown_user (keys %nomail) { + print "\t$unknown_user\n"; + print $nomail_bad "$unknown_user\n"; + delete $nomail{$unknown_user}; + } + $nomail_bad->close; + print "\n"; + } + + # Now that we don't need it, get rid of the nomail file. + unlink "$datadir/nomail"; + } +} + +sub _update_longdescs_who_index { + my $dbh = Bugzilla->dbh; + # When doing a search on who posted a comment, longdescs is joined + # against the bugs table. So we need an index on both of these, + # not just on "who". + my $who_index = $dbh->bz_index_info('longdescs', 'longdescs_who_idx'); + if (!$who_index || scalar @{$who_index->{FIELDS}} == 1) { + # If the index doesn't exist, this will harmlessly do nothing. + $dbh->bz_drop_index('longdescs', 'longdescs_who_idx'); + $dbh->bz_add_index('longdescs', 'longdescs_who_idx', [qw(who bug_id)]); + } +} + +sub _fix_uppercase_custom_field_names { + # Before the final release of 3.0, custom fields could be + # created with mixed-case names. + my $dbh = Bugzilla->dbh; + my $fields = $dbh->selectall_arrayref( + 'SELECT name, type FROM fielddefs WHERE custom = 1'); + foreach my $row (@$fields) { + my ($name, $type) = @$row; + if ($name ne lc($name)) { + $dbh->bz_rename_column('bugs', $name, lc($name)); + $dbh->bz_rename_table($name, lc($name)) + if $type == FIELD_TYPE_SINGLE_SELECT; + $dbh->do('UPDATE fielddefs SET name = ? WHERE name = ?', + undef, lc($name), $name); + } + } +} + +sub _fix_uppercase_index_names { + # We forgot to fix indexes in the above code. + my $dbh = Bugzilla->dbh; + my $fields = $dbh->selectcol_arrayref( + 'SELECT name FROM fielddefs WHERE type = ? AND custom = 1', + undef, FIELD_TYPE_SINGLE_SELECT); + foreach my $field (@$fields) { + my $indexes = $dbh->bz_table_indexes($field); + foreach my $name (keys %$indexes) { + next if $name eq lc($name); + my $index = $indexes->{$name}; + # Lowercase the name and everything in the definition. + my $new_name = lc($name); + my @new_fields = map {lc($_)} @{$index->{FIELDS}}; + my $new_def = {FIELDS => \@new_fields, TYPE => $index->{TYPE}}; + $new_def = \@new_fields if !$index->{TYPE}; + $dbh->bz_drop_index($field, $name); + $dbh->bz_add_index($field, $new_name, $new_def); + } + } +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Install::DB - Fix up the database during installation. + +=head1 SYNOPSIS + + use Bugzilla::Install::DB qw(indicate_progress); + Bugzilla::Install::DB::update_table_definitions(); + + indicate_progress({ total => $total, current => $count, every => 10 }); + +=head1 DESCRIPTION + +This module is used primarily by L<checksetup.pl> to modify the +database during upgrades. + +=head1 SUBROUTINES + +=over + +=item C<update_table_definitions()> + +Description: This is the primary code that updates table definitions + during upgrades. If you modify the schema in some + way, you should add code to the end of this function to + make sure that your modifications happen over all installations. + +Params: none + +Returns: nothing + +=item C<update_fielddefs_definition()> + +Description: L<checksetup.pl> depends on the fielddefs table having + its schema adjusted before the rest of the tables. So + these schema updates happen in a separate function from + L</update_table_definitions()>. + +Params: none + +Returns: nothing + +=item C<indicate_progress({ total => $total, current => $count, every => 1 })> + +Description: This prints out lines of dots as a long update is going on, + to let the user know where we are and that we're not frozen. + A new line of dots will start every 60 dots. + +Params: C<total> - The total number of items we're processing. + C<current> - The number of the current item we're processing. + C<every> - How often the function should print out a dot. + For example, if this is 10, the function will print out + a dot every ten items. + +Returns: nothing + +=back diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm new file mode 100644 index 000000000..c13df2893 --- /dev/null +++ b/Bugzilla/Install/Filesystem.pm @@ -0,0 +1,667 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> +# Bill Barry <after.fallout@gmail.com> + +package Bugzilla::Install::Filesystem; + +# NOTE: This package may "use" any modules that it likes, +# and localconfig is available. However, all functions in this +# package should assume that: +# +# * Templates are not available. +# * Files do not have the correct permissions. +# * The database does not exist. + +use strict; + +use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::Install::Localconfig; +use Bugzilla::Util; + +use File::Find; +use File::Path; +use IO::File; +use POSIX (); + +use base qw(Exporter); +our @EXPORT = qw( + update_filesystem + create_htaccess + fix_all_file_permissions +); + +# This looks like a constant because it effectively is, but +# it has to call other subroutines and read the current filesystem, +# so it's defined as a sub. This is not exported, so it doesn't have +# a perldoc. However, look at the various hashes defined inside this +# function to understand what it returns. (There are comments throughout.) +# +# The rationale for the file permissions is that the web server generally +# runs as apache, so the cgi scripts should not be writable for apache, +# otherwise someone may find it possible to change the cgis when exploiting +# some security flaw somewhere (not necessarily in Bugzilla!) +sub FILESYSTEM { + my $datadir = bz_locations()->{'datadir'}; + my $attachdir = bz_locations()->{'attachdir'}; + my $extensionsdir = bz_locations()->{'extensionsdir'}; + my $webdotdir = bz_locations()->{'webdotdir'}; + my $templatedir = bz_locations()->{'templatedir'}; + my $libdir = bz_locations()->{'libpath'}; + + my $ws_group = Bugzilla->localconfig->{'webservergroup'}; + + # The set of permissions that we use: + + # FILES + # Executable by the web server + my $ws_executable = $ws_group ? 0750 : 0755; + # Executable by the owner only. + my $owner_executable = 0700; + # Readable by the web server. + my $ws_readable = $ws_group ? 0640 : 0644; + # Readable by the owner only. + my $owner_readable = 0600; + # Writeable by the web server. + my $ws_writeable = $ws_group ? 0660 : 0666; + + # DIRECTORIES + # Readable by the web server. + my $ws_dir_readable = $ws_group ? 0750 : 0755; + # Readable only by the owner. + my $owner_dir_readable = 0700; + # Writeable by the web server. + my $ws_dir_writeable = $ws_group ? 0770 : 01777; + # The webserver can overwrite files owned by other users, + # in this directory. + my $ws_dir_full_control = $ws_group ? 0770 : 0777; + + # Note: When being processed by checksetup, these have their permissions + # set in this order: %all_dirs, %recurse_dirs, %all_files. + # + # Each is processed in alphabetical order of keys, so shorter keys + # will have their permissions set before longer keys (thus setting + # the permissions on parent directories before setting permissions + # on their children). + + # --- FILE PERMISSIONS (Non-created files) --- # + my %files = ( + '*' => { perms => $ws_readable }, + '*.cgi' => { perms => $ws_executable }, + 'whineatnews.pl' => { perms => $ws_executable }, + 'collectstats.pl' => { perms => $ws_executable }, + 'checksetup.pl' => { perms => $owner_executable }, + 'importxml.pl' => { perms => $ws_executable }, + 'runtests.pl' => { perms => $owner_executable }, + 'testserver.pl' => { perms => $ws_executable }, + 'whine.pl' => { perms => $ws_executable }, + 'customfield.pl' => { perms => $owner_executable }, + 'email_in.pl' => { perms => $ws_executable }, + + 'docs/makedocs.pl' => { perms => $owner_executable }, + 'docs/rel_notes.txt' => { perms => $ws_readable }, + 'docs/README.docs' => { perms => $owner_readable }, + "$datadir/bugzilla-update.xml" => { perms => $ws_writeable }, + "$datadir/params" => { perms => $ws_writeable }, + "$datadir/mailer.testfile" => { perms => $ws_writeable }, + ); + + # Directories that we want to set the perms on, but not + # recurse through. These are directories we didn't create + # in checkesetup.pl. + my %non_recurse_dirs = ( + '.' => $ws_dir_readable, + docs => $ws_dir_readable, + ); + + # This sets the permissions for each item inside each of these + # directories, including the directory itself. + # 'CVS' directories are special, though, and are never readable by + # the webserver. + my %recurse_dirs = ( + # Writeable directories + "$datadir/template" => { files => $ws_readable, + dirs => $ws_dir_full_control }, + $attachdir => { files => $ws_writeable, + dirs => $ws_dir_writeable }, + $webdotdir => { files => $ws_writeable, + dirs => $ws_dir_writeable }, + graphs => { files => $ws_writeable, + dirs => $ws_dir_writeable }, + + # Readable directories + "$datadir/mining" => { files => $ws_readable, + dirs => $ws_dir_readable }, + "$datadir/duplicates" => { files => $ws_readable, + dirs => $ws_dir_readable }, + "$libdir/Bugzilla" => { files => $ws_readable, + dirs => $ws_dir_readable }, + $templatedir => { files => $ws_readable, + dirs => $ws_dir_readable }, + images => { files => $ws_readable, + dirs => $ws_dir_readable }, + css => { files => $ws_readable, + dirs => $ws_dir_readable }, + js => { files => $ws_readable, + dirs => $ws_dir_readable }, + skins => { files => $ws_readable, + dirs => $ws_dir_readable }, + t => { files => $owner_readable, + dirs => $owner_dir_readable }, + 'docs/html' => { files => $ws_readable, + dirs => $ws_dir_readable }, + 'docs/pdf' => { files => $ws_readable, + dirs => $ws_dir_readable }, + 'docs/txt' => { files => $ws_readable, + dirs => $ws_dir_readable }, + 'docs/images' => { files => $ws_readable, + dirs => $ws_dir_readable }, + 'docs/lib' => { files => $owner_readable, + dirs => $owner_dir_readable }, + 'docs/xml' => { files => $owner_readable, + dirs => $owner_dir_readable }, + ); + + # --- FILES TO CREATE --- # + + # The name of each directory that we should actually *create*, + # pointing at its default permissions. + my %create_dirs = ( + $datadir => $ws_dir_full_control, + "$datadir/mimedump-tmp" => $ws_dir_writeable, + "$datadir/mining" => $ws_dir_readable, + "$datadir/duplicates" => $ws_dir_readable, + $attachdir => $ws_dir_writeable, + $extensionsdir => $ws_dir_readable, + graphs => $ws_dir_writeable, + $webdotdir => $ws_dir_writeable, + 'skins/custom' => $ws_dir_readable, + 'skins/contrib' => $ws_dir_readable, + ); + + # The name of each file, pointing at its default permissions and + # default contents. + my %create_files = ( + "$datadir/mail" => { perms => $ws_readable }, + ); + + # Each standard stylesheet has an associated custom stylesheet that + # we create. + foreach my $standard (<skins/standard/*.css>) { + my $custom = $standard; + $custom =~ s|^skins/standard|skins/custom|; + $create_files{$custom} = { perms => $ws_readable, contents => <<EOT +/* + * Custom rules for $standard. + * The rules you put here override rules in that stylesheet. + */ +EOT + }; + } + + # Because checksetup controls the creation of index.html separately + # from all other files, it gets its very own hash. + my %index_html = ( + 'index.html' => { perms => $ws_readable, contents => <<EOT +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> + <meta http-equiv="Refresh" content="0; URL=index.cgi"> +</head> +<body> + <h1>I think you are looking for <a href="index.cgi">index.cgi</a></h1> +</body> +</html> +EOT + } + ); + + # Because checksetup controls the .htaccess creation separately + # by a localconfig variable, these go in a separate variable from + # %create_files. + my $ht_default_deny = <<EOT; +# nothing in this directory is retrievable unless overridden by an .htaccess +# in a subdirectory +deny from all +EOT + + my %htaccess = ( + "$attachdir/.htaccess" => { perms => $ws_readable, + contents => $ht_default_deny }, + "$libdir/Bugzilla/.htaccess" => { perms => $ws_readable, + contents => $ht_default_deny }, + "$templatedir/.htaccess" => { perms => $ws_readable, + contents => $ht_default_deny }, + + '.htaccess' => { perms => $ws_readable, contents => <<EOT +# Don't allow people to retrieve non-cgi executable files or our private data +<FilesMatch ^(.*\\.pm|.*\\.pl|.*localconfig.*)\$> + deny from all +</FilesMatch> +EOT + }, + + "$webdotdir/.htaccess" => { perms => $ws_readable, contents => <<EOT +# Restrict access to .dot files to the public webdot server at research.att.com +# if research.att.com ever changes their IP, or if you use a different +# webdot server, you'll need to edit this +<FilesMatch \\.dot\$> + Allow from 192.20.225.0/24 + Deny from all +</FilesMatch> + +# Allow access to .png files created by a local copy of 'dot' +<FilesMatch \\.png\$> + Allow from all +</FilesMatch> + +# And no directory listings, either. +Deny from all +EOT + }, + + # Even though $datadir may not (and should not) be in the webtree, + # we can't know for sure, so create the .htaccess anyway. It's harmless + # if it's not accessible... + "$datadir/.htaccess" => { perms => $ws_readable, contents => <<EOT +# Nothing in this directory is retrievable unless overridden by an .htaccess +# in a subdirectory; the only exception is duplicates.rdf, which is used by +# duplicates.xul and must be loadable over the web +deny from all +<Files duplicates.rdf> + allow from all +</Files> +EOT + + + }, + ); + + my %all_files = (%create_files, %htaccess, %index_html, %files); + my %all_dirs = (%create_dirs, %non_recurse_dirs); + + return { + create_dirs => \%create_dirs, + recurse_dirs => \%recurse_dirs, + all_dirs => \%all_dirs, + + create_files => \%create_files, + htaccess => \%htaccess, + index_html => \%index_html, + all_files => \%all_files, + }; +} + +sub update_filesystem { + my ($params) = @_; + my $fs = FILESYSTEM(); + my %dirs = %{$fs->{create_dirs}}; + my %files = %{$fs->{create_files}}; + + my $datadir = bz_locations->{'datadir'}; + # If the graphs/ directory doesn't exist, we're upgrading from + # a version old enough that we need to update the $datadir/mining + # format. + if (-d "$datadir/mining" && !-d 'graphs') { + _update_old_charts($datadir); + } + + # By sorting the dirs, we assure that shorter-named directories + # (meaning parent directories) are always created before their + # child directories. + foreach my $dir (sort keys %dirs) { + unless (-d $dir) { + print "Creating $dir directory...\n"; + mkdir $dir || die $!; + # For some reason, passing in the permissions to "mkdir" + # doesn't work right, but doing a "chmod" does. + chmod $dirs{$dir}, $dir || die $!; + } + } + + _create_files(%files); + if ($params->{index_html}) { + _create_files(%{$fs->{index_html}}); + } + elsif (-e 'index.html') { + my $templatedir = bz_locations()->{'templatedir'}; + print <<EOT; + +*** It appears that you still have an old index.html hanging around. + Either the contents of this file should be moved into a template and + placed in the '$templatedir/en/custom' directory, or you should delete + the file. + +EOT + } + + # Delete old files that no longer need to exist + + # 2001-04-29 jake@bugzilla.org - Remove oldemailtech + # http://bugzilla.mozilla.org/show_bugs.cgi?id=71552 + if (-d 'shadow') { + print "Removing shadow directory...\n"; + rmtree("shadow"); + } + + if (-e "$datadir/versioncache") { + print "Removing versioncache...\n"; + unlink "$datadir/versioncache"; + } + +} + +sub create_htaccess { + _create_files(%{FILESYSTEM()->{htaccess}}); + + # Repair old .htaccess files + my $htaccess = new IO::File('.htaccess', 'r') || die ".htaccess: $!"; + my $old_data; + { local $/; $old_data = <$htaccess>; } + $htaccess->close; + + my $repaired = 0; + if ($old_data =~ s/\|localconfig\|/\|.*localconfig.*\|/) { + $repaired = 1; + } + if ($old_data !~ /\(\.\*\\\.pm\|/) { + $old_data =~ s/\(/(.*\\.pm\|/; + $repaired = 1; + } + if ($repaired) { + print "Repairing .htaccess...\n"; + $htaccess = new IO::File('.htaccess', 'w') || die $!; + print $htaccess $old_data; + $htaccess->close; + } + + + my $webdot_dir = bz_locations()->{'webdotdir'}; + # The public webdot IP address changed. + my $webdot = new IO::File("$webdot_dir/.htaccess", 'r') + || die "$webdot_dir/.htaccess: $!"; + my $webdot_data; + { local $/; $webdot_data = <$webdot>; } + $webdot->close; + if ($webdot_data =~ /192\.20\.225\.10/) { + print "Repairing $webdot_dir/.htaccess...\n"; + $webdot_data =~ s/192\.20\.225\.10/192.20.225.0\/24/g; + $webdot = new IO::File("$webdot_dir/.htaccess", 'w') || die $!; + print $webdot $webdot_data; + $webdot->close; + } +} + +# A helper for the above functions. +sub _create_files { + my (%files) = @_; + + # It's not necessary to sort these, but it does make the + # output of checksetup.pl look a bit nicer. + foreach my $file (sort keys %files) { + unless (-e $file) { + print "Creating $file...\n"; + my $info = $files{$file}; + my $fh = new IO::File($file, O_WRONLY | O_CREAT, $info->{perms}) + || die $!; + print $fh $info->{contents} if $info->{contents}; + $fh->close; + } + } +} + +# If you ran a REALLY old version of Bugzilla, your chart files are in the +# wrong format. This code is a little messy, because it's very old, and +# when moving it into this module, I couldn't test it so I left it almost +# completely alone. +sub _update_old_charts { + my ($datadir) = @_; + print "Updating old chart storage format...\n"; + foreach my $in_file (glob("$datadir/mining/*")) { + # Don't try and upgrade image or db files! + next if (($in_file =~ /\.gif$/i) || + ($in_file =~ /\.png$/i) || + ($in_file =~ /\.db$/i) || + ($in_file =~ /\.orig$/i)); + + rename("$in_file", "$in_file.orig") or next; + open(IN, "$in_file.orig") or next; + open(OUT, '>', $in_file) or next; + + # Fields in the header + my @declared_fields; + + # Fields we changed to half way through by mistake + # This list comes from an old version of collectstats.pl + # This part is only for people who ran later versions of 2.11 (devel) + my @intermediate_fields = qw(DATE UNCONFIRMED NEW ASSIGNED REOPENED + RESOLVED VERIFIED CLOSED); + + # Fields we actually want (matches the current collectstats.pl) + my @out_fields = qw(DATE NEW ASSIGNED REOPENED UNCONFIRMED RESOLVED + VERIFIED CLOSED FIXED INVALID WONTFIX LATER REMIND + DUPLICATE WORKSFORME MOVED); + + while (<IN>) { + if (/^# fields?: (.*)\s$/) { + @declared_fields = map uc, (split /\||\r/, $1); + print OUT "# fields: ", join('|', @out_fields), "\n"; + } + elsif (/^(\d+\|.*)/) { + my @data = split(/\||\r/, $1); + my %data; + if (@data == @declared_fields) { + # old format + for my $i (0 .. $#declared_fields) { + $data{$declared_fields[$i]} = $data[$i]; + } + } + elsif (@data == @intermediate_fields) { + # Must have changed over at this point + for my $i (0 .. $#intermediate_fields) { + $data{$intermediate_fields[$i]} = $data[$i]; + } + } + elsif (@data == @out_fields) { + # This line's fine - it has the right number of entries + for my $i (0 .. $#out_fields) { + $data{$out_fields[$i]} = $data[$i]; + } + } + else { + print "Oh dear, input line $. of $in_file had " . + scalar(@data) . " fields\nThis was unexpected.", + " You may want to check your data files.\n"; + } + + print OUT join('|', + map { defined ($data{$_}) ? ($data{$_}) : "" } @out_fields), + "\n"; + } + else { + print OUT; + } + } + + close(IN); + close(OUT); + } +} + + +sub fix_all_file_permissions { + my ($output) = @_; + + my $ws_group = Bugzilla->localconfig->{'webservergroup'}; + my $group_id = _check_web_server_group($ws_group, $output); + + return if ON_WINDOWS; + + my $fs = FILESYSTEM(); + my %files = %{$fs->{all_files}}; + my %dirs = %{$fs->{all_dirs}}; + my %recurse_dirs = %{$fs->{recurse_dirs}}; + + print get_text('install_file_perms_fix') . "\n" if $output; + + my $owner_id = POSIX::getuid(); + $group_id = POSIX::getgid() unless defined $group_id; + + foreach my $dir (sort keys %dirs) { + next unless -d $dir; + _fix_perms($dir, $owner_id, $group_id, $dirs{$dir}); + } + + foreach my $dir (sort keys %recurse_dirs) { + next unless -d $dir; + # Set permissions on the directory itself. + my $perms = $recurse_dirs{$dir}; + _fix_perms($dir, $owner_id, $group_id, $perms->{dirs}); + # Now recurse through the directory and set the correct permissions + # on subdirectories and files. + find({ no_chdir => 1, wanted => sub { + my $name = $File::Find::name; + if (-d $name) { + _fix_perms($name, $owner_id, $group_id, $perms->{dirs}); + } + else { + _fix_perms($name, $owner_id, $group_id, $perms->{files}); + } + }}, $dir); + } + + foreach my $file (sort keys %files) { + # %files supports globs + foreach my $filename (glob $file) { + # Don't touch directories. + next if -d $filename || !-e $filename; + _fix_perms($filename, $owner_id, $group_id, + $files{$file}->{perms}); + } + } + + _fix_cvs_dirs($owner_id, '.'); +} + +# A helper for fix_all_file_permissions +sub _fix_cvs_dirs { + my ($owner_id, $dir) = @_; + my $owner_gid = POSIX::getgid(); + find({ no_chdir => 1, wanted => sub { + my $name = $File::Find::name; + if ($File::Find::dir =~ /\/CVS/ || $_ eq '.cvsignore' + || (-d $name && $_ eq 'CVS')) { + _fix_perms($name, $owner_id, $owner_gid, 0700); + } + }}, $dir); +} + +sub _fix_perms { + my ($name, $owner, $group, $perms) = @_; + #printf ("Changing $name to %o\n", $perms); + chown $owner, $group, $name + || warn "Failed to change ownership of $name: $!"; + chmod $perms, $name + || warn "Failed to change permissions of $name: $!"; +} + +sub _check_web_server_group { + my ($group, $output) = @_; + + my $filename = bz_locations()->{'localconfig'}; + my $group_id; + + # If we are on Windows, webservergroup does nothing + if (ON_WINDOWS && $group && $output) { + print "\n\n" . get_text('install_webservergroup_windows') . "\n\n"; + } + + # If we're not on Windows, make sure that webservergroup isn't + # empty. + elsif (!ON_WINDOWS && !$group && $output) { + print "\n\n" . get_text('install_webservergroup_empty') . "\n\n"; + } + + # If we're not on Windows, make sure we are actually a member of + # the webservergroup. + elsif (!ON_WINDOWS && $group) { + $group_id = getgrnam($group); + ThrowCodeError('invalid_webservergroup', { group => $group }) + unless defined $group_id; + + # If on unix, see if we need to print a warning about a webservergroup + # that we can't chgrp to + if ($output && $< != 0 && !grep($_ eq $group_id, split(" ", $)))) { + print "\n\n" . get_text('install_webservergroup_not_in') . "\n\n"; + } + } + + return $group_id; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Install::Filesystem - Fix up the filesystem during + installation. + +=head1 DESCRIPTION + +This module is used primarily by L<checksetup.pl> to modify the +filesystem during installation, including creating the data/ directory. + +=head1 SUBROUTINES + +=over + +=item C<update_filesystem({ index_html => 0 })> + +Description: Creates all the directories and files that Bugzilla + needs to function but doesn't ship with. Also does + any updates to these files as necessary during an + upgrade. + +Params: C<index_html> - Whether or not we should create + the F<index.html> file. + +Returns: nothing + +=item C<create_htaccess()> + +Description: Creates all of the .htaccess files for Apache, + in the various Bugzilla directories. Also updates + the .htaccess files if they need updating. + +Params: none + +Returns: nothing + +=item C<fix_all_file_permissions($output)> + +Description: Sets all the file permissions on all of Bugzilla's files + to what they should be. Note that permissions are different + depending on whether or not C<$webservergroup> is set + in F<localconfig>. + +Params: C<$output> - C<true> if you want this function to print + out information about what it's doing. + +Returns: nothing + +=back diff --git a/Bugzilla/Install/Localconfig.pm b/Bugzilla/Install/Localconfig.pm new file mode 100644 index 000000000..ed502d8a7 --- /dev/null +++ b/Bugzilla/Install/Localconfig.pm @@ -0,0 +1,471 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Initial Developer of the Original Code is Everything Solved. +# Portions created by Everything Solved are Copyright (C) 2006 +# Everything Solved. All Rights Reserved. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + +package Bugzilla::Install::Localconfig; + +# NOTE: This package may "use" any modules that it likes. However, +# all functions in this package should assume that: +# +# * The data/ directory does not exist. +# * Templates are not available. +# * Files do not have the correct permissions +# * The database is not up to date + +use strict; + +use Bugzilla::Constants; + +use Data::Dumper; +use IO::File; +use Safe; + +use base qw(Exporter); + +our @EXPORT_OK = qw( + read_localconfig + update_localconfig +); + +use constant LOCALCONFIG_VARS => ( + { + name => 'create_htaccess', + default => 1, + desc => <<EOT +# If you are using Apache as your web server, Bugzilla can create .htaccess +# files for you that will instruct Apache not to serve files that shouldn't +# be accessed from the web (like your local configuration data and non-cgi +# executable files). For this to work, the directory your Bugzilla +# installation is in must be within the jurisdiction of a <Directory> block +# in the httpd.conf file that has 'AllowOverride Limit' in it. If it has +# 'AllowOverride All' or other options with Limit, that's fine. +# (Older Apache installations may use an access.conf file to store these +# <Directory> blocks.) +# If this is set to 1, Bugzilla will create these files if they don't exist. +# If this is set to 0, Bugzilla will not create these files. +EOT + }, + { + name => 'webservergroup', + default => ON_WINDOWS ? '' : 'apache', + desc => q{# This is the group your web server runs as. +# If you have a Windows box, ignore this setting. +# If you do not have access to the group your web server runs under, +# set this to "". If you do set this to "", then your Bugzilla installation +# will be _VERY_ insecure, because some files will be world readable/writable, +# and so anyone who can get local access to your machine can do whatever they +# want. You should only have this set to "" if this is a testing installation +# and you cannot set this up any other way. YOU HAVE BEEN WARNED! +# If you set this to anything other than "", you will need to run checksetup.pl +# as} . ROOT_USER . qq{, or as a user who is a member of the specified group.\n} + }, + { + name => 'db_driver', + default => 'mysql', + desc => <<EOT +# What SQL database to use. Default is mysql. List of supported databases +# can be obtained by listing Bugzilla/DB directory - every module corresponds +# to one supported database and the name corresponds to a driver name. +EOT + }, + { + name => 'db_host', + default => 'localhost', + desc => + "# The DNS name of the host that the database server runs on.\n" + }, + { + name => 'db_name', + default => 'bugs', + desc => "# The name of the database\n" + }, + { + name => 'db_user', + default => 'bugs', + desc => "# Who we connect to the database as.\n" + }, + { + name => 'db_pass', + default => '', + desc => <<EOT +# Enter your database password here. It's normally advisable to specify +# a password for your bugzilla database user. +# If you use apostrophe (') or a backslash (\\) in your password, you'll +# need to escape it by preceding it with a '\\' character. (\\') or (\\) +# (Far simpler just not to use those characters.) +EOT + }, + { + name => 'db_port', + default => 0, + desc => <<EOT +# Sometimes the database server is running on a non-standard port. If that's +# the case for your database server, set this to the port number that your +# database server is running on. Setting this to 0 means "use the default +# port for my database server." +EOT + }, + { + name => 'db_sock', + default => '', + desc => <<EOT +# MySQL Only: Enter a path to the unix socket for MySQL. If this is +# blank, then MySQL's compiled-in default will be used. You probably +# want that. +EOT + }, + { + name => 'db_check', + default => 1, + desc => <<EOT +# Should checksetup.pl try to verify that your database setup is correct? +# (with some combinations of database servers/Perl modules/moonphase this +# doesn't work) +EOT + }, + { + name => 'index_html', + default => 0, + desc => <<EOT +# With the introduction of a configurable index page using the +# template toolkit, Bugzilla's main index page is now index.cgi. +# Most web servers will allow you to use index.cgi as a directory +# index, and many come preconfigured that way, but if yours doesn't +# then you'll need an index.html file that provides redirection +# to index.cgi. Setting \$index_html to 1 below will allow +# checksetup.pl to create one for you if it doesn't exist. +# NOTE: checksetup.pl will not replace an existing file, so if you +# wish to have checksetup.pl create one for you, you must +# make sure that index.html doesn't already exist +EOT + }, + { + name => 'cvsbin', + default => \&_get_default_cvsbin, + desc => <<EOT +# For some optional functions of Bugzilla (such as the pretty-print patch +# viewer), we need the cvs binary to access files and revisions. +# Because it's possible that this program is not in your path, you can specify +# its location here. Please specify the full path to the executable. +EOT + }, + { + name => 'interdiffbin', + default => \&_get_default_interdiffbin, + desc => <<EOT +# For some optional functions of Bugzilla (such as the pretty-print patch +# viewer), we need the interdiff binary to make diffs between two patches. +# Because it's possible that this program is not in your path, you can specify +# its location here. Please specify the full path to the executable. +EOT + }, + { + name => 'diffpath', + default => \&_get_default_diffpath, + desc => <<EOT +# The interdiff feature needs diff, so we have to have that path. +# Please specify the directory name only; do not use trailing slash. +EOT + }, +); + +use constant OLD_LOCALCONFIG_VARS => qw( + mysqlpath + contenttypes + pages + severities platforms opsys priorities +); + +sub read_localconfig { + my ($include_deprecated) = @_; + my $filename = bz_locations()->{'localconfig'}; + + my %localconfig; + if (-e $filename) { + my $s = new Safe; + # Some people like to store their database password in another file. + $s->permit('dofile'); + + $s->rdo($filename); + if ($@ || $!) { + my $err_msg = $@ ? $@ : $!; + die <<EOT; +An error has occurred while reading your 'localconfig' file. The text of +the error message is: + +$err_msg + +Please fix the error in your 'localconfig' file. Alternately, rename your +'localconfig' file, rerun checksetup.pl, and re-enter your answers. + + \$ mv -f localconfig localconfig.old + \$ ./checksetup.pl +EOT + } + + my @vars = map($_->{name}, LOCALCONFIG_VARS); + push(@vars, OLD_LOCALCONFIG_VARS) if $include_deprecated; + foreach my $var (@vars) { + my $glob = $s->varglob($var); + # We can't get the type of a variable out of a Safe automatically. + # We can only get the glob itself. So we figure out its type this + # way, by trying first a scalar, then an array, then a hash. + # + # The interesting thing is that this converts all deprecated + # array or hash vars into hashrefs or arrayrefs, but that's + # fine since as I write this all modern localconfig vars are + # actually scalars. + if (defined $$glob) { + $localconfig{$var} = $$glob; + } + elsif (defined @$glob) { + $localconfig{$var} = \@$glob; + } + elsif (defined %$glob) { + $localconfig{$var} = \%$glob; + } + } + } + + return \%localconfig; +} + + +# +# This is quite tricky. But fun! +# +# First we read the file 'localconfig'. Then we check if the variables we +# need are defined. If not, we will append the new settings to +# localconfig, instruct the user to check them, and stop. +# +# Why do it this way? +# +# Assume we will enhance Bugzilla and eventually more local configuration +# stuff arises on the horizon. +# +# But the file 'localconfig' is not in the Bugzilla CVS or tarfile. You +# know, we never want to overwrite your own version of 'localconfig', so +# we can't put it into the CVS/tarfile, can we? +# +# Now, when we need a new variable, we simply add the necessary stuff to +# LOCALCONFIG_VARS. When the user gets the new version of Bugzilla from CVS and +# runs checksetup, it finds out "Oh, there is something new". Then it adds +# some default value to the user's local setup and informs the user to +# check that to see if it is what the user wants. +# +# Cute, ey? +# +sub update_localconfig { + my ($params) = @_; + + my $output = $params->{output} || 0; + my $answer = Bugzilla->installation_answers; + my $localconfig = read_localconfig('include deprecated'); + + my @new_vars; + foreach my $var (LOCALCONFIG_VARS) { + my $name = $var->{name}; + if (!defined $localconfig->{$name}) { + push(@new_vars, $name); + $var->{default} = &{$var->{default}} if ref($var->{default}) eq 'CODE'; + $localconfig->{$name} = $answer->{$name} || $var->{default}; + } + } + + my @old_vars; + foreach my $name (OLD_LOCALCONFIG_VARS) { + push(@old_vars, $name) if defined $localconfig->{$name}; + } + + if (!$localconfig->{'interdiffbin'} && $output) { + print <<EOT + +OPTIONAL NOTE: If you want to be able to use the 'difference between two +patches' feature of Bugzilla (which requires the PatchReader Perl module +as well), you should install patchutils from: + + http://cyberelk.net/tim/patchutils/ + +EOT + } + + my $filename = bz_locations->{'localconfig'}; + + if (scalar @old_vars) { + my $oldstuff = join(', ', @old_vars); + print <<EOT + +The following variables are no longer used in $filename, and +should be removed: $oldstuff + +EOT + } + + if (scalar @new_vars) { + my $filename = bz_locations->{'localconfig'}; + my $fh = new IO::File($filename, '>>') || die "$filename: $!"; + $fh->seek(0, SEEK_END); + foreach my $var (LOCALCONFIG_VARS) { + if (grep($_ eq $var->{name}, @new_vars)) { + print $fh "\n", $var->{desc}, + Data::Dumper->Dump([$localconfig->{$var->{name}}], + ["*$var->{name}"]); + } + } + + my $newstuff = join(', ', @new_vars); + print <<EOT; + +This version of Bugzilla contains some variables that you may want to +change and adapt to your local settings. Please edit the file +$filename and rerun checksetup.pl. + +The following variables are new to $filename since you last ran +checksetup.pl: $newstuff + +EOT + exit; + } + + # Reset the cache for Bugzilla->localconfig so that it will be re-read + delete Bugzilla->request_cache->{localconfig}; + + return { old_vars => \@old_vars, new_vars => \@new_vars }; +} + +sub _get_default_cvsbin { + return '' if ON_WINDOWS; + + my $cvs_executable = `which cvs`; + if ($cvs_executable =~ /no cvs/ || $cvs_executable eq '') { + # If which didn't find it, just set to blank + $cvs_executable = ""; + } else { + chomp $cvs_executable; + } + return $cvs_executable; +} + +sub _get_default_interdiffbin { + return '' if ON_WINDOWS; + + my $interdiff = `which interdiff`; + if ($interdiff =~ /no interdiff/ || $interdiff eq '') { + # If which didn't find it, just set to blank + $interdiff = ''; + } else { + chomp $interdiff; + } + return $interdiff; +} + +sub _get_default_diffpath { + return '' if ON_WINDOWS; + + my $diff_binaries; + $diff_binaries = `which diff`; + if ($diff_binaries =~ /no diff/ || $diff_binaries eq '') { + # If which didn't find it, set to blank + $diff_binaries = ""; + } else { + $diff_binaries =~ s:/diff\n$::; + } + return $diff_binaries; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Install::Localconfig - Functions and variables dealing + with the manipulation and creation of the F<localconfig> file. + +=head1 SYNOPSIS + + use Bugzilla::Install::Requirements qw(update_localconfig); + update_localconfig({ output => 1 }); + +=head1 DESCRIPTION + +This module is used primarily by L<checksetup.pl> to create and +modify the localconfig file. Most scripts should use L<Bugzilla/localconfig> +to access localconfig variables. + +=head1 CONSTANTS + +=over + +=item C<LOCALCONFIG_VARS> + +An array of hashrefs. These hashrefs contain three keys: + + name - The name of the variable. + default - The default value for the variable. Should always be + something that can fit in a scalar. + desc - Additional text to put in localconfig before the variable + definition. Must end in a newline. Each line should start + with "#" unless you have some REALLY good reason not + to do that. + +=item C<OLD_LOCALCONFIG_VARS> + +An array of names of variables. If C<update_localconfig> finds these +variables defined in localconfig, it will print out a warning. + +=back + +=head1 SUBROUTINES + +=over + +=item C<read_localconfig($include_deprecated)> + +Description: Reads the localconfig file and returns all valid + values in a hashref. + +Params: C<$include_deprecated> - C<true> if you want the returned + hashref to also include variables listed in + C<OLD_LOCALCONFIG_VARS>, if they exist. Generally + this is only for use by C<update_localconfig>. + +Returns: A hashref of the localconfig variables. If an array + is defined, it will be an arrayref in the returned hash. If a + hash is defined, it will be a hashref in the returned hash. + Only includes variables specified in C<LOCALCONFIG_VARS> + (and C<OLD_LOCALCONFIG_VARS> if C<$include_deprecated> is + specified). + +=item C<update_localconfig({ output =E<gt> 1 })> + +Description: Adds any new variables to localconfig that aren't + currently defined there. Also optionally prints out + a message about vars that *should* be there and aren't. + Exits the program if it adds any new vars. + +Params: C<output> - C<true> if the function should display informational + output and warnings. It will always display errors or + any message which would cause program execution to halt. + +Returns: A hashref, with C<old_vals> being an array of names of variables + that were removed, and C<new_vals> being an array of names + of variables that were added to localconfig. + +=back diff --git a/Bugzilla/Install/Requirements.pm b/Bugzilla/Install/Requirements.pm new file mode 100644 index 000000000..43cdaf7ec --- /dev/null +++ b/Bugzilla/Install/Requirements.pm @@ -0,0 +1,698 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> +# Marc Schumann <wurblzap@gmail.com> + +package Bugzilla::Install::Requirements; + +# NOTE: This package MUST NOT "use" any Bugzilla modules other than +# Bugzilla::Constants, anywhere. We may "use" standard perl modules. +# +# Subroutines may "require" and "import" from modules, but they +# MUST NOT "use." + +use strict; + +use List::Util qw(max); +use POSIX (); +use Safe; + +use base qw(Exporter); +our @EXPORT = qw( + REQUIRED_MODULES + OPTIONAL_MODULES + + check_requirements + check_graphviz + display_version_and_os + have_vers + vers_cmp + install_command +); + +use Bugzilla::Constants; + +# The below two constants are subroutines so that they can implement +# a hook. Other than that they are actually constants. + +# "package" is the perl package we're checking for. "module" is the name +# of the actual module we load with "require" to see if the package is +# installed or not. "version" is the version we need, or 0 if we'll accept +# any version. +# +# "blacklist" is an arrayref of regular expressions that describe versions that +# are 'blacklisted'--that is, even if the version is high enough, Bugzilla +# will refuse to say that it's OK to run with that version. +sub REQUIRED_MODULES { + my @modules = ( + { + package => 'CGI', + module => 'CGI', + version => '2.93' + }, + { + package => 'TimeDate', + module => 'Date::Format', + version => '2.21' + }, + { + package => 'DBI', + module => 'DBI', + version => '1.41' + }, + { + package => 'PathTools', + module => 'File::Spec', + version => '0.84' + }, + { + package => 'Template-Toolkit', + module => 'Template', + version => '2.12' + }, + { + package => 'Email-Send', + module => 'Email::Send', + version => ON_WINDOWS ? '2.16' : '2.00' + }, + { + # This will pull in Email::MIME for us, also. + package => 'Email-MIME-Modifier', + module => 'Email::MIME::Modifier', + version => 0 + }, + ); + + my $all_modules = _get_extension_requirements( + 'REQUIRED_MODULES', \@modules); + return $all_modules; +}; + +sub OPTIONAL_MODULES { + my @modules = ( + { + package => 'GD', + module => 'GD', + version => '1.20', + feature => 'Graphical Reports, New Charts, Old Charts' + }, + { + package => 'Template-GD', + # This module tells us whether or not Template-GD is installed + # on Template-Toolkits after 2.14, and still works with 2.14 and lower. + module => 'Template::Plugin::GD::Image', + version => 0, + feature => 'Graphical Reports' + }, + { + package => 'Chart', + module => 'Chart::Base', + version => '1.0', + feature => 'New Charts, Old Charts' + }, + { + package => 'GDGraph', + module => 'GD::Graph', + version => 0, + feature => 'Graphical Reports' + }, + { + package => 'GDTextUtil', + module => 'GD::Text', + version => 0, + feature => 'Graphical Reports' + }, + { + package => 'XML-Twig', + module => 'XML::Twig', + version => 0, + feature => 'Move Bugs Between Installations' + }, + { + package => 'MIME-tools', + # MIME::Parser is packaged as MIME::Tools on ActiveState Perl + module => ON_WINDOWS ? 'MIME::Tools' : 'MIME::Parser', + version => '5.406', + feature => 'Move Bugs Between Installations' + }, + { + package => 'libwww-perl', + module => 'LWP::UserAgent', + version => 0, + feature => 'Automatic Update Notifications' + }, + { + package => 'PatchReader', + module => 'PatchReader', + version => '0.9.4', + feature => 'Patch Viewer' + }, + { + package => 'PerlMagick', + module => 'Image::Magick', + version => 0, + feature => 'Optionally Convert BMP Attachments to PNGs' + }, + { + package => 'perl-ldap', + module => 'Net::LDAP', + version => 0, + feature => 'LDAP Authentication' + }, + { + package => 'SOAP-Lite', + module => 'SOAP::Lite', + version => 0, + feature => 'XML-RPC Interface' + }, + { + # We need the 'utf8_mode' method of HTML::Parser, for HTML::Scrubber. + package => 'HTML-Parser', + module => 'HTML::Parser', + version => '3.40', + feature => 'More HTML in Product/Group Descriptions' + }, + { + package => 'HTML-Scrubber', + module => 'HTML::Scrubber', + version => 0, + feature => 'More HTML in Product/Group Descriptions' + }, + + # Inbound Email + { + package => 'Email-MIME-Attachment-Stripper', + module => 'Email::MIME::Attachment::Stripper', + version => 0, + feature => 'Inbound Email' + }, + { + package => 'Email-Reply', + module => 'Email::Reply', + version => 0, + feature => 'Inbound Email' + }, + + # mod_perl + { + package => 'mod_perl', + module => 'mod_perl2', + version => '1.999022', + feature => 'mod_perl' + }, + # Even very new releases of perl (5.8.5) don't come with this version, + # so I didn't want to make it a general requirement just for + # running under mod_cgi. + { + package => 'CGI', + module => 'CGI', + version => '3.11', + feature => 'mod_perl' + }, + { + package => 'Apache-DBI', + module => 'Apache::DBI', + version => '0.96', + feature => 'mod_perl' + }, + ); + + my $all_modules = _get_extension_requirements( + 'OPTIONAL_MODULES', \@modules); + return $all_modules; +}; + +# This implements the install-requirements hook described in Bugzilla::Hook. +sub _get_extension_requirements { + my ($function, $base_modules) = @_; + my @all_modules; + # get a list of all extensions + my @extensions = glob(bz_locations()->{'extensionsdir'} . "/*"); + foreach my $extension (@extensions) { + my $file = "$extension/code/install-requirements.pl"; + if (-e $file) { + my $safe = new Safe; + # This is a very liberal Safe. + $safe->permit(qw(:browse require entereval caller)); + $safe->rdo($file); + if ($@) { + warn $@; + next; + } + my $modules = eval { &{$safe->varglob($function)}($base_modules) }; + next unless $modules; + push(@all_modules, @$modules); + } + } + + unshift(@all_modules, @$base_modules); + return \@all_modules; +}; + +sub check_requirements { + my ($output) = @_; + + print "\nChecking perl modules...\n" if $output; + my $root = ROOT_USER; + my %missing = _check_missing(REQUIRED_MODULES, $output); + + print "\nChecking available perl DBD modules...\n" if $output; + my $have_one_dbd = 0; + my $db_modules = DB_MODULE; + foreach my $db (keys %$db_modules) { + my $dbd = $db_modules->{$db}->{dbd}; + $have_one_dbd = 1 if have_vers($dbd, $output); + } + + print "\nThe following Perl modules are optional:\n" if $output; + my %missing_optional = _check_missing(OPTIONAL_MODULES, $output); + + # If we're running on Windows, reset the input line terminator so that + # console input works properly - loading CGI tends to mess it up + $/ = "\015\012" if ON_WINDOWS; + + my $pass = !scalar(keys %missing) && $have_one_dbd; + return { + pass => $pass, + one_dbd => $have_one_dbd, + missing => \%missing, + optional => \%missing_optional, + any_missing => !$pass || scalar(keys %missing_optional), + }; +} + +# A helper for check_requirements +sub _check_missing { + my ($modules, $output) = @_; + + my %missing; + foreach my $module (@$modules) { + unless (have_vers($module, $output)) { + $missing{$module->{package}} = $module; + } + } + + return %missing; +} + +sub print_module_instructions { + my ($check_results, $output) = @_; + + # We only print these notes if we have to. + if ((!$output && %{$check_results->{missing}}) + || ($output && $check_results->{any_missing})) + { + print "\n* NOTE: You must run any commands listed below as " + . ROOT_USER . ".\n\n"; + + if (ON_WINDOWS) { + print <<EOT; +*********************************************************************** +* Note For Windows Users * +*********************************************************************** +* In order to install the modules listed below, you first have to run * +* the following command as an Administrator: * +* * +* ppm repo add theory58S http://theoryx5.uwinnipeg.ca/ppms * +* * +* Then you have to do (also as an Administrator): * +* * +* ppm repo up theory58S * +* * +* Do that last command over and over until you see "theory58S" at the * +* top of the displayed list. * +*********************************************************************** +EOT + } + } + + # Required Modules + if (my %missing = %{$check_results->{missing}}) { + print <<EOT; +*********************************************************************** +* REQUIRED MODULES * +*********************************************************************** +* Bugzilla requires you to install some Perl modules which are either * +* missing from your system, or the version on your system is too old. * +* * +* The latest versions of each module can be installed by running the * +* commands below. * +*********************************************************************** +EOT + + print "COMMANDS:\n\n"; + foreach my $package (keys %missing) { + my $command = install_command($missing{$package}); + print " $command\n"; + } + print "\n"; + } + + if (!$check_results->{one_dbd}) { + print <<EOT; +*********************************************************************** +* DATABASE ACCESS * +*********************************************************************** +* In order to access your database, Bugzilla requires that the * +* correct "DBD" module be installed for the database that you are * +* running. * +* * +* Pick and run the correct command below for the database that you * +* plan to use with Bugzilla. * +*********************************************************************** +COMMANDS: + +EOT + + my %db_modules = %{DB_MODULE()}; + foreach my $db (keys %db_modules) { + my $command = install_command($db_modules{$db}->{dbd}); + printf "%10s: \%s\n", $db_modules{$db}->{name}, $command; + print ' ' x 12 . "Minimum version required: " + . $db_modules{$db}->{dbd}->{version} . "\n"; + } + print "\n"; + } + + return unless $output; + + if (my %missing = %{$check_results->{optional}}) { + print <<EOT; +********************************************************************** +* OPTIONAL MODULES * +********************************************************************** +* Certain Perl modules are not required by Bugzilla, but by * +* installing the latest version you gain access to additional * +* features. * +* * +* The optional modules you do not have installed are listed below, * +* with the name of the feature they enable. If you want to install * +* one of these modules, just run the appropriate command in the * +* "COMMANDS TO INSTALL" section. * +********************************************************************** + +EOT + # We want to sort them so that they are ordered by feature. + my @missing_names = sort {$missing{$a}->{feature} + cmp $missing{$b}->{feature}} (keys %missing); + + # Now we have to determine how large the table cols will be. + my $longest_name = max(map(length($_), @missing_names)); + + # The first column header is at least 11 characters long. + $longest_name = 11 if $longest_name < 11; + + # The table is 71 characters long. There are seven mandatory + # characters (* and space) in the string. So, we have a total + # of 64 characters to work with. + my $remaining_space = 64 - $longest_name; + print '*' x 71 . "\n"; + printf "* \%${longest_name}s * %-${remaining_space}s *\n", + 'MODULE NAME', 'ENABLES FEATURE(S)'; + print '*' x 71 . "\n"; + foreach my $name (@missing_names) { + printf "* \%${longest_name}s * %-${remaining_space}s *\n", + $name, $missing{$name}->{feature}; + } + print '*' x 71 . "\n"; + + print "COMMANDS TO INSTALL:\n\n"; + foreach my $module (@missing_names) { + my $command = install_command($missing{$module}); + printf "%15s: $command\n", $module; + } + } +} + +sub check_graphviz { + my ($output) = @_; + + return 1 if (Bugzilla->params->{'webdotbase'} =~ /^https?:/); + + printf("Checking for %15s %-9s ", "GraphViz", "(any)") if $output; + + my $return = 0; + if(-x Bugzilla->params->{'webdotbase'}) { + print "ok: found\n" if $output; + $return = 1; + } else { + print "not a valid executable: " . Bugzilla->params->{'webdotbase'} . "\n"; + } + + my $webdotdir = bz_locations()->{'webdotdir'}; + # Check .htaccess allows access to generated images + if (-e "$webdotdir/.htaccess") { + my $htaccess = new IO::File("$webdotdir/.htaccess", 'r') + || die "$webdotdir/.htaccess: " . $!; + if (!grep(/png/, $htaccess->getlines)) { + print "Dependency graph images are not accessible.\n"; + print "delete $webdotdir/.htaccess and re-run checksetup.pl to fix.\n"; + } + $htaccess->close; + } + + return $return; +} + +sub display_version_and_os { + # Display version information + printf "\n* This is Bugzilla " . BUGZILLA_VERSION . " on perl %vd\n", + $^V; + my @os_details = POSIX::uname; + # 0 is the name of the OS, 2 is the major version, + my $os_name = $os_details[0] . ' ' . $os_details[2]; + if (ON_WINDOWS) { + require Win32; + $os_name = Win32::GetOSName(); + } + # 3 is the minor version. + print "* Running on $os_name $os_details[3]\n" +} + +# This was originally clipped from the libnet Makefile.PL, adapted here to +# use the below vers_cmp routine for accurate version checking. +sub have_vers { + my ($params, $output) = @_; + my $module = $params->{module}; + my $package = $params->{package}; + if (!$package) { + $package = $module; + $package =~ s/::/-/g; + } + my $wanted = $params->{version}; + + my ($msg, $vnum, $vstr); + no strict 'refs'; + printf("Checking for %15s %-9s ", $package, !$wanted?'(any)':"(v$wanted)") + if $output; + + eval "require $module;"; + + # VERSION is provided by UNIVERSAL:: + $vnum = eval { $module->VERSION } || -1; + + # CGI's versioning scheme went 2.75, 2.751, 2.752, 2.753, 2.76 + # That breaks the standard version tests, so we need to manually correct + # the version + if ($module eq 'CGI' && $vnum =~ /(2\.7\d)(\d+)/) { + $vnum = $1 . "." . $2; + } + + if ($vnum eq "-1") { # string compare just in case it's non-numeric + $vstr = "not found"; + } + elsif (vers_cmp($vnum,"0") > -1) { + $vstr = "found v$vnum"; + } + else { + $vstr = "found unknown version"; + } + + my $vok = (vers_cmp($vnum,$wanted) > -1); + my $blacklisted; + if ($vok && $params->{blacklist}) { + $blacklisted = grep($vnum =~ /$_/, @{$params->{blacklist}}); + $vok = 0 if $blacklisted; + } + + my $ok = $vok ? "ok:" : ""; + my $black_string = $blacklisted ? "(blacklisted)" : ""; + print "$ok $vstr $black_string\n" if $output; + return $vok ? 1 : 0; +} + +# This is taken straight from Sort::Versions 1.5, which is not included +# with perl by default. +sub vers_cmp { + my ($a, $b) = @_; + + # Remove leading zeroes - Bug 344661 + $a =~ s/^0*(\d.+)/$1/; + $b =~ s/^0*(\d.+)/$1/; + + my @A = ($a =~ /([-.]|\d+|[^-.\d]+)/g); + my @B = ($b =~ /([-.]|\d+|[^-.\d]+)/g); + + my ($A, $B); + while (@A and @B) { + $A = shift @A; + $B = shift @B; + if ($A eq '-' and $B eq '-') { + next; + } elsif ( $A eq '-' ) { + return -1; + } elsif ( $B eq '-') { + return 1; + } elsif ($A eq '.' and $B eq '.') { + next; + } elsif ( $A eq '.' ) { + return -1; + } elsif ( $B eq '.' ) { + return 1; + } elsif ($A =~ /^\d+$/ and $B =~ /^\d+$/) { + if ($A =~ /^0/ || $B =~ /^0/) { + return $A cmp $B if $A cmp $B; + } else { + return $A <=> $B if $A <=> $B; + } + } else { + $A = uc $A; + $B = uc $B; + return $A cmp $B if $A cmp $B; + } + } + @A <=> @B; +} + +sub install_command { + my $module = shift; + my ($command, $package); + + if (ON_WINDOWS) { + $command = 'ppm install %s'; + $package = $module->{package}; + } + else { + $command = "$^X -MCPAN -e 'install \%s'"; + # Non-Windows installations need to use module names, because + # CPAN doesn't understand package names. + $package = $module->{module}; + } + return sprintf $command, $package; +} + + +1; + +__END__ + +=head1 NAME + +Bugzilla::Install::Requirements - Functions and variables dealing + with Bugzilla's perl-module requirements. + +=head1 DESCRIPTION + +This module is used primarily by C<checksetup.pl> to determine whether +or not all of Bugzilla's prerequisites are installed. (That is, all the +perl modules it requires.) + +=head1 CONSTANTS + +=over 4 + +=item C<REQUIRED_MODULES> + +An arrayref of hashrefs that describes the perl modules required by +Bugzilla. The hashes have two keys, C<name> and C<version>, which +represent the name of the module and the version that we require. + +=back + +=head1 SUBROUTINES + +=over 4 + +=item C<check_requirements($output)> + + Description: This checks what optional or required perl modules + are installed, like C<checksetup.pl> does. + + Params: C<$output> - C<true> if you want the function to print + out information about what it's doing, + and the versions of everything installed. + If you don't pass the minimum requirements, + the will always print out something, + regardless of this parameter. + + Returns: A hashref containing three values: + C<pass> - Whether or not we have all the mandatory + requirements. + C<missing> - A hash showing which mandatory requirements + are missing. The key is the module name, + and the value is the version we require. + C<optional> - Which optional modules are installed and + up-to-date enough for Bugzilla. + +=item C<check_graphviz($output)> + +Description: Checks if the graphviz binary specified in the + C<webdotbase> parameter is a valid binary, or a valid URL. + +Params: C<$output> - C<$true> if you want the function to + print out information about what it's doing. + +Returns: C<1> if the check was successful, C<0> otherwise. + +=item C<vers_cmp($a, $b)> + + Description: This is a comparison function, like you would use in + C<sort>, except that it compares two version numbers. + It's actually identical to versioncmp from + L<Sort::Versions>. + + Params: c<$a> and C<$b> are versions you want to compare. + + Returns: -1 if $a is less than $b, 0 if they are equal, and + 1 if $a is greater than $b. + +=item C<have_vers($module, $output)> + + Description: Tells you whether or not you have the appropriate + version of the module requested. It also prints + out a message to the user explaining the check + and the result. + + Params: C<$module> - A hashref, in the format of an item from + L</REQUIRED_MODULES>. + C<$output> - Set to true if you want this function to + print information to STDOUT about what it's + doing. + + Returns: C<1> if you have the module installed and you have the + appropriate version. C<0> otherwise. + +=item C<install_command($module)> + + Description: Prints out the appropriate command to install the + module specified, depending on whether you're + on Windows or Linux. + + Params: C<$module> - A hashref, in the format of an item from + L</REQUIRED_MODULES>. + + Returns: nothing + +=back diff --git a/Bugzilla/Keyword.pm b/Bugzilla/Keyword.pm new file mode 100644 index 000000000..2152b338d --- /dev/null +++ b/Bugzilla/Keyword.pm @@ -0,0 +1,189 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + +use strict; + +package Bugzilla::Keyword; + +use base qw(Bugzilla::Object); + +use Bugzilla::Error; +use Bugzilla::Util; + +############################### +#### Initialization #### +############################### + +use constant DB_COLUMNS => qw( + keyworddefs.id + keyworddefs.name + keyworddefs.description +); + +use constant DB_TABLE => 'keyworddefs'; + +use constant REQUIRED_CREATE_FIELDS => qw(name description); + +use constant VALIDATORS => { + name => \&_check_name, + description => \&_check_description, +}; + +use constant UPDATE_COLUMNS => qw( + name + description +); + +############################### +#### Accessors ###### +############################### + +sub description { return $_[0]->{'description'}; } + +sub bug_count { + my ($self) = @_; + return $self->{'bug_count'} if defined $self->{'bug_count'}; + ($self->{'bug_count'}) = + Bugzilla->dbh->selectrow_array( + 'SELECT COUNT(*) FROM keywords WHERE keywordid = ?', + undef, $self->id); + return $self->{'bug_count'}; +} + +############################### +#### Mutators ##### +############################### + +sub set_name { $_[0]->set('name', $_[1]); } +sub set_description { $_[0]->set('description', $_[1]); } + +############################### +#### Subroutines ###### +############################### + +sub keyword_count { + my ($count) = + Bugzilla->dbh->selectrow_array('SELECT COUNT(*) FROM keyworddefs'); + return $count; +} + +sub get_all_with_bug_count { + my $class = shift; + my $dbh = Bugzilla->dbh; + my $keywords = + $dbh->selectall_arrayref('SELECT ' . join(', ', DB_COLUMNS) . ', + COUNT(keywords.bug_id) AS bug_count + FROM keyworddefs + LEFT JOIN keywords + ON keyworddefs.id = keywords.keywordid ' . + $dbh->sql_group_by('keyworddefs.id', + 'keyworddefs.name, + keyworddefs.description') . ' + ORDER BY keyworddefs.name', {'Slice' => {}}); + if (!$keywords) { + return []; + } + + foreach my $keyword (@$keywords) { + bless($keyword, $class); + } + return $keywords; +} + +############################### +### Validators ### +############################### + +sub _check_name { + my ($self, $name) = @_; + + $name = trim($name); + $name eq "" && ThrowUserError("keyword_blank_name"); + if ($name =~ /[\s,]/) { + ThrowUserError("keyword_invalid_name"); + } + + # We only want to validate the non-existence of the name if + # we're creating a new Keyword or actually renaming the keyword. + if (!ref($self) || $self->name ne $name) { + my $keyword = new Bugzilla::Keyword({ name => $name }); + ThrowUserError("keyword_already_exists", { name => $name }) if $keyword; + } + + return $name; +} + +sub _check_description { + my ($self, $desc) = @_; + $desc = trim($desc); + $desc eq '' && ThrowUserError("keyword_blank_description"); + return $desc; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Keyword - A Keyword that can be added to a bug. + +=head1 SYNOPSIS + + use Bugzilla::Keyword; + + my $count = Bugzilla::Keyword::keyword_count; + + my $description = $keyword->description; + + my $keywords = Bugzilla::Keyword->get_all_with_bug_count(); + +=head1 DESCRIPTION + +Bugzilla::Keyword represents a keyword that can be added to a bug. + +This implements all standard C<Bugzilla::Object> methods. See +L<Bugzilla::Object> for more details. + +=head1 SUBROUTINES + +This is only a list of subroutines specific to C<Bugzilla::Keyword>. +See L<Bugzilla::Object> for more subroutines that this object +implements. + +=over + +=item C<keyword_count()> + + Description: A utility function to get the total number + of keywords defined. Mostly used to see + if there are any keywords defined at all. + Params: none + Returns: An integer, the count of keywords. + +=item C<get_all_with_bug_count()> + + Description: Returns all defined keywords. This is an efficient way + to get the associated bug counts, as only one SQL query + is executed with this method, instead of one per keyword + when calling get_all and then bug_count. + Params: none + Returns: A reference to an array of Keyword objects, or an empty + arrayref if there are no keywords. + +=back + +=cut diff --git a/Bugzilla/Mailer.pm b/Bugzilla/Mailer.pm new file mode 100644 index 000000000..d5ecb5a38 --- /dev/null +++ b/Bugzilla/Mailer.pm @@ -0,0 +1,116 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): Terry Weissman <terry@mozilla.org>, +# Bryce Nesbitt <bryce-mozilla@nextbus.com> +# Dan Mosedale <dmose@mozilla.org> +# Alan Raetz <al_raetz@yahoo.com> +# Jacob Steenhagen <jake@actex.net> +# Matthew Tuck <matty@chariot.net.au> +# Bradley Baetz <bbaetz@student.usyd.edu.au> +# J. Paul Reed <preed@sigkill.com> +# Gervase Markham <gerv@gerv.net> +# Byron Jones <bugzilla@glob.com.au> +# Frédéric Buclin <LpSolit@gmail.com> +# Max Kanat-Alexander <mkanat@bugzilla.org> + +package Bugzilla::Mailer; + +use strict; + +use base qw(Exporter); +@Bugzilla::Mailer::EXPORT = qw(MessageToMTA); + +use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::Util; + +use Encode qw(encode); +use Email::MIME; +# Loading this gives us encoding_set. +use Email::MIME::Modifier; +use Email::Send; + +sub MessageToMTA { + my ($msg) = (@_); + my $method = Bugzilla->params->{'mail_delivery_method'}; + return if $method eq 'None'; + + my $email = ref($msg) ? $msg : Email::MIME->new($msg); + foreach my $part ($email->parts) { + $part->charset_set('UTF-8') if Bugzilla->params->{'utf8'}; + $part->encoding_set('quoted-printable') if !is_7bit_clean($part->body); + } + + # MIME-Version must be set otherwise some mailsystems ignore the charset + $email->header_set('MIME-Version', '1.0') if !$email->header('MIME-Version'); + + # Encode the headers correctly in quoted-printable + foreach my $header qw(From To Cc Reply-To Sender Errors-To Subject) { + if (my $value = $email->header($header)) { + my $encoded = encode('MIME-Q', $value); + $email->header_set($header, $encoded); + } + } + + my $from = $email->header('From'); + + my ($hostname, @args); + if ($method eq "Sendmail") { + if (ON_WINDOWS) { + $Email::Send::Sendmail::SENDMAIL = SENDMAIL_EXE; + } + push @args, "-i"; + push(@args, "-f$from") if $from; + push(@args, "-ODeliveryMode=deferred") + if !Bugzilla->params->{"sendmailnow"}; + } + else { + # Sendmail will automatically append our hostname to the From + # address, but other mailers won't. + my $urlbase = Bugzilla->params->{'urlbase'}; + $urlbase =~ m|//([^/]+)/?|; + $hostname = $1; + $from .= "\@$hostname" if $from !~ /@/; + $email->header_set('From', $from); + } + + if ($method eq "SMTP") { + push @args, Host => Bugzilla->params->{"smtpserver"}, + Hello => $hostname; + } + + if ($method eq "Test") { + my $filename = bz_locations()->{'datadir'} . '/mailer.testfile'; + open TESTFILE, '>>', $filename; + print TESTFILE "\n\n---\n\n" . $email->as_string; + close TESTFILE; + } + else { + # This is useful for both Sendmail and Qmail, so we put it out here. + local $ENV{PATH} = SENDMAIL_PATH; + my $mailer = Email::Send->new({ mailer => $method, + mailer_args => \@args }); + my $retval = $mailer->send($email); + ThrowCodeError('mail_send_error', { msg => $retval, mail => $email }) + if !$retval; + } +} + +1; diff --git a/Bugzilla/Milestone.pm b/Bugzilla/Milestone.pm index 7b5d47d49..2e70b4e2d 100644 --- a/Bugzilla/Milestone.pm +++ b/Bugzilla/Milestone.pm @@ -13,11 +13,14 @@ # The Original Code is the Bugzilla Bug Tracking System. # # Contributor(s): Tiago R. Mello <timello@async.com.br> +# Max Kanat-Alexander <mkanat@bugzilla.org> use strict; package Bugzilla::Milestone; +use base qw(Bugzilla::Object); + use Bugzilla::Util; use Bugzilla::Error; @@ -27,50 +30,45 @@ use Bugzilla::Error; use constant DEFAULT_SORTKEY => 0; +use constant DB_TABLE => 'milestones'; + use constant DB_COLUMNS => qw( - milestones.value - milestones.product_id - milestones.sortkey + id + value + product_id + sortkey ); -my $columns = join(", ", DB_COLUMNS); +use constant NAME_FIELD => 'value'; +use constant LIST_ORDER => 'sortkey, value'; sub new { - my $invocant = shift; - my $class = ref($invocant) || $invocant; - my $self = {}; - bless($self, $class); - return $self->_init(@_); -} - -sub _init { - my $self = shift; - my ($product_id, $value) = (@_); + my $class = shift; + my $param = shift; my $dbh = Bugzilla->dbh; - my $milestone; - - if (defined $product_id - && detaint_natural($product_id) - && defined $value) { - - trick_taint($value); - $milestone = $dbh->selectrow_hashref(qq{ - SELECT $columns FROM milestones - WHERE value = ? - AND product_id = ?}, undef, ($value, $product_id)); - } else { - ThrowCodeError('bad_arg', - {argument => 'product_id/value', - function => 'Bugzilla::Milestone::_init'}); + my $product; + if (ref $param) { + $product = $param->{product}; + my $name = $param->{name}; + if (!defined $product) { + ThrowCodeError('bad_arg', + {argument => 'product', + function => "${class}::new"}); + } + if (!defined $name) { + ThrowCodeError('bad_arg', + {argument => 'name', + function => "${class}::new"}); + } + + my $condition = 'product_id = ? AND value = ?'; + my @values = ($product->id, $name); + $param = { condition => $condition, values => \@values }; } - return undef unless (defined $milestone); - - foreach my $field (keys %$milestone) { - $self->{$field} = $milestone->{$field}; - } - return $self; + unshift @_, $param; + return $class->SUPER::new(@_); } sub bug_count { @@ -105,8 +103,8 @@ sub check_milestone { ThrowUserError('milestone_not_specified'); } - my $milestone = new Bugzilla::Milestone($product->id, - $milestone_name); + my $milestone = new Bugzilla::Milestone({ product => $product, + name => $milestone_name }); unless ($milestone) { ThrowUserError('milestone_not_valid', {'product' => $product->name, @@ -141,7 +139,8 @@ Bugzilla::Milestone - Bugzilla product milestone class. use Bugzilla::Milestone; - my $milestone = new Bugzilla::Milestone(1, 'milestone_value'); + my $milestone = new Bugzilla::Milestone( + { product => $product, name => 'milestone_value' }); my $product_id = $milestone->product_id; my $value = $milestone->value; diff --git a/Bugzilla/Object.pm b/Bugzilla/Object.pm new file mode 100644 index 000000000..30ecc77e2 --- /dev/null +++ b/Bugzilla/Object.pm @@ -0,0 +1,595 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Everything Solved. +# Portions created by Everything Solved are Copyright (C) 2006 +# Everything Solved. All Rights Reserved. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> +# Frédéric Buclin <LpSolit@gmail.com> + +use strict; + +package Bugzilla::Object; + +use Bugzilla::Util; +use Bugzilla::Error; + +use constant NAME_FIELD => 'name'; +use constant ID_FIELD => 'id'; +use constant LIST_ORDER => NAME_FIELD; + +############################### +#### Initialization #### +############################### + +sub new { + my $invocant = shift; + my $class = ref($invocant) || $invocant; + my $object = $class->_init(@_); + bless($object, $class) if $object; + return $object; +} + + +# Note: Because this uses sql_istrcmp, if you make a new object use +# Bugzilla::Object, make sure that you modify bz_setup_database +# in Bugzilla::DB::Pg appropriately, to add the right LOWER +# index. You can see examples already there. +sub _init { + my $class = shift; + my ($param) = @_; + my $dbh = Bugzilla->dbh; + my $columns = join(',', $class->DB_COLUMNS); + my $table = $class->DB_TABLE; + my $name_field = $class->NAME_FIELD; + my $id_field = $class->ID_FIELD; + + my $id = $param unless (ref $param eq 'HASH'); + my $object; + + if (defined $id) { + # We special-case if somebody specifies an ID, so that we can + # validate it as numeric. + detaint_natural($id) + || ThrowCodeError('param_must_be_numeric', + {function => $class . '::_init'}); + + $object = $dbh->selectrow_hashref(qq{ + SELECT $columns FROM $table + WHERE $id_field = ?}, undef, $id); + } else { + unless (defined $param->{name} || (defined $param->{'condition'} + && defined $param->{'values'})) + { + ThrowCodeError('bad_arg', { argument => 'param', + function => $class . '::new' }); + } + + my ($condition, @values); + if (defined $param->{name}) { + $condition = $dbh->sql_istrcmp($name_field, '?'); + push(@values, $param->{name}); + } + elsif (defined $param->{'condition'} && defined $param->{'values'}) { + caller->isa('Bugzilla::Object') + || ThrowCodeError('protection_violation', + { caller => caller, + function => $class . '::new', + argument => 'condition/values' }); + $condition = $param->{'condition'}; + push(@values, @{$param->{'values'}}); + } + + map { trick_taint($_) } @values; + $object = $dbh->selectrow_hashref( + "SELECT $columns FROM $table WHERE $condition", undef, @values); + } + + return $object; +} + +sub new_from_list { + my $invocant = shift; + my $class = ref($invocant) || $invocant; + my ($id_list) = @_; + my $dbh = Bugzilla->dbh; + my $columns = join(',', $class->DB_COLUMNS); + my $table = $class->DB_TABLE; + my $order = $class->LIST_ORDER; + my $id_field = $class->ID_FIELD; + + my $objects; + if (@$id_list) { + my @detainted_ids; + foreach my $id (@$id_list) { + detaint_natural($id) || + ThrowCodeError('param_must_be_numeric', + {function => $class . '::new_from_list'}); + push(@detainted_ids, $id); + } + $objects = $dbh->selectall_arrayref( + "SELECT $columns FROM $table WHERE $id_field IN (" + . join(',', @detainted_ids) . ") ORDER BY $order", {Slice=>{}}); + } else { + return []; + } + + foreach my $object (@$objects) { + bless($object, $class); + } + return $objects; +} + +############################### +#### Accessors ###### +############################### + +sub id { return $_[0]->{'id'}; } +sub name { return $_[0]->{'name'}; } + +############################### +#### Methods #### +############################### + +sub set { + my ($self, $field, $value) = @_; + + # This method is protected. It's used to help implement set_ functions. + caller->isa('Bugzilla::Object') + || ThrowCodeError('protection_violation', + { caller => caller, + superclass => __PACKAGE__, + function => 'Bugzilla::Object->set' }); + + my $validators = $self->VALIDATORS; + if (exists $validators->{$field}) { + my $validator = $validators->{$field}; + $value = $self->$validator($value, $field); + } + + $self->{$field} = $value; +} + +sub update { + my $self = shift; + + my $dbh = Bugzilla->dbh; + my $table = $self->DB_TABLE; + my $id_field = $self->ID_FIELD; + + my $old_self = $self->new($self->id); + + my (@update_columns, @values, %changes); + foreach my $column ($self->UPDATE_COLUMNS) { + if ($old_self->{$column} ne $self->{$column}) { + my $value = $self->{$column}; + trick_taint($value) if defined $value; + push(@values, $value); + push(@update_columns, $column); + # We don't use $value because we don't want to detaint this for + # the caller. + $changes{$column} = [$old_self->{$column}, $self->{$column}]; + } + } + + my $columns = join(', ', map {"$_ = ?"} @update_columns); + + $dbh->do("UPDATE $table SET $columns WHERE $id_field = ?", undef, + @values, $self->id) if @values; + + return \%changes; +} + +############################### +#### Subroutines ###### +############################### + +sub create { + my ($class, $params) = @_; + my $dbh = Bugzilla->dbh; + + $class->check_required_create_fields($params); + my $field_values = $class->run_create_validators($params); + return $class->insert_create_data($field_values); +} + +sub check_required_create_fields { + my ($class, $params) = @_; + + foreach my $field ($class->REQUIRED_CREATE_FIELDS) { + ThrowCodeError('param_required', + { function => "${class}->create", param => $field }) + if !exists $params->{$field}; + } +} + +sub run_create_validators { + my ($class, $params) = @_; + + my $validators = $class->VALIDATORS; + + my %field_values; + # We do the sort just to make sure that validation always + # happens in a consistent order. + foreach my $field (sort keys %$params) { + my $value; + if (exists $validators->{$field}) { + my $validator = $validators->{$field}; + $value = $class->$validator($params->{$field}, $field); + } + else { + $value = $params->{$field}; + } + # We want people to be able to explicitly set fields to NULL, + # and that means they can be set to undef. + trick_taint($value) if defined $value && !ref($value); + $field_values{$field} = $value; + } + + return \%field_values; +} + +sub insert_create_data { + my ($class, $field_values) = @_; + my $dbh = Bugzilla->dbh; + + my (@field_names, @values); + while (my ($field, $value) = each %$field_values) { + push(@field_names, $field); + push(@values, $value); + } + + my $qmarks = '?,' x @field_names; + chop($qmarks); + my $table = $class->DB_TABLE; + $dbh->do("INSERT INTO $table (" . join(', ', @field_names) + . ") VALUES ($qmarks)", undef, @values); + my $id = $dbh->bz_last_key($table, $class->ID_FIELD); + return $class->new($id); +} + +sub get_all { + my $class = shift; + my $dbh = Bugzilla->dbh; + my $table = $class->DB_TABLE; + my $order = $class->LIST_ORDER; + my $id_field = $class->ID_FIELD; + + my $ids = $dbh->selectcol_arrayref(qq{ + SELECT $id_field FROM $table ORDER BY $order}); + + my $objects = $class->new_from_list($ids); + return @$objects; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Object - A base class for objects in Bugzilla. + +=head1 SYNOPSIS + + my $object = new Bugzilla::Object(1); + my $object = new Bugzilla::Object({name => 'TestProduct'}); + + my $id = $object->id; + my $name = $object->name; + +=head1 DESCRIPTION + +Bugzilla::Object is a base class for Bugzilla objects. You never actually +create a Bugzilla::Object directly, you only make subclasses of it. + +Basically, Bugzilla::Object exists to allow developers to create objects +more easily. All you have to do is define C<DB_TABLE>, C<DB_COLUMNS>, +and sometimes C<LIST_ORDER> and you have a whole new object. + +You should also define accessors for any columns other than C<name> +or C<id>. + +=head1 CONSTANTS + +Frequently, these will be the only things you have to define in your +subclass in order to have a fully-functioning object. C<DB_TABLE> +and C<DB_COLUMNS> are required. + +=over + +=item C<DB_TABLE> + +The name of the table that these objects are stored in. For example, +for C<Bugzilla::Keyword> this would be C<keyworddefs>. + +=item C<DB_COLUMNS> + +The names of the columns that you want to read out of the database +and into this object. This should be an array. + +=item C<NAME_FIELD> + +The name of the column that should be considered to be the unique +"name" of this object. The 'name' is a B<string> that uniquely identifies +this Object in the database. Defaults to 'name'. When you specify +C<{name => $name}> to C<new()>, this is the column that will be +matched against in the DB. + +=item C<ID_FIELD> + +The name of the column that represents the unique B<integer> ID +of this object in the database. Defaults to 'id'. + +=item C<LIST_ORDER> + +The order that C<new_from_list> and C<get_all> should return objects +in. This should be the name of a database column. Defaults to +L</NAME_FIELD>. + +=item C<REQUIRED_CREATE_FIELDS> + +The list of fields that B<must> be specified when the user calls +C<create()>. This should be an array. + +=item C<VALIDATORS> + +A hashref that points to a function that will validate each param to +L</create>. + +Validators are called both by L</create> and L</set>. When +they are called by L</create>, the first argument will be the name +of the class (what we normally call C<$class>). + +When they are called by L</set>, the first argument will be +a reference to the current object (what we normally call C<$self>). + +The second argument will be the value passed to L</create> or +L</set>for that field. + +The third argument will be the name of the field being validated. +This may be required by validators which validate several distinct fields. + +These functions should call L<Bugzilla::Error/ThrowUserError> if they fail. + +The validator must return the validated value. + +=item C<UPDATE_COLUMNS> + +A list of columns to update when L</update> is called. +If a field can't be changed, it shouldn't be listed here. (For example, +the L</ID_FIELD> usually can't be updated.) + +=back + +=head1 METHODS + +=head2 Constructors + +=over + +=item C<new($param)> + +=over + +=item B<Description> + +The constructor is used to load an existing object from the database, +by id or by name. + +=item B<Params> + +If you pass an integer, the integer is the id of the object, +from the database, that we want to read in. (id is defined +as the value in the L</ID_FIELD> column). + +If you pass in a hash, you can pass a C<name> key. The +value of the C<name> key is the case-insensitive name of the object +(from L</NAME_FIELD>) in the DB. + +B<Additional Parameters Available for Subclasses> + +If you are a subclass of C<Bugzilla::Object>, you can pass +C<condition> and C<values> as hash keys, instead of the above. + +C<condition> is a set of SQL conditions for the WHERE clause, which contain +placeholders. + +C<values> is a reference to an array. The array contains the values +for each placeholder in C<condition>, in order. + +This is to allow subclasses to have complex parameters, and then to +translate those parameters into C<condition> and C<values> when they +call C<$self->SUPER::new> (which is this function, usually). + +If you try to call C<new> outside of a subclass with the C<condition> +and C<values> parameters, Bugzilla will throw an error. These parameters +are intended B<only> for use by subclasses. + +=item B<Returns> + +A fully-initialized object. + +=back + +=item C<new_from_list(\@id_list)> + + Description: Creates an array of objects, given an array of ids. + + Params: \@id_list - A reference to an array of numbers, database ids. + If any of these are not numeric, the function + will throw an error. If any of these are not + valid ids in the database, they will simply + be skipped. + + Returns: A reference to an array of objects. + +=back + +=head2 Database Manipulation + +=over + +=item C<create> + +Description: Creates a new item in the database. + Throws a User Error if any of the passed-in params + are invalid. + +Params: C<$params> - hashref - A value to put in each database + field for this object. Certain values must be set (the + ones specified in L</REQUIRED_CREATE_FIELDS>), and + the function will throw a Code Error if you don't set + them. + +Returns: The Object just created in the database. + +Notes: In order for this function to work in your subclass, + your subclass's L</ID_FIELD> must be of C<SERIAL> + type in the database. Your subclass also must + define L</REQUIRED_CREATE_FIELDS> and L</VALIDATORS>. + + Subclass Implementors: This function basically just + calls L</check_required_create_fields>, then + L</run_create_validators>, and then finally + L</insert_create_data>. So if you have a complex system that + you need to implement, you can do it by calling these + three functions instead of C<SUPER::create>. + +=item C<check_required_create_fields> + +=over + +=item B<Description> + +Part of L</create>. Throws an error if any of the L</REQUIRED_CREATE_FIELDS> +have not been specified in C<$params> + +=item B<Params> + +=over + +=item C<$params> - The same as C<$params> from L</create>. + +=back + +=item B<Returns> (nothing) + +=back + +=item C<run_create_validators> + +Description: Runs the validation of input parameters for L</create>. + This subroutine exists so that it can be overridden + by subclasses who need to do special validations + of their input parameters. This method is B<only> called + by L</create>. + +Params: The same as L</create>. + +Returns: A hash, in a similar format as C<$params>, except that + these are the values to be inserted into the database, + not the values that were input to L</create>. + +=item C<insert_create_data> + +Part of L</create>. + +Takes the return value from L</run_create_validators> and inserts the +data into the database. Returns a newly created object. + +=item C<update> + +=over + +=item B<Description> + +Saves the values currently in this object to the database. +Only the fields specified in L</UPDATE_COLUMNS> will be +updated, and they will only be updated if their values have changed. + +=item B<Params> (none) + +=item B<Returns> + +A hashref showing what changed during the update. The keys are the column +names from L</UPDATE_COLUMNS>. If a field was not changed, it will not be +in the hash at all. If the field was changed, the key will point to an arrayref. +The first item of the arrayref will be the old value, and the second item +will be the new value. + +If there were no changes, we return a reference to an empty hash. + +=back + +=back + +=head2 Subclass Helpers + +These functions are intended only for use by subclasses. If +you call them from anywhere else, they will throw a C<CodeError>. + +=over + +=item C<set> + +=over + +=item B<Description> + +Sets a certain hash member of this class to a certain value. +Used for updating fields. Calls the validator for this field, +if it exists. Subclasses should use this function +to implement the various C<set_> mutators for their different +fields. + +See L</VALIDATORS> for more information. + +=item B<Params> + +=over + +=item C<$field> - The name of the hash member to update. This should +be the same as the name of the field in L</VALIDATORS>, if it exists there. + +=item C<$value> - The value that you're setting the field to. + +=back + +=item B<Returns> (nothing) + +=back + +=back + +=head1 CLASS FUNCTIONS + +=over + +=item C<get_all> + + Description: Returns all objects in this table from the database. + + Params: none. + + Returns: A list of objects, or an empty list if there are none. + + Notes: Note that you must call this as C<$class->get_all>. For + example, C<Bugzilla::Keyword->get_all>. + C<Bugzilla::Keyword::get_all> will not work. + +=back + +=cut diff --git a/Bugzilla/Product.pm b/Bugzilla/Product.pm index 5405b1651..728bd0652 100644 --- a/Bugzilla/Product.pm +++ b/Bugzilla/Product.pm @@ -18,7 +18,6 @@ use strict; package Bugzilla::Product; -use Bugzilla::Component; use Bugzilla::Version; use Bugzilla::Milestone; @@ -26,12 +25,18 @@ use Bugzilla::Util; use Bugzilla::Group; use Bugzilla::Error; +use Bugzilla::Install::Requirements; + +use base qw(Bugzilla::Object); + use constant DEFAULT_CLASSIFICATION_ID => 1; ############################### #### Initialization #### ############################### +use constant DB_TABLE => 'products'; + use constant DB_COLUMNS => qw( products.id products.name @@ -45,52 +50,6 @@ use constant DB_COLUMNS => qw( products.defaultmilestone ); -my $columns = join(", ", DB_COLUMNS); - -sub new { - my $invocant = shift; - my $class = ref($invocant) || $invocant; - my $self = {}; - bless($self, $class); - return $self->_init(@_); -} - -sub _init { - my $self = shift; - my ($param) = @_; - my $dbh = Bugzilla->dbh; - - my $id = $param unless (ref $param eq 'HASH'); - my $product; - - if (defined $id) { - detaint_natural($id) - || ThrowCodeError('param_must_be_numeric', - {function => 'Bugzilla::Product::_init'}); - - $product = $dbh->selectrow_hashref(qq{ - SELECT $columns FROM products - WHERE id = ?}, undef, $id); - - } elsif (defined $param->{'name'}) { - - trick_taint($param->{'name'}); - $product = $dbh->selectrow_hashref(qq{ - SELECT $columns FROM products - WHERE name = ?}, undef, $param->{'name'}); - } else { - ThrowCodeError('bad_arg', - {argument => 'param', - function => 'Bugzilla::Product::_init'}); - } - - return undef unless (defined $product); - - foreach my $field (keys %$product) { - $self->{$field} = $product->{$field}; - } - return $self; -} ############################### #### Methods #### @@ -106,11 +65,8 @@ sub components { WHERE product_id = ? ORDER BY name}, undef, $self->id); - my @components; - foreach my $id (@$ids) { - push @components, new Bugzilla::Component($id); - } - $self->{components} = \@components; + require Bugzilla::Component; + $self->{components} = Bugzilla::Component->new_from_list($ids); } return $self->{components}; } @@ -125,7 +81,10 @@ sub group_controls { group_control_map.entry, group_control_map.membercontrol, group_control_map.othercontrol, - group_control_map.canedit + group_control_map.canedit, + group_control_map.editcomponents, + group_control_map.editbugs, + group_control_map.canconfirm FROM groups LEFT JOIN group_control_map ON groups.id = group_control_map.group_id @@ -147,16 +106,11 @@ sub versions { my $dbh = Bugzilla->dbh; if (!defined $self->{versions}) { - my $values = $dbh->selectcol_arrayref(q{ - SELECT value FROM versions - WHERE product_id = ? - ORDER BY value}, undef, $self->id); + my $ids = $dbh->selectcol_arrayref(q{ + SELECT id FROM versions + WHERE product_id = ?}, undef, $self->id); - my @versions; - foreach my $value (@$values) { - push @versions, new Bugzilla::Version($self->id, $value); - } - $self->{versions} = \@versions; + $self->{versions} = Bugzilla::Version->new_from_list($ids); } return $self->{versions}; } @@ -166,16 +120,11 @@ sub milestones { my $dbh = Bugzilla->dbh; if (!defined $self->{milestones}) { - my $values = $dbh->selectcol_arrayref(q{ - SELECT value FROM milestones - WHERE product_id = ? - ORDER BY sortkey}, undef, $self->id); + my $ids = $dbh->selectcol_arrayref(q{ + SELECT id FROM milestones + WHERE product_id = ?}, undef, $self->id); - my @milestones; - foreach my $value (@$values) { - push @milestones, new Bugzilla::Milestone($self->id, $value); - } - $self->{milestones} = \@milestones; + $self->{milestones} = Bugzilla::Milestone->new_from_list($ids); } return $self->{milestones}; } @@ -206,13 +155,42 @@ sub bug_ids { return $self->{'bug_ids'}; } +sub user_has_access { + my ($self, $user) = @_; + + return Bugzilla->dbh->selectrow_array( + 'SELECT CASE WHEN group_id IS NULL THEN 1 ELSE 0 END + FROM products LEFT JOIN group_control_map + ON group_control_map.product_id = products.id + AND group_control_map.entry != 0 + AND group_id NOT IN (' . $user->groups_as_string . ') + WHERE products.id = ? ' . Bugzilla->dbh->sql_limit(1), + undef, $self->id); +} + +sub flag_types { + my $self = shift; + + if (!defined $self->{'flag_types'}) { + $self->{'flag_types'} = {}; + foreach my $type ('bug', 'attachment') { + my %flagtypes; + foreach my $component (@{$self->components}) { + foreach my $flagtype (@{$component->flag_types->{$type}}) { + $flagtypes{$flagtype->{'id'}} ||= $flagtype; + } + } + $self->{'flag_types'}->{$type} = [sort { $a->{'sortkey'} <=> $b->{'sortkey'} + || $a->{'name'} cmp $b->{'name'} } values %flagtypes]; + } + } + return $self->{'flag_types'}; +} ############################### #### Accessors ###### ############################### -sub id { return $_[0]->{'id'}; } -sub name { return $_[0]->{'name'}; } sub description { return $_[0]->{'description'}; } sub milestone_url { return $_[0]->{'milestoneurl'}; } sub disallow_new { return $_[0]->{'disallownew'}; } @@ -226,19 +204,6 @@ sub classification_id { return $_[0]->{'classification_id'}; } #### Subroutines ###### ############################### -sub get_all_products { - my $dbh = Bugzilla->dbh; - - my $ids = $dbh->selectcol_arrayref(q{ - SELECT id FROM products ORDER BY name}); - - my @products; - foreach my $id (@$ids) { - push @products, new Bugzilla::Product($id); - } - return @products; -} - sub check_product { my ($product_name) = @_; @@ -266,7 +231,7 @@ Bugzilla::Product - Bugzilla product class. use Bugzilla::Product; my $product = new Bugzilla::Product(1); - my $product = new Bugzilla::Product('AcmeProduct'); + my $product = new Bugzilla::Product({ name => 'AcmeProduct' }); my @components = $product->components(); my $groups_controls = $product->group_controls(); @@ -274,6 +239,8 @@ Bugzilla::Product - Bugzilla product class. my @versions = $product->versions(); my $bugcount = $product->bug_count(); my $bug_ids = $product->bug_ids(); + my $has_access = $product->user_has_access($user); + my $flag_types = $product->flag_types(); my $id = $product->id; my $name = $product->name; @@ -288,25 +255,17 @@ Bugzilla::Product - Bugzilla product class. =head1 DESCRIPTION -Product.pm represents a product object. +Product.pm represents a product object. It is an implementation +of L<Bugzilla::Object>, and thus provides all methods that +L<Bugzilla::Object> provides. + +The methods that are specific to C<Bugzilla::Product> are listed +below. =head1 METHODS =over -=item C<new($param)> - - Description: The constructor is used to load an existing product - by passing a product id or a hash. - - Params: $param - If you pass an integer, the integer is the - product id from the database that we want to - read in. If you pass in a hash with 'name' key, - then the value of the name key is the name of a - product from the DB. - - Returns: A Bugzilla::Product object. - =item C<components()> Description: Returns an array of component objects belonging to @@ -359,19 +318,32 @@ Product.pm represents a product object. Returns: An array of integer. -=back +=item C<user_has_access()> -=head1 SUBROUTINES + Description: Tells you whether or not the user is allowed to enter + bugs into this product, based on the C<entry> group + control. To see whether or not a user can actually + enter a bug into a product, use C<$user->can_enter_product>. -=over + Params: C<$user> - A Bugzilla::User object. + + Returns C<1> If this user's groups allow him C<entry> access to + this Product, C<0> otherwise. -=item C<get_all_products()> +=item C<flag_types()> - Description: Returns all products from the database. + Description: Returns flag types available for at least one of + its components. Params: none. - Returns: Bugzilla::Product object list. + Returns: Two references to an array of flagtype objects. + +=back + +=head1 SUBROUTINES + +=over =item C<check_product($product_name)> @@ -384,4 +356,8 @@ Product.pm represents a product object. =back +=head1 SEE ALSO + +L<Bugzilla::Object> + =cut diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index 9fe852769..ffe8e74f9 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -34,22 +34,28 @@ package Bugzilla::Search; use base qw(Exporter); @Bugzilla::Search::EXPORT = qw(IsValidQueryType); -use Bugzilla::Config; use Bugzilla::Error; use Bugzilla::Util; use Bugzilla::Constants; use Bugzilla::Group; use Bugzilla::User; use Bugzilla::Field; +use Bugzilla::Bug; +use Bugzilla::Keyword; use Date::Format; use Date::Parse; +# How much we should add to the relevance, for each word that matches +# in bugs.short_desc, during fulltext search. This is high because +# we want summary matches to be *very* relevant, by default. +use constant SUMMARY_RELEVANCE_FACTOR => 7; + # Some fields are not sorted on themselves, but on other fields. # We need to have a list of these fields and what they map to. # Each field points to an array that contains the fields mapped # to, in order. -our %specialorder = ( +use constant SPECIAL_ORDER => { 'bugs.target_milestone' => [ 'ms_order.sortkey','ms_order.value' ], 'bugs.bug_status' => [ 'bug_status.sortkey','bug_status.value' ], 'bugs.rep_platform' => [ 'rep_platform.sortkey','rep_platform.value' ], @@ -57,12 +63,12 @@ our %specialorder = ( 'bugs.op_sys' => [ 'op_sys.sortkey','op_sys.value' ], 'bugs.resolution' => [ 'resolution.sortkey', 'resolution.value' ], 'bugs.bug_severity' => [ 'bug_severity.sortkey','bug_severity.value' ] -); +}; # When we add certain fields to the ORDER BY, we need to then add a # table join to the FROM statement. This hash maps input fields to # the join statements that need to be added. -our %specialorderjoin = ( +use constant SPECIAL_ORDER_JOIN => { 'bugs.target_milestone' => 'LEFT JOIN milestones AS ms_order ON ms_order.value = bugs.target_milestone AND ms_order.product_id = bugs.product_id', 'bugs.bug_status' => 'LEFT JOIN bug_status ON bug_status.value = bugs.bug_status', 'bugs.rep_platform' => 'LEFT JOIN rep_platform ON rep_platform.value = bugs.rep_platform', @@ -70,7 +76,7 @@ our %specialorderjoin = ( 'bugs.op_sys' => 'LEFT JOIN op_sys ON op_sys.value = bugs.op_sys', 'bugs.resolution' => 'LEFT JOIN resolution ON resolution.value = bugs.resolution', 'bugs.bug_severity' => 'LEFT JOIN bug_severity ON bug_severity.value = bugs.bug_severity' -); +}; # Create a new Search # Note that the param argument may be modified by Bugzilla::Search @@ -111,10 +117,20 @@ sub init { my @andlist; my %chartfields; + my %special_order = %{SPECIAL_ORDER()}; + my %special_order_join = %{SPECIAL_ORDER_JOIN()}; + + my @select_fields = Bugzilla->get_fields({ type => FIELD_TYPE_SINGLE_SELECT, + obsolete => 0 }); + foreach my $field (@select_fields) { + my $name = $field->name; + $special_order{"bugs.$name"} = [ "$name.sortkey", "$name.value" ], + $special_order_join{"bugs.$name"} = + "LEFT JOIN $name ON $name.value = bugs.$name"; + } + my $dbh = Bugzilla->dbh; - &::GetVersionTable(); - # First, deal with all the old hard-coded non-chart-based poop. if (grep(/map_assigned_to/, @$fieldsref)) { push @supptables, "INNER JOIN profiles AS map_assigned_to " . @@ -180,25 +196,26 @@ sub init { # into their equivalent lists of open and closed statuses. if ($params->param('bug_status')) { my @bug_statuses = $params->param('bug_status'); - if (scalar(@bug_statuses) == scalar(@::legal_bug_status) + my @legal_statuses = @{get_legal_field_values('bug_status')}; + if (scalar(@bug_statuses) == scalar(@legal_statuses) || $bug_statuses[0] eq "__all__") { $params->delete('bug_status'); } elsif ($bug_statuses[0] eq '__open__') { - $params->param('bug_status', grep(&::IsOpenedState($_), - @::legal_bug_status)); + $params->param('bug_status', grep(is_open_state($_), + @legal_statuses)); } elsif ($bug_statuses[0] eq "__closed__") { - $params->param('bug_status', grep(! &::IsOpenedState($_), - @::legal_bug_status)); + $params->param('bug_status', grep(!is_open_state($_), + @legal_statuses)); } } if ($params->param('resolution')) { my @resolutions = $params->param('resolution'); - - if (scalar(@resolutions) == scalar(@::legal_resolution)) { + my $legal_resolutions = get_legal_field_values('resolution'); + if (scalar(@resolutions) == scalar(@$legal_resolutions)) { $params->delete('resolution'); } } @@ -208,6 +225,9 @@ sub init { "assigned_to", "reporter", "component", "classification", "target_milestone", "bug_group"); + # Include custom select fields. + push(@legal_fields, map { $_->name } @select_fields); + foreach my $field ($params->param()) { if (lsearch(\@legal_fields, $field) != -1) { push(@specialchart, [$field, "anyexact", @@ -237,7 +257,7 @@ sub init { foreach my $name (split(',', $email)) { $name = trim($name); if ($name) { - &::DBNameToIdAndCheck($name); + login_to_id($name, THROW_ERROR); } } } @@ -293,15 +313,17 @@ sub init { } if ($chfieldfrom ne '' || $chfieldto ne '') { - my $sql_chfrom = $chfieldfrom ? &::SqlQuote(SqlifyDate($chfieldfrom)):''; - my $sql_chto = $chfieldto ? &::SqlQuote(SqlifyDate($chfieldto)) :''; - my $sql_chvalue = $chvalue ne '' ? &::SqlQuote($chvalue) : ''; + my $sql_chfrom = $chfieldfrom ? $dbh->quote(SqlifyDate($chfieldfrom)):''; + my $sql_chto = $chfieldto ? $dbh->quote(SqlifyDate($chfieldto)) :''; + my $sql_chvalue = $chvalue ne '' ? $dbh->quote($chvalue) : ''; + trick_taint($sql_chvalue); if(!@chfield) { push(@wherepart, "bugs.delta_ts >= $sql_chfrom") if ($sql_chfrom); push(@wherepart, "bugs.delta_ts <= $sql_chto") if ($sql_chto); } else { my $bug_creation_clause; my @list; + my @actlist; foreach my $f (@chfield) { if ($f eq "[Bug creation]") { # Treat [Bug creation] differently because we need to look @@ -311,14 +333,15 @@ sub init { push(@l, "bugs.creation_ts <= $sql_chto") if($sql_chto); $bug_creation_clause = "(" . join(' AND ', @l) . ")"; } else { - push(@list, "\nactcheck.fieldid = " . get_field_id($f)); + push(@actlist, get_field_id($f)); } } - # @list won't have any elements if the only field being searched + # @actlist won't have any elements if the only field being searched # is [Bug creation] (in which case we don't need bugs_activity). - if(@list) { - my $extra = ""; + if(@actlist) { + my $extra = " actcheck.bug_id = bugs.bug_id"; + push(@list, "(actcheck.bug_when IS NOT NULL)"); if($sql_chfrom) { $extra .= " AND actcheck.bug_when >= $sql_chfrom"; } @@ -328,8 +351,9 @@ sub init { if($sql_chvalue) { $extra .= " AND actcheck.added = $sql_chvalue"; } - push(@supptables, "INNER JOIN bugs_activity AS actcheck " . - "ON actcheck.bug_id = bugs.bug_id $extra"); + push(@supptables, "LEFT JOIN bugs_activity AS actcheck " . + "ON $extra AND actcheck.fieldid IN (" . + join(",", @actlist) . ")"); } # Now that we're done using @list to determine if there are any @@ -344,7 +368,7 @@ sub init { my $sql_deadlinefrom; my $sql_deadlineto; - if (Bugzilla->user->in_group(Param('timetrackinggroup'))){ + if (Bugzilla->user->in_group(Bugzilla->params->{'timetrackinggroup'})){ my $deadlinefrom; my $deadlineto; @@ -353,7 +377,8 @@ sub init { validate_date($deadlinefrom) || ThrowUserError('illegal_date', {date => $deadlinefrom, format => 'YYYY-MM-DD'}); - $sql_deadlinefrom = &::SqlQuote($deadlinefrom); + $sql_deadlinefrom = $dbh->quote($deadlinefrom); + trick_taint($sql_deadlinefrom); push(@wherepart, "bugs.deadline >= $sql_deadlinefrom"); } @@ -362,7 +387,8 @@ sub init { validate_date($deadlineto) || ThrowUserError('illegal_date', {date => $deadlineto, format => 'YYYY-MM-DD'}); - $sql_deadlineto = &::SqlQuote($deadlineto); + $sql_deadlineto = $dbh->quote($deadlineto); + trick_taint($sql_deadlineto); push(@wherepart, "bugs.deadline <= $sql_deadlineto"); } } @@ -373,7 +399,8 @@ sub init { my $s = trim($params->param($f)); if ($s ne "") { my $n = $f; - my $q = &::SqlQuote($s); + my $q = $dbh->quote($s); + trick_taint($q); my $type = $params->param($f . "_type"); push(@specialchart, [$f, $type, $s]); } @@ -381,9 +408,7 @@ sub init { } if (defined $params->param('content')) { - # Append a new chart implementing content quicksearch push(@specialchart, ['content', 'matches', $params->param('content')]); - push(@specialchart, ['short_desc', 'allwords', $params->param('content')]); } my $chartid; @@ -399,7 +424,7 @@ sub init { my %funcsbykey; my @funcdefs = ( - "^(?:assigned_to|reporter|qa_contact),(?:notequals|equals|anyexact),%group\\.(\\w+)%" => sub { + "^(?:assigned_to|reporter|qa_contact),(?:notequals|equals|anyexact),%group\\.([^%]+)%" => sub { my $group = $1; my $groupid = Bugzilla::Group::ValidateGroupName( $group, ($user)); $groupid || ThrowUserError('invalid_group_name',{name => $group}); @@ -441,7 +466,7 @@ sub init { $f = "COALESCE(map_$f.login_name,'')"; }, - "^(?:cc),(?:notequals|equals|anyexact),%group\\.(\\w+)%" => sub { + "^(?:cc),(?:notequals|equals|anyexact),%group\\.([^%]+)%" => sub { my $group = $1; my $groupid = Bugzilla::Group::ValidateGroupName( $group, ($user)); $groupid || ThrowUserError('invalid_group_name',{name => $group}); @@ -542,20 +567,20 @@ sub init { my $table = "longdescs_$chartid"; push(@supptables, "INNER JOIN longdescs AS $table " . "ON $table.bug_id = bugs.bug_id"); - my $id = &::DBNameToIdAndCheck($v); + my $id = login_to_id($v, THROW_ERROR); $term = "$table.who = $id"; }, "^long_?desc,changedbefore" => sub { my $table = "longdescs_$chartid"; push(@supptables, "INNER JOIN longdescs AS $table " . "ON $table.bug_id = bugs.bug_id"); - $term = "$table.bug_when < " . &::SqlQuote(SqlifyDate($v)); + $term = "$table.bug_when < " . $dbh->quote(SqlifyDate($v)); }, "^long_?desc,changedafter" => sub { my $table = "longdescs_$chartid"; push(@supptables, "INNER JOIN longdescs AS $table " . "ON $table.bug_id = bugs.bug_id"); - $term = "$table.bug_when > " . &::SqlQuote(SqlifyDate($v)); + $term = "$table.bug_when > " . $dbh->quote(SqlifyDate($v)); }, "^content,matches" => sub { # "content" is an alias for columns containing text for which we @@ -568,8 +593,8 @@ sub init { # Add the longdescs table to the query so we can search comments. my $table = "longdescs_$chartid"; my $extra = ""; - if (Param("insidergroup") - && !UserInGroup(Param("insidergroup"))) + if (Bugzilla->params->{"insidergroup"} + && !Bugzilla->user->in_group(Bugzilla->params->{"insidergroup"})) { $extra = "AND $table.isprivate < 1"; } @@ -578,30 +603,28 @@ sub init { # Create search terms to add to the SELECT and WHERE clauses. # $term1 searches comments. - # $term2 searches summaries, which contributes to the relevance - # ranking in SELECT but doesn't limit which bugs get retrieved. my $term1 = $dbh->sql_fulltext_search("${table}.thetext", $v); - my $term2 = $dbh->sql_fulltext_search("bugs.short_desc", $v); + + # short_desc searching for the WHERE clause + my @words = _split_words_into_like('bugs.short_desc', $v); + my $term2_where = join(' OR ', @words); + + # short_desc relevance + my $factor = SUMMARY_RELEVANCE_FACTOR; + my @s_words = map("CASE WHEN $_ THEN $factor ELSE 0 END", @words); + my $term2_select = join(' + ', @s_words); # The term to use in the WHERE clause. - $term = "$term1 > 0"; + $term = "$term1 > 0 OR ($term2_where)"; # In order to sort by relevance (in case the user requests it), # we SELECT the relevance value and give it an alias so we can # add it to the SORT BY clause when we build it in buglist.cgi. # - # Note: MySQL calculates relevance for each comment separately, - # so we need to do some additional calculations to get an overall - # relevance value, which we do by calculating the average (mean) - # comment relevance and then adding the summary relevance, if any. - # This weights summary relevance heavily, which makes sense - # since summaries are short and thus highly significant. - # - # Note: We should be calculating the average relevance of all + # Note: We should be calculating the relevance based on all # comments for a bug, not just matching comments, but that's hard # (see http://bugzilla.mozilla.org/show_bug.cgi?id=145588#c35). - my $select_term = - "(SUM($term1)/COUNT($term1) + $term2) AS relevance"; + my $select_term = "(SUM($term1) + $term2_select) AS relevance"; # add the column not used in aggregate function explicitly push(@groupby, 'bugs.short_desc'); @@ -620,9 +643,9 @@ sub init { "^content," => sub { ThrowUserError("search_content_without_matches"); }, - "^deadline,(?:lessthan|greaterthan|equals|notequals),(-|\\+)?(\\d+)([dDwWmMyY])\$" => sub { + "^(?:deadline|creation_ts|delta_ts),(?:lessthan|greaterthan|equals|notequals),(?:-|\\+)?(?:\\d+)(?:[dDwWmMyY])\$" => sub { $v = SqlifyDate($v); - $q = &::SqlQuote($v); + $q = $dbh->quote($v); }, "^commenter,(?:equals|anyexact),(%\\w+%)" => sub { my $match = pronoun($1, $user); @@ -633,7 +656,9 @@ sub init { } my $table = "longdescs_$chartseq"; my $extra = ""; - if (Param("insidergroup") && !UserInGroup(Param("insidergroup"))) { + if (Bugzilla->params->{"insidergroup"} + && !Bugzilla->user->in_group(Bugzilla->params->{"insidergroup"})) + { $extra = "AND $table.isprivate < 1"; } push(@supptables, "LEFT JOIN longdescs AS $table " . @@ -651,7 +676,9 @@ sub init { } my $table = "longdescs_$chartseq"; my $extra = ""; - if (Param("insidergroup") && !UserInGroup(Param("insidergroup"))) { + if (Bugzilla->params->{"insidergroup"} + && !Bugzilla->user->in_group(Bugzilla->params->{"insidergroup"})) + { $extra = "AND $table.isprivate < 1"; } if ($list) { @@ -672,18 +699,32 @@ sub init { "^long_?desc," => sub { my $table = "longdescs_$chartid"; my $extra = ""; - if (Param("insidergroup") && !UserInGroup(Param("insidergroup"))) { + if (Bugzilla->params->{"insidergroup"} + && !Bugzilla->user->in_group(Bugzilla->params->{"insidergroup"})) + { $extra = "AND $table.isprivate < 1"; } push(@supptables, "INNER JOIN longdescs AS $table " . "ON $table.bug_id = bugs.bug_id $extra"); $f = "$table.thetext"; }, + "^longdescs\.isprivate," => sub { + my $table = "longdescs_$chartid"; + my $extra = ""; + if (Bugzilla->params->{"insidergroup"} + && !Bugzilla->user->in_group(Bugzilla->params->{"insidergroup"})) + { + $extra = "AND $table.isprivate < 1"; + } + push(@supptables, "INNER JOIN longdescs AS $table " . + "ON $table.bug_id = bugs.bug_id $extra"); + $f = "$table.isprivate"; + }, "^work_time,changedby" => sub { my $table = "longdescs_$chartid"; push(@supptables, "INNER JOIN longdescs AS $table " . "ON $table.bug_id = bugs.bug_id"); - my $id = &::DBNameToIdAndCheck($v); + my $id = login_to_id($v, THROW_ERROR); $term = "(($table.who = $id"; $term .= ") AND ($table.work_time <> 0))"; }, @@ -691,14 +732,14 @@ sub init { my $table = "longdescs_$chartid"; push(@supptables, "INNER JOIN longdescs AS $table " . "ON $table.bug_id = bugs.bug_id"); - $term = "(($table.bug_when < " . &::SqlQuote(SqlifyDate($v)); + $term = "(($table.bug_when < " . $dbh->quote(SqlifyDate($v)); $term .= ") AND ($table.work_time <> 0))"; }, "^work_time,changedafter" => sub { my $table = "longdescs_$chartid"; push(@supptables, "INNER JOIN longdescs AS $table " . "ON $table.bug_id = bugs.bug_id"); - $term = "(($table.bug_when > " . &::SqlQuote(SqlifyDate($v)); + $term = "(($table.bug_when > " . $dbh->quote(SqlifyDate($v)); $term .= ") AND ($table.work_time <> 0))"; }, "^work_time," => sub { @@ -744,12 +785,14 @@ sub init { COUNT(DISTINCT $table.bug_when) / COUNT(bugs.bug_id)) + bugs.remaining_time)))"; + $q = $dbh->quote($v); + trick_taint($q); if ($t eq "regexp") { - push(@having, $dbh->sql_regexp($expression, &::SqlQuote($v))); + push(@having, $dbh->sql_regexp($expression, $q)); } elsif ($t eq "notregexp") { - push(@having, $dbh->sql_not_regexp($expression, &::SqlQuote($v))); + push(@having, $dbh->sql_not_regexp($expression, $q)); } else { - push(@having, "$expression $oper " . &::SqlQuote($v)); + push(@having, "$expression $oper " . $q); } push(@groupby, "bugs.remaining_time"); } @@ -777,7 +820,9 @@ sub init { my $atable = "attachments_$chartid"; my $dtable = "attachdata_$chartid"; my $extra = ""; - if (Param("insidergroup") && !UserInGroup(Param("insidergroup"))) { + if (Bugzilla->params->{"insidergroup"} + && !Bugzilla->user->in_group(Bugzilla->params->{"insidergroup"})) + { $extra = "AND $atable.isprivate = 0"; } push(@supptables, "INNER JOIN attachments AS $atable " . @@ -786,10 +831,26 @@ sub init { "ON $dtable.id = $atable.attach_id"); $f = "$dtable.thedata"; }, + "^attachments\.submitter," => sub { + my $atable = "map_attachment_submitter_$chartid"; + my $extra = ""; + if (Bugzilla->params->{"insidergroup"} + && !Bugzilla->user->in_group(Bugzilla->params->{"insidergroup"})) + { + $extra = "AND $atable.isprivate = 0"; + } + push(@supptables, "INNER JOIN attachments AS $atable " . + "ON bugs.bug_id = $atable.bug_id $extra"); + push(@supptables, "LEFT JOIN profiles AS attachers_$chartid " . + "ON $atable.submitter_id = attachers_$chartid.userid"); + $f = "attachers_$chartid.login_name"; + }, "^attachments\..*," => sub { my $table = "attachments_$chartid"; my $extra = ""; - if (Param("insidergroup") && !UserInGroup(Param("insidergroup"))) { + if (Bugzilla->params->{"insidergroup"} + && !Bugzilla->user->in_group(Bugzilla->params->{"insidergroup"})) + { $extra = "AND $table.isprivate = 0"; } push(@supptables, "INNER JOIN attachments AS $table " . @@ -797,18 +858,18 @@ sub init { $f =~ m/^attachments\.(.*)$/; my $field = $1; if ($t eq "changedby") { - $v = &::DBNameToIdAndCheck($v); - $q = &::SqlQuote($v); + $v = login_to_id($v, THROW_ERROR); + $q = $dbh->quote($v); $field = "submitter_id"; $t = "equals"; } elsif ($t eq "changedbefore") { $v = SqlifyDate($v); - $q = &::SqlQuote($v); + $q = $dbh->quote($v); $field = "creation_ts"; $t = "lessthan"; } elsif ($t eq "changedafter") { $v = SqlifyDate($v); - $q = &::SqlQuote($v); + $q = $dbh->quote($v); $field = "creation_ts"; $t = "greaterthan"; } @@ -835,8 +896,7 @@ sub init { # negative conditions (f.e. "flag isn't review+"). my $flags = "flags_$chartid"; push(@supptables, "LEFT JOIN flags AS $flags " . - "ON bugs.bug_id = $flags.bug_id " . - "AND $flags.is_active = 1"); + "ON bugs.bug_id = $flags.bug_id "); my $flagtypes = "flagtypes_$chartid"; push(@supptables, "LEFT JOIN flagtypes AS $flagtypes " . "ON $flags.type_id = $flagtypes.id"); @@ -866,8 +926,7 @@ sub init { "^requestees.login_name," => sub { my $flags = "flags_$chartid"; push(@supptables, "LEFT JOIN flags AS $flags " . - "ON bugs.bug_id = $flags.bug_id " . - "AND $flags.is_active = 1"); + "ON bugs.bug_id = $flags.bug_id "); push(@supptables, "LEFT JOIN profiles AS requestees_$chartid " . "ON $flags.requestee_id = requestees_$chartid.userid"); $f = "requestees_$chartid.login_name"; @@ -875,8 +934,7 @@ sub init { "^setters.login_name," => sub { my $flags = "flags_$chartid"; push(@supptables, "LEFT JOIN flags AS $flags " . - "ON bugs.bug_id = $flags.bug_id " . - "AND $flags.is_active = 1"); + "ON bugs.bug_id = $flags.bug_id "); push(@supptables, "LEFT JOIN profiles AS setters_$chartid " . "ON $flags.setter_id = setters_$chartid.userid"); $f = "setters_$chartid.login_name"; @@ -919,16 +977,15 @@ sub init { }, "^keywords,(?!changed)" => sub { - &::GetVersionTable(); my @list; my $table = "keywords_$chartid"; foreach my $value (split(/[\s,]+/, $v)) { if ($value eq '') { next; } - my $id = &::GetKeywordIdFromName($value); - if ($id) { - push(@list, "$table.keywordid = $id"); + my $keyword = new Bugzilla::Keyword({name => $value}); + if ($keyword) { + push(@list, "$table.keywordid = " . $keyword->id); } else { ThrowUserError("unknown_keyword", @@ -1058,7 +1115,9 @@ sub init { if ($w eq "---" && $f !~ /milestone/) { $w = ""; } - push(@list, &::SqlQuote($w)); + $q = $dbh->quote($w); + trick_taint($q); + push(@list, $q); } if (@list) { $term = "$ff IN (" . join (',', @list) . ")"; @@ -1099,7 +1158,7 @@ sub init { "ON $table.bug_id = bugs.bug_id " . "AND $table.fieldid = $fieldid " . "AND $table.bug_when $operator " . - &::SqlQuote(SqlifyDate($v)) ); + $dbh->quote(SqlifyDate($v)) ); $term = "($table.bug_when IS NOT NULL)"; }, ",(changedfrom|changedto)" => sub { @@ -1121,7 +1180,7 @@ sub init { if (!$fieldid) { ThrowCodeError("invalid_field_name", {field => $f}); } - my $id = &::DBNameToIdAndCheck($v); + my $id = login_to_id($v, THROW_ERROR); push(@supptables, "LEFT JOIN bugs_activity AS $table " . "ON $table.bug_id = bugs.bug_id " . "AND $table.fieldid = $fieldid " . @@ -1161,7 +1220,8 @@ sub init { $params->param("value$chart-$row-$col", shift(@$ref)); if ($debug) { push(@debugdata, "$row-$col = " . - $params->param("field$chart-$row-$col") . ' | ' . $params->param("type$chart-$row-$col") . ' | ' . + $params->param("field$chart-$row-$col") . ' | ' . + $params->param("type$chart-$row-$col") . ' | ' . $params->param("value$chart-$row-$col") . ' *'); } $col++; @@ -1245,7 +1305,7 @@ sub init { # e.g. bugs_activity.bug_id # $t = type of query. e.g. "equal to", "changed after", case sensitive substr" # $v = value - value the user typed in to the form -# $q = sanitized version of user input (SqlQuote($v)) +# $q = sanitized version of user input trick_taint(($dbh->quote($v))) # @supptables = Tables and/or table aliases used in query # %suppseen = A hash used to store all the tables in supptables to weed # out duplicates. @@ -1254,11 +1314,8 @@ sub init { # $suppstring = String which is pasted into query containing all table names # get a list of field names to verify the user-submitted chart fields against - &::SendSQL("SELECT name, fieldid FROM fielddefs"); - while (&::MoreSQLData()) { - my ($name, $id) = &::FetchSQLData(); - $chartfields{$name} = $id; - } + %chartfields = @{$dbh->selectcol_arrayref( + q{SELECT name, id FROM fielddefs}, { Columns=>[1,2] })}; $row = 0; for ($chart=-1 ; @@ -1291,7 +1348,8 @@ sub init { # already know about it), or it was in %chartfields, so it is # a valid field name, which means that it's ok. trick_taint($f); - $q = &::SqlQuote($v); + $q = $dbh->quote($v); + trick_taint($q); my $rhs = $v; $rhs =~ tr/,//; my $func; @@ -1352,7 +1410,7 @@ sub init { if ($orderitem =~ /\s+AS\s+(.+)$/i) { $orderitem = $1; } - BuildOrderBy($orderitem, \@orderby); + BuildOrderBy(\%special_order, $orderitem, \@orderby); } # Now JOIN the correct tables in the FROM clause. # This is done separately from the above because it's @@ -1360,8 +1418,8 @@ sub init { foreach my $orderitem (@inputorder) { # Grab the part without ASC or DESC. my @splitfield = split(/\s+/, $orderitem); - if ($specialorderjoin{$splitfield[0]}) { - push(@supptables, $specialorderjoin{$splitfield[0]}); + if ($special_order_join{$splitfield[0]}) { + push(@supptables, $special_order_join{$splitfield[0]}); } } @@ -1412,7 +1470,7 @@ sub init { $query .= " OR (bugs.reporter_accessible = 1 AND bugs.reporter = $userid) " . " OR (bugs.cclist_accessible = 1 AND cc.who IS NOT NULL) " . " OR (bugs.assigned_to = $userid) "; - if (Param('useqacontact')) { + if (Bugzilla->params->{'useqacontact'}) { $query .= "OR (bugs.qa_contact = $userid) "; } } @@ -1519,24 +1577,24 @@ sub ListIDsForEmail { } $list = join(',', @list); } elsif ($type eq 'substring') { - &::SendSQL("SELECT userid FROM profiles WHERE " . - $dbh->sql_position(lc(::SqlQuote($email)), "LOWER(login_name)") . - " > 0 " . $dbh->sql_limit(51)); - while (&::MoreSQLData()) { - my ($id) = &::FetchSQLData(); - push(@list, $id); - } + my $sql_email = $dbh->quote($email); + trick_taint($sql_email); + my $result = $dbh->selectcol_arrayref( + q{SELECT userid FROM profiles WHERE } . + $dbh->sql_position(lc($sql_email), q{LOWER(login_name)}) . + q{ > 0 } . $dbh->sql_limit(51)); + @list = @{$result}; if (scalar(@list) < 50) { $list = join(',', @list); } } elsif ($type eq 'regexp') { - &::SendSQL("SELECT userid FROM profiles WHERE " . - $dbh->sql_regexp("login_name", ::SqlQuote($email)) . - " " . $dbh->sql_limit(51)); - while (&::MoreSQLData()) { - my ($id) = &::FetchSQLData(); - push(@list, $id); - } + my $sql_email = $dbh->quote($email); + trick_taint($sql_email); + my $result = $dbh->selectcol_arrayref( + qq{SELECT userid FROM profiles WHERE } . + $dbh->sql_regexp("login_name", $sql_email) . + q{ } . $dbh->sql_limit(51)); + @list = @{$result}; if (scalar(@list) < 50) { $list = join(',', @list); } @@ -1550,13 +1608,10 @@ sub build_subselect { my ($outer, $inner, $table, $cond) = @_; my $q = "SELECT $inner FROM $table WHERE $cond"; #return "$outer IN ($q)"; - &::SendSQL($q); - my @list; - while (&::MoreSQLData()) { - push (@list, &::FetchOneColumn()); - } - return "1=2" unless @list; # Could use boolean type on dbs which support it - return "$outer IN (" . join(',', @list) . ")"; + my $dbh = Bugzilla->dbh; + my $list = $dbh->selectcol_arrayref($q); + return "1=2" unless @$list; # Could use boolean type on dbs which support it + return "$outer IN (" . join(',', @$list) . ")"; } sub GetByWordList { @@ -1568,7 +1623,8 @@ sub GetByWordList { my $word = $w; if ($word ne "") { $word =~ tr/A-Z/a-z/; - $word = &::SqlQuote(quotemeta($word)); + $word = $dbh->quote(quotemeta($word)); + trick_taint($word); $word =~ s/^'//; $word =~ s/'$//; $word = '(^|[^a-z0-9])' . $word . '($|[^a-z0-9])'; @@ -1584,10 +1640,13 @@ sub GetByWordListSubstr { my ($field, $strs) = (@_); my @list; my $dbh = Bugzilla->dbh; + my $sql_word; foreach my $word (split(/[\s,]+/, $strs)) { if ($word ne "") { - push(@list, $dbh->sql_position(lc(::SqlQuote($word)), + $sql_word = $dbh->quote($word); + trick_taint($sql_word); + push(@list, $dbh->sql_position(lc($sql_word), "LOWER($field)") . " > 0"); } } @@ -1660,7 +1719,7 @@ sub IsValidQueryType # BuildOrderBy recursively, to let it know that we're "reversing" the # order. That is, that we wanted "A DESC", not "A". sub BuildOrderBy { - my ($orderitem, $stringlist, $reverseorder) = (@_); + my ($special_order, $orderitem, $stringlist, $reverseorder) = (@_); my @twopart = split(/\s+/, $orderitem); my $orderfield = $twopart[0]; @@ -1678,15 +1737,31 @@ sub BuildOrderBy { } # Handle fields that have non-standard sort orders, from $specialorder. - if ($specialorder{$orderfield}) { - foreach my $subitem (@{$specialorder{$orderfield}}) { + if ($special_order->{$orderfield}) { + foreach my $subitem (@{$special_order->{$orderfield}}) { # DESC on a field with non-standard sort order means # "reverse the normal order for each field that we map to." - BuildOrderBy($subitem, $stringlist, $orderdirection =~ m/desc/i); + BuildOrderBy($special_order, $subitem, $stringlist, + $orderdirection =~ m/desc/i); } return; } push(@$stringlist, trim($orderfield . ' ' . $orderdirection)); } + +# This is a helper for fulltext search +sub _split_words_into_like { + my ($field, $text) = @_; + my $dbh = Bugzilla->dbh; + # This code is very similar to Bugzilla::DB::sql_fulltext_search, + # so you can look there if you'd like an explanation of what it's + # doing. + my $lower_text = lc($text); + my @words = split(/\s+/, $lower_text); + @words = map($dbh->quote("%$_%"), @words); + map(trick_taint($_), @words); + @words = map($dbh->sql_istrcmp($field, $_, 'LIKE'), @words); + return @words; +} 1; diff --git a/Bugzilla/Search/CVS/Entries b/Bugzilla/Search/CVS/Entries index 2e6562bf2..92aa3d51b 100644 --- a/Bugzilla/Search/CVS/Entries +++ b/Bugzilla/Search/CVS/Entries @@ -1,2 +1,3 @@ -/Quicksearch.pm/1.2.2.2/Tue Jul 25 23:25:14 2006//TBUGZILLA-2_22_3 +/Quicksearch.pm/1.12.2.1/Fri Mar 16 23:17:35 2007//TBUGZILLA-3_0 +/Saved.pm/1.3/Mon Nov 13 03:08:44 2006//TBUGZILLA-3_0 D diff --git a/Bugzilla/Search/CVS/Tag b/Bugzilla/Search/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/Bugzilla/Search/CVS/Tag +++ b/Bugzilla/Search/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/Bugzilla/Search/Quicksearch.pm b/Bugzilla/Search/Quicksearch.pm index 5163e4769..83746ed5f 100644 --- a/Bugzilla/Search/Quicksearch.pm +++ b/Bugzilla/Search/Quicksearch.pm @@ -23,17 +23,19 @@ package Bugzilla::Search::Quicksearch; # Make it harder for us to do dangerous things in Perl. use strict; -use Bugzilla::Config; use Bugzilla::Error; +use Bugzilla::Constants; +use Bugzilla::Keyword; +use Bugzilla::Bug; +use Bugzilla::Field; use Bugzilla::Util; use base qw(Exporter); @Bugzilla::Search::Quicksearch::EXPORT = qw(quicksearch); -my $cgi = Bugzilla->cgi; - # Word renamings -my %mappings = (# Status, Resolution, Platform, OS, Priority, Severity +use constant MAPPINGS => { + # Status, Resolution, Platform, OS, Priority, Severity "status" => "bug_status", "resolution" => "resolution", # no change "platform" => "rep_platform", @@ -83,28 +85,34 @@ my %mappings = (# Status, Resolution, Platform, OS, Priority, Severity "attachmentdata" => "attach_data.thedata", "attachdata" => "attach_data.thedata", "attachmentmimetype" => "attachments.mimetype", - "attachmimetype" => "attachments.mimetype"); + "attachmimetype" => "attachments.mimetype" +}; # We might want to put this into localconfig or somewhere -my @platforms = ('pc', 'sun', 'macintosh', 'mac'); -my @productExceptions = ('row' # [Browser] - # ^^^ - ,'new' # [MailNews] - # ^^^ - ); -my @componentExceptions = ('hang' # [Bugzilla: Component/Keyword Changes] - # ^^^^ - ); +use constant PLATFORMS => ('pc', 'sun', 'macintosh', 'mac'); +use constant PRODUCT_EXCEPTIONS => ( + 'row', # [Browser] + # ^^^ + 'new', # [MailNews] + # ^^^ +); +use constant COMPONENT_EXCEPTIONS => ( + 'hang' # [Bugzilla: Component/Keyword Changes] + # ^^^^ +); # Quicksearch-wide globals for boolean charts. -my $chart = 0; -my $and = 0; -my $or = 0; +our ($chart, $and, $or); sub quicksearch { my ($searchstring) = (@_); + my $cgi = Bugzilla->cgi; my $urlbase = correct_urlbase(); + $chart = 0; + $and = 0; + $or = 0; + # Remove leading and trailing commas and whitespace. $searchstring =~ s/(^[\s,]+|[\s,]+$)//g; ThrowUserError('buglist_parameters_required') unless ($searchstring); @@ -142,8 +150,8 @@ sub quicksearch { } # It's no alias either, so it's a more complex query. - - &::GetVersionTable(); + my $legal_statuses = get_legal_field_values('bug_status'); + my $legal_resolutions = get_legal_field_values('resolution'); # Globally translate " AND ", " OR ", " NOT " to space, pipe, dash. $searchstring =~ s/\s+AND\s+/ /g; @@ -151,17 +159,18 @@ sub quicksearch { $searchstring =~ s/\s+NOT\s+/ -/g; my @words = splitString($searchstring); - my $searchComments = $#words < Param('quicksearch_comment_cutoff'); - my @openStates = &::OpenStates(); + my $searchComments = + $#words < Bugzilla->params->{'quicksearch_comment_cutoff'}; + my @openStates = BUG_STATE_OPEN; my @closedStates; my (%states, %resolutions); - foreach (@::legal_bug_status) { - push(@closedStates, $_) unless &::IsOpenedState($_); + foreach (@$legal_statuses) { + push(@closedStates, $_) unless is_open_state($_); } foreach (@openStates) { $states{$_} = 1 } if ($words[0] eq 'ALL') { - foreach (@::legal_bug_status) { $states{$_} = 1 } + foreach (@$legal_statuses) { $states{$_} = 1 } shift @words; } elsif ($words[0] eq 'OPEN') { @@ -173,7 +182,7 @@ sub quicksearch { \%resolutions, [split(/,/, substr($words[0], 1))], \@closedStates, - \@::legal_resolution)) { + $legal_resolutions)) { shift @words; # Allowing additional resolutions means we need to keep # the "no resolution" resolution. @@ -189,8 +198,8 @@ sub quicksearch { if (matchPrefixes(\%states, \%resolutions, [split(/,/, $words[0])], - \@::legal_bug_status, - \@::legal_resolution)) { + $legal_statuses, + $legal_resolutions)) { shift @words; } else { @@ -265,8 +274,8 @@ sub quicksearch { my @values = split(/,/, $2); foreach my $field (@fields) { # Be tolerant about unknown fields - next unless defined($mappings{$field}); - $field = $mappings{$field}; + next unless defined(MAPPINGS->{$field}); + $field = MAPPINGS->{$field}; foreach (@values) { addChart($field, 'substring', $_, $negate); } @@ -279,7 +288,7 @@ sub quicksearch { # by comma, which is another legal boolean OR indicator. foreach my $word (split(/,/, $or_operand)) { # Platform - if (grep({lc($word) eq $_} @platforms)) { + if (grep({lc($word) eq $_} PLATFORMS)) { addChart('rep_platform', 'substring', $word, $negate); } @@ -290,7 +299,7 @@ sub quicksearch { } # Severity elsif (grep({lc($word) eq substr($_, 0, 3)} - @::legal_severity)) { + @{get_legal_field_values('bug_severity')})) { addChart('bug_severity', 'substring', $word, $negate); } @@ -308,21 +317,21 @@ sub quicksearch { else { # Default QuickSearch word if (!grep({lc($word) eq $_} - @productExceptions) && + PRODUCT_EXCEPTIONS) && length($word)>2 ) { addChart('product', 'substring', $word, $negate); } if (!grep({lc($word) eq $_} - @componentExceptions) && + COMPONENT_EXCEPTIONS) && length($word)>2 ) { addChart('component', 'substring', $word, $negate); } if (grep({lc($word) eq $_} - @::legal_keywords)) { + map($_->name, Bugzilla::Keyword->get_all))) { addChart('keywords', 'substring', $word, $negate); if (length($word)>2) { @@ -378,8 +387,8 @@ sub quicksearch { if ($cgi->param('load')) { # Param 'load' asks us to display the query in the advanced search form. - print $cgi->redirect(-uri => "${urlbase}query.cgi?format=advanced&" . - $modified_query_string); + print $cgi->redirect(-uri => "${urlbase}query.cgi?format=advanced&" + . $modified_query_string); } # Otherwise, pass the modified query string to the caller. @@ -400,28 +409,22 @@ sub splitString { my @parts; my $i = 0; - # Escape backslashes - $string =~ s/\\/\\\//g; - # Now split on quote sign; be tolerant about unclosed quotes @quoteparts = split(/"/, $string); - foreach (@quoteparts) { - # After every odd quote, escape whitespace - s/(\s)/\\$1/g if $i++ % 2; + foreach my $part (@quoteparts) { + # After every odd quote, quote special chars + $part = url_quote($part) if $i++ % 2; } # Join again $string = join('"', @quoteparts); # Now split on unescaped whitespace - @parts = split(/(?<!\\)\s+/, $string); + @parts = split(/\s+/, $string); foreach (@parts) { - # Restore whitespace - s/\\(\s)/$1/g; - # Restore backslashes - s/\\\//\\/g; # Remove quotes s/"//g; } + return @parts; } @@ -489,9 +492,10 @@ sub addChart { sub makeChart { my ($expr, $field, $type, $value) = @_; + my $cgi = Bugzilla->cgi; $cgi->param("field$expr", $field); $cgi->param("type$expr", $type); - $cgi->param("value$expr", $value); + $cgi->param("value$expr", url_decode($value)); } 1; diff --git a/Bugzilla/Search/Saved.pm b/Bugzilla/Search/Saved.pm new file mode 100644 index 000000000..83528405f --- /dev/null +++ b/Bugzilla/Search/Saved.pm @@ -0,0 +1,265 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Everything Solved. +# Portions created by Everything Solved are Copyright (C) 2006 +# Everything Solved. All Rights Reserved. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + +use strict; + +package Bugzilla::Search::Saved; + +use base qw(Bugzilla::Object); + +use Bugzilla::CGI; +use Bugzilla::Constants; +use Bugzilla::Group; +use Bugzilla::Error; +use Bugzilla::Search qw(IsValidQueryType); +use Bugzilla::User; +use Bugzilla::Util; + +############# +# Constants # +############# + +use constant DB_TABLE => 'namedqueries'; + +use constant DB_COLUMNS => qw( + id + userid + name + query + query_type +); + +use constant REQUIRED_CREATE_FIELDS => qw(name query); + +use constant VALIDATORS => { + name => \&_check_name, + query => \&_check_query, + query_type => \&_check_query_type, + link_in_footer => \&_check_link_in_footer, +}; + +use constant UPDATE_COLUMNS => qw(query query_type); + +############## +# Validators # +############## + +sub _check_link_in_footer { return $_[1] ? 1 : 0; } + +sub _check_name { + my ($invocant, $name) = @_; + $name = trim($name); + $name || ThrowUserError("query_name_missing"); + $name !~ /[<>&]/ || ThrowUserError("illegal_query_name"); + if (length($name) > MAX_LEN_QUERY_NAME) { + ThrowUserError("query_name_too_long"); + } + return $name; +} + +sub _check_query { + my ($invocant, $query) = @_; + $query || ThrowUserError("buglist_parameters_required"); + my $cgi = new Bugzilla::CGI($query); + $cgi->clean_search_url; + return $cgi->query_string; +} + +sub _check_query_type { + my ($invocant, $type) = @_; + # Right now the only query type is LIST_OF_BUGS. + return $type ? LIST_OF_BUGS : QUERY_LIST; +} + +######################### +# Database Manipulation # +######################### + +sub create { + my $class = shift; + Bugzilla->login(LOGIN_REQUIRED); + my $dbh = Bugzilla->dbh; + $class->check_required_create_fields(@_); + my $params = $class->run_create_validators(@_); + + # Right now you can only create a Saved Search for the current user. + $params->{userid} = Bugzilla->user->id; + + $dbh->bz_lock_tables('namedqueries WRITE', + 'namedqueries_link_in_footer WRITE'); + my $lif = delete $params->{link_in_footer}; + my $obj = $class->insert_create_data($params); + if ($lif) { + $dbh->do('INSERT INTO namedqueries_link_in_footer + (user_id, namedquery_id) VALUES (?,?)', + undef, $params->{userid}, $obj->id); + } + $dbh->bz_unlock_tables(); + + return $obj; +} + +##################### +# Complex Accessors # +##################### + +sub edit_link { + my ($self) = @_; + return $self->{edit_link} if defined $self->{edit_link}; + my $cgi = new Bugzilla::CGI($self->url); + if (!$cgi->param('query_type') + || !IsValidQueryType($cgi->param('query_type'))) + { + $cgi->param('query_type', 'advanced'); + } + $self->{edit_link} = $cgi->canonicalise_query; + return $self->{edit_link}; +} + +sub used_in_whine { + my ($self) = @_; + return $self->{used_in_whine} if exists $self->{used_in_whine}; + ($self->{used_in_whine}) = Bugzilla->dbh->selectrow_array( + 'SELECT 1 FROM whine_events INNER JOIN whine_queries + ON whine_events.id = whine_queries.eventid + WHERE whine_events.owner_userid = ? AND query_name = ?', undef, + $self->{userid}, $self->name) || 0; + return $self->{used_in_whine}; +} + +sub link_in_footer { + my ($self, $user) = @_; + # We only cache link_in_footer for the current Bugzilla->user. + return $self->{link_in_footer} if exists $self->{link_in_footer} && !$user; + my $user_id = $user ? $user->id : Bugzilla->user->id; + my $link_in_footer = Bugzilla->dbh->selectrow_array( + 'SELECT 1 FROM namedqueries_link_in_footer + WHERE namedquery_id = ? AND user_id = ?', + undef, $self->id, $user_id) || 0; + $self->{link_in_footer} = $link_in_footer if !$user; + return $link_in_footer; +} + +sub shared_with_group { + my ($self) = @_; + return $self->{shared_with_group} if exists $self->{shared_with_group}; + # Bugzilla only currently supports sharing with one group, even + # though the database backend allows for an infinite number. + my ($group_id) = Bugzilla->dbh->selectrow_array( + 'SELECT group_id FROM namedquery_group_map WHERE namedquery_id = ?', + undef, $self->id); + $self->{shared_with_group} = $group_id ? new Bugzilla::Group($group_id) + : undef; + return $self->{shared_with_group}; +} + +#################### +# Simple Accessors # +#################### + +sub bug_ids_only { return ($_[0]->{'query_type'} == LIST_OF_BUGS) ? 1 : 0; } +sub url { return $_[0]->{'query'}; } + +sub user { + my ($self) = @_; + return $self->{user} if defined $self->{user}; + $self->{user} = new Bugzilla::User($self->{userid}); + return $self->{user}; +} + +############ +# Mutators # +############ + +sub set_url { $_[0]->set('query', $_[1]); } +sub set_query_type { $_[0]->set('query_type', $_[1]); } + +1; + +__END__ + +=head1 NAME + + Bugzilla::Search::Saved - A saved search + +=head1 SYNOPSIS + + use Bugzilla::Search::Saved; + + my $query = new Bugzilla::Search::Saved($query_id); + + my $edit_link = $query->edit_link; + my $search_url = $query->url; + my $owner = $query->user; + +=head1 DESCRIPTION + +This module exists to represent a L<Bugzilla::Search> that has been +saved to the database. + +This is an implementation of L<Bugzilla::Object>, and so has all the +same methods available as L<Bugzilla::Object>, in addition to what is +documented below. + +=head1 METHODS + +=head2 Constructors and Database Manipulation + +=over + +=item C<new> + +Does not accept a bare C<name> argument. Instead, accepts only an id. + +See also: L<Bugzilla::Object/new>. + +=back + + +=head2 Accessors + +These return data about the object, without modifying the object. + +=over + +=item C<edit_link> + +A url with which you can edit the search. + +=item C<url> + +The CGI parameters for the search, as a string. + +=item C<link_in_footer> + +Whether or not this search should be displayed in the footer for the +I<current user> (not the owner of the search, but the person actually +using Bugzilla right now). + +=item C<bug_ids_only> + +True if the search contains only a list of Bug IDs. + +=item C<shared_with_group> + +The L<Bugzilla::Group> that this search is shared with. C<undef> if +this search isn't shared. + +=back diff --git a/Bugzilla/Series.pm b/Bugzilla/Series.pm index 521357488..877f69866 100644 --- a/Bugzilla/Series.pm +++ b/Bugzilla/Series.pm @@ -32,11 +32,10 @@ use lib "."; package Bugzilla::Series; +use Bugzilla::Error; use Bugzilla::Util; use Bugzilla::User; -use constant PUBLIC_USER_ID => 0; - sub new { my $invocant = shift; my $class = ref($invocant) || $invocant; @@ -85,8 +84,8 @@ sub initFromDatabase { my $self = shift; my $series_id = shift; - &::detaint_natural($series_id) - || &::ThrowCodeError("invalid_series_id", { 'series_id' => $series_id }); + detaint_natural($series_id) + || ThrowCodeError("invalid_series_id", { 'series_id' => $series_id }); my $dbh = Bugzilla->dbh; my @series = $dbh->selectrow_array("SELECT series.series_id, cc1.name, " . @@ -135,26 +134,26 @@ sub initFromCGI { $self->{'series_id'} = $cgi->param('series_id') || undef; if (defined($self->{'series_id'})) { detaint_natural($self->{'series_id'}) - || &::ThrowCodeError("invalid_series_id", + || ThrowCodeError("invalid_series_id", { 'series_id' => $self->{'series_id'} }); } $self->{'category'} = $cgi->param('category') || $cgi->param('newcategory') - || &::ThrowUserError("missing_category"); + || ThrowUserError("missing_category"); $self->{'subcategory'} = $cgi->param('subcategory') || $cgi->param('newsubcategory') - || &::ThrowUserError("missing_subcategory"); + || ThrowUserError("missing_subcategory"); $self->{'name'} = $cgi->param('name') - || &::ThrowUserError("missing_name"); + || ThrowUserError("missing_name"); $self->{'creator'} = Bugzilla->user->id; $self->{'frequency'} = $cgi->param('frequency'); detaint_natural($self->{'frequency'}) - || &::ThrowUserError("missing_frequency"); + || ThrowUserError("missing_frequency"); $self->{'query'} = $cgi->canonicalise_query("format", "ctype", "action", "category", "subcategory", "name", @@ -165,7 +164,7 @@ sub initFromCGI { # Change 'admin' here and in series.html.tmpl, or remove the check # completely, if you want to change who can make series public. - $self->{'public'} = 0 unless UserInGroup('admin'); + $self->{'public'} = 0 unless Bugzilla->user->in_group('admin'); } sub writeToDatabase { @@ -200,16 +199,15 @@ sub writeToDatabase { # Insert the new series into the series table $dbh->do("INSERT INTO series (creator, category, subcategory, " . "name, frequency, query, is_public) VALUES " . - "($self->{'creator'}, " . - "$category_id, $subcategory_id, " . - $dbh->quote($self->{'name'}) . ", $self->{'frequency'}," . - $dbh->quote($self->{'query'}) . ", $self->{'public'})"); + "(?, ?, ?, ?, ?, ?, ?)", undef, + $self->{'creator'}, $category_id, $subcategory_id, $self->{'name'}, + $self->{'frequency'}, $self->{'query'}, $self->{'public'}); # Retrieve series_id $self->{'series_id'} = $dbh->selectrow_array("SELECT MAX(series_id) " . "FROM series"); $self->{'series_id'} - || &::ThrowCodeError("missing_series_id", { 'series' => $self }); + || ThrowCodeError("missing_series_id", { 'series' => $self }); } $dbh->bz_unlock_tables(); diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm index edb2e148d..2764afabe 100644 --- a/Bugzilla/Template.pm +++ b/Bugzilla/Template.pm @@ -27,6 +27,7 @@ # Max Kanat-Alexander <mkanat@bugzilla.org> # Frédéric Buclin <LpSolit@gmail.com> # Greg Hendricks <ghendricks@novell.com> +# David D. Kilzer <ddkilzer@kilzer.net> package Bugzilla::Template; @@ -34,14 +35,19 @@ package Bugzilla::Template; use strict; use Bugzilla::Constants; -use Bugzilla::Config qw(:DEFAULT $templatedir $datadir $project); +use Bugzilla::Install::Requirements; use Bugzilla::Util; use Bugzilla::User; use Bugzilla::Error; use MIME::Base64; +use Bugzilla::Bug; # for time2str - replace by TT Date plugin?? use Date::Format (); +use File::Find; +use File::Path; +use File::Spec; +use IO::Dir; use base qw(Template); @@ -51,27 +57,27 @@ use base qw(Template); # traverse the arrays of exported and exportable symbols, pulling out functions # (which is how Perl implements constants) and ignoring the rest (which, if # Constants.pm exports only constants, as it should, will be nothing else). -use Bugzilla::Constants (); -my %constants; -foreach my $constant (@Bugzilla::Constants::EXPORT, - @Bugzilla::Constants::EXPORT_OK) -{ - if (defined &{$Bugzilla::Constants::{$constant}}) { - # Constants can be lists, and we can't know whether we're getting - # a scalar or a list in advance, since they come to us as the return - # value of a function call, so we have to retrieve them all in list - # context into anonymous arrays, then extract the scalar ones (i.e. - # the ones whose arrays contain a single element) from their arrays. - $constants{$constant} = [&{$Bugzilla::Constants::{$constant}}]; - if (scalar(@{$constants{$constant}}) == 1) { - $constants{$constant} = @{$constants{$constant}}[0]; +sub _load_constants { + my %constants; + foreach my $constant (@Bugzilla::Constants::EXPORT, + @Bugzilla::Constants::EXPORT_OK) + { + if (defined &{$Bugzilla::Constants::{$constant}}) { + # Constants can be lists, and we can't know whether we're + # getting a scalar or a list in advance, since they come to us + # as the return value of a function call, so we have to + # retrieve them all in list context into anonymous arrays, + # then extract the scalar ones (i.e. the ones whose arrays + # contain a single element) from their arrays. + $constants{$constant} = [&{$Bugzilla::Constants::{$constant}}]; + if (scalar(@{$constants{$constant}}) == 1) { + $constants{$constant} = @{$constants{$constant}}[0]; + } } } + return \%constants; } -# XXX - mod_perl -my $template_include_path; - # Make an ordered list out of a HTTP Accept-Language header see RFC 2616, 14.4 # We ignore '*' and <language-range>;q=0 # For languages with the same priority q the order remains unchanged. @@ -100,66 +106,85 @@ sub sortAcceptLanguage { # Returns the path to the templates based on the Accept-Language # settings of the user and of the available languages # If no Accept-Language is present it uses the defined default +# Templates may also be found in the extensions/ tree sub getTemplateIncludePath { + my $lang = Bugzilla->request_cache->{'language'} || ""; # Return cached value if available - # XXXX - mod_perl! - if ($template_include_path) { - return $template_include_path; - } - my $languages = trim(Param('languages')); + my $include_path = Bugzilla->request_cache->{"template_include_path_$lang"}; + return $include_path if $include_path; + + my $templatedir = bz_locations()->{'templatedir'}; + my $project = bz_locations()->{'project'}; + + my $languages = trim(Bugzilla->params->{'languages'}); if (not ($languages =~ /,/)) { if ($project) { - $template_include_path = [ + $include_path = [ "$templatedir/$languages/$project", "$templatedir/$languages/custom", - "$templatedir/$languages/extension", "$templatedir/$languages/default" ]; } else { - $template_include_path = [ + $include_path = [ "$templatedir/$languages/custom", - "$templatedir/$languages/extension", "$templatedir/$languages/default" ]; } - return $template_include_path; } my @languages = sortAcceptLanguage($languages); - my @accept_language = sortAcceptLanguage($ENV{'HTTP_ACCEPT_LANGUAGE'} || "" ); + # If $lang is specified, only consider this language. + my @accept_language = ($lang) || sortAcceptLanguage($ENV{'HTTP_ACCEPT_LANGUAGE'} || ""); my @usedlanguages; - foreach my $lang (@accept_language) { + foreach my $language (@accept_language) { # Per RFC 1766 and RFC 2616 any language tag matches also its # primary tag. That is 'en' (accept language) matches 'en-us', # 'en-uk' etc. but not the otherway round. (This is unfortunately # not very clearly stated in those RFC; see comment just over 14.5 # in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4) - if(my @found = grep /^\Q$lang\E(-.+)?$/i, @languages) { + if(my @found = grep /^\Q$language\E(-.+)?$/i, @languages) { push (@usedlanguages, @found); } } - push(@usedlanguages, Param('defaultlanguage')); + push(@usedlanguages, Bugzilla->params->{'defaultlanguage'}); if ($project) { - $template_include_path = [ + $include_path = [ map(( "$templatedir/$_/$project", "$templatedir/$_/custom", - "$templatedir/$_/extension", "$templatedir/$_/default" ), @usedlanguages ) ]; } else { - $template_include_path = [ + $include_path = [ map(( "$templatedir/$_/custom", - "$templatedir/$_/extension", "$templatedir/$_/default" ), @usedlanguages ) ]; } - return $template_include_path; + + # add in extension template directories: + my @extensions = glob(bz_locations()->{'extensionsdir'} . "/*"); + foreach my $extension (@extensions) { + trick_taint($extension); # since this comes right from the filesystem + # we have bigger issues if it is insecure + push(@$include_path, + map(( + $extension."/template/".$_), + @usedlanguages)); + } + + # remove duplicates since they keep popping up: + my @dirs; + foreach my $dir (@$include_path) { + push(@dirs, $dir) unless grep ($dir eq $_, @dirs); + } + Bugzilla->request_cache->{"template_include_path_$lang"} = \@dirs; + + return Bugzilla->request_cache->{"template_include_path_$lang"}; } sub put_header { @@ -200,7 +225,7 @@ sub get_format { eval { $self->context->template($template); }; - # This parsing may seem fragile, but its OK: + # This parsing may seem fragile, but it's OK: # http://lists.template-toolkit.org/pipermail/templates/2003-March/004370.html # Even if it is wrong, any sort of error is going to cause a failure # eventually, so the only issue would be an incorrect error message @@ -218,6 +243,214 @@ sub get_format { }; } +# This routine quoteUrls contains inspirations from the HTML::FromText CPAN +# module by Gareth Rees <garethr@cre.canon.co.uk>. It has been heavily hacked, +# all that is really recognizable from the original is bits of the regular +# expressions. +# This has been rewritten to be faster, mainly by substituting 'as we go'. +# If you want to modify this routine, read the comments carefully + +sub quoteUrls { + my ($text, $curr_bugid) = (@_); + return $text unless $text; + + # We use /g for speed, but uris can have other things inside them + # (http://foo/bug#3 for example). Filtering that out filters valid + # bug refs out, so we have to do replacements. + # mailto can't contain space or #, so we don't have to bother for that + # Do this by escaping \0 to \1\0, and replacing matches with \0\0$count\0\0 + # \0 is used because it's unlikely to occur in the text, so the cost of + # doing this should be very small + # Also, \0 won't appear in the value_quote'd bug title, so we don't have + # to worry about bogus substitutions from there + + # escape the 2nd escape char we're using + my $chr1 = chr(1); + $text =~ s/\0/$chr1\0/g; + + # However, note that adding the title (for buglinks) can affect things + # In particular, attachment matches go before bug titles, so that titles + # with 'attachment 1' don't double match. + # Dupe checks go afterwards, because that uses ^ and \Z, which won't occur + # if it was substituted as a bug title (since that always involve leading + # and trailing text) + + # Because of entities, it's easier (and quicker) to do this before escaping + + my @things; + my $count = 0; + my $tmp; + + # Provide tooltips for full bug links (Bug 74355) + my $urlbase_re = '(' . join('|', + map { qr/$_/ } grep($_, Bugzilla->params->{'urlbase'}, + Bugzilla->params->{'sslbase'})) . ')'; + $text =~ s~\b(${urlbase_re}\Qshow_bug.cgi?id=\E([0-9]+)(\#c([0-9]+))?)\b + ~($things[$count++] = get_bug_link($3, $1, $5)) && + ("\0\0" . ($count-1) . "\0\0") + ~egox; + + # non-mailto protocols + my $safe_protocols = join('|', SAFE_PROTOCOLS); + my $protocol_re = qr/($safe_protocols)/i; + + $text =~ s~\b(${protocol_re}: # The protocol: + [^\s<>\"]+ # Any non-whitespace + [\w\/]) # so that we end in \w or / + ~($tmp = html_quote($1)) && + ($things[$count++] = "<a href=\"$tmp\">$tmp</a>") && + ("\0\0" . ($count-1) . "\0\0") + ~egox; + + # We have to quote now, otherwise the html itself is escaped + # THIS MEANS THAT A LITERAL ", <, >, ' MUST BE ESCAPED FOR A MATCH + + $text = html_quote($text); + + # Color quoted text + $text =~ s~^(>.+)$~<span class="quote">$1</span >~mg; + $text =~ s~</span >\n<span class="quote">~\n~g; + + # mailto: + # Use |<nothing> so that $1 is defined regardless + $text =~ s~\b(mailto:|)?([\w\.\-\+\=]+\@[\w\-]+(?:\.[\w\-]+)+)\b + ~<a href=\"mailto:$2\">$1$2</a>~igx; + + # attachment links - handle both cases separately for simplicity + $text =~ s~((?:^Created\ an\ |\b)attachment\s*\(id=(\d+)\)(\s\[edit\])?) + ~($things[$count++] = get_attachment_link($2, $1)) && + ("\0\0" . ($count-1) . "\0\0") + ~egmx; + + $text =~ s~\b(attachment\s*\#?\s*(\d+)) + ~($things[$count++] = get_attachment_link($2, $1)) && + ("\0\0" . ($count-1) . "\0\0") + ~egmxi; + + # Current bug ID this comment belongs to + my $current_bugurl = $curr_bugid ? "show_bug.cgi?id=$curr_bugid" : ""; + + # This handles bug a, comment b type stuff. Because we're using /g + # we have to do this in one pattern, and so this is semi-messy. + # Also, we can't use $bug_re?$comment_re? because that will match the + # empty string + my $bug_word = get_text('term', { term => 'bug' }); + my $bug_re = qr/\Q$bug_word\E\s*\#?\s*(\d+)/i; + my $comment_re = qr/comment\s*\#?\s*(\d+)/i; + $text =~ s~\b($bug_re(?:\s*,?\s*$comment_re)?|$comment_re) + ~ # We have several choices. $1 here is the link, and $2-4 are set + # depending on which part matched + (defined($2) ? get_bug_link($2,$1,$3) : + "<a href=\"$current_bugurl#c$4\">$1</a>") + ~egox; + + # Old duplicate markers. These don't use $bug_word because they are old + # and were never customizable. + $text =~ s~(?<=^\*\*\*\ This\ bug\ has\ been\ marked\ as\ a\ duplicate\ of\ ) + (\d+) + (?=\ \*\*\*\Z) + ~get_bug_link($1, $1) + ~egmx; + + # Now remove the encoding hacks + $text =~ s/\0\0(\d+)\0\0/$things[$1]/eg; + $text =~ s/$chr1\0/\0/g; + + return $text; +} + +# Creates a link to an attachment, including its title. +sub get_attachment_link { + my ($attachid, $link_text) = @_; + my $dbh = Bugzilla->dbh; + + detaint_natural($attachid) + || die "get_attachment_link() called with non-integer attachment number"; + + my ($bugid, $isobsolete, $desc) = + $dbh->selectrow_array('SELECT bug_id, isobsolete, description + FROM attachments WHERE attach_id = ?', + undef, $attachid); + + if ($bugid) { + my $title = ""; + my $className = ""; + if (Bugzilla->user->can_see_bug($bugid)) { + $title = $desc; + } + if ($isobsolete) { + $className = "bz_obsolete"; + } + # Prevent code injection in the title. + $title = value_quote($title); + + $link_text =~ s/ \[details\]$//; + my $linkval = "attachment.cgi?id=$attachid"; + # Whitespace matters here because these links are in <pre> tags. + return qq|<span class="$className">| + . qq|<a href="${linkval}" name="attach_${attachid}" title="$title">$link_text</a>| + . qq| <a href="${linkval}&action=edit" title="$title">[details]</a>| + . qq|</span>|; + } + else { + return qq{$link_text}; + } +} + +# Creates a link to a bug, including its title. +# It takes either two or three parameters: +# - The bug number +# - The link text, to place between the <a>..</a> +# - An optional comment number, for linking to a particular +# comment in the bug + +sub get_bug_link { + my ($bug_num, $link_text, $comment_num) = @_; + my $dbh = Bugzilla->dbh; + + if (!defined($bug_num) || ($bug_num eq "")) { + return "<missing bug number>"; + } + my $quote_bug_num = html_quote($bug_num); + detaint_natural($bug_num) || return "<invalid bug number: $quote_bug_num>"; + + my ($bug_state, $bug_res, $bug_desc) = + $dbh->selectrow_array('SELECT bugs.bug_status, resolution, short_desc + FROM bugs WHERE bugs.bug_id = ?', + undef, $bug_num); + + if ($bug_state) { + # Initialize these variables to be "" so that we don't get warnings + # if we don't change them below (which is highly likely). + my ($pre, $title, $post) = ("", "", ""); + + $title = $bug_state; + if ($bug_state eq 'UNCONFIRMED') { + $pre = "<i>"; + $post = "</i>"; + } + elsif (!is_open_state($bug_state)) { + $pre = '<span class="bz_closed">'; + $title .= " $bug_res"; + $post = '</span>'; + } + if (Bugzilla->user->can_see_bug($bug_num)) { + $title .= " - $bug_desc"; + } + # Prevent code injection in the title. + $title = value_quote($title); + + my $linkval = "show_bug.cgi?id=$bug_num"; + if (defined $comment_num) { + $linkval .= "#c$comment_num"; + } + return qq{$pre<a href="$linkval" title="$title">$link_text</a>$post}; + } + else { + return qq{$link_text}; + } +} + ############################################################################### # Templatization Code @@ -296,7 +529,7 @@ sub create { # We need a possibility to reset the cache, so that no files from # the previous language pollute the action. if ($opts{'clean_cache'}) { - $template_include_path = undef; + delete Bugzilla->request_cache->{template_include_path_}; } # IMPORTANT - If you make any configuration changes here, make sure to @@ -313,7 +546,7 @@ sub create { PRE_CHOMP => 1, TRIM => 1, - COMPILE_DIR => "$datadir/template", + COMPILE_DIR => bz_locations()->{'datadir'} . "/template", # Initialize templates (f.e. by loading plugins like Hook). PRE_PROCESS => "global/initialize.none.tmpl", @@ -406,7 +639,7 @@ sub create { my ($context, $bug) = @_; return sub { my $text = shift; - return &::quoteUrls($text, $bug); + return quoteUrls($text, $bug); }; }, 1 @@ -416,12 +649,18 @@ sub create { my ($context, $bug) = @_; return sub { my $text = shift; - return &::GetBugLink($bug, $text); + return get_bug_link($bug, $text); }; }, 1 ], + bug_list_link => sub + { + my $buglist = shift; + return join(", ", map(get_bug_link($_, $_), split(/ *, */, $buglist))); + }, + # In CSV, quotes are doubled, and any value containing a quote or a # comma is enclosed in quotes. csv => sub @@ -468,7 +707,7 @@ sub create { my ($var) = Template::Filters::html_filter(@_); # Obscure '@'. $var =~ s/\@/\@/g; - if (Param('utf8')) { + if (Bugzilla->params->{'utf8'}) { # Remove the following characters because they're # influencing BiDi: # -------------------------------------------------------- @@ -510,7 +749,7 @@ sub create { my ($output) = ""; $var =~ s/[\r\n]/ /g; - $var =~ s/([;\\\",])/\\$1/g; + $var =~ s/([;\\\"])/\\$1/g; if ($par) { $output = sprintf("%s:%s", $par, $var); @@ -526,6 +765,22 @@ sub create { 1 ], + # Note that using this filter is even more dangerous than + # using "none," and you should only use it when you're SURE + # the output won't be displayed directly to a web browser. + txt => sub { + my ($var) = @_; + # Trivial HTML tag remover + $var =~ s/<[^>]*>//g; + # And this basically reverses the html filter. + $var =~ s/\@/@/g; + $var =~ s/\</</g; + $var =~ s/\>/>/g; + $var =~ s/\"/\"/g; + $var =~ s/\&/\&/g; + return $var; + }, + # Wrap a displayed comment to the appropriate length wrap_comment => \&Bugzilla::Util::wrap_comment, @@ -537,12 +792,12 @@ sub create { PLUGIN_BASE => 'Bugzilla::Template::Plugin', - CONSTANTS => \%constants, + CONSTANTS => _load_constants(), # Default variables for all templates VARIABLES => { # Function for retrieving global parameters. - 'Param' => \&Bugzilla::Config::Param, + 'Param' => sub { return Bugzilla->params->{$_[0]}; }, # Function to create date strings 'time2str' => \&Date::Format::time2str, @@ -558,9 +813,6 @@ sub create { # started the session. 'sudoer' => sub { return Bugzilla->sudoer; }, - # UserInGroup. Deprecated - use the user.* functions instead - 'UserInGroup' => \&Bugzilla::User::UserInGroup, - # SendBugMail - sends mail about a bug, using Bugzilla::BugMail.pm 'SendBugMail' => sub { my ($id, $mailrecipients) = (@_); @@ -568,14 +820,99 @@ sub create { Bugzilla::BugMail::Send($id, $mailrecipients); }, - # Bugzilla version - # This could be made a ref, or even a CONSTANT with TT2.08 - 'VERSION' => $Bugzilla::Config::VERSION , + # These don't work as normal constants. + DB_MODULE => \&Bugzilla::Constants::DB_MODULE, + REQUIRED_MODULES => + \&Bugzilla::Install::Requirements::REQUIRED_MODULES, + OPTIONAL_MODULES => sub { + my @optional = @{OPTIONAL_MODULES()}; + @optional = sort {$a->{feature} cmp $b->{feature}} + @optional; + return \@optional; + }, }, }) || die("Template creation failed: " . $class->error()); } +# Used as part of the two subroutines below. +our (%_templates_to_precompile, $_current_path); + +sub precompile_templates { + my ($output) = @_; + + # Remove the compiled templates. + my $datadir = bz_locations()->{'datadir'}; + if (-e "$datadir/template") { + print "Removing existing compiled templates ...\n" if $output; + + # XXX This frequently fails if the webserver made the files, because + # then the webserver owns the directories. We could fix that by + # doing a chmod/chown on all the directories here. + rmtree("$datadir/template"); + + # Check that the directory was really removed + if(-e "$datadir/template") { + print "\n\n"; + print "The directory '$datadir/template' could not be removed.\n"; + print "Please remove it manually and rerun checksetup.pl.\n\n"; + exit; + } + } + + print "Precompiling templates...\n" if $output; + + my $templatedir = bz_locations()->{'templatedir'}; + # Don't hang on templates which use the CGI library + eval("use CGI qw(-no_debug)"); + + my $dir_reader = new IO::Dir($templatedir) || die "$templatedir: $!"; + my @language_dirs = grep { /^[a-z-]+$/i } $dir_reader->read; + $dir_reader->close; + + foreach my $dir (@language_dirs) { + next if ($dir eq 'CVS'); + -d "$templatedir/$dir/default" || -d "$templatedir/$dir/custom" + || next; + local $ENV{'HTTP_ACCEPT_LANGUAGE'} = $dir; + # We locally hack this parameter so that Bugzilla::Template + # accepts this language no matter what. + local Bugzilla->params->{'languages'} = "$dir,en"; + my $template = Bugzilla::Template->create(clean_cache => 1); + + # Precompile all the templates found in all the directories. + %_templates_to_precompile = (); + foreach my $subdir (qw(custom extension default), bz_locations()->{'project'}) { + next unless $subdir; # If 'project' is empty. + $_current_path = File::Spec->catdir($templatedir, $dir, $subdir); + next unless -d $_current_path; + # Traverse the template hierarchy. + find({ wanted => \&_precompile_push, no_chdir => 1 }, $_current_path); + } + # The sort isn't totally necessary, but it makes debugging easier + # by making the templates always be compiled in the same order. + foreach my $file (sort keys %_templates_to_precompile) { + # Compile the template but throw away the result. This has the side- + # effect of writing the compiled version to disk. + $template->context->template($file); + } + } + + # If anything created a Template object before now, clear it out. + delete Bugzilla->request_cache->{template}; +} + +# Helper for precompile_templates +sub _precompile_push { + my $name = $File::Find::name; + return if (-d $name); + return if ($name =~ /\/CVS\//); + return if ($name !~ /\.tmpl$/); + + $name =~ s/\Q$_current_path\E\///; + $_templates_to_precompile{$name} = 1; +} + 1; __END__ @@ -603,6 +940,22 @@ the C<Template> constructor. It should not be used directly by scripts or modules - instead, use C<Bugzilla-E<gt>instance-E<gt>template> to get an already created module. +=head1 SUBROUTINES + +=over + +=item C<precompile_templates($output)> + +Description: Compiles all of Bugzilla's templates in every language. + Used mostly by F<checksetup.pl>. + +Params: C<$output> - C<true> if you want the function to print + out information about what it's doing. + +Returns: nothing + +=back + =head1 METHODS =over diff --git a/Bugzilla/Template/CVS/Tag b/Bugzilla/Template/CVS/Tag index a828702f4..941648ec7 100644 --- a/Bugzilla/Template/CVS/Tag +++ b/Bugzilla/Template/CVS/Tag @@ -1 +1 @@ -TBUGZILLA-2_22_3 +TBUGZILLA-3_0 diff --git a/Bugzilla/Template/Plugin/CVS/Entries b/Bugzilla/Template/Plugin/CVS/Entries index 4176f174d..fc4a382ee 100644 --- a/Bugzilla/Template/Plugin/CVS/Entries +++ b/Bugzilla/Template/Plugin/CVS/Entries @@ -1,4 +1,4 @@ -/Bugzilla.pm/1.2/Fri Feb 7 07:19:15 2003//TBUGZILLA-2_22_3 -/Hook.pm/1.1.12.1/Fri Mar 3 12:21:21 2006//TBUGZILLA-2_22_3 -/User.pm/1.1/Wed Aug 4 18:08:21 2004//TBUGZILLA-2_22_3 +/Bugzilla.pm/1.2/Fri Feb 7 07:19:15 2003//TBUGZILLA-3_0 +/Hook.pm/1.7/Mon Jul 3 21:42:47 2006//TBUGZILLA-3_0 +/User.pm/1.1/Wed Aug 4 18:08:21 2004//TBUGZILLA-3_0 D diff --git a/Bugzilla/Template/Plugin/CVS/Tag b/Bugzilla/Template/Plugin/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/Bugzilla/Template/Plugin/CVS/Tag +++ b/Bugzilla/Template/Plugin/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/Bugzilla/Template/Plugin/Hook.pm b/Bugzilla/Template/Plugin/Hook.pm index 90aa0724d..a5eec820b 100644 --- a/Bugzilla/Template/Plugin/Hook.pm +++ b/Bugzilla/Template/Plugin/Hook.pm @@ -18,12 +18,19 @@ # Rights Reserved. # # Contributor(s): Myk Melez <myk@mozilla.org> +# Zach Lipton <zach@zachlipton.com> # package Bugzilla::Template::Plugin::Hook; use strict; +use Bugzilla::Constants; +use Bugzilla::Template; +use Bugzilla::Util; +use Bugzilla::Error; +use File::Spec; + use base qw(Template::Plugin); sub load { @@ -42,7 +49,38 @@ sub process { my $paths = $self->{_CONTEXT}->{LOAD_TEMPLATES}->[0]->paths; my $template = $self->{_CONTEXT}->stash->{component}->{name}; my @hooks = (); + + # sanity check: + if (!$template =~ /[\w\.\/\-_\\]+/) { + ThrowCodeError('template_invalid', { name => $template}); + } + # also get extension hook files that live in extensions/: + # parse out the parts of the template name + my ($vol, $subpath, $filename) = File::Spec->splitpath($template); + $subpath = $subpath || ''; + $filename =~ m/(.*)\.(.*)\.tmpl/; + my $templatename = $1; + my $type = $2; + # munge the filename to create the extension hook filename: + my $extensiontemplate = $subpath.'/'.$templatename.'-'.$hook_name.'.'.$type.'.tmpl'; + my @extensions = glob(bz_locations()->{'extensionsdir'} . "/*"); + my @usedlanguages = getLanguages(); + foreach my $extension (@extensions) { + foreach my $language (@usedlanguages) { + my $file = $extension.'/template/'.$language.'/'.$extensiontemplate; + if (-e $file) { + # tt is stubborn and won't take a template file not in its + # include path, so we open a filehandle and give it to process() + # so the hook gets invoked: + open (my $fh, $file); + push(@hooks, $fh); + } + } + } + + # we keep this too since you can still put hook templates in + # template/en/custom/hook foreach my $path (@$paths) { my @files = glob("$path/hook/$template/$hook_name/*.tmpl"); @@ -65,6 +103,24 @@ sub process { return $output; } +# get a list of languages we accept so we can find the hook +# that corresponds to our desired languages: +sub getLanguages() { + my $languages = trim(Bugzilla->params->{'languages'}); + if (not ($languages =~ /,/)) { # only one language + return $languages; + } + my @languages = Bugzilla::Template::sortAcceptLanguage($languages); + my @accept_language = Bugzilla::Template::sortAcceptLanguage($ENV{'HTTP_ACCEPT_LANGUAGE'} || "" ); + my @usedlanguages; + foreach my $lang (@accept_language) { + if(my @found = grep /^\Q$lang\E(-.+)?$/i, @languages) { + push (@usedlanguages, @found); + } + } + return @usedlanguages; +} + 1; __END__ @@ -79,5 +135,7 @@ Template Toolkit plugin to process hooks added into templates by extensions. =head1 SEE ALSO -L<Template::Plugin>, +L<Template::Plugin> +L<http:E<sol>E<sol>www.bugzilla.orgE<sol>docsE<sol>tipE<sol>htmlE<sol>customization.html> L<http:E<sol>E<sol>bugzilla.mozilla.orgE<sol>show_bug.cgi?id=229658> +L<http:E<sol>E<sol>bugzilla.mozilla.orgE<sol>show_bug.cgi?id=298341> diff --git a/Bugzilla/Token.pm b/Bugzilla/Token.pm index 807e546a5..7db6b9165 100644 --- a/Bugzilla/Token.pm +++ b/Bugzilla/Token.pm @@ -30,9 +30,9 @@ use strict; # Bundle the functions in this file together into the "Bugzilla::Token" package. package Bugzilla::Token; -use Bugzilla::Config; +use Bugzilla::Constants; use Bugzilla::Error; -use Bugzilla::BugMail; +use Bugzilla::Mailer; use Bugzilla::Util; use Date::Format; @@ -43,22 +43,49 @@ use base qw(Exporter); @Bugzilla::Token::EXPORT = qw(issue_session_token check_token_data delete_token); -# This module requires that its caller have said "require globals.pl" to import -# relevant functions from that script. - ################################################################################ -# Constants +# Public Functions ################################################################################ -# The maximum number of days a token will remain valid. -my $maxtokenage = 3; +# Creates and sends a token to create a new user account. +# It assumes that the login has the correct format and is not already in use. +sub issue_new_user_account_token { + my $login_name = shift; + my $dbh = Bugzilla->dbh; + my $template = Bugzilla->template; + my $vars = {}; -################################################################################ -# Public Functions -################################################################################ + # Is there already a pending request for this login name? If yes, do not throw + # an error because the user may have lost his email with the token inside. + # But to prevent using this way to mailbomb an email address, make sure + # the last request is at least 10 minutes old before sending a new email. + + my $pending_requests = + $dbh->selectrow_array('SELECT COUNT(*) + FROM tokens + WHERE tokentype = ? + AND ' . $dbh->sql_istrcmp('eventdata', '?') . ' + AND issuedate > NOW() - ' . $dbh->sql_interval(10, 'MINUTE'), + undef, ('account', $login_name)); + + ThrowUserError('too_soon_for_new_token', {'type' => 'account'}) if $pending_requests; + + my ($token, $token_ts) = _create_token(undef, 'account', $login_name); + + $vars->{'email'} = $login_name . Bugzilla->params->{'emailsuffix'}; + $vars->{'token_ts'} = $token_ts; + $vars->{'token'} = $token; + + my $message; + $template->process('account/email/request-new.txt.tmpl', $vars, \$message) + || ThrowTemplateError($template->error()); + + MessageToMTA($message); +} sub IssueEmailChangeToken { my ($userid, $old_email, $new_email) = @_; + my $email_suffix = Bugzilla->params->{'emailsuffix'}; my ($token, $token_ts) = _create_token($userid, 'emailold', $old_email . ":" . $new_email); @@ -69,65 +96,61 @@ sub IssueEmailChangeToken { my $template = Bugzilla->template; my $vars = {}; - $vars->{'oldemailaddress'} = $old_email . Param('emailsuffix'); - $vars->{'newemailaddress'} = $new_email . Param('emailsuffix'); + $vars->{'oldemailaddress'} = $old_email . $email_suffix; + $vars->{'newemailaddress'} = $new_email . $email_suffix; - $vars->{'max_token_age'} = $maxtokenage; + $vars->{'max_token_age'} = MAX_TOKEN_AGE; $vars->{'token_ts'} = $token_ts; $vars->{'token'} = $token; - $vars->{'emailaddress'} = $old_email . Param('emailsuffix'); + $vars->{'emailaddress'} = $old_email . $email_suffix; my $message; $template->process("account/email/change-old.txt.tmpl", $vars, \$message) || ThrowTemplateError($template->error()); - Bugzilla::BugMail::MessageToMTA($message); + MessageToMTA($message); $vars->{'token'} = $newtoken; - $vars->{'emailaddress'} = $new_email . Param('emailsuffix'); + $vars->{'emailaddress'} = $new_email . $email_suffix; $message = ""; $template->process("account/email/change-new.txt.tmpl", $vars, \$message) || ThrowTemplateError($template->error()); - Bugzilla::BugMail::MessageToMTA($message); + MessageToMTA($message); } +# Generates a random token, adds it to the tokens table, and sends it +# to the user with instructions for using it to change their password. sub IssuePasswordToken { - # Generates a random token, adds it to the tokens table, and sends it - # to the user with instructions for using it to change their password. - - my ($loginname) = @_; - + my $loginname = shift; my $dbh = Bugzilla->dbh; + my $template = Bugzilla->template; + my $vars = {}; # Retrieve the user's ID from the database. - my $quotedloginname = &::SqlQuote($loginname); - &::SendSQL("SELECT profiles.userid, tokens.issuedate FROM profiles - LEFT JOIN tokens - ON tokens.userid = profiles.userid - AND tokens.tokentype = 'password' - AND tokens.issuedate > NOW() - " . - $dbh->sql_interval(10, 'MINUTE') . " - WHERE " . $dbh->sql_istrcmp('login_name', $quotedloginname)); - my ($userid, $toosoon) = &::FetchSQLData(); - - if ($toosoon) { - ThrowUserError('too_soon_for_new_token'); - }; + trick_taint($loginname); + my ($userid, $too_soon) = + $dbh->selectrow_array('SELECT profiles.userid, tokens.issuedate + FROM profiles + LEFT JOIN tokens + ON tokens.userid = profiles.userid + AND tokens.tokentype = ? + AND tokens.issuedate > NOW() - ' . + $dbh->sql_interval(10, 'MINUTE') . ' + WHERE ' . $dbh->sql_istrcmp('login_name', '?'), + undef, ('password', $loginname)); + + ThrowUserError('too_soon_for_new_token', {'type' => 'password'}) if $too_soon; my ($token, $token_ts) = _create_token($userid, 'password', $::ENV{'REMOTE_ADDR'}); # Mail the user the token along with instructions for using it. - - my $template = Bugzilla->template; - my $vars = {}; - $vars->{'token'} = $token; - $vars->{'emailaddress'} = $loginname . Param('emailsuffix'); + $vars->{'emailaddress'} = $loginname . Bugzilla->params->{'emailsuffix'}; - $vars->{'max_token_age'} = $maxtokenage; + $vars->{'max_token_age'} = MAX_TOKEN_AGE; $vars->{'token_ts'} = $token_ts; my $message = ""; @@ -135,7 +158,7 @@ sub IssuePasswordToken { $vars, \$message) || ThrowTemplateError($template->error()); - Bugzilla::BugMail::MessageToMTA($message); + MessageToMTA($message); } sub issue_session_token { @@ -149,9 +172,10 @@ sub issue_session_token { sub CleanTokenTable { my $dbh = Bugzilla->dbh; $dbh->bz_lock_tables('tokens WRITE'); - &::SendSQL("DELETE FROM tokens WHERE " . - $dbh->sql_to_days('NOW()') . " - " . - $dbh->sql_to_days('issuedate') . " >= " . $maxtokenage); + $dbh->do('DELETE FROM tokens + WHERE ' . $dbh->sql_to_days('NOW()') . ' - ' . + $dbh->sql_to_days('issuedate') . ' >= ?', + undef, MAX_TOKEN_AGE); $dbh->bz_unlock_tables(); } @@ -160,9 +184,8 @@ sub GenerateUniqueToken { # for the tokens themselves and checks uniqueness by searching for # the token in the "tokens" table. Gives up if it can't come up # with a token after about one hundred tries. - my ($table, $column) = @_; - + my $token; my $duplicate = 1; my $tries = 0; @@ -181,38 +204,34 @@ sub GenerateUniqueToken { $sth->execute($token); $duplicate = $sth->fetchrow_array; } - return $token; } +# Cancels a previously issued token and notifies the system administrator. +# This should only happen when the user accidentally makes a token request +# or when a malicious hacker makes a token request on behalf of a user. sub Cancel { - # Cancels a previously issued token and notifies the system administrator. - # This should only happen when the user accidentally makes a token request - # or when a malicious hacker makes a token request on behalf of a user. - my ($token, $cancelaction, $vars) = @_; - my $dbh = Bugzilla->dbh; - $vars ||= {}; - - # Quote the token for inclusion in SQL statements. - my $quotedtoken = &::SqlQuote($token); - - # Get information about the token being cancelled. - &::SendSQL("SELECT " . $dbh->sql_date_format('issuedate') . ", - tokentype , eventdata , login_name , realname - FROM tokens, profiles - WHERE tokens.userid = profiles.userid - AND token = $quotedtoken"); - my ($issuedate, $tokentype, $eventdata, $loginname, $realname) = &::FetchSQLData(); - - # Get the email address of the Bugzilla maintainer. - my $maintainer = Param('maintainer'); - my $template = Bugzilla->template; + $vars ||= {}; - $vars->{'emailaddress'} = $loginname . Param('emailsuffix'); - $vars->{'maintainer'} = $maintainer; + # Get information about the token being canceled. + trick_taint($token); + my ($issuedate, $tokentype, $eventdata, $loginname) = + $dbh->selectrow_array('SELECT ' . $dbh->sql_date_format('issuedate') . ', + tokentype, eventdata, login_name + FROM tokens + LEFT JOIN profiles + ON tokens.userid = profiles.userid + WHERE token = ?', + undef, $token); + + # If we are cancelling the creation of a new user account, then there + # is no entry in the 'profiles' table. + $loginname ||= $eventdata; + $vars->{'emailaddress'} = $loginname . Bugzilla->params->{'emailsuffix'}; + $vars->{'maintainer'} = Bugzilla->params->{'maintainer'}; $vars->{'remoteaddress'} = $::ENV{'REMOTE_ADDR'}; $vars->{'token'} = $token; $vars->{'tokentype'} = $tokentype; @@ -226,7 +245,7 @@ sub Cancel { $template->process("account/cancel-token.txt.tmpl", $vars, \$message) || ThrowTemplateError($template->error()); - Bugzilla::BugMail::MessageToMTA($message); + MessageToMTA($message); # Delete the token from the database. delete_token($token); @@ -234,54 +253,54 @@ sub Cancel { sub DeletePasswordTokens { my ($userid, $reason) = @_; - my $dbh = Bugzilla->dbh; - my $sth = $dbh->prepare("SELECT token " . - "FROM tokens " . - "WHERE userid=? AND tokentype='password'"); - $sth->execute($userid); - while (my $token = $sth->fetchrow_array) { + + detaint_natural($userid); + my $tokens = $dbh->selectcol_arrayref('SELECT token FROM tokens + WHERE userid = ? AND tokentype = ?', + undef, ($userid, 'password')); + + foreach my $token (@$tokens) { Bugzilla::Token::Cancel($token, $reason); } } +# Returns an email change token if the user has one. sub HasEmailChangeToken { - # Returns an email change token if the user has one. - - my ($userid) = @_; - + my $userid = shift; my $dbh = Bugzilla->dbh; - &::SendSQL("SELECT token FROM tokens WHERE userid = $userid " . - "AND (tokentype = 'emailnew' OR tokentype = 'emailold') " . - $dbh->sql_limit(1)); - my ($token) = &::FetchSQLData(); - + + my $token = $dbh->selectrow_array('SELECT token FROM tokens + WHERE userid = ? + AND (tokentype = ? OR tokentype = ?) ' . + $dbh->sql_limit(1), + undef, ($userid, 'emailnew', 'emailold')); return $token; } +# Returns the userid, issuedate and eventdata for the specified token sub GetTokenData { - # Returns the userid, issuedate and eventdata for the specified token - my ($token) = @_; + my $dbh = Bugzilla->dbh; + return unless defined $token; $token = clean_text($token); trick_taint($token); - - my $dbh = Bugzilla->dbh; + return $dbh->selectrow_array( "SELECT userid, " . $dbh->sql_date_format('issuedate') . ", eventdata FROM tokens WHERE token = ?", undef, $token); } +# Deletes specified token sub delete_token { - # Deletes specified token - my ($token) = @_; + my $dbh = Bugzilla->dbh; + return unless defined $token; trick_taint($token); - my $dbh = Bugzilla->dbh; $dbh->bz_lock_tables('tokens WRITE'); $dbh->do("DELETE FROM tokens WHERE token = ?", undef, $token); $dbh->bz_unlock_tables(); @@ -335,16 +354,16 @@ sub check_token_data { # Internal Functions ################################################################################ +# Generates a unique token and inserts it into the database +# Returns the token and the token timestamp sub _create_token { - # Generates a unique token and inserts it into the database - # Returns the token and the token timestamp my ($userid, $tokentype, $eventdata) = @_; + my $dbh = Bugzilla->dbh; - detaint_natural($userid); + detaint_natural($userid) if defined $userid; trick_taint($tokentype); trick_taint($eventdata); - my $dbh = Bugzilla->dbh; $dbh->bz_lock_tables('tokens WRITE'); my $token = GenerateUniqueToken(); @@ -375,6 +394,7 @@ Bugzilla::Token - Provides different routines to manage tokens. use Bugzilla::Token; + Bugzilla::Token::issue_new_user_account_token($login_name); Bugzilla::Token::IssueEmailChangeToken($user_id, $old_email, $new_email); Bugzilla::Token::IssuePasswordToken($login_name); Bugzilla::Token::DeletePasswordTokens($user_id, $reason); @@ -394,6 +414,18 @@ Bugzilla::Token - Provides different routines to manage tokens. =over +=item C<issue_new_user_account_token($login_name)> + + Description: Creates and sends a token per email to the email address + requesting a new user account. It doesn't check whether + the user account already exists. The user will have to + use this token to confirm the creation of his user account. + + Params: $login_name - The new login name requested by the user. + + Returns: Nothing. It throws an error if the same user made the same + request in the last few minutes. + =item C<sub IssueEmailChangeToken($user_id, $old_email, $new_email)> Description: Sends two distinct tokens per email to the old and new email @@ -457,8 +489,8 @@ Bugzilla::Token - Provides different routines to manage tokens. to the user to inform him about this action. Params: $user_id: The user ID of the user account whose password tokens - are cancelled. - $reason: The reason why these tokens are cancelled. + are canceled. + $reason: The reason why these tokens are canceled. Returns: Nothing. diff --git a/Bugzilla/Update.pm b/Bugzilla/Update.pm new file mode 100644 index 000000000..f2b17a6b0 --- /dev/null +++ b/Bugzilla/Update.pm @@ -0,0 +1,224 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + +package Bugzilla::Update; + +use strict; + +use Bugzilla::Constants; + +use constant REMOTE_FILE => 'http://updates.bugzilla.org/bugzilla-update.xml'; +use constant LOCAL_FILE => "/bugzilla-update.xml"; # Relative to datadir. +use constant TIME_INTERVAL => 86400; # Default is one day, in seconds. +use constant TIMEOUT => 5; # Number of seconds before timeout. + +# Look for new releases and notify logged in administrators about them. +sub get_notifications { + return if (Bugzilla->params->{'upgrade_notification'} eq 'disabled'); + + # If the XML::Twig module is missing, we won't be able to parse + # the XML file. So there is no need to go further. + eval("require XML::Twig"); + return if $@; + + my $local_file = bz_locations()->{'datadir'} . LOCAL_FILE; + # Update the local XML file if this one doesn't exist or if + # the last modification time (stat[9]) is older than TIME_INTERVAL. + if (!-e $local_file || (time() - (stat($local_file))[9] > TIME_INTERVAL)) { + # Are we sure we didn't try to refresh this file already + # but we failed because we cannot modify its timestamp? + my $can_alter = 1; + if (-e $local_file) { + # Try to alter its last modification time. + $can_alter = utime(undef, undef, $local_file); + } + if ($can_alter) { + my $error = _synchronize_data(); + # If an error is returned, leave now. + return $error if $error; + } + else { + return {'error' => 'no_update', 'xml_file' => $local_file}; + } + } + + # If we cannot access the local XML file, ignore it. + return {'error' => 'no_access', 'xml_file' => $local_file} unless (-r $local_file); + + my $twig = XML::Twig->new(); + $twig->safe_parsefile($local_file); + # If the XML file is invalid, return. + return {'error' => 'corrupted', 'xml_file' => $local_file} if $@; + my $root = $twig->root; + + my @releases; + foreach my $branch ($root->children('branch')) { + my $release = { + 'branch_ver' => $branch->{'att'}->{'id'}, + 'latest_ver' => $branch->{'att'}->{'vid'}, + 'status' => $branch->{'att'}->{'status'}, + 'url' => $branch->{'att'}->{'url'}, + 'date' => $branch->{'att'}->{'date'} + }; + push(@releases, $release); + } + + # On which branch is the current installation running? + my @current_version = + (BUGZILLA_VERSION =~ m/^(\d+)\.(\d+)(?:(rc|\.)(\d+))?\+?$/); + + my @release; + if (Bugzilla->params->{'upgrade_notification'} eq 'development_snapshot') { + @release = grep {$_->{'status'} eq 'development'} @releases; + # If there is no development snapshot available, then we are in the + # process of releasing a release candidate. That's the release we want. + unless (scalar(@release)) { + @release = grep {$_->{'status'} eq 'release-candidate'} @releases; + } + } + elsif (Bugzilla->params->{'upgrade_notification'} eq 'latest_stable_release') { + @release = grep {$_->{'status'} eq 'stable'} @releases; + } + elsif (Bugzilla->params->{'upgrade_notification'} eq 'stable_branch_release') { + # We want the latest stable version for the current branch. + # If we are running a development snapshot, we won't match anything. + my $branch_version = $current_version[0] . '.' . $current_version[1]; + + # We do a string comparison instead of a numerical one, because + # e.g. 2.2 == 2.20, but 2.2 ne 2.20 (and 2.2 is indeed much older). + @release = grep {$_->{'branch_ver'} eq $branch_version} @releases; + + # If the branch is now closed, we should strongly suggest + # to upgrade to the latest stable release available. + if (scalar(@release) && $release[0]->{'status'} eq 'closed') { + @release = grep {$_->{'status'} eq 'stable'} @releases; + return {'data' => $release[0], 'deprecated' => $branch_version}; + } + } + else { + # Unknown parameter. + return {'error' => 'unknown_parameter'}; + } + + # Return if no new release is available. + return unless scalar(@release); + + # Only notify the administrator if the latest version available + # is newer than the current one. + my @new_version = + ($release[0]->{'latest_ver'} =~ m/^(\d+)\.(\d+)(?:(rc|\.)(\d+))?\+?$/); + + # We convert release candidates 'rc' to integers (rc ? 0 : 1) in order + # to compare versions easily. + $current_version[2] = ($current_version[2] && $current_version[2] eq 'rc') ? 0 : 1; + $new_version[2] = ($new_version[2] && $new_version[2] eq 'rc') ? 0 : 1; + + my $is_newer = _compare_versions(\@current_version, \@new_version); + return ($is_newer == 1) ? {'data' => $release[0]} : undef; +} + +sub _synchronize_data { + eval("require LWP::UserAgent"); + return {'error' => 'missing_package', 'package' => 'LWP::UserAgent'} if $@; + + my $local_file = bz_locations()->{'datadir'} . LOCAL_FILE; + + my $ua = LWP::UserAgent->new(); + $ua->timeout(TIMEOUT); + $ua->protocols_allowed(['http', 'https']); + # If the URL of the proxy is given, use it, else get this information + # from the environment variable. + my $proxy_url = Bugzilla->params->{'proxy_url'}; + if ($proxy_url) { + $ua->proxy(['http', 'https'], $proxy_url); + } + else { + $ua->env_proxy; + } + $ua->mirror(REMOTE_FILE, $local_file); + + # $ua->mirror() forces the modification time of the local XML file + # to match the modification time of the remote one. + # So we have to update it manually to reflect that a newer version + # of the file has effectively been requested. This will avoid + # any new download for the next TIME_INTERVAL. + if (-e $local_file) { + # Try to alter its last modification time. + my $can_alter = utime(undef, undef, $local_file); + # This error should never happen. + $can_alter || return {'error' => 'no_update', 'xml_file' => $local_file}; + } + else { + # We have been unable to download the file. + return {'error' => 'cannot_download', 'xml_file' => $local_file}; + } + + # Everything went well. + return 0; +} + +sub _compare_versions { + my ($old_ver, $new_ver) = @_; + while (scalar(@$old_ver) && scalar(@$new_ver)) { + my $old = shift(@$old_ver) || 0; + my $new = shift(@$new_ver) || 0; + return $new <=> $old if ($new <=> $old); + } + return scalar(@$new_ver) <=> scalar(@$old_ver); + +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Update - Update routines for Bugzilla + +=head1 SYNOPSIS + + use Bugzilla::Update; + + # Get information about new releases + my $new_release = Bugzilla::Update::get_notifications(); + +=head1 DESCRIPTION + +This module contains all required routines to notify you +about new releases. It downloads an XML file from bugzilla.org +and parses it, in order to display information based on your +preferences. Absolutely no information about the Bugzilla version +you are running is sent to bugzilla.org. + +=head1 FUNCTIONS + +=over + +=item C<get_notifications()> + + Description: This function informs you about new releases, if any. + + Params: None. + + Returns: On success, a reference to a hash with data about + new releases, if any. + On failure, a reference to a hash with the reason + of the failure and the name of the unusable XML file. + +=back + +=cut diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm index 5c9ed9367..3e952e56d 100644 --- a/Bugzilla/User.pm +++ b/Bugzilla/User.pm @@ -27,6 +27,9 @@ # Gervase Markham <gerv@gerv.net> # Lance Larsh <lance.larsh@oracle.com> # Justin C. De Vries <judevries@novell.com> +# Dennis Melentyev <dennis.melentyev@infopulse.com.ua> +# Frédéric Buclin <LpSolit@gmail.com> +# Mads Bondo Dydensborg <mbd@dbc.dk> ################################################################################ # Module Initialization @@ -38,18 +41,17 @@ use strict; # This module implements utilities for dealing with Bugzilla users. package Bugzilla::User; -use Bugzilla::Config; use Bugzilla::Error; use Bugzilla::Util; use Bugzilla::Constants; use Bugzilla::User::Setting; use Bugzilla::Product; use Bugzilla::Classification; +use Bugzilla::Field; -use base qw(Exporter); -@Bugzilla::User::EXPORT = qw(insert_new_user is_available_username - login_to_id - UserInGroup +use base qw(Bugzilla::Object Exporter); +@Bugzilla::User::EXPORT = qw(is_available_username + login_to_id user_id_to_login validate_password USER_MATCH_MULTIPLE USER_MATCH_FAILED USER_MATCH_SUCCESS MATCH_SKIP_CONFIRM ); @@ -64,116 +66,182 @@ use constant USER_MATCH_SUCCESS => 1; use constant MATCH_SKIP_CONFIRM => 1; +use constant DEFAULT_USER => { + 'id' => 0, + 'realname' => '', + 'login_name' => '', + 'showmybugslink' => 0, + 'disabledtext' => '', + 'disable_mail' => 0, +}; + +use constant DB_TABLE => 'profiles'; + +# XXX Note that Bugzilla::User->name does not return the same thing +# that you passed in for "name" to new(). That's because historically +# Bugzilla::User used "name" for the realname field. This should be +# fixed one day. +use constant DB_COLUMNS => ( + 'profiles.userid AS id', + 'profiles.login_name', + 'profiles.realname', + 'profiles.mybugslink AS showmybugslink', + 'profiles.disabledtext', + 'profiles.disable_mail', +); +use constant NAME_FIELD => 'login_name'; +use constant ID_FIELD => 'userid'; +use constant LIST_ORDER => NAME_FIELD; + +use constant REQUIRED_CREATE_FIELDS => qw(login_name cryptpassword); + +use constant VALIDATORS => { + cryptpassword => \&_check_password, + disable_mail => \&_check_disable_mail, + disabledtext => \&_check_disabledtext, + login_name => \&check_login_name_for_creation, + realname => \&_check_realname, +}; + +sub UPDATE_COLUMNS { + my $self = shift; + my @cols = qw( + disable_mail + disabledtext + login_name + realname + ); + push(@cols, 'cryptpassword') if exists $self->{cryptpassword}; + return @cols; +}; + ################################################################################ # Functions ################################################################################ sub new { my $invocant = shift; - my $user_id = shift; + my $class = ref($invocant) || $invocant; + my ($param) = @_; - if ($user_id) { - my $uid = $user_id; - detaint_natural($user_id) - || ThrowCodeError('invalid_numeric_argument', - {argument => 'userID', - value => $uid, - function => 'Bugzilla::User::new'}); - return $invocant->_create("userid=?", $user_id); - } - else { - return $invocant->_create; + my $user = DEFAULT_USER; + bless ($user, $class); + return $user unless $param; + + return $class->SUPER::new(@_); +} + +sub update { + my $self = shift; + my $changes = $self->SUPER::update(@_); + my $dbh = Bugzilla->dbh; + + if (exists $changes->{login_name}) { + # If we changed the login, silently delete any tokens. + $dbh->do('DELETE FROM tokens WHERE userid = ?', undef, $self->id); + # And rederive regex groups + $self->derive_regexp_groups(); } + + # Logout the user if necessary. + Bugzilla->logout_user($self) + if (exists $changes->{login_name} || exists $changes->{disabledtext} + || exists $changes->{cryptpassword}); + + # XXX Can update profiles_activity here as soon as it understands + # field names like login_name. + + return $changes; } -# This routine is sort of evil. Nothing except the login stuff should -# be dealing with addresses as an input, and they can get the id as a -# side effect of the other sql they have to do anyway. -# Bugzilla::BugMail still does this, probably as a left over from the -# pre-id days. Provide this as a helper, but don't document it, and hope -# that it can go away. -# The request flag stuff also does this, but it really should be passing -# in the id its already had to validate (or the User.pm object, of course) -sub new_from_login { - my $invocant = shift; - my $login = shift; +################################################################################ +# Validators +################################################################################ - my $dbh = Bugzilla->dbh; - return $invocant->_create($dbh->sql_istrcmp('login_name', '?'), $login); +sub _check_disable_mail { return $_[1] ? 1 : 0; } +sub _check_disabledtext { return trim($_[1]) || ''; } + +# This is public since createaccount.cgi needs to use it before issuing +# a token for account creation. +sub check_login_name_for_creation { + my ($invocant, $name) = @_; + $name = trim($name); + $name || ThrowUserError('user_login_required'); + validate_email_syntax($name) + || ThrowUserError('illegal_email_address', { addr => $name }); + + # Check the name if it's a new user, or if we're changing the name. + if (!ref($invocant) || $invocant->login ne $name) { + is_available_username($name) + || ThrowUserError('account_exists', { email => $name }); + } + + return $name; } -# Internal helper for the above |new| methods -# $cond is a string (including a placeholder ?) for the search -# requirement for the profiles table -sub _create { - my $invocant = shift; - my $class = ref($invocant) || $invocant; +sub _check_password { + my ($self, $pass) = @_; + + # If the password is '*', do not encrypt it or validate it further--we + # are creating a user who should not be able to log in using DB + # authentication. + return $pass if $pass eq '*'; - my $cond = shift; - my $val = shift; + validate_password($pass); + my $cryptpassword = bz_crypt($pass); + return $cryptpassword; +} - # Allow invocation with no parameters to create a blank object - my $self = { - 'id' => 0, - 'name' => '', - 'login' => '', - 'showmybugslink' => 0, - 'disabledtext' => '', - 'flags' => {}, - }; - bless ($self, $class); - return $self unless $cond && $val; +sub _check_realname { return trim($_[1]) || ''; } - # We're checking for validity here, so any value is OK - trick_taint($val); +################################################################################ +# Mutators +################################################################################ - my $dbh = Bugzilla->dbh; +sub set_disabledtext { $_[0]->set('disabledtext', $_[1]); } +sub set_disable_mail { $_[0]->set('disable_mail', $_[1]); } - my ($id, - $login, - $name, - $disabledtext, - $mybugslink) = $dbh->selectrow_array(qq{SELECT userid, - login_name, - realname, - disabledtext, - mybugslink - FROM profiles - WHERE $cond}, - undef, - $val); - - return undef unless defined $id; - - $self->{'id'} = $id; - $self->{'name'} = $name; - $self->{'login'} = $login; - $self->{'disabledtext'} = $disabledtext; - $self->{'showmybugslink'} = $mybugslink; - - return $self; +sub set_login { + my ($self, $login) = @_; + $self->set('login_name', $login); + delete $self->{identity}; + delete $self->{nick}; } +sub set_name { + my ($self, $name) = @_; + $self->set('realname', $name); + delete $self->{identity}; +} + +sub set_password { $_[0]->set('cryptpassword', $_[1]); } + + +################################################################################ +# Methods +################################################################################ + # Accessors for user attributes -sub id { $_[0]->{id}; } -sub login { $_[0]->{login}; } -sub email { $_[0]->{login} . Param('emailsuffix'); } -sub name { $_[0]->{name}; } +sub name { $_[0]->{realname}; } +sub login { $_[0]->{login_name}; } +sub email { $_[0]->login . Bugzilla->params->{'emailsuffix'}; } sub disabledtext { $_[0]->{'disabledtext'}; } sub is_disabled { $_[0]->disabledtext ? 1 : 0; } sub showmybugslink { $_[0]->{showmybugslink}; } +sub email_disabled { $_[0]->{disable_mail}; } +sub email_enabled { !($_[0]->{disable_mail}); } -sub set_flags { - my $self = shift; - while (my $key = shift) { - $self->{'flags'}->{$key} = shift; - } +sub set_authorizer { + my ($self, $authorizer) = @_; + $self->{authorizer} = $authorizer; } - -sub get_flag { - my $self = shift; - my $key = shift; - return $self->{'flags'}->{$key}; +sub authorizer { + my ($self) = @_; + if (!$self->{authorizer}) { + require Bugzilla::Auth; + $self->{authorizer} = new Bugzilla::Auth(); + } + return $self->{authorizer}; } # Generate a string to identify the user by name + login if the user @@ -185,7 +253,7 @@ sub identity { if (!defined $self->{identity}) { $self->{identity} = - $self->{name} ? "$self->{name} <$self->{login}>" : $self->{login}; + $self->name ? $self->name . " <" . $self->login. ">" : $self->login; } return $self->{identity}; @@ -197,7 +265,7 @@ sub nick { return "" unless $self->id; if (!defined $self->{nick}) { - $self->{nick} = (split(/@/, $self->{login}, 2))[0]; + $self->{nick} = (split(/@/, $self->login, 2))[0]; } return $self->{nick}; @@ -205,37 +273,63 @@ sub nick { sub queries { my $self = shift; - return $self->{queries} if defined $self->{queries}; return [] unless $self->id; my $dbh = Bugzilla->dbh; - my $used_in_whine_ref = $dbh->selectcol_arrayref(q{ - SELECT DISTINCT query_name - FROM whine_events we - INNER JOIN whine_queries wq - ON we.id = wq.eventid - WHERE we.owner_userid = ?}, undef, $self->{id}); - - my $queries_ref = $dbh->selectall_arrayref(q{ - SELECT name, query, linkinfooter, query_type - FROM namedqueries - WHERE userid = ? - ORDER BY UPPER(name)},{'Slice'=>{}}, $self->{id}); - - foreach my $name (@$used_in_whine_ref) { - foreach my $queries_hash (@$queries_ref) { - if ($queries_hash->{name} eq $name) { - $queries_hash->{usedinwhine} = 1; - last; - } - } - } - $self->{queries} = $queries_ref; - + my $query_ids = $dbh->selectcol_arrayref( + 'SELECT id FROM namedqueries WHERE userid = ?', undef, $self->id); + require Bugzilla::Search::Saved; + $self->{queries} = Bugzilla::Search::Saved->new_from_list($query_ids); return $self->{queries}; } +sub queries_subscribed { + my $self = shift; + return $self->{queries_subscribed} if defined $self->{queries_subscribed}; + return [] unless $self->id; + + # Exclude the user's own queries. + my @my_query_ids = map($_->id, @{$self->queries}); + my $query_id_string = join(',', @my_query_ids) || '-1'; + + # Only show subscriptions that we can still actually see. If a + # user changes the shared group of a query, our subscription + # will remain but we won't have access to the query anymore. + my $subscribed_query_ids = Bugzilla->dbh->selectcol_arrayref( + "SELECT lif.namedquery_id + FROM namedqueries_link_in_footer lif + INNER JOIN namedquery_group_map ngm + ON ngm.namedquery_id = lif.namedquery_id + WHERE lif.user_id = ? + AND lif.namedquery_id NOT IN ($query_id_string) + AND ngm.group_id IN (" . $self->groups_as_string . ")", + undef, $self->id); + require Bugzilla::Search::Saved; + $self->{queries_subscribed} = + Bugzilla::Search::Saved->new_from_list($subscribed_query_ids); + return $self->{queries_subscribed}; +} + +sub queries_available { + my $self = shift; + return $self->{queries_available} if defined $self->{queries_available}; + return [] unless $self->id; + + # Exclude the user's own queries. + my @my_query_ids = map($_->id, @{$self->queries}); + my $query_id_string = join(',', @my_query_ids) || '-1'; + + my $avail_query_ids = Bugzilla->dbh->selectcol_arrayref( + 'SELECT namedquery_id FROM namedquery_group_map + WHERE group_id IN (' . $self->groups_as_string . ") + AND namedquery_id NOT IN ($query_id_string)"); + require Bugzilla::Search::Saved; + $self->{queries_available} = + Bugzilla::Search::Saved->new_from_list($avail_query_ids); + return $self->{queries_available}; +} + sub settings { my ($self) = @_; @@ -257,6 +351,8 @@ sub flush_queries_cache { my $self = shift; delete $self->{queries}; + delete $self->{queries_subscribed}; + delete $self->{queries_available}; } sub groups { @@ -277,24 +373,51 @@ sub groups { # The above gives us an arrayref [name, id, name, id, ...] # Convert that into a hashref my %groups = @$groups; - my $sth; my @groupidstocheck = values(%groups); my %groupidschecked = (); - $sth = $dbh->prepare("SELECT groups.name, groups.id + my $rows = $dbh->selectall_arrayref( + "SELECT DISTINCT groups.name, groups.id, member_id FROM group_group_map INNER JOIN groups ON groups.id = grantor_id - WHERE member_id = ? - AND grant_type = " . GROUP_MEMBERSHIP); - while (my $node = shift @groupidstocheck) { - $sth->execute($node); - my ($member_name, $member_id); - while (($member_name, $member_id) = $sth->fetchrow_array) { - if (!$groupidschecked{$member_id}) { - $groupidschecked{$member_id} = 1; - push @groupidstocheck, $member_id; - $groups{$member_name} = $member_id; + WHERE grant_type = " . GROUP_MEMBERSHIP); + my %group_names = (); + my %group_membership = (); + foreach my $row (@$rows) { + my ($member_name, $grantor_id, $member_id) = @$row; + # Just save the group names + $group_names{$grantor_id} = $member_name; + + # And group membership + push (@{$group_membership{$member_id}}, $grantor_id); + } + + # Let's walk the groups hierarchy tree (using FIFO) + # On the first iteration it's pre-filled with direct groups + # membership. Later on, each group can add its own members into the + # FIFO. Circular dependencies are eliminated by checking + # $groupidschecked{$member_id} hash values. + # As a result, %groups will have all the groups we are the member of. + while ($#groupidstocheck >= 0) { + # Pop the head group from FIFO + my $member_id = shift @groupidstocheck; + + # Skip the group if we have already checked it + if (!$groupidschecked{$member_id}) { + # Mark group as checked + $groupidschecked{$member_id} = 1; + + # Add all its members to the FIFO check list + # %group_membership contains arrays of group members + # for all groups. Accessible by group number. + foreach my $newgroupid (@{$group_membership{$member_id}}) { + push @groupidstocheck, $newgroupid + if (!$groupidschecked{$newgroupid}); } + # Note on if clause: we could have group in %groups from 1st + # query and do not have it in second one + $groups{$group_names{$member_id}} = $member_id + if $group_names{$member_id} && $member_id; } } $self->{groups} = \%groups; @@ -343,7 +466,9 @@ sub bless_groups { } # If visibilitygroups are used, restrict the set of groups. - if ((!$self->in_group('editusers')) && Param('usevisibilitygroups')) { + if (!$self->in_group('editusers') + && Bugzilla->params->{'usevisibilitygroups'}) + { # Users need to see a group in order to bless it. my $visibleGroups = join(', ', @{$self->visible_groups_direct()}) || return $self->{'bless_groups'} = []; @@ -357,8 +482,32 @@ sub bless_groups { } sub in_group { - my ($self, $group) = @_; - return exists $self->groups->{$group} ? 1 : 0; + my ($self, $group, $product_id) = @_; + if (exists $self->groups->{$group}) { + return 1; + } + elsif ($product_id && detaint_natural($product_id)) { + # Make sure $group exists on a per-product basis. + return 0 unless (grep {$_ eq $group} PER_PRODUCT_PRIVILEGES); + + $self->{"product_$product_id"} = {} unless exists $self->{"product_$product_id"}; + if (!defined $self->{"product_$product_id"}->{$group}) { + my $dbh = Bugzilla->dbh; + my $in_group = $dbh->selectrow_array( + "SELECT 1 + FROM group_control_map + WHERE product_id = ? + AND $group != 0 + AND group_id IN (" . $self->groups_as_string . ") " . + $dbh->sql_limit(1), + undef, $product_id); + + $self->{"product_$product_id"}->{$group} = $in_group ? 1 : 0; + } + return $self->{"product_$product_id"}->{$group}; + } + # If we come here, then the user is not in the requested group. + return 0; } sub in_group_id { @@ -367,11 +516,31 @@ sub in_group_id { return exists $j{$id} ? 1 : 0; } +sub get_products_by_permission { + my ($self, $group) = @_; + # Make sure $group exists on a per-product basis. + return [] unless (grep {$_ eq $group} PER_PRODUCT_PRIVILEGES); + + my $product_ids = Bugzilla->dbh->selectcol_arrayref( + "SELECT DISTINCT product_id + FROM group_control_map + WHERE $group != 0 + AND group_id IN(" . $self->groups_as_string . ")"); + + # No need to go further if the user has no "special" privs. + return [] unless scalar(@$product_ids); + + # We will restrict the list to products the user can see. + my $selectable_products = $self->get_selectable_products; + my @products = grep {lsearch($product_ids, $_->id) > -1} @$selectable_products; + return \@products; +} + sub can_see_user { my ($self, $otherUser) = @_; my $query; - if (Param('usevisibilitygroups')) { + if (Bugzilla->params->{'usevisibilitygroups'}) { # If the user can see no groups, then no users are visible either. my $visibleGroups = $self->visible_groups_as_string() || return 0; $query = qq{SELECT COUNT(DISTINCT userid) @@ -444,7 +613,8 @@ sub can_see_bug { $self->{sthCanSeeBug} = $sth; return ($ready && ((($reporter == $userid) && $reporter_access) - || (Param('useqacontact') && $qacontact && ($qacontact == $userid)) + || (Bugzilla->params->{'useqacontact'} + && $qacontact && ($qacontact == $userid)) || ($owner == $userid) || ($isoncclist && $cclist_access) || (!$missinggroup))); @@ -458,43 +628,32 @@ sub can_see_product { sub get_selectable_products { my $self = shift; - my $classification_id = shift; + my $class_id = shift; + my $class_restricted = Bugzilla->params->{'useclassification'} && $class_id; + + if (!defined $self->{selectable_products}) { + my $query = "SELECT id " . + " FROM products " . + "LEFT JOIN group_control_map " . + " ON group_control_map.product_id = products.id "; + if (Bugzilla->params->{'useentrygroupdefault'}) { + $query .= " AND group_control_map.entry != 0 "; + } else { + $query .= " AND group_control_map.membercontrol = " . CONTROLMAPMANDATORY; + } + $query .= " AND group_id NOT IN(" . $self->groups_as_string . ") " . + " WHERE group_id IS NULL " . + "ORDER BY name"; - if (defined $self->{selectable_products}) { - return $self->{selectable_products}; + my $prod_ids = Bugzilla->dbh->selectcol_arrayref($query); + $self->{selectable_products} = Bugzilla::Product->new_from_list($prod_ids); } - my $dbh = Bugzilla->dbh; - my @params = (); - - my $query = "SELECT id " . - "FROM products " . - "LEFT JOIN group_control_map " . - "ON group_control_map.product_id = products.id "; - if (Param('useentrygroupdefault')) { - $query .= "AND group_control_map.entry != 0 "; - } else { - $query .= "AND group_control_map.membercontrol = " . - CONTROLMAPMANDATORY . " "; - } - $query .= "AND group_id NOT IN(" . - $self->groups_as_string . ") " . - "WHERE group_id IS NULL "; - - if (Param('useclassification') && $classification_id) { - $query .= "AND classification_id = ? "; - detaint_natural($classification_id); - push(@params, $classification_id); + # Restrict the list of products to those being in the classification, if any. + if ($class_restricted) { + return [grep {$_->classification_id == $class_id} @{$self->{selectable_products}}]; } - - $query .= "ORDER BY name"; - - my $prod_ids = $dbh->selectcol_arrayref($query, undef, @params); - my @products; - foreach my $prod_id (@$prod_ids) { - push(@products, new Bugzilla::Product($prod_id)); - } - $self->{selectable_products} = \@products; + # If we come here, then we want all selectable products. return $self->{selectable_products}; } @@ -512,7 +671,8 @@ sub get_selectable_classifications { $class->{$product->classification_id} ||= new Bugzilla::Classification($product->classification_id); } - my @sorted_class = sort {lc($a->name) cmp lc($b->name)} (values %$class); + my @sorted_class = sort {$a->sortkey <=> $b->sortkey + || lc($a->name) cmp lc($b->name)} (values %$class); $self->{selectable_classifications} = \@sorted_class; return $self->{selectable_classifications}; } @@ -522,79 +682,116 @@ sub can_enter_product { my $dbh = Bugzilla->dbh; if (!defined($product_name)) { - return unless $warn; + return unless $warn == THROW_ERROR; ThrowUserError('no_products'); } trick_taint($product_name); + my $can_enter = + grep($_->name eq $product_name, @{$self->get_enterable_products}); - # Checks whether the user has access to the product. - my $has_access = $dbh->selectrow_array('SELECT CASE WHEN group_id IS NULL - THEN 1 ELSE 0 END - FROM products - LEFT JOIN group_control_map - ON group_control_map.product_id = products.id - AND group_control_map.entry != 0 - AND group_id NOT IN (' . $self->groups_as_string . ') - WHERE products.name = ? ' . - $dbh->sql_limit(1), - undef, $product_name); - - if (!$has_access) { - return unless $warn; - ThrowUserError('entry_access_denied', { product => $product_name }); - } + return 1 if $can_enter; + + return 0 unless $warn == THROW_ERROR; + + # Check why access was denied. These checks are slow, + # but that's fine, because they only happen if we fail. - # Checks whether the product is open for new bugs and - # has at least one component and one version. - my ($is_open, $has_version) = - $dbh->selectrow_array('SELECT CASE WHEN disallownew = 0 - THEN 1 ELSE 0 END, - CASE WHEN versions.value IS NOT NULL - THEN 1 ELSE 0 END - FROM products - INNER JOIN components - ON components.product_id = products.id - LEFT JOIN versions - ON versions.product_id = products.id - WHERE products.name = ? ' . - $dbh->sql_limit(1), undef, $product_name); - - # Returns undef if the product has no components - # Returns 0 if the product has no versions, or is closed for bug entry - # Returns 1 if the user can enter bugs into the product - return ($is_open && $has_version) unless $warn; - - # (undef, undef): the product has no components, - # (0, ?) : the product is closed for new bug entry, - # (?, 0) : the product has no versions, - # (1, 1) : the user can enter bugs into the product, - if (!defined $is_open) { - ThrowUserError('missing_component', { product => $product_name }); - } elsif (!$is_open) { - ThrowUserError('product_disabled', { product => $product_name }); - } elsif (!$has_version) { - ThrowUserError('missing_version', { product => $product_name }); + my $product = new Bugzilla::Product({name => $product_name}); + + # The product could not exist or you could be denied... + if (!$product || !$product->user_has_access($self)) { + ThrowUserError('entry_access_denied', {product => $product_name}); } - return 1; + # It could be closed for bug entry... + elsif ($product->disallow_new) { + ThrowUserError('product_disabled', {product => $product}); + } + # It could have no components... + elsif (!@{$product->components}) { + ThrowUserError('missing_component', {product => $product}); + } + # It could have no versions... + elsif (!@{$product->versions}) { + ThrowUserError ('missing_version', {product => $product}); + } + + die "can_enter_product reached an unreachable location."; } sub get_enterable_products { my $self = shift; + my $dbh = Bugzilla->dbh; if (defined $self->{enterable_products}) { return $self->{enterable_products}; } - my @products; - foreach my $product (Bugzilla::Product::get_all_products()) { - if ($self->can_enter_product($product->name)) { - push(@products, $product); - } + # All products which the user has "Entry" access to. + my @enterable_ids =@{$dbh->selectcol_arrayref( + 'SELECT products.id FROM products + LEFT JOIN group_control_map + ON group_control_map.product_id = products.id + AND group_control_map.entry != 0 + AND group_id NOT IN (' . $self->groups_as_string . ') + WHERE group_id IS NULL + AND products.disallownew = 0') || []}; + + if (@enterable_ids) { + # And all of these products must have at least one component + # and one version. + @enterable_ids = @{$dbh->selectcol_arrayref( + 'SELECT DISTINCT products.id FROM products + INNER JOIN components ON components.product_id = products.id + INNER JOIN versions ON versions.product_id = products.id + WHERE products.id IN (' . (join(',', @enterable_ids)) . + ')') || []}; } - $self->{enterable_products} = \@products; + + $self->{enterable_products} = + Bugzilla::Product->new_from_list(\@enterable_ids); return $self->{enterable_products}; } +sub get_accessible_products { + my $self = shift; + + # Map the objects into a hash using the ids as keys + my %products = map { $_->id => $_ } + @{$self->get_selectable_products}, + @{$self->get_enterable_products}; + + return [ values %products ]; +} + +sub check_can_admin_product { + my ($self, $product_name) = @_; + + # First make sure the product name is valid. + my $product = Bugzilla::Product::check_product($product_name); + + ($self->in_group('editcomponents', $product->id) + && $self->can_see_product($product->name)) + || ThrowUserError('product_access_denied', {product => $product->name}); + + # Return the validated product object. + return $product; +} + +sub can_request_flag { + my ($self, $flag_type) = @_; + + return ($self->can_set_flag($flag_type) + || !$flag_type->request_group + || $self->in_group_id($flag_type->request_group->id)) ? 1 : 0; +} + +sub can_set_flag { + my ($self, $flag_type) = @_; + + return (!$flag_type->grant_group + || $self->in_group_id($flag_type->grant_group->id)) ? 1 : 0; +} + # visible_groups_inherited returns a reference to a list of all the groups # whose members are visible to this user. sub visible_groups_inherited { @@ -616,11 +813,19 @@ sub visible_groups_direct { return [] unless $self->id; my $dbh = Bugzilla->dbh; - my $glist = join(',',(-1,values(%{$self->groups}))); - my $sth = $dbh->prepare("SELECT DISTINCT grantor_id - FROM group_group_map - WHERE member_id IN($glist) - AND grant_type=" . GROUP_VISIBLE); + my $sth; + + if (Bugzilla->params->{'usevisibilitygroups'}) { + my $glist = join(',',(-1,values(%{$self->groups}))); + $sth = $dbh->prepare("SELECT DISTINCT grantor_id + FROM group_group_map + WHERE member_id IN($glist) + AND grant_type=" . GROUP_VISIBLE); + } + else { + # All groups are visible if usevisibilitygroups is off. + $sth = $dbh->prepare('SELECT id FROM groups'); + } $sth->execute(); while (my ($row) = $sth->fetchrow_array) { @@ -636,6 +841,38 @@ sub visible_groups_as_string { return join(', ', @{$self->visible_groups_inherited()}); } +# This function defines the groups a user may share a query with. +# More restrictive sites may want to build this reference to a list of group IDs +# from bless_groups instead of mirroring visible_groups_inherited, perhaps. +sub queryshare_groups { + my $self = shift; + my @queryshare_groups; + + return $self->{queryshare_groups} if defined $self->{queryshare_groups}; + + if ($self->in_group(Bugzilla->params->{'querysharegroup'})) { + # We want to be allowed to share with groups we're in only. + # If usevisibilitygroups is on, then we need to restrict this to groups + # we may see. + if (Bugzilla->params->{'usevisibilitygroups'}) { + foreach(@{$self->visible_groups_inherited()}) { + next unless $self->in_group_id($_); + push(@queryshare_groups, $_); + } + } + else { + @queryshare_groups = values(%{$self->groups}); + } + } + + return $self->{queryshare_groups} = \@queryshare_groups; +} + +sub queryshare_groups_as_string { + my $self = shift; + return join(', ', @{$self->queryshare_groups()}); +} + sub derive_regexp_groups { my ($self) = @_; @@ -646,9 +883,6 @@ sub derive_regexp_groups { my $sth; - # avoid races, we are only up to date as of the BEGINNING of this process - my $time = $dbh->selectrow_array("SELECT NOW()"); - # add derived records for any matching regexps $sth = $dbh->prepare("SELECT id, userregexp, user_group_map.group_id @@ -668,40 +902,30 @@ sub derive_regexp_groups { AND isbless = 0 AND grant_type = ?}); while (my ($group, $regexp, $present) = $sth->fetchrow_array()) { - if (($regexp ne '') && ($self->{login} =~ m/$regexp/i)) { + if (($regexp ne '') && ($self->login =~ m/$regexp/i)) { $group_insert->execute($id, $group, GRANT_REGEXP) unless $present; } else { $group_delete->execute($id, $group, GRANT_REGEXP) if $present; } } - - $dbh->do(q{UPDATE profiles - SET refreshed_when = ? - WHERE userid=?}, - undef, - $time, - $id); } sub product_responsibilities { my $self = shift; + my $dbh = Bugzilla->dbh; return $self->{'product_resp'} if defined $self->{'product_resp'}; return [] unless $self->id; - my $h = Bugzilla->dbh->selectall_arrayref( - qq{SELECT products.name AS productname, - components.name AS componentname, - initialowner, - initialqacontact - FROM products, components - WHERE products.id = components.product_id - AND ? IN (initialowner, initialqacontact) - }, - {'Slice' => {}}, $self->id); - $self->{'product_resp'} = $h; - - return $h; + my $comp_ids = $dbh->selectcol_arrayref('SELECT id FROM components + WHERE initialowner = ? + OR initialqacontact = ?', + undef, ($self->id, $self->id)); + + # We cannot |use| it, because Component.pm already |use|s User.pm. + require Bugzilla::Component; + $self->{'product_resp'} = Bugzilla::Component->new_from_list($comp_ids); + return $self->{'product_resp'}; } sub can_bless { @@ -714,8 +938,8 @@ sub can_bless { } # Otherwise, we're checking a specific group - my $group_name = shift; - return (grep {$$_{'name'} eq $group_name} (@{$self->bless_groups})) ? 1 : 0; + my $group_id = shift; + return (grep {$$_{'id'} eq $group_id} (@{$self->bless_groups})) ? 1 : 0; } sub flatten_group_membership { @@ -751,9 +975,10 @@ sub match { # $str contains the string to match, while $limit contains the # maximum number of records to retrieve. my ($str, $limit, $exclude_disabled) = @_; - - my @users = (); + my $user = Bugzilla->user; + my $dbh = Bugzilla->dbh; + my @users = (); return \@users if $str =~ /^\s*$/; # The search order is wildcards, then exact match, then substring search. @@ -762,97 +987,79 @@ sub match { # ones following it will not execute. # first try wildcards - my $wildstr = $str; - my $user = Bugzilla->user; - my $dbh = Bugzilla->dbh; - if ($wildstr =~ s/\*/\%/g && # don't do wildcards if no '*' in the string - Param('usermatchmode') ne 'off') { # or if we only want exact matches + if ($wildstr =~ s/\*/\%/g # don't do wildcards if no '*' in the string + # or if we only want exact matches + && Bugzilla->params->{'usermatchmode'} ne 'off') + { # Build the query. - my $sqlstr = &::SqlQuote($wildstr); - my $query = "SELECT DISTINCT userid, realname, login_name, " . - "LENGTH(login_name) AS namelength " . - "FROM profiles "; - if (&::Param('usevisibilitygroups')) { - $query .= ", user_group_map "; + trick_taint($wildstr); + my $query = "SELECT DISTINCT login_name FROM profiles "; + if (Bugzilla->params->{'usevisibilitygroups'}) { + $query .= "INNER JOIN user_group_map + ON user_group_map.user_id = profiles.userid "; } - $query .= "WHERE (" - . $dbh->sql_istrcmp('login_name', $sqlstr, "LIKE") . " OR " . - $dbh->sql_istrcmp('realname', $sqlstr, "LIKE") . ") "; - if (&::Param('usevisibilitygroups')) { - $query .= "AND user_group_map.user_id = userid " . - "AND isbless = 0 " . + $query .= "WHERE (" + . $dbh->sql_istrcmp('login_name', '?', "LIKE") . " OR " . + $dbh->sql_istrcmp('realname', '?', "LIKE") . ") "; + if (Bugzilla->params->{'usevisibilitygroups'}) { + $query .= "AND isbless = 0 " . "AND group_id IN(" . - join(', ', (-1, @{$user->visible_groups_inherited})) . - ")"; + join(', ', (-1, @{$user->visible_groups_inherited})) . ") "; } $query .= " AND disabledtext = '' " if $exclude_disabled; - $query .= "ORDER BY namelength "; + $query .= " ORDER BY login_name "; $query .= $dbh->sql_limit($limit) if $limit; # Execute the query, retrieve the results, and make them into # User objects. - - &::PushGlobalSQLState(); - &::SendSQL($query); - push(@users, new Bugzilla::User(&::FetchSQLData())) while &::MoreSQLData(); - &::PopGlobalSQLState(); - + my $user_logins = $dbh->selectcol_arrayref($query, undef, ($wildstr, $wildstr)); + foreach my $login_name (@$user_logins) { + push(@users, new Bugzilla::User({ name => $login_name })); + } } else { # try an exact match - - my $sqlstr = &::SqlQuote($str); - my $query = "SELECT userid, realname, login_name " . - "FROM profiles " . - "WHERE " . $dbh->sql_istrcmp('login_name', $sqlstr); # Exact matches don't care if a user is disabled. + trick_taint($str); + my $user_id = $dbh->selectrow_array('SELECT userid FROM profiles + WHERE ' . $dbh->sql_istrcmp('login_name', '?'), + undef, $str); - &::PushGlobalSQLState(); - &::SendSQL($query); - push(@users, new Bugzilla::User(&::FetchSQLData())) if &::MoreSQLData(); - &::PopGlobalSQLState(); + push(@users, new Bugzilla::User($user_id)) if $user_id; } # then try substring search - if ((scalar(@users) == 0) - && (&::Param('usermatchmode') eq 'search') + && (Bugzilla->params->{'usermatchmode'} eq 'search') && (length($str) >= 3)) { + $str = lc($str); + trick_taint($str); - my $sqlstr = &::SqlQuote(lc($str)); - - my $query = "SELECT DISTINCT userid, realname, login_name, " . - "LENGTH(login_name) AS namelength " . - "FROM profiles"; - if (&::Param('usevisibilitygroups')) { - $query .= ", user_group_map"; + my $query = "SELECT DISTINCT login_name FROM profiles "; + if (Bugzilla->params->{'usevisibilitygroups'}) { + $query .= "INNER JOIN user_group_map + ON user_group_map.user_id = profiles.userid "; } $query .= " WHERE (" . - $dbh->sql_position($sqlstr, 'LOWER(login_name)') . " > 0" . - " OR " . - $dbh->sql_position($sqlstr, 'LOWER(realname)') . " > 0)"; - if (&::Param('usevisibilitygroups')) { - $query .= " AND user_group_map.user_id = userid" . - " AND isbless = 0" . + $dbh->sql_position('?', 'LOWER(login_name)') . " > 0" . " OR " . + $dbh->sql_position('?', 'LOWER(realname)') . " > 0) "; + if (Bugzilla->params->{'usevisibilitygroups'}) { + $query .= " AND isbless = 0" . " AND group_id IN(" . - join(', ', (-1, @{$user->visible_groups_inherited})) . ")"; + join(', ', (-1, @{$user->visible_groups_inherited})) . ") "; } - $query .= " AND disabledtext = ''" if $exclude_disabled; - $query .= " ORDER BY namelength"; - $query .= " " . $dbh->sql_limit($limit) if $limit; - &::PushGlobalSQLState(); - &::SendSQL($query); - push(@users, new Bugzilla::User(&::FetchSQLData())) while &::MoreSQLData(); - &::PopGlobalSQLState(); - } - - # order @users by alpha - - @users = sort { uc($a->login) cmp uc($b->login) } @users; + $query .= " AND disabledtext = '' " if $exclude_disabled; + $query .= " ORDER BY login_name "; + $query .= $dbh->sql_limit($limit) if $limit; + my $user_logins = $dbh->selectcol_arrayref($query, undef, ($str, $str)); + foreach my $login_name (@$user_logins) { + push(@users, new Bugzilla::User({ name => $login_name })); + } + } return \@users; } @@ -908,6 +1115,8 @@ sub match_field { my $need_confirm = 0; # whether to display confirmation screen my $match_multiple = 0; # whether we ever matched more than one user + my $params = Bugzilla->params; + # prepare default form values # What does a "--do_not_change--" field look like (if any)? @@ -934,13 +1143,15 @@ sub match_field { # to show up correctly on the confirmation page, we need # to find out the name of its flag type. if ($field_name =~ /^requestee-(\d+)$/) { - my $flag = Bugzilla::Flag::get($1); + require Bugzilla::Flag; + my $flag = new Bugzilla::Flag($1); $expanded_fields->{$field_name}->{'flag_type'} = - $flag->{'type'}; + $flag->type; } elsif ($field_name =~ /^requestee_type-(\d+)$/) { + require Bugzilla::FlagType; $expanded_fields->{$field_name}->{'flag_type'} = - Bugzilla::FlagType::get($1); + new Bugzilla::FlagType($1); } } } @@ -1008,8 +1219,8 @@ sub match_field { } my $limit = 0; - if (&::Param('maxusermatches')) { - $limit = &::Param('maxusermatches') + 1; + if ($params->{'maxusermatches'}) { + $limit = $params->{'maxusermatches'} + 1; } for my $query (@queries) { @@ -1022,10 +1233,11 @@ sub match_field { # skip confirmation for exact matches if ((scalar(@{$users}) == 1) - && (@{$users}[0]->{'login'} eq $query)) + && (lc(@{$users}[0]->login) eq lc($query))) + { $cgi->append(-name=>$field, - -values=>[@{$users}[0]->{'login'}]); + -values=>[@{$users}[0]->login]); next; } @@ -1038,18 +1250,18 @@ sub match_field { if (scalar(@{$users}) == 1) { # exactly one match $cgi->append(-name=>$field, - -values=>[@{$users}[0]->{'login'}]); + -values=>[@{$users}[0]->login]); - $need_confirm = 1 if &::Param('confirmuniqueusermatch'); + $need_confirm = 1 if $params->{'confirmuniqueusermatch'}; } elsif ((scalar(@{$users}) > 1) - && (&::Param('maxusermatches') != 1)) { + && ($params->{'maxusermatches'} != 1)) { $need_confirm = 1; $match_multiple = 1; - if ((&::Param('maxusermatches')) - && (scalar(@{$users}) > &::Param('maxusermatches'))) + if (($params->{'maxusermatches'}) + && (scalar(@{$users}) > $params->{'maxusermatches'})) { $matches->{$field}->{$query}->{'status'} = 'trunc'; pop @{$users}; # take the last one out @@ -1119,37 +1331,28 @@ our %names_to_events = ( 'Attachment description' => EVT_ATTACHMENT_DATA, 'Attachment mime type' => EVT_ATTACHMENT_DATA, 'Attachment is patch' => EVT_ATTACHMENT_DATA, - 'BugsThisDependsOn' => EVT_DEPEND_BLOCK, - 'OtherBugsDependingOnThis' => EVT_DEPEND_BLOCK); + 'Depends on' => EVT_DEPEND_BLOCK, + 'Blocks' => EVT_DEPEND_BLOCK); # Returns true if the user wants mail for a given bug change. # Note: the "+" signs before the constants suppress bareword quoting. sub wants_bug_mail { my $self = shift; - my ($bug_id, $relationship, $fieldDiffs, $commentField, $changer, $bug_is_new) = @_; + my ($bug_id, $relationship, $fieldDiffs, $commentField, $dependencyText, + $changer, $bug_is_new) = @_; - # Don't send any mail, ever, if account is disabled - # XXX Temporary Compatibility Change 1 of 2: - # This code is disabled for the moment to make the behaviour like the old - # system, which sent bugmail to disabled accounts. - # return 0 if $self->{'disabledtext'}; - # Make a list of the events which have happened during this bug change, # from the point of view of this user. my %events; foreach my $ref (@$fieldDiffs) { - my ($who, $fieldName, $when, $old, $new) = @$ref; + my ($who, $whoname, $fieldName, $when, $old, $new) = @$ref; # A change to any of the above fields sets the corresponding event if (defined($names_to_events{$fieldName})) { $events{$names_to_events{$fieldName}} = 1; } else { # Catch-all for any change not caught by a more specific event - # XXX: Temporary Compatibility Change 2 of 2: - # This code is disabled, and replaced with the code a few lines - # below, in order to make the behaviour more like the original, - # which only added this event if _all_ changes were of "other" type. - # $events{+EVT_OTHER} = 1; + $events{+EVT_OTHER} = 1; } # If the user is in a particular role and the value of that role @@ -1188,13 +1391,13 @@ sub wants_bug_mail { $events{+EVT_COMMENT} = 1; } - my @event_list = keys %events; - - # XXX Temporary Compatibility Change 2 of 2: - # See above comment. - if (!scalar(@event_list)) { - @event_list = (EVT_OTHER); + # Dependent changed bugmails must have an event to ensure the bugmail is + # emailed. + if ($dependencyText ne '') { + $events{+EVT_DEPEND_BLOCK} = 1; } + + my @event_list = keys %events; my $wants_mail = $self->wants_mail(\@event_list, $relationship); @@ -1203,7 +1406,7 @@ sub wants_bug_mail { # # We do them separately because if _any_ of them are set, we don't want # the mail. - if ($wants_mail && $changer && ($self->{'login'} eq $changer)) { + if ($wants_mail && $changer && ($self->login eq $changer)) { $wants_mail &= $self->wants_mail([EVT_CHANGED_BY_ME], $relationship); } @@ -1213,10 +1416,10 @@ sub wants_bug_mail { # need one piece of information, and doing so (as of 2004-11-23) slows # down bugmail sending by a factor of 2. If Bug creation was more # lazy, this might not be so bad. - my $bug_status = $dbh->selectrow_array("SELECT bug_status - FROM bugs - WHERE bug_id = $bug_id"); - + my $bug_status = $dbh->selectrow_array('SELECT bug_status + FROM bugs WHERE bug_id = ?', + undef, $bug_id); + if ($bug_status eq "UNCONFIRMED") { $wants_mail &= $self->wants_mail([EVT_UNCONFIRMED], $relationship); } @@ -1238,22 +1441,26 @@ sub wants_mail { # No mail if there are no events return 0 if !scalar(@$events); - - my $dbh = Bugzilla->dbh; - + # If a relationship isn't given, default to REL_ANY. if (!defined($relationship)) { $relationship = REL_ANY; } - + + # Skip DB query if relationship is explicit + return 1 if $relationship == REL_GLOBAL_WATCHER; + + my $dbh = Bugzilla->dbh; + my $wants_mail = - $dbh->selectrow_array("SELECT 1 - FROM email_setting - WHERE user_id = $self->{'id'} - AND relationship = $relationship - AND event IN (" . join(",", @$events) . ") - LIMIT 1"); - + $dbh->selectrow_array('SELECT 1 + FROM email_setting + WHERE user_id = ? + AND relationship = ? + AND event IN (' . join(',', @$events) . ') ' . + $dbh->sql_limit(1), + undef, ($self->{'id'}, $relationship)); + return defined($wants_mail) ? 1 : 0; } @@ -1261,7 +1468,7 @@ sub is_mover { my $self = shift; if (!defined $self->{'is_mover'}) { - my @movers = map { trim($_) } split(',', Param('movers')); + my @movers = map { trim($_) } split(',', Bugzilla->params->{'movers'}); $self->{'is_mover'} = ($self->id && lsearch(\@movers, $self->login) != -1); } @@ -1272,7 +1479,7 @@ sub is_insider { my $self = shift; if (!defined $self->{'is_insider'}) { - my $insider_group = Param('insidergroup'); + my $insider_group = Bugzilla->params->{'insidergroup'}; $self->{'is_insider'} = ($insider_group && $self->in_group($insider_group)) ? 1 : 0; } @@ -1286,13 +1493,13 @@ sub get_userlist { my $dbh = Bugzilla->dbh; my $query = "SELECT DISTINCT login_name, realname,"; - if (&::Param('usevisibilitygroups')) { + if (Bugzilla->params->{'usevisibilitygroups'}) { $query .= " COUNT(group_id) "; } else { $query .= " 1 "; } $query .= "FROM profiles "; - if (&::Param('usevisibilitygroups')) { + if (Bugzilla->params->{'usevisibilitygroups'}) { $query .= "LEFT JOIN user_group_map " . "ON user_group_map.user_id = userid AND isbless = 0 " . "AND group_id IN(" . @@ -1318,34 +1525,18 @@ sub get_userlist { return $self->{'userlist'}; } -sub insert_new_user { - my ($username, $realname, $password, $disabledtext) = (@_); +sub create { + my $invocant = shift; + my $class = ref($invocant) || $invocant; my $dbh = Bugzilla->dbh; - $disabledtext ||= ''; + $dbh->bz_lock_tables('profiles WRITE', 'profiles_activity WRITE', + 'user_group_map WRITE', 'email_setting WRITE', 'groups READ', + 'tokens READ', 'fielddefs READ'); - # If not specified, generate a new random password for the user. - # If the password is '*', do not encrypt it; we are creating a user - # based on the ENV auth method. - $password ||= generate_random_password(); - my $cryptpassword = ($password ne '*') ? bz_crypt($password) : $password; - - # XXX - These should be moved into is_available_username or validate_email_syntax - # At the least, they shouldn't be here. They're safe for now, though. - trick_taint($username); - trick_taint($realname); - - # Insert the new user record into the database. - $dbh->do("INSERT INTO profiles - (login_name, realname, cryptpassword, disabledtext, - refreshed_when) - VALUES (?, ?, ?, ?, '1901-01-01 00:00:00')", - undef, - ($username, $realname, $cryptpassword, $disabledtext)); + my $user = $class->SUPER::create(@_); # Turn on all email for the new user - my $userid = $dbh->bz_last_key('profiles', 'userid'); - foreach my $rel (RELATIONSHIPS) { foreach my $event (POS_EVENTS, NEG_EVENTS) { # These "exceptions" define the default email preferences. @@ -1355,25 +1546,33 @@ sub insert_new_user { next if ($event == EVT_CHANGED_BY_ME); next if (($event == EVT_CC) && ($rel != REL_REPORTER)); - $dbh->do("INSERT INTO email_setting " . - "(user_id, relationship, event) " . - "VALUES ($userid, $rel, $event)"); - } + $dbh->do('INSERT INTO email_setting (user_id, relationship, event) + VALUES (?, ?, ?)', undef, ($user->id, $rel, $event)); + } } foreach my $event (GLOBAL_EVENTS) { - $dbh->do("INSERT INTO email_setting " . - "(user_id, relationship, event) " . - "VALUES ($userid, " . REL_ANY . ", $event)"); + $dbh->do('INSERT INTO email_setting (user_id, relationship, event) + VALUES (?, ?, ?)', undef, ($user->id, REL_ANY, $event)); } - my $user = new Bugzilla::User($userid); $user->derive_regexp_groups(); - - # Return the password to the calling code so it can be included - # in an email sent to the user. - return $password; + # Add the creation date to the profiles_activity table. + # $who is the user who created the new user account, i.e. either an + # admin or the new user himself. + my $who = Bugzilla->user->id || $user->id; + my $creation_date_fieldid = get_field_id('creation_ts'); + + $dbh->do('INSERT INTO profiles_activity + (userid, who, profiles_when, fieldid, newvalue) + VALUES (?, ?, NOW(), ?, NOW())', + undef, ($user->id, $who, $creation_date_fieldid)); + + $dbh->bz_unlock_tables(); + + # Return the newly created user account. + return $user; } sub is_available_username { @@ -1393,15 +1592,18 @@ sub is_available_username { # was unsafe and required weird escaping; using substring to pull out # the new/old email addresses and sql_position() to find the delimiter (':') # is cleaner/safer - my $sth = $dbh->prepare( - "SELECT eventdata FROM tokens WHERE tokentype = 'emailold' - AND SUBSTRING(eventdata, 1, (" - . $dbh->sql_position(q{':'}, 'eventdata') . "- 1)) = ? - OR SUBSTRING(eventdata, (" - . $dbh->sql_position(q{':'}, 'eventdata') . "+ 1)) = ?"); - $sth->execute($username, $username); - - if (my ($eventdata) = $sth->fetchrow_array()) { + my $eventdata = $dbh->selectrow_array( + "SELECT eventdata + FROM tokens + WHERE (tokentype = 'emailold' + AND SUBSTRING(eventdata, 1, (" . + $dbh->sql_position(q{':'}, 'eventdata') . "- 1)) = ?) + OR (tokentype = 'emailnew' + AND SUBSTRING(eventdata, (" . + $dbh->sql_position(q{':'}, 'eventdata') . "+ 1)) = ?)", + undef, ($username, $username)); + + if ($eventdata) { # Allow thru owner of token if($old_username && ($eventdata eq "$old_username:$username")) { return 1; @@ -1413,24 +1615,50 @@ sub is_available_username { } sub login_to_id { - my ($login) = (@_); + my ($login, $throw_error) = @_; my $dbh = Bugzilla->dbh; - # $login will only be used by the following SELECT statement, so it's safe. + # No need to validate $login -- it will be used by the following SELECT + # statement only, so it's safe to simply trick_taint. trick_taint($login); my $user_id = $dbh->selectrow_array("SELECT userid FROM profiles WHERE " . $dbh->sql_istrcmp('login_name', '?'), undef, $login); if ($user_id) { return $user_id; + } elsif ($throw_error) { + ThrowUserError('invalid_username', { name => $login }); } else { return 0; } } -sub UserInGroup { - return exists Bugzilla->user->groups->{$_[0]} ? 1 : 0; +sub user_id_to_login { + my $user_id = shift; + my $dbh = Bugzilla->dbh; + + return '' unless ($user_id && detaint_natural($user_id)); + + my $login = $dbh->selectrow_array('SELECT login_name FROM profiles + WHERE userid = ?', undef, $user_id); + return $login || ''; +} + +sub validate_password { + my ($password, $matchpassword) = @_; + + if (length($password) < USER_PASSWORD_MIN_LENGTH) { + ThrowUserError('password_too_short'); + } elsif (length($password) > USER_PASSWORD_MAX_LENGTH) { + ThrowUserError('password_too_long'); + } elsif ((defined $matchpassword) && ($password ne $matchpassword)) { + ThrowUserError('passwords_dont_match'); + } + # Having done these checks makes us consider the password untainted. + trick_taint($_[0]); + return 1; } + 1; __END__ @@ -1449,7 +1677,12 @@ Bugzilla::User - Object for a Bugzilla user $user->get_selectable_classifications; # Class Functions - $password = insert_new_user($username, $realname, $password, $disabledtext); + $user = Bugzilla::User->create({ + login_name => $username, + realname => $realname, + cryptpassword => $plaintext_password, + disabledtext => $disabledtext, + disable_mail => 0}); =head1 DESCRIPTION @@ -1459,6 +1692,10 @@ there is currently no way to modify a user from this package. Note that the currently logged in user (if any) is available via L<Bugzilla-E<gt>user|Bugzilla/"user">. +C<Bugzilla::User> is an implementation of L<Bugzilla::Object>, and thus +provides all the methods of L<Bugzilla::Object> in addition to the +methods listed below. + =head1 CONSTANTS =over @@ -1487,26 +1724,43 @@ confirmation screen. =head1 METHODS -=over 4 +=head2 Saved and Shared Queries -=item C<new($userid)> +=over -Creates a new C<Bugzilla::User> object for the given user id. If no user -id was given, a blank object is created with no user attributes. +=item C<queries> -If an id was given but there was no matching user found, undef is returned. +Returns an arrayref of the user's own saved queries, sorted by name. The +array contains L<Bugzilla::Search::Saved> objects. -=begin undocumented +=item C<queries_subscribed> -=item C<new_from_login($login)> +Returns an arrayref of shared queries that the user has subscribed to. +That is, these are shared queries that the user sees in their footer. +This array contains L<Bugzilla::Search::Saved> objects. -Creates a new C<Bugzilla::User> object given the provided login. Returns -C<undef> if no matching user is found. +=item C<queries_available> -This routine should not be required in general; most scripts should be using -userids instead. +Returns an arrayref of all queries to which the user could possibly +subscribe. This includes the contents of L</queries_subscribed>. +An array of L<Bugzilla::Search::Saved> objects. + +=item C<flush_queries_cache> + +Some code modifies the set of stored queries. Because C<Bugzilla::User> does +not handle these modifications, but does cache the result of calling C<queries> +internally, such code must call this method to flush the cached result. -=end undocumented +=item C<queryshare_groups> + +An arrayref of group ids. The user can share their own queries with these +groups. + +=back + +=head2 Other Methods + +=over =item C<id> @@ -1543,26 +1797,16 @@ which to identify the user. Currently the part of the user's email address before the at sign (@), but that could change, especially if we implement usernames not dependent on email address. -=item C<queries> +=item C<authorizer> -Returns an array of the user's named queries, sorted in a case-insensitive -order by name. Each entry is a hash with three keys: +This is the L<Bugzilla::Auth> object that the User logged in with. +If the user hasn't logged in yet, a new, empty Bugzilla::Auth() object is +returned. -=over +=item C<set_authorizer($authorizer)> -=item * - -name - The name of the query - -=item * - -query - The text for the query - -=item * - -linkinfooter - Whether or not the query should be displayed in the footer. - -=back +Sets the L<Bugzilla::Auth> object to be returned by C<authorizer()>. +Should only be called by C<Bugzilla::Auth::login>, for the most part. =item C<disabledtext> @@ -1582,12 +1826,6 @@ value - the value of this setting for this user. Will be the same is_default - a boolean to indicate whether the user has chosen to make a preference for themself or use the site default. -=item C<flush_queries_cache> - -Some code modifies the set of stored queries. Because C<Bugzilla::User> does -not handle these modifications, but does cache the result of calling C<queries> -internally, such code must call this method to flush the cached result. - =item C<groups> Returns a hashref of group names for groups the user is a member of. The keys @@ -1597,13 +1835,15 @@ obtained by C<values(%{$user-E<gt>groups})>.) =item C<groups_as_string> -Returns a string containing a comma-seperated list of numeric group ids. If +Returns a string containing a comma-separated list of numeric group ids. If the user is not a member of any groups, returns "-1". This is most often used within an SQL IN() function. -=item C<in_group> +=item C<in_group($group_name, $product_id)> -Determines whether or not a user is in the given group by name. +Determines whether or not a user is in the given group by name. +If $product_id is given, it also checks for local privileges for +this product. =item C<in_group_id> @@ -1618,6 +1858,12 @@ The arrayref consists of the groups the user can bless, taking into account that having editusers permissions means that you can bless all groups, and that you need to be aware of a group in order to bless a group. +=item C<get_products_by_permission($group)> + +Returns a list of product objects for which the user has $group privileges +and which he can access. +$group must be one of the groups defined in PER_PRODUCT_PRIVILEGES. + =item C<can_see_user(user)> Returns 1 if the specified user account exists and is visible to the user, @@ -1692,6 +1938,32 @@ method should be called in such a case to force reresolution of these groups. Returns: an array of product objects. +=item C<check_can_admin_product($product_name)> + + Description: Checks whether the user is allowed to administrate the product. + + Params: $product_name - a product name. + + Returns: On success, a product object. On failure, an error is thrown. + +=item C<can_request_flag($flag_type)> + + Description: Checks whether the user can request flags of the given type. + + Params: $flag_type - a Bugzilla::FlagType object. + + Returns: 1 if the user can request flags of the given type, + 0 otherwise. + +=item C<can_set_flag($flag_type)> + + Description: Checks whether the user can set flags of the given type. + + Params: $flag_type - a Bugzilla::FlagType object. + + Returns: 1 if the user can set flags of the given type, + 0 otherwise. + =item C<get_userlist> Returns a reference to an array of users. The array is populated with hashrefs @@ -1723,29 +1995,8 @@ list). =item C<product_responsibilities> -Retrieve user's product responsibilities as a list of hashes. -One hash per Bugzilla component the user has a responsibility for. -These are the hash keys: - -=over - -=item productname - -Name of the product. - -=item componentname - -Name of the component. - -=item initialowner - -User ID of default assignee. - -=item initialqacontact - -User ID of default QA contact. - -=back +Retrieve user's product responsibilities as a list of component objects. +Each object is a component the user has a responsibility for. =item C<can_bless> @@ -1753,24 +2004,9 @@ When called with no arguments: Returns C<1> if the user can bless at least one group, returns C<0> otherwise. When called with one argument: -Returns C<1> if the user can bless the group with that name, returns +Returns C<1> if the user can bless the group with that id, returns C<0> otherwise. -=item C<set_flags> -=item C<get_flag> - -User flags are template-accessible user status information, stored in the form -of a hash. For an example of use, when the current user is authenticated in -such a way that they are allowed to log out, the 'can_logout' flag is set to -true (1). The template then checks this flag before displaying the "Log Out" -link. - -C<set_flags> is called with any number of key,value pairs. Flags for each key -will be set to the specified value. - -C<get_flag> is called with a single key name, which returns the associated -value. - =item C<wants_bug_mail> Returns true if the user wants mail for a given bug change. @@ -1801,23 +2037,21 @@ called "statically," just like a normal procedural function. =over 4 -=item C<insert_new_user> +=item C<create> -Creates a new user in the database. +The same as L<Bugzilla::Object/create>. -Params: $username (scalar, string) - The login name for the new user. - $realname (scalar, string) - The full name for the new user. - $password (scalar, string) - Optional. The password for the new user; - if not given, a random password will be - generated. - $disabledtext (scalar, string) - Optional. The disable text for the new - user; if not given, it will be empty. - If given, the user will be disabled, - meaning the account will be - unavailable for login. - -Returns: The password for this user, in plain text, so it can be included - in an e-mail sent to the user. +Params: login_name - B<Required> The login name for the new user. + realname - The full name for the new user. + cryptpassword - B<Required> The password for the new user. + Even though the name says "crypt", you should just specify + a plain-text password. If you specify '*', the user will not + be able to log in using DB authentication. + disabledtext - The disable-text for the new user. If given, the user + will be disabled, meaning he cannot log in. Defaults to an + empty string. + disable_mail - If 1, bug-related mail will not be sent to this user; + if 0, mail will be sent depending on the user's email preferences. =item C<is_available_username> @@ -1832,13 +2066,15 @@ Params: $username (scalar, string) - The full login name of the username can change his username to $username. (That is, this function will return a boolean true value). -=item C<login_to_id($login)> +=item C<login_to_id($login, $throw_error)> Takes a login name of a Bugzilla user and changes that into a numeric ID for that user. This ID can then be passed to Bugzilla::User::new to create a new user. -If no valid user exists with that login name, then the function will return 0. +If no valid user exists with that login name, then the function returns 0. +However, if $throw_error is set, the function will throw a user error +instead of returning. This function can also be used when you want to just find out the userid of a user, but you don't want the full weight of Bugzilla::User. @@ -1846,9 +2082,20 @@ of a user, but you don't want the full weight of Bugzilla::User. However, consider using a Bugzilla::User object instead of this function if you need more information about the user than just their ID. -=item C<UserInGroup($groupname)> +=item C<user_id_to_login($user_id)> + +Returns the login name of the user account for the given user ID. If no +valid user ID is given or the user has no entry in the profiles table, +we return an empty string. + +=item C<validate_password($passwd1, $passwd2)> + +Returns true if a password is valid (i.e. meets Bugzilla's +requirements for length and content), else returns false. +Untaints C<$passwd1> if successful. -Takes a name of a group, and returns 1 if a user is in the group, 0 otherwise. +If a second password is passed in, this function also verifies that +the two passwords match. =back diff --git a/Bugzilla/User/CVS/Entries b/Bugzilla/User/CVS/Entries index 6efae6945..d5dfdd22d 100644 --- a/Bugzilla/User/CVS/Entries +++ b/Bugzilla/User/CVS/Entries @@ -1,2 +1,2 @@ -/Setting.pm/1.6/Tue Jul 26 14:09:48 2005//TBUGZILLA-2_22_3 -D +/Setting.pm/1.10/Mon Dec 11 18:00:46 2006//TBUGZILLA-3_0 +D/Setting//// diff --git a/Bugzilla/User/CVS/Tag b/Bugzilla/User/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/Bugzilla/User/CVS/Tag +++ b/Bugzilla/User/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/Bugzilla/User/Setting.pm b/Bugzilla/User/Setting.pm index 450d20a7f..bdc653b97 100644 --- a/Bugzilla/User/Setting.pm +++ b/Bugzilla/User/Setting.pm @@ -14,7 +14,8 @@ # # Contributor(s): Shane H. W. Travis <travis@sedsystems.ca> # Max Kanat-Alexander <mkanat@bugzilla.org> -# +# Marc Schumann <wurblzap@gmail.com> +# Frédéric Buclin <LpSolit@gmail.com> package Bugzilla::User::Setting; @@ -22,12 +23,13 @@ package Bugzilla::User::Setting; use strict; use base qw(Exporter); + # Module stuff @Bugzilla::User::Setting::EXPORT = qw(get_all_settings get_defaults add_setting); use Bugzilla::Error; -use Bugzilla::Util qw{trick_taint}; +use Bugzilla::Util qw(trick_taint get_text); ############################### ### Module Initialization ### @@ -39,10 +41,10 @@ sub new { my $user_id = shift; my $class = ref($invocant) || $invocant; + my $subclass = ''; # Create a ref to an empty hash and bless it my $self = {}; - bless($self, $class); my $dbh = Bugzilla->dbh; @@ -60,9 +62,10 @@ sub new { # to retrieve the information for this setting ourselves. if (scalar @_ == 0) { - my ($default, $is_enabled, $value) = + my ($default, $is_enabled, $value); + ($default, $is_enabled, $value, $subclass) = $dbh->selectrow_array( - q{SELECT default_value, is_enabled, setting_value + q{SELECT default_value, is_enabled, setting_value, subclass FROM setting LEFT JOIN profile_setting ON setting.name = profile_setting.setting_name @@ -73,9 +76,9 @@ sub new { # if not defined, then grab the default value if (! defined $value) { - ($default, $is_enabled) = + ($default, $is_enabled, $subclass) = $dbh->selectrow_array( - q{SELECT default_value, is_enabled + q{SELECT default_value, is_enabled, subclass FROM setting WHERE name = ?}, undef, @@ -96,12 +99,23 @@ sub new { } } else { - # If the values were passed in, simply assign them and return. - $self->{'is_enabled'} = shift; - $self->{'default_value'} = shift; - $self->{'value'} = shift; - $self->{'is_default'} = shift; + ($subclass) = $dbh->selectrow_array( + q{SELECT subclass FROM setting WHERE name = ?}, + undef, + $setting_name); + # If the values were passed in, simply assign them and return. + $self->{'is_enabled'} = shift; + $self->{'default_value'} = shift; + $self->{'value'} = shift; + $self->{'is_default'} = shift; + } + if ($subclass) { + eval('require ' . $class . '::' . $subclass); + $@ && ThrowCodeError('setting_subclass_invalid', + {'subclass' => $subclass}); + $class = $class . '::' . $subclass; } + bless($self, $class); $self->{'_setting_name'} = $setting_name; $self->{'_user_id'} = $user_id; @@ -114,25 +128,39 @@ sub new { ############################### sub add_setting { - my ($name, $values, $default_value) = @_; + my ($name, $values, $default_value, $subclass, $force_check) = @_; my $dbh = Bugzilla->dbh; - return if _setting_exists($name); + my $exists = _setting_exists($name); + return if ($exists && !$force_check); - ($name && $values && $default_value) + ($name && $default_value) || ThrowCodeError("setting_info_invalid"); - print "Adding a new user setting called '$name'\n"; - $dbh->do(q{INSERT INTO setting (name, default_value, is_enabled) - VALUES (?, ?, 1)}, - undef, ($name, $default_value)); + if ($exists) { + # If this setting exists, we delete it and regenerate it. + $dbh->do('DELETE FROM setting_value WHERE name = ?', undef, $name); + $dbh->do('DELETE FROM setting WHERE name = ?', undef, $name); + # Remove obsolete user preferences for this setting. + my $list = join(', ', map {$dbh->quote($_)} @$values); + $dbh->do("DELETE FROM profile_setting + WHERE setting_name = ? AND setting_value NOT IN ($list)", + undef, $name); + } + else { + print get_text('install_setting_new', { name => $name }) . "\n"; + } + $dbh->do(q{INSERT INTO setting (name, default_value, is_enabled, subclass) + VALUES (?, ?, 1, ?)}, + undef, ($name, $default_value, $subclass)); my $sth = $dbh->prepare(q{INSERT INTO setting_value (name, value, sortindex) VALUES (?, ?, ?)}); - my @values_list = keys %{$values}; - foreach my $key (@values_list){ - $sth->execute($name, $key, $values->{$key}); + my $sortindex = 5; + foreach my $key (@$values){ + $sth->execute($name, $key, $sortindex); + $sortindex += 5; } } @@ -307,17 +335,19 @@ $settings->{$setting_name} = new Bugzilla::User::Setting( =over 4 -=item C<add_setting($name, $values, $default_value)> +=item C<add_setting($name, \@values, $default_value)> Description: Checks for the existence of a setting, and adds it to the database if it does not yet exist. + Params: C<$name> - string - the name of the new setting - C<$values> - hash - contains the new values (key) and - sortindexes for the new setting + C<$values> - arrayref - contains the new choices + for the new Setting. C<$default_value> - string - the site default + Returns: a pointer to a hash of settings -# -# + + =item C<get_all_settings($user_id)> Description: Provides the user's choices for each setting in the diff --git a/Bugzilla/User/Setting/CVS/Entries b/Bugzilla/User/Setting/CVS/Entries new file mode 100644 index 000000000..54514e3ca --- /dev/null +++ b/Bugzilla/User/Setting/CVS/Entries @@ -0,0 +1,2 @@ +/Skin.pm/1.1/Wed Sep 6 20:45:30 2006//TBUGZILLA-3_0 +D diff --git a/Bugzilla/User/Setting/CVS/Repository b/Bugzilla/User/Setting/CVS/Repository new file mode 100644 index 000000000..8acce1564 --- /dev/null +++ b/Bugzilla/User/Setting/CVS/Repository @@ -0,0 +1 @@ +mozilla/webtools/bugzilla/Bugzilla/User/Setting diff --git a/Bugzilla/User/Setting/CVS/Root b/Bugzilla/User/Setting/CVS/Root new file mode 100644 index 000000000..cdb6f4a07 --- /dev/null +++ b/Bugzilla/User/Setting/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot diff --git a/Bugzilla/User/Setting/CVS/Tag b/Bugzilla/User/Setting/CVS/Tag new file mode 100644 index 000000000..efdc1ff3e --- /dev/null +++ b/Bugzilla/User/Setting/CVS/Tag @@ -0,0 +1 @@ +NBUGZILLA-3_0 diff --git a/Bugzilla/User/Setting/Skin.pm b/Bugzilla/User/Setting/Skin.pm new file mode 100755 index 000000000..c4858503f --- /dev/null +++ b/Bugzilla/User/Setting/Skin.pm @@ -0,0 +1,80 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Marc Schumann <wurblzap@gmail.com> +# + + +package Bugzilla::User::Setting::Skin; + +use strict; + +use base qw(Bugzilla::User::Setting); + +use Bugzilla::Constants; +use File::Spec::Functions; +use File::Basename; + +use constant BUILTIN_SKIN_NAMES => ['standard']; + +sub legal_values { + my ($self) = @_; + + return $self->{'legal_values'} if defined $self->{'legal_values'}; + + my $dirbase = bz_locations()->{'skinsdir'}; + # Avoid modification of the list BUILTIN_SKIN_NAMES points to by copying the + # list over instead of simply writing $legal_values = BUILTIN_SKIN_NAMES. + my @legal_values = @{(BUILTIN_SKIN_NAMES)}; + + foreach my $direntry (glob(catdir($dirbase, '*'))) { + if (-d $direntry) { + # Stylesheet set + push(@legal_values, basename($direntry)); + } + elsif ($direntry =~ /\.css$/) { + # Single-file stylesheet + push(@legal_values, basename($direntry)); + } + } + + return $self->{'legal_values'} = \@legal_values; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::User::Setting::Skin - Object for a user preference setting for skins + +=head1 SYNOPSIS + +=head1 DESCRIPTION + +Skin.pm extends Bugzilla::User::Setting and implements a class specialized for +skins settings. + +=head1 METHODS + +=over + +=item C<legal_values()> + +Description: Returns all legal skins +Params: none +Returns: A reference to an array containing the names of all legal skins + +=back diff --git a/Bugzilla/Util.pm b/Bugzilla/Util.pm index 8ac74a95f..e97bb11d0 100644 --- a/Bugzilla/Util.pm +++ b/Bugzilla/Util.pm @@ -24,6 +24,7 @@ # Christopher Aillon <christopher@aillon.com> # Max Kanat-Alexander <mkanat@bugzilla.org> # Frédéric Buclin <LpSolit@gmail.com> +# Marc Schumann <wurblzap@gmail.com> package Bugzilla::Util; @@ -33,18 +34,18 @@ use base qw(Exporter); @Bugzilla::Util::EXPORT = qw(is_tainted trick_taint detaint_natural detaint_signed html_quote url_quote value_quote xml_quote - css_class_quote html_light_quote - i_am_cgi correct_urlbase - lsearch max min + css_class_quote html_light_quote url_decode + i_am_cgi get_netaddr correct_urlbase + lsearch diff_arrays diff_strings trim wrap_comment find_wrap_point perform_substs format_time format_time_decimal validate_date file_mod_time is_7bit_clean bz_crypt generate_random_password - validate_email_syntax clean_text); + validate_email_syntax clean_text + get_text); -use Bugzilla::Config; use Bugzilla::Constants; use Date::Parse; @@ -64,20 +65,20 @@ sub is_tainted { sub trick_taint { require Carp; Carp::confess("Undef to trick_taint") unless defined $_[0]; - my ($match) = $_[0] =~ /^(.*)$/s; - $_[0] = $match; + my $match = $_[0] =~ /^(.*)$/s; + $_[0] = $match ? $1 : undef; return (defined($_[0])); } sub detaint_natural { - my ($match) = $_[0] =~ /^(\d+)$/; - $_[0] = $match; + my $match = $_[0] =~ /^(\d+)$/; + $_[0] = $match ? $1 : undef; return (defined($_[0])); } sub detaint_signed { - my ($match) = $_[0] =~ /^([-+]?\d+)$/; - $_[0] = $match; + my $match = $_[0] =~ /^([-+]?\d+)$/; + $_[0] = $match ? $1 : undef; # Remove any leading plus sign. if (defined($_[0]) && $_[0] =~ /^\+(\d+)$/) { $_[0] = $1; @@ -235,17 +236,19 @@ sub i_am_cgi { } sub correct_urlbase { - return Param('urlbase') if Param('ssl') eq 'never'; + my $ssl = Bugzilla->params->{'ssl'}; + return Bugzilla->params->{'urlbase'} if $ssl eq 'never'; - if (Param('sslbase')) { - return Param('sslbase') if Param('ssl') eq 'always'; + my $sslbase = Bugzilla->params->{'sslbase'}; + if ($sslbase) { + return $sslbase if $ssl eq 'always'; # Authenticated Sessions - return Param('sslbase') if Bugzilla->user->id; + return $sslbase if Bugzilla->user->id; } # Set to "authenticated sessions" but nobody's logged in, or # sslbase isn't set. - return Param('urlbase'); + return Bugzilla->params->{'urlbase'}; } sub lsearch { @@ -260,22 +263,6 @@ sub lsearch { return -1; } -sub max { - my $max = shift(@_); - foreach my $val (@_) { - $max = $val if $val > $max; - } - return $max; -} - -sub min { - my $min = shift(@_); - foreach my $val (@_) { - $min = $val if $val < $min; - } - return $min; -} - sub diff_arrays { my ($old_ref, $new_ref) = @_; @@ -370,7 +357,7 @@ sub find_wrap_point { sub perform_substs { my ($str, $substs) = (@_); - $str =~ s/%([a-z]*)%/(defined $substs->{$1} ? $substs->{$1} : Param($1))/eg; + $str =~ s/%([a-z]*)%/(defined $substs->{$1} ? $substs->{$1} : Bugzilla->params->{$1})/eg; return $str; } @@ -396,7 +383,8 @@ sub format_time { } else { # Search for %Z or %z, meaning we want the timezone to be displayed. - # Till bug 182238 gets fixed, we assume Param('timezone') is used. + # Till bug 182238 gets fixed, we assume Bugzilla->params->{'timezone'} + # is used. $show_timezone = ($format =~ s/\s?%Z$//i); } @@ -405,7 +393,7 @@ sub format_time { if (defined $time) { $date = time2str($format, $time); - $date .= " " . &::Param('timezone') if $show_timezone; + $date .= " " . Bugzilla->params->{'timezone'} if $show_timezone; } else { # Don't let invalid (time) strings to be passed to templates! @@ -466,7 +454,7 @@ sub generate_random_password { sub validate_email_syntax { my ($addr) = @_; - my $match = Param('emailregexp'); + my $match = Bugzilla->params->{'emailregexp'}; my $ret = ($addr =~ /$match/ && $addr !~ /[\\\(\)<>&,;:"\[\] \t\r\n]/); if ($ret) { # We assume these checks to suffice to consider the address untainted. @@ -501,6 +489,41 @@ sub clean_text { return trim($dtext); } +sub get_text { + my ($name, $vars) = @_; + my $template = Bugzilla->template_inner; + $vars ||= {}; + $vars->{'message'} = $name; + my $message; + $template->process('global/message.txt.tmpl', $vars, \$message) + || ThrowTemplateError($template->error()); + # Remove the indenting that exists in messages.html.tmpl. + $message =~ s/^ //gm; + return $message; +} + + +sub get_netaddr { + my $ipaddr = shift; + + # Check for a valid IPv4 addr which we know how to parse + if (!$ipaddr || $ipaddr !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { + return undef; + } + + my $addr = unpack("N", pack("CCCC", split(/\./, $ipaddr))); + + my $maskbits = Bugzilla->params->{'loginnetmask'}; + + # Make Bugzilla ignore the IP address if loginnetmask is set to 0 + return "0.0.0.0" if ($maskbits == 0); + + $addr >>= (32-$maskbits); + + $addr <<= (32-$maskbits); + return join(".", unpack("CCCC", pack("N", $addr))); +} + 1; __END__ @@ -529,13 +552,12 @@ Bugzilla::Util - Generic utility functions for bugzilla $rv = url_decode($var); # Functions that tell you about your environment - my $is_cgi = i_am_cgi(); + my $is_cgi = i_am_cgi(); + my $net_addr = get_netaddr($ip_addr); my $urlbase = correct_urlbase(); # Functions for searching $loc = lsearch(\@arr, $val); - $val = max($a, $b, $c); - $val = min($a, $b, $c); # Data manipulation ($removed, $added) = diff_arrays(\@old, \@new); @@ -652,12 +674,27 @@ is kept separate from html_quote partly for compatibility with previous code Converts the %xx encoding from the given URL back to its original form. +=back + +=head2 Environment and Location + +Functions returning information about your environment or location. + +=over 4 + =item C<i_am_cgi()> Tells you whether or not you are being run as a CGI script in a web server. For example, it would return false if the caller is running in a command-line script. +=item C<get_netaddr($ipaddr)> + +Given an IP address, this returns the associated network address, using +C<Bugzilla->params->{'loginnetmask'}> as the netmask. This can be used +to obtain data in order to restrict weak authentication methods (such as +cookies) to only some addresses. + =item C<correct_urlbase()> Returns either the C<sslbase> or C<urlbase> parameter, depending on the @@ -678,14 +715,6 @@ reference. If the item is not in the list, returns -1. -=item C<max($a, $b, ...)> - -Returns the maximum from a set of values. - -=item C<min($a, $b, ...)> - -Returns the minimum from a set of values. - =back =head2 Data Manipulation @@ -766,6 +795,34 @@ ASCII 10 (LineFeed) and ASCII 13 (Carrage Return). Returns the parameter "cleaned" by exchanging non-printable characters with spaces. Specifically characters (ASCII 0 through 31) and (ASCII 127) will become ASCII 32 (Space). +=item C<get_text> + +=over + +=item B<Description> + +This is a method of getting localized strings within Bugzilla code. +Use this when you don't want to display a whole template, you just +want a particular string. + +It uses the F<global/message.txt.tmpl> template to return a string. + +=item B<Params> + +=over + +=item C<$message> - The identifier for the message. + +=item C<$vars> - A hashref. Any variables you want to pass to the template. + +=back + +=item B<Returns> + +A string. + +=back + =back =head2 Formatting Time @@ -840,6 +897,7 @@ and tokens. Do a syntax checking for a legal email address and returns 1 if the check is successful, else returns 0. +Untaints C<$email> if successful. =item C<validate_date($date)> diff --git a/Bugzilla/Version.pm b/Bugzilla/Version.pm index 9492e8135..ba7631a80 100644 --- a/Bugzilla/Version.pm +++ b/Bugzilla/Version.pm @@ -13,11 +13,15 @@ # The Original Code is the Bugzilla Bug Tracking System. # # Contributor(s): Tiago R. Mello <timello@async.com.br> +# Max Kanat-Alexander <mkanat@bugzilla.org> use strict; package Bugzilla::Version; +use base qw(Bugzilla::Object); + +use Bugzilla::Install::Requirements qw(vers_cmp); use Bugzilla::Util; use Bugzilla::Error; @@ -27,49 +31,52 @@ use Bugzilla::Error; use constant DEFAULT_VERSION => 'unspecified'; +use constant DB_TABLE => 'versions'; + use constant DB_COLUMNS => qw( - versions.value - versions.product_id + id + value + product_id ); -our $columns = join(", ", DB_COLUMNS); +use constant NAME_FIELD => 'value'; +# This is "id" because it has to be filled in and id is probably the fastest. +# We do a custom sort in new_from_list below. +use constant LIST_ORDER => 'id'; sub new { - my $invocant = shift; - my $class = ref($invocant) || $invocant; - my $self = {}; - bless($self, $class); - return $self->_init(@_); -} - -sub _init { - my $self = shift; - my ($product_id, $value) = (@_); + my $class = shift; + my $param = shift; my $dbh = Bugzilla->dbh; - my $version; - - if (defined $product_id - && detaint_natural($product_id) - && defined $value) { - - trick_taint($value); - $version = $dbh->selectrow_hashref(qq{ - SELECT $columns FROM versions - WHERE value = ? - AND product_id = ?}, undef, ($value, $product_id)); - } else { - ThrowCodeError('bad_arg', - {argument => 'product_id/value', - function => 'Bugzilla::Version::_init'}); + my $product; + if (ref $param) { + $product = $param->{product}; + my $name = $param->{name}; + if (!defined $product) { + ThrowCodeError('bad_arg', + {argument => 'product', + function => "${class}::new"}); + } + if (!defined $name) { + ThrowCodeError('bad_arg', + {argument => 'name', + function => "${class}::new"}); + } + + my $condition = 'product_id = ? AND value = ?'; + my @values = ($product->id, $name); + $param = { condition => $condition, values => \@values }; } - return undef unless (defined $version); + unshift @_, $param; + return $class->SUPER::new(@_); +} - foreach my $field (keys %$version) { - $self->{$field} = $version->{$field}; - } - return $self; +sub new_from_list { + my $self = shift; + my $list = $self->SUPER::new_from_list(@_); + return [sort { vers_cmp(lc($a->name), lc($b->name)) } @$list]; } sub bug_count { @@ -85,6 +92,53 @@ sub bug_count { return $self->{'bug_count'}; } +sub remove_from_db { + my $self = shift; + my $dbh = Bugzilla->dbh; + + # The version cannot be removed if there are bugs + # associated with it. + if ($self->bug_count) { + ThrowUserError("version_has_bugs", { nb => $self->bug_count }); + } + + $dbh->do(q{DELETE FROM versions WHERE product_id = ? AND value = ?}, + undef, ($self->product_id, $self->name)); +} + +sub update { + my $self = shift; + my ($name, $product) = @_; + my $dbh = Bugzilla->dbh; + + $name || ThrowUserError('version_not_specified'); + + # Remove unprintable characters + $name = clean_text($name); + + return 0 if ($name eq $self->name); + my $version = new Bugzilla::Version({ product => $product, name => $name }); + + if ($version) { + ThrowUserError('version_already_exists', + {'name' => $version->name, + 'product' => $product->name}); + } + + trick_taint($name); + $dbh->do("UPDATE bugs SET version = ? + WHERE version = ? AND product_id = ?", undef, + ($name, $self->name, $self->product_id)); + + $dbh->do("UPDATE versions SET value = ? + WHERE product_id = ? AND value = ?", undef, + ($name, $self->product_id, $self->name)); + + $self->{'value'} = $name; + + return 1; +} + ############################### ##### Accessors #### ############################### @@ -100,7 +154,8 @@ sub check_version { my ($product, $version_name) = @_; $version_name || ThrowUserError('version_not_specified'); - my $version = new Bugzilla::Version($product->id, $version_name); + my $version = new Bugzilla::Version( + { product => $product, name => $version_name }); unless ($version) { ThrowUserError('version_not_valid', {'product' => $product->name, @@ -109,6 +164,31 @@ sub check_version { return $version; } +sub create { + my ($name, $product) = @_; + my $dbh = Bugzilla->dbh; + + # Cleanups and validity checks + $name || ThrowUserError('version_blank_name'); + + # Remove unprintable characters + $name = clean_text($name); + + my $version = new Bugzilla::Version({ product => $product, name => $name }); + if ($version) { + ThrowUserError('version_already_exists', + {'name' => $version->name, + 'product' => $product->name}); + } + + # Add the new version + trick_taint($name); + $dbh->do(q{INSERT INTO versions (value, product_id) + VALUES (?, ?)}, undef, ($name, $product->id)); + + return new Bugzilla::Version($dbh->bz_last_key('versions', 'id')); +} + 1; __END__ @@ -126,11 +206,17 @@ Bugzilla::Version - Bugzilla product version class. my $product_id = $version->product_id; my $value = $version->value; + $version->remove_from_db; + + my $updated = $version->update($version_name, $product); + my $version = $hash_ref->{'version_value'}; my $version = Bugzilla::Version::check_version($product_obj, 'acme_version'); + my $version = Bugzilla::Version::create($version_name, $product); + =head1 DESCRIPTION Version.pm represents a Product Version object. @@ -157,6 +243,23 @@ Version.pm represents a Product Version object. Returns: Integer with the number of bugs. +=item C<remove_from_db()> + + Description: Removes the version from the database. + + Params: none. + + Retruns: none. + +=item C<update($name, $product)> + + Description: Update the value of the version. + + Params: $name - String with the new version value. + $product - Bugzilla::Product object the version belongs to. + + Returns: An integer - 1 if the version has been updated, else 0. + =back =head1 SUBROUTINES @@ -172,6 +275,15 @@ Version.pm represents a Product Version object. Returns: Bugzilla::Version object. +=item C<create($version_name, $product)> + + Description: Create a new version for the given product. + + Params: $version_name - String with a version value. + $product - A Bugzilla::Product object. + + Returns: A Bugzilla::Version object. + =back =cut diff --git a/Bugzilla/WebService.pm b/Bugzilla/WebService.pm new file mode 100755 index 000000000..dddc87a15 --- /dev/null +++ b/Bugzilla/WebService.pm @@ -0,0 +1,134 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Marc Schumann <wurblzap@gmail.com> +# Max Kanat-Alexander <mkanat@bugzilla.org> + +package Bugzilla::WebService; + +use strict; +use Bugzilla::WebService::Constants; +use Date::Parse; + +sub fail_unimplemented { + my $this = shift; + + die SOAP::Fault + ->faultcode(ERROR_UNIMPLEMENTED) + ->faultstring('Service Unimplemented'); +} + +sub datetime_format { + my ($self, $date_string) = @_; + + my $time = str2time($date_string); + my ($sec, $min, $hour, $mday, $mon, $year) = localtime $time; + # This format string was stolen from SOAP::Utils->format_datetime, + # which doesn't work but which has almost the right format string. + my $iso_datetime = sprintf('%d%02d%02dT%02d:%02d:%02d', + $year + 1900, $mon + 1, $mday, $hour, $min, $sec); + return $iso_datetime; +} + +sub handle_login { + my ($self, $module, $method) = @_; + my $exempt = LOGIN_EXEMPT->{$module}; + return if $exempt && grep { $_ eq $method } @$exempt; + Bugzilla->login; +} + +package Bugzilla::WebService::XMLRPC::Transport::HTTP::CGI; + +use strict; +eval 'use base qw(XMLRPC::Transport::HTTP::CGI)'; + +sub make_response { + my $self = shift; + + $self->SUPER::make_response(@_); + + # XMLRPC::Transport::HTTP::CGI doesn't know about Bugzilla carrying around + # its cookies in Bugzilla::CGI, so we need to copy them over. + foreach (@{Bugzilla->cgi->{'Bugzilla_cookie_list'}}) { + $self->response->headers->push_header('Set-Cookie', $_); + } +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::WebService - The Web Service interface to Bugzilla + +=head1 DESCRIPTION + +This is the standard API for external programs that want to interact +with Bugzilla. It provides various methods in various modules. + +=head1 STABLE, EXPERIMENTAL, and UNSTABLE + +Methods are marked B<STABLE> if you can expect their parameters and +return values not to change between versions of Bugzilla. You are +best off always using methods marked B<STABLE>. We may add parameters +and additional items to the return values, but your old code will +always continue to work with any new changes we make. If we ever break +a B<STABLE> interface, we'll post a big notice in the Release Notes, +and it will only happen during a major new release. + +Methods (or parts of methods) are marked B<EXPERIMENTAL> if +we I<believe> they will be stable, but there's a slight chance that +small parts will change in the future. + +Certain parts of a method's description may be marked as B<UNSTABLE>, +in which case those parts are not guaranteed to stay the same between +Bugzilla versions. + +=head1 ERRORS + +If a particular webservice call fails, it will throw a standard XML-RPC +error. There will be a numeric error code, and then the description +field will contain descriptive text of the error. Each error that Bugzilla +can throw has a specific code that will not change between versions of +Bugzilla. + +The various errors that functions can throw are specified by the +documentation of those functions. + +If your code needs to know what error Bugzilla threw, use the numeric +code. Don't try to parse the description, because that may change +from version to version of Bugzilla. + +Note that if you display the error to the user in an HTML program, make +sure that you properly escape the error, as it will not be HTML-escaped. + +=head2 Transient vs. Fatal Errors + +If the error code is a number greater than 0, the error is considered +"transient," which means that it was an error made by the user, not +some problem with Bugzilla itself. + +If the error code is a number less than 0, the error is "fatal," which +means that it's some error in Bugzilla itself that probably requires +administrative attention. + +Negative numbers and positive numbers don't overlap. That is, if there's +an error 302, there won't be an error -302. + +=head2 Unknown Errors + +Sometimes a function will throw an error that doesn't have a specific +error code. In this case, the code will be C<-32000> if it's a "fatal" +error, and C<32000> if it's a "transient" error. diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm new file mode 100755 index 000000000..a632ffaf0 --- /dev/null +++ b/Bugzilla/WebService/Bug.pm @@ -0,0 +1,459 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Marc Schumann <wurblzap@gmail.com> +# Max Kanat-Alexander <mkanat@bugzilla.org> + +package Bugzilla::WebService::Bug; + +use strict; +use base qw(Bugzilla::WebService); +import SOAP::Data qw(type); + +use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::Field; +use Bugzilla::WebService::Constants; +use Bugzilla::Util qw(detaint_natural); +use Bugzilla::Bug; +use Bugzilla::BugMail; +use Bugzilla::Constants; + +############# +# Constants # +############# + +# This maps the names of internal Bugzilla bug fields to things that would +# make sense to somebody who's not intimately familiar with the inner workings +# of Bugzilla. (These are the field names that the WebService uses.) +use constant FIELD_MAP => { + status => 'bug_status', + severity => 'bug_severity', + description => 'comment', + summary => 'short_desc', + platform => 'rep_platform', +}; + +use constant GLOBAL_SELECT_FIELDS => qw( + bug_severity + bug_status + op_sys + priority + rep_platform + resolution +); + +use constant PRODUCT_SPECIFIC_FIELDS => qw(version target_milestone component); + +########### +# Methods # +########### + +sub get_bugs { + my ($self, $params) = @_; + my $ids = $params->{ids}; + defined $ids || ThrowCodeError('param_required', { param => 'ids' }); + + my @return; + foreach my $bug_id (@$ids) { + ValidateBugID($bug_id); + my $bug = new Bugzilla::Bug($bug_id); + + # This is done in this fashion in order to produce a stable API. + # The internals of Bugzilla::Bug are not stable enough to just + # return them directly. + my $creation_ts = $self->datetime_format($bug->creation_ts); + my $delta_ts = $self->datetime_format($bug->delta_ts); + my %item; + $item{'creation_time'} = type('dateTime')->value($creation_ts); + $item{'last_change_time'} = type('dateTime')->value($delta_ts); + $item{'internals'} = $bug; + $item{'id'} = type('int')->value($bug->bug_id); + $item{'summary'} = type('string')->value($bug->short_desc); + + if (Bugzilla->params->{'usebugaliases'}) { + $item{'alias'} = type('string')->value($bug->alias); + } + else { + # For API reasons, we always want the value to appear, we just + # don't want it to have a value if aliases are turned off. + $item{'alias'} = undef; + } + + push(@return, \%item); + } + + return { bugs => \@return }; +} + + +sub create { + my ($self, $params) = @_; + + Bugzilla->login(LOGIN_REQUIRED); + + my %field_values; + foreach my $field (keys %$params) { + my $field_name = FIELD_MAP->{$field} || $field; + $field_values{$field_name} = $params->{$field}; + } + + # Make sure all the required fields are in the hash. + foreach my $field (Bugzilla::Bug::REQUIRED_CREATE_FIELDS) { + $field_values{$field} = undef unless exists $field_values{$field}; + } + + # WebService users can't set the creation date of a bug. + delete $field_values{'creation_ts'}; + + my $bug = Bugzilla::Bug->create(\%field_values); + + Bugzilla::BugMail::Send($bug->bug_id, { changer => $bug->reporter->login }); + + return { id => type('int')->value($bug->bug_id) }; +} + +sub legal_values { + my ($self, $params) = @_; + my $field = FIELD_MAP->{$params->{field}} || $params->{field}; + + my @custom_select = + Bugzilla->get_fields({ type => FIELD_TYPE_SINGLE_SELECT }); + + my $values; + if (grep($_ eq $field, GLOBAL_SELECT_FIELDS, @custom_select)) { + $values = get_legal_field_values($field); + } + elsif (grep($_ eq $field, PRODUCT_SPECIFIC_FIELDS)) { + my $id = $params->{product_id}; + defined $id || ThrowCodeError('param_required', + { function => 'Bug.legal_values', param => 'product_id' }); + grep($_->id eq $id, @{Bugzilla->user->get_accessible_products}) + || ThrowUserError('product_access_denied', { product => $id }); + + my $product = new Bugzilla::Product($id); + my @objects; + if ($field eq 'version') { + @objects = @{$product->versions}; + } + elsif ($field eq 'target_milestone') { + @objects = @{$product->milestones}; + } + elsif ($field eq 'component') { + @objects = @{$product->components}; + } + + $values = [map { $_->name } @objects]; + } + else { + ThrowCodeError('invalid_field_name', { field => $params->{field} }); + } + + my @result; + foreach my $val (@$values) { + push(@result, type('string')->value($val)); + } + + return { values => \@result }; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Webservice::Bug - The API for creating, changing, and getting the +details of bugs. + +=head1 DESCRIPTION + +This part of the Bugzilla API allows you to file a new bug in Bugzilla, +or get information about bugs that have already been filed. + +=head1 METHODS + +See L<Bugzilla::WebService> for a description of B<STABLE>, B<UNSTABLE>, +and B<EXPERIMENTAL>. + +=head2 Utility Functions + +=over + +=item C<legal_values> B<EXPERIMENTAL> + +=over + +=item B<Description> + +Tells you what values are allowed for a particular field. + +=item B<Params> + +=over + +=item C<field> - The name of the field you want information about. +This should be the same as the name you would use in L</create>, below. + +=item C<product_id> - If you're picking a product-specific field, you have +to specify the id of the product you want the values for. + +=back + +=item B<Returns> + +C<values> - An array of strings: the legal values for this field. +The values will be sorted as they normally would be in Bugzilla. + +=item B<Errors> + +=over + +=item 106 (Invalid Product) + +You were required to specify a product, and either you didn't, or you +specified an invalid product (or a product that you can't access). + +=item 108 (Invalid Field Name) + +You specified a field that doesn't exist or isn't a drop-down field. + +=back + +=back + + +=back + +=head2 Bug Creation and Modification + +=over + +=item C<get_bugs> B<EXPERIMENTAL> + +=over + +=item B<Description> + +Gets information about particular bugs in the database. + +=item B<Params> + +=over + +=item C<ids> + +An array of numbers and strings. + +If an element in the array is entirely numeric, it represents a bug_id +from the Bugzilla database to fetch. If it contains any non-numeric +characters, it is considered to be a bug alias instead, and the bug with +that alias will be loaded. + +Note that it's possible for aliases to be disabled in Bugzilla, in which +case you will be told that you have specified an invalid bug_id if you +try to specify an alias. (It will be error 100.) + +=back + +=item B<Returns> + +A hash containing a single element, C<bugs>. This is an array of hashes. +Each hash contains the following items: + +=over + +=item id + +C<int> The numeric bug_id of this bug. + +=item alias + +C<string> The alias of this bug. If there is no alias or aliases are +disabled in this Bugzilla, this will be an empty string. + +=item summary + +C<string> The summary of this bug. + +=item creation_time + +C<dateTime> When the bug was created. + +=item last_change_time + +C<dateTime> When the bug was last changed. + +=item internals B<UNSTABLE> + +A hash. The internals of a L<Bugzilla::Bug> object. This is extremely +unstable, and you should only rely on this if you absolutely have to. The +structure of the hash may even change between point releases of Bugzilla. + +=back + +=item B<Errors> + +=over + +=item 100 (Invalid Bug Alias) + +If you specified an alias and either: (a) the Bugzilla you're querying +doesn't support aliases or (b) there is no bug with that alias. + +=item 101 (Invalid Bug ID) + +The bug_id you specified doesn't exist in the database. + +=item 102 (Access Denied) + +You do not have access to the bug_id you specified. + +=back + +=back + + + +=item C<create> B<EXPERIMENTAL> + +=over + +=item B<Description> + +This allows you to create a new bug in Bugzilla. If you specify any +invalid fields, they will be ignored. If you specify any fields you +are not allowed to set, they will just be set to their defaults or ignored. + +You cannot currently set all the items here that you can set on enter_bug.cgi. + +The WebService interface may allow you to set things other than those listed +here, but realize that anything undocumented is B<UNSTABLE> and will very +likely change in the future. + +=item B<Params> + +Some params must be set, or an error will be thrown. These params are +marked B<Required>. + +Some parameters can have defaults set in Bugzilla, by the administrator. +If these parameters have defaults set, you can omit them. These parameters +are marked B<Defaulted>. + +Clients that want to be able to interact uniformly with multiple +Bugzillas should always set both the params marked B<Required> and those +marked B<Defaulted>, because some Bugzillas may not have defaults set +for B<Defaulted> parameters, and then this method will throw an error +if you don't specify them. + +The descriptions of the parameters below are what they mean when Bugzilla is +being used to track software bugs. They may have other meanings in some +installations. + +=over + +=item C<product> (string) B<Required> - The name of the product the bug +is being filed against. + +=item C<component> (string) B<Required> - The name of a component in the +product above. + +=item C<summary> (string) B<Required> - A brief description of the bug being +filed. + +=item C<version> (string) B<Required> - A version of the product above; +the version the bug was found in. + +=item C<description> (string) B<Defaulted> - The initial description for +this bug. Some Bugzilla installations require this to not be blank. + +=item C<op_sys> (string) B<Defaulted> - The operating system the bug was +discovered on. + +=item C<platform> (string) B<Defaulted> - What type of hardware the bug was +experienced on. + +=item C<priority> (string) B<Defaulted> - What order the bug will be fixed +in by the developer, compared to the developer's other bugs. + +=item C<severity> (string) B<Defaulted> - How severe the bug is. + +=item C<alias> (string) - A brief alias for the bug that can be used +instead of a bug number when accessing this bug. Must be unique in +all of this Bugzilla. + +=item C<assigned_to> (username) - A user to assign this bug to, if you +don't want it to be assigned to the component owner. + +=item C<cc> (array) - An array of usernames to CC on this bug. + +=item C<qa_contact> (username) - If this installation has QA Contacts +enabled, you can set the QA Contact here if you don't want to use +the component's default QA Contact. + +=item C<status> (string) - The status that this bug should start out as. +Note that only certain statuses can be set on bug creation. + +=item C<target_milestone> (string) - A valid target milestone for this +product. + +=back + +In addition to the above parameters, if your installation has any custom +fields, you can set them just by passing in the name of the field and +its value as a string. + +=item B<Returns> + +A hash with one element, C<id>. This is the id of the newly-filed bug. + +=item B<Errors> + +=over + +=item 103 (Invalid Alias) + +The alias you specified is invalid for some reason. See the error message +for more details. + +=item 104 (Invalid Field) + +One of the drop-down fields has an invalid value. The error message will +have more detail. + +=item 105 (Invalid Component) + +Either you didn't specify a component, or the component you specified was +invalid. + +=item 106 (Invalid Product) + +Either you didn't specify a product, this product doesn't exist, or +you don't have permission to enter bugs in this product. + +=item 107 (Invalid Summary) + +You didn't specify a summary for the bug. + +=item 504 (Invalid User) + +Either the QA Contact, Assignee, or CC lists have some invalid user +in them. The error message will have more details. + +=back + +=back + + +=back diff --git a/Bugzilla/WebService/Bugzilla.pm b/Bugzilla/WebService/Bugzilla.pm new file mode 100755 index 000000000..1eeeebddc --- /dev/null +++ b/Bugzilla/WebService/Bugzilla.pm @@ -0,0 +1,96 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Marc Schumann <wurblzap@gmail.com> +# Max Kanat-Alexander <mkanat@bugzilla.org> +# Mads Bondo Dydensborg <mbd@dbc.dk> + +package Bugzilla::WebService::Bugzilla; + +use strict; +use base qw(Bugzilla::WebService); +use Bugzilla::Constants; +import SOAP::Data qw(type); + +use Time::Zone; + +sub version { + return { version => type('string')->value(BUGZILLA_VERSION) }; +} + +sub timezone { + my $offset = tz_offset(); + $offset = (($offset / 60) / 60) * 100; + $offset = sprintf('%+05d', $offset); + return { timezone => type('string')->value($offset) }; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::WebService::Bugzilla - Global functions for the webservice interface. + +=head1 DESCRIPTION + +This provides functions that tell you about Bugzilla in general. + +=head1 METHODS + +See L<Bugzilla::WebService> for a description of what B<STABLE>, B<UNSTABLE>, +and B<EXPERIMENTAL> mean. + +=over + +=item C<version> B<EXPERIMENTAL> + +=over + +=item B<Description> + +Returns the current version of Bugzilla. + +=item B<Params> (none) + +=item B<Returns> + +A hash with a single item, C<version>, that is the version as a +string. + +=item B<Errors> (none) + +=back + +=item C<timezone> B<EXPERIMENTAL> + +=over + +=item B<Description> + +Returns the timezone of the server Bugzilla is running on. This is +important because all dates/times that the webservice interface +returns will be in this timezone. + +=item B<Params> (none) + +=item B<Returns> + +A hash with a single item, C<timezone>, that is the timezone as a +string in (+/-)XXXX (RFC 2822) format. + +=back + +=back diff --git a/Bugzilla/WebService/CVS/Entries b/Bugzilla/WebService/CVS/Entries new file mode 100644 index 000000000..327b46910 --- /dev/null +++ b/Bugzilla/WebService/CVS/Entries @@ -0,0 +1,6 @@ +/Bug.pm/1.4/Tue Nov 14 19:10:52 2006//TBUGZILLA-3_0 +/Bugzilla.pm/1.4/Tue Oct 31 23:26:28 2006//TBUGZILLA-3_0 +/Constants.pm/1.6/Sun Feb 4 16:23:21 2007//TBUGZILLA-3_0 +/Product.pm/1.4/Sun Feb 4 17:51:54 2007//TBUGZILLA-3_0 +/User.pm/1.4/Sun Feb 4 16:23:21 2007//TBUGZILLA-3_0 +D diff --git a/Bugzilla/WebService/CVS/Repository b/Bugzilla/WebService/CVS/Repository new file mode 100644 index 000000000..636b26e10 --- /dev/null +++ b/Bugzilla/WebService/CVS/Repository @@ -0,0 +1 @@ +mozilla/webtools/bugzilla/Bugzilla/WebService diff --git a/Bugzilla/WebService/CVS/Root b/Bugzilla/WebService/CVS/Root new file mode 100644 index 000000000..cdb6f4a07 --- /dev/null +++ b/Bugzilla/WebService/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot diff --git a/Bugzilla/WebService/CVS/Tag b/Bugzilla/WebService/CVS/Tag new file mode 100644 index 000000000..efdc1ff3e --- /dev/null +++ b/Bugzilla/WebService/CVS/Tag @@ -0,0 +1 @@ +NBUGZILLA-3_0 diff --git a/Bugzilla/WebService/Constants.pm b/Bugzilla/WebService/Constants.pm new file mode 100755 index 000000000..39d25298d --- /dev/null +++ b/Bugzilla/WebService/Constants.pm @@ -0,0 +1,112 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Marc Schumann <wurblzap@gmail.com> +# Max Kanat-Alexander <mkanat@bugzilla.org> + +package Bugzilla::WebService::Constants; + +use strict; +use base qw(Exporter); + +@Bugzilla::WebService::Constants::EXPORT = qw( + WS_ERROR_CODE + ERROR_UNKNOWN_FATAL + ERROR_UNKNOWN_TRANSIENT + + ERROR_AUTH_NODATA + ERROR_UNIMPLEMENTED + + LOGIN_EXEMPT +); + +# This maps the error names in global/*-error.html.tmpl to numbers. +# Generally, transient errors should have a number above 0, and +# fatal errors should have a number below 0. +# +# This hash should generally contain any error that could be thrown +# by the WebService interface. If it's extremely unlikely that the +# error could be thrown (like some CodeErrors), it doesn't have to +# be listed here. +# +# "Transient" means "If you resubmit that request with different data, +# it may work." +# +# "Fatal" means, "There's something wrong with Bugzilla, probably +# something an administrator would have to fix." +# +# NOTE: Numbers must never be recycled. If you remove a number, leave a +# comment that it was retired. Also, if an error changes its name, you'll +# have to fix it here. +use constant WS_ERROR_CODE => { + # Bug errors usually occupy the 100-200 range. + invalid_bug_id_or_alias => 100, + invalid_bug_id_non_existent => 101, + bug_access_denied => 102, + invalid_field_name => 108, + # These all mean "invalid alias" + alias_not_defined => 103, + alias_too_long => 103, + alias_in_use => 103, + alias_is_numeric => 103, + alias_has_comma_or_space => 103, + # Misc. bug field errors + illegal_field => 104, + # Component errors + require_component => 105, + component_name_too_long => 105, + component_not_valid => 105, + # Invalid Product + no_products => 106, + entry_access_denied => 106, + product_access_denied => 106, + product_disabled => 106, + # Invalid Summary + require_summary => 107, + + # Authentication errors are usually 300-400. + invalid_username_or_password => 300, + account_disabled => 301, + auth_invalid_email => 302, + extern_id_conflict => -303, + + # User errors are 500-600. + account_exists => 500, + illegal_email_address => 501, + password_too_short => 502, + password_too_long => 503, + invalid_username => 504, + # This is from strict_isolation, but it also basically means + # "invalid user." + invalid_user_group => 504, +}; + +# These are the fallback defaults for errors not in ERROR_CODE. +use constant ERROR_UNKNOWN_FATAL => -32000; +use constant ERROR_UNKNOWN_TRANSIENT => 32000; + +use constant ERROR_AUTH_NODATA => 410; +use constant ERROR_UNIMPLEMENTED => 910; +use constant ERROR_GENERAL => 999; + +# For some methods, we shouldn't call Bugzilla->login before we call them. +# This is a hash--package names pointing to an arrayref of method names. +use constant LOGIN_EXEMPT => { + # Callers may have to know the Bugzilla version before logging in, + # even on a requirelogin installation. + Bugzilla => ['version'], + User => ['offer_account_by_email', 'login'], +}; + +1; diff --git a/Bugzilla/WebService/Product.pm b/Bugzilla/WebService/Product.pm new file mode 100755 index 000000000..fb11a00bc --- /dev/null +++ b/Bugzilla/WebService/Product.pm @@ -0,0 +1,182 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Marc Schumann <wurblzap@gmail.com> +# Mads Bondo Dydensborg <mbd@dbc.dk> + +package Bugzilla::WebService::Product; + +use strict; +use base qw(Bugzilla::WebService); +use Bugzilla::Product; +use Bugzilla::User; +import SOAP::Data qw(type); + +# Get the ids of the products the user can search +sub get_selectable_products { + return {ids => [map {$_->id} @{Bugzilla->user->get_selectable_products}]}; +} + +# Get the ids of the products the user can enter bugs against +sub get_enterable_products { + return {ids => [map {$_->id} @{Bugzilla->user->get_enterable_products}]}; +} + +# Get the union of the products the user can search and enter bugs against. +sub get_accessible_products { + return {ids => [map {$_->id} @{Bugzilla->user->get_accessible_products}]}; +} + +# Get a list of actual products, based on list of ids +sub get_products { + my ($self, $params) = @_; + + # Only products that are in the users accessible products, + # can be allowed to be returned + my $accessible_products = Bugzilla->user->get_accessible_products; + + # Create a hash with the ids the user wants + my %ids = map { $_ => 1 } @{$params->{ids}}; + + # Return the intersection of this, by grepping the ids from + # accessible products. + my @requested_accessible = grep { $ids{$_->id} } @$accessible_products; + + # Now create a result entry for each. + my @products = + map {{ + internals => $_, + id => type('int')->value($_->id), + name => type('string')->value($_->name), + description => type('string')->value($_->description), + } + } @requested_accessible; + + return { products => \@products }; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Webservice::Product - The Product API + +=head1 DESCRIPTION + +This part of the Bugzilla API allows you to list the available Products and +get information about them. + +=head1 METHODS + +See L<Bugzilla::WebService> for a description of what B<STABLE>, B<UNSTABLE>, +and B<EXPERIMENTAL> mean, and for more information about error codes. + +=head2 List Products + +=over + +=item C<get_selectable_products> B<UNSTABLE> + +=over + +=item B<Description> + +Returns a list of the ids of the products the user can search on. + +=item B<Params> (none) + +=item B<Returns> + +A hash containing one item, C<ids>, that contains an array of product +ids. + +=item B<Errors> (none) + +=back + +=item C<get_enterable_products> B<UNSTABLE> + +=over + +=item B<Description> + +Returns a list of the ids of the products the user can enter bugs +against. + +=item B<Params> (none) + +=item B<Returns> + +A hash containing one item, C<ids>, that contains an array of product +ids. + +=item B<Errors> (none) + +=back + +=item C<get_accessible_products> B<UNSTABLE> + +=over + +=item B<Description> + +Returns a list of the ids of the products the user can search or enter +bugs against. + +=item B<Params> (none) + +=item B<Returns> + +A hash containing one item, C<ids>, that contains an array of product +ids. + +=item B<Errors> (none) + +=back + +=item C<get_products> B<UNSTABLE> + +=over + +=item B<Description> + +Returns a list of information about the products passed to it. + +=item B<Params> + +A hash containing one item, C<ids>, that is an array of product ids. + +=item B<Returns> + +A hash containing one item, C<products>, that is an array of +hashes. Each hash describes a product, and has the following items: +C<id>, C<name>, C<description>, and C<internals>. The C<id> item is +the id of the product. The C<name> item is the name of the +product. The C<description> is the description of the +product. Finally, the C<internals> is an internal representation of +the product. + +Note, that if the user tries to access a product that is not in the +list of accessible products for the user, or a product that does not +exist, that is silently ignored, and no information about that product +is returned. + +=item B<Errors> (none) + +=back + +=back + diff --git a/Bugzilla/WebService/User.pm b/Bugzilla/WebService/User.pm new file mode 100755 index 000000000..db02ff75a --- /dev/null +++ b/Bugzilla/WebService/User.pm @@ -0,0 +1,298 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Marc Schumann <wurblzap@gmail.com> +# Max Kanat-Alexander <mkanat@bugzilla.org> +# Mads Bondo Dydensborg <mbd@dbc.dk> + +package Bugzilla::WebService::User; + +use strict; +use base qw(Bugzilla::WebService); + +import SOAP::Data qw(type); + +use Bugzilla; +use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::User; +use Bugzilla::Util qw(trim); +use Bugzilla::Token; + +############## +# User Login # +############## + +sub login { + my ($self, $params) = @_; + my $remember = $params->{remember}; + + # Convert $remember from a boolean 0/1 value to a CGI-compatible one. + if (defined($remember)) { + $remember = $remember? 'on': ''; + } + else { + # Use Bugzilla's default if $remember is not supplied. + $remember = + Bugzilla->params->{'rememberlogin'} eq 'defaulton'? 'on': ''; + } + + # Make sure the CGI user info class works if necessary. + my $cgi = Bugzilla->cgi; + $cgi->param('Bugzilla_login', $params->{login}); + $cgi->param('Bugzilla_password', $params->{password}); + $cgi->param('Bugzilla_remember', $remember); + + Bugzilla->login; + return { id => type('int')->value(Bugzilla->user->id) }; +} + +sub logout { + my $self = shift; + Bugzilla->logout; + return undef; +} + +################# +# User Creation # +################# + +sub offer_account_by_email { + my $self = shift; + my ($params) = @_; + my $email = trim($params->{email}) + || ThrowCodeError('param_required', { param => 'email' }); + + $email = Bugzilla::User->check_login_name_for_creation($email); + + # Create and send a token for this new account. + Bugzilla::Token::issue_new_user_account_token($email); + + return undef; +} + +sub create { + my $self = shift; + my ($params) = @_; + + Bugzilla->user->in_group('editusers') + || ThrowUserError("auth_failure", { group => "editusers", + action => "add", + object => "users"}); + + my $email = trim($params->{email}) + || ThrowCodeError('param_required', { param => 'email' }); + my $realname = trim($params->{full_name}); + my $password = trim($params->{password}) || '*'; + + my $user = Bugzilla::User->create({ + login_name => $email, + realname => $realname, + cryptpassword => $password + }); + + return { id => type('int')->value($user->id) }; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Webservice::User - The User Account and Login API + +=head1 DESCRIPTION + +This part of the Bugzilla API allows you to create User Accounts and +log in/out using an existing account. + +=head1 METHODS + +See L<Bugzilla::WebService> for a description of what B<STABLE>, B<UNSTABLE>, +and B<EXPERIMENTAL> mean, and for more information about error codes. + +=head2 Logging In and Out + +=over + +=item C<login> B<EXPERIMENTAL> + +=over + +=item B<Description> + +Logging in, with a username and password, is required for many +Bugzilla installations, in order to search for bugs, post new bugs, +etc. This method logs in an user. + +=item B<Params> + +=over + +=item C<login> (string) - The user's login name. + +=item C<password> (string) - The user's password. + +=item C<remember> (bool) B<Optional> - if the cookies returned by the +call to login should expire with the session or not. In order for +this option to have effect the Bugzilla server must be configured to +allow the user to set this option - the Bugzilla parameter +I<rememberlogin> must be set to "defaulton" or +"defaultoff". Addionally, the client application must implement +management of cookies across sessions. + +=back + +=item B<Returns> + +On success, a hash containing one item, C<id>, the numeric id of the +user that was logged in. A set of http cookies is also sent with the +response. These cookies must be sent along with any future requests +to the webservice, for the duration of the session. + +=item B<Errors> + +=over + +=item 300 (Invalid Username or Password) + +The username does not exist, or the password is wrong. + +=item 301 (Account Disabled) + +The account has been disabled. A reason may be specified with the +error. + +=back + +=back + +=item C<logout> B<EXPERIMENTAL> + +=over + +=item B<Description> + +Log out the user. Does nothing if there is no user logged in. + +=item B<Params> (none) + +=item B<Returns> (nothing) + +=item B<Errors> (none) + +=back + +=back + +=head2 Account Creation + +=over + +=item C<offer_account_by_email> B<EXPERIMENTAL> + +=over + +=item B<Description> + +Sends an email to the user, offering to create an account. The user +will have to click on a URL in the email, and choose their password +and real name. + +This is the recommended way to create a Bugzilla account. + +=item B<Param> + +=over + +=item C<email> (string) - the email to send the offer to. + +=back + +=item B<Returns> (nothing) + +=item B<Errors> + +=over + +=item 500 (Illegal Email Address) + +This Bugzilla does not allow you to create accounts with the format of +email address you specified. Account creation may be entirely disabled. + +=item 501 (Account Already Exists) + +An account with that email address already exists in Bugzilla. + +=back + +=back + +=item C<create> B<EXPERIMENTAL> + +=over + +=item B<Description> + +Creates a user account directly in Bugzilla, password and all. +Instead of this, you should use L</offer_account_by_email> when +possible, because that makes sure that the email address specified can +actually receive an email. This function does not check that. + +=item B<Params> + +=over + +=item C<email> (string) - The email address for the new user. + +=item C<full_name> (string) B<Optional> - The user's full name. Will +be set to empty if not specified. + +=item C<password> (string) B<Optional> - The password for the new user +account, in plain text. It will be stripped of leading and trailing +whitespace. If blank or not specified, the newly created account will +exist in Bugzilla, but will not be allowed to log in using DB +authentication until a password is set either by the user (through +resetting their password) or by the administrator. + +=back + +=item B<Returns> + +A hash containing one item, C<id>, the numeric id of the user that was +created. + +=item B<Errors> + +The same as L</offer_account_by_email>. If a password is specified, +the function may also throw: + +=over + +=item 502 (Password Too Short) + +The password specified is too short. (Usually, this means the +password is under three characters.) + +=item 503 (Password Too Long) + +The password specified is too long. (Usually, this means the +password is over ten characters.) + +=back + +=back + +=back diff --git a/CVS/Entries b/CVS/Entries index 83ce93ee4..f6b246153 100644 --- a/CVS/Entries +++ b/CVS/Entries @@ -1,68 +1,72 @@ -/.cvsignore/1.6/Mon May 13 22:28:26 2002//TBUGZILLA-2_22_3 -/Bugzilla.pm/1.29.2.2/Tue Aug 8 20:53:40 2006//TBUGZILLA-2_22_3 -/QUICKSTART/1.6.2.1/Sun Jul 29 18:14:14 2007//TBUGZILLA-2_22_3 -/README/1.52/Fri Oct 10 02:22:39 2003//TBUGZILLA-2_22_3 -/UPGRADING/1.1/Fri Aug 10 22:35:21 2001//TBUGZILLA-2_22_3 -/UPGRADING-pre-2.8/1.3/Thu Mar 27 00:06:37 2003//TBUGZILLA-2_22_3 -/attachment.cgi/1.103.2.2/Sat Oct 14 21:07:19 2006//TBUGZILLA-2_22_3 -/buglist.cgi/1.325.2.3/Wed Aug 9 01:30:53 2006//TBUGZILLA-2_22_3 -/bugzilla.dtd/1.13/Tue Jan 10 23:30:33 2006//TBUGZILLA-2_22_3 -/chart.cgi/1.17/Sun Oct 30 21:31:27 2005//TBUGZILLA-2_22_3 -/checksetup.pl/1.469.2.18/Sun Jul 22 22:25:15 2007//TBUGZILLA-2_22_3 -/colchange.cgi/1.51/Mon Oct 24 23:11:55 2005//TBUGZILLA-2_22_3 -/collectstats.pl/1.46.2.1/Mon Aug 20 18:09:47 2007//TBUGZILLA-2_22_3 -/config.cgi/1.14/Mon Oct 24 23:11:55 2005//TBUGZILLA-2_22_3 -/createaccount.cgi/1.46/Tue Dec 20 22:16:07 2005//TBUGZILLA-2_22_3 -/describecomponents.cgi/1.33/Wed Oct 26 16:15:48 2005//TBUGZILLA-2_22_3 -/describekeywords.cgi/1.17/Wed Oct 26 16:15:50 2005//TBUGZILLA-2_22_3 -/duplicates.cgi/1.51.2.1/Mon Jun 19 12:16:05 2006//TBUGZILLA-2_22_3 -/duplicates.xul/1.2/Thu Oct 21 19:02:28 2004//TBUGZILLA-2_22_3 -/editclassifications.cgi/1.18.2.1/Sat Oct 14 22:05:54 2006//TBUGZILLA-2_22_3 -/editcomponents.cgi/1.68.2.1/Sat Oct 14 22:05:54 2006//TBUGZILLA-2_22_3 -/editflagtypes.cgi/1.31.2.1/Sat Oct 14 22:05:54 2006//TBUGZILLA-2_22_3 -/editgroups.cgi/1.65.2.4/Sat Oct 14 22:05:54 2006//TBUGZILLA-2_22_3 -/editkeywords.cgi/1.35.2.2/Sat Oct 14 22:05:54 2006//TBUGZILLA-2_22_3 -/editmilestones.cgi/1.49.2.1/Sat Oct 14 22:05:54 2006//TBUGZILLA-2_22_3 -/editparams.cgi/1.32.2.2/Sat Oct 14 22:05:54 2006//TBUGZILLA-2_22_3 -/editproducts.cgi/1.110.2.4/Sat Oct 14 22:05:54 2006//TBUGZILLA-2_22_3 -/editsettings.cgi/1.6.2.1/Sat Oct 14 22:05:54 2006//TBUGZILLA-2_22_3 -/editusers.cgi/1.113.2.1/Sat Oct 14 22:05:54 2006//TBUGZILLA-2_22_3 -/editvalues.cgi/1.9.2.2/Sat Oct 14 22:05:55 2006//TBUGZILLA-2_22_3 -/editversions.cgi/1.44.2.2/Sat Oct 14 22:05:55 2006//TBUGZILLA-2_22_3 -/editwhines.cgi/1.13.2.1/Sat Oct 14 22:05:55 2006//TBUGZILLA-2_22_3 -/enter_bug.cgi/1.126.2.2/Mon Aug 21 19:26:06 2006//TBUGZILLA-2_22_3 -/globals.pl/1.348.2.5/Sat Oct 14 20:30:53 2006//TBUGZILLA-2_22_3 -/importxml.pl/1.47.2.9/Tue Feb 6 14:58:42 2007//TBUGZILLA-2_22_3 -/index.cgi/1.17/Sun Oct 30 21:31:27 2005//TBUGZILLA-2_22_3 -/long_list.cgi/1.47/Tue Oct 25 19:31:31 2005//TBUGZILLA-2_22_3 -/page.cgi/1.18/Mon Oct 24 23:11:55 2005//TBUGZILLA-2_22_3 -/post_bug.cgi/1.135.2.5/Sun Jan 28 21:20:45 2007//TBUGZILLA-2_22_3 -/process_bug.cgi/1.302.2.5/Thu Jan 4 23:37:19 2007//TBUGZILLA-2_22_3 -/productmenu.js/1.3/Sun Aug 21 20:05:39 2005//TBUGZILLA-2_22_3 -/query.cgi/1.155.2.1/Thu Mar 30 22:23:06 2006//TBUGZILLA-2_22_3 -/quips.cgi/1.32/Sun Oct 30 21:31:28 2005//TBUGZILLA-2_22_3 -/relogin.cgi/1.32.2.3/Sat Oct 14 22:05:55 2006//TBUGZILLA-2_22_3 -/report.cgi/1.37/Fri Dec 2 20:48:03 2005//TBUGZILLA-2_22_3 -/reports.cgi/1.80.2.1/Sat Jun 3 19:53:59 2006//TBUGZILLA-2_22_3 -/request.cgi/1.29.2.2/Sat Oct 14 21:07:19 2006//TBUGZILLA-2_22_3 -/robots.txt/1.2/Wed Apr 24 18:11:00 2002//TBUGZILLA-2_22_3 -/runtests.pl/1.4/Fri Sep 3 06:59:08 2004//TBUGZILLA-2_22_3 -/sanitycheck.cgi/1.110.2.4/Sun Jul 22 22:25:15 2007//TBUGZILLA-2_22_3 -/show_activity.cgi/1.20/Fri Jan 6 14:38:35 2006//TBUGZILLA-2_22_3 -/show_bug.cgi/1.38.2.1/Sat Oct 14 21:45:51 2006//TBUGZILLA-2_22_3 -/showattachment.cgi/1.14/Mon May 5 01:15:29 2003//TBUGZILLA-2_22_3 -/showdependencygraph.cgi/1.48.2.2/Fri Oct 20 23:22:38 2006//TBUGZILLA-2_22_3 -/showdependencytree.cgi/1.40.2.1/Wed Oct 11 22:40:31 2006//TBUGZILLA-2_22_3 -/sidebar.cgi/1.16/Mon Oct 24 23:11:55 2005//TBUGZILLA-2_22_3 -/summarize_time.cgi/1.13.2.1/Wed Apr 12 22:49:11 2006//TBUGZILLA-2_22_3 -/testagent.cgi/1.2/Thu Jul 22 07:05:05 2004//TBUGZILLA-2_22_3 -/testserver.pl/1.9.2.2/Tue Jul 25 06:21:07 2006//TBUGZILLA-2_22_3 -/token.cgi/1.39.2.2/Fri Sep 22 23:25:51 2006//TBUGZILLA-2_22_3 -/userprefs.cgi/1.95/Tue Dec 20 22:25:57 2005//TBUGZILLA-2_22_3 -/votes.cgi/1.34.2.2/Fri Oct 13 13:01:57 2006//TBUGZILLA-2_22_3 -/whine.pl/1.22.2.1/Mon Feb 27 23:12:33 2006//TBUGZILLA-2_22_3 -/whineatnews.pl/1.20/Mon Aug 15 17:58:10 2005//TBUGZILLA-2_22_3 -/xml.cgi/1.13/Wed Aug 10 01:30:39 2005//TBUGZILLA-2_22_3 +/.cvsignore/1.7/Tue Mar 28 19:49:01 2006//TBUGZILLA-3_0 +/Bugzilla.pm/1.55.2.1/Fri Mar 16 20:17:49 2007//TBUGZILLA-3_0 +/QUICKSTART/1.6/Mon Dec 26 19:43:57 2005//TBUGZILLA-3_0 +/README/1.52/Fri Oct 10 02:22:39 2003//TBUGZILLA-3_0 +/UPGRADING/1.1/Fri Aug 10 22:35:21 2001//TBUGZILLA-3_0 +/UPGRADING-pre-2.8/1.3/Thu Mar 27 00:06:37 2003//TBUGZILLA-3_0 +/attachment.cgi/1.126/Sun Jan 21 15:11:52 2007//TBUGZILLA-3_0 +/buglist.cgi/1.351.2.1/Wed Feb 28 14:00:52 2007//TBUGZILLA-3_0 +/bugzilla.dtd/1.15/Sat Jan 6 23:51:56 2007//TBUGZILLA-3_0 +/chart.cgi/1.23/Sun Jan 7 23:58:21 2007//TBUGZILLA-3_0 +/checksetup.pl/1.547/Sat Dec 9 11:51:33 2006//TBUGZILLA-3_0 +/colchange.cgi/1.58/Mon Sep 4 16:21:47 2006//TBUGZILLA-3_0 +/collectstats.pl/1.58.2.1/Mon Mar 12 17:04:11 2007//TBUGZILLA-3_0 +/config.cgi/1.24/Tue Oct 17 04:41:05 2006//TBUGZILLA-3_0 +/createaccount.cgi/1.54/Tue Sep 5 19:18:26 2006//TBUGZILLA-3_0 +/describecomponents.cgi/1.37/Wed Dec 27 07:37:20 2006//TBUGZILLA-3_0 +/describekeywords.cgi/1.20/Mon Sep 4 16:21:47 2006//TBUGZILLA-3_0 +/duplicates.cgi/1.59/Thu Jul 6 06:12:04 2006//TBUGZILLA-3_0 +/duplicates.xul/1.2/Thu Oct 21 19:02:28 2004//TBUGZILLA-3_0 +/editclassifications.cgi/1.26/Sat Oct 14 22:02:09 2006//TBUGZILLA-3_0 +/editcomponents.cgi/1.80/Tue Dec 19 06:39:28 2006//TBUGZILLA-3_0 +/editfields.cgi/1.7/Mon Nov 13 02:50:16 2006//TBUGZILLA-3_0 +/editflagtypes.cgi/1.49/Thu Jan 4 17:48:16 2007//TBUGZILLA-3_0 +/editgroups.cgi/1.82/Fri Oct 20 21:16:53 2006//TBUGZILLA-3_0 +/editkeywords.cgi/1.43/Sat Oct 14 22:02:09 2006//TBUGZILLA-3_0 +/editmilestones.cgi/1.57/Tue Dec 19 10:35:42 2006//TBUGZILLA-3_0 +/editparams.cgi/1.43/Mon Dec 11 18:00:46 2006//TBUGZILLA-3_0 +/editproducts.cgi/1.132/Tue Dec 19 10:35:42 2006//TBUGZILLA-3_0 +/editsettings.cgi/1.9/Sat Oct 14 22:02:09 2006//TBUGZILLA-3_0 +/editusers.cgi/1.141/Fri Nov 10 16:51:27 2006//TBUGZILLA-3_0 +/editvalues.cgi/1.19/Sat Oct 14 22:02:09 2006//TBUGZILLA-3_0 +/editversions.cgi/1.53/Fri Nov 10 16:51:27 2006//TBUGZILLA-3_0 +/editwhines.cgi/1.20/Sat Oct 14 22:02:09 2006//TBUGZILLA-3_0 +/email_in.pl/1.5/Sat Jan 6 14:14:59 2007//TBUGZILLA-3_0 +/enter_bug.cgi/1.154/Sun Jan 14 01:42:40 2007//TBUGZILLA-3_0 +/importxml.pl/1.74.2.1/Tue Apr 3 23:55:52 2007//TBUGZILLA-3_0 +/index.cgi/1.23/Mon Aug 21 21:27:41 2006//TBUGZILLA-3_0 +/long_list.cgi/1.47/Tue Oct 25 19:31:31 2005//TBUGZILLA-3_0 +/mod_perl.pl/1.5/Sun Feb 25 02:43:24 2007//TBUGZILLA-3_0 +/page.cgi/1.19/Wed Jun 21 00:44:47 2006//TBUGZILLA-3_0 +/post_bug.cgi/1.183.2.1/Tue Mar 6 11:43:01 2007//TBUGZILLA-3_0 +/process_bug.cgi/1.351.2.1/Sat Mar 10 12:22:14 2007//TBUGZILLA-3_0 +/productmenu.js/1.3/Sun Aug 21 20:05:39 2005//TBUGZILLA-3_0 +/query.cgi/1.172/Fri Dec 29 23:41:34 2006//TBUGZILLA-3_0 +/quips.cgi/1.37/Mon Sep 4 16:21:47 2006//TBUGZILLA-3_0 +/relogin.cgi/1.39/Sat Oct 14 22:02:09 2006//TBUGZILLA-3_0 +/report.cgi/1.39/Wed Jun 21 00:44:47 2006//TBUGZILLA-3_0 +/reports.cgi/1.89/Thu Aug 3 17:54:04 2006//TBUGZILLA-3_0 +/request.cgi/1.41/Sat Oct 14 21:04:55 2006//TBUGZILLA-3_0 +/robots.txt/1.2/Wed Apr 24 18:11:00 2002//TBUGZILLA-3_0 +/runtests.pl/1.4/Fri Sep 3 06:59:08 2004//TBUGZILLA-3_0 +/sanitycheck.cgi/1.127/Tue Dec 26 20:17:25 2006//TBUGZILLA-3_0 +/search_plugin.cgi/1.2/Thu Sep 28 22:19:33 2006//TBUGZILLA-3_0 +/show_activity.cgi/1.22/Wed Jun 21 00:44:48 2006//TBUGZILLA-3_0 +/show_bug.cgi/1.50/Wed Dec 27 01:21:32 2006//TBUGZILLA-3_0 +/showattachment.cgi/1.15/Wed Mar 1 22:46:21 2006//TBUGZILLA-3_0 +/showdependencygraph.cgi/1.56/Sat Dec 16 01:47:12 2006//TBUGZILLA-3_0 +/showdependencytree.cgi/1.49/Fri Oct 20 20:50:30 2006//TBUGZILLA-3_0 +/sidebar.cgi/1.18/Wed Jun 21 00:44:48 2006//TBUGZILLA-3_0 +/summarize_time.cgi/1.21/Mon Sep 4 16:21:47 2006//TBUGZILLA-3_0 +/testagent.cgi/1.3/Sun Feb 11 00:12:24 2007//TBUGZILLA-3_0 +/testserver.pl/1.16/Sun Feb 11 00:12:24 2007//TBUGZILLA-3_0 +/token.cgi/1.48/Fri Oct 20 18:52:24 2006//TBUGZILLA-3_0 +/userprefs.cgi/1.112/Sun Jan 7 23:58:21 2007//TBUGZILLA-3_0 +/votes.cgi/1.50/Fri Oct 13 12:59:57 2006//TBUGZILLA-3_0 +/whine.pl/1.32/Sun Oct 22 00:46:21 2006//TBUGZILLA-3_0 +/whineatnews.pl/1.27/Sun Jul 30 03:50:24 2006//TBUGZILLA-3_0 +/xml.cgi/1.13/Wed Aug 10 01:30:39 2005//TBUGZILLA-3_0 +/xmlrpc.cgi/1.2/Sun Feb 4 16:23:20 2007//TBUGZILLA-3_0 D/Bugzilla//// D/contrib//// D/docs//// diff --git a/CVS/Tag b/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/CVS/Tag +++ b/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/QUICKSTART b/QUICKSTART index 86d11317d..7da834b17 100644 --- a/QUICKSTART +++ b/QUICKSTART @@ -9,16 +9,16 @@ and a Sendmail compatible MTA are available. For other configurations, please see Section 4 of the Bugzilla Guide in the docs/ directory. 1. Decide from which URL and directory under your webserver root you - will be serving the Bugzilla webpages. + will be serving the Bugzilla webpages from. -2. Unpack the distribution into the chosen directory (there is no copying or +2. Unpack distribution into the chosen directory (there is no copying or installation involved). -3. Run ./checksetup.pl, look for unsolved requirements, and install them. +3. Run ./checksetup.pl, look for unsolved requirements, install them. You can run checksetup as many times as necessary to check if - everything required has been installed. + everything required is installed. - These will usually include assorted Perl modules, MySQL or PostgreSQL, + This will usually include assorted Perl modules, MySQL or PostgreSQL, and a MTA. After a successful dependency check, checksetup should complain that @@ -41,7 +41,7 @@ see Section 4 of the Bugzilla Guide in the docs/ directory. in the Bugzilla Guide or PostgreSQL documentation. 6. Run checksetup.pl once more; if all goes well, it should set up the - Bugzilla database for you. If not, return to step 5. + Bugzilla database for you. If not, move back to step 5. checksetup.pl should ask you, this time, for the administrator's email address and password. These will be used for the initial diff --git a/attachment.cgi b/attachment.cgi index fe755e843..578adfac0 100755 --- a/attachment.cgi +++ b/attachment.cgi @@ -26,6 +26,7 @@ # Max Kanat-Alexander <mkanat@bugzilla.org> # Greg Hendricks <ghendricks@novell.com> # Frédéric Buclin <LpSolit@gmail.com> +# Marc Schumann <wurblzap@gmail.com> ################################################################################ # Script Initialization @@ -36,12 +37,9 @@ use strict; use lib qw(.); -# Include the Bugzilla CGI and general utility library. -require "globals.pl"; - use Bugzilla; -use Bugzilla::Config qw(:locations); use Bugzilla::Constants; +use Bugzilla::Error; use Bugzilla::Flag; use Bugzilla::FlagType; use Bugzilla::User; @@ -49,13 +47,18 @@ use Bugzilla::Util; use Bugzilla::Bug; use Bugzilla::Field; use Bugzilla::Attachment; +use Bugzilla::Attachment::PatchReader; +use Bugzilla::Token; Bugzilla->login(); -my $cgi = Bugzilla->cgi; -my $dbh = Bugzilla->dbh; -my $template = Bugzilla->template; -my $vars = {}; +# For most scripts we don't make $cgi and $template global variables. But +# when preparing Bugzilla for mod_perl, this script used these +# variables in so many subroutines that it was easier to just +# make them globals. +local our $cgi = Bugzilla->cgi; +local our $template = Bugzilla->template; +local our $vars = {}; ################################################################################ # Main Body Execution @@ -104,6 +107,9 @@ elsif ($action eq "update") Bugzilla->login(LOGIN_REQUIRED); update(); } +elsif ($action eq "delete") { + delete_attachment(); +} else { ThrowCodeError("unknown_action", { action => $action }); @@ -130,6 +136,7 @@ exit; sub validateID { my $param = @_ ? $_[0] : 'id'; + my $dbh = Bugzilla->dbh; my $user = Bugzilla->user; # If we're not doing interdiffs, check if id wasn't specified and @@ -152,21 +159,22 @@ sub validateID || ThrowUserError("invalid_attach_id", { attach_id => $cgi->param($param) }); # Make sure the attachment exists in the database. - SendSQL("SELECT bug_id, isprivate, submitter_id - FROM attachments WHERE attach_id = $attach_id"); - MoreSQLData() - || ThrowUserError("invalid_attach_id", { attach_id => $attach_id }); + my ($bugid, $isprivate, $submitter_id) = $dbh->selectrow_array( + "SELECT bug_id, isprivate, submitter_id + FROM attachments + WHERE attach_id = ?", + undef, $attach_id); + ThrowUserError("invalid_attach_id", { attach_id => $attach_id }) + unless $bugid; # Make sure the user is authorized to access this attachment's bug. - my ($bugid, $isprivate, $submitter_id) = FetchSQLData(); - ValidateBugID($bugid); if ($isprivate && $user->id != $submitter_id && !$user->is_insider) { - ThrowUserError("auth_failure", {action => "access", - object => "attachment"}); + ThrowUserError('auth_failure', {action => 'access', + object => 'attachment'}); } - return ($attach_id,$bugid); + return ($attach_id, $bugid); } # Validates format of a diff/interdiff. Takes a list as an parameter, which @@ -197,37 +205,17 @@ sub validateContext return $context; } -sub validateCanEdit -{ - my ($attach_id) = (@_); - my $user = Bugzilla->user; - - my $attachment = Bugzilla::Attachment->get($attach_id); - - # Bug 97729 - the submitter can edit their attachments - return if ($attachment->attacher->id == $user->id); - - # Only people in the insider group can view private attachments. - if ($attachment->isprivate && !$user->is_insider) { - ThrowUserError('illegal_attachment_edit', {attach_id => $attachment->id}); - } - - # People in editbugs can edit all attachments - return if UserInGroup("editbugs"); - - # If we come here, then this attachment cannot be seen by the user. - ThrowUserError('illegal_attachment_edit', { attach_id => $attachment->id }); -} - sub validateCanChangeAttachment { my ($attachid) = @_; - SendSQL("SELECT product_id + my $dbh = Bugzilla->dbh; + my ($productid) = $dbh->selectrow_array( + "SELECT product_id FROM attachments INNER JOIN bugs ON bugs.bug_id = attachments.bug_id - WHERE attach_id = $attachid"); - my $productid = FetchOneColumn(); + WHERE attach_id = ?", undef, $attachid); + Bugzilla->user->can_edit_product($productid) || ThrowUserError("illegal_attachment_edit", { attach_id => $attachid }); @@ -236,73 +224,17 @@ sub validateCanChangeAttachment sub validateCanChangeBug { my ($bugid) = @_; - SendSQL("SELECT product_id + my $dbh = Bugzilla->dbh; + my ($productid) = $dbh->selectrow_array( + "SELECT product_id FROM bugs - WHERE bug_id = $bugid"); - my $productid = FetchOneColumn(); + WHERE bug_id = ?", undef, $bugid); + Bugzilla->user->can_edit_product($productid) || ThrowUserError("illegal_attachment_edit_bug", { bug_id => $bugid }); } -sub validateDescription -{ - $cgi->param('description') - || ThrowUserError("missing_attachment_description"); -} - -sub validateIsPatch -{ - # Set the ispatch flag to zero if it is undefined, since the UI uses - # an HTML checkbox to represent this flag, and unchecked HTML checkboxes - # do not get sent in HTML requests. - $cgi->param('ispatch', $cgi->param('ispatch') ? 1 : 0); - - # Set the content type to text/plain if the attachment is a patch. - $cgi->param('contenttype', 'text/plain') if $cgi->param('ispatch'); -} - -sub validateContentType -{ - if (!defined $cgi->param('contenttypemethod')) - { - ThrowUserError("missing_content_type_method"); - } - elsif ($cgi->param('contenttypemethod') eq 'autodetect') - { - my $contenttype = $cgi->uploadInfo($cgi->param('data'))->{'Content-Type'}; - # The user asked us to auto-detect the content type, so use the type - # specified in the HTTP request headers. - if ( !$contenttype ) - { - ThrowUserError("missing_content_type"); - } - $cgi->param('contenttype', $contenttype); - } - elsif ($cgi->param('contenttypemethod') eq 'list') - { - # The user selected a content type from the list, so use their selection. - $cgi->param('contenttype', $cgi->param('contenttypeselection')); - } - elsif ($cgi->param('contenttypemethod') eq 'manual') - { - # The user entered a content type manually, so use their entry. - $cgi->param('contenttype', $cgi->param('contenttypeentry')); - } - else - { - ThrowCodeError("illegal_content_type_method", - { contenttypemethod => $cgi->param('contenttypemethod') }); - } - - if ( $cgi->param('contenttype') !~ - /^(application|audio|image|message|model|multipart|text|video)\/.+$/ ) - { - ThrowUserError("invalid_content_type", - { contenttype => $cgi->param('contenttype') }); - } -} - sub validateIsObsolete { # Set the isobsolete flag to zero if it is undefined, since the UI uses @@ -319,128 +251,6 @@ sub validatePrivate $cgi->param('isprivate', $cgi->param('isprivate') ? 1 : 0); } -sub validateData -{ - my $maxsize = $cgi->param('ispatch') ? Param('maxpatchsize') : Param('maxattachmentsize'); - $maxsize *= 1024; # Convert from K - my $fh; - # Skip uploading into a local variable if the user wants to upload huge - # attachments into local files. - if (!$cgi->param('bigfile')) - { - $fh = $cgi->upload('data'); - } - my $data; - - # We could get away with reading only as much as required, except that then - # we wouldn't have a size to print to the error handler below. - if (!$cgi->param('bigfile')) - { - # enable 'slurp' mode - local $/; - $data = <$fh>; - } - - $data - || ($cgi->param('bigfile')) - || ThrowUserError("zero_length_file"); - - # Windows screenshots are usually uncompressed BMP files which - # makes for a quick way to eat up disk space. Let's compress them. - # We do this before we check the size since the uncompressed version - # could easily be greater than maxattachmentsize. - if (Param('convert_uncompressed_images') && $cgi->param('contenttype') eq 'image/bmp'){ - require Image::Magick; - my $img = Image::Magick->new(magick=>'bmp'); - $img->BlobToImage($data); - $img->set(magick=>'png'); - my $imgdata = $img->ImageToBlob(); - $data = $imgdata; - $cgi->param('contenttype', 'image/png'); - $vars->{'convertedbmp'} = 1; - } - - # Make sure the attachment does not exceed the maximum permitted size - my $len = $data ? length($data) : 0; - if ($maxsize && $len > $maxsize) { - my $vars = { filesize => sprintf("%.0f", $len/1024) }; - if ($cgi->param('ispatch')) { - ThrowUserError("patch_too_large", $vars); - } else { - ThrowUserError("file_too_large", $vars); - } - } - - return $data || ''; -} - -sub validateFilename -{ - defined $cgi->upload('data') - || ThrowUserError("file_not_specified"); - - my $filename = $cgi->upload('data'); - - # Remove path info (if any) from the file name. The browser should do this - # for us, but some are buggy. This may not work on Mac file names and could - # mess up file names with slashes in them, but them's the breaks. We only - # use this as a hint to users downloading attachments anyway, so it's not - # a big deal if it munges incorrectly occasionally. - $filename =~ s/^.*[\/\\]//; - - # Truncate the filename to 100 characters, counting from the end of the string - # to make sure we keep the filename extension. - $filename = substr($filename, -100, 100); - - return $filename; -} - -sub validateObsolete -{ - my @obsolete_ids = (); - - # Make sure the attachment id is valid and the user has permissions to view - # the bug to which it is attached. Make sure also that the user can view - # the attachment itself. - foreach my $attachid ($cgi->param('obsolete')) { - my $vars = {}; - $vars->{'attach_id'} = $attachid; - - detaint_natural($attachid) - || ThrowCodeError("invalid_attach_id_to_obsolete", $vars); - - SendSQL("SELECT bug_id, isobsolete, description - FROM attachments WHERE attach_id = $attachid"); - - # Make sure the attachment exists in the database. - MoreSQLData() - || ThrowUserError("invalid_attach_id", $vars); - - my ($bugid, $isobsolete, $description) = FetchSQLData(); - - # Check that the user can modify this attachment - validateCanEdit($attachid); - - $vars->{'description'} = $description; - - if ($bugid != $cgi->param('bugid')) - { - $vars->{'my_bug_id'} = $cgi->param('bugid'); - $vars->{'attach_bug_id'} = $bugid; - ThrowCodeError("mismatched_bug_ids_on_obsolete", $vars); - } - - if ( $isobsolete ) - { - ThrowCodeError("attachment_already_obsolete", $vars); - } - - push(@obsolete_ids, $attachid); - } - - return @obsolete_ids; -} - # Returns 1 if the parameter is a content-type viewable in this browser # Note that we don't use $cgi->Accept()'s ability to check if a content-type # matches, because this will return a value even if it's matched by the generic @@ -482,12 +292,13 @@ sub view { # Retrieve and validate parameters my ($attach_id) = validateID(); - + my $dbh = Bugzilla->dbh; + # Retrieve the attachment content and its content type from the database. - SendSQL("SELECT mimetype, filename, thedata FROM attachments " . + my ($contenttype, $filename, $thedata) = $dbh->selectrow_array( + "SELECT mimetype, filename, thedata FROM attachments " . "INNER JOIN attach_data ON id = attach_id " . - "WHERE attach_id = $attach_id"); - my ($contenttype, $filename, $thedata) = FetchSQLData(); + "WHERE attach_id = ?", undef, $attach_id); # Bug 111522: allow overriding content-type manually in the posted form # params. @@ -495,7 +306,7 @@ sub view { $cgi->param('contenttypemethod', 'manual'); $cgi->param('contenttypeentry', $cgi->param('content_type')); - validateContentType(); + Bugzilla::Attachment->validate_content_type(THROW_ERROR); $contenttype = $cgi->param('content_type'); } @@ -508,7 +319,7 @@ sub view { my $hash = ($attach_id % 100) + 100; $hash =~ s/.*(\d\d)$/group.$1/; - if (open(AH, "$attachdir/$hash/attachment.$attach_id")) { + if (open(AH, bz_locations()->{'attachdir'} . "/$hash/attachment.$attach_id")) { binmode AH; $filesize = (stat(AH))[7]; } @@ -538,301 +349,63 @@ sub view } -sub interdiff -{ - # Retrieve and validate parameters - my ($old_id) = validateID('oldid'); - my ($new_id) = validateID('newid'); - my $format = validateFormat('html', 'raw'); - my $context = validateContext(); - - # Get old patch data - my ($old_bugid, $old_description, $old_filename, $old_file_list) = - get_unified_diff($old_id); - - # Get new patch data - my ($new_bugid, $new_description, $new_filename, $new_file_list) = - get_unified_diff($new_id); - - my $warning = warn_if_interdiff_might_fail($old_file_list, $new_file_list); - - # - # send through interdiff, send output directly to template - # - # Must hack path so that interdiff will work. - # - $ENV{'PATH'} = $::diffpath; - open my $interdiff_fh, "$::interdiffbin $old_filename $new_filename|"; - binmode $interdiff_fh; - my ($reader, $last_reader) = setup_patch_readers("", $context); - if ($format eq 'raw') - { - require PatchReader::DiffPrinter::raw; - $last_reader->sends_data_to(new PatchReader::DiffPrinter::raw()); - # Actually print out the patch - print $cgi->header(-type => 'text/plain', - -expires => '+3M'); - } - else - { - $vars->{warning} = $warning if $warning; - $vars->{bugid} = $new_bugid; - $vars->{oldid} = $old_id; - $vars->{old_desc} = $old_description; - $vars->{newid} = $new_id; - $vars->{new_desc} = $new_description; - delete $vars->{attachid}; - delete $vars->{do_context}; - delete $vars->{context}; - setup_template_patch_reader($last_reader, $format, $context); - } - $reader->iterate_fh($interdiff_fh, "interdiff #$old_id #$new_id"); - close $interdiff_fh; - $ENV{'PATH'} = ''; - - # - # Delete temporary files - # - unlink($old_filename) or warn "Could not unlink $old_filename: $!"; - unlink($new_filename) or warn "Could not unlink $new_filename: $!"; -} - -sub get_unified_diff -{ - my ($id) = @_; - - # Bring in the modules we need - require PatchReader::Raw; - require PatchReader::FixPatchRoot; - require PatchReader::DiffPrinter::raw; - require PatchReader::PatchInfoGrabber; - require File::Temp; - - # Get the patch - SendSQL("SELECT bug_id, description, ispatch, thedata " . - "FROM attachments " . - "INNER JOIN attach_data " . - "ON id = attach_id " . - "WHERE attach_id = $id"); - my ($bugid, $description, $ispatch, $thedata) = FetchSQLData(); - if (!$ispatch) { - $vars->{'attach_id'} = $id; - ThrowCodeError("must_be_patch"); - } - - # Reads in the patch, converting to unified diff in a temp file - my $reader = new PatchReader::Raw; - my $last_reader = $reader; - - # fixes patch root (makes canonical if possible) - if (Param('cvsroot')) { - my $fix_patch_root = new PatchReader::FixPatchRoot(Param('cvsroot')); - $last_reader->sends_data_to($fix_patch_root); - $last_reader = $fix_patch_root; - } - - # Grabs the patch file info - my $patch_info_grabber = new PatchReader::PatchInfoGrabber(); - $last_reader->sends_data_to($patch_info_grabber); - $last_reader = $patch_info_grabber; - - # Prints out to temporary file - my ($fh, $filename) = File::Temp::tempfile(); - my $raw_printer = new PatchReader::DiffPrinter::raw($fh); - $last_reader->sends_data_to($raw_printer); - $last_reader = $raw_printer; - - # Iterate! - $reader->iterate_string($id, $thedata); - - return ($bugid, $description, $filename, $patch_info_grabber->patch_info()->{files}); -} - -sub warn_if_interdiff_might_fail { - my ($old_file_list, $new_file_list) = @_; - # Verify that the list of files diffed is the same - my @old_files = sort keys %{$old_file_list}; - my @new_files = sort keys %{$new_file_list}; - if (@old_files != @new_files || - join(' ', @old_files) ne join(' ', @new_files)) { - return "interdiff1"; - } - - # Verify that the revisions in the files are the same - foreach my $file (keys %{$old_file_list}) { - if ($old_file_list->{$file}{old_revision} ne - $new_file_list->{$file}{old_revision}) { - return "interdiff2"; - } - } - - return undef; -} - -sub setup_patch_readers { - my ($diff_root, $context) = @_; - - # - # Parameters: - # format=raw|html - # context=patch|file|0-n - # collapsed=0|1 - # headers=0|1 - # - - # Define the patch readers - # The reader that reads the patch in (whatever its format) - require PatchReader::Raw; - my $reader = new PatchReader::Raw; - my $last_reader = $reader; - # Fix the patch root if we have a cvs root - if (Param('cvsroot')) - { - require PatchReader::FixPatchRoot; - $last_reader->sends_data_to(new PatchReader::FixPatchRoot(Param('cvsroot'))); - $last_reader->sends_data_to->diff_root($diff_root) if defined($diff_root); - $last_reader = $last_reader->sends_data_to; - } - # Add in cvs context if we have the necessary info to do it - if ($context ne "patch" && $::cvsbin && Param('cvsroot_get')) - { - require PatchReader::AddCVSContext; - $last_reader->sends_data_to( - new PatchReader::AddCVSContext($context, - Param('cvsroot_get'))); - $last_reader = $last_reader->sends_data_to; - } - return ($reader, $last_reader); -} - -sub setup_template_patch_reader -{ - my ($last_reader, $format, $context) = @_; +sub interdiff { + # Retrieve and validate parameters + my ($old_id) = validateID('oldid'); + my ($new_id) = validateID('newid'); + my $format = validateFormat('html', 'raw'); + my $context = validateContext(); - require PatchReader::DiffPrinter::template; + # XXX - validateID should be replaced by Attachment::check_attachment() + # and should return an attachment object. This would save us a lot of + # trouble. + my $old_attachment = Bugzilla::Attachment->get($old_id); + my $new_attachment = Bugzilla::Attachment->get($new_id); - # Define the vars for templates - if (defined $cgi->param('headers')) { - $vars->{headers} = $cgi->param('headers'); - } else { - $vars->{headers} = 1 if !defined $cgi->param('headers'); - } - $vars->{collapsed} = $cgi->param('collapsed'); - $vars->{context} = $context; - $vars->{do_context} = $::cvsbin && Param('cvsroot_get') && !$vars->{'newid'}; - - # Print everything out - print $cgi->header(-type => 'text/html', - -expires => '+3M'); - $last_reader->sends_data_to(new PatchReader::DiffPrinter::template($template, - "attachment/diff-header.$format.tmpl", - "attachment/diff-file.$format.tmpl", - "attachment/diff-footer.$format.tmpl", - { %{$vars}, - bonsai_url => Param('bonsai_url'), - lxr_url => Param('lxr_url'), - lxr_root => Param('lxr_root'), - })); + Bugzilla::Attachment::PatchReader::process_interdiff( + $old_attachment, $new_attachment, $format, $context); } -sub diff -{ - # Retrieve and validate parameters - my ($attach_id) = validateID(); - my $format = validateFormat('html', 'raw'); - my $context = validateContext(); - - # Get patch data - SendSQL("SELECT bug_id, description, ispatch, thedata FROM attachments " . - "INNER JOIN attach_data ON id = attach_id " . - "WHERE attach_id = $attach_id"); - my ($bugid, $description, $ispatch, $thedata) = FetchSQLData(); - - # If it is not a patch, view normally - if (!$ispatch) - { - view(); - return; - } +sub diff { + # Retrieve and validate parameters + my ($attach_id) = validateID(); + my $format = validateFormat('html', 'raw'); + my $context = validateContext(); - my ($reader, $last_reader) = setup_patch_readers(undef,$context); + my $attachment = Bugzilla::Attachment->get($attach_id); - if ($format eq 'raw') - { - require PatchReader::DiffPrinter::raw; - $last_reader->sends_data_to(new PatchReader::DiffPrinter::raw()); - # Actually print out the patch - print $cgi->header(-type => 'text/plain', - -expires => '+3M'); - $reader->iterate_string("Attachment $attach_id", $thedata); - } - else - { - my @other_patches = (); - if ($::interdiffbin && $::diffpath) { - # Get the list of attachments that the user can view in this bug. - my @attachments = @{Bugzilla::Attachment->get_attachments_by_bug($bugid)}; - # Extract patches only. - @attachments = grep {$_->ispatch == 1} @attachments; - # We want them sorted from newer to older. - @attachments = sort { $b->id <=> $a->id } @attachments; - - # Ignore the current patch, but select the one right before it - # chronologically. - my $select_next_patch = 0; - foreach my $attach (@attachments) { - if ($attach->id == $attach_id) { - $select_next_patch = 1; - } - else { - push(@other_patches, { 'id' => $attach->id, - 'desc' => $attach->description, - 'selected' => $select_next_patch }); - $select_next_patch = 0; - } - } + # If it is not a patch, view normally. + if (!$attachment->ispatch) { + view(); + return; } - $vars->{bugid} = $bugid; - $vars->{attachid} = $attach_id; - $vars->{description} = $description; - $vars->{other_patches} = \@other_patches; - setup_template_patch_reader($last_reader, $format, $context); - # Actually print out the patch - $reader->iterate_string("Attachment $attach_id", $thedata); - } + Bugzilla::Attachment::PatchReader::process_diff($attachment, $format, $context); } # Display all attachments for a given bug in a series of IFRAMEs within one # HTML page. -sub viewall -{ +sub viewall { # Retrieve and validate parameters my $bugid = $cgi->param('bugid'); ValidateBugID($bugid); + my $bug = new Bugzilla::Bug($bugid); my $attachments = Bugzilla::Attachment->get_attachments_by_bug($bugid); + foreach my $a (@$attachments) { $a->{'isviewable'} = isViewable($a->contenttype); } - # Retrieve the bug summary (for displaying on screen) and assignee. - SendSQL("SELECT short_desc, assigned_to FROM bugs " . - "WHERE bug_id = $bugid"); - my ($bugsummary, $assignee_id) = FetchSQLData(); + # Define the variables and functions that will be passed to the UI template. + $vars->{'bug'} = $bug; + $vars->{'attachments'} = $attachments; - # Define the variables and functions that will be passed to the UI template. - $vars->{'bugid'} = $bugid; - $vars->{'attachments'} = $attachments; - $vars->{'bugassignee_id'} = $assignee_id; - $vars->{'bugsummary'} = $bugsummary; - $vars->{'GetBugLink'} = \&GetBugLink; + print $cgi->header(); - print $cgi->header(); - - # Generate and return the UI (HTML page) from the appropriate template. - $template->process("attachment/show-multiple.html.tmpl", $vars) - || ThrowTemplateError($template->error()); + # Generate and return the UI (HTML page) from the appropriate template. + $template->process("attachment/show-multiple.html.tmpl", $vars) + || ThrowTemplateError($template->error()); } # Display a form for entering a new attachment. @@ -842,48 +415,32 @@ sub enter my $bugid = $cgi->param('bugid'); ValidateBugID($bugid); validateCanChangeBug($bugid); + my $dbh = Bugzilla->dbh; + my $user = Bugzilla->user; + my $bug = new Bugzilla::Bug($bugid, $user->id); # Retrieve the attachments the user can edit from the database and write # them into an array of hashes where each hash represents one attachment. my $canEdit = ""; - if (!UserInGroup("editbugs")) { - $canEdit = "AND submitter_id = " . Bugzilla->user->id; + if (!$user->in_group('editbugs', $bug->product_id)) { + $canEdit = "AND submitter_id = " . $user->id; } - SendSQL("SELECT attach_id, description, isprivate + my $attachments = $dbh->selectall_arrayref( + "SELECT attach_id AS id, description, isprivate FROM attachments - WHERE bug_id = $bugid + WHERE bug_id = ? AND isobsolete = 0 $canEdit - ORDER BY attach_id"); - my @attachments; # the attachments array - while ( MoreSQLData() ) { - my %a; # the attachment hash - ($a{'id'}, $a{'description'}, $a{'isprivate'}) = FetchSQLData(); - - # Add the hash representing the attachment to the array of attachments. - push @attachments, \%a; - } - - # Retrieve the bug summary (for displaying on screen) and assignee. - SendSQL("SELECT short_desc, assigned_to FROM bugs - WHERE bug_id = $bugid"); - my ($bugsummary, $assignee_id) = FetchSQLData(); + ORDER BY attach_id",{'Slice' =>{}}, $bugid); # Define the variables and functions that will be passed to the UI template. - $vars->{'bugid'} = $bugid; - $vars->{'attachments'} = \@attachments; - $vars->{'bugassignee_id'} = $assignee_id; - $vars->{'bugsummary'} = $bugsummary; - $vars->{'GetBugLink'} = \&GetBugLink; - - SendSQL("SELECT product_id, component_id FROM bugs - WHERE bug_id = $bugid"); - my ($product_id, $component_id) = FetchSQLData(); + $vars->{'bug'} = $bug; + $vars->{'attachments'} = $attachments; + my $flag_types = Bugzilla::FlagType::match({'target_type' => 'attachment', - 'product_id' => $product_id, - 'component_id' => $component_id}); + 'product_id' => $bug->product_id, + 'component_id' => $bug->component_id}); $vars->{'flag_types'} = $flag_types; - $vars->{'any_flags_requesteeble'} = grep($_->{'is_requesteeble'}, - @$flag_types); + $vars->{'any_flags_requesteeble'} = grep($_->is_requesteeble, @$flag_types); print $cgi->header(); @@ -896,171 +453,53 @@ sub enter sub insert { my $dbh = Bugzilla->dbh; - my $userid = Bugzilla->user->id; + my $user = Bugzilla->user; # Retrieve and validate parameters my $bugid = $cgi->param('bugid'); ValidateBugID($bugid); validateCanChangeBug($bugid); ValidateComment(scalar $cgi->param('comment')); - my $attachurl = $cgi->param('attachurl') || ''; - my $data; - my $filename; - my $contenttype; - my $isurl; - validateIsPatch(); - validateDescription(); - - if (Param('allow_attach_url') - && ($attachurl =~ /^(http|https|ftp):\/\/\S+/) - && !defined $cgi->upload('data')) { - $filename = ''; - $data = $attachurl; - $isurl = 1; - $contenttype = SqlQuote('text/plain'); - $cgi->param('ispatch', 0); - $cgi->delete('bigfile'); - } else { - $filename = validateFilename(); - # need to validate content type before data as - # we now check the content type for image/bmp in validateData() - validateContentType() unless $cgi->param('ispatch'); - $data = validateData(); - $contenttype = SqlQuote($cgi->param('contenttype')); - $isurl = 0; - } - - my @obsolete_ids = (); - @obsolete_ids = validateObsolete() if $cgi->param('obsolete'); - - # The order of these function calls is important, as both Flag::validate - # and FlagType::validate assume User::match_field has ensured that the - # values in the requestee fields are legitimate user email addresses. - my $match_status = Bugzilla::User::match_field($cgi, { - '^requestee(_type)?-(\d+)$' => { 'type' => 'multi' }, - }, MATCH_SKIP_CONFIRM); - - $vars->{'match_field'} = 'requestee'; - if ($match_status == USER_MATCH_FAILED) { - $vars->{'message'} = 'user_match_failed'; - } - elsif ($match_status == USER_MATCH_MULTIPLE) { - $vars->{'message'} = 'user_match_multiple'; - } - - # FlagType::validate() and Flag::validate() should not detect - # any reference to existing flags when creating a new attachment. - # Setting the third param to -1 will force this function to check this point. - Bugzilla::Flag::validate($cgi, $bugid, -1); - Bugzilla::FlagType::validate($cgi, $bugid, -1); - - # Escape characters in strings that will be used in SQL statements. - my $sql_filename = SqlQuote($filename); - my $description = SqlQuote($cgi->param('description')); - my $isprivate = $cgi->param('isprivate') ? 1 : 0; - - # Figure out when the changes were made. - my ($timestamp) = Bugzilla->dbh->selectrow_array("SELECT NOW()"); - my $sql_timestamp = SqlQuote($timestamp); - - # Insert the attachment into the database. - my $sth = $dbh->prepare("INSERT INTO attachments - (bug_id, creation_ts, filename, description, - mimetype, ispatch, isurl, isprivate, submitter_id) - VALUES ($bugid, $sql_timestamp, $sql_filename, - $description, $contenttype, " . $cgi->param('ispatch') . ", - $isurl, $isprivate, $userid)"); - $sth->execute(); - # Retrieve the ID of the newly created attachment record. - my $attachid = $dbh->bz_last_key('attachments', 'attach_id'); - - # We only use $data here in this INSERT with a placeholder, - # so it's safe. - $sth = $dbh->prepare("INSERT INTO attach_data - (id, thedata) VALUES ($attachid, ?)"); - trick_taint($data); - $sth->bind_param(1, $data, $dbh->BLOB_TYPE); - $sth->execute(); - - - # If the file is to be stored locally, stream the file from the webserver - # to the local file without reading it into a local variable. - if ($cgi->param('bigfile')) - { - my $fh = $cgi->upload('data'); - my $hash = ($attachid % 100) + 100; - $hash =~ s/.*(\d\d)$/group.$1/; - mkdir "$attachdir/$hash", 0770; - chmod 0770, "$attachdir/$hash"; - open(AH, ">$attachdir/$hash/attachment.$attachid"); - binmode AH; - my $sizecount = 0; - my $limit = (Param("maxlocalattachment") * 1048576); - while (<$fh>) { - print AH $_; - $sizecount += length($_); - if ($sizecount > $limit) { - close AH; - close $fh; - unlink "$attachdir/$hash/attachment.$attachid"; - ThrowUserError("local_file_too_large"); - } - } - close AH; - close $fh; - } + my ($timestamp) = Bugzilla->dbh->selectrow_array("SELECT NOW()"); + my $bug = new Bugzilla::Bug($bugid); + my $attachid = + Bugzilla::Attachment->insert_attachment_for_bug(THROW_ERROR, $bug, $user, + $timestamp, \$vars); # Insert a comment about the new attachment into the database. my $comment = "Created an attachment (id=$attachid)\n" . $cgi->param('description') . "\n"; $comment .= ("\n" . $cgi->param('comment')) if defined $cgi->param('comment'); - AppendComment($bugid, $userid, $comment, $isprivate, $timestamp); - - # Make existing attachments obsolete. - my $fieldid = get_field_id('attachments.isobsolete'); - foreach my $obsolete_id (@obsolete_ids) { - # If the obsolete attachment has request flags, cancel them. - # This call must be done before updating the 'attachments' table. - Bugzilla::Flag::CancelRequests($bugid, $obsolete_id, $sql_timestamp); - - SendSQL("UPDATE attachments SET isobsolete = 1 " . - "WHERE attach_id = $obsolete_id"); - SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, - fieldid, removed, added) - VALUES ($bugid, $obsolete_id, $userid, $sql_timestamp, $fieldid, - '0', '1')"); - } + my $isprivate = $cgi->param('isprivate') ? 1 : 0; + AppendComment($bugid, $user->id, $comment, $isprivate, $timestamp); # Assign the bug to the user, if they are allowed to take it my $owner = ""; - if ($cgi->param('takebug') && UserInGroup("editbugs")) { + if ($cgi->param('takebug') && $user->in_group('editbugs', $bug->product_id)) { my @fields = ("assigned_to", "bug_status", "resolution", "everconfirmed", "login_name"); # Get the old values, for the bugs_activity table - SendSQL("SELECT " . join(", ", @fields) . " " . + my @oldvalues = $dbh->selectrow_array( + "SELECT " . join(", ", @fields) . " " . "FROM bugs " . "INNER JOIN profiles " . "ON profiles.userid = bugs.assigned_to " . - "WHERE bugs.bug_id = $bugid"); + "WHERE bugs.bug_id = ?", undef, $bugid); - my @oldvalues = FetchSQLData(); - my @newvalues = ($userid, "ASSIGNED", "", 1, Bugzilla->user->login); + my @newvalues = ($user->id, "ASSIGNED", "", 1, $user->login); # Make sure the person we are taking the bug from gets mail. $owner = $oldvalues[4]; - - @oldvalues = map(SqlQuote($_), @oldvalues); - @newvalues = map(SqlQuote($_), @newvalues); - + # Update the bug record. Note that this doesn't involve login_name. - SendSQL("UPDATE bugs SET delta_ts = $sql_timestamp, " . - join(", ", map("$fields[$_] = $newvalues[$_]", (0..3))) . - " WHERE bug_id = $bugid"); + $dbh->do('UPDATE bugs SET delta_ts = ?, ' . + join(', ', map("$fields[$_] = ?", (0..3))) . ' WHERE bug_id = ?', + undef, ($timestamp, map($newvalues[$_], (0..3)) , $bugid)); # If the bug was a dupe, we have to remove its entry from the # 'duplicates' table. @@ -1069,28 +508,21 @@ sub insert # We store email addresses in the bugs_activity table rather than IDs. $oldvalues[0] = $oldvalues[4]; $newvalues[0] = $newvalues[4]; - - # Add the changes to the bugs_activity table + for (my $i = 0; $i < 4; $i++) { if ($oldvalues[$i] ne $newvalues[$i]) { - my $fieldid = get_field_id($fields[$i]); - SendSQL("INSERT INTO bugs_activity " . - "(bug_id, who, bug_when, fieldid, removed, added) " . - "VALUES ($bugid, $userid, $sql_timestamp, " . - "$fieldid, $oldvalues[$i], $newvalues[$i])"); + LogActivityEntry($bugid, $fields[$i], $oldvalues[$i], + $newvalues[$i], $user->id, $timestamp); } } } - - # Create flags. - Bugzilla::Flag::process($bugid, $attachid, $timestamp, $cgi); - + # Define the variables and functions that will be passed to the UI template. - $vars->{'mailrecipients'} = { 'changer' => Bugzilla->user->login, + $vars->{'mailrecipients'} = { 'changer' => $user->login, 'owner' => $owner }; $vars->{'bugid'} = $bugid; $vars->{'attachid'} = $attachid; - $vars->{'description'} = $description; + $vars->{'description'} = $cgi->param('description'); $vars->{'contenttypemethod'} = $cgi->param('contenttypemethod'); $vars->{'contenttype'} = $cgi->param('contenttype'); @@ -1129,17 +561,15 @@ sub edit { 'product_id' => $product_id , 'component_id' => $component_id }); foreach my $flag_type (@$flag_types) { - $flag_type->{'flags'} = Bugzilla::Flag::match({ 'type_id' => $flag_type->{'id'}, - 'attach_id' => $attachment->id, - 'is_active' => 1 }); + $flag_type->{'flags'} = Bugzilla::Flag::match({ 'type_id' => $flag_type->id, + 'attach_id' => $attachment->id }); } $vars->{'flag_types'} = $flag_types; - $vars->{'any_flags_requesteeble'} = grep($_->{'is_requesteeble'}, @$flag_types); + $vars->{'any_flags_requesteeble'} = grep($_->is_requesteeble, @$flag_types); $vars->{'attachment'} = $attachment; $vars->{'bugsummary'} = $bugsummary; $vars->{'isviewable'} = $isviewable; $vars->{'attachments'} = $bugattachments; - $vars->{'GetBugLink'} = \&GetBugLink; # Determine if PatchReader is installed eval { @@ -1160,18 +590,20 @@ sub edit { # Users cannot edit the content of the attachment itself. sub update { - my $dbh = Bugzilla->dbh; - my $user = Bugzilla->user; - my $userid = $user->id; + my $user = Bugzilla->user; + my $userid = $user->id; + my $dbh = Bugzilla->dbh; # Retrieve and validate parameters ValidateComment(scalar $cgi->param('comment')); my ($attach_id, $bugid) = validateID(); - validateCanEdit($attach_id); + my $bug = new Bugzilla::Bug($bugid); + my $attachment = Bugzilla::Attachment->get($attach_id); + $attachment->validate_can_edit($bug->product_id); validateCanChangeAttachment($attach_id); - validateDescription(); - validateIsPatch(); - validateContentType() unless $cgi->param('ispatch'); + Bugzilla::Attachment->validate_description(THROW_ERROR); + Bugzilla::Attachment->validate_is_patch(THROW_ERROR); + Bugzilla::Attachment->validate_content_type(THROW_ERROR) unless $cgi->param('ispatch'); validateIsObsolete(); validatePrivate(); @@ -1188,17 +620,16 @@ sub update $cgi->param('isprivate', $oldisprivate); } - # The order of these function calls is important, as both Flag::validate - # and FlagType::validate assume User::match_field has ensured that the - # values in the requestee fields are legitimate user email addresses. + # The order of these function calls is important, as Flag::validate + # assumes User::match_field has ensured that the values in the + # requestee fields are legitimate user email addresses. Bugzilla::User::match_field($cgi, { '^requestee(_type)?-(\d+)$' => { 'type' => 'multi' } }); Bugzilla::Flag::validate($cgi, $bugid, $attach_id); - Bugzilla::FlagType::validate($cgi, $bugid, $attach_id); - # Lock database tables in preparation for updating the attachment. - $dbh->bz_lock_tables('attachments WRITE', 'flags WRITE' , + # Lock database tables in preparation for updating the attachment. + $dbh->bz_lock_tables('attachments WRITE', 'flags WRITE' , 'flagtypes READ', 'fielddefs READ', 'bugs_activity WRITE', 'flaginclusions AS i READ', 'flagexclusions AS e READ', # cc, bug_group_map, user_group_map, and groups are in here so we @@ -1208,87 +639,94 @@ sub update # Bugzilla::User can flatten groups. 'bugs WRITE', 'profiles READ', 'email_setting READ', 'cc READ', 'bug_group_map READ', 'user_group_map READ', - 'group_group_map READ', 'groups READ'); + 'group_group_map READ', 'groups READ', 'group_control_map READ'); # Get a copy of the attachment record before we make changes # so we can record those changes in the activity table. - SendSQL("SELECT description, mimetype, filename, ispatch, isobsolete, isprivate - FROM attachments WHERE attach_id = $attach_id"); my ($olddescription, $oldcontenttype, $oldfilename, $oldispatch, - $oldisobsolete, $oldisprivate) = FetchSQLData(); + $oldisobsolete, $oldisprivate) = $dbh->selectrow_array( + "SELECT description, mimetype, filename, ispatch, isobsolete, isprivate + FROM attachments WHERE attach_id = ?", undef, $attach_id); # Quote the description and content type for use in the SQL UPDATE statement. - my $quoteddescription = SqlQuote($cgi->param('description')); - my $quotedcontenttype = SqlQuote($cgi->param('contenttype')); - my $quotedfilename = SqlQuote($cgi->param('filename')); + my $description = $cgi->param('description'); + my $contenttype = $cgi->param('contenttype'); + my $filename = $cgi->param('filename'); + # we can detaint this way thanks to placeholders + trick_taint($description); + trick_taint($contenttype); + trick_taint($filename); # Figure out when the changes were made. - SendSQL("SELECT NOW()"); - my $timestamp = FetchOneColumn(); + my ($timestamp) = $dbh->selectrow_array("SELECT NOW()"); # Update flags. We have to do this before committing changes # to attachments so that we can delete pending requests if the user # is obsoleting this attachment without deleting any requests # the user submits at the same time. - Bugzilla::Flag::process($bugid, $attach_id, $timestamp, $cgi); + Bugzilla::Flag::process($bug, $attachment, $timestamp, $cgi); # Update the attachment record in the database. - SendSQL("UPDATE attachments - SET description = $quoteddescription , - mimetype = $quotedcontenttype , - filename = $quotedfilename , - ispatch = " . $cgi->param('ispatch') . ", - isobsolete = " . $cgi->param('isobsolete') . ", - isprivate = " . $cgi->param('isprivate') . " - WHERE attach_id = $attach_id - "); + $dbh->do("UPDATE attachments + SET description = ?, + mimetype = ?, + filename = ?, + ispatch = ?, + isobsolete = ?, + isprivate = ? + WHERE attach_id = ?", + undef, ($description, $contenttype, $filename, + $cgi->param('ispatch'), $cgi->param('isobsolete'), + $cgi->param('isprivate'), $attach_id)); # Record changes in the activity table. - my $sql_timestamp = SqlQuote($timestamp); if ($olddescription ne $cgi->param('description')) { - my $quotedolddescription = SqlQuote($olddescription); my $fieldid = get_field_id('attachments.description'); - SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, + $dbh->do("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added) - VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid, - $quotedolddescription, $quoteddescription)"); + VALUES (?,?,?,?,?,?,?)", + undef, ($bugid, $attach_id, $userid, $timestamp, $fieldid, + $olddescription, $description)); } if ($oldcontenttype ne $cgi->param('contenttype')) { - my $quotedoldcontenttype = SqlQuote($oldcontenttype); my $fieldid = get_field_id('attachments.mimetype'); - SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, + $dbh->do("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added) - VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid, - $quotedoldcontenttype, $quotedcontenttype)"); + VALUES (?,?,?,?,?,?,?)", + undef, ($bugid, $attach_id, $userid, $timestamp, $fieldid, + $oldcontenttype, $contenttype)); } if ($oldfilename ne $cgi->param('filename')) { - my $quotedoldfilename = SqlQuote($oldfilename); my $fieldid = get_field_id('attachments.filename'); - SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, + $dbh->do("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added) - VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid, - $quotedoldfilename, $quotedfilename)"); + VALUES (?,?,?,?,?,?,?)", + undef, ($bugid, $attach_id, $userid, $timestamp, $fieldid, + $oldfilename, $filename)); } if ($oldispatch ne $cgi->param('ispatch')) { my $fieldid = get_field_id('attachments.ispatch'); - SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, + $dbh->do("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added) - VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid, - $oldispatch, " . $cgi->param('ispatch') . ")"); + VALUES (?,?,?,?,?,?,?)", + undef, ($bugid, $attach_id, $userid, $timestamp, $fieldid, + $oldispatch, $cgi->param('ispatch'))); } if ($oldisobsolete ne $cgi->param('isobsolete')) { my $fieldid = get_field_id('attachments.isobsolete'); - SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, + $dbh->do("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added) - VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid, - $oldisobsolete, " . $cgi->param('isobsolete') . ")"); + VALUES (?,?,?,?,?,?,?)", + undef, ($bugid, $attach_id, $userid, $timestamp, $fieldid, + $oldisobsolete, $cgi->param('isobsolete'))); } if ($oldisprivate ne $cgi->param('isprivate')) { my $fieldid = get_field_id('attachments.isprivate'); - SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, + $dbh->do("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, fieldid, removed, added) - VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid, - $oldisprivate, " . $cgi->param('isprivate') . ")"); + VALUES (?,?,?,?,?,?,?)", + undef, ($bugid, $attach_id, $userid, $timestamp, $fieldid, + $oldisprivate, $cgi->param('isprivate'))); } # Unlock all database tables now that we are finished updating the database. @@ -1318,3 +756,83 @@ sub update $template->process("attachment/updated.html.tmpl", $vars) || ThrowTemplateError($template->error()); } + +# Only administrators can delete attachments. +sub delete_attachment { + my $user = Bugzilla->login(LOGIN_REQUIRED); + my $dbh = Bugzilla->dbh; + + print $cgi->header(); + + $user->in_group('admin') + || ThrowUserError('auth_failure', {group => 'admin', + action => 'delete', + object => 'attachment'}); + + Bugzilla->params->{'allow_attachment_deletion'} + || ThrowUserError('attachment_deletion_disabled'); + + # Make sure the administrator is allowed to edit this attachment. + my ($attach_id, $bug_id) = validateID(); + my $attachment = Bugzilla::Attachment->get($attach_id); + validateCanChangeAttachment($attach_id); + + $attachment->datasize || ThrowUserError('attachment_removed'); + + # We don't want to let a malicious URL accidentally delete an attachment. + my $token = trim($cgi->param('token')); + if ($token) { + my ($creator_id, $date, $event) = Bugzilla::Token::GetTokenData($token); + unless ($creator_id + && ($creator_id == $user->id) + && ($event eq "attachment$attach_id")) + { + # The token is invalid. + ThrowUserError('token_inexistent'); + } + + # The token is valid. Delete the content of the attachment. + my $msg; + $vars->{'attachid'} = $attach_id; + $vars->{'bugid'} = $bug_id; + $vars->{'date'} = $date; + $vars->{'reason'} = clean_text($cgi->param('reason') || ''); + $vars->{'mailrecipients'} = { 'changer' => $user->login }; + + $template->process("attachment/delete_reason.txt.tmpl", $vars, \$msg) + || ThrowTemplateError($template->error()); + + $dbh->bz_lock_tables('attachments WRITE', 'attach_data WRITE', 'flags WRITE'); + $dbh->do('DELETE FROM attach_data WHERE id = ?', undef, $attach_id); + $dbh->do('UPDATE attachments SET mimetype = ?, ispatch = ?, isurl = ?, + isobsolete = ? + WHERE attach_id = ?', undef, + ('text/plain', 0, 0, 1, $attach_id)); + $dbh->do('DELETE FROM flags WHERE attach_id = ?', undef, $attach_id); + $dbh->bz_unlock_tables; + + # If the attachment is stored locally, remove it. + if (-e $attachment->_get_local_filename) { + unlink $attachment->_get_local_filename; + } + + # Now delete the token. + delete_token($token); + + # Paste the reason provided by the admin into a comment. + AppendComment($bug_id, $user->id, $msg); + + $template->process("attachment/updated.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + } + else { + # Create a token. + $token = issue_session_token('attachment' . $attach_id); + + $vars->{'a'} = $attachment; + $vars->{'token'} = $token; + + $template->process("attachment/confirm-delete.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + } +} diff --git a/buglist.cgi b/buglist.cgi index 036c95785..a22a74842 100755 --- a/buglist.cgi +++ b/buglist.cgi @@ -35,24 +35,19 @@ use strict; use lib qw(.); use Bugzilla; +use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::Util; use Bugzilla::Search; use Bugzilla::Search::Quicksearch; -use Bugzilla::Constants; +use Bugzilla::Search::Saved; use Bugzilla::User; use Bugzilla::Bug; +use Bugzilla::Product; +use Bugzilla::Keyword; +use Bugzilla::Field; -# Include the Bugzilla CGI and general utility library. -require "globals.pl"; - -use vars qw(@components - @legal_keywords - @legal_platform - @legal_priority - @legal_product - @legal_severity - @settable_resolution - @target_milestone - @versions); +use Date::Parse; my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; @@ -79,6 +74,12 @@ if (defined($searchstring)) { # as if this had been a normal query from the beginning. } +# Reject empty searches from the simple search form, including +# words being a single or several consecutive whitespaces only. +if (defined($cgi->param('content')) && $cgi->param('content') =~ /^\s*$/) { + ThrowUserError("buglist_parameters_required"); +} + ################################################################################ # Data and Security Validation ################################################################################ @@ -89,11 +90,10 @@ my $dotweak = $cgi->param('tweak') ? 1 : 0; # Log the user in if ($dotweak) { Bugzilla->login(LOGIN_REQUIRED); - UserInGroup("editbugs") + Bugzilla->user->in_group("editbugs") || ThrowUserError("auth_failure", {group => "editbugs", action => "modify", object => "multiple_bugs"}); - GetVersionTable(); } # Hack to support legacy applications that think the RDF ctype is at format=rdf. @@ -139,12 +139,14 @@ my $format = $template->get_format("list/list", scalar $cgi->param('format'), # Server push is a Netscape 3+ hack incompatible with MSIE, Lynx, and others. # Even Communicator 4.51 has bugs with it, especially during page reload. # http://www.browsercaps.org used as source of compatible browsers. +# Safari (WebKit) does not support it, despite a UA that says otherwise (bug 188712) +# MSIE 5+ supports it on Mac (but not on Windows) (bug 190370) # my $serverpush = $format->{'extension'} eq "html" && exists $ENV{'HTTP_USER_AGENT'} && $ENV{'HTTP_USER_AGENT'} =~ /Mozilla.[3-9]/ - && $ENV{'HTTP_USER_AGENT'} !~ /[Cc]ompatible/ + && (($ENV{'HTTP_USER_AGENT'} !~ /[Cc]ompatible/) || ($ENV{'HTTP_USER_AGENT'} =~ /MSIE 5.*Mac_PowerPC/)) && $ENV{'HTTP_USER_AGENT'} !~ /WebKit/ && !$agent && !defined($cgi->param('serverpush')) @@ -199,7 +201,7 @@ foreach my $chart (@charts) { # Utilities ################################################################################ -my @weekday= qw( Sun Mon Tue Wed Thu Fri Sat ); +local our @weekday= qw( Sun Mon Tue Wed Thu Fri Sat ); sub DiffDate { my ($datestr) = @_; my $date = str2time($datestr); @@ -216,18 +218,55 @@ sub DiffDate { } sub LookupNamedQuery { - my ($name) = @_; + my ($name, $sharer_id, $query_type, $throw_error) = @_; my $user = Bugzilla->login(LOGIN_REQUIRED); my $dbh = Bugzilla->dbh; - # $name is safe -- we only use it below in a SELECT placeholder and then - # in error messages (which are always HTML-filtered). + my $owner_id; + $throw_error = 1 unless defined $throw_error; + + # $name and $sharer_id are safe -- we only use them below in SELECT + # placeholders and then in error messages (which are always HTML-filtered). $name || ThrowUserError("query_name_missing"); trick_taint($name); - my $result = $dbh->selectrow_array("SELECT query FROM namedqueries" - . " WHERE userid = ? AND name = ?" - , undef, ($user->id, $name)); + if ($sharer_id) { + $owner_id = $sharer_id; + detaint_natural($owner_id); + $owner_id || ThrowUserError('illegal_user_id', {'userid' => $sharer_id}); + } + else { + $owner_id = $user->id; + } + + my @args = ($owner_id, $name); + my $extra = ''; + # If $query_type is defined, then we restrict our search. + if (defined $query_type) { + $extra = ' AND query_type = ? '; + detaint_natural($query_type); + push(@args, $query_type); + } + my ($id, $result) = $dbh->selectrow_array("SELECT id, query + FROM namedqueries + WHERE userid = ? AND name = ? + $extra", + undef, @args); + if (!defined($result)) { + return 0 unless $throw_error; + ThrowUserError("missing_query", {'queryname' => $name, + 'sharer_id' => $sharer_id}); + } + + if ($sharer_id) { + my $group = $dbh->selectrow_array('SELECT group_id + FROM namedquery_group_map + WHERE namedquery_id = ?', + undef, $id); + if (!grep {$_ == $group} values(%{$user->groups()})) { + ThrowUserError("missing_query", {'queryname' => $name, + 'sharer_id' => $sharer_id}); + } + } - defined($result) || ThrowUserError("missing_query", {'queryname' => $name}); $result || ThrowUserError("buglist_parameters_required", {'queryname' => $name}); @@ -255,50 +294,26 @@ sub LookupNamedQuery { # Returns: A boolean true value if the query existed in the database # before, and we updated it. A boolean false value otherwise. sub InsertNamedQuery { - my ($userid, $query_name, $query, $link_in_footer, $query_type) = @_; - $link_in_footer ||= 0; - $query_type ||= QUERY_LIST; - $query_name = trim($query_name); - Bugzilla->login(LOGIN_REQUIRED); + my ($query_name, $query, $link_in_footer, $query_type) = @_; my $dbh = Bugzilla->dbh; - my $query_existed_before; - - # Validate the query name. - $query_name || ThrowUserError("query_name_missing"); - $query_name !~ /[<>&]/ || ThrowUserError("illegal_query_name"); - (length($query_name) <= 64) || ThrowUserError("query_name_too_long"); - trick_taint($query_name); - - detaint_natural($userid); - detaint_natural($link_in_footer); - - $query || ThrowUserError("buglist_parameters_required", - {'queryname' => $query}); - # $query is safe, because we always urlencode or html_quote - # it when we display it to the user. - trick_taint($query); - - $dbh->bz_lock_tables('namedqueries WRITE'); - - my $result = $dbh->selectrow_array("SELECT userid FROM namedqueries" - . " WHERE userid = ? AND name = ?" - , undef, ($userid, $query_name)); - if ($result) { - $query_existed_before = 1; - $dbh->do("UPDATE namedqueries" - . " SET query = ?, linkinfooter = ?, query_type = ?" - . " WHERE userid = ? AND name = ?" - , undef, ($query, $link_in_footer, $query_type, $userid, $query_name)); + + $query_name = trim($query_name); + my ($query_obj) = grep {$_->name eq $query_name} @{Bugzilla->user->queries}; + + if ($query_obj) { + $query_obj->set_url($query); + $query_obj->set_query_type($query_type); + $query_obj->update(); } else { - $query_existed_before = 0; - $dbh->do("INSERT INTO namedqueries" - . " (userid, name, query, linkinfooter, query_type)" - . " VALUES (?, ?, ?, ?, ?)" - , undef, ($userid, $query_name, $query, $link_in_footer, $query_type)); + Bugzilla::Search::Saved->create({ + name => $query_name, + query => $query, + query_type => $query_type, + link_in_footer => $link_in_footer + }); } - $dbh->bz_unlock_tables(); - return $query_existed_before; + return $query_obj ? 1 : 0; } sub LookupSeries { @@ -386,9 +401,15 @@ if ($cgi->param('cmdtype') eq "dorem" && $cgi->param('remaction') =~ /^run/) { # Take appropriate action based on user's request. if ($cgi->param('cmdtype') eq "dorem") { if ($cgi->param('remaction') eq "run") { - $buffer = LookupNamedQuery(scalar $cgi->param("namedcmd")); + $buffer = LookupNamedQuery(scalar $cgi->param("namedcmd"), + scalar $cgi->param('sharer_id')); + # If this is the user's own query, remember information about it + # so that it can be modified easily. $vars->{'searchname'} = $cgi->param('namedcmd'); - $vars->{'searchtype'} = "saved"; + if (!$cgi->param('sharer_id') || + $cgi->param('sharer_id') == Bugzilla->user->id) { + $vars->{'searchtype'} = "saved"; + } $params = new Bugzilla::CGI($buffer); $order = $params->param('order') || $order; @@ -428,9 +449,24 @@ if ($cgi->param('cmdtype') eq "dorem") { } # If we are here, then we can safely remove the saved search - $dbh->do("DELETE FROM namedqueries" - . " WHERE userid = ? AND name = ?" - , undef, ($user->id, $qname)); + my ($query_id) = $dbh->selectrow_array('SELECT id FROM namedqueries + WHERE userid = ? + AND name = ?', + undef, ($user->id, $qname)); + if (!$query_id) { + # The user has no query of this name. Play along. + } + else { + $dbh->do('DELETE FROM namedqueries + WHERE id = ?', + undef, $query_id); + $dbh->do('DELETE FROM namedqueries_link_in_footer + WHERE namedquery_id = ?', + undef, $query_id); + $dbh->do('DELETE FROM namedquery_group_map + WHERE namedquery_id = ?', + undef, $query_id); + } # Now reset the cached queries $user->flush_queries_cache(); @@ -438,7 +474,7 @@ if ($cgi->param('cmdtype') eq "dorem") { print $cgi->header(); # Generate and return the UI (HTML page) from the appropriate template. $vars->{'message'} = "buglist_query_gone"; - $vars->{'namedcmd'} = $cgi->param('namedcmd'); + $vars->{'namedcmd'} = $qname; $vars->{'url'} = "query.cgi"; $template->process("global/message.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -448,7 +484,7 @@ if ($cgi->param('cmdtype') eq "dorem") { elsif (($cgi->param('cmdtype') eq "doit") && defined $cgi->param('remtype')) { if ($cgi->param('remtype') eq "asdefault") { my $user = Bugzilla->login(LOGIN_REQUIRED); - InsertNamedQuery($user->id, DEFAULT_QUERY_NAME, $buffer); + InsertNamedQuery(DEFAULT_QUERY_NAME, $buffer); $vars->{'message'} = "buglist_new_default_query"; } elsif ($cgi->param('remtype') eq "asnamed") { @@ -456,32 +492,61 @@ elsif (($cgi->param('cmdtype') eq "doit") && defined $cgi->param('remtype')) { my $query_name = $cgi->param('newqueryname'); my $new_query = $cgi->param('newquery'); my $query_type = QUERY_LIST; - # If add_bugids is true, we are adding individual bugs to a saved - # search. We get the existing list of bug IDs (if any) and append - # the new ones. - if ($cgi->param('add_bugids')) { - my %bug_ids; - foreach my $bug_id (split(/[\s,]+/, $cgi->param('bug_ids'))) { - next unless $bug_id; - ValidateBugID($bug_id); - $bug_ids{$bug_id} = 1; + # If list_of_bugs is true, we are adding/removing individual bugs + # to a saved search. We get the existing list of bug IDs (if any) + # and add/remove the passed ones. + if ($cgi->param('list_of_bugs')) { + # We add or remove bugs based on the action choosen. + my $action = trim($cgi->param('action') || ''); + $action =~ /^(add|remove)$/ + || ThrowCodeError('unknown_action', {'action' => $action}); + + # If we are removing bugs, then we must have an existing + # saved search selected. + if ($action eq 'remove') { + $query_name && ThrowUserError('no_bugs_to_remove'); } - ThrowUserError("no_bug_ids") unless scalar(keys %bug_ids); - if (!trim($query_name)) { - # No new query name has been given. We append new bug IDs - # to the existing list. + my %bug_ids; + if ($query_name) { + # Make sure this name is not already in use by a normal saved search. + if (LookupNamedQuery($query_name, undef, QUERY_LIST, !THROW_ERROR)) { + ThrowUserError('query_name_exists', {'name' => $query_name}); + } + } + else { + # No new query name has been given. We retrieve bug IDs + # currently set in the selected saved search. $query_name = $cgi->param('oldqueryname'); - my $old_query = LookupNamedQuery($query_name); - foreach my $bug_id (split(/[\s,=]+/, $old_query)) { + my $old_query = LookupNamedQuery($query_name, undef, LIST_OF_BUGS); + # We get the encoded query. We need to decode it. + my $old_cgi = new Bugzilla::CGI($old_query); + foreach my $bug_id (split /[\s,]+/, scalar $old_cgi->param('bug_id')) { $bug_ids{$bug_id} = 1 if detaint_natural($bug_id); } } - $new_query = "bug_id=" . join(',', sort {$a <=> $b} keys %bug_ids); + + my $keep_bug = ($action eq 'add') ? 1 : 0; + my $changes = 0; + foreach my $bug_id (split(/[\s,]+/, $cgi->param('bug_ids'))) { + next unless $bug_id; + ValidateBugID($bug_id); + $bug_ids{$bug_id} = $keep_bug; + $changes = 1; + } + ThrowUserError('no_bug_ids', {'action' => $action}) unless $changes; + + # Only keep bug IDs we want to add/keep. Disregard deleted ones. + my @bug_ids = grep { $bug_ids{$_} == 1 } keys %bug_ids; + # If the list is now empty, we could as well delete it completely. + ThrowUserError('no_bugs_in_list', {'saved_search' => $query_name}) + unless scalar(@bug_ids); + + $new_query = "bug_id=" . join(',', sort {$a <=> $b} @bug_ids); $query_type = LIST_OF_BUGS; } my $tofooter = 1; - my $existed_before = InsertNamedQuery($user->id, $query_name, $new_query, + my $existed_before = InsertNamedQuery($query_name, $new_query, $tofooter, $query_type); if ($existed_before) { $vars->{'message'} = "buglist_updated_named_query"; @@ -533,7 +598,7 @@ if (!$params->param('query_format')) { # Note: For column names using aliasing (SQL "<field> AS <alias>"), the column # ID needs to be identical to the field ID for list ordering to work. -my $columns = {}; +local our $columns = {}; sub DefineColumn { my ($id, $name, $title) = @_; $columns->{$id} = { 'name' => $name , 'title' => $title }; @@ -541,7 +606,7 @@ sub DefineColumn { # Column: ID Name Title DefineColumn("bug_id" , "bugs.bug_id" , "ID" ); -DefineColumn("alias" , "bugs.alias" , "Alias" ); +DefineColumn("alias" , "bugs.alias" , "Alias" ); DefineColumn("opendate" , "bugs.creation_ts" , "Opened" ); DefineColumn("changeddate" , "bugs.delta_ts" , "Changed" ); DefineColumn("bug_severity" , "bugs.bug_severity" , "Severity" ); @@ -585,6 +650,10 @@ DefineColumn("percentage_complete", DefineColumn("relevance" , "relevance" , "Relevance" ); DefineColumn("deadline" , $dbh->sql_date_format('bugs.deadline', '%Y-%m-%d') . " AS deadline", "Deadline"); +foreach my $field (Bugzilla->get_fields({ custom => 1, obsolete => 0})) { + DefineColumn($field->name, 'bugs.' . $field->name, $field->description); +} + ################################################################################ # Display Column Determination ################################################################################ @@ -644,7 +713,7 @@ if (trim($votes) && !grep($_ eq 'votes', @displaycolumns)) { # Remove the timetracking columns if they are not a part of the group # (happens if a user had access to time tracking and it was revoked/disabled) -if (!UserInGroup(Param("timetrackinggroup"))) { +if (!Bugzilla->user->in_group(Bugzilla->params->{"timetrackinggroup"})) { @displaycolumns = grep($_ ne 'estimated_time', @displaycolumns); @displaycolumns = grep($_ ne 'remaining_time', @displaycolumns); @displaycolumns = grep($_ ne 'actual_time', @displaycolumns); @@ -671,7 +740,7 @@ my @selectcolumns = ("bug_id", "bug_severity", "priority", "bug_status", "resolution"); # if using classification, we also need to look in product.classification_id -if (Param("useclassification")) { +if (Bugzilla->params->{"useclassification"}) { push (@selectcolumns,"product"); } @@ -897,6 +966,12 @@ if ($serverpush) { $template->process("list/server-push.html.tmpl", $vars) || ThrowTemplateError($template->error()); + # Under mod_perl, flush stdout so that the page actually shows up. + if ($ENV{MOD_PERL}) { + require Apache2::RequestUtil; + Apache2::RequestUtil->request->rflush(); + } + # Don't do multipart_end() until we're ready to display the replacement # page, otherwise any errors that happen before then (like SQL errors) # will result in a blank page being shown to the user instead of the error. @@ -906,7 +981,7 @@ if ($serverpush) { # query performance. $dbh = Bugzilla->switch_to_shadow_db(); -# Normally, we ignore SIGTERM and SIGPIPE (see globals.pl) but we need to +# Normally, we ignore SIGTERM and SIGPIPE, but we need to # respond to them here to prevent someone DOSing us by reloading a query # a large number of times. $::SIG{TERM} = 'DEFAULT'; @@ -949,13 +1024,13 @@ while (my @row = $buglist_sth->fetchrow_array()) { # Put in the change date as a time, so that the template date plugin # can format the date in any way needed by the template. ICS and Atom # have specific, and different, date and time formatting. - $bug->{'changedtime'} = str2time($bug->{'changeddate'}); + $bug->{'changedtime'} = str2time($bug->{'changeddate'}, Bugzilla->params->{'timezone'}); $bug->{'changeddate'} = DiffDate($bug->{'changeddate'}); } if ($bug->{'opendate'}) { # Put in the open date as a time for the template date plugin. - $bug->{'opentime'} = str2time($bug->{'opendate'}); + $bug->{'opentime'} = str2time($bug->{'opendate'}, Bugzilla->params->{'timezone'}); $bug->{'opendate'} = DiffDate($bug->{'opendate'}); } @@ -1015,7 +1090,7 @@ $vars->{'buglist_joined'} = join(',', @bugidlist); $vars->{'columns'} = $columns; $vars->{'displaycolumns'} = \@displaycolumns; -my @openstates = OpenStates(); +my @openstates = BUG_STATE_OPEN; $vars->{'openstates'} = \@openstates; $vars->{'closedstates'} = ['CLOSED', 'VERIFIED', 'RESOLVED']; @@ -1028,11 +1103,11 @@ $vars->{'urlquerypart'} = $params->canonicalise_query('order', 'cmdtype', 'query_based_on'); $vars->{'order'} = $order; -$vars->{'caneditbugs'} = UserInGroup('editbugs'); +$vars->{'caneditbugs'} = Bugzilla->user->in_group('editbugs'); my @bugowners = keys %$bugowners; -if (scalar(@bugowners) > 1 && UserInGroup('editbugs')) { - my $suffix = Param('emailsuffix'); +if (scalar(@bugowners) > 1 && Bugzilla->user->in_group('editbugs')) { + my $suffix = Bugzilla->params->{'emailsuffix'}; map(s/$/$suffix/, @bugowners) if $suffix; my $bugowners = join(",", @bugowners); $vars->{'bugowners'} = $bugowners; @@ -1048,14 +1123,14 @@ $vars->{'currenttime'} = time(); # The following variables are used when the user is making changes to multiple bugs. if ($dotweak) { $vars->{'dotweak'} = 1; - $vars->{'use_keywords'} = 1 if @::legal_keywords; + $vars->{'use_keywords'} = 1 if Bugzilla::Keyword::keyword_count(); $vars->{'products'} = Bugzilla->user->get_enterable_products; - $vars->{'platforms'} = \@::legal_platform; - $vars->{'op_sys'} = \@::legal_opsys; - $vars->{'priorities'} = \@::legal_priority; - $vars->{'severities'} = \@::legal_severity; - $vars->{'resolutions'} = \@::settable_resolution; + $vars->{'platforms'} = get_legal_field_values('rep_platform'); + $vars->{'op_sys'} = get_legal_field_values('op_sys'); + $vars->{'priorities'} = get_legal_field_values('priority'); + $vars->{'severities'} = get_legal_field_values('bug_severity'); + $vars->{'resolutions'} = Bugzilla::Bug->settable_resolutions; $vars->{'unconfirmedstate'} = 'UNCONFIRMED'; @@ -1070,10 +1145,12 @@ if ($dotweak) { # products), and a list of components for the product. $vars->{'bugproducts'} = [ keys %$bugproducts ]; if (scalar(@{$vars->{'bugproducts'}}) == 1) { - my $product = $vars->{'bugproducts'}->[0]; - $vars->{'versions'} = $::versions{$product}; - $vars->{'components'} = $::components{$product}; - $vars->{'targetmilestones'} = $::target_milestone{$product} if Param('usetargetmilestone'); + my $product = new Bugzilla::Product( + {name => $vars->{'bugproducts'}->[0]}); + $vars->{'versions'} = [map($_->name ,@{$product->versions})]; + $vars->{'components'} = [map($_->name, @{$product->components})]; + $vars->{'targetmilestones'} = [map($_->name, @{$product->milestones})] + if Bugzilla->params->{'usetargetmilestone'}; } } @@ -1128,7 +1205,7 @@ if ($serverpush) { # close the "please wait" page, then open the buglist page print $cgi->multipart_end(); my @extra; - push @extra, (-charset => "utf8") if Param("utf8"); + push @extra, (-charset => "utf8") if Bugzilla->params->{"utf8"}; print $cgi->multipart_start(-type => $contenttype, -content_disposition => $disposition, @extra); diff --git a/bugzilla.dtd b/bugzilla.dtd index 25a0a895b..c0f9ff4a3 100644 --- a/bugzilla.dtd +++ b/bugzilla.dtd @@ -5,7 +5,7 @@ maintainer CDATA #REQUIRED exporter CDATA #IMPLIED > -<!ELEMENT bug (bug_id, (alias?, creation_ts, short_desc, delta_ts, reporter_accessible, cclist_accessible, classification_id, classification, product, component, version, rep_platform, op_sys, bug_status, resolution?, bug_file_loc?, status_whiteboard?, keywords*, priority, bug_severity, target_milestone?, dependson*, blocked*, votes?, everconfirmed, reporter, assigned_to, qa_contact?, cc*, (estimated_time, remaining_time, actual_time, deadline)?, group*, flag*, long_desc*, attachment*)?)> +<!ELEMENT bug (bug_id, (alias?, creation_ts, short_desc, delta_ts, reporter_accessible, cclist_accessible, classification_id, classification, product, component, version, rep_platform, op_sys, bug_status, resolution?, dup_id?, bug_file_loc?, status_whiteboard?, keywords*, priority, bug_severity, target_milestone?, dependson*, blocked*, votes?, everconfirmed, reporter, assigned_to, qa_contact?, cc*, (estimated_time, remaining_time, actual_time, deadline)?, group*, flag*, long_desc*, attachment*)?)> <!ATTLIST bug error (NotFound | NotPermitted | InvalidBugId) #IMPLIED > @@ -33,6 +33,7 @@ <!ELEMENT status_whiteboard (#PCDATA)> <!ELEMENT op_sys (#PCDATA)> <!ELEMENT resolution (#PCDATA)> +<!ELEMENT dup_id (#PCDATA)> <!ELEMENT bug_file_loc (#PCDATA)> <!ELEMENT short_desc (#PCDATA)> <!ELEMENT keywords (#PCDATA)> @@ -46,15 +47,16 @@ <!ELEMENT remaining_time (#PCDATA)> <!ELEMENT actual_time (#PCDATA)> <!ELEMENT deadline (#PCDATA)> -<!ELEMENT long_desc (who, bug_when, thetext)> +<!ELEMENT long_desc (who, bug_when, work_time?, thetext)> <!ATTLIST long_desc encoding (base64) #IMPLIED isprivate (0|1) #IMPLIED > <!ELEMENT who (#PCDATA)> <!ELEMENT bug_when (#PCDATA)> +<!ELEMENT work_time (#PCDATA)> <!ELEMENT thetext (#PCDATA)> -<!ELEMENT attachment (attachid, date, desc, filename?, type?, data?, flag*)> +<!ELEMENT attachment (attachid, date, desc, filename?, type?, size?, data?, flag*)> <!ATTLIST attachment isobsolete (0|1) #IMPLIED ispatch (0|1) #IMPLIED @@ -65,6 +67,7 @@ <!ELEMENT desc (#PCDATA)> <!ELEMENT filename (#PCDATA)> <!ELEMENT type (#PCDATA)> +<!ELEMENT size (#PCDATA)> <!ELEMENT data (#PCDATA)> <!ATTLIST data encoding (base64) #IMPLIED diff --git a/chart.cgi b/chart.cgi index c60eedac4..1a080143a 100755 --- a/chart.cgi +++ b/chart.cgi @@ -35,8 +35,8 @@ # # JS-less chart creation - hard. # Broken image on error or no data - need to do much better. -# Centralise permission checking, so UserInGroup('editbugs') not scattered -# everywhere. +# Centralise permission checking, so Bugzilla->user->in_group('editbugs') +# not scattered everywhere. # User documentation :-) # # Bonus: @@ -45,16 +45,21 @@ use strict; use lib qw(.); -require "globals.pl"; use Bugzilla; use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::Util; use Bugzilla::Chart; use Bugzilla::Series; use Bugzilla::User; -my $cgi = Bugzilla->cgi; -my $template = Bugzilla->template; -my $vars = {}; +# For most scripts we don't make $cgi and $template global variables. But +# when preparing Bugzilla for mod_perl, this script used these +# variables in so many subroutines that it was easier to just +# make them globals. +local our $cgi = Bugzilla->cgi; +local our $template = Bugzilla->template; +local our $vars = {}; # Go back to query.cgi if we are adding a boolean chart parameter. if (grep(/^cmd-/, $cgi->param())) { @@ -70,7 +75,7 @@ my $series_id = $cgi->param('series_id'); # Because some actions are chosen by buttons, we can't encode them as the value # of the action param, because that value is localisation-dependent. So, we # encode it in the name, as "action-<action>". Some params even contain the -# series_id they apply to (e.g. subscribe, unsubscribe.) +# series_id they apply to (e.g. subscribe, unsubscribe). my @actions = grep(/^action-/, $cgi->param()); if ($actions[0] && $actions[0] =~ /^action-([^\d]+)(\d*)$/) { $action = $1; @@ -88,13 +93,13 @@ if ($action eq "search") { my $user = Bugzilla->login(LOGIN_REQUIRED); -UserInGroup(Param("chartgroup")) - || ThrowUserError("auth_failure", {group => Param("chartgroup"), +Bugzilla->user->in_group(Bugzilla->params->{"chartgroup"}) + || ThrowUserError("auth_failure", {group => Bugzilla->params->{"chartgroup"}, action => "use", object => "charts"}); # Only admins may create public queries -UserInGroup('admin') || $cgi->delete('public'); +Bugzilla->user->in_group('admin') || $cgi->delete('public'); # All these actions relate to chart construction. if ($action =~ /^(assemble|add|remove|sum|subscribe|unsubscribe)$/) { @@ -219,11 +224,11 @@ sub assertCanEdit { sub assertCanCreate { my ($cgi) = shift; - UserInGroup("editbugs") || ThrowUserError("illegal_series_creation"); + Bugzilla->user->in_group("editbugs") || ThrowUserError("illegal_series_creation"); # Check permission for frequency my $min_freq = 7; - if ($cgi->param('frequency') < $min_freq && !UserInGroup("admin")) { + if ($cgi->param('frequency') < $min_freq && !Bugzilla->user->in_group("admin")) { ThrowUserError("illegal_frequency", { 'minimum' => $min_freq }); } } diff --git a/checksetup.pl b/checksetup.pl index 451b7f039..eefff4918 100755 --- a/checksetup.pl +++ b/checksetup.pl @@ -35,4727 +35,461 @@ # Lance Larsh <lance.larsh@oracle.com> # A. Karl Kornel <karl@kornel.name> # Marc Schumann <wurblzap@gmail.com> -# Noel Cragg <noel@red-bean.com> -# -# -# -# Hey, what's this? -# -# 'checksetup.pl' is a script that is supposed to run during installation -# time and also after every upgrade. -# -# The goal of this script is to make the installation even easier. -# It does this by doing things for you as well as testing for problems -# in advance. -# -# You can run the script whenever you like. You SHOULD run it after -# you update Bugzilla, because it may then update your SQL table -# definitions to resync them with the code. -# -# Currently, this module does the following: -# -# - check for required perl modules -# - set defaults for local configuration variables -# - create and populate the data directory after installation -# - set the proper rights for the *.cgi, *.html, etc. files -# - verify that the code can access the database server -# - creates the database 'bugs' if it does not exist -# - creates the tables inside the database if they don't exist -# - automatically changes the table definitions if they are from -# an older version of Bugzilla -# - populates the groups -# - put the first user into all groups so that the system can -# be administrated -# - changes preexisting SQL tables if you change your local -# settings, e.g. when you add a new platform -# - ... and a whole lot more. -# -# There should be no need for Bugzilla Administrators to modify -# this script; all user-configurable stuff has been moved -# into a local configuration file called 'localconfig'. When that file -# in changed and 'checkconfig.pl' is run, then the user's changes -# will be reflected back into the database. -# -# Developers, however, have to modify this file at various places. To -# make this easier, there are some special tags for which one -# can search. -# -# To Search for -# -# add/delete local configuration variables --LOCAL-- -# check for more required modules --MODULES-- -# change the defaults for local configuration vars --LOCAL-- -# update the assigned file permissions --CHMOD-- -# add more database-related checks --DATABASE-- -# change table definitions --TABLE-- -# add more groups --GROUPS-- -# add user-adjustable settings --SETTINGS-- -# create initial administrator account --ADMIN-- -# -# Note: sometimes those special comments occur more than once. For -# example, --LOCAL-- is used at least 3 times in this code! --TABLE-- -# is also used more than once, so search for each and every occurrence! -# -# To operate checksetup non-interactively, run it with a single argument -# specifying a filename that contains the information usually obtained by -# prompting the user or by editing localconfig. -# -# The format of that file is as follows: -# -# -# $answer{'db_host'} = q[ -# $db_host = 'localhost'; -# $db_driver = 'mydbdriver'; -# $db_port = 3306; -# $db_name = 'mydbname'; -# $db_user = 'mydbuser'; -# ]; -# -# $answer{'db_pass'} = q[$db_pass = 'mydbpass';]; -# -# $answer{'ADMIN_OK'} = 'Y'; -# $answer{'ADMIN_EMAIL'} = 'myadmin@mydomain.net'; -# $answer{'ADMIN_PASSWORD'} = 'fooey'; -# $answer{'ADMIN_REALNAME'} = 'Joel Peshkin'; -# -# $answer{'SMTP_SERVER'} = 'mail.mydomain.net'; -# -# -# Note: Only information that supersedes defaults from LocalVar() -# function calls needs to be specified in this file. -# -use strict; +# This file has detailed POD docs, do "perldoc checksetup.pl" to see them. -BEGIN { - if ($^O =~ /MSWin32/i) { - require 5.008001; # for CGI 2.93 or higher - } - require 5.006_001; - use File::Basename; - chdir dirname($0); -} +###################################################################### +# Initialization +###################################################################### +use strict; +use 5.008; +use File::Basename; +use Getopt::Long qw(:config bundling); +use Pod::Usage; +use POSIX qw(setlocale LC_CTYPE); +use Safe; + +BEGIN { chdir dirname($0); } use lib "."; - -use vars qw( $db_name %answer ); use Bugzilla::Constants; +use Bugzilla::Install::Requirements; -my $silent; - -my %switch; -$switch{'no_templates'} = grep(/^--no-templates$/, @ARGV) - || grep(/^-t$/, @ARGV); +require 5.008001 if ON_WINDOWS; # for CGI 2.93 or higher -# The use of some Bugzilla modules brings in modules we need to test for -# Check first, via BEGIN -BEGIN { - - # However, don't run under -c (because of tests) - if (!$^C) { - -########################################################################### -# Check for help request. Display help page if --help/-h/-? was passed. -########################################################################### -my $help = grep(/^--help$/, @ARGV) || grep (/^-h$/, @ARGV) || grep (/^-\?$/, @ARGV) || 0; -help_page() if $help; - -sub help_page { - my $programname = $0; - $programname =~ s#^\./##; - print "$programname - checks your setup and updates your Bugzilla installation\n"; - print "\nUsage: $programname [SCRIPT [--verbose]] [--check-modules|--help]\n"; - print " [--no-templates]\n"; - print "\n"; - print " --help Display this help text.\n"; - print " --check-modules Only check for correct module dependencies and quit thereafter;\n"; - print " does not perform any changes.\n"; - print " --no-templates (-t) Don't compile the templates at all. Existing\n"; - print " compiled templates will remain; missing compiled\n"; - print " templates will not be created. (Used primarily by\n"; - print " developers to speed up checksetup.) Use this\n"; - print " switch at your own risk.\n"; - print " SCRIPT Name of script to drive non-interactive mode.\n"; - print " This script should define an \%answer hash whose\n"; - print " keys are variable names and the values answers to\n"; - print " all the questions checksetup.pl asks.\n"; - print " (See comments at top of $programname for more info.)\n"; - print " --verbose Output results of SCRIPT being processed.\n"; - print "\n"; - - exit 1; -} +###################################################################### +# Live Code +###################################################################### -########################################################################### -# Non-interactive override. Pass a filename on the command line which is -# a Perl script. This script defines a %answer hash whose names are tags -# and whose values are answers to all the questions checksetup.pl asks. -# Grep this file for references to that hash to see the tags to use for the -# possible answers. One example is ADMIN_EMAIL. -########################################################################### -if ($ARGV[0] && ($ARGV[0] !~ /^-/)) { - do $ARGV[0] - or ($@ && die("Error $@ processing $ARGV[0]")) - or die("Error $! processing $ARGV[0]"); - $silent = !grep(/^--no-silent$/, @ARGV) && !grep(/^--verbose$/, @ARGV); -} +my %switch; +GetOptions(\%switch, 'help|h|?', 'check-modules', 'no-templates|t', + 'verbose|v|no-silent', 'make-admin=s'); + +# Print the help message if that switch was selected. +pod2usage({-verbose => 1, -exitval => 1}) if $switch{'help'}; + +# Read in the "answers" file if it exists, for running in +# non-interactive mode. +my $answers_file = $ARGV[0]; +my $silent = $answers_file && !$switch{'verbose'}; + +display_version_and_os() unless $silent; +# Check required --MODULES-- +my $module_results = check_requirements(!$silent); +Bugzilla::Install::Requirements::print_module_instructions( + $module_results, !$silent); +exit if !$module_results->{pass}; +# Break out if checking the modules is all we have been asked to do. +exit if $switch{'check-modules'}; ########################################################################### -# Check required module +# Load Bugzilla Modules ########################################################################### -# -# Here we check for --MODULES-- -# - -print "\nChecking perl modules ...\n" unless $silent; - -# vers_cmp is adapted from Sort::Versions 1.3 1996/07/11 13:37:00 kjahds, -# which is not included with Perl by default, hence the need to copy it here. -# Seems silly to require it when this is the only place we need it... -sub vers_cmp { - if (@_ < 2) { die "not enough parameters for vers_cmp" } - if (@_ > 2) { die "too many parameters for vers_cmp" } - my ($a, $b) = @_; - my (@A) = ($a =~ /(\.|\d+|[^\.\d]+)/g); - my (@B) = ($b =~ /(\.|\d+|[^\.\d]+)/g); - my ($A,$B); - while (@A and @B) { - $A = shift @A; - $B = shift @B; - if ($A eq "." and $B eq ".") { - next; - } elsif ( $A eq "." ) { - return -1; - } elsif ( $B eq "." ) { - return 1; - } elsif ($A =~ /^\d+$/ and $B =~ /^\d+$/) { - return $A <=> $B if $A <=> $B; - } else { - $A = uc $A; - $B = uc $B; - return $A cmp $B if $A cmp $B; - } - } - @A <=> @B; -} - -# This was originally clipped from the libnet Makefile.PL, adapted here to -# use the above vers_cmp routine for accurate version checking. -sub have_vers { - my ($pkg, $wanted) = @_; - my ($msg, $vnum, $vstr); - no strict 'refs'; - printf("Checking for %15s %-9s ", $pkg, !$wanted?'(any)':"(v$wanted)") unless $silent; - - # Modules may change $SIG{__DIE__} and $SIG{__WARN__}, so localise them here - # so that later errors display 'normally' - local $::SIG{__DIE__}; - local $::SIG{__WARN__}; - - eval "require $pkg;"; - - # do this twice to avoid a "used only once" error for these vars - $vnum = ${"${pkg}::VERSION"} || ${"${pkg}::Version"} || 0; - $vnum = ${"${pkg}::VERSION"} || ${"${pkg}::Version"} || 0; - $vnum = -1 if $@; - - # CGI's versioning scheme went 2.75, 2.751, 2.752, 2.753, 2.76 - # That breaks the standard version tests, so we need to manually correct - # the version - if ($pkg eq 'CGI' && $vnum =~ /(2\.7\d)(\d+)/) { - $vnum = $1 . "." . $2; - } - - if ($vnum eq "-1") { # string compare just in case it's non-numeric - $vstr = "not found"; - } - elsif (vers_cmp($vnum,"0") > -1) { - $vstr = "found v$vnum"; - } - else { - $vstr = "found unknown version"; - } - - my $vok = (vers_cmp($vnum,$wanted) > -1); - print ((($vok) ? "ok: " : " "), "$vstr\n") unless $silent; - return $vok; -} - -# Check versions of dependencies. 0 for version = any version acceptable -my $modules = [ - { - name => 'AppConfig', - version => '1.52' - }, - { - name => 'CGI', - version => '2.93' - }, - { - name => 'Data::Dumper', - version => '0' - }, - { - name => 'Date::Format', - version => '2.21' - }, - { - name => 'DBI', - version => '1.38' - }, - { - name => 'File::Spec', - version => '0.84' - }, - { - name => 'File::Temp', - version => '0' - }, - { - name => 'Template', - version => '2.10' - }, - { - name => 'Text::Wrap', - version => '2001.0131' - }, - { - name => 'Mail::Mailer', - version => '1.67' - }, - { - name => 'MIME::Base64', - version => '3.01' - }, - { - # MIME::Parser is packaged as MIME::Tools on ActiveState Perl - name => $^O =~ /MSWin32/i ? 'MIME::Tools' : 'MIME::Parser', - version => '5.406' - }, - { - name => 'Storable', - version => '0' - }, -]; - -my %ppm_modules = ( - 'AppConfig' => 'AppConfig', - 'Chart::Base' => 'Chart', - 'CGI' => 'CGI', - 'Data::Dumper' => 'Data-Dumper', - 'Date::Format' => 'TimeDate', - 'DBI' => 'DBI', - 'DBD::mysql' => 'DBD-mysql', - 'Template' => 'Template-Toolkit', - 'PatchReader' => 'PatchReader', - 'GD' => 'GD', - 'GD::Graph' => 'GDGraph', - 'GD::Text::Align' => 'GDTextUtil', - 'Mail::Mailer' => 'MailTools', - 'Mail::Base64' => 'MIME-Base64', - 'MIME::Tools' => 'MIME-Tools', - 'Template::Plugin::GD' => 'Template', -); - -sub install_command { - my $module = shift; - if ($^O =~ /MSWin32/i) { - return "ppm install " . $ppm_modules{$module} if exists $ppm_modules{$module}; - return "ppm install " . $module; - } else { - return "$^X -MCPAN -e 'install \"$module\"'"; - } -} - -$::root = ($^O =~ /MSWin32/i ? 'Administrator' : 'root'); - -my %missing = (); - -foreach my $module (@{$modules}) { - unless (have_vers($module->{name}, $module->{version})) { - $missing{$module->{name}} = $module->{version}; - } -} - -print "\nThe following Perl modules are optional:\n" unless $silent; -my $gd = have_vers("GD","1.20"); -my $template_gd = have_vers('Template::Plugin::GD::Image', 0); -my $chartbase = have_vers("Chart::Base","1.0"); -my $xmlparser = have_vers("XML::Twig",0); -my $gdgraph = have_vers("GD::Graph",0); -my $gdtextalign = have_vers("GD::Text::Align",0); -my $patchreader = have_vers("PatchReader","0.9.4"); -my $imagemagick = have_vers("Image::Magick",0); -my $html_parser = have_vers("HTML::Parser", ($] >= 5.008) ? "3.40" : 0); -my $scrubber = have_vers("HTML::Scrubber", 0); - -print "\n" unless $silent; - -if ($^O =~ /MSWin32/i && !$silent) { - print "All the required modules are available at:\n"; - print " http://landfill.bugzilla.org/ppm/\n"; - print "You can add the repository with the following command:\n"; - print " ppm rep add bugzilla http://landfill.bugzilla.org/ppm/\n\n"; -} +# It's never safe to "use" a Bugzilla module in checksetup. If a module +# prerequisite is missing, and you "use" a module that requires it, +# then instead of our nice normal checksetup message, the user would +# get a cryptic perl error about the missing module. -if ((!$gd || !$chartbase) && !$silent) { - print "If you you want to see graphical bug charts (plotting historical "; - print "data over \ntime), you should install libgd and the following Perl "; - print "modules:\n\n"; - print "GD: " . install_command("GD") ."\n" if !$gd; - print "Chart: " . install_command("Chart::Base") . "\n" if !$chartbase; - print "\n"; -} -if (!$xmlparser && !$silent) { - print "If you want to use the bug import/export feature to move bugs to\n", - "or from other bugzilla installations, you will need to install\n ", - "the XML::Twig module by running (as $::root):\n\n", - " " . install_command("XML::Twig") . "\n\n"; -} -if (!$imagemagick && !$silent) { - print "If you want to convert BMP image attachments to PNG to conserve\n", - "disk space, you will need to install the ImageMagick application\n", - "Available from http://www.imagemagick.org, and the Image::Magick\n", - "Perl module by running (as $::root):\n\n", - " " . install_command("Image::Magick") . "\n\n"; +# We need $::ENV{'PATH'} to remain defined. +my $env = $::ENV{'PATH'}; +require Bugzilla; +$::ENV{'PATH'} = $env; -} -if ((!$gd || !$gdgraph || !$gdtextalign || !$template_gd) && !$silent) { - print "If you you want to see graphical bug reports (bar, pie and line "; - print "charts of \ncurrent data), you should install libgd and the "; - print "following Perl modules:\n\n"; - print "GD: " . install_command("GD") . "\n" if !$gd; - print "GD::Graph: " . install_command("GD::Graph") . "\n" - if !$gdgraph; - print "GD::Text::Align: " . install_command("GD::Text::Align") . "\n" - if !$gdtextalign; - print "Template::Plugin::GD: " . install_command('Template::Plugin::GD') - . "\n" if !$template_gd; - print "\n"; -} -if (!$patchreader && !$silent) { - print "If you want to see pretty HTML views of patches, you should "; - print "install the \nPatchReader module:\n"; - print "PatchReader: " . install_command("PatchReader") . "\n"; -} -if ((!$scrubber || !$html_parser) && !$silent) { - print "If you want additional HTML tags within product and group "; - print "descriptions,\nyou should install:\n"; - print "HTML::Scrubber: " . install_command("HTML::Scrubber") . "\n" - if !$scrubber; - print "HTML::Parser: " . install_command("HTML::Parser") . "\n" - if !$html_parser; - print "\n"; -} +require Bugzilla::Config; +import Bugzilla::Config qw(:admin); -if (%missing) { - print "\n\n"; - print "Bugzilla requires some Perl modules which are either missing from\n", - "your system, or the version on your system is too old.\n", - "They can be installed by running (as $::root) the following:\n"; - foreach my $module (keys %missing) { - print " " . install_command("$module") . "\n"; - if ($missing{$module} > 0) { - print " Minimum version required: $missing{$module}\n"; - } - } - print "\n"; - exit; -} +require Bugzilla::Install::Localconfig; +import Bugzilla::Install::Localconfig qw(update_localconfig); -} -} +require Bugzilla::Install::Filesystem; +import Bugzilla::Install::Filesystem qw(update_filesystem create_htaccess + fix_all_file_permissions); +require Bugzilla::Install::DB; +require Bugzilla::DB; +require Bugzilla::Template; +require Bugzilla::Field; +require Bugzilla::Install; -# Break out if checking the modules is all we have been asked to do. -exit if grep(/^--check-modules$/, @ARGV); +Bugzilla->usage_mode(USAGE_MODE_CMDLINE); +Bugzilla->installation_mode(INSTALLATION_MODE_NON_INTERACTIVE) if $answers_file; +Bugzilla->installation_answers($answers_file); -# If we're running on Windows, reset the input line terminator so that -# console input works properly - loading CGI tends to mess it up - -if ($^O =~ /MSWin/i) { - $/ = "\015\012"; -} +# When we're running at the command line, we need to pick the right +# language before ever creating a template object. +$ENV{'HTTP_ACCEPT_LANGUAGE'} ||= setlocale(LC_CTYPE); ########################################################################### -# Global definitions +# Check and update --LOCAL-- configuration ########################################################################### -use Bugzilla::Config qw(:DEFAULT :admin :locations); - -# 12/17/00 justdave@syndicomm.com - removed declarations of the localconfig -# variables from this location. We don't want these declared here. They'll -# automatically get declared in the process of reading in localconfig, and -# this way we can look in the symbol table to see if they've been declared -# yet or not. +print "Reading " . bz_locations()->{'localconfig'} . "...\n" unless $silent; +update_localconfig({ output => !$silent }); +my $lc_hash = Bugzilla->localconfig; ########################################################################### -# Check and update local configuration +# Check --DATABASE-- setup ########################################################################### -# -# This is quite tricky. But fun! -# -# First we read the file 'localconfig'. Then we check if the variables we -# need are defined. If not, we will append the new settings to -# localconfig, instruct the user to check them, and stop. -# -# Why do it this way? -# -# Assume we will enhance Bugzilla and eventually more local configuration -# stuff arises on the horizon. -# -# But the file 'localconfig' is not in the Bugzilla CVS or tarfile. You -# know, we never want to overwrite your own version of 'localconfig', so -# we can't put it into the CVS/tarfile, can we? -# -# Now, when we need a new variable, we simply add the necessary stuff to -# checksetup. When the user gets the new version of Bugzilla from CVS and -# runs checksetup, it finds out "Oh, there is something new". Then it adds -# some default value to the user's local setup and informs the user to -# check that to see if it is what the user wants. -# -# Cute, ey? -# +# At this point, localconfig is defined and is readable. So we know +# everything we need to create the DB. We have to create it early, +# because some data required to populate data/params is stored in the DB. -print "Checking user setup ...\n" unless $silent; -$@ = undef; -do $localconfig; -if ($@) { # capture errors in localconfig, bug 97290 - print STDERR <<EOT; -An error has occurred while reading your -'localconfig' file. The text of the error message is: - -$@ - -Please fix the error in your 'localconfig' file. -Alternately rename your 'localconfig' file, rerun -checksetup.pl, and re-enter your answers. - - \$ mv -f localconfig localconfig.old - \$ ./checksetup.pl - - -EOT - die "Syntax error in localconfig"; -} - -sub LocalVarExists -{ - my ($name) = @_; - return $main::{$name}; # if localconfig declared it, we're done. -} - -my $newstuff = ""; -sub LocalVar -{ - my ($name, $definition) = @_; - return if LocalVarExists($name); # if localconfig declared it, we're done. - $newstuff .= " " . $name; - open FILE, '>>', $localconfig; - print FILE ($answer{$name} or $definition), "\n\n"; - close FILE; -} +Bugzilla::DB::bz_check_requirements(!$silent); +Bugzilla::DB::bz_create_database() if $lc_hash->{'db_check'}; - -# -# Set up the defaults for the --LOCAL-- variables below: -# - -LocalVar('index_html', <<'END'); -# -# With the introduction of a configurable index page using the -# template toolkit, Bugzilla's main index page is now index.cgi. -# Most web servers will allow you to use index.cgi as a directory -# index, and many come preconfigured that way, but if yours doesn't -# then you'll need an index.html file that provides redirection -# to index.cgi. Setting $index_html to 1 below will allow -# checksetup.pl to create one for you if it doesn't exist. -# NOTE: checksetup.pl will not replace an existing file, so if you -# wish to have checksetup.pl create one for you, you must -# make sure that index.html doesn't already exist -$index_html = 0; -END - - -if (!LocalVarExists('cvsbin')) { - my $cvs_executable; - if ($^O !~ /MSWin32/i) { - $cvs_executable = `which cvs`; - if ($cvs_executable =~ /no cvs/ || $cvs_executable eq '') { - # If which didn't find it, just set to blank - $cvs_executable = ""; - } else { - chomp $cvs_executable; - } - } else { - $cvs_executable = ""; - } - - LocalVar('cvsbin', <<"END"); -# -# For some optional functions of Bugzilla (such as the pretty-print patch -# viewer), we need the cvs binary to access files and revisions. -# Because it's possible that this program is not in your path, you can specify -# its location here. Please specify the full path to the executable. -\$cvsbin = "$cvs_executable"; -END -} - - -if (!LocalVarExists('interdiffbin')) { - my $interdiff_executable; - if ($^O !~ /MSWin32/i) { - $interdiff_executable = `which interdiff`; - if ($interdiff_executable =~ /no interdiff/ || - $interdiff_executable eq '') { - if (!$silent) { - print "\nOPTIONAL NOTE: If you want to be able to "; - print "use the\n 'difference between two patches' feature"; - print "of Bugzilla (requires\n the PatchReader Perl module "; - print "as well), you should install\n patchutils from "; - print "http://cyberelk.net/tim/patchutils/\n\n"; - } - - # If which didn't find it, set to blank - $interdiff_executable = ""; - } else { - chomp $interdiff_executable; - } - } else { - $interdiff_executable = ""; - } - - LocalVar('interdiffbin', <<"END"); - -# -# For some optional functions of Bugzilla (such as the pretty-print patch -# viewer), we need the interdiff binary to make diffs between two patches. -# Because it's possible that this program is not in your path, you can specify -# its location here. Please specify the full path to the executable. -\$interdiffbin = "$interdiff_executable"; -END -} - - -if (!LocalVarExists('diffpath')) { - my $diff_binaries; - if ($^O !~ /MSWin32/i) { - $diff_binaries = `which diff`; - if ($diff_binaries =~ /no diff/ || $diff_binaries eq '') { - # If which didn't find it, set to blank - $diff_binaries = ""; - } else { - $diff_binaries =~ s:/diff\n$::; - } - } else { - $diff_binaries = ""; - } - - LocalVar('diffpath', <<"END"); - -# -# The interdiff feature needs diff, so we have to have that path. -# Please specify the directory name only; do not use trailing slash. -\$diffpath = "$diff_binaries"; -END -} - - -LocalVar('create_htaccess', <<'END'); -# -# If you are using Apache as your web server, Bugzilla can create .htaccess -# files for you that will instruct Apache not to serve files that shouldn't -# be accessed from the web (like your local configuration data and non-cgi -# executable files). For this to work, the directory your Bugzilla -# installation is in must be within the jurisdiction of a <Directory> block -# in the httpd.conf file that has 'AllowOverride Limit' in it. If it has -# 'AllowOverride All' or other options with Limit, that's fine. -# (Older Apache installations may use an access.conf file to store these -# <Directory> blocks.) -# If this is set to 1, Bugzilla will create these files if they don't exist. -# If this is set to 0, Bugzilla will not create these files. -$create_htaccess = 1; -END - -my $webservergroup_default; -if ($^O !~ /MSWin32/i) { - $webservergroup_default = 'apache'; -} else { - $webservergroup_default = ''; -} - -LocalVar('webservergroup', <<"END"); -# -# This is the group your web server runs as. -# If you have a windows box, ignore this setting. -# If you do not have access to the group your web server runs under, -# set this to "". If you do set this to "", then your Bugzilla installation -# will be _VERY_ insecure, because some files will be world readable/writable, -# and so anyone who can get local access to your machine can do whatever they -# want. You should only have this set to "" if this is a testing installation -# and you cannot set this up any other way. YOU HAVE BEEN WARNED! -# If you set this to anything other than "", you will need to run checksetup.pl -# as $::root, or as a user who is a member of the specified group. -\$webservergroup = "$webservergroup_default"; -END - - - -LocalVar('db_driver', ' -# -# What SQL database to use. Default is mysql. List of supported databases -# can be obtained by listing Bugzilla/DB directory - every module corresponds -# to one supported database and the name corresponds to a driver name. -# -$db_driver = "mysql"; -'); -LocalVar('db_host', q[ -# -# How to access the SQL database: -# -$db_host = 'localhost'; # where is the database? -$db_name = 'bugs'; # name of the SQL database -$db_user = 'bugs'; # user to attach to the SQL database - -# Sometimes the database server is running on a non-standard -# port. If that's the case for your database server, set this -# to the port number that your database server is running on. -# Setting this to 0 means "use the default port for my database -# server." -$db_port = 0; -]); -LocalVar('db_pass', q[ -# -# Enter your database password here. It's normally advisable to specify -# a password for your bugzilla database user. -# If you use apostrophe (') or a backslash (\) in your password, you'll -# need to escape it by preceding it with a '\' character. (\') or (\\) -# (Far simpler just not to use those characters.) -# -$db_pass = ''; -]); - -LocalVar('db_sock', q[ -# MySQL Only: Enter a path to the unix socket for MySQL. If this is -# blank, then MySQL's compiled-in default will be used. You probably -# want that. -$db_sock = ''; -]); - -LocalVar('db_check', q[ -# -# Should checksetup.pl try to verify that your database setup is correct? -# (with some combinations of database servers/Perl modules/moonphase this -# doesn't work) -# -$db_check = 1; -]); - -my @deprecatedvars; -push(@deprecatedvars, '@severities') if (LocalVarExists('severities')); -push(@deprecatedvars, '@priorities') if (LocalVarExists('priorities')); -push(@deprecatedvars, '@opsys') if (LocalVarExists('opsys')); -push(@deprecatedvars, '@platforms') if (LocalVarExists('platforms')); - -if (@deprecatedvars) { - print "\nThe following settings in your localconfig file", - " are no longer used:\n " . join(", ", @deprecatedvars) . - "\nThis data is now controlled through the Bugzilla", - " administrative interface.\nWe recommend you remove these", - " settings from localconfig after checksetup\nruns successfully.\n"; -} -if (LocalVarExists('mysqlpath')) { - print "\nThe \$mysqlpath setting in your localconfig file ", - "is no longer required.\nWe recommend you remove it.\n"; -} - -if ($newstuff ne "") { - print "\nThis version of Bugzilla contains some variables that you may \n", - "want to change and adapt to your local settings. Please edit the\n", - "file '$localconfig' and rerun checksetup.pl\n\n", - "The following variables are new to localconfig since you last ran\n", - "checksetup.pl: $newstuff\n\n"; - exit; -} - -# 2000-Dec-18 - justdave@syndicomm.com - see Bug 52921 -# This is a hack to read in the values defined in localconfig without getting -# them defined at compile time if they're missing from localconfig. -# Ideas swiped from pp. 281-282, O'Reilly's "Programming Perl 2nd Edition" -# Note that we won't need to do this in globals.pl because globals.pl couldn't -# care less whether they were defined ahead of time or not. -my $my_db_check = ${*{$main::{'db_check'}}{SCALAR}}; -my $my_db_driver = ${*{$main::{'db_driver'}}{SCALAR}}; -my $my_db_name = ${*{$main::{'db_name'}}{SCALAR}}; -my $my_index_html = ${*{$main::{'index_html'}}{SCALAR}}; -my $my_create_htaccess = ${*{$main::{'create_htaccess'}}{SCALAR}}; -my $my_webservergroup = ${*{$main::{'webservergroup'}}{SCALAR}}; - -if ($my_webservergroup && !$silent) { - if ($^O !~ /MSWin32/i) { - # if on unix, see if we need to print a warning about a webservergroup - # that we can't chgrp to - my $webservergid = (getgrnam($my_webservergroup))[2] - or die("no such group: $my_webservergroup"); - if ($< != 0 && !grep($_ eq $webservergid, split(" ", $)))) { - print <<EOF; - -Warning: you have entered a value for the "webservergroup" parameter in -localconfig, but you are not either a) running this script as $::root; or b) a -member of this group. This can cause permissions problems and decreased -security. If you experience problems running Bugzilla scripts, log in as -$::root and re-run this script, become a member of the group, or remove the -value of the "webservergroup" parameter. Note that any warnings about -"uninitialized values" that you may see below are caused by this. - -EOF - } - } - - else { - # if on Win32, print a reminder that setting this value adds no security - print <<EOF; - -Warning: You have set webservergroup in your localconfig. -Please understand that this does not bring you any security when -running under Windows. -Verify that the file permissions in your Bugzilla directory are -suitable for your system. -Avoid unnecessary write access. - -EOF - } - -} else { - # There's no webservergroup, this is very very very very bad. - # However, if we're being run on windows, then this option doesn't - # really make sense. Doesn't make it any more secure either, though, - # but don't print the message, since they can't do anything about it. - if (($^O !~ /MSWin32/i) && !$silent) { - print <<EOF; - -******************************************************************************** -WARNING! You have not entered a value for the "webservergroup" parameter -in localconfig. This means that certain files and directories which need -to be editable by both you and the webserver must be world writable, and -other files (including the localconfig file which stores your database -password) must be world readable. This means that _anyone_ who can obtain -local access to this machine can do whatever they want to your Bugzilla -installation, and is probably also able to run arbitrary Perl code as the -user that the webserver runs as. - -You really, really, really need to change this setting. -******************************************************************************** - -EOF - } -} +# now get a handle to the database: +my $dbh = Bugzilla->dbh; +# Create the tables, and do any database-specific schema changes. +$dbh->bz_setup_database(); +# Populate the tables that hold the values for the <select> fields. +$dbh->bz_populate_enum_tables(); ########################################################################### -# Check data directory +# Check --DATA-- directory ########################################################################### -# -# Create initial --DATA-- directory and make the initial empty files there: -# - -# The |require "globals.pl"| above ends up creating a template object with -# a COMPILE_DIR of "$datadir". This means that TT creates the directory for us, -# so this code wouldn't run if we just checked for the existence of the -# directory. Instead, check for the existence of '$datadir/nomail', which is -# created in this block -unless (-d $datadir && -e "$datadir/nomail") { - print "Creating data directory ($datadir) ...\n"; - # permissions for non-webservergroup are fixed later on - mkdir $datadir, 0770; - mkdir "$datadir/mimedump-tmp", 01777; - open FILE, '>>', "$datadir/nomail"; close FILE; - open FILE, '>>', "$datadir/mail"; close FILE; -} - - -unless (-d $attachdir) { - print "Creating local attachments directory ...\n"; - # permissions for non-webservergroup are fixed later on - mkdir $attachdir, 0770; -} - - -# 2000-12-14 New graphing system requires a directory to put the graphs in -# This code copied from what happens for the data dir above. -# If the graphs dir is not present, we assume that they have been using -# a Bugzilla with the old data format, and upgrade their data files. - -# NB - the graphs dir isn't movable yet, unlike the datadir -unless (-d 'graphs') { - print "Creating graphs directory...\n"; - # permissions for non-webservergroup are fixed later on - mkdir 'graphs', 0770; - # Upgrade data format - foreach my $in_file (glob("$datadir/mining/*")) - { - # Don't try and upgrade image or db files! - if (($in_file =~ /\.gif$/i) || - ($in_file =~ /\.png$/i) || - ($in_file =~ /\.db$/i) || - ($in_file =~ /\.orig$/i)) { - next; - } - - rename("$in_file", "$in_file.orig") or next; - open(IN, "$in_file.orig") or next; - open(OUT, '>', $in_file) or next; - - # Fields in the header - my @declared_fields = (); - - # Fields we changed to half way through by mistake - # This list comes from an old version of collectstats.pl - # This part is only for people who ran later versions of 2.11 (devel) - my @intermediate_fields = qw(DATE UNCONFIRMED NEW ASSIGNED REOPENED - RESOLVED VERIFIED CLOSED); - - # Fields we actually want (matches the current collectstats.pl) - my @out_fields = qw(DATE NEW ASSIGNED REOPENED UNCONFIRMED RESOLVED - VERIFIED CLOSED FIXED INVALID WONTFIX LATER REMIND - DUPLICATE WORKSFORME MOVED); - - while (<IN>) { - if (/^# fields?: (.*)\s$/) { - @declared_fields = map uc, (split /\||\r/, $1); - print OUT "# fields: ", join('|', @out_fields), "\n"; - } - elsif (/^(\d+\|.*)/) { - my @data = split /\||\r/, $1; - my %data = (); - if (@data == @declared_fields) { - # old format - for my $i (0 .. $#declared_fields) { - $data{$declared_fields[$i]} = $data[$i]; - } - } - elsif (@data == @intermediate_fields) { - # Must have changed over at this point - for my $i (0 .. $#intermediate_fields) { - $data{$intermediate_fields[$i]} = $data[$i]; - } - } - elsif (@data == @out_fields) { - # This line's fine - it has the right number of entries - for my $i (0 .. $#out_fields) { - $data{$out_fields[$i]} = $data[$i]; - } - } - else { - print "Oh dear, input line $. of $in_file had " . - scalar(@data) . " fields\n"; - print "This was unexpected. You may want to check your data files.\n"; - } - - print OUT join('|', map { - defined ($data{$_}) ? ($data{$_}) : "" - } @out_fields), "\n"; - } - else { - print OUT; - } - } - - close(IN); - close(OUT); - } -} - -unless (-d "$datadir/mining") { - mkdir "$datadir/mining", 0700; -} - -unless (-d "$webdotdir") { - # perms/ownership are fixed up later - mkdir "$webdotdir", 0700; -} - -if (!-d "skins/custom") { - # perms/ownership are fixed up later - mkdir "skins/custom", 0700; -} - -if (!-e "skins/.cvsignore") { - open CVSIGNORE, '>>', "skins/.cvsignore"; - print CVSIGNORE ".cvsignore\n"; - print CVSIGNORE "custom\n"; - close CVSIGNORE; -} - -# Create custom stylesheets for each standard stylesheet. -foreach my $standard (<skins/standard/*.css>) { - my $custom = $standard; - $custom =~ s|^skins/standard|skins/custom|; - if (!-e $custom) { - open STYLESHEET, '>', $custom; - print STYLESHEET <<"END"; -/* - * Custom rules for $standard. - * The rules you put here override rules in that stylesheet. - */ -END - close STYLESHEET; - } -} - -if ($my_create_htaccess) { - my $fileperm = 0644; - my $dirperm = 01777; - if ($my_webservergroup) { - $fileperm = 0640; - $dirperm = 0770; - } - if (!-e ".htaccess") { - print "Creating .htaccess...\n"; - open HTACCESS, '>', '.htaccess'; - print HTACCESS <<'END'; -# don't allow people to retrieve non-cgi executable files or our private data -<FilesMatch ^(.*\.pm|.*\.pl|.*localconfig.*)$> - deny from all -</FilesMatch> -END - close HTACCESS; - chmod $fileperm, ".htaccess"; - } else { - # 2002-12-21 Bug 186383 - open HTACCESS, ".htaccess"; - my $oldaccess = ""; - while (<HTACCESS>) { - $oldaccess .= $_; - } - close HTACCESS; - my $repaired = 0; - if ($oldaccess =~ s/\|localconfig\|/\|.*localconfig.*\|/) { - $repaired = 1; - } - if ($oldaccess !~ /\(\.\*\\\.pm\|/) { - $oldaccess =~ s/\(/(.*\\.pm\|/; - $repaired = 1; - } - if ($repaired) { - print "Repairing .htaccess...\n"; - open HTACCESS, '>', '.htaccess'; - print HTACCESS $oldaccess; - close HTACCESS; - } - - } - if (!-e "$attachdir/.htaccess") { - print "Creating $attachdir/.htaccess...\n"; - open HTACCESS, ">$attachdir/.htaccess"; - print HTACCESS <<'END'; -# nothing in this directory is retrievable unless overridden by an .htaccess -# in a subdirectory; -deny from all -END - close HTACCESS; - chmod $fileperm, "$attachdir/.htaccess"; - } - if (!-e "Bugzilla/.htaccess") { - print "Creating Bugzilla/.htaccess...\n"; - open HTACCESS, '>', 'Bugzilla/.htaccess'; - print HTACCESS <<'END'; -# nothing in this directory is retrievable unless overridden by an .htaccess -# in a subdirectory -deny from all -END - close HTACCESS; - chmod $fileperm, "Bugzilla/.htaccess"; - } - # Even though $datadir may not (and should not) be in the webtree, - # we can't know for sure, so create the .htaccess anyway. It's harmless - # if it's not accessible... - if (!-e "$datadir/.htaccess") { - print "Creating $datadir/.htaccess...\n"; - open HTACCESS, '>', "$datadir/.htaccess"; - print HTACCESS <<'END'; -# nothing in this directory is retrievable unless overridden by an .htaccess -# in a subdirectory; the only exception is duplicates.rdf, which is used by -# duplicates.xul and must be loadable over the web -deny from all -<Files duplicates.rdf> - allow from all -</Files> -END - close HTACCESS; - chmod $fileperm, "$datadir/.htaccess"; - } - # Ditto for the template dir - if (!-e "$templatedir/.htaccess") { - print "Creating $templatedir/.htaccess...\n"; - open HTACCESS, '>', "$templatedir/.htaccess"; - print HTACCESS <<'END'; -# nothing in this directory is retrievable unless overridden by an .htaccess -# in a subdirectory -deny from all -END - close HTACCESS; - chmod $fileperm, "$templatedir/.htaccess"; - } - if (!-e "$webdotdir/.htaccess") { - print "Creating $webdotdir/.htaccess...\n"; - open HTACCESS, '>', "$webdotdir/.htaccess"; - print HTACCESS <<'END'; -# Restrict access to .dot files to the public webdot server at research.att.com -# if research.att.com ever changes their IP, or if you use a different -# webdot server, you'll need to edit this -<FilesMatch \.dot$> - Allow from 192.20.225.0/24 - Deny from all -</FilesMatch> - -# Allow access to .png files created by a local copy of 'dot' -<FilesMatch \.png$> - Allow from all -</FilesMatch> - -# And no directory listings, either. -Deny from all -END - close HTACCESS; - chmod $fileperm, "$webdotdir/.htaccess"; - } - else { - # The public webdot IP address changed. - my $webdot = new IO::File("$webdotdir/.htaccess", 'r') - || die "$webdotdir/.htaccess: $!"; - my $webdot_data; - { local $/; $webdot_data = <$webdot>; } - $webdot->close; - if ($webdot_data =~ /192\.20\.225\.10/) { - print "Repairing $webdotdir/.htaccess...\n"; - $webdot_data =~ s/192\.20\.225\.10/192.20.225.0\/24/g; - $webdot = new IO::File("$webdotdir/.htaccess", 'w') || die $!; - print $webdot $webdot_data; - $webdot->close; - } - } - -} - -if ($my_index_html) { - if (!-e "index.html") { - print "Creating index.html...\n"; - open HTML, '>', 'index.html'; - print HTML <<'END'; -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> -<head> -<meta http-equiv="Refresh" content="0; URL=index.cgi"> -</head> -<body> -<h1>I think you are looking for <a href="index.cgi">index.cgi</a></h1> -</body> -</html> -END - close HTML; - } - else { - open HTML, "index.html"; - if (! grep /index\.cgi/, <HTML>) { - print "\n\n"; - print "*** It appears that you still have an old index.html hanging\n"; - print " around. The contents of this file should be moved into a\n"; - print " template and placed in the 'en/custom' directory within"; - print " your template directory.\n\n"; - } - close HTML; - } -} - -# Just to be sure ... -unlink "$datadir/versioncache"; - -# Check for a new install - -my $newinstall = !-e "$datadir/params"; +update_filesystem({ index_html => $lc_hash->{'index_html'} }); +create_htaccess() if $lc_hash->{'create_htaccess'}; # Remove parameters from the params file that no longer exist in Bugzilla, # and set the defaults for new ones - -my @oldparams = UpdateParams(); - -if (@oldparams) { - open(PARAMFILE, '>>', 'old-params.txt') - || die "$0: Can't open old-params.txt for writing: $!\n"; - - print "The following parameters are no longer used in Bugzilla, " . - "and so have been\nmoved from your parameters file " . - "into old-params.txt:\n"; - - foreach my $p (@oldparams) { - my ($item, $value) = @{$p}; - - print PARAMFILE "\n\n$item:\n$value\n"; - - print $item; - print ", " unless $item eq $oldparams[$#oldparams]->[0]; - } - print "\n"; - close PARAMFILE; -} - -# Set mail_delivery_method to SMTP and prompt for SMTP server -# if running on Windows and no third party sendmail wrapper -# is available -if ($^O =~ /MSWin32/i - && Param('mail_delivery_method') eq 'sendmail' - && !-e SENDMAIL_EXE) -{ - print "\nBugzilla requires an SMTP server to function on Windows.\n" . - "Please enter your SMTP server's hostname: "; - my $smtp = $answer{'SMTP_SERVER'} - || ($silent && die("cant preload SMTP_SERVER")) - || <STDIN>; - chomp $smtp; - if (!$smtp) { - print "\nWarning: No SMTP Server provided, defaulting to localhost\n"; - $smtp = 'localhost'; - } - SetParam('mail_delivery_method', 'smtp'); - SetParam('smtpserver', $smtp); -} - -# Enable UTF-8 on new installs -if ($newinstall) { - SetParam('utf8', 1); -} - -# WriteParams will only write out still-valid entries -WriteParams(); - -unless ($switch{'no_templates'}) { - if (-e "$datadir/template") { - print "Removing existing compiled templates ...\n" unless $silent; - - File::Path::rmtree("$datadir/template"); - - #Check that the directory was really removed - if(-e "$datadir/template") { - print "\n\n"; - print "The directory '$datadir/template' could not be removed.\n"; - print "Please remove it manually and rerun checksetup.pl.\n\n"; - exit; - } - } - - # Precompile stuff. This speeds up initial access (so the template isn't - # compiled multiple times simultaneously by different servers), and helps - # to get the permissions right. - sub compile { - my $name = $File::Find::name; - - return if (-d $name); - return if ($name =~ /\/CVS\//); - return if ($name !~ /\.tmpl$/); - $name =~ s/\Q$::templatepath\E\///; # trim the bit we don't pass to TT - - # Compile the template but throw away the result. This has the side- - # effect of writing the compiled version to disk. - $::template->context()->template($name); - } - - eval("use Template"); - - { - print "Precompiling templates ...\n" unless $silent; - - use File::Find; - require Bugzilla::Template; - - # Don't hang on templates which use the CGI library - eval("use CGI qw(-no_debug)"); - - use File::Spec; - opendir(DIR, $templatedir) || die "Can't open '$templatedir': $!"; - my @files = grep { /^[a-z-]+$/i } readdir(DIR); - closedir DIR; - - foreach my $dir (@files) { - next if($dir =~ /^CVS$/i); - -d "$templatedir/$dir/custom" || -d "$templatedir/$dir/default" - || next; - local $ENV{'HTTP_ACCEPT_LANGUAGE'} = $dir; - SetParam("languages", "$dir,en"); - $::template = Bugzilla::Template->create(clean_cache => 1); - my @templatepaths; - foreach my $subdir (qw(custom extension default)) { - $::templatepath = File::Spec->catdir($templatedir, $dir, $subdir); - next unless -d $::templatepath; - # Traverse the template hierarchy. - find({ wanted => \&compile, no_chdir => 1 }, $::templatepath); - } - } - } -} +update_params(); ########################################################################### -# Set proper rights +# Pre-compile --TEMPLATE-- code ########################################################################### -# -# Here we use --CHMOD-- and friends to set the file permissions -# -# The rationale is that the web server generally runs as apache, so the cgi -# scripts should not be writable for apache, otherwise someone may be possible -# to change the cgi's when exploiting some security flaw somewhere (not -# necessarily in Bugzilla!) -# -# Also, some *.pl files are executable, some are not. -# -# +++ Can anybody tell me what a Windows Perl would do with this code? -# -# Changes 03/14/00 by SML -# -# This abstracts out what files are executable and what ones are not. It makes -# for slightly neater code and lets us do things like determine exactly which -# files are executable and which ones are not. -# -# Not all directories have permissions changed on them. i.e., changing ./CVS -# to be 0640 is bad. -# -# Fixed bug in chmod invocation. chmod (at least on my linux box running perl -# 5.005 needs a valid first argument, not 0. -# -# (end changes, 03/14/00 by SML) -# -# Changes 15/06/01 kiko@async.com.br -# -# Fix file permissions for non-webservergroup installations (see -# http://bugzilla.mozilla.org/show_bug.cgi?id=71555). I'm setting things -# by default to world readable/executable for all files, and -# world-writable (with sticky on) to data and graphs. -# - -# These are the files which need to be marked executable -my @executable_files = ('whineatnews.pl', 'collectstats.pl', - 'checksetup.pl', 'importxml.pl', 'runtests.pl', 'testserver.pl', - 'whine.pl'); - -# tell me if a file is executable. All CGI files and those in @executable_files -# are executable -sub isExecutableFile { - my ($file) = @_; - if ($file =~ /\.cgi/) { - return 1; - } - - my $exec_file; - foreach $exec_file (@executable_files) { - if ($file eq $exec_file) { - return 1; - } - } - return undef; -} - -# fix file (or files - wildcards ok) permissions -sub fixPerms { - my ($file_pattern, $owner, $group, $umask, $do_dirs) = @_; - my @files = glob($file_pattern); - my $execperm = 0777 & ~ $umask; - my $normperm = 0666 & ~ $umask; - foreach my $file (@files) { - next if (!-e $file); - # do not change permissions on directories here unless $do_dirs is set - if (!(-d $file)) { - chown $owner, $group, $file; - # check if the file is executable. - if (isExecutableFile($file)) { - #printf ("Changing $file to %o\n", $execperm); - chmod $execperm, $file; - } else { - #printf ("Changing $file to %o\n", $normperm); - chmod $normperm, $file; - } - } - elsif ($do_dirs) { - chown $owner, $group, $file; - if ($file =~ /CVS$/) { - chmod 0700, $file; - } - else { - #printf ("Changing $file to %o\n", $execperm); - chmod $execperm, $file; - fixPerms("$file/.htaccess", $owner, $group, $umask, $do_dirs); - # do the contents of the directory - fixPerms("$file/*", $owner, $group, $umask, $do_dirs); - } - } - } -} - -if ($^O !~ /MSWin32/i) { - if ($my_webservergroup) { - # Funny! getgrname returns the GID if fed with NAME ... - my $webservergid = getgrnam($my_webservergroup) - or die("no such group: $my_webservergroup"); - # chown needs to be called with a valid uid, not 0. $< returns the - # caller's uid. Maybe there should be a $bugzillauid, and call - # with that userid. - fixPerms('.htaccess', $<, $webservergid, 027); # glob('*') doesn't catch dotfiles - fixPerms("$datadir/.htaccess", $<, $webservergid, 027); - fixPerms("$datadir/duplicates", $<, $webservergid, 027, 1); - fixPerms("$datadir/mining", $<, $webservergid, 027, 1); - fixPerms("$datadir/template", $<, $webservergid, 007, 1); # webserver will write to these - fixPerms($attachdir, $<, $webservergid, 007, 1); # webserver will write to these - fixPerms($webdotdir, $<, $webservergid, 007, 1); - fixPerms("$webdotdir/.htaccess", $<, $webservergid, 027); - fixPerms("$datadir/params", $<, $webservergid, 017); - fixPerms('*', $<, $webservergid, 027); - fixPerms('Bugzilla', $<, $webservergid, 027, 1); - fixPerms($templatedir, $<, $webservergid, 027, 1); - fixPerms('images', $<, $webservergid, 027, 1); - fixPerms('css', $<, $webservergid, 027, 1); - fixPerms('skins', $<, $webservergid, 027, 1); - fixPerms('js', $<, $webservergid, 027, 1); - chmod 0644, 'globals.pl'; - - # Don't use fixPerms here, because it won't change perms - # on the directory unless it's using recursion - chown $<, $webservergid, $datadir; - chmod 0771, $datadir; - chown $<, $webservergid, 'graphs'; - chmod 0770, 'graphs'; - } else { - # get current gid from $( list - my $gid = (split " ", $()[0]; - fixPerms('.htaccess', $<, $gid, 022); # glob('*') doesn't catch dotfiles - fixPerms("$datadir/.htaccess", $<, $gid, 022); - fixPerms("$datadir/duplicates", $<, $gid, 022, 1); - fixPerms("$datadir/mining", $<, $gid, 022, 1); - fixPerms("$datadir/template", $<, $gid, 000, 1); # webserver will write to these - fixPerms($webdotdir, $<, $gid, 000, 1); - chmod 01777, $webdotdir; - fixPerms("$webdotdir/.htaccess", $<, $gid, 022); - fixPerms("$datadir/params", $<, $gid, 011); - fixPerms('*', $<, $gid, 022); - fixPerms('Bugzilla', $<, $gid, 022, 1); - fixPerms($templatedir, $<, $gid, 022, 1); - fixPerms('images', $<, $gid, 022, 1); - fixPerms('css', $<, $gid, 022, 1); - fixPerms('skins', $<, $gid, 022, 1); - fixPerms('js', $<, $gid, 022, 1); - - # Don't use fixPerms here, because it won't change perms - # on the directory unless it's using recursion - chown $<, $gid, $datadir; - chmod 0777, $datadir; - chown $<, $gid, 'graphs'; - chmod 01777, 'graphs'; - } -} +Bugzilla::Template::precompile_templates(!$silent) + unless $switch{'no-templates'}; ########################################################################### -# Global Utility Library +# Set proper rights (--CHMOD--) ########################################################################### -# This is done here, because some modules require params to be set up, which -# won't have happened earlier. - -# It's never safe to "use" a Bugzilla module in checksetup. If a module -# prerequisite is missing, and you "use" a module that requires it, -# then instead of our nice normal checksetup message the user would -# get a cryptic perl error about the missing module. - -# This is done so we can add new settings as developers need them. -require Bugzilla::User::Setting; -import Bugzilla::User::Setting qw(add_setting); - -require Bugzilla::Util; -import Bugzilla::Util qw(bz_crypt trim html_quote is_7bit_clean); - -require Bugzilla::User; -import Bugzilla::User qw(insert_new_user); - -# globals.pl clears the PATH, but File::Find uses Cwd::cwd() instead of -# Cwd::getcwd(), which we need to do because `pwd` isn't in the path - see -# http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2001-09/msg00115.html -# As a workaround, since we only use File::Find in checksetup, which doesn't -# run in taint mode anyway, preserve the path... -my $origPath = $::ENV{'PATH'}; - -# Use the Bugzilla utility library for various functions. We do this -# here rather than at the top of the file so globals.pl doesn't define -# localconfig variables for us before we get a chance to check for -# their existence and create them if they don't exist. Also, globals.pl -# removes $ENV{'path'}, which we need in order to run `which mysql` above. -require "globals.pl"; - -# ...and restore it. This doesn't change tainting, so this will still cause -# errors if this script ever does run with -T. -$::ENV{'PATH'} = $origPath; +fix_all_file_permissions(!$silent); ########################################################################### -# Check Database setup +# Check GraphViz setup ########################################################################### -# -# Check if we have access to the --DATABASE-- -# - -# No need to "use" this here. It should already be loaded from the -# version-checking routines above, and this file won't even compile if -# DBI isn't installed so the user gets nasty errors instead of our -# pretty one saying they need to install it. -- justdave@syndicomm.com -#use DBI; - -if ($my_db_check) { - # Do we have the database itself? - - # Unfortunately, $my_db_driver doesn't map perfectly between DBD - # and Bugzilla::DB. We need to fix the case a bit. - (my $dbd_name = trim($my_db_driver)) =~ s/(\w+)/\u\L$1/g; - # And MySQL is special, because it's all lowercase in DBD. - $dbd_name = 'mysql' if $dbd_name eq 'Mysql'; - - my $dbd = "DBD::$dbd_name"; - unless (eval("require $dbd")) { - print "Bugzilla requires that perl's $dbd be installed.\n" - . "To install this module, you can do:\n " - . " " . install_command($dbd) . "\n"; - exit; - } - - my $dbh = Bugzilla::DB::connect_main("no database connection"); - my $sql_want = $dbh->REQUIRED_VERSION; - my $sql_server = $dbh->PROGRAM_NAME; - my $dbd_ver = $dbh->DBD_VERSION; - unless (have_vers($dbd, $dbd_ver)) { - die "Bugzilla requires at least version $dbd_ver of $dbd."; - } - - printf("Checking for %15s %-9s ", $sql_server, "(v$sql_want)") unless $silent; - my $sql_vers = $dbh->bz_server_version; - - # Check what version of the database server is installed and let - # the user know if the version is too old to be used with Bugzilla. - if ( vers_cmp($sql_vers,$sql_want) > -1 ) { - print "ok: found v$sql_vers\n" unless $silent; - } else { - die "\nYour $sql_server v$sql_vers is too old.\n" . - " Bugzilla requires version $sql_want or later of $sql_server.\n" . - " Please download and install a newer version.\n"; - } - - # See if we can connect to the database. - my $conn_success = eval { - my $check_dbh = Bugzilla::DB::connect_main(); - $check_dbh->disconnect; - }; - if (!$conn_success) { - print "Creating database $my_db_name ...\n"; - # Try to create the DB, and if we fail print an error. - if (!eval { $dbh->do("CREATE DATABASE $my_db_name") }) { - my $error = $dbh->errstr; - die <<"EOF" - -The '$my_db_name' database could not be created. The error returned was: - -$error - -This might have several reasons: - -* $sql_server is not running. -* $sql_server is running, but there is a problem either in the - server configuration or the database access rights. Read the Bugzilla - Guide in the doc directory. The section about database configuration - should help. -* There is a subtle problem with Perl, DBI, or $sql_server. Make - sure all settings in '$localconfig' are correct. If all else fails, set - '\$db_check' to zero.\n -EOF - } - } - $dbh->disconnect if $dbh; -} - -# now get a handle to the database: -my $dbh = Bugzilla->dbh; - -END { $dbh->disconnect if $dbh } +# If we are using a local 'dot' binary, verify the specified binary exists +# and that the generated images are accessible. +check_graphviz(!$silent) if Bugzilla->params->{'webdotbase'}; ########################################################################### -# Check for LDAP +# Changes to the fielddefs --TABLE-- ########################################################################### -for my $verifymethod (split /,\s*/, Param('user_verify_class')) { - if ($verifymethod eq 'LDAP') { - my $netLDAP = have_vers("Net::LDAP", 0); - if (!$netLDAP && !$silent) { - print "If you wish to use LDAP authentication, then you must install Net::LDAP\n\n"; - } - } -} +# Using Bugzilla::Field's create() or update() depends on the +# fielddefs table having a modern definition. So, we have to make +# these particular schema changes before we make any other schema changes. +Bugzilla::Install::DB::update_fielddefs_definition(); + +Bugzilla::Field::populate_field_definitions(); ########################################################################### -# Check GraphViz setup +# Update the tables to the current definition --TABLE-- ########################################################################### -# -# If we are using a local 'dot' binary, verify the specified binary exists -# and that the generated images are accessible. -# - -if( Param('webdotbase') && Param('webdotbase') !~ /^https?:/ ) { - printf("Checking for %15s %-9s ", "GraphViz", "(any)") unless $silent; - if(-x Param('webdotbase')) { - print "ok: found\n" unless $silent; - } else { - print "not a valid executable: " . Param('webdotbase') . "\n"; - } - - # Check .htaccess allows access to generated images - if(-e "$webdotdir/.htaccess") { - open HTACCESS, "$webdotdir/.htaccess"; - if(! grep(/png/,<HTACCESS>)) { - print "Dependency graph images are not accessible.\n"; - print "delete $webdotdir/.htaccess and re-run checksetup.pl to fix.\n"; - } - close HTACCESS; - } -} - -print "\n" unless $silent; +Bugzilla::Install::DB::update_table_definitions(); ########################################################################### -# Create tables +# Bugzilla uses --GROUPS-- to assign various rights to its users. ########################################################################### -# Note: --TABLE-- definitions are now in Bugzilla::DB::Schema. -$dbh->bz_setup_database(); +Bugzilla::Install::update_system_groups(); ########################################################################### -# Populate groups table +# Create --SETTINGS-- users can adjust ########################################################################### -sub GroupDoesExist -{ - my ($name) = @_; - my $sth = $dbh->prepare("SELECT name FROM groups WHERE name='$name'"); - $sth->execute; - if ($sth->rows) { - return 1; - } - return 0; -} - - -# -# This subroutine ensures that a group exists. If not, it will be created -# automatically, and given the next available groupid -# - -sub AddGroup { - my ($name, $desc, $userregexp) = @_; - $userregexp ||= ""; - - return if GroupDoesExist($name); - - print "Adding group $name ...\n"; - my $sth = $dbh->prepare('INSERT INTO groups - (name, description, userregexp, isbuggroup, - last_changed) - VALUES (?, ?, ?, ?, NOW())'); - $sth->execute($name, $desc, $userregexp, 0); - - my $last = $dbh->bz_last_key('groups', 'id'); - return $last; -} - +Bugzilla::Install::update_settings(); ########################################################################### -# Populate the list of fields. +# Create Administrator --ADMIN-- ########################################################################### -my $headernum = 1; - -sub AddFDef { - my ($name, $description, $mailhead) = (@_); - - my $sth = $dbh->prepare("SELECT fieldid FROM fielddefs " . - "WHERE name = ?"); - $sth->execute($name); - my ($fieldid) = ($sth->fetchrow_array()); - if (!$fieldid) { - $dbh->do(q{INSERT INTO fielddefs - (name, description, mailhead, sortkey) - VALUES (?, ?, ?, ?)}, - undef, ($name, $description, $mailhead, $headernum)); - } else { - $dbh->do(q{UPDATE fielddefs - SET name = ?, description = ?, - mailhead = ?, sortkey = ? - WHERE fieldid = ?}, undef, - $name, $description, $mailhead, $headernum, $fieldid); - } - $headernum++; -} - - -# Note that all of these entries are unconditional, from when get_field_id -# used to create an entry if it wasn't found. New fielddef columns should -# be created with their associated schema change. -AddFDef("bug_id", "Bug \#", 1); -AddFDef("short_desc", "Summary", 1); -AddFDef("classification", "Classification", 1); -AddFDef("product", "Product", 1); -AddFDef("version", "Version", 1); -AddFDef("rep_platform", "Platform", 1); -AddFDef("bug_file_loc", "URL", 1); -AddFDef("op_sys", "OS/Version", 1); -AddFDef("bug_status", "Status", 1); -AddFDef("status_whiteboard", "Status Whiteboard", 0); -AddFDef("keywords", "Keywords", 1); -AddFDef("resolution", "Resolution", 0); -AddFDef("bug_severity", "Severity", 1); -AddFDef("priority", "Priority", 1); -AddFDef("component", "Component", 1); -AddFDef("assigned_to", "AssignedTo", 1); -AddFDef("reporter", "ReportedBy", 1); -AddFDef("votes", "Votes", 0); -AddFDef("qa_contact", "QAContact", 1); -AddFDef("cc", "CC", 1); -AddFDef("dependson", "BugsThisDependsOn", 1); -AddFDef("blocked", "OtherBugsDependingOnThis", 1); -AddFDef("attachments.description", "Attachment description", 0); -AddFDef("attachments.filename", "Attachment filename", 0); -AddFDef("attachments.mimetype", "Attachment mime type", 0); -AddFDef("attachments.ispatch", "Attachment is patch", 0); -AddFDef("attachments.isobsolete", "Attachment is obsolete", 0); -AddFDef("attachments.isprivate", "Attachment is private", 0); - -AddFDef("target_milestone", "Target Milestone", 0); -AddFDef("creation_ts", "Creation date", 0); -AddFDef("delta_ts", "Last changed date", 0); -AddFDef("longdesc", "Comment", 0); -AddFDef("alias", "Alias", 0); -AddFDef("everconfirmed", "Ever Confirmed", 0); -AddFDef("reporter_accessible", "Reporter Accessible", 0); -AddFDef("cclist_accessible", "CC Accessible", 0); -AddFDef("bug_group", "Group", 0); -AddFDef("estimated_time", "Estimated Hours", 1); -AddFDef("remaining_time", "Remaining Hours", 0); -AddFDef("deadline", "Deadline", 1); -AddFDef("commenter", "Commenter", 0); - -# Oops. Bug 163299 -$dbh->do("DELETE FROM fielddefs WHERE name='cc_accessible'"); - -# Oops. Bug 215319 -$dbh->do("DELETE FROM fielddefs WHERE name='requesters.login_name'"); - -AddFDef("flagtypes.name", "Flag", 0); -AddFDef("requestees.login_name", "Flag Requestee", 0); -AddFDef("setters.login_name", "Flag Setter", 0); -AddFDef("work_time", "Hours Worked", 0); -AddFDef("percentage_complete", "Percentage Complete", 0); - -AddFDef("content", "Content", 0); - -$dbh->do("DELETE FROM fielddefs WHERE name='attachments.thedata'"); -AddFDef("attach_data.thedata", "Attachment data", 0); -AddFDef("attachments.isurl", "Attachment is a URL", 0); - -# 2005-11-13 LpSolit@gmail.com - Bug 302599 -# One of the field names was a fragment of SQL code, which is DB dependent. -# We have to rename it to a real name, which is DB independent. -my $new_field_name = 'days_elapsed'; -my $field_description = 'Days since bug changed'; - -my ($old_field_id, $old_field_name) = - $dbh->selectrow_array('SELECT fieldid, name - FROM fielddefs - WHERE description = ?', - undef, $field_description); - -if ($old_field_id && ($old_field_name ne $new_field_name)) { - print "SQL fragment found in the 'fielddefs' table...\n"; - print "Old field name: " . $old_field_name . "\n"; - # We have to fix saved searches first. Queries have been escaped - # before being saved. We have to do the same here to find them. - $old_field_name = url_quote($old_field_name); - my $broken_named_queries = - $dbh->selectall_arrayref('SELECT userid, name, query - FROM namedqueries WHERE ' . - $dbh->sql_istrcmp('query', '?', 'LIKE'), - undef, "%=$old_field_name%"); - - my $sth_UpdateQueries = $dbh->prepare('UPDATE namedqueries SET query = ? - WHERE userid = ? AND name = ?'); - - print "Fixing saved searches...\n" if scalar(@$broken_named_queries); - foreach my $named_query (@$broken_named_queries) { - my ($userid, $name, $query) = @$named_query; - $query =~ s/=\Q$old_field_name\E(&|$)/=$new_field_name$1/gi; - $sth_UpdateQueries->execute($query, $userid, $name); - } - - # We now do the same with saved chart series. - my $broken_series = - $dbh->selectall_arrayref('SELECT series_id, query - FROM series WHERE ' . - $dbh->sql_istrcmp('query', '?', 'LIKE'), - undef, "%=$old_field_name%"); - - my $sth_UpdateSeries = $dbh->prepare('UPDATE series SET query = ? - WHERE series_id = ?'); - - print "Fixing saved chart series...\n" if scalar(@$broken_series); - foreach my $series (@$broken_series) { - my ($series_id, $query) = @$series; - $query =~ s/=\Q$old_field_name\E(&|$)/=$new_field_name$1/gi; - $sth_UpdateSeries->execute($query, $series_id); - } - - # Now that saved searches have been fixed, we can fix the field name. - print "Fixing the 'fielddefs' table...\n"; - print "New field name: " . $new_field_name . "\n"; - $dbh->do('UPDATE fielddefs SET name = ? WHERE fieldid = ?', - undef, ($new_field_name, $old_field_id)); -} -AddFDef($new_field_name, $field_description, 0); +Bugzilla::Install::make_admin($switch{'make-admin'}) if $switch{'make-admin'}; +Bugzilla::Install::create_admin(); ########################################################################### -# Detect changed local settings +# Create default Product and Classification ########################################################################### -# Nick Barnes nb+bz@ravenbrook.com 2005-10-05 -# -# PopulateEnumTable($table, @values): if the table $table has no -# entries, fill it with the entries in the list @values, in the same -# order as that list. - -sub PopulateEnumTable { - my ($table, @valuelist) = @_; - - # If we encounter any of the keys in this hash, they are - # automatically set to isactive=0 - my %defaultinactive = ('---' => 1); - - # Check if there are any table entries - my $query = "SELECT COUNT(id) FROM $table"; - my $sth = $dbh->prepare($query); - $sth->execute(); - - # If the table is empty... - if ( !$sth->fetchrow_array() ) { - my $insert = $dbh->prepare("INSERT INTO $table" - . " (value,sortkey,isactive) VALUES (?,?,?)"); - my $sortorder = 0; - foreach my $value (@valuelist) { - $sortorder = $sortorder + 100; - # Not active if the value exists in $defaultinactive - my $isactive = exists($defaultinactive{$value}) ? 0 : 1; - print "Inserting value '$value' in table $table" - . " with sortkey $sortorder...\n"; - $insert->execute($value, $sortorder, $isactive); - } - } -} - -# Set default values for what used to be the enum types. These values -# are no longer stored in localconfig. If we are upgrading from a -# Bugzilla with enums to a Bugzilla without enums, we use the -# enum values. -# -# The values that you see here are ONLY DEFAULTS. They are only used -# the FIRST time you run checksetup, IF you are NOT upgrading from a -# Bugzilla with enums. After that, they are either controlled through -# the Bugzilla UI or through the DB. - -my $enum_defaults = { - bug_severity => ['blocker', 'critical', 'major', 'normal', - 'minor', 'trivial', 'enhancement'], - priority => ["P1","P2","P3","P4","P5"], - op_sys => ["All","Windows","Mac OS","Linux","Other"], - rep_platform => ["All","PC","Macintosh","Other"], - bug_status => ["UNCONFIRMED","NEW","ASSIGNED","REOPENED","RESOLVED", - "VERIFIED","CLOSED"], - resolution => ["","FIXED","INVALID","WONTFIX","LATER","REMIND", - "DUPLICATE","WORKSFORME","MOVED"], -}; - -# Get all the enum column values for the existing database, or the -# defaults if the columns are not enums. -my $enum_values = $dbh->bz_enum_initial_values($enum_defaults); - -# Populate the enum tables. -while (my ($table, $values) = each %$enum_values) { - PopulateEnumTable($table, @$values); -} +Bugzilla::Install::create_default_product(); ########################################################################### -# Create initial test product if there are no products present. +# Final checks ########################################################################### -my $sth = $dbh->prepare("SELECT description FROM products"); -$sth->execute; -unless ($sth->rows) { - print "Creating initial dummy product 'TestProduct' ...\n"; - my $test_product_name = 'TestProduct'; - my $test_product_desc = - 'This is a test product. This ought to be blown away and' - . ' replaced with real stuff in a finished installation of bugzilla.'; - my $test_product_version = 'other'; - - $dbh->do(q{INSERT INTO products(name, description, milestoneurl, - disallownew, votesperuser, votestoconfirm) - VALUES (?, ?, '', ?, ?, ?)}, - undef, $test_product_name, $test_product_desc, 0, 0, 0); - - # We could probably just assume that this is "1", but better - # safe than sorry... - my $product_id = $dbh->bz_last_key('products', 'id'); - - $dbh->do(q{INSERT INTO versions (value, product_id) - VALUES (?, ?)}, - undef, $test_product_version, $product_id); - # note: since admin user is not yet known, components gets a 0 for - # initialowner and this is fixed during final checks. - $dbh->do("INSERT INTO components (name, product_id, description, " . - "initialowner) " . - "VALUES (" . - "'TestComponent', $product_id, " . - "'This is a test component in the test product database. " . - "This ought to be blown away and replaced with real stuff in " . - "a finished installation of Bugzilla.', 0)"); - $dbh->do(q{INSERT INTO milestones (product_id, value, sortkey) - VALUES (?,?,?)}, - undef, $product_id, '---', 0); -} -# Create a default classification if one does not exist -my $class_count = - $dbh->selectrow_array("SELECT COUNT(*) FROM classifications"); -if (!$class_count) { - $dbh->do("INSERT INTO classifications (name,description) " . - "VALUES('Unclassified','Unassigned to any classifications')"); +# Check if the default parameter for urlbase is still set, and if so, give +# notification that they should go and visit editparams.cgi +if (Bugzilla->params->{'urlbase'} eq '') { + print "\n" . Bugzilla::Install::get_text('install_urlbase_default') . "\n" + unless $silent; } -########################################################################### -# Update the tables to the current definition -########################################################################### +__END__ -# Both legacy code and modern code need this variable. -my @admins = (); - -# really old fields that were added before checksetup.pl existed -# but aren't in very old bugzilla's (like 2.1) -# Steve Stock (sstock@iconnect-inc.com) - -$dbh->bz_add_column('bugs', 'target_milestone', - {TYPE => 'varchar(20)', NOTNULL => 1, DEFAULT => "'---'"}); -$dbh->bz_add_column('bugs', 'qa_contact', {TYPE => 'INT3'}); -$dbh->bz_add_column('bugs', 'status_whiteboard', - {TYPE => 'MEDIUMTEXT', NOTNULL => 1, DEFAULT => "''"}); -$dbh->bz_add_column('products', 'disallownew', - {TYPE => 'BOOLEAN', NOTNULL => 1}, 0); -$dbh->bz_add_column('products', 'milestoneurl', - {TYPE => 'TINYTEXT', NOTNULL => 1}, ''); -$dbh->bz_add_column('components', 'initialqacontact', - {TYPE => 'TINYTEXT'}); -$dbh->bz_add_column('components', 'description', - {TYPE => 'MEDIUMTEXT', NOTNULL => 1}, ''); - -# 1999-06-22 Added an entry to the attachments table to record who the -# submitter was. Nothing uses this yet, but it still should be recorded. -$dbh->bz_add_column('attachments', 'submitter_id', - {TYPE => 'INT3', NOTNULL => 1}, 0); +=head1 NAME -# -# One could even populate this field automatically, e.g. with -# -# unless (GetField('attachments', 'submitter_id') { -# $dbh->bz_add_column ... -# populate -# } -# -# For now I was too lazy, so you should read the documentation :-) +checksetup.pl - A do-it-all upgrade and installation script for Bugzilla. +=head1 SYNOPSIS + ./checksetup.pl [--help|--check-modules] + ./checksetup.pl [SCRIPT [--verbose]] [--no-templates|-t] + [--make-admin=user@domain.com] -# 1999-9-15 Apparently, newer alphas of MySQL won't allow you to have "when" -# as a column name. So, I have had to rename a column in the bugs_activity -# table. +=head1 OPTIONS -$dbh->bz_rename_column('bugs_activity', 'when', 'bug_when'); +=over +=item F<SCRIPT> +Name of script to drive non-interactive mode. This script should +define an C<%answer> hash whose keys are variable names and the +values answers to all the questions checksetup.pl asks. For details +on the format of this script, do C<perldoc checksetup.pl> and look for +the L</"RUNNING CHECKSETUP NON-INTERACTIVELY"> section. -# 1999-10-11 Restructured voting database to add a cached value in each bug -# recording how many total votes that bug has. While I'm at it, I removed -# the unused "area" field from the bugs database. It is distressing to -# realize that the bugs table has reached the maximum number of indices -# allowed by MySQL (16), which may make future enhancements awkward. -# (P.S. All is not lost; it appears that the latest betas of MySQL support -# a new table format which will allow 32 indices.) +=item B<--help> -$dbh->bz_drop_column('bugs', 'area'); -if (!$dbh->bz_column_info('bugs', 'votes')) { - $dbh->bz_add_column('bugs', 'votes', {TYPE => 'INT3', NOTNULL => 1, - DEFAULT => 0}); - $dbh->bz_add_index('bugs', 'bugs_votes_idx', [qw(votes)]); -} -$dbh->bz_add_column('products', 'votesperuser', - {TYPE => 'INT2', NOTNULL => 1}, 0); +Display this help text +=item B<--check-modules> -# The product name used to be very different in various tables. -# -# It was varchar(16) in bugs -# tinytext in components -# tinytext in products -# tinytext in versions -# -# tinytext is equivalent to varchar(255), which is quite huge, so I change -# them all to varchar(64). - -# Only do this if these fields still exist - they're removed below, in -# a later change -if ($dbh->bz_column_info('products', 'product')) { - $dbh->bz_alter_column('bugs', 'product', - {TYPE => 'varchar(64)', NOTNULL => 1}); - $dbh->bz_alter_column('components', 'program', {TYPE => 'varchar(64)'}); - $dbh->bz_alter_column('products', 'product', {TYPE => 'varchar(64)'}); - $dbh->bz_alter_column('versions', 'program', - {TYPE => 'varchar(64)', NOTNULL => 1}); -} +Only check for correct module dependencies and quit afterward. -# 2000-01-16 Added a "keywords" field to the bugs table, which -# contains a string copy of the entries of the keywords table for this -# bug. This is so that I can easily sort and display a keywords -# column in bug lists. - -if (!$dbh->bz_column_info('bugs', 'keywords')) { - $dbh->bz_add_column('bugs', 'keywords', - {TYPE => 'MEDIUMTEXT', NOTNULL => 1, DEFAULT => "''"}); - - my @kwords; - print "Making sure 'keywords' field of table 'bugs' is empty ...\n"; - $dbh->do("UPDATE bugs SET keywords = '' " . - "WHERE keywords != ''"); - print "Repopulating 'keywords' field of table 'bugs' ...\n"; - my $sth = $dbh->prepare("SELECT keywords.bug_id, keyworddefs.name " . - "FROM keywords, keyworddefs " . - "WHERE keyworddefs.id = keywords.keywordid " . - "ORDER BY keywords.bug_id, keyworddefs.name"); - $sth->execute; - my @list; - my $bugid = 0; - my @row; - while (1) { - my ($b, $k) = ($sth->fetchrow_array()); - if (!defined $b || $b ne $bugid) { - if (@list) { - $dbh->do("UPDATE bugs SET keywords = " . - $dbh->quote(join(', ', @list)) . - " WHERE bug_id = $bugid"); - } - if (!$b) { - last; - } - $bugid = $b; - @list = (); - } - push(@list, $k); - } -} +=item B<--make-admin>=username@domain.com +Makes the specified user into a Bugzilla administrator. This is +in case you accidentally lock yourself out of the Bugzilla administrative +interface. -# 2000-01-18 Added a "disabledtext" field to the profiles table. If not -# empty, then this account has been disabled, and this field is to contain -# text describing why. -$dbh->bz_add_column('profiles', 'disabledtext', - {TYPE => 'MEDIUMTEXT', NOTNULL => 1}, ''); +=item B<--no-templates> (B<-t>) +Don't compile the templates at all. Existing compiled templates will +remain; missing compiled templates will not be created. (Used primarily +by developers to speed up checksetup.) Use this switch at your own risk. -# 2000-01-20 Added a new "longdescs" table, which is supposed to have all the -# long descriptions in it, replacing the old long_desc field in the bugs -# table. The below hideous code populates this new table with things from -# the old field, with ugly parsing and heuristics. +=item B<--verbose> -sub WriteOneDesc { - my ($id, $who, $when, $buffer) = (@_); - $buffer = trim($buffer); - if ($buffer eq '') { - return; - } - $dbh->do("INSERT INTO longdescs (bug_id, who, bug_when, thetext) VALUES " . - "($id, $who, " . time2str("'%Y/%m/%d %H:%M:%S'", $when) . - ", " . $dbh->quote($buffer) . ")"); -} +Output results of SCRIPT being processed. +=back -if ($dbh->bz_column_info('bugs', 'long_desc')) { - eval("use Date::Parse"); - eval("use Date::Format"); - my $sth = $dbh->prepare("SELECT count(*) FROM bugs"); - $sth->execute(); - my ($total) = ($sth->fetchrow_array); - - print "Populating new long_desc table. This is slow. There are $total\n"; - print "bugs to process; a line of dots will be printed for each 50.\n\n"; - $| = 1; - - $dbh->bz_lock_tables('bugs write', 'longdescs write', 'profiles write', - 'bz_schema WRITE'); - - $dbh->do('DELETE FROM longdescs'); - - $sth = $dbh->prepare("SELECT bug_id, creation_ts, reporter, long_desc " . - "FROM bugs ORDER BY bug_id"); - $sth->execute(); - my $count = 0; - while (1) { - my ($id, $createtime, $reporterid, $desc) = ($sth->fetchrow_array()); - if (!$id) { - last; - } - print "."; - $count++; - if ($count % 10 == 0) { - print " "; - if ($count % 50 == 0) { - print "$count/$total (" . int($count * 100 / $total) . "%)\n"; - } - } - $desc =~ s/\r//g; - my $who = $reporterid; - my $when = str2time($createtime); - my $buffer = ""; - foreach my $line (split(/\n/, $desc)) { - $line =~ s/\s+$//g; # Trim trailing whitespace. - if ($line =~ /^------- Additional Comments From ([^\s]+)\s+(\d.+\d)\s+-------$/) { - my $name = $1; - my $date = str2time($2); - $date += 59; # Oy, what a hack. The creation time is - # accurate to the second. But we the long - # text only contains things accurate to the - # minute. And so, if someone makes a comment - # within a minute of the original bug creation, - # then the comment can come *before* the - # bug creation. So, we add 59 seconds to - # the time of all comments, so that they - # are always considered to have happened at - # the *end* of the given minute, not the - # beginning. - if ($date >= $when) { - WriteOneDesc($id, $who, $when, $buffer); - $buffer = ""; - $when = $date; - my $s2 = $dbh->prepare("SELECT userid FROM profiles " . - "WHERE login_name = " . - $dbh->quote($name)); - $s2->execute(); - ($who) = ($s2->fetchrow_array()); - if (!$who) { - # This username doesn't exist. Try a special - # netscape-only hack (sorry about that, but I don't - # think it will hurt any other installations). We - # have many entries in the bugsystem from an ancient - # world where the "@netscape.com" part of the loginname - # was omitted. So, look up the user again with that - # appended, and use it if it's there. - if ($name !~ /\@/) { - my $nsname = $name . "\@netscape.com"; - $s2 = - $dbh->prepare("SELECT userid FROM profiles " . - "WHERE login_name = " . - $dbh->quote($nsname)); - $s2->execute(); - ($who) = ($s2->fetchrow_array()); - } - } - - if (!$who) { - # This username doesn't exist. Maybe someone renamed - # him or something. Invent a new profile entry, - # disabled, just to represent him. - $dbh->do("INSERT INTO profiles " . - "(login_name, cryptpassword," . - " disabledtext) VALUES (" . - $dbh->quote($name) . - ", " . $dbh->quote(bz_crypt('okthen')) . - ", " . - "'Account created only to maintain database integrity')"); - $who = $dbh->bz_last_key('profiles', 'userid'); - } - next; - } else { -# print "\nDecided this line of bug $id has a date of " . -# time2str("'%Y/%m/%d %H:%M:%S'", $date) . -# "\nwhich is less than previous line:\n$line\n\n"; - } - - } - $buffer .= $line . "\n"; - } - WriteOneDesc($id, $who, $when, $buffer); - } - - - print "\n\n"; - - $dbh->bz_drop_column('bugs', 'long_desc'); - - $dbh->bz_unlock_tables(); -} +=head1 DESCRIPTION +Hey, what's this? -# 2000-01-18 Added a new table fielddefs that records information about the -# different fields we keep an activity log on. The bugs_activity table -# now has a pointer into that table instead of recording the name directly. - -if ($dbh->bz_column_info('bugs_activity', 'field')) { - $dbh->bz_add_column('bugs_activity', 'fieldid', - {TYPE => 'INT3', NOTNULL => 1}, 0); - - $dbh->bz_add_index('bugs_activity', 'bugs_activity_fieldid_idx', - [qw(fieldid)]); - print "Populating new fieldid field ...\n"; - - $dbh->bz_lock_tables('bugs_activity WRITE', 'fielddefs WRITE'); - - my $sth = $dbh->prepare('SELECT DISTINCT field FROM bugs_activity'); - $sth->execute(); - my %ids; - while (my ($f) = ($sth->fetchrow_array())) { - my $q = $dbh->quote($f); - my $s2 = - $dbh->prepare("SELECT fieldid FROM fielddefs WHERE name = $q"); - $s2->execute(); - my ($id) = ($s2->fetchrow_array()); - if (!$id) { - $dbh->do("INSERT INTO fielddefs (name, description) VALUES " . - "($q, $q)"); - $id = $dbh->bz_last_key('fielddefs', 'fieldid'); - } - $dbh->do("UPDATE bugs_activity SET fieldid = $id WHERE field = $q"); - } - $dbh->bz_unlock_tables(); - - $dbh->bz_drop_column('bugs_activity', 'field'); -} +F<checksetup.pl> is a script that is supposed to run during +installation time and also after every upgrade. - +The goal of this script is to make the installation even easier. +It does this by doing things for you as well as testing for problems +in advance. -# 2000-01-18 New email-notification scheme uses a new field in the bug to -# record when email notifications were last sent about this bug. Also, -# added 'newemailtech' field to record if user wants to use the experimental -# stuff. -# 2001-04-29 jake@bugzilla.org - The newemailtech field is no longer needed -# http://bugzilla.mozilla.org/show_bugs.cgi?id=71552 +You can run the script whenever you like. You MUST run it after +you update Bugzilla, because it will then update your SQL table +definitions to resync them with the code. -if (!$dbh->bz_column_info('bugs', 'lastdiffed')) { - $dbh->bz_add_column('bugs', 'lastdiffed', {TYPE =>'DATETIME'}); - $dbh->do('UPDATE bugs SET lastdiffed = now()'); -} +You can see all the details of what the script does at +L</How Checksetup Works>. +=head1 MODIFYING CHECKSETUP -# 2000-01-22 The "login_name" field in the "profiles" table was not -# declared to be unique. Sure enough, somehow, I got 22 duplicated entries -# in my database. This code detects that, cleans up the duplicates, and -# then tweaks the table to declare the field to be unique. What a pain. -if (!$dbh->bz_index_info('profiles', 'profiles_login_name_idx') - || !$dbh->bz_index_info('profiles', 'profiles_login_name_idx')->{TYPE}) -{ - print "Searching for duplicate entries in the profiles table ...\n"; - while (1) { - # This code is weird in that it loops around and keeps doing this - # select again. That's because I'm paranoid about deleting entries - # out from under us in the profiles table. Things get weird if - # there are *three* or more entries for the same user... - $sth = $dbh->prepare("SELECT p1.userid, p2.userid, p1.login_name " . - "FROM profiles AS p1, profiles AS p2 " . - "WHERE p1.userid < p2.userid " . - "AND p1.login_name = p2.login_name " . - "ORDER BY p1.login_name"); - $sth->execute(); - my ($u1, $u2, $n) = ($sth->fetchrow_array); - if (!$u1) { - last; - } - print "Both $u1 & $u2 are ids for $n! Merging $u2 into $u1 ...\n"; - foreach my $i (["bugs", "reporter"], - ["bugs", "assigned_to"], - ["bugs", "qa_contact"], - ["attachments", "submitter_id"], - ["bugs_activity", "who"], - ["cc", "who"], - ["votes", "who"], - ["longdescs", "who"]) { - my ($table, $field) = (@$i); - print " Updating $table.$field ...\n"; - $dbh->do("UPDATE $table SET $field = $u1 " . - "WHERE $field = $u2"); - } - $dbh->do("DELETE FROM profiles WHERE userid = $u2"); - } - print "OK, changing index type to prevent duplicates in the future ...\n"; - - $dbh->bz_drop_index('profiles', 'profiles_login_name_idx'); - $dbh->bz_add_index('profiles', 'profiles_login_name_idx', - {TYPE => 'UNIQUE', FIELDS => [qw(login_name)]}); -} - - -# 2000-01-24 Added a new field to let people control whether the "My -# bugs" link appears at the bottom of each page. Also can control -# whether each named query should show up there. - -$dbh->bz_add_column('profiles', 'mybugslink', {TYPE => 'BOOLEAN', NOTNULL => 1, - DEFAULT => 'TRUE'}); -$dbh->bz_add_column('namedqueries', 'linkinfooter', - {TYPE => 'BOOLEAN', NOTNULL => 1}, 0); - -my $comp_init_owner = $dbh->bz_column_info('components', 'initialowner'); -if ($comp_init_owner && $comp_init_owner->{TYPE} eq 'TINYTEXT') { - $sth = $dbh->prepare( - "SELECT program, value, initialowner, initialqacontact " . - "FROM components"); - $sth->execute(); - while (my ($program, $value, $initialowner) = $sth->fetchrow_array()) { - $initialowner =~ s/([\\\'])/\\$1/g; $initialowner =~ s/\0/\\0/g; - $program =~ s/([\\\'])/\\$1/g; $program =~ s/\0/\\0/g; - $value =~ s/([\\\'])/\\$1/g; $value =~ s/\0/\\0/g; - - my $s2 = $dbh->prepare("SELECT userid " . - "FROM profiles " . - "WHERE login_name = '$initialowner'"); - $s2->execute(); - - my $initialownerid = $s2->fetchrow_array(); - - unless (defined $initialownerid) { - print "Warning: You have an invalid default assignee '$initialowner'\n" . - "in component '$value' of program '$program'. !\n"; - $initialownerid = 0; - } - - my $update = - "UPDATE components " . - "SET initialowner = $initialownerid " . - "WHERE program = '$program' " . - "AND value = '$value'"; - my $s3 = $dbh->prepare("UPDATE components " . - "SET initialowner = $initialownerid " . - "WHERE program = '$program' " . - "AND value = '$value';"); - $s3->execute(); - } - - $dbh->bz_alter_column('components','initialowner',{TYPE => 'INT3'}); -} +There should be no need for Bugzilla Administrators to modify +this script; all user-configurable stuff has been moved +into a local configuration file called F<localconfig>. When that file +in changed and F<checksetup.pl> is run, then the user's changes +will be reflected back into the database. -my $comp_init_qa = $dbh->bz_column_info('components', 'initialqacontact'); -if ($comp_init_qa && $comp_init_qa->{TYPE} eq 'TINYTEXT') { - $sth = $dbh->prepare( - "SELECT program, value, initialqacontact, initialqacontact " . - "FROM components"); - $sth->execute(); - while (my ($program, $value, $initialqacontact) = $sth->fetchrow_array()) { - $initialqacontact =~ s/([\\\'])/\\$1/g; $initialqacontact =~ s/\0/\\0/g; - $program =~ s/([\\\'])/\\$1/g; $program =~ s/\0/\\0/g; - $value =~ s/([\\\'])/\\$1/g; $value =~ s/\0/\\0/g; - - my $s2 = $dbh->prepare("SELECT userid " . - "FROM profiles " . - "WHERE login_name = '$initialqacontact'"); - $s2->execute(); - - my $initialqacontactid = $s2->fetchrow_array(); - - unless (defined $initialqacontactid) { - if ($initialqacontact ne '') { - print "Warning: You have an invalid default QA contact $initialqacontact' in program '$program', component '$value'!\n"; - } - $initialqacontactid = 0; - } - - my $update = "UPDATE components " . - "SET initialqacontact = $initialqacontactid " . - "WHERE program = '$program' AND value = '$value'"; - my $s3 = $dbh->prepare("UPDATE components " . - "SET initialqacontact = $initialqacontactid " . - "WHERE program = '$program' " . - "AND value = '$value';"); - $s3->execute(); - } - - $dbh->bz_alter_column('components','initialqacontact',{TYPE => 'INT3'}); -} +However, developers often need to modify the installation process. +This section explains how F<checksetup.pl> works, so that you +know the right part to modify. +=head2 How Checksetup Works -if (!$dbh->bz_column_info('bugs', 'everconfirmed')) { - $dbh->bz_add_column('bugs', 'everconfirmed', - {TYPE => 'BOOLEAN', NOTNULL => 1}, 1); -} -$dbh->bz_add_column('products', 'maxvotesperbug', - {TYPE => 'INT2', NOTNULL => 1, DEFAULT => '10000'}); -$dbh->bz_add_column('products', 'votestoconfirm', - {TYPE => 'INT2', NOTNULL => 1}, 0); - -# 2000-03-21 Adding a table for target milestones to -# database - matthew@zeroknowledge.com -# If the milestones table is empty, and we're still back in a Bugzilla -# that has a bugs.product field, that means that we just created -# the milestones table and it needs to be populated. -my $milestones_exist = $dbh->selectrow_array("SELECT 1 FROM milestones"); -if (!$milestones_exist && $dbh->bz_column_info('bugs', 'product')) { - print "Replacing blank milestones...\n"; - - $dbh->do("UPDATE bugs " . - "SET target_milestone = '---' " . - "WHERE target_milestone = ' '"); - - # If we are upgrading from 2.8 or earlier, we will have *created* - # the milestones table with a product_id field, but Bugzilla expects - # it to have a "product" field. So we change the field backward so - # other code can run. The change will be reversed later in checksetup. - if ($dbh->bz_column_info('milestones', 'product_id')) { - # Dropping the column leaves us with a milestones_product_id_idx - # index that is only on the "value" column. We need to drop the - # whole index so that it can be correctly re-created later. - $dbh->bz_drop_index('milestones', 'milestones_product_id_idx'); - $dbh->bz_drop_column('milestones', 'product_id'); - $dbh->bz_add_column('milestones', 'product', - {TYPE => 'varchar(64)', NOTNULL => 1}, ''); - } - - # Populate the milestone table with all existing values in the database - $sth = $dbh->prepare("SELECT DISTINCT target_milestone, product FROM bugs"); - $sth->execute(); - - print "Populating milestones table...\n"; - - my $value; - my $product; - while(($value, $product) = $sth->fetchrow_array()) - { - # check if the value already exists - my $sortkey = substr($value, 1); - if ($sortkey !~ /^\d+$/) { - $sortkey = 0; - } else { - $sortkey *= 10; - } - $value = $dbh->quote($value); - $product = $dbh->quote($product); - my $s2 = $dbh->prepare("SELECT value " . - "FROM milestones " . - "WHERE value = $value " . - "AND product = $product"); - $s2->execute(); - - if(!$s2->fetchrow_array()) - { - $dbh->do("INSERT INTO milestones(value, product, sortkey) VALUES($value, $product, $sortkey)"); - } - } -} +F<checksetup.pl> runs through several stages during installation: -# 2000-03-22 Changed the default value for target_milestone to be "---" -# (which is still not quite correct, but much better than what it was -# doing), and made the size of the value field in the milestones table match -# the size of the target_milestone field in the bugs table. - -$dbh->bz_alter_column('bugs', 'target_milestone', - {TYPE => 'varchar(20)', NOTNULL => 1, DEFAULT => "'---'"}); -$dbh->bz_alter_column('milestones', 'value', - {TYPE => 'varchar(20)', NOTNULL => 1}); - - -# 2000-03-23 Added a defaultmilestone field to the products table, so that -# we know which milestone to initially assign bugs to. - -if (!$dbh->bz_column_info('products', 'defaultmilestone')) { - $dbh->bz_add_column('products', 'defaultmilestone', - {TYPE => 'varchar(20)', NOTNULL => 1, DEFAULT => "'---'"}); - $sth = $dbh->prepare("SELECT product, defaultmilestone FROM products"); - $sth->execute(); - while (my ($product, $defaultmilestone) = $sth->fetchrow_array()) { - $product = $dbh->quote($product); - $defaultmilestone = $dbh->quote($defaultmilestone); - my $s2 = $dbh->prepare("SELECT value FROM milestones " . - "WHERE value = $defaultmilestone " . - "AND product = $product"); - $s2->execute(); - if (!$s2->fetchrow_array()) { - $dbh->do("INSERT INTO milestones(value, product) " . - "VALUES ($defaultmilestone, $product)"); - } - } -} +=over -# 2000-03-24 Added unique indexes into the cc and keyword tables. This -# prevents certain database inconsistencies, and, moreover, is required for -# new generalized list code to work. - -if (!$dbh->bz_index_info('cc', 'cc_bug_id_idx') - || !$dbh->bz_index_info('cc', 'cc_bug_id_idx')->{TYPE}) -{ - - # XXX should eliminate duplicate entries before altering - # - $dbh->bz_drop_index('cc', 'cc_bug_id_idx'); - $dbh->bz_add_index('cc', 'cc_bug_id_idx', - {TYPE => 'UNIQUE', FIELDS => [qw(bug_id who)]}); -} - -if (!$dbh->bz_index_info('keywords', 'keywords_bug_id_idx') - || !$dbh->bz_index_info('keywords', 'keywords_bug_id_idx')->{TYPE}) -{ - - # XXX should eliminate duplicate entries before altering - # - $dbh->bz_drop_index('keywords', 'keywords_bug_id_idx'); - $dbh->bz_add_index('keywords', 'keywords_bug_id_idx', - {TYPE => 'UNIQUE', FIELDS => [qw(bug_id keywordid)]}); -} - -# 2000-07-15 Added duplicates table so Bugzilla tracks duplicates in a better -# way than it used to. This code searches the comments to populate the table -# initially. It's executed if the table is empty; if it's empty because there -# are no dupes (as opposed to having just created the table) it won't have -# any effect anyway, so it doesn't matter. -$sth = $dbh->prepare("SELECT count(*) from duplicates"); -$sth->execute(); -if (!($sth->fetchrow_arrayref()->[0])) { - # populate table - print("Populating duplicates table...\n") unless $silent; - - $sth = $dbh->prepare( - "SELECT longdescs.bug_id, thetext " . - "FROM longdescs " . - "LEFT JOIN bugs ON longdescs.bug_id = bugs.bug_id " . - "WHERE (" . $dbh->sql_regexp("thetext", - "'[.*.]{3} This bug has been marked as a duplicate of [[:digit:]]+ [.*.]{3}'") . ") " . - "AND (resolution = 'DUPLICATE') " . - "ORDER BY longdescs.bug_when"); - $sth->execute(); - - my %dupes; - my $key; - - # Because of the way hashes work, this loop removes all but the last dupe - # resolution found for a given bug. - while (my ($dupe, $dupe_of) = $sth->fetchrow_array()) { - $dupes{$dupe} = $dupe_of; - } - - foreach $key (keys(%dupes)){ - $dupes{$key} =~ /^.*\*\*\* This bug has been marked as a duplicate of (\d+) \*\*\*$/ms; - $dupes{$key} = $1; - $dbh->do("INSERT INTO duplicates VALUES('$dupes{$key}', '$key')"); - # BugItsADupeOf Dupe - } -} +=item 1 -# 2000-12-18. Added an 'emailflags' field for storing preferences about -# when email gets sent on a per-user basis. -if (!$dbh->bz_column_info('profiles', 'emailflags') && - !$dbh->bz_column_info('email_setting', 'user_id')) { - $dbh->bz_add_column('profiles', 'emailflags', {TYPE => 'MEDIUMTEXT'}); -} +Checks if the required and optional perl modules are installed, +using L<Bugzilla::Install::Requirements/check_requirements>. -# 2000-11-27 For Bugzilla 2.5 and later. Copy data from 'comments' to -# 'longdescs' - the new name of the comments table. -if ($dbh->bz_table_info('comments')) { - my $quoted_when = $dbh->quote_identifier('when'); - # This is MySQL-specific syntax, but that's OK because it will only - # ever run on MySQL. - $dbh->do("INSERT INTO longdescs (bug_when, bug_id, who, thetext) - SELECT $quoted_when, bug_id, who, comment - FROM comments"); - $dbh->bz_drop_table("comments"); -} +=item 2 -# 2001-04-08 Added a special directory for the duplicates stats. -unless (-d "$datadir/duplicates") { - print "Creating duplicates directory...\n"; - mkdir "$datadir/duplicates", 0770; - if ($my_webservergroup eq "") { - chmod 01777, "$datadir/duplicates"; - } -} +Creates or updates the F<localconfig> file, using +L<Bugzilla::Install::Localconfig/update_localconfig>. -# -# 2001-04-10 myk@mozilla.org: -# isactive determines whether or not a group is active. An inactive group -# cannot have bugs added to it. Deactivation is a much milder form of -# deleting a group that allows users to continue to work on bugs in the group -# without enabling them to extend the life of the group by adding bugs to it. -# http://bugzilla.mozilla.org/show_bug.cgi?id=75482 -# -$dbh->bz_add_column('groups', 'isactive', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'}); +=item 3 -# -# 2001-06-15 myk@mozilla.org: -# isobsolete determines whether or not an attachment is pertinent/relevant/valid. -# -$dbh->bz_add_column('attachments', 'isobsolete', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); - -# 2001-04-29 jake@bugzilla.org - Remove oldemailtech -# http://bugzilla.mozilla.org/show_bugs.cgi?id=71552 -if (-d 'shadow') { - print "Removing shadow directory...\n"; - unlink glob("shadow/*"); - unlink glob("shadow/.*"); - rmdir "shadow"; -} -$dbh->bz_drop_column("profiles", "emailnotification"); -$dbh->bz_drop_column("profiles", "newemailtech"); - - -# 2003-11-19; chicks@chicks.net; bug 225973: fix field size to accommodate -# wider algorithms such as Blowfish. Note that this needs to be run -# before recrypting passwords in the following block. -$dbh->bz_alter_column('profiles', 'cryptpassword', {TYPE => 'varchar(128)'}); - -# 2001-06-12; myk@mozilla.org; bugs 74032, 77473: -# Recrypt passwords using Perl &crypt instead of the mysql equivalent -# and delete plaintext passwords from the database. -if ($dbh->bz_column_info('profiles', 'password')) { - - print <<ENDTEXT; -Your current installation of Bugzilla stores passwords in plaintext -in the database and uses mysql's encrypt function instead of Perl's -crypt function to crypt passwords. Passwords are now going to be -re-crypted with the Perl function, and plaintext passwords will be -deleted from the database. This could take a while if your -installation has many users. -ENDTEXT - - # Re-crypt everyone's password. - my $sth = $dbh->prepare("SELECT userid, password FROM profiles"); - $sth->execute(); - - my $i = 1; - - print "Fixing password #1... "; - while (my ($userid, $password) = $sth->fetchrow_array()) { - my $cryptpassword = $dbh->quote(bz_crypt($password)); - $dbh->do("UPDATE profiles " . - "SET cryptpassword = $cryptpassword " . - "WHERE userid = $userid"); - ++$i; - # Let the user know where we are at every 500 records. - print "$i... " if !($i%500); - } - print "$i... Done.\n"; - - # Drop the plaintext password field. - $dbh->bz_drop_column('profiles', 'password'); -} +Checks the DBD and database version, using +L<Bugzilla::DB/bz_check_requirements>. -# -# 2001-06-06 justdave@syndicomm.com: -# There was no index on the 'who' column in the long descriptions table. -# This caused queries by who posted comments to take a LONG time. -# http://bugzilla.mozilla.org/show_bug.cgi?id=57350 -$dbh->bz_add_index('longdescs', 'longdescs_who_idx', [qw(who)]); - -# 2001-06-15 kiko@async.com.br - Change bug:version size to avoid -# truncates re http://bugzilla.mozilla.org/show_bug.cgi?id=9352 -$dbh->bz_alter_column('bugs', 'version', - {TYPE => 'varchar(64)', NOTNULL => 1}); - -# 2001-07-20 jake@bugzilla.org - Change bugs_activity to only record changes -# http://bugzilla.mozilla.org/show_bug.cgi?id=55161 -if ($dbh->bz_column_info('bugs_activity', 'oldvalue')) { - $dbh->bz_add_column("bugs_activity", "removed", {TYPE => "TINYTEXT"}); - $dbh->bz_add_column("bugs_activity", "added", {TYPE => "TINYTEXT"}); - - # Need to get fieldid's for the fields that have multiple values - my @multi = (); - foreach my $f ("cc", "dependson", "blocked", "keywords") { - my $sth = $dbh->prepare("SELECT fieldid " . - "FROM fielddefs " . - "WHERE name = '$f'"); - $sth->execute(); - my ($fid) = $sth->fetchrow_array(); - push (@multi, $fid); - } - - # Now we need to process the bugs_activity table and reformat the data - my $i = 0; - print "Fixing activity log "; - my $sth = $dbh->prepare("SELECT bug_id, who, bug_when, fieldid, - oldvalue, newvalue FROM bugs_activity"); - $sth->execute; - while (my ($bug_id, $who, $bug_when, $fieldid, $oldvalue, $newvalue) = $sth->fetchrow_array()) { - # print the iteration count every 500 records - # so the user knows we didn't die - print "$i..." if !($i++ % 500); - # Make sure (old|new)value isn't null (to suppress warnings) - $oldvalue ||= ""; - $newvalue ||= ""; - my ($added, $removed) = ""; - if (grep ($_ eq $fieldid, @multi)) { - $oldvalue =~ s/[\s,]+/ /g; - $newvalue =~ s/[\s,]+/ /g; - my @old = split(" ", $oldvalue); - my @new = split(" ", $newvalue); - my (@add, @remove) = (); - # Find values that were "added" - foreach my $value(@new) { - if (! grep ($_ eq $value, @old)) { - push (@add, $value); - } - } - # Find values that were removed - foreach my $value(@old) { - if (! grep ($_ eq $value, @new)) { - push (@remove, $value); - } - } - $added = join (", ", @add); - $removed = join (", ", @remove); - # If we can't determine what changed, put a ? in both fields - unless ($added || $removed) { - $added = "?"; - $removed = "?"; - } - # If the original field (old|new)value was full, then this - # could be incomplete data. - if (length($oldvalue) == 255 || length($newvalue) == 255) { - $added = "? $added"; - $removed = "? $removed"; - } - } else { - $removed = $oldvalue; - $added = $newvalue; - } - $added = $dbh->quote($added); - $removed = $dbh->quote($removed); - $dbh->do("UPDATE bugs_activity SET removed = $removed, added = $added - WHERE bug_id = $bug_id AND who = $who - AND bug_when = '$bug_when' AND fieldid = $fieldid"); - } - print ". Done.\n"; - $dbh->bz_drop_column("bugs_activity", "oldvalue"); - $dbh->bz_drop_column("bugs_activity", "newvalue"); -} - -$dbh->bz_alter_column("profiles", "disabledtext", - {TYPE => 'MEDIUMTEXT', NOTNULL => 1}, ''); - -# 2001-07-26 myk@mozilla.org bug 39816 (original) -# 2002-02-06 bbaetz@student.usyd.edu.au bug 97471 (revision) -# Add fields to the bugs table that record whether or not the reporter -# and users on the cc: list can see bugs even when -# they are not members of groups to which the bugs are restricted. -$dbh->bz_add_column("bugs", "reporter_accessible", - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'}); -$dbh->bz_add_column("bugs", "cclist_accessible", - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'}); - -# 2001-08-21 myk@mozilla.org bug84338: -# Add a field to the bugs_activity table for the attachment ID, so installations -# using the attachment manager can record changes to attachments. -$dbh->bz_add_column("bugs_activity", "attach_id", {TYPE => 'INT3'}); - -# 2002-02-04 bbaetz@student.usyd.edu.au bug 95732 -# Remove logincookies.cryptpassword, and delete entries which become -# invalid -if ($dbh->bz_column_info("logincookies", "cryptpassword")) { - # We need to delete any cookies which are invalid before dropping the - # column - - print "Removing invalid login cookies...\n"; - - # mysql doesn't support DELETE with multi-table queries, so we have - # to iterate - my $sth = $dbh->prepare("SELECT cookie FROM logincookies, profiles " . - "WHERE logincookies.cryptpassword != " . - "profiles.cryptpassword AND " . - "logincookies.userid = profiles.userid"); - $sth->execute(); - while (my ($cookie) = $sth->fetchrow_array()) { - $dbh->do("DELETE FROM logincookies WHERE cookie = $cookie"); - } - - $dbh->bz_drop_column("logincookies", "cryptpassword"); -} +=item 4 -# 2002-02-13 bbaetz@student.usyd.edu.au - bug 97471 -# qacontact/assignee should always be able to see bugs, -# so remove their restriction column -if ($dbh->bz_column_info("bugs", "qacontact_accessible")) { - print "Removing restrictions on bugs for assignee and qacontact...\n"; +Creates the Bugzilla database if it doesn't exist, using +L<Bugzilla::DB/bz_create_database>. - $dbh->bz_drop_column("bugs", "qacontact_accessible"); - $dbh->bz_drop_column("bugs", "assignee_accessible"); -} +=item 5 -# 2002-02-20 jeff.hedlund@matrixsi.com - bug 24789 time tracking -$dbh->bz_add_column("longdescs", "work_time", - {TYPE => 'decimal(5,2)', NOTNULL => 1, DEFAULT => '0'}); -$dbh->bz_add_column("bugs", "estimated_time", - {TYPE => 'decimal(5,2)', NOTNULL => 1, DEFAULT => '0'}); -$dbh->bz_add_column("bugs", "remaining_time", - {TYPE => 'decimal(5,2)', NOTNULL => 1, DEFAULT => '0'}); -$dbh->bz_add_column("bugs", "deadline", {TYPE => 'DATETIME'}); - -# 2002-03-15 bbaetz@student.usyd.edu.au - bug 129466 -# 2002-05-13 preed@sigkill.com - bug 129446 patch backported to the -# BUGZILLA-2_14_1-BRANCH as a security blocker for the 2.14.2 release -# -# Use the ip, not the hostname, in the logincookies table -if ($dbh->bz_column_info("logincookies", "hostname")) { - # We've changed what we match against, so all entries are now invalid - $dbh->do("DELETE FROM logincookies"); - - # Now update the logincookies schema - $dbh->bz_drop_column("logincookies", "hostname"); - $dbh->bz_add_column("logincookies", "ipaddr", - {TYPE => 'varchar(40)', NOTNULL => 1}, ''); -} +Creates all of the tables in the Bugzilla database, using +L<Bugzilla::DB/bz_setup_database>. -# 2002-08-19 - bugreport@peshkin.net bug 143826 -# Add private comments and private attachments on less-private bugs -$dbh->bz_add_column('longdescs', 'isprivate', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); -$dbh->bz_add_column('attachments', 'isprivate', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); - - -# 2002-07-03 myk@mozilla.org bug99203: -# Add a bug alias field to the bugs table so bugs can be referenced by alias -# in addition to ID. -if (!$dbh->bz_column_info("bugs", "alias")) { - $dbh->bz_add_column("bugs", "alias", {TYPE => "varchar(20)"}); - $dbh->bz_add_index('bugs', 'bugs_alias_idx', - {TYPE => 'UNIQUE', FIELDS => [qw(alias)]}); -} +Note that all the table definitions are stored in +L<Bugzilla::DB::Schema/ABSTRACT_SCHEMA>. -# 2002-07-15 davef@tetsubo.com - bug 67950 -# Move quips to the db. -if (-r "$datadir/comments" && -s "$datadir/comments" - && open (COMMENTS, "<$datadir/comments")) { - print "Populating quips table from $datadir/comments...\n\n"; - while (<COMMENTS>) { - chomp; - $dbh->do("INSERT INTO quips (quip) VALUES (" - . $dbh->quote($_) . ")"); - } - print "Quips are now stored in the database, rather than in an external file.\n" . - "The quips previously stored in $datadir/comments have been copied into\n" . - "the database, and that file has been renamed to $datadir/comments.bak\n" . - "You may delete the renamed file once you have confirmed that all your \n" . - "quips were moved successfully.\n\n"; - close COMMENTS; - rename("$datadir/comments", "$datadir/comments.bak"); -} +=item 6 -# 2002-07-31 bbaetz@student.usyd.edu.au bug 158236 -# Remove unused column -if ($dbh->bz_column_info("namedqueries", "watchfordiffs")) { - $dbh->bz_drop_column("namedqueries", "watchfordiffs"); -} +Puts the values into the enum tables (like C<resolution>, C<bug_status>, +etc.) using L<Bugzilla::DB/bz_populate_enum_tables>. -# 2002-08-12 jake@bugzilla.org/bbaetz@student.usyd.edu.au - bug 43600 -# Use integer IDs for products and components. -if ($dbh->bz_column_info("products", "product")) { - print "Updating database to use product IDs.\n"; - - # First, we need to remove possible NULL entries - # NULLs may exist, but won't have been used, since all the uses of them - # are in NOT NULL fields in other tables - $dbh->do("DELETE FROM products WHERE product IS NULL"); - $dbh->do("DELETE FROM components WHERE value IS NULL"); - - $dbh->bz_add_column("products", "id", - {TYPE => 'SMALLSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); - $dbh->bz_add_column("components", "product_id", - {TYPE => 'INT2', NOTNULL => 1}, 0); - $dbh->bz_add_column("versions", "product_id", - {TYPE => 'INT2', NOTNULL => 1}, 0); - $dbh->bz_add_column("milestones", "product_id", - {TYPE => 'INT2', NOTNULL => 1}, 0); - $dbh->bz_add_column("bugs", "product_id", - {TYPE => 'INT2', NOTNULL => 1}, 0); - - # The attachstatusdefs table was added in version 2.15, but removed again - # in early 2.17. If it exists now, we still need to perform this change - # with product_id because the code further down which converts the - # attachment statuses to flags depends on it. But we need to avoid this - # if the user is upgrading from 2.14 or earlier (because it won't be - # there to convert). - if ($dbh->bz_table_info("attachstatusdefs")) { - $dbh->bz_add_column("attachstatusdefs", "product_id", - {TYPE => 'INT2', NOTNULL => 1}, 0); - } - - my %products; - my $sth = $dbh->prepare("SELECT id, product FROM products"); - $sth->execute; - while (my ($product_id, $product) = $sth->fetchrow_array()) { - if (exists $products{$product}) { - print "Ignoring duplicate product $product\n"; - $dbh->do("DELETE FROM products WHERE id = $product_id"); - next; - } - $products{$product} = 1; - $dbh->do("UPDATE components SET product_id = $product_id " . - "WHERE program = " . $dbh->quote($product)); - $dbh->do("UPDATE versions SET product_id = $product_id " . - "WHERE program = " . $dbh->quote($product)); - $dbh->do("UPDATE milestones SET product_id = $product_id " . - "WHERE product = " . $dbh->quote($product)); - $dbh->do("UPDATE bugs SET product_id = $product_id " . - "WHERE product = " . $dbh->quote($product)); - $dbh->do("UPDATE attachstatusdefs SET product_id = $product_id " . - "WHERE product = " . $dbh->quote($product)) - if $dbh->bz_table_info("attachstatusdefs"); - } - - print "Updating the database to use component IDs.\n"; - $dbh->bz_add_column("components", "id", - {TYPE => 'SMALLSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); - $dbh->bz_add_column("bugs", "component_id", - {TYPE => 'INT2', NOTNULL => 1}, 0); - - my %components; - $sth = $dbh->prepare("SELECT id, value, product_id FROM components"); - $sth->execute; - while (my ($component_id, $component, $product_id) = $sth->fetchrow_array()) { - if (exists $components{$component}) { - if (exists $components{$component}{$product_id}) { - print "Ignoring duplicate component $component for product $product_id\n"; - $dbh->do("DELETE FROM components WHERE id = $component_id"); - next; - } - } else { - $components{$component} = {}; - } - $components{$component}{$product_id} = 1; - $dbh->do("UPDATE bugs SET component_id = $component_id " . - "WHERE component = " . $dbh->quote($component) . - " AND product_id = $product_id"); - } - print "Fixing Indexes and Uniqueness.\n"; - $dbh->bz_drop_index('milestones', 'milestones_product_idx'); - - $dbh->bz_add_index('milestones', 'milestones_product_id_idx', - {TYPE => 'UNIQUE', FIELDS => [qw(product_id value)]}); - - $dbh->bz_drop_index('bugs', 'bugs_product_idx'); - $dbh->bz_add_index('bugs', 'bugs_product_id_idx', [qw(product_id)]); - $dbh->bz_drop_index('bugs', 'bugs_component_idx'); - $dbh->bz_add_index('bugs', 'bugs_component_id_idx', [qw(component_id)]); - - print "Removing, renaming, and retyping old product and component fields.\n"; - $dbh->bz_drop_column("components", "program"); - $dbh->bz_drop_column("versions", "program"); - $dbh->bz_drop_column("milestones", "product"); - $dbh->bz_drop_column("bugs", "product"); - $dbh->bz_drop_column("bugs", "component"); - $dbh->bz_drop_column("attachstatusdefs", "product") - if $dbh->bz_table_info("attachstatusdefs"); - $dbh->bz_rename_column("products", "product", "name"); - $dbh->bz_alter_column("products", "name", - {TYPE => 'varchar(64)', NOTNULL => 1}); - $dbh->bz_rename_column("components", "value", "name"); - $dbh->bz_alter_column("components", "name", - {TYPE => 'varchar(64)', NOTNULL => 1}); - - print "Adding indexes for products and components tables.\n"; - $dbh->bz_add_index('products', 'products_name_idx', - {TYPE => 'UNIQUE', FIELDS => [qw(name)]}); - $dbh->bz_add_index('components', 'components_product_id_idx', - {TYPE => 'UNIQUE', FIELDS => [qw(product_id name)]}); - $dbh->bz_add_index('components', 'components_name_idx', [qw(name)]); -} +=item 7 -# 2002-09-22 - bugreport@peshkin.net - bug 157756 -# -# If the whole groups system is new, but the installation isn't, -# convert all the old groupset groups, etc... -# -# This requires: -# 1) define groups ids in group table -# 2) populate user_group_map with grants from old groupsets and blessgroupsets -# 3) populate bug_group_map with data converted from old bug groupsets -# 4) convert activity logs to use group names instead of numbers -# 5) identify the admin from the old all-ones groupset -# -# ListBits(arg) returns a list of UNKNOWN<n> if the group -# has been deleted for all bits set in arg. When the activity -# records are converted from groupset numbers to lists of -# group names, ListBits is used to fill in a list of references -# to groupset bits for groups that no longer exist. -# -sub ListBits { - my ($num) = @_; - my @res = (); - my $curr = 1; - while (1) { - # Convert a big integer to a list of bits - my $sth = $dbh->prepare("SELECT ($num & ~$curr) > 0, - ($num & $curr), - ($num & ~$curr), - $curr << 1"); - $sth->execute; - my ($more, $thisbit, $remain, $nval) = $sth->fetchrow_array; - push @res,"UNKNOWN<$curr>" if ($thisbit); - $curr = $nval; - $num = $remain; - last if (!$more); - } - return @res; -} +Creates any files that Bugzilla needs but doesn't ship with, using +L<Bugzilla::Install::Filesystem/update_filesystem>. -# The groups system needs to be converted if groupset exists -if ($dbh->bz_column_info("profiles", "groupset")) { - $dbh->bz_add_column('groups', 'last_changed', - {TYPE => 'DATETIME', NOTNULL => 1}, '0000-00-00 00:00:00'); - - # Some mysql versions will promote any unique key to primary key - # so all unique keys are removed first and then added back in - $dbh->bz_drop_index('groups', 'groups_bit_idx'); - $dbh->bz_drop_index('groups', 'groups_name_idx'); - my @primary_key = $dbh->primary_key(undef, undef, 'groups'); - if (@primary_key) { - $dbh->do("ALTER TABLE groups DROP PRIMARY KEY"); - } - - $dbh->bz_add_column('groups', 'id', - {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); - - $dbh->bz_add_index('groups', 'groups_name_idx', - {TYPE => 'UNIQUE', FIELDS => [qw(name)]}); - $dbh->bz_add_column('profiles', 'refreshed_when', - {TYPE => 'DATETIME', NOTNULL => 1}, '0000-00-00 00:00:00'); - - # Convert all existing groupset records to map entries before removing - # groupset fields or removing "bit" from groups. - $sth = $dbh->prepare("SELECT bit, id FROM groups - WHERE bit > 0"); - $sth->execute(); - while (my ($bit, $gid) = $sth->fetchrow_array) { - # Create user_group_map membership grants for old groupsets. - # Get each user with the old groupset bit set - my $sth2 = $dbh->prepare("SELECT userid FROM profiles - WHERE (groupset & $bit) != 0"); - $sth2->execute(); - while (my ($uid) = $sth2->fetchrow_array) { - # Check to see if the user is already a member of the group - # and, if not, insert a new record. - my $query = "SELECT user_id FROM user_group_map - WHERE group_id = $gid AND user_id = $uid - AND isbless = 0"; - my $sth3 = $dbh->prepare($query); - $sth3->execute(); - if ( !$sth3->fetchrow_array() ) { - $dbh->do("INSERT INTO user_group_map - (user_id, group_id, isbless, grant_type) - VALUES($uid, $gid, 0, " . GRANT_DIRECT . ")"); - } - } - # Create user can bless group grants for old groupsets, but only - # if we're upgrading from a Bugzilla that had blessing. - if($dbh->bz_column_info('profiles', 'blessgroupset')) { - # Get each user with the old blessgroupset bit set - $sth2 = $dbh->prepare("SELECT userid FROM profiles - WHERE (blessgroupset & $bit) != 0"); - $sth2->execute(); - while (my ($uid) = $sth2->fetchrow_array) { - $dbh->do("INSERT INTO user_group_map - (user_id, group_id, isbless, grant_type) - VALUES($uid, $gid, 1, " . GRANT_DIRECT . ")"); - } - } - # Create bug_group_map records for old groupsets. - # Get each bug with the old group bit set. - $sth2 = $dbh->prepare("SELECT bug_id FROM bugs - WHERE (groupset & $bit) != 0"); - $sth2->execute(); - while (my ($bug_id) = $sth2->fetchrow_array) { - # Insert the bug, group pair into the bug_group_map. - $dbh->do("INSERT INTO bug_group_map - (bug_id, group_id) - VALUES($bug_id, $gid)"); - } - } - # Replace old activity log groupset records with lists of names of groups. - # Start by defining the bug_group field and getting its id. - AddFDef("bug_group", "Group", 0); - $sth = $dbh->prepare("SELECT fieldid " . - "FROM fielddefs " . - "WHERE name = " . $dbh->quote('bug_group')); - $sth->execute(); - my ($bgfid) = $sth->fetchrow_array; - # Get the field id for the old groupset field - $sth = $dbh->prepare("SELECT fieldid " . - "FROM fielddefs " . - "WHERE name = " . $dbh->quote('groupset')); - $sth->execute(); - my ($gsid) = $sth->fetchrow_array; - # Get all bugs_activity records from groupset changes - if ($gsid) { - $sth = $dbh->prepare("SELECT bug_id, bug_when, who, added, removed - FROM bugs_activity WHERE fieldid = $gsid"); - $sth->execute(); - while (my ($bug_id, $bug_when, $who, $added, $removed) = $sth->fetchrow_array) { - $added ||= 0; - $removed ||= 0; - # Get names of groups added. - my $sth2 = $dbh->prepare("SELECT name " . - "FROM groups " . - "WHERE (bit & $added) != 0 " . - "AND (bit & $removed) = 0"); - $sth2->execute(); - my @logadd = (); - while (my ($n) = $sth2->fetchrow_array) { - push @logadd, $n; - } - # Get names of groups removed. - $sth2 = $dbh->prepare("SELECT name " . - "FROM groups " . - "WHERE (bit & $removed) != 0 " . - "AND (bit & $added) = 0"); - $sth2->execute(); - my @logrem = (); - while (my ($n) = $sth2->fetchrow_array) { - push @logrem, $n; - } - # Get list of group bits added that correspond to missing groups. - $sth2 = $dbh->prepare("SELECT ($added & ~BIT_OR(bit)) FROM groups"); - $sth2->execute(); - my ($miss) = $sth2->fetchrow_array; - if ($miss) { - push @logadd, ListBits($miss); - print "\nWARNING - GROUPSET ACTIVITY ON BUG $bug_id CONTAINS DELETED GROUPS\n"; - } - # Get list of group bits deleted that correspond to missing groups. - $sth2 = $dbh->prepare("SELECT ($removed & ~BIT_OR(bit)) FROM groups"); - $sth2->execute(); - ($miss) = $sth2->fetchrow_array; - if ($miss) { - push @logrem, ListBits($miss); - print "\nWARNING - GROUPSET ACTIVITY ON BUG $bug_id CONTAINS DELETED GROUPS\n"; - } - my $logr = ""; - my $loga = ""; - $logr = join(", ", @logrem) . '?' if @logrem; - $loga = join(", ", @logadd) . '?' if @logadd; - # Replace to old activity record with the converted data. - $dbh->do("UPDATE bugs_activity SET fieldid = $bgfid, added = " . - $dbh->quote($loga) . ", removed = " . - $dbh->quote($logr) . - " WHERE bug_id = $bug_id AND bug_when = " . - $dbh->quote($bug_when) . - " AND who = $who AND fieldid = $gsid"); - - } - # Replace groupset changes with group name changes in profiles_activity. - # Get profiles_activity records for groupset. - $sth = $dbh->prepare( - "SELECT userid, profiles_when, who, newvalue, oldvalue " . - "FROM profiles_activity " . - "WHERE fieldid = $gsid"); - $sth->execute(); - while (my ($uid, $uwhen, $uwho, $added, $removed) = $sth->fetchrow_array) { - $added ||= 0; - $removed ||= 0; - # Get names of groups added. - my $sth2 = $dbh->prepare("SELECT name " . - "FROM groups " . - "WHERE (bit & $added) != 0 " . - "AND (bit & $removed) = 0"); - $sth2->execute(); - my @logadd = (); - while (my ($n) = $sth2->fetchrow_array) { - push @logadd, $n; - } - # Get names of groups removed. - $sth2 = $dbh->prepare("SELECT name " . - "FROM groups " . - "WHERE (bit & $removed) != 0 " . - "AND (bit & $added) = 0"); - $sth2->execute(); - my @logrem = (); - while (my ($n) = $sth2->fetchrow_array) { - push @logrem, $n; - } - my $ladd = ""; - my $lrem = ""; - $ladd = join(", ", @logadd) . '?' if @logadd; - $lrem = join(", ", @logrem) . '?' if @logrem; - # Replace profiles_activity record for groupset change - # with group list. - $dbh->do("UPDATE profiles_activity " . - "SET fieldid = $bgfid, newvalue = " . - $dbh->quote($ladd) . ", oldvalue = " . - $dbh->quote($lrem) . - " WHERE userid = $uid AND profiles_when = " . - $dbh->quote($uwhen) . - " AND who = $uwho AND fieldid = $gsid"); - - } - } - # Identify admin group. - my $sth = $dbh->prepare("SELECT id FROM groups - WHERE name = 'admin'"); - $sth->execute(); - my ($adminid) = $sth->fetchrow_array(); - # find existing admins - # Don't lose admins from DBs where Bug 157704 applies - $sth = $dbh->prepare( - "SELECT userid, (groupset & 65536), login_name " . - "FROM profiles " . - "WHERE (groupset | 65536) = 9223372036854775807"); - $sth->execute(); - while ( my ($userid, $iscomplete, $login_name) = $sth->fetchrow_array() ) { - # existing administrators are made members of group "admin" - print "\nWARNING - $login_name IS AN ADMIN IN SPITE OF BUG 157704\n\n" - if (!$iscomplete); - push @admins, $userid; - } - $dbh->bz_drop_column('profiles','groupset'); - $dbh->bz_drop_column('profiles','blessgroupset'); - $dbh->bz_drop_column('bugs','groupset'); - $dbh->bz_drop_column('groups','bit'); - $dbh->do("DELETE FROM fielddefs WHERE name = " . $dbh->quote('groupset')); -} +=item 8 -# September 2002 myk@mozilla.org bug 98801 -# Convert the attachment statuses tables into flags tables. -if ($dbh->bz_table_info("attachstatuses") - && $dbh->bz_table_info("attachstatusdefs")) -{ - print "Converting attachment statuses to flags...\n"; - - # Get IDs for the old attachment status and new flag fields. - my ($old_field_id) = $dbh->selectrow_array( - "SELECT fieldid FROM fielddefs WHERE name='attachstatusdefs.name'") - || 0; - - $sth = $dbh->prepare("SELECT fieldid FROM fielddefs " . - "WHERE name='flagtypes.name'"); - $sth->execute(); - my $new_field_id = $sth->fetchrow_arrayref()->[0]; - - # Convert attachment status definitions to flag types. If more than one - # status has the same name and description, it is merged into a single - # status with multiple inclusion records. - $sth = $dbh->prepare("SELECT id, name, description, sortkey, product_id " . - "FROM attachstatusdefs"); - - # status definition IDs indexed by name/description - my $def_ids = {}; - - # merged IDs and the IDs they were merged into. The key is the old ID, - # the value is the new one. This allows us to give statuses the right - # ID when we convert them over to flags. This map includes IDs that - # weren't merged (in this case the old and new IDs are the same), since - # it makes the code simpler. - my $def_id_map = {}; - - $sth->execute(); - while (my ($id, $name, $desc, $sortkey, $prod_id) = $sth->fetchrow_array()) { - my $key = $name . $desc; - if (!$def_ids->{$key}) { - $def_ids->{$key} = $id; - my $quoted_name = $dbh->quote($name); - my $quoted_desc = $dbh->quote($desc); - $dbh->do("INSERT INTO flagtypes (id, name, description, sortkey, " . - "target_type) VALUES ($id, $quoted_name, $quoted_desc, " . - "$sortkey, 'a')"); - } - $def_id_map->{$id} = $def_ids->{$key}; - $dbh->do("INSERT INTO flaginclusions (type_id, product_id) " . - "VALUES ($def_id_map->{$id}, $prod_id)"); - } - - # Note: even though we've converted status definitions, we still can't drop - # the table because we need it to convert the statuses themselves. - - # Convert attachment statuses to flags. To do this we select the statuses - # from the status table and then, for each one, figure out who set it - # and when they set it from the bugs activity table. - my $id = 0; - $sth = $dbh->prepare( - "SELECT attachstatuses.attach_id, attachstatusdefs.id, " . - "attachstatusdefs.name, attachments.bug_id " . - "FROM attachstatuses, attachstatusdefs, attachments " . - "WHERE attachstatuses.statusid = attachstatusdefs.id " . - "AND attachstatuses.attach_id = attachments.attach_id"); - - # a query to determine when the attachment status was set and who set it - my $sth2 = $dbh->prepare("SELECT added, who, bug_when " . - "FROM bugs_activity " . - "WHERE bug_id = ? AND attach_id = ? " . - "AND fieldid = $old_field_id " . - "ORDER BY bug_when DESC"); - - $sth->execute(); - while (my ($attach_id, $def_id, $status, $bug_id) = $sth->fetchrow_array()) { - ++$id; - - # Determine when the attachment status was set and who set it. - # We should always be able to find out this info from the bug activity, - # but we fall back to default values just in case. - $sth2->execute($bug_id, $attach_id); - my ($added, $who, $when); - while (($added, $who, $when) = $sth2->fetchrow_array()) { - last if $added =~ /(^|[, ]+)\Q$status\E([, ]+|$)/; - } - $who = $dbh->quote($who); # "NULL" by default if $who is undefined - $when = $when ? $dbh->quote($when) : "NOW()"; - - - $dbh->do("INSERT INTO flags (id, type_id, status, bug_id, attach_id, " . - "creation_date, modification_date, requestee_id, setter_id) " . - "VALUES ($id, $def_id_map->{$def_id}, '+', $bug_id, " . - "$attach_id, $when, $when, NULL, $who)"); - } - - # Now that we've converted both tables we can drop them. - $dbh->bz_drop_table("attachstatuses"); - $dbh->bz_drop_table("attachstatusdefs"); - - # Convert activity records for attachment statuses into records for flags. - my $sth = $dbh->prepare("SELECT attach_id, who, bug_when, added, removed " . - "FROM bugs_activity WHERE fieldid = $old_field_id"); - $sth->execute(); - while (my ($attach_id, $who, $when, $old_added, $old_removed) = - $sth->fetchrow_array()) - { - my @additions = split(/[, ]+/, $old_added); - @additions = map("$_+", @additions); - my $new_added = $dbh->quote(join(", ", @additions)); - - my @removals = split(/[, ]+/, $old_removed); - @removals = map("$_+", @removals); - my $new_removed = $dbh->quote(join(", ", @removals)); - - $old_added = $dbh->quote($old_added); - $old_removed = $dbh->quote($old_removed); - $who = $dbh->quote($who); - $when = $dbh->quote($when); - - $dbh->do("UPDATE bugs_activity SET fieldid = $new_field_id, " . - "added = $new_added, removed = $new_removed " . - "WHERE attach_id = $attach_id AND who = $who " . - "AND bug_when = $when AND fieldid = $old_field_id " . - "AND added = $old_added AND removed = $old_removed"); - } - - # Remove the attachment status field from the field definitions. - $dbh->do("DELETE FROM fielddefs WHERE name='attachstatusdefs.name'"); - - print "done.\n"; -} +Creates the F<.htaccess> files if you haven't specified not to +in F<localconfig>. It does this with +L<Bugzilla::Install::Filesystem/create_htaccess>. -# 2004-12-13 Nick.Barnes@pobox.com bug 262268 -# Check for spaces and commas in flag type names; if found, rename them. -if ($dbh->bz_table_info("flagtypes")) { - # Get all names and IDs, to find broken ones and to - # check for collisions when renaming. - $sth = $dbh->prepare("SELECT name, id FROM flagtypes"); - $sth->execute(); - - my %flagtypes; - my @badflagnames; - - # find broken flagtype names, and populate a hash table - # to check for collisions. - while (my ($name, $id) = $sth->fetchrow_array()) { - $flagtypes{$name} = $id; - if ($name =~ /[ ,]/) { - push(@badflagnames, $name); - } - } - if (@badflagnames) { - print "Removing spaces and commas from flag names...\n"; - my ($flagname, $tryflagname); - my $sth = $dbh->prepare("UPDATE flagtypes SET name = ? WHERE id = ?"); - foreach $flagname (@badflagnames) { - print " Bad flag type name \"$flagname\" ...\n"; - # find a new name for this flagtype. - ($tryflagname = $flagname) =~ tr/ ,/__/; - # avoid collisions with existing flagtype names. - while (defined($flagtypes{$tryflagname})) { - print " ... can't rename as \"$tryflagname\" ...\n"; - $tryflagname .= "'"; - if (length($tryflagname) > 50) { - my $lastchanceflagname = (substr $tryflagname, 0, 47) . '...'; - if (defined($flagtypes{$lastchanceflagname})) { - print " ... last attempt as \"$lastchanceflagname\" still failed.'\n", - "Rename the flag by hand and run checksetup.pl again.\n"; - die("Bad flag type name $flagname"); - } - $tryflagname = $lastchanceflagname; - } - } - $sth->execute($tryflagname, $flagtypes{$flagname}); - print " renamed flag type \"$flagname\" as \"$tryflagname\"\n"; - $flagtypes{$tryflagname} = $flagtypes{$flagname}; - delete $flagtypes{$flagname}; - } - print "... done.\n"; - } -} +=item 9 -# 2002-11-24 - bugreport@peshkin.net - bug 147275 -# -# If group_control_map is empty, backward-compatibility -# usebuggroups-equivalent records should be created. -my $entry = Param('useentrygroupdefault'); -$sth = $dbh->prepare("SELECT COUNT(*) FROM group_control_map"); -$sth->execute(); -my ($mapcnt) = $sth->fetchrow_array(); -if ($mapcnt == 0) { - # Initially populate group_control_map. - # First, get all the existing products and their groups. - $sth = $dbh->prepare("SELECT groups.id, products.id, groups.name, " . - "products.name FROM groups, products " . - "WHERE isbuggroup != 0"); - $sth->execute(); - while (my ($groupid, $productid, $groupname, $productname) - = $sth->fetchrow_array()) { - if ($groupname eq $productname) { - # Product and group have same name. - $dbh->do("INSERT INTO group_control_map " . - "(group_id, product_id, entry, membercontrol, " . - "othercontrol, canedit) " . - "VALUES ($groupid, $productid, $entry, " . - CONTROLMAPDEFAULT . ", " . - CONTROLMAPNA . ", 0)"); - } else { - # See if this group is a product group at all. - my $sth2 = $dbh->prepare("SELECT id FROM products WHERE name = " . - $dbh->quote($groupname)); - $sth2->execute(); - my ($id) = $sth2->fetchrow_array(); - if (!$id) { - # If there is no product with the same name as this - # group, then it is permitted for all products. - $dbh->do("INSERT INTO group_control_map " . - "(group_id, product_id, entry, membercontrol, " . - "othercontrol, canedit) " . - "VALUES ($groupid, $productid, 0, " . - CONTROLMAPSHOWN . ", " . - CONTROLMAPNA . ", 0)"); - } - } - } -} +Updates the system parameters (stored in F<data/params>), using +L<Bugzilla::Config/update_params>. -# 2004-07-17 GRM - Remove "subscriptions" concept from charting, and add -# group-based security instead. -if ($dbh->bz_table_info("user_series_map")) { - # Oracle doesn't like "date" as a column name, and apparently some DBs - # don't like 'value' either. We use the changes to subscriptions as - # something to hang these renamings off. - $dbh->bz_rename_column('series_data', 'date', 'series_date'); - $dbh->bz_rename_column('series_data', 'value', 'series_value'); - - # series_categories.category_id produces a too-long column name for the - # auto-incrementing sequence (Oracle again). - $dbh->bz_rename_column('series_categories', 'category_id', 'id'); - - $dbh->bz_add_column("series", "public", - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); - - # Migrate public-ness across from user_series_map to new field - $sth = $dbh->prepare("SELECT series_id from user_series_map " . - "WHERE user_id = 0"); - $sth->execute(); - while (my ($public_series_id) = $sth->fetchrow_array()) { - $dbh->do("UPDATE series SET public = 1 " . - "WHERE series_id = $public_series_id"); - } - - $dbh->bz_drop_table("user_series_map"); -} - -# 2003-06-26 Copy the old charting data into the database, and create the -# queries that will keep it all running. When the old charting system goes -# away, if this code ever runs, it'll just find no files and do nothing. -my $series_exists = $dbh->selectrow_array("SELECT 1 FROM series " . - $dbh->sql_limit(1)); -if (!$series_exists) { - print "Migrating old chart data into database ...\n" unless $silent; - - require Bugzilla::Series; - - # We prepare the handle to insert the series data - my $seriesdatasth = $dbh->prepare("INSERT INTO series_data " . - "(series_id, series_date, series_value) " . - "VALUES (?, ?, ?)"); - - my $deletesth = $dbh->prepare("DELETE FROM series_data - WHERE series_id = ? AND series_date = ?"); - - my $groupmapsth = $dbh->prepare("INSERT INTO category_group_map " . - "(category_id, group_id) " . - "VALUES (?, ?)"); - - # Fields in the data file (matches the current collectstats.pl) - my @statuses = - qw(NEW ASSIGNED REOPENED UNCONFIRMED RESOLVED VERIFIED CLOSED); - my @resolutions = - qw(FIXED INVALID WONTFIX LATER REMIND DUPLICATE WORKSFORME MOVED); - my @fields = (@statuses, @resolutions); - - # We have a localization problem here. Where do we get these values? - my $all_name = "-All-"; - my $open_name = "All Open"; - - my $products = $dbh->selectall_arrayref("SELECT name FROM products"); - - foreach my $product ((map { $_->[0] } @$products), "-All-") { - # First, create the series - my %queries; - my %seriesids; - - my $query_prod = ""; - if ($product ne "-All-") { - $query_prod = "product=" . html_quote($product) . "&"; - } - - # The query for statuses is different to that for resolutions. - $queries{$_} = ($query_prod . "bug_status=$_") foreach (@statuses); - $queries{$_} = ($query_prod . "resolution=$_") foreach (@resolutions); - - foreach my $field (@fields) { - # Create a Series for each field in this product. - # user ID = 0 is used. - my $series = new Bugzilla::Series(undef, $product, $all_name, - $field, 0, 1, - $queries{$field}, 1); - $series->writeToDatabase(); - $seriesids{$field} = $series->{'series_id'}; - } - - # We also add a new query for "Open", so that migrated products get - # the same set as new products (see editproducts.cgi.) - my @openedstatuses = ("UNCONFIRMED", "NEW", "ASSIGNED", "REOPENED"); - my $query = join("&", map { "bug_status=$_" } @openedstatuses); - my $series = new Bugzilla::Series(undef, $product, $all_name, - $open_name, 0, 1, - $query_prod . $query, 1); - $series->writeToDatabase(); - $seriesids{$open_name} = $series->{'series_id'}; - - # Now, we attempt to read in historical data, if any - # Convert the name in the same way that collectstats.pl does - my $product_file = $product; - $product_file =~ s/\//-/gs; - $product_file = "$datadir/mining/$product_file"; - - # There are many reasons that this might fail (e.g. no stats for this - # product), so we don't worry if it does. - open(IN, $product_file) or next; - - # The data files should be in a standard format, even for old - # Bugzillas, because of the conversion code further up this file. - my %data; - my $last_date = ""; - - while (<IN>) { - if (/^(\d+\|.*)/) { - my @numbers = split(/\||\r/, $1); - - # Only take the first line for each date; it was possible to - # run collectstats.pl more than once in a day. - next if $numbers[0] eq $last_date; - - for my $i (0 .. $#fields) { - # $numbers[0] is the date - $data{$fields[$i]}{$numbers[0]} = $numbers[$i + 1]; - - # Keep a total of the number of open bugs for this day - if (IsOpenedState($fields[$i])) { - $data{$open_name}{$numbers[0]} += $numbers[$i + 1]; - } - } - - $last_date = $numbers[0]; - } - } - - close(IN); - - foreach my $field (@fields, $open_name) { - # Insert values into series_data: series_id, date, value - my %fielddata = %{$data{$field}}; - foreach my $date (keys %fielddata) { - # We need to delete in case the text file had duplicate entries - # in it. - $deletesth->execute($seriesids{$field}, - $date); - - # We prepared this above - $seriesdatasth->execute($seriesids{$field}, - $date, - $fielddata{$date} || 0); - } - } - - # Create the groupsets for the category - my $category_id = - $dbh->selectrow_array("SELECT id " . - "FROM series_categories " . - "WHERE name = " . $dbh->quote($product)); - my $product_id = - $dbh->selectrow_array("SELECT id " . - "FROM products " . - "WHERE name = " . $dbh->quote($product)); - - if (defined($category_id) && defined($product_id)) { - - # Get all the mandatory groups for this product - my $group_ids = - $dbh->selectcol_arrayref("SELECT group_id " . - "FROM group_control_map " . - "WHERE product_id = $product_id " . - "AND (membercontrol = " . CONTROLMAPMANDATORY . - " OR othercontrol = " . CONTROLMAPMANDATORY . ")"); - - foreach my $group_id (@$group_ids) { - $groupmapsth->execute($category_id, $group_id); - } - } - } -} +=item 10 -AddFDef("owner_idle_time", "Time Since Assignee Touched", 0); +Pre-compiles all templates, to improve the speed of Bugzilla. +It uses L<Bugzilla::Template/precompile_templates> to do this. -# 2004-04-12 - Keep regexp-based group permissions up-to-date - Bug 240325 -if ($dbh->bz_column_info("user_group_map", "isderived")) { - $dbh->bz_add_column('user_group_map', 'grant_type', - {TYPE => 'INT1', NOTNULL => 1, DEFAULT => '0'}); - $dbh->do("DELETE FROM user_group_map WHERE isderived != 0"); - $dbh->do("UPDATE user_group_map SET grant_type = " . GRANT_DIRECT); - $dbh->bz_drop_column("user_group_map", "isderived"); +=item 11 - $dbh->bz_drop_index('user_group_map', 'user_group_map_user_id_idx'); - $dbh->bz_add_index('user_group_map', 'user_group_map_user_id_idx', - {TYPE => 'UNIQUE', - FIELDS => [qw(user_id group_id grant_type isbless)]}); +Fixes all file permissions to be secure. It does this differently depending +on whether or not you've specified C<$webservergroup> in F<localconfig>. - # Make sure groups get rederived - $dbh->do("UPDATE groups SET last_changed = NOW() WHERE name = 'admin'"); -} +The function that does this is +L<Bugzilla::Install::Filesystem/fix_all_file_permissions>. -# 2004-07-03 - Make it possible to disable flags without deleting them -# from the database. Bug 223878, jouni@heikniemi.net - -$dbh->bz_add_column('flags', 'is_active', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'}); - -# 2004-07-16 - Make it possible to have group-group relationships other than -# membership and bless. -if ($dbh->bz_column_info("group_group_map", "isbless")) { - $dbh->bz_add_column('group_group_map', 'grant_type', - {TYPE => 'INT1', NOTNULL => 1, DEFAULT => '0'}); - $dbh->do("UPDATE group_group_map SET grant_type = " . - "IF(isbless, " . GROUP_BLESS . ", " . - GROUP_MEMBERSHIP . ")"); - $dbh->bz_drop_index('group_group_map', 'group_group_map_member_id_idx'); - $dbh->bz_drop_column("group_group_map", "isbless"); - $dbh->bz_add_index('group_group_map', 'group_group_map_member_id_idx', - {TYPE => 'UNIQUE', FIELDS => [qw(member_id grantor_id grant_type)]}); -} - -# Allow profiles to optionally be linked to a unique identifier in an outside -# login data source -$dbh->bz_add_column("profiles", "extern_id", {TYPE => 'varchar(64)'}); - -# 2004-11-20 - LpSolit@netscape.net - Bug 180879 -# Add grant and request groups for flags -$dbh->bz_add_column('flagtypes', 'grant_group_id', {TYPE => 'INT3'}); -$dbh->bz_add_column('flagtypes', 'request_group_id', {TYPE => 'INT3'}); - -# 2004-01-03 - bug 253721 erik@dasbistro.com -# mailto is no longer just userids -$dbh->bz_rename_column('whine_schedules', 'mailto_userid', 'mailto'); -$dbh->bz_add_column('whine_schedules', 'mailto_type', - {TYPE => 'INT2', NOTNULL => 1, DEFAULT => '0'}); - -# 2005-01-29 - mkanat@bugzilla.org -if (!$dbh->bz_column_info('longdescs', 'already_wrapped')) { - # Old, pre-wrapped comments should not be auto-wrapped - $dbh->bz_add_column('longdescs', 'already_wrapped', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}, 1); - # If an old comment doesn't have a newline in the first 80 characters, - # (or doesn't contain a newline at all) and it contains a space, - # then it's probably a mis-wrapped comment and we should wrap it - # at display-time. - print "Fixing old, mis-wrapped comments...\n"; - $dbh->do(q{UPDATE longdescs SET already_wrapped = 0 - WHERE (} . $dbh->sql_position(q{'\n'}, 'thetext') . q{ > 80 - OR } . $dbh->sql_position(q{'\n'}, 'thetext') . q{ = 0) - AND SUBSTRING(thetext FROM 1 FOR 80) LIKE '% %'}); -} +=item 12 -# 2001-09-03 (landed 2005-02-24) dkl@redhat.com bug 17453 -# Moved enum types to separate tables so we need change the old enum types to -# standard varchars in the bugs table. -$dbh->bz_alter_column('bugs', 'bug_status', - {TYPE => 'varchar(64)', NOTNULL => 1}); -# 2005-03-23 Tomas.Kopal@altap.cz - add default value to resolution, bug 286695 -$dbh->bz_alter_column('bugs', 'resolution', - {TYPE => 'varchar(64)', NOTNULL => 1, DEFAULT => "''"}); -$dbh->bz_alter_column('bugs', 'priority', - {TYPE => 'varchar(64)', NOTNULL => 1}); -$dbh->bz_alter_column('bugs', 'bug_severity', - {TYPE => 'varchar(64)', NOTNULL => 1}); -$dbh->bz_alter_column('bugs', 'rep_platform', - {TYPE => 'varchar(64)', NOTNULL => 1}, ''); -$dbh->bz_alter_column('bugs', 'op_sys', - {TYPE => 'varchar(64)', NOTNULL => 1}); - - -# 2005-02-20 - LpSolit@gmail.com - Bug 277504 -# When migrating quips from the '$datadir/comments' file to the DB, -# the user ID should be NULL instead of 0 (which is an invalid user ID). -if ($dbh->bz_column_info('quips', 'userid')->{NOTNULL}) { - $dbh->bz_alter_column('quips', 'userid', {TYPE => 'INT3'}); - print "Changing owner to NULL for quips where the owner is unknown...\n"; - $dbh->do('UPDATE quips SET userid = NULL WHERE userid = 0'); -} +Populates the C<fielddefs> table, using +L<Bugzilla::Field/populate_field_definitions>. -# 2005-02-21 - LpSolit@gmail.com - Bug 279910 -# qacontact_accessible and assignee_accessible field names no longer exist -# in the 'bugs' table. Their corresponding entries in the 'bugs_activity' -# table should therefore be marked as obsolete, meaning that they cannot -# be used anymore when querying the database - they are not deleted in -# order to keep track of these fields in the activity table. -if (!$dbh->bz_column_info('fielddefs', 'obsolete')) { - $dbh->bz_add_column('fielddefs', 'obsolete', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}); - print "Marking qacontact_accessible and assignee_accessible as obsolete fields...\n"; - $dbh->do("UPDATE fielddefs SET obsolete = 1 - WHERE name = 'qacontact_accessible' - OR name = 'assignee_accessible'"); -} +=item 13 -# Add fulltext indexes for bug summaries and descriptions/comments. -if (!$dbh->bz_index_info('bugs', 'bugs_short_desc_idx')) { - print "Adding full-text index for short_desc column in bugs table...\n"; - $dbh->bz_add_index('bugs', 'bugs_short_desc_idx', - {TYPE => 'FULLTEXT', FIELDS => [qw(short_desc)]}); -} -# Right now, we only create the "thetext" index on MySQL. -if ($dbh->isa('Bugzilla::DB::Mysql') - && !$dbh->bz_index_info('longdescs', 'longdescs_thetext_idx')) -{ - print "Adding full-text index for thetext column in longdescs table...\n"; - $dbh->bz_add_index('longdescs', 'longdescs_thetext_idx', - {TYPE => 'FULLTEXT', FIELDS => [qw(thetext)]}); -} +This is the major part of checksetup--updating the table definitions +from one version of Bugzilla to another. -# 2002 November, myk@mozilla.org, bug 178841: -# -# Convert the "attachments.filename" column from a ridiculously large -# "mediumtext" to a much more sensible "varchar(100)". Also takes -# the opportunity to remove paths from existing filenames, since they -# shouldn't be there for security. Buggy browsers include them, -# and attachment.cgi now takes them out, but old ones need converting. -# -{ - my $ref = $dbh->bz_column_info("attachments", "filename"); - if ($ref->{TYPE} ne 'varchar(100)') { - print "Removing paths from filenames in attachments table...\n"; - - $sth = $dbh->prepare("SELECT attach_id, filename FROM attachments " . - "WHERE " . $dbh->sql_position(q{'/'}, 'filename') . " > 0 OR " . - $dbh->sql_position(q{'\\\\'}, 'filename') . " > 0"); - $sth->execute; - - while (my ($attach_id, $filename) = $sth->fetchrow_array) { - $filename =~ s/^.*[\/\\]//; - my $quoted_filename = $dbh->quote($filename); - $dbh->do("UPDATE attachments SET filename = $quoted_filename " . - "WHERE attach_id = $attach_id"); - } - - print "Done.\n"; - - print "Resizing attachments.filename from mediumtext to varchar(100).\n"; - $dbh->bz_alter_column("attachments", "filename", - {TYPE => 'varchar(100)', NOTNULL => 1}); - } -} +The code for this is in L<Bugzilla::Install::DB/update_table_definitions>. -# 2003-01-11, burnus@net-b.de, bug 184309 -# Support for quips approval -$dbh->bz_add_column('quips', 'approved', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'}); - -# 2002-12-20 Bug 180870 - remove manual shadowdb replication code -$dbh->bz_drop_table("shadowlog"); +=item 14 -# 2003-04-27 - bugzilla@chimpychompy.org (GavinS) -# -# Bug 180086 (http://bugzilla.mozilla.org/show_bug.cgi?id=180086) -# -# Renaming the 'count' column in the votes table because Sybase doesn't -# like it -if ($dbh->bz_column_info('votes', 'count')) { - # 2003-04-24 - myk@mozilla.org/bbaetz@acm.org, bug 201018 - # Force all cached groups to be updated at login, due to security bug - # Do this here, inside the next schema change block, so that it doesn't - # get invalidated on every checksetup run. - $dbh->do("UPDATE profiles SET refreshed_when='1900-01-01 00:00:00'"); - - $dbh->bz_rename_column('votes', 'count', 'vote_count'); -} +Creates the system groups--the ones like C<editbugs>, C<admin>, and so on. +This is L<Bugzilla::Install/update_system_groups>. -# 2004/02/15 - Summaries shouldn't be null - see bug 220232 -$dbh->bz_alter_column('bugs', 'short_desc', - {TYPE => 'MEDIUMTEXT', NOTNULL => 1}, ''); - -# 2003-10-24 - alt@sonic.net, bug 224208 -# Support classification level -$dbh->bz_add_column('products', 'classification_id', - {TYPE => 'INT2', NOTNULL => 1, DEFAULT => '1'}); - -# 2005-01-12 Nick Barnes <nb@ravenbrook.com> bug 278010 -# Rename any group which has an empty name. -# Note that there can be at most one such group (because of -# the SQL index on the name column). -$sth = $dbh->prepare("SELECT id FROM groups where name = ''"); -$sth->execute(); -my ($emptygroupid) = $sth->fetchrow_array(); -if ($emptygroupid) { - # There is a group with an empty name; find a name to rename it - # as. Must avoid collisions with existing names. Start with - # group_$gid and add _<n> if necessary. - my $trycount = 0; - my $trygroupname; - my $trygroupsth = $dbh->prepare("SELECT id FROM groups where name = ?"); - do { - $trygroupname = "group_$emptygroupid"; - if ($trycount > 0) { - $trygroupname .= "_$trycount"; - } - $trygroupsth->execute($trygroupname); - if ($trygroupsth->rows > 0) { - $trycount ++; - } - } while ($trygroupsth->rows > 0); - $sth = $dbh->prepare("UPDATE groups SET name = ? " . - "WHERE id = $emptygroupid"); - $sth->execute($trygroupname); - print "Group $emptygroupid had an empty name; renamed as '$trygroupname'.\n"; -} +=item 15 -# 2005-02-12 bugreport@peshkin.net, bug 281787 -$dbh->bz_add_index('bugs_activity', 'bugs_activity_who_idx', [qw(who)]); - -# This lastdiffed change and these default changes are unrelated, -# but in order for MySQL to successfully run these default changes only once, -# they have to be inside this block. -# If bugs.lastdiffed is NOT NULL... -if($dbh->bz_column_info('bugs', 'lastdiffed')->{NOTNULL}) { - # Add defaults for some fields that should have them but didn't. - $dbh->bz_alter_column('bugs', 'status_whiteboard', - {TYPE => 'MEDIUMTEXT', NOTNULL => 1, DEFAULT => "''"}); - $dbh->bz_alter_column('bugs', 'keywords', - {TYPE => 'MEDIUMTEXT', NOTNULL => 1, DEFAULT => "''"}); - $dbh->bz_alter_column('bugs', 'votes', - {TYPE => 'INT3', NOTNULL => 1, DEFAULT => '0'}); - # And change lastdiffed to NULL - $dbh->bz_alter_column('bugs', 'lastdiffed', {TYPE => 'DATETIME'}); -} +Creates all of the user-adjustable preferences that appear on the +"General Preferences" screen. This is L<Bugzilla::Install/update_settings>. -# 2005-03-09 qa_contact should be NULL instead of 0, bug 285534 -if ($dbh->bz_column_info('bugs', 'qa_contact')->{NOTNULL}) { - $dbh->bz_alter_column('bugs', 'qa_contact', {TYPE => 'INT3'}); - $dbh->do("UPDATE bugs SET qa_contact = NULL WHERE qa_contact = 0"); -} +=item 16 -# 2005-03-27 initialqacontact should be NULL instead of 0, bug 287483 -if ($dbh->bz_column_info('components', 'initialqacontact')->{NOTNULL}) { - $dbh->bz_alter_column('components', 'initialqacontact', {TYPE => 'INT3'}); - $dbh->do("UPDATE components SET initialqacontact = NULL " . - "WHERE initialqacontact = 0"); -} +Creates an administrator, if one doesn't already exist, using +L<Bugzilla::Install/create_admin>. -# 2005-03-29 - gerv@gerv.net - bug 73665. -# Migrate email preferences to new email prefs table. -if ($dbh->bz_column_info("profiles", "emailflags")) { - print "Migrating email preferences to new table ...\n" unless $silent; - - # These are the "roles" and "reasons" from the original code, mapped to - # the new terminology of relationships and events. - my %relationships = ("Owner" => REL_ASSIGNEE, - "Reporter" => REL_REPORTER, - "QAcontact" => REL_QA, - "CClist" => REL_CC, - "Voter" => REL_VOTER); - - my %events = ("Removeme" => EVT_ADDED_REMOVED, - "Comments" => EVT_COMMENT, - "Attachments" => EVT_ATTACHMENT, - "Status" => EVT_PROJ_MANAGEMENT, - "Resolved" => EVT_OPENED_CLOSED, - "Keywords" => EVT_KEYWORD, - "CC" => EVT_CC, - "Other" => EVT_OTHER, - "Unconfirmed" => EVT_UNCONFIRMED); - - # Request preferences - my %requestprefs = ("FlagRequestee" => EVT_FLAG_REQUESTED, - "FlagRequester" => EVT_REQUESTED_FLAG); - - # Select all emailflags flag strings - my $sth = $dbh->prepare("SELECT userid, emailflags FROM profiles"); - $sth->execute(); - - while (my ($userid, $flagstring) = $sth->fetchrow_array()) { - # If the user has never logged in since emailprefs arrived, and the - # temporary code to give them a default string never ran, then - # $flagstring will be null. In this case, they just get all mail. - $flagstring ||= ""; - - # The 255 param is here, because without a third param, split will - # trim any trailing null fields, which causes Perl to eject lots of - # warnings. Any suitably large number would do. - my %emailflags = split(/~/, $flagstring, 255); # Appease my editor: / - - my $sth2 = $dbh->prepare("INSERT into email_setting " . - "(user_id, relationship, event) VALUES (" . - "$userid, ?, ?)"); - foreach my $relationship (keys %relationships) { - foreach my $event (keys %events) { - my $key = "email$relationship$event"; - if (!exists($emailflags{$key}) || $emailflags{$key} eq 'on') { - $sth2->execute($relationships{$relationship}, - $events{$event}); - } - } - } - - # Note that in the old system, the value of "excludeself" is assumed to - # be off if the preference does not exist in the user's list, unlike - # other preferences whose value is assumed to be on if they do not - # exist. - # - # This preference has changed from global to per-relationship. - if (!exists($emailflags{'ExcludeSelf'}) - || $emailflags{'ExcludeSelf'} ne 'on') - { - foreach my $relationship (keys %relationships) { - $dbh->do("INSERT into email_setting " . - "(user_id, relationship, event) VALUES (" . - $userid . ", " . - $relationships{$relationship}. ", " . - EVT_CHANGED_BY_ME . ")"); - } - } - - foreach my $key (keys %requestprefs) { - if (!exists($emailflags{$key}) || $emailflags{$key} eq 'on') { - $dbh->do("INSERT into email_setting " . - "(user_id, relationship, event) VALUES (" . - $userid . ", " . REL_ANY . ", " . - $requestprefs{$key} . ")"); - } - } - } - - # EVT_ATTACHMENT_DATA should initially have identical settings to - # EVT_ATTACHMENT. - CloneEmailEvent(EVT_ATTACHMENT, EVT_ATTACHMENT_DATA); - - $dbh->bz_drop_column("profiles", "emailflags"); -} +We also can make somebody an admin at this step, if the user specified +the C<--make-admin> switch. -# Check for any "new" email settings that wouldn't have been ported over -# during the block above. Since these settings would have otherwise -# fallen under EVT_OTHER, we'll just clone those settings. That way if -# folks have already disabled all of that mail, there won't be any change. -{ - my %events = ("Dependency Tree Changes" => EVT_DEPEND_BLOCK); - - foreach my $desc (keys %events) { - my $event = $events{$desc}; - $sth = $dbh->prepare("SELECT count(*) FROM email_setting WHERE event = $event"); - $sth->execute(); - if (!($sth->fetchrow_arrayref()->[0])) { - # No settings in the table yet, so we assume that this is the - # first time it's being set. - print "Initializing \"$desc\" email_setting ...\n" unless $silent; - CloneEmailEvent(EVT_OTHER, $event); - } - } -} +=item 17 -sub CloneEmailEvent { - my ($source, $target) = @_; - - my $sth1 = $dbh->prepare("SELECT user_id, relationship FROM email_setting - WHERE event = $source"); - my $sth2 = $dbh->prepare("INSERT into email_setting " . - "(user_id, relationship, event) VALUES (" . - "?, ?, $target)"); - - $sth1->execute(); - - while (my ($userid, $relationship) = $sth1->fetchrow_array()) { - $sth2->execute($userid, $relationship); - } -} - -# 2005-03-27: Standardize all boolean fields to plain "tinyint" -if ( $dbh->isa('Bugzilla::DB::Mysql') ) { - # This is a change to make things consistent with Schema, so we use - # direct-database access methods. - my $quip_info_sth = $dbh->column_info(undef, undef, 'quips', '%'); - my $quips_cols = $quip_info_sth->fetchall_hashref("COLUMN_NAME"); - my $approved_col = $quips_cols->{'approved'}; - if ( $approved_col->{TYPE_NAME} eq 'TINYINT' - and $approved_col->{COLUMN_SIZE} == 1 ) - { - # series.public could have been renamed to series.is_public, - # and so wouldn't need to be fixed manually. - if ($dbh->bz_column_info('series', 'public')) { - $dbh->bz_alter_column_raw('series', 'public', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '0'}); - } - $dbh->bz_alter_column_raw('bug_status', 'isactive', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'}); - $dbh->bz_alter_column_raw('rep_platform', 'isactive', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'}); - $dbh->bz_alter_column_raw('resolution', 'isactive', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'}); - $dbh->bz_alter_column_raw('op_sys', 'isactive', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'}); - $dbh->bz_alter_column_raw('bug_severity', 'isactive', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'}); - $dbh->bz_alter_column_raw('priority', 'isactive', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'}); - $dbh->bz_alter_column_raw('quips', 'approved', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => '1'}); - } -} +Creates the default Classification, Product, and Component, using +L<Bugzilla::Install/create_default_product>. -# 2005-04-07 - alt@sonic.net, bug 289455 -# make classification_id field type be consistent with DB:Schema -$dbh->bz_alter_column('products', 'classification_id', - {TYPE => 'INT2', NOTNULL => 1, DEFAULT => '1'}); - -# initialowner was accidentally NULL when we checked-in Schema, -# when it really should be NOT NULL. -$dbh->bz_alter_column('components', 'initialowner', - {TYPE => 'INT3', NOTNULL => 1}, 0); - -# 2005-03-28 - bug 238800 - index flags.type_id to make editflagtypes.cgi speedy -$dbh->bz_add_index('flags', 'flags_type_id_idx', [qw(type_id)]); - -# For a short time, the flags_type_id_idx was misnamed in upgraded installs. -$dbh->bz_drop_index('flags', 'type_id'); - -# 2005-04-28 - LpSolit@gmail.com - Bug 7233: add an index to versions -$dbh->bz_alter_column('versions', 'value', - {TYPE => 'varchar(64)', NOTNULL => 1}); - -# A helper for the below code -sub _de_dup_version { - my ($product_id, $version) = @_; - my $dbh = Bugzilla->dbh; - print "Fixing duplicate version $version in product_id $product_id...\n"; - $dbh->do('DELETE FROM versions WHERE product_id = ? AND value = ?', - undef, $product_id, $version); - $dbh->do('INSERT INTO versions (product_id, value) VALUES (?,?)', - undef, $product_id, $version); -} +=back -# Versions could be duplicated, since they didn't have a UNIQUE index. -if (!$dbh->bz_index_info('versions', 'versions_product_id_idx')) { - my $dup_versions = $dbh->selectall_arrayref( - 'SELECT product_id, value FROM versions - GROUP BY product_id, value HAVING COUNT(value) > 1', {Slice=>{}}); - foreach my $dup_version (@$dup_versions) { - _de_dup_version($dup_version->{product_id}, $dup_version->{value}); - } - - $dbh->bz_add_index('versions', 'versions_product_id_idx', - {TYPE => 'UNIQUE', FIELDS => [qw(product_id value)]}); -} +=head2 Modifying the Database -# Milestone sortkeys get a default just like all other sortkeys. -if (!exists $dbh->bz_column_info('milestones', 'sortkey')->{DEFAULT}) { - $dbh->bz_alter_column('milestones', 'sortkey', - {TYPE => 'INT2', NOTNULL => 1, DEFAULT => 0}); -} +Sometimes you'll want to modify the database. In fact, that's mostly +what checksetup does, is upgrade old Bugzilla databases to the modern +format. -# 2005-06-14 - LpSolit@gmail.com - Bug 292544: only set creation_ts -# when all bug fields have been correctly set. -$dbh->bz_alter_column('bugs', 'creation_ts', {TYPE => 'DATETIME'}); - -if (!exists $dbh->bz_column_info('whine_queries', 'title')->{DEFAULT}) { - - # The below change actually has nothing to do with the whine_queries - # change, it just has to be contained within a schema change so that - # it doesn't run every time we run checksetup. - - # Old Bugzillas have "other" as an OS choice, new ones have "Other" - # (capital O). - # XXX - This should be moved inside of a later schema change, once - # we have one to move it to the inside of. - print "Setting any 'other' op_sys to 'Other'...\n"; - $dbh->do('UPDATE op_sys SET value = ? WHERE value = ?', - undef, "Other", "other"); - $dbh->do('UPDATE bugs SET op_sys = ? WHERE op_sys = ?', - undef, "Other", "other"); - if (Param('defaultopsys') eq 'other') { - # We can't actually fix the param here, because WriteParams() will - # make $datadir/params unwriteable to the webservergroup. - # It's too much of an ugly hack to copy the permission-fixing code - # down to here. (It would create more potential future bugs than - # it would solve problems.) - print "WARNING: Your 'defaultopsys' param is set to 'other', but" - . " Bugzilla now\n" - . " uses 'Other' (capital O).\n"; - } - - # Add a DEFAULT to whine_queries stuff so that editwhines.cgi - # works on PostgreSQL. - $dbh->bz_alter_column('whine_queries', 'title', {TYPE => 'varchar(128)', - NOTNULL => 1, DEFAULT => "''"}); -} +If you'd like to know how to make changes to the datbase, see +the information in the Bugzilla Developer's Guide, at: +L<http://www.bugzilla.org/docs/developer.html#sql-schema> -# 2005-06-29 bugreport@peshkin.net, bug 299156 -if ($dbh->bz_index_info('attachments', 'attachments_submitter_id_idx') - && (scalar(@{$dbh->bz_index_info('attachments', - 'attachments_submitter_id_idx' - )->{FIELDS}}) < 2) - ) { - $dbh->bz_drop_index('attachments', 'attachments_submitter_id_idx'); -} -$dbh->bz_add_index('attachments', 'attachments_submitter_id_idx', - [qw(submitter_id bug_id)]); - -# 2005-08-25 - bugreport@peshkin.net - Bug 305333 -if ($dbh->bz_column_info("attachments", "thedata")) { - print "Migrating attachment data to its own table...\n"; - print "(This may take a very long time)\n"; - $dbh->do("INSERT INTO attach_data (id, thedata) - SELECT attach_id, thedata FROM attachments"); - $dbh->bz_drop_column("attachments", "thedata"); -} +Also see L<Bugzilla::DB/"Schema Modification Methods"> and +L<Bugzilla::DB/"Schema Information Methods">. -# 2005-11-26 - wurblzap@gmail.com - Bug 300473 -# Repair broken automatically generated series queries for non-open bugs. -my $broken_series_indicator = - 'field0-0-0=resolution&type0-0-0=notequals&value0-0-0=---'; -my $broken_nonopen_series = - $dbh->selectall_arrayref("SELECT series_id, query FROM series - WHERE query LIKE '$broken_series_indicator%'"); -if (@$broken_nonopen_series) { - print 'Repairing broken series...'; - my $sth_nuke = - $dbh->prepare('DELETE FROM series_data WHERE series_id = ?'); - # This statement is used to repair a series by replacing the broken query - # with the correct one. - my $sth_repair = - $dbh->prepare('UPDATE series SET query = ? WHERE series_id = ?'); - # The corresponding series for open bugs look like one of these two - # variations (bug 225687 changed the order of bug states). - # This depends on the set of bug states representing open bugs not to have - # changed since series creation. - my $open_bugs_query_base_old = - join("&", map { "bug_status=" . url_quote($_) } - ('UNCONFIRMED', 'NEW', 'ASSIGNED', 'REOPENED')); - my $open_bugs_query_base_new = - join("&", map { "bug_status=" . url_quote($_) } OpenStates()); - my $sth_openbugs_series = - $dbh->prepare("SELECT series_id FROM series - WHERE query IN (?, ?)"); - # Statement to find the series which has collected the most data. - my $sth_data_collected = - $dbh->prepare('SELECT count(*) FROM series_data WHERE series_id = ?'); - # Statement to select a broken non-open bugs count data entry. - my $sth_select_broken_nonopen_data = - $dbh->prepare('SELECT series_date, series_value FROM series_data' . - ' WHERE series_id = ?'); - # Statement to select an open bugs count data entry. - my $sth_select_open_data = - $dbh->prepare('SELECT series_value FROM series_data' . - ' WHERE series_id = ? AND series_date = ?'); - # Statement to fix a broken non-open bugs count data entry. - my $sth_fix_broken_nonopen_data = - $dbh->prepare('UPDATE series_data SET series_value = ?' . - ' WHERE series_id = ? AND series_date = ?'); - # Statement to delete an unfixable broken non-open bugs count data entry. - my $sth_delete_broken_nonopen_data = - $dbh->prepare('DELETE FROM series_data' . - ' WHERE series_id = ? AND series_date = ?'); - - foreach (@$broken_nonopen_series) { - my ($broken_series_id, $nonopen_bugs_query) = @$_; - - # Determine the product-and-component part of the query. - if ($nonopen_bugs_query =~ /^$broken_series_indicator(.*)$/) { - my $prodcomp = $1; - - # If there is more than one series for the corresponding open-bugs - # series, we pick the one with the most data, which should be the - # one which was generated on creation. - # It's a pity we can't do subselects. - $sth_openbugs_series->execute($open_bugs_query_base_old . $prodcomp, - $open_bugs_query_base_new . $prodcomp); - my ($found_open_series_id, $datacount) = (undef, -1); - foreach my $open_series_id ($sth_openbugs_series->fetchrow_array()) { - $sth_data_collected->execute($open_series_id); - my ($this_datacount) = $sth_data_collected->fetchrow_array(); - if ($this_datacount > $datacount) { - $datacount = $this_datacount; - $found_open_series_id = $open_series_id; - } - } - - if ($found_open_series_id) { - # Move along corrupted series data and correct it. The - # corruption consists of it being the number of all bugs - # instead of the number of non-open bugs, so we calculate the - # correct count by subtracting the number of open bugs. - # If there is no corresponding open-bugs count for some reason - # (shouldn't happen), we drop the data entry. - print " $broken_series_id..."; - $sth_select_broken_nonopen_data->execute($broken_series_id); - while (my $rowref = - $sth_select_broken_nonopen_data->fetchrow_arrayref()) { - my ($date, $broken_value) = @$rowref; - my ($openbugs_value) = - $dbh->selectrow_array($sth_select_open_data, undef, - $found_open_series_id, $date); - if (defined($openbugs_value)) { - $sth_fix_broken_nonopen_data->execute - ($broken_value - $openbugs_value, - $broken_series_id, $date); - } - else { - print "\nWARNING - During repairs of series " . - "$broken_series_id, the irreparable data\n" . - "entry for date $date was encountered and is " . - "being deleted.\n" . - "Continuing repairs..."; - $sth_delete_broken_nonopen_data->execute - ($broken_series_id, $date); - } - } - - # Fix the broken query so that it collects correct data in the - # future. - $nonopen_bugs_query =~ - s/^$broken_series_indicator/field0-0-0=resolution&type0-0-0=regexp&value0-0-0=./; - $sth_repair->execute($nonopen_bugs_query, $broken_series_id); - } - else { - print "\nWARNING - Series $broken_series_id was meant to\n" . - "collect non-open bug counts, but it has counted\n" . - "all bugs instead. It cannot be repaired\n" . - "automatically because no series that collected open\n" . - "bug counts was found. You'll probably want to delete\n" . - "or repair collected data for series $broken_series_id " . - "manually.\n" . - "Continuing repairs..."; - } - } - } - print " done.\n"; -} +=head1 RUNNING CHECKSETUP NON-INTERACTIVELY -# 2005-09-15 lance.larsh@oracle.com Bug 308717 -if ($dbh->bz_column_info("series", "public")) { - # PUBLIC is a reserved word in Oracle, so renaming the column - # PUBLIC in table SERIES avoids having to quote the column name - # in every query against that table - $dbh->bz_rename_column('series', 'public', 'is_public'); -} +To operate checksetup non-interactively, run it with a single argument +specifying a filename that contains the information usually obtained by +prompting the user or by editing localconfig. -# 2005-09-28 bugreport@peshkin.net Bug 149504 -$dbh->bz_add_column('attachments', 'isurl', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 0}); - -# 2005-10-21 LpSolit@gmail.com - Bug 313020 -$dbh->bz_add_column('namedqueries', 'query_type', - {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 0}); - -# 2005-11-04 LpSolit@gmail.com - Bug 305927 -$dbh->bz_alter_column('groups', 'userregexp', - {TYPE => 'TINYTEXT', NOTNULL => 1, DEFAULT => "''"}); - -# 2005-09-26 - olav@bkor.dhs.org - Bug 119524 -# Convert logincookies into a varchar -# this allows to store a random token instead of a guessable auto_increment -$dbh->bz_alter_column('logincookies', 'cookie', - {TYPE => 'varchar(16)', PRIMARYKEY => 1, NOTNULL => 1}); - -# Fixup for Bug 101380 -# "Newlines, nulls, leading/trailing spaces are getting into summaries" - -my $controlchar_bugs = - $dbh->selectall_arrayref("SELECT short_desc, bug_id FROM bugs WHERE " . - $dbh->sql_regexp('short_desc', "'[[:cntrl:]]'")); -if (scalar(@$controlchar_bugs)) -{ - my $msg = 'Cleaning control characters from bug summaries...'; - my $found = 0; - foreach (@$controlchar_bugs) { - my ($short_desc, $bug_id) = @$_; - my $clean_short_desc = clean_text($short_desc); - if ($clean_short_desc ne $short_desc) { - print $msg if !$found; - $found = 1; - print " $bug_id..."; - $dbh->do("UPDATE bugs SET short_desc = ? WHERE bug_id = ?", - undef, $clean_short_desc, $bug_id); - } - } - print " done.\n" if $found; -} +The format of that file is as follows: -# If you had to change the --TABLE-- definition in any way, then add your -# differential change code *** A B O V E *** this comment. -# -# That is: if you add a new field, you first search for the first occurrence -# of --TABLE-- and add your field to into the table hash. This new setting -# would be honored for every new installation. Then add your -# bz_add_field/bz_drop_field/bz_change_field_type/bz_rename_field code above. -# This would then be honored by everyone who updates his Bugzilla installation. -# + $answer{'db_host'} = 'localhost'; + $answer{'db_driver'} = 'mydbdriver'; + $answer{'db_port'} = 0; + $answer{'db_name'} = 'mydbname'; + $answer{'db_user'} = 'mydbuser'; + $answer{'db_pass'} = 'mydbpass'; -# -# Bugzilla uses --GROUPS-- to assign various rights to its users. -# + $answer{'urlbase'} = 'http://bugzilla.mydomain.com/'; -AddGroup('tweakparams', 'Can tweak operating parameters'); -AddGroup('editusers', 'Can edit or disable users'); -AddGroup('creategroups', 'Can create and destroy groups.'); -AddGroup('editclassifications', 'Can create, destroy, and edit classifications.'); -AddGroup('editcomponents', 'Can create, destroy, and edit components.'); -AddGroup('editkeywords', 'Can create, destroy, and edit keywords.'); -AddGroup('admin', 'Administrators'); - -if (!GroupDoesExist("editbugs")) { - my $id = AddGroup('editbugs', 'Can edit all bug fields.', ".*"); - my $sth = $dbh->prepare("SELECT userid FROM profiles"); - $sth->execute(); - while (my ($userid) = $sth->fetchrow_array()) { - $dbh->do("INSERT INTO user_group_map - (user_id, group_id, isbless, grant_type) - VALUES ($userid, $id, 0, " . GRANT_DIRECT . ")"); - } -} + (Any localconfig variable or parameter can be specified as above.) -if (!GroupDoesExist("canconfirm")) { - my $id = AddGroup('canconfirm', 'Can confirm a bug.', ".*"); - my $sth = $dbh->prepare("SELECT userid FROM profiles"); - $sth->execute(); - while (my ($userid) = $sth->fetchrow_array()) { - $dbh->do("INSERT INTO user_group_map - (user_id, group_id, isbless, grant_type) - VALUES ($userid, $id, 0, " . GRANT_DIRECT . ")"); - } + $answer{'ADMIN_EMAIL'} = 'myadmin@mydomain.net'; + $answer{'ADMIN_PASSWORD'} = 'fooey'; + $answer{'ADMIN_REALNAME'} = 'Joel Peshkin'; -} + $answer{'SMTP_SERVER'} = 'mail.mydomain.net'; -# Create bz_canusewhineatothers and bz_canusewhines -if (!GroupDoesExist('bz_canusewhines')) { - my $whine_group = AddGroup('bz_canusewhines', - 'User can configure whine reports for self'); - my $whineatothers_group = AddGroup('bz_canusewhineatothers', - 'Can configure whine reports for ' . - 'other users'); - my $group_exists = $dbh->selectrow_array( - q{SELECT 1 FROM group_group_map - WHERE member_id = ? AND grantor_id = ? AND grant_type = ?}, - undef, $whineatothers_group, $whine_group, GROUP_MEMBERSHIP); - $dbh->do("INSERT INTO group_group_map " . - "(member_id, grantor_id, grant_type) " . - "VALUES (${whineatothers_group}, ${whine_group}, " . - GROUP_MEMBERSHIP . ")") unless $group_exists; -} + $answer{'NO_PAUSE'} = 1 -# 2005-08-14 bugreport@peshkin.net -- Bug 304583 -use constant GRANT_DERIVED => 1; -# Get rid of leftover DERIVED group permissions -$dbh->do("DELETE FROM user_group_map WHERE grant_type = " . GRANT_DERIVED); -# Evaluate regexp-based group memberships -$sth = $dbh->prepare("SELECT profiles.userid, profiles.login_name, - groups.id, groups.userregexp, - user_group_map.group_id - FROM (profiles - CROSS JOIN groups) - LEFT JOIN user_group_map - ON user_group_map.user_id = profiles.userid - AND user_group_map.group_id = groups.id - AND user_group_map.grant_type = ? - WHERE (userregexp != '' - OR user_group_map.group_id IS NOT NULL)"); - -my $sth_add = $dbh->prepare("INSERT INTO user_group_map - (user_id, group_id, isbless, grant_type) - VALUES(?, ?, 0, " . GRANT_REGEXP . ")"); - -my $sth_del = $dbh->prepare("DELETE FROM user_group_map - WHERE user_id = ? - AND group_id = ? - AND isbless = 0 - AND grant_type = " . GRANT_REGEXP); - -$sth->execute(GRANT_REGEXP); -while (my ($uid, $login, $gid, $rexp, $present) = $sth->fetchrow_array()) { - if ($login =~ m/$rexp/i) { - $sth_add->execute($uid, $gid) unless $present; - } else { - $sth_del->execute($uid, $gid) if $present; - } -} +C<NO_PAUSE> means "never stop and prompt the user to hit Enter to continue, +just go ahead and do things, even if they are potentially dangerous." +Don't set this to 1 unless you know what you are doing. -# 2005-10-10 karl@kornel.name -- Bug 204498 -if (!GroupDoesExist('bz_sudoers')) { - my $sudoers_group = AddGroup('bz_sudoers', - 'Can perform actions as other users'); - my $sudo_protect_group = AddGroup('bz_sudo_protect', - 'Can not be impersonated by other users'); - my ($admin_group) = $dbh->selectrow_array('SELECT id FROM groups - WHERE name = ?', undef, 'admin'); - - # Admins should be given sudo access - # Everyone in sudo should be in sudo_protect - # Admins can grant membership in both groups - my $sth = $dbh->prepare('INSERT INTO group_group_map - (member_id, grantor_id, grant_type) - VALUES (?, ?, ?)'); - $sth->execute($admin_group, $sudoers_group, GROUP_MEMBERSHIP); - $sth->execute($sudoers_group, $sudo_protect_group, GROUP_MEMBERSHIP); - $sth->execute($admin_group, $sudoers_group, GROUP_BLESS); - $sth->execute($admin_group, $sudo_protect_group, GROUP_BLESS); -} +=head1 SEE ALSO -########################################################################### -# Create --SETTINGS-- users can adjust -########################################################################### +=over -# 2005-03-03 travis@sedsystems.ca -- Bug 41972 -add_setting ("display_quips", {"on" => 1, "off" => 2 }, "on" ); +=item * -# 2005-03-10 travis@sedsystems.ca -- Bug 199048 -add_setting ("comment_sort_order", {"oldest_to_newest" => 1, - "newest_to_oldest" => 2, - "newest_to_oldest_desc_first" => 3}, - "oldest_to_newest" ); +L<Bugzilla::Install::Requirements> -# 2005-05-12 bugzilla@glob.com.au -- Bug 63536 -add_setting ("post_bug_submit_action", {"next_bug" => 1, - "same_bug" => 2, - "nothing" => 3, - }, - "next_bug" ); +=item * -# 2005-06-29 wurblzap@gmail.com -- Bug 257767 -add_setting ('csv_colsepchar', {',' => 1, ';' => 2 }, ',' ); +L<Bugzilla::Install::Localconfig> -# 2005-10-21 LpSolit@gmail.com -- Bug 313020 -add_setting('per_bug_queries', {'on' => 1, 'off' => 2}, 'on'); +=item * -########################################################################### -# Create Administrator --ADMIN-- -########################################################################### +L<Bugzilla::Install::Filesystem> -sub bailout { # this is just in case we get interrupted while getting passwd - if ($^O !~ /MSWin32/i) { - system("stty","echo"); # re-enable input echoing - } - exit 1; -} +=item * -if (@admins) { - # Identify admin group. - my $sth = $dbh->prepare("SELECT id FROM groups - WHERE name = 'admin'"); - $sth->execute(); - my ($adminid) = $sth->fetchrow_array(); - foreach my $userid (@admins) { - $dbh->do("INSERT INTO user_group_map - (user_id, group_id, isbless, grant_type) - VALUES ($userid, $adminid, 0, " . GRANT_DIRECT . ")"); - # Existing administrators are made blessers of group "admin" - # but only explicitly defined blessers can bless group admin. - # Other groups can be blessed by any admin (by default) or additional - # defined blessers. - $dbh->do("INSERT INTO user_group_map - (user_id, group_id, isbless, grant_type) - VALUES ($userid, $adminid, 1, " . GRANT_DIRECT . ")"); - } - - $dbh->bz_lock_tables('groups READ', - 'group_group_map WRITE'); - $dbh->do('DELETE FROM group_group_map WHERE member_id = ?', - undef, $adminid); - $sth = $dbh->prepare("SELECT id FROM groups"); - $sth->execute(); - while ( my ($id) = $sth->fetchrow_array() ) { - # Admins can bless every group. - $dbh->do("INSERT INTO group_group_map - (member_id, grantor_id, grant_type) - VALUES ($adminid, $id," . GROUP_BLESS . ")"); - # Admins can see every group. - $dbh->do("INSERT INTO group_group_map - (member_id, grantor_id, grant_type) - VALUES ($adminid, $id," . GROUP_VISIBLE . ")"); - # Admins are initially members of every group. - next if ($id == $adminid); - $dbh->do("INSERT INTO group_group_map - (member_id, grantor_id, grant_type) - VALUES ($adminid, $id," . GROUP_MEMBERSHIP . ")"); - } - $dbh->bz_unlock_tables(); -} +L<Bugzilla::Install::DB> +=item * -my @groups = (); -$sth = $dbh->prepare("SELECT id FROM groups"); -$sth->execute(); -while ( my @row = $sth->fetchrow_array() ) { - push (@groups, $row[0]); -} +L<Bugzilla::Install> -# Prompt the user for the email address and name of an administrator. Create -# that login, if it doesn't exist already, and make it a member of all groups. - -$sth = $dbh->prepare("SELECT user_id FROM groups INNER JOIN user_group_map " . - "ON id = group_id WHERE name = 'admin'"); -$sth->execute; -# when we have no admin users, prompt for admin email address and password ... -if ($sth->rows == 0) { - my $login = ""; - my $realname = ""; - my $pass1 = ""; - my $pass2 = "*"; - my $admin_ok = 0; - my $admin_create = 1; - my $mailcheckexp = ""; - my $mailcheck = ""; - - # Here we look to see what the emailregexp is set to so we can - # check the email address they enter. Bug 96675. If they have no - # params (likely but not always the case), we use the default. - if (-e "$datadir/params") { - require "$datadir/params"; # if they have a params file, use that - } - if (Param('emailregexp')) { - $mailcheckexp = Param('emailregexp'); - $mailcheck = Param('emailregexpdesc'); - } else { - $mailcheckexp = '^[\\w\\.\\+\\-=]+@[\\w\\.\\-]+\\.[\\w\\-]+$'; - $mailcheck = 'A legal address must contain exactly one \'@\', - and at least one \'.\' after the @.'; - } - - print "\nLooks like we don't have an administrator set up yet.\n"; - print "Either this is your first time using Bugzilla, or your\n "; - print "administrator's privileges might have accidentally been deleted.\n"; - while(! $admin_ok ) { - while( $login eq "" ) { - print "Enter the e-mail address of the administrator: "; - $login = $answer{'ADMIN_EMAIL'} - || ($silent && die("cant preload ADMIN_EMAIL")) - || <STDIN>; - chomp $login; - if(! $login ) { - print "\nYou DO want an administrator, don't you?\n"; - } - unless ($login =~ /$mailcheckexp/) { - print "\nThe login address is invalid:\n"; - print "$mailcheck\n"; - print "You can change this test on the params page once checksetup has successfully\n"; - print "completed.\n\n"; - # Go round, and ask them again - $login = ""; - } - } - $sth = $dbh->prepare("SELECT login_name FROM profiles " . - "WHERE " . $dbh->sql_istrcmp('login_name', '?')); - $sth->execute($login); - if ($sth->rows > 0) { - print "$login already has an account.\n"; - print "Make this user the administrator? [Y/n] "; - my $ok = $answer{'ADMIN_OK'} - || ($silent && die("cant preload ADMIN_OK")) - || <STDIN>; - chomp $ok; - if ($ok !~ /^n/i) { - $admin_ok = 1; - $admin_create = 0; - } else { - print "OK, well, someone has to be the administrator.\n"; - print "Try someone else.\n"; - $login = ""; - } - } else { - print "You entered $login. Is this correct? [Y/n] "; - my $ok = $answer{'ADMIN_OK'} - || ($silent && die("cant preload ADMIN_OK")) - || <STDIN>; - chomp $ok; - if ($ok !~ /^n/i) { - $admin_ok = 1; - } else { - print "That's okay, typos happen. Give it another shot.\n"; - $login = ""; - } - } - } - - if ($admin_create) { - while( $realname eq "" ) { - print "Enter the real name of the administrator: "; - $realname = $answer{'ADMIN_REALNAME'} - || ($silent && die("cant preload ADMIN_REALNAME")) - || <STDIN>; - chomp $realname; - if(! $realname ) { - print "\nReally. We need a full name.\n"; - } - if(! is_7bit_clean($realname)) { - print "\nSorry, but at this stage the real name can only " . - "contain standard English\ncharacters. Once Bugzilla " . - "has been installed, you can use the 'Prefs' page\nto " . - "update the real name.\n"; - $realname = ''; - } - } - - # trap a few interrupts so we can fix the echo if we get aborted. - $SIG{HUP} = \&bailout; - $SIG{INT} = \&bailout; - $SIG{QUIT} = \&bailout; - $SIG{TERM} = \&bailout; - - if ($^O !~ /MSWin32/i) { - system("stty","-echo"); # disable input echoing - } - - while( $pass1 ne $pass2 ) { - while( $pass1 eq "" || $pass1 !~ /^[[:print:]]{3,16}$/ ) { - print "Enter a password for the administrator account: "; - $pass1 = $answer{'ADMIN_PASSWORD'} - || ($silent && die("cant preload ADMIN_PASSWORD")) - || <STDIN>; - chomp $pass1; - if(! $pass1 ) { - print "\n\nAn empty password is a security risk. Try again!\n"; - } elsif ( $pass1 !~ /^.{3,16}$/ ) { - print "\n\nThe password must be 3-16 characters in length.\n"; - } elsif ( $pass1 !~ /^[[:print:]]{3,16}$/ ) { - print "\n\nThe password contains non-printable characters.\n"; - } - } - print "\nPlease retype the password to verify: "; - $pass2 = $answer{'ADMIN_PASSWORD'} - || ($silent && die("cant preload ADMIN_PASSWORD")) - || <STDIN>; - chomp $pass2; - if ($pass1 ne $pass2) { - print "\n\nPasswords don't match. Try again!\n"; - $pass1 = ""; - $pass2 = "*"; - } - } - - if ($^O !~ /MSWin32/i) { - system("stty","echo"); # re-enable input echoing - } - - $SIG{HUP} = 'DEFAULT'; # and remove our interrupt hooks - $SIG{INT} = 'DEFAULT'; - $SIG{QUIT} = 'DEFAULT'; - $SIG{TERM} = 'DEFAULT'; - - insert_new_user($login, $realname, $pass1); - } - - # Put the admin in each group if not already - my $userid = $dbh->selectrow_array("SELECT userid FROM profiles WHERE " . - $dbh->sql_istrcmp('login_name', '?'), - undef, $login); - - # Admins get explicit membership and bless capability for the admin group - my ($admingroupid) = $dbh->selectrow_array("SELECT id FROM groups - WHERE name = 'admin'"); - $dbh->do("INSERT INTO user_group_map - (user_id, group_id, isbless, grant_type) - VALUES ($userid, $admingroupid, 0, " . GRANT_DIRECT . ")"); - $dbh->do("INSERT INTO user_group_map - (user_id, group_id, isbless, grant_type) - VALUES ($userid, $admingroupid, 1, " . GRANT_DIRECT . ")"); - - # Admins get inherited membership and bless capability for all groups - foreach my $group ( @groups ) { - my $sth_check = $dbh->prepare("SELECT member_id FROM group_group_map - WHERE member_id = ? - AND grantor_id = ? - AND grant_type = ?"); - $sth_check->execute($admingroupid, $group, GROUP_MEMBERSHIP); - unless ($sth_check->rows) { - $dbh->do("INSERT INTO group_group_map - (member_id, grantor_id, grant_type) - VALUES ($admingroupid, $group, " . GROUP_MEMBERSHIP . ")"); - } - $sth_check->execute($admingroupid, $group, GROUP_BLESS); - unless ($sth_check->rows) { - $dbh->do("INSERT INTO group_group_map - (member_id, grantor_id, grant_type) - VALUES ($admingroupid, $group, " . GROUP_BLESS . ")"); - } - } - - print "\n$login is now set up as an administrator account.\n"; -} +=item * +L<Bugzilla::Config/update_params> -# -# Final checks... - -$sth = $dbh->prepare("SELECT user_id " . - "FROM groups INNER JOIN user_group_map " . - "ON groups.id = user_group_map.group_id " . - "WHERE groups.name = 'admin'"); -$sth->execute; -my ($adminuid) = $sth->fetchrow_array; -if (!$adminuid) { die "No administrator!" } # should never get here -# when test product was created, admin was unknown -$dbh->do("UPDATE components " . - "SET initialowner = $adminuid " . - "WHERE initialowner = 0"); - -unlink "$datadir/versioncache"; +=item * -# Check if the default parameter for urlbase is still set, and if so, give -# notification that they should go and visit editparams.cgi +L<Bugzilla::DB/CONNECTION> -my @params = Bugzilla::Config::Core::get_param_list(); -my $urlbase_default = ''; -foreach my $item (@params) { - next unless $item->{'name'} eq 'urlbase'; - $urlbase_default = $item->{'default'}; - last; -} +=back -if (Param('urlbase') eq $urlbase_default) { - print "Now that you have installed Bugzilla, you should visit the \n" . - "'Parameters' page (linked in the footer of the Administrator \n" . - "account) to ensure it is set up as you wish - this includes \n" . - "setting the 'urlbase' option to the correct url.\n" unless $silent; -} -################################################################################ diff --git a/colchange.cgi b/colchange.cgi index 43bfd86ee..de834b8bc 100755 --- a/colchange.cgi +++ b/colchange.cgi @@ -20,24 +20,20 @@ # # Contributor(s): Terry Weissman <terry@mozilla.org> # Gervase Markham <gerv@gerv.net> +# Max Kanat-Alexander <mkanat@bugzilla.org> use strict; use lib qw(.); -use vars qw( - @legal_keywords -); - use Bugzilla; use Bugzilla::Constants; +use Bugzilla::Error; use Bugzilla::User; -require "globals.pl"; +use Bugzilla::Keyword; Bugzilla->login(); -GetVersionTable(); - my $cgi = Bugzilla->cgi; my $template = Bugzilla->template; my $vars = {}; @@ -49,39 +45,41 @@ my @masterlist = ("opendate", "changeddate", "bug_severity", "priority", "reporter", "reporter_realname", "bug_status", "resolution"); -if (Param("useclassification")) { +if (Bugzilla->params->{"useclassification"}) { push(@masterlist, "classification"); } push(@masterlist, ("product", "component", "version", "op_sys")); -if (Param("usevotes")) { +if (Bugzilla->params->{"usevotes"}) { push (@masterlist, "votes"); } -if (Param("usebugaliases")) { +if (Bugzilla->params->{"usebugaliases"}) { unshift(@masterlist, "alias"); } -if (Param("usetargetmilestone")) { +if (Bugzilla->params->{"usetargetmilestone"}) { push(@masterlist, "target_milestone"); } -if (Param("useqacontact")) { +if (Bugzilla->params->{"useqacontact"}) { push(@masterlist, "qa_contact"); push(@masterlist, "qa_contact_realname"); } -if (Param("usestatuswhiteboard")) { +if (Bugzilla->params->{"usestatuswhiteboard"}) { push(@masterlist, "status_whiteboard"); } -if (@::legal_keywords) { +if (Bugzilla::Keyword::keyword_count()) { push(@masterlist, "keywords"); } -if (UserInGroup(Param("timetrackinggroup"))) { +if (Bugzilla->user->in_group(Bugzilla->params->{"timetrackinggroup"})) { push(@masterlist, ("estimated_time", "remaining_time", "actual_time", "percentage_complete", "deadline")); } push(@masterlist, ("short_desc", "short_short_desc")); +push(@masterlist, Bugzilla->custom_field_names); + $vars->{'masterlist'} = \@masterlist; my @collist; @@ -100,7 +98,7 @@ if (defined $cgi->param('rememberedquery')) { } } my $list = join(" ", @collist); - my $urlbase = Param("urlbase"); + my $urlbase = Bugzilla->params->{"urlbase"}; if ($list) { $cgi->send_cookie(-name => 'COLUMNLIST', diff --git a/collectstats.pl b/collectstats.pl index 120df0130..7bc2b6174 100755 --- a/collectstats.pl +++ b/collectstats.pl @@ -23,6 +23,7 @@ # Gervase Markham <gerv@gerv.net> # Richard Walters <rwalters@qualcomm.com> # Jean-Sebastien Guay <jean_seb@hybride.com> +# Frédéric Buclin <LpSolit@gmail.com> # Run me out of cron at midnight to collect Bugzilla statistics. # @@ -32,18 +33,19 @@ use AnyDBM_File; use strict; use IO::Handle; -use vars @::legal_product; use lib "."; -require "globals.pl"; -use Bugzilla::Search; -use Bugzilla::User; use Bugzilla; -use Bugzilla::Config qw(:DEFAULT $datadir); +use Bugzilla::Constants; +use Bugzilla::Util; +use Bugzilla::Search; +use Bugzilla::User; +use Bugzilla::Product; +use Bugzilla::Field; # Turn off output buffering (probably needed when displaying output feedback -# in the regenerate mode.) +# in the regenerate mode). $| = 1; # Tidy up after graphing module @@ -53,9 +55,10 @@ if (chdir("graphs")) { chdir(".."); } -GetVersionTable(); +# This is a pure command line script. +Bugzilla->usage_mode(USAGE_MODE_CMDLINE); -Bugzilla->switch_to_shadow_db(); +my $dbh = Bugzilla->switch_to_shadow_db(); # To recreate the daily statistics, run "collectstats.pl --regenerate" . my $regenerate = 0; @@ -64,15 +67,50 @@ if ($#ARGV >= 0 && $ARGV[0] eq "--regenerate") { $regenerate = 1; } -my @myproducts; -push( @myproducts, "-All-", @::legal_product ); +my $datadir = bz_locations()->{'datadir'}; + +my @myproducts = map {$_->name} Bugzilla::Product->get_all; +unshift(@myproducts, "-All-"); + +# As we can now customize the list of resolutions, looking at the actual list +# of available resolutions only is not enough as some now removed resolutions +# may have existed in the past, or have been renamed. We want them all. +my @resolutions = @{get_legal_field_values('resolution')}; +my $old_resolutions = + $dbh->selectcol_arrayref('SELECT bugs_activity.added + FROM bugs_activity + INNER JOIN fielddefs + ON fielddefs.id = bugs_activity.fieldid + LEFT JOIN resolution + ON resolution.value = bugs_activity.added + WHERE fielddefs.name = ? + AND resolution.id IS NULL + + UNION + + SELECT bugs_activity.removed + FROM bugs_activity + INNER JOIN fielddefs + ON fielddefs.id = bugs_activity.fieldid + LEFT JOIN resolution + ON resolution.value = bugs_activity.removed + WHERE fielddefs.name = ? + AND resolution.id IS NULL', + undef, ('resolution', 'resolution')); + +push(@resolutions, @$old_resolutions); +# Exclude "" from the resolution list. +@resolutions = grep {$_} @resolutions; + +# Actually, the list of statuses is predefined. This will change in the near future. +my @statuses = qw(NEW ASSIGNED REOPENED UNCONFIRMED RESOLVED VERIFIED CLOSED); my $tstart = time; foreach (@myproducts) { my $dir = "$datadir/mining"; &check_data_dir ($dir); - + if ($regenerate) { ®enerate_stats($dir, $_); } else { @@ -126,9 +164,13 @@ sub collect_stats { my $dir = shift; my $product = shift; my $when = localtime (time); - my $product_id = get_product_id($product) unless $product eq '-All-'; + my $dbh = Bugzilla->dbh; - die "Unknown product $product" unless ($product_id or $product eq '-All-'); + my $product_id; + if ($product ne '-All-') { + my $prod = Bugzilla::Product::check_product($product); + $product_id = $prod->id; + } # NB: Need to mangle the product for the filename, but use the real # product name in the query @@ -137,47 +179,111 @@ sub collect_stats { my $file = join '/', $dir, $file_product; my $exists = -f $file; - if (open DATA, ">>$file") { - push my @row, &today; + # if the file exists, get the old status and resolution list for that product. + my @data; + @data = get_old_data($file) if $exists; - foreach my $status ('NEW', 'ASSIGNED', 'REOPENED', 'UNCONFIRMED', 'RESOLVED', 'VERIFIED', 'CLOSED') { - if( $product eq "-All-" ) { - SendSQL("SELECT COUNT(bug_status) FROM bugs WHERE bug_status='$status'"); - } else { - SendSQL("SELECT COUNT(bug_status) FROM bugs WHERE bug_status='$status' AND product_id=$product_id"); - } + # If @data is not empty, then we have to recreate the data file. + if (scalar(@data)) { + open(DATA, '>', $file) + || ThrowCodeError('chart_file_open_fail', {'filename' => $file}); + } + else { + open(DATA, '>>', $file) + || ThrowCodeError('chart_file_open_fail', {'filename' => $file}); + } - push @row, FetchOneColumn(); - } + # Now collect current data. + my @row = (today()); + my $status_sql = q{SELECT COUNT(*) FROM bugs WHERE bug_status = ?}; + my $reso_sql = q{SELECT COUNT(*) FROM bugs WHERE resolution = ?}; - foreach my $resolution ('FIXED', 'INVALID', 'WONTFIX', 'LATER', 'REMIND', 'DUPLICATE', 'WORKSFORME', 'MOVED') { - if( $product eq "-All-" ) { - SendSQL("SELECT COUNT(resolution) FROM bugs WHERE resolution='$resolution'"); - } else { - SendSQL("SELECT COUNT(resolution) FROM bugs WHERE resolution='$resolution' AND product_id=$product_id"); - } + if ($product ne '-All-') { + $status_sql .= q{ AND product_id = ?}; + $reso_sql .= q{ AND product_id = ?}; + } - push @row, FetchOneColumn(); - } + my $sth_status = $dbh->prepare($status_sql); + my $sth_reso = $dbh->prepare($reso_sql); + + my @values ; + foreach my $status (@statuses) { + @values = ($status); + push (@values, $product_id) if ($product ne '-All-'); + my $count = $dbh->selectrow_array($sth_status, undef, @values); + push(@row, $count); + } + foreach my $resolution (@resolutions) { + @values = ($resolution); + push (@values, $product_id) if ($product ne '-All-'); + my $count = $dbh->selectrow_array($sth_reso, undef, @values); + push(@row, $count); + } - if (! $exists) { - print DATA <<FIN; + if (!$exists || scalar(@data)) { + my $fields = join('|', ('DATE', @statuses, @resolutions)); + print DATA <<FIN; # Bugzilla Daily Bug Stats # # Do not edit me! This file is generated. # -# fields: DATE|NEW|ASSIGNED|REOPENED|UNCONFIRMED|RESOLVED|VERIFIED|CLOSED|FIXED|INVALID|WONTFIX|LATER|REMIND|DUPLICATE|WORKSFORME|MOVED +# fields: $fields # Product: $product # Created: $when FIN - } + } - print DATA (join '|', @row) . "\n"; - close DATA; - chmod 0644, $file; - } else { - print "$0: $file, $!"; + # Add existing data, if needed. Note that no count is not treated + # the same way as a count with 0 bug. + foreach my $data (@data) { + print DATA join('|', map {defined $data->{$_} ? $data->{$_} : ''} + ('DATE', @statuses, @resolutions)) . "\n"; + } + print DATA (join '|', @row) . "\n"; + close DATA; + chmod 0644, $file; +} + +sub get_old_data { + my $file = shift; + + open(DATA, '<', $file) + || ThrowCodeError('chart_file_open_fail', {'filename' => $file}); + + my @data; + my @columns; + my $recreate = 0; + while (<DATA>) { + chomp; + next unless $_; + if (/^# fields?:\s*(.+)\s*$/) { + @columns = split(/\|/, $1); + # Compare this list with @statuses and @resolutions. + # If they are identical, then we can safely append new data + # to the end of the file; else we have to recreate it. + $recreate = 1; + my @new_cols = ($columns[0], @statuses, @resolutions); + if (scalar(@columns) == scalar(@new_cols)) { + my $identical = 1; + for (0 .. $#columns) { + $identical = 0 if ($columns[$_] ne $new_cols[$_]); + } + last if $identical; + } + } + next unless $recreate; + next if (/^#/); # Ignore comments. + # If we have to recreate the file, we have to load all existing + # data first. + my @line = split /\|/; + my %data; + foreach my $column (@columns) { + $data{$column} = shift @line; + } + push(@data, \%data); } + close(DATA); + return @data; } sub calculate_dupes { @@ -194,6 +300,8 @@ sub calculate_dupes { # Save % count here in a date-named file # so we can read it back in to do changed counters # First, delete it if it exists, so we don't add to the contents of an old file + my $datadir = bz_locations()->{'datadir'}; + if (my @files = <$datadir/duplicates/dupes$today*>) { map { trick_taint($_) } @files; unlink @files; @@ -220,7 +328,7 @@ sub calculate_dupes { } $count{$dupe_of}++; - } + } # Now we collapse the dupe tree by iterating over %count until # there is no further change. @@ -272,37 +380,41 @@ sub regenerate_stats { my $and_product = ""; my $from_product = ""; - + + my @values = (); if ($product ne '-All-') { - $and_product = " AND products.name = " . SqlQuote($product); - $from_product = "INNER JOIN products " . - "ON bugs.product_id = products.id"; - } - + $and_product = q{ AND products.name = ?}; + $from_product = q{ INNER JOIN products + ON bugs.product_id = products.id}; + push (@values, $product); + } + # Determine the start date from the date the first bug in the # database was created, and the end date from the current day. # If there were no bugs in the search, return early. - SendSQL("SELECT " . $dbh->sql_to_days('creation_ts') . " AS start, " . - $dbh->sql_to_days('current_date') . " AS end, " . - $dbh->sql_to_days("'1970-01-01'") . - " FROM bugs $from_product WHERE " . - $dbh->sql_to_days('creation_ts') . " IS NOT NULL " . - $and_product . - " ORDER BY start " . $dbh->sql_limit(1)); - - my ($start, $end, $base) = FetchSQLData(); + my $query = q{SELECT } . + $dbh->sql_to_days('creation_ts') . q{ AS start, } . + $dbh->sql_to_days('current_date') . q{ AS end, } . + $dbh->sql_to_days("'1970-01-01'") . + qq{ FROM bugs $from_product + WHERE } . $dbh->sql_to_days('creation_ts') . + qq{ IS NOT NULL $and_product + ORDER BY start } . $dbh->sql_limit(1); + my ($start, $end, $base) = $dbh->selectrow_array($query, undef, @values); + if (!defined $start) { return; } - + if (open DATA, ">$file") { DATA->autoflush(1); + my $fields = join('|', ('DATE', @statuses, @resolutions)); print DATA <<FIN; # Bugzilla Daily Bug Stats # # Do not edit me! This file is generated. # -# fields: DATE|NEW|ASSIGNED|REOPENED|UNCONFIRMED|RESOLVED|VERIFIED|CLOSED|FIXED|INVALID|WONTFIX|LATER|REMIND|DUPLICATE|WORKSFORME|MOVED +# fields: $fields # Product: $product # Created: $when FIN @@ -315,16 +427,17 @@ FIN # Get a list of bugs that were created the previous day, and # add those bugs to the list of bugs for this product. - SendSQL("SELECT bug_id FROM bugs $from_product " . - " WHERE bugs.creation_ts < " . $dbh->sql_from_days($day - 1) . - " AND bugs.creation_ts >= " . $dbh->sql_from_days($day - 2) . - $and_product . - " ORDER BY bug_id"); - - my @row; - while (@row = FetchSQLData()) { - push @bugs, $row[0]; - } + $query = qq{SELECT bug_id + FROM bugs $from_product + WHERE bugs.creation_ts < } . + $dbh->sql_from_days($day - 1) . + q{ AND bugs.creation_ts >= } . + $dbh->sql_from_days($day - 2) . + $and_product . q{ ORDER BY bug_id}; + + my $bug_ids = $dbh->selectcol_arrayref($query, undef, @values); + + push(@bugs, @$bug_ids); # For each bug that existed on that day, determine its status # at the beginning of the day. If there were no status @@ -334,62 +447,47 @@ FIN # the bugs_activity table for that bug made on or after that # day. my %bugcount; - my @logstates = qw(NEW ASSIGNED REOPENED UNCONFIRMED RESOLVED - VERIFIED CLOSED); - my @logresolutions = qw(FIXED INVALID WONTFIX LATER REMIND - DUPLICATE WORKSFORME MOVED); - foreach (@logstates) { - $bugcount{$_} = 0; - } - - foreach (@logresolutions) { - $bugcount{$_} = 0; - } + foreach (@statuses) { $bugcount{$_} = 0; } + foreach (@resolutions) { $bugcount{$_} = 0; } + # Get information on bug states and resolutions. + $query = qq{SELECT bugs_activity.removed + FROM bugs_activity + INNER JOIN fielddefs + ON bugs_activity.fieldid = fielddefs.id + WHERE fielddefs.name = ? + AND bugs_activity.bug_id = ? + AND bugs_activity.bug_when >= } . + $dbh->sql_from_days($day) . + " ORDER BY bugs_activity.bug_when " . + $dbh->sql_limit(1); + + my $sth_bug = $dbh->prepare($query); + my $sth_status = $dbh->prepare(q{SELECT bug_status + FROM bugs + WHERE bug_id = ?}); + my $sth_reso = $dbh->prepare(q{SELECT resolution + FROM bugs + WHERE bug_id = ?}); + for my $bug (@bugs) { - # First, get information on various bug states. - SendSQL("SELECT bugs_activity.removed " . - " FROM bugs_activity " . - "INNER JOIN fielddefs " . - " ON bugs_activity.fieldid = fielddefs.fieldid " . - " WHERE fielddefs.name = 'bug_status' " . - " AND bugs_activity.bug_id = $bug " . - " AND bugs_activity.bug_when >= " . $dbh->sql_from_days($day) . - " ORDER BY bugs_activity.bug_when " . - $dbh->sql_limit(1)); - - my $status; - if (@row = FetchSQLData()) { - $status = $row[0]; - } else { - SendSQL("SELECT bug_status FROM bugs WHERE bug_id = $bug"); - $status = FetchOneColumn(); + my $status = $dbh->selectrow_array($sth_bug, undef, + 'bug_status', $bug); + unless ($status) { + $status = $dbh->selectrow_array($sth_status, undef, $bug); } - + if (defined $bugcount{$status}) { $bugcount{$status}++; } - - # Next, get information on various bug resolutions. - SendSQL("SELECT bugs_activity.removed " . - " FROM bugs_activity " . - "INNER JOIN fielddefs " . - " ON bugs_activity.fieldid = fielddefs.fieldid " . - " WHERE fielddefs.name = 'resolution' " . - " AND bugs_activity.bug_id = $bug " . - " AND bugs_activity.bug_when >= " . $dbh->sql_from_days($day) . - " ORDER BY bugs_activity.bug_when " . - $dbh->sql_limit(1)); - - if (@row = FetchSQLData()) { - $status = $row[0]; - } else { - SendSQL("SELECT resolution FROM bugs WHERE bug_id = $bug"); - $status = FetchOneColumn(); + my $resolution = $dbh->selectrow_array($sth_bug, undef, + 'resolution', $bug); + unless ($resolution) { + $resolution = $dbh->selectrow_array($sth_reso, undef, $bug); } - if (defined $bugcount{$status}) { - $bugcount{$status}++; + if (defined $bugcount{$resolution}) { + $bugcount{$resolution}++; } } @@ -397,14 +495,8 @@ FIN # of bugs in each state. my $date = sqlday($day, $base); print DATA "$date"; - foreach (@logstates) { - print DATA "|$bugcount{$_}"; - } - - foreach (@logresolutions) { - print DATA "|$bugcount{$_}"; - } - + foreach (@statuses) { print DATA "|$bugcount{$_}"; } + foreach (@resolutions) { print DATA "|$bugcount{$_}"; } print DATA "\n"; } @@ -482,19 +574,22 @@ sub CollectSeriesData { # We set up the user for Search.pm's permission checking - each series # runs with the permissions of its creator. my $user = new Bugzilla::User($serieses->{$series_id}->{'creator'}); + my $cgi = new Bugzilla::CGI($serieses->{$series_id}->{'query'}); + my $search = new Bugzilla::Search('params' => $cgi, + 'fields' => ["bugs.bug_id"], + 'user' => $user); + my $sql = $search->getSQL(); + my $data; - - # Do not die if Search->new() detects invalid data, such as an obsolete - # login name or a renamed product or component, etc. - eval { - my $search = new Bugzilla::Search('params' => $cgi, - 'fields' => ["bugs.bug_id"], - 'user' => $user); - my $sql = $search->getSQL(); + + # We can't die if we get dodgy SQL back for whatever reason, so we + # eval() this and, if it fails, just ignore it and carry on. + # One day we might even log an error. + eval { $data = $shadow_dbh->selectall_arrayref($sql); }; - + if (!$@) { # We need to count the returned rows. Without subselects, we can't # do this directly in the SQL for all queries. So we do it by hand. diff --git a/config.cgi b/config.cgi index bea4f6faa..c320ae515 100755 --- a/config.cgi +++ b/config.cgi @@ -28,60 +28,56 @@ # Make it harder for us to do dangerous things in Perl. use strict; -# Include the Bugzilla CGI and general utility library. use lib qw(.); -require "globals.pl"; + use Bugzilla; use Bugzilla::Constants; - -# Suppress "used only once" warnings. -use vars - qw( - @legal_priority - @legal_severity - @legal_platform - @legal_opsys - @legal_resolution - - @legal_components - @legal_target_milestone - @legal_versions - @legal_keywords - ); - -# Use the global template variables defined in globals.pl -# to generate the output. +use Bugzilla::Error; +use Bugzilla::Keyword; +use Bugzilla::Bug; +use Bugzilla::Field; my $user = Bugzilla->login(LOGIN_OPTIONAL); +my $cgi = Bugzilla->cgi; # If the 'requirelogin' parameter is on and the user is not # authenticated, return empty fields. -if (Param('requirelogin') && !$user->id) { +if (Bugzilla->params->{'requirelogin'} && !$user->id) { display_data(); } -# Retrieve this installation's configuration. -GetVersionTable(); - # Pass a bunch of Bugzilla configuration to the templates. my $vars = {}; -$vars->{'priority'} = \@::legal_priority; -$vars->{'severity'} = \@::legal_severity; -$vars->{'platform'} = \@::legal_platform; -$vars->{'op_sys'} = \@::legal_opsys; -$vars->{'keyword'} = \@::legal_keywords; -$vars->{'resolution'} = \@::legal_resolution; -$vars->{'status'} = \@::legal_bug_status; +$vars->{'priority'} = get_legal_field_values('priority'); +$vars->{'severity'} = get_legal_field_values('bug_severity'); +$vars->{'platform'} = get_legal_field_values('rep_platform'); +$vars->{'op_sys'} = get_legal_field_values('op_sys'); +$vars->{'keyword'} = [map($_->name, Bugzilla::Keyword->get_all)]; +$vars->{'resolution'} = get_legal_field_values('resolution'); +$vars->{'status'} = get_legal_field_values('bug_status'); # Include a list of product objects. -$vars->{'products'} = $user->get_selectable_products; +if ($cgi->param('product')) { + my @products = $cgi->param('product'); + foreach my $product_name (@products) { + # We don't use check_product because config.cgi outputs mostly + # in XML and JS and we don't want to display an HTML error + # instead of that. + my $product = new Bugzilla::Product({ name => $product_name }); + if ($product && $user->can_see_product($product->name)) { + push (@{$vars->{'products'}}, $product); + } + } +} else { + $vars->{'products'} = $user->get_selectable_products; +} # Create separate lists of open versus resolved statuses. This should really # be made part of the configuration. my @open_status; my @closed_status; -foreach my $status (@::legal_bug_status) { - IsOpenedState($status) ? push(@open_status, $status) +foreach my $status (@{$vars->{'status'}}) { + is_open_state($status) ? push(@open_status, $status) : push(@closed_status, $status); } $vars->{'open_status'} = \@open_status; @@ -96,7 +92,7 @@ display_data($vars); sub display_data { my $vars = shift; - my $cgi = Bugzilla->cgi; + my $cgi = Bugzilla->cgi; my $template = Bugzilla->template; # Determine how the user would like to receive the output; diff --git a/contrib/BugzillaEmail.pm b/contrib/BugzillaEmail.pm deleted file mode 100644 index db31d1f24..000000000 --- a/contrib/BugzillaEmail.pm +++ /dev/null @@ -1,84 +0,0 @@ -# -*- Mode: perl; indent-tabs-mode: nil -*- - -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# This code is based on code found in bug_email.pl from the bugzilla -# email tracker. Initial contributors are :: -# Terry Weissman <terry@mozilla.org> -# Gregor Fischer <fischer@suse.de> -# Klaas Freitag <freitag@suse.de> -# Seth Landsman <seth@dworkin.net> -# Lance Larsh <lance.larsh@oracle.com> - -# The purpose of this module is to abstract out a bunch of the code -# that is central to email interfaces to bugzilla and its database - -# Contributor : Seth Landsman <seth@dworkin.net> - -# Initial checkin : 03/15/00 (SML) -# findUser() function moved from bug_email.pl to here - -push @INC, "../."; # this script now lives in contrib - -require "globals.pl"; - -use strict; - -my $dbh = Bugzilla->dbh; - -my $EMAIL_TRANSFORM_NONE = "email_transform_none"; -my $EMAIL_TRANSFORM_BASE_DOMAIN = "email_transform_base_domain"; -my $EMAIL_TRANSFORM_NAME_ONLY = "email_transform_name_only"; - -# change to do incoming email address fuzzy matching -my $email_transform = $EMAIL_TRANSFORM_NAME_ONLY; - -# findUser() -# This function takes an email address and returns the user email. -# matching is sloppy based on the $email_transform parameter -sub findUser($) { - my ($address) = @_; - # if $email_transform is $EMAIL_TRANSFORM_NONE, return the address, otherwise, return undef - if ($email_transform eq $EMAIL_TRANSFORM_NONE) { - my $stmt = "SELECT login_name FROM profiles WHERE " . - $dbh->sql_istrcmp('login_name', $dbh->quote($address)); - SendSQL($stmt); - my $found_address = FetchOneColumn(); - return $found_address; - } elsif ($email_transform eq $EMAIL_TRANSFORM_BASE_DOMAIN) { - my ($username) = ($address =~ /(.+)@/); - my $stmt = "SELECT login_name FROM profiles WHERE " . $dbh->sql_regexp( - $dbh->sql_istring('login_name'), $dbh->sql_istring($dbh->quote($username))); - SendSQL($stmt); - - my $domain; - my $found = undef; - my $found_address; - my $new_address = undef; - while ((!$found) && ($found_address = FetchOneColumn())) { - ($domain) = ($found_address =~ /.+@(.+)/); - if ($address =~ /$domain/) { - $found = 1; - $new_address = $found_address; - } - } - return $new_address; - } elsif ($email_transform eq $EMAIL_TRANSFORM_NAME_ONLY) { - my ($username) = ($address =~ /(.+)@/); - my $stmt = "SELECT login_name FROM profiles WHERE " .$dbh->sql_regexp( - $dbh->sql_istring('login_name'), $dbh->sql_istring($dbh->quote($username))); - SendSQL($stmt); - my $found_address = FetchOneColumn(); - return $found_address; - } -} - -1; diff --git a/contrib/CVS/Entries b/contrib/CVS/Entries index 18a6125f7..4bfabb057 100644 --- a/contrib/CVS/Entries +++ b/contrib/CVS/Entries @@ -1,21 +1,17 @@ -/BugzillaEmail.pm/1.4/Wed Aug 31 08:00:25 2005//TBUGZILLA-2_22_3 -/README/1.10/Mon Jul 5 21:54:00 2004//TBUGZILLA-2_22_3 -/README.Mailif/1.4/Fri Nov 25 19:47:38 2005//TBUGZILLA-2_22_3 -/bug_email.pl/1.31.2.6/Mon Jun 19 16:25:16 2006//TBUGZILLA-2_22_3 -/bugmail_help.html/1.3.2.3/Mon Jun 19 16:12:10 2006//TBUGZILLA-2_22_3 -/bugzilla.procmailrc/1.1/Wed Mar 15 23:39:09 2000//TBUGZILLA-2_22_3 -/bugzilla_email_append.pl/1.10/Fri Nov 25 21:57:07 2005//TBUGZILLA-2_22_3 -/bugzilla_ldapsync.rb/1.2/Sat Apr 26 16:35:04 2003//TBUGZILLA-2_22_3 -/bzdbcopy.pl/1.1.4.1/Sun Apr 30 23:54:37 2006//TBUGZILLA-2_22_3 -/cvs-update.pl/1.1/Tue Nov 11 05:58:52 2003//TBUGZILLA-2_22_3 -/gnats2bz.pl/1.6/Thu Jan 31 14:29:21 2002//TBUGZILLA-2_22_3 -/jb2bz.py/1.5/Fri Aug 26 23:11:32 2005//TBUGZILLA-2_22_3 -/merge-users.pl/1.1.2.2/Sun Feb 26 13:17:48 2006//TBUGZILLA-2_22_3 -/mysqld-watcher.pl/1.5/Thu Mar 27 00:06:53 2003//TBUGZILLA-2_22_3 -/sendbugmail.pl/1.3/Thu Feb 24 23:42:48 2005//TBUGZILLA-2_22_3 -/sendunsentbugmail.pl/1.7/Sun Nov 13 17:32:12 2005//TBUGZILLA-2_22_3 -/syncLDAP.pl/1.4/Wed Aug 10 01:30:40 2005//TBUGZILLA-2_22_3 -/yp_nomail.sh/1.1/Tue Sep 12 23:50:31 2000//TBUGZILLA-2_22_3 +/README/1.10/Mon Jul 5 21:54:00 2004//TBUGZILLA-3_0 +/bugzilla_ldapsync.rb/1.2/Sat Apr 26 16:35:04 2003//TBUGZILLA-3_0 +/bz_webservice_demo.pl/1.7/Sat Jan 6 14:20:16 2007//TBUGZILLA-3_0 +/bzdbcopy.pl/1.3/Fri Dec 29 23:17:53 2006//TBUGZILLA-3_0 +/cvs-update.pl/1.1/Tue Nov 11 05:58:52 2003//TBUGZILLA-3_0 +/gnats2bz.pl/1.8/Sun Sep 3 20:37:01 2006//TBUGZILLA-3_0 +/jb2bz.py/1.5/Fri Aug 26 23:11:32 2005//TBUGZILLA-3_0 +/merge-users.pl/1.3.2.1/Wed Mar 28 12:58:49 2007//TBUGZILLA-3_0 +/mysqld-watcher.pl/1.5/Thu Mar 27 00:06:53 2003//TBUGZILLA-3_0 +/recode.pl/1.4/Fri Dec 29 23:16:22 2006//TBUGZILLA-3_0 +/sendbugmail.pl/1.7/Mon Jul 3 21:42:47 2006//TBUGZILLA-3_0 +/sendunsentbugmail.pl/1.9/Wed Jun 21 00:44:48 2006//TBUGZILLA-3_0 +/syncLDAP.pl/1.9/Fri Aug 25 22:10:39 2006//TBUGZILLA-3_0 +/yp_nomail.sh/1.1/Tue Sep 12 23:50:31 2000//TBUGZILLA-3_0 D/bugzilla-submit//// D/cmdline//// D/gnatsparse//// diff --git a/contrib/CVS/Tag b/contrib/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/contrib/CVS/Tag +++ b/contrib/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/contrib/README.Mailif b/contrib/README.Mailif deleted file mode 100644 index 0c65cef83..000000000 --- a/contrib/README.Mailif +++ /dev/null @@ -1,80 +0,0 @@ - -The Bugzilla Mail interface -=========================== - -(UPDATE 03/14/00 to better reflect reality by SML) - -The Bugzilla Mail interface allows to submit bugs to Bugzilla by email. - -The Mail Interface Contribution consists of three files: -README.Mailif - this readme. -bug_email.pl - the script -bugmail_help.html - a user help html site - -Installation: - -Next is to add a user who receives the bugmails, e. g. bugmail. Create a -mail account and a home directory for the user. - -The mailinterface script bug_email.pl needs to get the mail through stdin. -I use procmail for that, with the following line in the .procmailrc: - -BUGZILLA_HOME=/usr/local/httpd/htdocs/bugzilla -:0 c -|(cd $BUGZILLA_HOME/contrib; ./bug_email.pl) - -This defines the Bugzilla directory as the variable BUGZILLA_HOME and passes -all incoming mail to the script after cd'ing into the bugzilla home. - -In some cases, it is necessary to alter the headers of incoming email. The -additional line to procmail : - -:0 fhw -| formail -I "From " -a "From " - -fixes many problems. - -See bugzilla.procmailrc for a sample procmailrc that works for me (SML) and -also deals with bugzilla_email_append.pl - -Customation: - -There are some values inside the script which need to be customized for your -needs: - -1. In sub-routine Reply (search 'sub Reply': -there is the line - print MAIL "From: Bugzilla Mailinterface<yourmail\@here.com>\n"; - ^^^^^^^^^^^^^^^^^^^^ -Fill in your correct mail here. That will make it easy for people to reply -to the mail. - -2. check, if your sendmail resides in /usr/sbin/sendmail, change the path if neccessary. -Search the script after 'default' - you find some default-Settings for bug -reports, which are used, if the sender did not send a field for it. The defaults -should be checked and changed. - -That's hopefully all, we will come up with any configuration file or something. - - -If your mail works, your script will insert mails from now on. - -The mailinterface supports two commandline switches: - -There are two command line switches : - --t: Testmode - The mailinterface does not really insert the bug into the database, but - writes some debug output to stdout and writes the mail into the file - bug_email_test.log in the data-dir. - --r: restricted mode - All lines before the first line with a keyword character are skipped. - In not restricted, default mode, these lines are added to the long - description of the bug. - - -02/2000 - Klaas Freitag, SuSE GmbH <freitag@suse.de> -03/2000 - Seth M. Landsman <seth@cs.brandeis.edu> - bug_email.pl now lives out of bugzilla/contrib - added line about formail diff --git a/contrib/bug_email.pl b/contrib/bug_email.pl deleted file mode 100755 index 158da294e..000000000 --- a/contrib/bug_email.pl +++ /dev/null @@ -1,1225 +0,0 @@ -#!/usr/bin/perl -w -# -*- Mode: perl; indent-tabs-mode: nil -*- -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Bugzilla Bug Tracking System. -# -# The Initial Developer of the Original Code is Netscape Communications -# Corporation. Portions created by Netscape are -# Copyright (C) 1998 Netscape Communications Corporation. All -# Rights Reserved. -# Contributor(s): Terry Weissman <terry@mozilla.org> -# Gregor Fischer <fischer@suse.de> -# Klaas Freitag <freitag@suse.de> -# Seth Landsman <seth@dworkin.net> -# Ludovic Dubost <ludovic@pobox.com> -############################################################### -# Bugzilla: Create a new bug via email -############################################################### -# The email needs to be feeded to this program on STDIN. -# This is usually done by having an entry like this in your -# .procmailrc: -# -# BUGZILLA_HOME=/usr/local/httpd/htdocs/bugzilla -# :0 c -# |(cd $BUGZILLA_HOME/contrib; ./bug_email.pl) -# -# -# Installation note: -# -# You need to work with bug_email.pl the MIME::Parser installed. -# -# $Id: bug_email.pl,v 1.31.2.6 2006/06/19 16:25:16 vladd%bugzilla.org Exp $ -############################################################### - -# 02/12/2000 (SML) -# - updates to work with most recent database changes to the bugs database -# - updated so that it works out of bugzilla/contrib -# - initial checkin into the mozilla CVS tree (yay) - -# 02/13/2000 (SML) -# - email transformation code. -# EMAIL_TRANSFORM_NONE does exact email matches -# EMAIL_TRANSFORM_NAME_ONLY matches on the username -# EMAIL_TRANSFORM_BASE_DOMAIN matches on the username and checks the domain of -# to see that the one in the database is a subset of the one in the sender address -# this is probably prone to false positives and probably needs more work. - -# 03/07/2000 (SML) -# - added in $DEFAULT_PRODUCT and $DEFAULT_COMPONENT. i.e., if $DEFAULT_PRODUCT = "PENDING", -# any email submitted bug will be entered with a product of PENDING, if no other product is -# specified in the email. - -# 10/21/2003 (Ludovic) -# - added $DEFAULT_VERSION, similar to product and component above -# - added command line switches to override version, product, and component, so separate -# email addresses can be used for different product/component/version combinations. -# Example for procmail: -# # Feed mail to stdin of bug_email.pl -# :0 Ec -# * !^Subject: .*[Bug .*] -# RESULT=|(cd $BUGZILLA_HOME/contrib && ./bug_email.pl -p='Tier_3_Operations' -c='General' ) - -# Next round of revisions : -# - querying a bug over email -# - appending a bug over email -# - keywords over email -# - use the globals.pl parameters functionality to edit and save this script's parameters -# - integrate some setup in the checksetup.pl script -# - gpg signatures for security - -use strict; -use MIME::Parser; - -BEGIN { - chdir '..'; # this script lives in contrib - push @INC, "contrib/."; - push @INC, "."; -} - -require "globals.pl"; -use BugzillaEmail; -use Bugzilla::Config qw(:DEFAULT $datadir); - -use lib "."; -use lib "../"; -use Bugzilla::Constants; -use Bugzilla::BugMail; -use Bugzilla::User; - -my @mailerrors = (); # Buffer for Errors in the mail -my @mailwarnings = (); # Buffer for Warnings found in the mail -my $critical_err = 0; # Counter for critical errors - must be zero for success -my %Control; -my $Header = ""; -my @RequiredLabels = (); -my @AllowedLabels = (); -my $Body = ""; -my @attachments = (); - -my $product_valid = 0; -my $test = 0; -my $restricted = 0; -my $SenderShort; -my $Message_ID; - -my $dbh = Bugzilla->dbh; - -# change to use default product / component functionality -my $DEFAULT_PRODUCT = "PENDING"; -my $DEFAULT_COMPONENT = "PENDING"; -my $DEFAULT_VERSION = "unspecified"; - -############################################################### -# storeAttachments -# -# in this sub, attachments found in the dump-sub will be written to -# the database. The info, which attachments need saving is stored -# in the global @attachments-list. -# The sub returns the number of stored attachments. -sub storeAttachments( $$ ) -{ - my ($bugid, $submitter_id ) = @_; - my $maxsize = 0; - my $data; - my $listref = \@attachments; - my $att_count = 0; - - $submitter_id ||= 0; - - foreach my $pairref ( @$listref ) { - my ($decoded_file, $mime, $on_disk, $description) = @$pairref; - - - # Size check - mysql has a maximum space for the data ? - $maxsize = 1047552; # should be queried by a system( "mysqld --help" );, - # but this seems not to be supported by all current mysql-versions - - # Read data file binary - if( $on_disk ) { - if( open( FILE, "$decoded_file" )) { - binmode FILE; - read FILE, $data, $maxsize; - close FILE; - $att_count ++; - } else { - print "Error while reading attachment $decoded_file!\n"; - next; - } - # print "unlinking $datadir/mimedump-tmp/$decoded_file"; - # unlink "$datadir/mimedump-tmp/$decoded_file"; - } else { - # data is in the scalar - $data = $decoded_file; - } - - - # Make SQL-String - my $sql = "insert into attachments (bug_id, creation_ts, description, mimetype, ispatch, filename, submitter_id) values ("; - $sql .= "$bugid, now(), " . SqlQuote( $description ) . ", "; - $sql .= SqlQuote( $mime ) . ", "; - $sql .= "0, "; - $sql .= SqlQuote( $decoded_file ) . ", "; - $sql .= "$submitter_id );"; - SendSQL( $sql ) unless( $test ); - $sql = "insert into attach_data (id, thedata) values (LAST_INSERT_ID(), "; - $sql .= SqlQuote( $data ) . ")"; - SendSQL( $sql ) unless( $test ); - } - - return( $att_count ); -} - - - -############################################################### -# Beautification -sub horLine( ) -{ - return( "-----------------------------------------------------------------------\n" ); -} - - -############################################################### -# Check if $Name is in $GroupName - -# This is no more CreateBugs group, so I'm using this routine to just determine if the user is -# in the database. Eventually, here should be a separate routine or renamed, or something (SML) -sub CheckPermissions { - my ($GroupName, $Name) = @_; - -# SendSQL("select login_name from profiles,groups where groups.name='$GroupName' and profiles.groupset & groups.bit = groups.bit and profiles.login_name=\'$Name\'"); -# my $NewName = FetchOneColumn(); -# if ( $NewName eq $Name ) { -# return $Name; -# } else { -# return; -# } -# my $query = "SELECT login_name FROM profiles WHERE profiles.login_name=\'$Name\'"; -# SendSQL($query); -# my $check_name = FetchOneColumn(); -# if ($check_name eq $Name) { -# return $Name; -# } else { -# return; -# } - return findUser($Name); -} - -############################################################### -# Check if product is valid. -sub CheckProduct { - my $Product = shift; - - SendSQL("select name from products where name = " . SqlQuote($Product)); - my $Result = FetchOneColumn(); - if (lc($Result) eq lc($Product)) { - return $Result; - } else { - return ""; - } -} - -############################################################### -# Check if component is valid for product. -sub CheckComponent { - my $Product = shift; - my $Component = shift; - - SendSQL("select components.name from components, products where components.product_id = products.id AND products.name=" . SqlQuote($Product) . " and components.name=" . SqlQuote($Component)); - my $Result = FetchOneColumn(); - if (lc($Result) eq lc($Component)) { - return $Result; - } else { - return ""; - } -} - -############################################################### -# Check if component is valid for product. -sub CheckVersion { - my $Product = shift; - my $Version = shift; - - SendSQL("select value from versions, products where versions.product_id = products.id AND products.name=" . SqlQuote($Product) . " and value=" . SqlQuote($Version)); - my $Result = FetchOneColumn(); - if (lc($Result) eq lc($Version)) { - return $Result; - } else { - return ""; - } -} - -############################################################### -# Reply to a mail. -sub Reply( $$$$ ) { - my ($Sender, $MessageID, $Subject, $Text) = @_; - - - die "Cannot find sender-email-address" unless defined( $Sender ); - - if( $test ) { - open( MAIL, '>>', "$datadir/bug_email_test.log" ); - } - else { - open( MAIL, "| /usr/sbin/sendmail -t" ); - } - - print MAIL "To: $Sender\n"; - print MAIL "From: Bugzilla Mailinterface<yourmail\@here.com>\n"; - print MAIL "Subject: $Subject\n"; - print MAIL "In-Reply-To: $MessageID\n" if ( defined( $MessageID )); - print MAIL "\n"; - print MAIL "$Text"; - close( MAIL ); - -} - - -############################################################### -# getEnumList -# Queries the Database for the table description and figures the -# enum-settings out - useful for checking fields for enums like -# prios -sub getEnumList( $ ) -{ - my $dbh = Bugzilla->dbh; - my ($fieldname) = @_; - my $result = $dbh->selectcol_arrayref(qq{SELECT value FROM $fieldname}); - - return($result); -} - -############################################################### -# CheckPriority -# Checks, if the priority setting is one of the enums defined -# in the data base -# Uses the global var. $Control{ 'priority' } -sub CheckPriority -{ - my $prio = $Control{'priority'}; - my $all_prios = getEnumList( "priority" ); - - if( $prio eq "" || (lsearch( $all_prios, $prio ) == -1) ) { - # OK, Prio was not defined - create Answer - my $Text = "You sent wrong priority-setting, valid values are:" . - join( "\n\t", @$all_prios ) . "\n\n"; - $Text .= "* The priority is set to the default value ". - SqlQuote( Param('defaultpriority')) . "\n"; - - BugMailError( 0, $Text ); - - # set default value from param-file - $Control{'priority'} = Param( 'defaultpriority' ); - } else { - # Nothing to do - } -} - -############################################################### -# CheckSeverity -# checks the bug_severity -sub CheckSeverity -{ - my $sever = ($Control{'bug_severity'} ||= "" ); - my $all_sever = getEnumList( "bug_severity" ); - - if( (lsearch($all_sever, $sever) == -1) || $sever eq "" ) { - # OK, Prio was not defined - create Answer - my $Text = "You sent wrong bug_severity-setting, valid values are:" . - join( "\n\t", @$all_sever ) . "\n\n"; - $Text .= "* The bug_severity is set to the default value ". - SqlQuote( "normal" ) . "\n"; - - BugMailError( 0, $Text ); - - # set default value from param-file - $Control{'bug_severity'} = "normal"; - } -} - -############################################################### -# CheckArea -# checks the area-field -sub CheckArea -{ - my $area = ($Control{'area'} ||= "" ); - my $all = getEnumList( "area" ); - - if( (lsearch($all, $area) == -1) || $area eq "" ) { - # OK, Area was not defined - create Answer - my $Text = "You sent wrong area-setting, valid values are:" . - join( "\n\t", @$all ) . "\n\n"; - $Text .= "* The area is set to the default value ". - SqlQuote( "BUILD" ) . "\n"; - - BugMailError( 0, $Text ); - - # set default value from param-file - $Control{'area'} = "BUILD"; - } -} - -############################################################### -# CheckPlatform -# checks the given Platform and corrects it -sub CheckPlatform -{ - my $platform = ($Control{'rep_platform'} ||= "" ); - my $all = getEnumList( "rep_platform" ); - - if( (lsearch($all, $platform) == -1) || $platform eq "" ) { - # OK, Prio was not defined - create Answer - my $Text = "You sent wrong platform-setting, valid values are:" . - join( "\n\t", @$all ) . "\n\n"; - $Text .= "* The rep_platform is set to the default value ". - SqlQuote( "All" ) . "\n"; - - BugMailError( 0, $Text ); - - # set default value from param-file - $Control{'rep_platform'} = "All"; - } -} - -############################################################### -# CheckSystem -# checks the given Op-Sys and corrects it -sub CheckSystem -{ - my $sys = ($Control{'op_sys'} ||= "" ); - my $all = getEnumList( "op_sys" ); - - if( (lsearch( $all, $sys ) == -1) || $sys eq "" ) { - # OK, Prio was not defined - create Answer - my $Text = "You sent wrong OS-setting, valid values are:" . - join( "\n\t", @$all ) . "\n\n"; - $Text .= "* The op_sys is set to the default value ". - SqlQuote( "Linux" ) . "\n"; - - BugMailError( 0, $Text ); - - # set default value from param-file - $Control{'op_sys'} = "Linux"; - } -} - - -############################################################### -# Fetches all lines of a query with a single column selected and -# returns it as an array -# -sub FetchAllSQLData( ) -{ - my @res = (); - - while( MoreSQLData() ){ - push( @res, FetchOneColumn() ); - } - return( @res ); -} - -############################################################### -# Error Handler for Errors in the mail -# -# This function can be called multiple within processing one mail and -# stores the errors found in the Mail. Errors are for example empty -# required tags, missing required tags and so on. -# -# The benefit is, that the mail users get a reply, where all mail errors -# are reported. The reply mail includes all messages what was wrong and -# the second mail the user sends can be ok, cause all his faults where -# reported. -# -# BugMailError takes two arguments: The first one is a flag, how heavy -# the error is: -# -# 0 - It's an error, but Bugzilla can process the bug. The user should -# handle that as a warning. -# -# 1 - It's a real bug. Bugzilla can't store the bug. The mail has to be -# resent. -# -# 2 - Permission error: The user does not have the permission to send -# a bug. -# -# The second argument is a Text which describes the bug. -# -# -# # -sub BugMailError($ $ ) -{ - my ( $errflag, $text ) = @_; - - # On permission error, don't sent all other Errors back -> just quit ! - if( $errflag == 2 ) { # Permission-Error - Reply( $SenderShort, $Message_ID, "Bugzilla Error", "Permission denied.\n\n" . - "You do not have the permissions to create a new bug. Sorry.\n" ); - exit; - } - - - # Warnings - store for the reply mail - if( $errflag == 0 ) { - push( @mailwarnings, $text ); - } - - # Critical Error - if( $errflag == 1 ) { - $critical_err += 1; - push( @mailerrors, $text ); - } -} - -############################################################### -# getWarningText() -# -# getWarningText() returns a reply-ready Textline of all the -# Warnings in the Mail -sub getWarningText() -{ - my $anz = @mailwarnings; - - my $ret = <<END - -The Bugzilla Mail Interface found warnings (JFYI): - -END - ; - - # Handshake if no warnings at all - return( "\n\n Your mail was processed without Warnings !\n" ) if( $anz == 0 ); - - # build a text - $ret .= join( "\n ", @mailwarnings ); - return( horLine() . $ret ); -} - -sub getErrorText() -{ - my $anz = @mailerrors; - - my $ret = <<END - -************************** ERROR ************************** - -Your request to the Bugzilla mail interface could not be met -due to errors in the mail. We will find it ! - - -END - ; - return( "\n\n Your mail was processed without errors !\n") if( $anz == 0 ); - # build a text - $ret .= join( "\n ", @mailerrors ); - return( $ret ); -} - -############################################################### -# generateTemplate -# -# This function generates a mail-Template with the -sub generateTemplate() -{ - my $w; - my $ret; - - # Required Labels - $ret =<<EOF - - -You may want to use this template to resend your mail. Please fill in the missing -keys. - -_____ snip _______________________________________________________________________ - -EOF - ; - foreach ( @RequiredLabels ) { - $w = ""; - $w = $Control{$_} if defined( $Control{ $_ } ); - $ret .= sprintf( " \@%-15s: %s\n", $_, $w ); - } - - $ret .= "\n"; - # Allowed Labels - foreach( @AllowedLabels ) { - next if( /reporter/ ); # Reporter is not a valid label - next if( /assigned_to/ ); # Assigned to is just a number - if( defined( $Control{ $_ } ) && lsearch( \@RequiredLabels, $_ ) == -1 ) { - $ret .= sprintf( " \@%-15s: %s\n", $_, $Control{ $_ } ); - } - } - - if( $Body eq "" ) { - $ret .= <<END - - < the bug-description follows here > - -_____ snip _______________________________________________________________________ - -END - ; } else { - $ret .= "\n" . $Body; - } - - return( $ret ); - -} -#------------------------------ -# -# dump_entity ENTITY, NAME -# -# Recursive routine for parsing a mime coded mail. -# One mail may contain more than one mime blocks, which need to be -# handled. Therefore, this function is called recursively. -# -# It gets the for bugzilla important information from the mailbody and -# stores them into the global attachment-list @attachments. The attachment-list -# is needed in storeAttachments. -# -sub dump_entity { - my ($entity, $name) = @_; - defined($name) or $name = "'anonymous'"; - my $IO; - - - # Output the body: - my @parts = $entity->parts; - if (@parts) { # multipart... - my $i; - foreach $i (0 .. $#parts) { # dump each part... - dump_entity($parts[$i], ("$name, part ".(1+$i))); - } - } else { # single part... - - # Get MIME type, and display accordingly... - my $msg_part = $entity->head->get( 'Content-Disposition' ); - - $msg_part ||= ""; - - my ($type, $subtype) = split('/', $entity->head->mime_type); - my $body = $entity->bodyhandle; - my ($data, $on_disk ); - - if( $msg_part =~ /^attachment/ ) { - # Attached File - my $des = $entity->head->get('Content-Description'); - $des ||= $entity->head->recommended_filename; - $des ||= "unnamed attachment"; - - if( defined( $body->path )) { # Data is on disk - $on_disk = 1; - $data = $body->path; - - } else { # Data is in core - $on_disk = 0; - $data = $body->as_string; - } - push ( @attachments, [ $data, $entity->head->mime_type, $on_disk, $des ] ); - } else { - # Real Message - if ($type =~ /^(text|message)$/) { # text: display it... - if ($IO = $body->open("r")) { - $Body .= $_ while (defined($_ = $IO->getline)); - $IO->close; - } else { # d'oh! - print "$0: couldn't find/open '$name': $!"; - } - } else { print "Oooops - no Body !\n"; } - } - } -} - -############################################################### -# sub extractControls -############################################################### -# -# This sub parses the message Body and filters the control-keys. -# Attention: Global hash Controls affected -# -sub extractControls( $ ) -{ - my ($body) = @_; - my $backbody = ""; - - my @lbody = split( /\n/, $body ); - - # In restricted mode, all lines before the first keyword - # are skipped. - if( $restricted ) { - while( $lbody[0] =~ /^\s*\@.*/ ){ shift( @lbody );} - } - - # Filtering for keys - foreach( @lbody ) { - if( /^\s*\@description/ ) { - s/\s*\@description//; - $backbody .= $_; - } elsif( /^\s*\@(.*?)(?:\s*=\s*|\s*:\s*|\s+)(.*?)\s*$/ ) { - $Control{lc($1)} = $2; - } else { - $backbody .= "$_" . "\n"; - } - } - - # that's it. - return( $backbody ); -} - -############################################################### -# Main starts here -############################################################### -# -# Commandline switches: -# -t: test mode - no DB-Inserts -foreach( @ARGV ) { - $restricted = 1 if ( /-r/ ); - $test = 1 if ( /-t/ ); - - if ( /-p=['"]?(.+)['"]?/ ) - { - $DEFAULT_PRODUCT = $1; - } - - if ( /-c=['"]?(.+)["']?/ ) - { - $DEFAULT_COMPONENT = $1; - } - - if ( /-v=['"]?(.+)["']?/ ) - { - $DEFAULT_VERSION = $1; - } - -} - -# -# Parsing a mime-message -# -if( -t STDIN ) { -print STDERR <<END - Bugzilla Mail Interface - - This scripts reads a mail message through stdin and parses the message, - for to insert a bug to bugzilla. - - Options - -t: Testmode - No insert to the DB, but logfile - -r: restricted mode - all lines before the keys in the mail are skipped - -END - ; -exit; -} - - -# Create a new MIME parser: -my $parser = new MIME::Parser; - -# Create and set the output directory: -# FIXME: There should be a $BUGZILLA_HOME variable (SML) -(-d "$datadir/mimedump-tmp") or mkdir "$datadir/mimedump-tmp",0755 or die "mkdir: $!"; -(-w "$datadir/mimedump-tmp") or die "can't write to directory"; - -$parser->output_dir("$datadir/mimedump-tmp"); - -# Read the MIME message: -my $entity = $parser->read(\*STDIN) or die "couldn't parse MIME stream"; -$entity->remove_sig(10); # Removes the signature in the last 10 lines - -# Getting values from parsed mail -my $Sender = $entity->get( 'From' ); -$Sender ||= $entity->get( 'Reply-To' ); -$Message_ID = $entity->get( 'Message-Id' ); - -die (" *** Can't find Sender-address in sent mail ! ***\n" ) unless defined( $Sender ); -chomp( $Sender ); -chomp( $Message_ID ); - -$SenderShort = $Sender; -$SenderShort =~ s/^.*?([a-zA-Z0-9_.-]+?\@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+).*$/$1/; - -$SenderShort = findUser($SenderShort); - -if (!defined($SenderShort)) { - $SenderShort = $Sender; - $SenderShort =~ s/^.*?([a-zA-Z0-9_.-]+?\@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+).*$/$1/; -} - -my $Subject = ""; -$Subject = $entity->get( 'Subject' ); -chomp( $Subject ); - -# Get all the attachments -dump_entity($entity); -# print $Body; -$Body = extractControls( $Body ); # fills the Control-Hash - -if( $test ) { - foreach (keys %Control ) { - print "$_ => $Control{$_}\n"; - } -} - -$Control{'short_desc'} ||= $Subject; -# -# * Mailparsing finishes here * -# - -###################################################################### -# Now a lot of Checks of the given Labels start. -# Check Control-Labels -# not: reporter ! -@AllowedLabels = ("product", "version", "rep_platform", - "bug_severity", "priority", "op_sys", "assigned_to", - "bug_status", "bug_file_loc", "short_desc", "component", - "status_whiteboard", "target_milestone", "groupset", - "qa_contact"); -#my @AllowedLabels = qw{Summary priority platform assign}; -foreach (keys %Control) { - if ( lsearch( \@AllowedLabels, $_) < 0 ) { - BugMailError( 0, "You sent a unknown label: " . $_ ); - } -} - -push( @AllowedLabels, "reporter" ); -$Control{'reporter'} = $SenderShort; - -# Check required Labels - not all labels are required, because they could be generated -# from the given information -# Just send a warning- the error-Flag will be set later -@RequiredLabels = qw{product version component short_desc}; -foreach my $Label (@RequiredLabels) { - if ( ! defined $Control{$Label} ) { - BugMailError( 0, "You were missing a required label: \@$Label\n" ); - next; - } - - if( $Control{$Label} =~ /^\s*$/ ) { - BugMailError( 0, "One of your required labels is empty: $Label" ); - next; - } -} - -if ( $Body =~ /^\s*$/s ) { - BugMailError( 1, "You sent a completely empty body !" ); -} - - -# umask 0; - -# Check Permissions ... -if (! CheckPermissions("CreateBugs", $SenderShort ) ) { - BugMailError( 2, "Permission denied.\n\n" . - "You do not have the permissions to create a new bug. Sorry.\n" ); -} - -# Set QA -if (Param("useqacontact")) { - if (defined($Control{'qa_contact'}) - && $Control{'qa_contact'} !~ /^\s*$/ ) { - $Control{'qa_contact'} = DBname_to_id($Control{'qa_contact'}); - } else { - SendSQL("select initialqacontact from components, products where components.product_id = products.id AND products.name=" . - SqlQuote($Control{'product'}) . - " and components.name=" . SqlQuote($Control{'component'})); - $Control{'qa_contact'} = FetchOneColumn(); - } -} - -# Set Assigned - assigned_to depends on the product, cause initialowner -# depends on the product ! -# => first check product ! -# Product -my @all_products = (); -# set to the default product. If the default product is empty, this has no effect -my $Product = $DEFAULT_PRODUCT; -$Product = CheckProduct( $Control{'product'} ) if( defined( $Control{ 'product'} )); - -if ( $Product eq "" ) { - my $Text = "You didn't send a value for the required key \@product !\n\n"; - - $Text = "You sent the invalid product \"$Control{'product'}\"!\n\n" - if( defined( $Control{ 'product'} )); - - $Text .= "Valid products are:\n\t"; - - SendSQL("select name from products ORDER BY name"); - @all_products = FetchAllSQLData(); - $Text .= join( "\n\t", @all_products ) . "\n\n"; - $Text .= horLine(); - - BugMailError( 1, $Text ); -} else { - # Fill list @all_products, which is needed in case of component-help - @all_products = ( $Product ); - $product_valid = 1; -} -$Control{'product'} = $Product; - -# -# Check the Component: -# - -# set to the default component. If the default component is empty, this has no effect -my $Component = $DEFAULT_COMPONENT; - -if( defined( $Control{'component' } )) { - $Component = CheckComponent( $Control{'product'}, $Control{'component'} ); -} - -if ( $Component eq "" ) { - - my $Text = "You did not send a value for the required key \@component!\n\n"; - - if( defined( $Control{ 'component' } )) { - $Text = "You sent the invalid component \"$Control{'component'}\" !\n"; - } - - # - # Attention: If no product was sent, the user needs info for all components of all - # products -> big reply mail :) - # if a product was sent, only reply the components of the sent product - my @val_components = (); - foreach my $prod ( @all_products ) { - $Text .= "\nValid components for product `$prod' are: \n\t"; - - SendSQL("SELECT components.name FROM components, products WHERE components.product_id=products.id AND products.name = " . SqlQuote($prod)); - @val_components = FetchAllSQLData(); - - $Text .= join( "\n\t", @val_components ) . "\n"; - } - - # Special: if there is a valid product, maybe it has only one component -> use it ! - # - my $amount_of_comps = @val_components; - if( $product_valid && $amount_of_comps == 1 ) { - $Component = $val_components[0]; - - $Text .= " * You did not send a component, but a valid product " . SqlQuote( $Product ) . ".\n"; - $Text .= " * This product only has one component ". SqlQuote( $Component ) .".\n" . - " * This component was set by bugzilla for submitting the bug.\n\n"; - BugMailError( 0, $Text ); # No blocker - - } else { # The component is really buggy :( - $Text .= horLine(); - BugMailError( 1, $Text ); - } -} -$Control{'component'} = $Component; - - -# -# Check assigned_to -# If a value was given in the e-mail, convert it to an ID, -# otherwise, retrieve it from the database. -if ( defined($Control{'assigned_to'}) - && $Control{'assigned_to'} !~ /^\s*$/ ) { - $Control{'assigned_to'} = login_to_id($Control{'assigned_to'}); -} else { - SendSQL("select initialowner from components, products where " . - " components.product_id=products.id AND products.name=" . - SqlQuote($Control{'product'}) . - " and components.name=" . SqlQuote($Control{'component'})); - $Control{'assigned_to'} = FetchOneColumn(); -} - -if ( $Control{'assigned_to'} == 0 ) { - my $Text = "Could not resolve key \@assigned_to !\n" . - "If you do NOT send a value for assigned_to, the bug will be assigned to\n" . - "the qa-contact for the product and component.\n"; - $Text .= "This works only if product and component are OK. \n" - . horLine(); - - BugMailError( 1, $Text ); -} - - -$Control{'reporter'} = login_to_id($Control{'reporter'}); -if ( ! $Control{'reporter'} ) { - BugMailError( 1, "Could not resolve reporter !\n" ); -} - -### Set default values -CheckPriority( ); -CheckSeverity( ); -CheckPlatform( ); -CheckSystem( ); -# CheckArea(); - -### Check values ... -# Version -my $Version = "$DEFAULT_VERSION"; -$Version = CheckVersion( $Control{'product'}, $Control{'version'} ) if( defined( $Control{'version'})); -if ( $Version eq "" ) { - my $Text = "You did not send a value for the required key \@version!\n\n"; - - if( defined( $Control{'version'})) { - my $Text = "You sent the invalid version \"$Control{'version'}\"!\n"; - } - - my $anz_versions; - my @all_versions; - # Assemble help text - foreach my $prod ( @all_products ) { - $Text .= "Valid versions for product " . SqlQuote( $prod ) . " are: \n\t"; - - SendSQL("select value from versions, products where versions.product_id=products.id AND products.name=" . SqlQuote( $prod )); - @all_versions = FetchAllSQLData(); - $anz_versions = @all_versions; - $Text .= join( "\n\t", @all_versions ) . "\n" ; - - } - - # Check if we could use the only version - if( $anz_versions == 1 && $product_valid ) { - $Version = $all_versions[0]; - # Fine, there is only one version string - $Text .= " * You did not send a version, but a valid product " . SqlQuote( $Product ) . ".\n"; - $Text .= " * This product has has only the one version ". SqlQuote( $Version) .".\n" . - " * This version was set by bugzilla for submitting the bug.\n\n"; - $Text .= horLine(); - BugMailError( 0, $Text ); # No blocker - } else { - $Text .= horLine(); - BugMailError( 1, $Text ); - } - -} - -$Control{'version'} = $Version; - -# GroupsSet: Protections for Bug info. This paramter controls the visibility of the -# given bug. An Error in the given Buggroup is not a blocker, a default is taken. -# -# The GroupSet is accepted only as literals linked with whitespaces, plus-signs or commas -# -my $GroupSet = ""; -my %GroupArr = (); -$GroupSet = $Control{'groupset'} if( defined( $Control{ 'groupset' })); -# -# Fetch the default value for groupsetting -my $DefaultGroup = 'ReadInternal'; -SendSQL("select id from groups where name=" . SqlQuote( $DefaultGroup )); -my $default_group = FetchOneColumn(); - -if( $GroupSet eq "" ) { - # Too bad: Groupset does not contain anything -> set to default - $GroupArr{$DefaultGroup} = $default_group if(defined( $default_group )); - # - # Give the user a hint - my $Text = "You did not send a value for optional key \@groupset, which controls\n"; - $Text .= "the Permissions of the bug. It will be set to a default value 'Internal Bug'\n"; - $Text .= "if the group '$DefaultGroup' exists. The QA may change that.\n"; - - BugMailError( 0, $Text ); -} else { - # literal e.g. 'ReadInternal' - my $gserr = 0; - my $Text = ""; - - # - # Split literal Groupsettings either on Whitespaces, +-Signs or , - # Then search for every Literal in the DB - col name - foreach ( split /\s+|\s*\+\s*|\s*,\s*/, $GroupSet ) { - SendSQL("select id, Name from groups where name=" . SqlQuote($_)); - my( $bval, $bname ) = FetchSQLData(); - - if( defined( $bname ) && $_ eq $bname ) { - $GroupArr{$bname} = $bval; - } else { - $Text .= "You sent the wrong GroupSet-String $_\n"; - $gserr = 1; - } - } - - # - # Give help if wrong GroupSet-String came - if( $gserr > 0 ) { - # There happend errors - $Text .= "Here are all valid literal Groupsetting-strings:\n\t"; - SendSQL( "select g.name from groups g, user_group_map u where u.user_id=".$Control{'reporter'}. - " and g.isbuggroup=1 and g.id = u.group_id group by g.name;" ); - $Text .= join( "\n\t", FetchAllSQLData()) . "\n"; - BugMailError( 0, $Text ); - } -} # End of checking groupsets -delete $Control{'groupset'}; - -# ################################################################################### -# Checking is finished -# - -# Check used fields -my @used_fields; - -foreach my $f (@AllowedLabels) { - if ((exists $Control{$f}) && ($Control{$f} !~ /^\s*$/ )) { - push (@used_fields, $f); - } -} - -# -# Creating the query for inserting the bug -# -> this should only be done, if there was no critical error before -if( $critical_err == 0 ) -{ - - my $reply = <<END - - +---------------------------------------------------------------------------+ - B U G Z I L L A - M A I L - I N T E R F A C E - +---------------------------------------------------------------------------+ - - Your Bugzilla Mail Interface request was successfull. - -END -; - - $reply .= "Your Bug-ID is "; - my $reporter = ""; - - my $query = "insert into bugs (\n" . join(",\n", @used_fields ) . - ", bug_status, creation_ts, delta_ts, everconfirmed) values ( "; - - # 'Yuck'. Then again, this whole file should be rewritten anyway... - $query =~ s/product/product_id/; - $query =~ s/component/component_id/; - - my $tmp_reply = "These values were stored by bugzilla:\n"; - my $val; - foreach my $field (@used_fields) { - if( $field eq "groupset" ) { - $query .= $Control{$field} . ",\n"; - } elsif ( $field eq 'product' ) { - $query .= get_product_id($Control{$field}) . ",\n"; - } elsif ( $field eq 'component' ) { - $query .= get_component_id(get_product_id($Control{'product'}), - $Control{$field}) . ",\n"; - } else { - $query .= SqlQuote($Control{$field}) . ",\n"; - } - - $val = $Control{ $field }; - - $val = DBID_to_name( $val ) if( $field =~ /reporter|assigned_to|qa_contact/ ); - - $tmp_reply .= sprintf( " \@%-15s = %-15s\n", $field, $val ); - - if ($field eq "reporter") { - $reporter = $val; - } - } - # - # Display GroupArr - # - $tmp_reply .= sprintf( " \@%-15s = %-15s\n", 'groupset', join(',', keys %GroupArr) ); - - $tmp_reply .= " ... and your error-description !\n"; - - my $comment = $Body; - $comment =~ s/\r\n/\n/g; # Get rid of windows-style line endings. - $comment =~ s/\r/\n/g; # Get rid of mac-style line endings. - $comment = trim($comment); - - SendSQL("SELECT now()"); - my $bug_when = FetchOneColumn(); - - my $ever_confirmed = 0; - my $state = SqlQuote("UNCONFIRMED"); - - SendSQL("SELECT votestoconfirm FROM products WHERE name = " . - SqlQuote($Control{'product'})); - if (!FetchOneColumn()) { - $ever_confirmed = 1; - $state = SqlQuote("NEW"); - } - - $query .= $state . ", \'$bug_when\', \'$bug_when\', $ever_confirmed)\n"; -# $query .= SqlQuote( "NEW" ) . ", now(), " . SqlQuote($comment) . " )\n"; - - SendSQL("SELECT userid FROM profiles WHERE " . - $dbh->sql_istrcmp('login_name', $dbh->quote($reporter))); - my $userid = FetchOneColumn(); - - my $id; - - if( ! $test ) { - SendSQL($query); - - $id = Bugzilla->dbh->bz_last_key('bugs', 'bug_id'); - - my $long_desc_query = "INSERT INTO longdescs SET bug_id=$id, who=$userid, bug_when=\'$bug_when\', thetext=" . SqlQuote($comment); - SendSQL($long_desc_query); - - # Cool, the mail was successful - # system("./processmail", $id, $SenderShort); - } else { - $id = 0xFFFFFFFF; # TEST ! - print "\n-------------------------------------------------------------------------\n"; - print "$query\n"; - } - - # - # Handle GroupArr - # - foreach my $grp (keys %GroupArr) { - if( ! $test) { - SendSQL("INSERT INTO bug_group_map SET bug_id=$id, group_id=$GroupArr{$grp}"); - } else { - print "INSERT INTO bug_group_map SET bug_id=$id, group_id=$GroupArr{$grp}\n"; - } - } - - # - # handle Attachments - # - my $attaches = storeAttachments( $id, $Control{'reporter'} ); - $tmp_reply .= "\n\tYou sent $attaches attachment(s). \n" if( $attaches > 0 ); - - $reply .= $id . "\n\n" . $tmp_reply . "\n" . getWarningText(); - - $entity->purge(); # Removes all temp files - - # - # Send the 'you did it'-reply - Reply( $SenderShort, $Message_ID,"Bugzilla success (ID $id)", $reply ); - - Bugzilla::BugMail::Send($id) if( ! $test); - -} else { - # There were critical errors in the mail - the bug couldn't be inserted. ! -my $errreply = <<END - - +---------------------------------------------------------------------------+ - B U G Z I L L A - M A I L - I N T E R F A C E - +---------------------------------------------------------------------------+ - -END - ; - - $errreply .= getErrorText() . getWarningText() . generateTemplate(); - - Reply( $SenderShort, $Message_ID, "Bugzilla Error", $errreply ); - - # print getErrorText(); - # print getWarningText(); - # print generateTemplate(); -} - - - - - -exit; - diff --git a/contrib/bugmail_help.html b/contrib/bugmail_help.html deleted file mode 100644 index 2d6426510..000000000 --- a/contrib/bugmail_help.html +++ /dev/null @@ -1,223 +0,0 @@ -<HTML> -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> -<!-- - The contents of this file are subject to the Mozilla Public - License Version 1.1 (the "License"); you may not use this file - except in compliance with the License. You may obtain a copy of - the License at http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - implied. See the License for the specific language governing - rights and limitations under the License. - - The Original Code is the Bugzilla Bug Tracking System. - - Contributor(s): Klaas Freitag <Freitag@SuSE.de> ---> - -<HEAD> <TITLE>Bugzilla Mail Interface</TITLE> </HEAD> -<BODY BGCOLOR="#FFFFFF"> -<CENTER><H1>The Bugzilla Mail Interface</H1> -Contributor: <A HREF="mailto:freitag@suse.de">Klaas Freitag</A>, SuSE GmbH -</CENTER> -<P> -The bugzilla Mail interface allows the registered bugzilla users to submit bugs by -sending email with a bug description. This is useful for people, who do not work -inhouse and want to submitt bugs to the bugzilla system. -<p> - - -I know, show me the <A HREF="#examplemail">example-mail !</A> - - -<H2>What do you need to do to submitt a bug by mail ?</H2> -You need to send a email in the described format to the bugmail-user of the -bugzilla-system. This is <A HREF="mailto:our_bugzilla@xyz.com">yourbugzilla@here.com</A> - -You receive a reply mail with the new bug-ID if your request was ok. -If not, you get a mail with -some help on the bugmail system and a specific analysis of your request. -<P> -Please don't refuse to send one or two wrong mails, you will get all the information -you need in the replies, and <I>only</I> in the mail replies. The information on this -page, concerning available products, versions and so on, is not dynamicly generated and -may be old therefore. - -<H1>The Mail Format</H1> -The bugmail needs a special format , which consists of some keywords and suitable -values for them and a description text. Note that the keyword block needs to be -above of the description text. - -<H2>Keywords</H2> -You need to tell bugzilla some properties of the bugs. This is done by keywords, which -start on a new line with a @, followed by the keyword and and equal-sign, followed by a -hopefully valid value. - - -<TABLE BORDER=4 FRAME=box CELLSPACING="5" width=95%> <COLGROUP> <col width="2*"> -<col width="5*"> <col width="1*"> </COLGROUP> - <TR> - <TH>Keyword</TH> - <TH>Value description</TH> - <TH>required and default value</TH> - </TR> - <TR> - <TD>@product</TD> - <TD>The product which has a bug</TD> - <TD>yes. <br> This is the most important information. Many other - fields depend on the product.</TD> - </TR> - <TR> - <TD>@component</TD> - <TD>the desired component which is affected by the bug</TD> - <TD>yes. <br> As the @product, this is a very important - field.</TD> - </TR> - <TR> - <TD>@version</TD> - <TD>The version of the product</TD> - <TD>yes. <br>See @product and @component</TD> - </TR> - <TR> - <TD>@short_desc</TD> - <TD>A summary of your bug report</TD> - <TD>yes. <br>This summary of the error you want to report - describes what happen. You may skip the long description, - but not this summary.<br> - <b>Note:</b>The short description may be given in the mail subject - instead of using the keyword !</TD> - </TR> - <TR> - <TD>@rep_platform</TD> - <TD>The desired platform</TD> - <TD>no.<br>If you don't give a value, this field is set to <I>All</I>.</TD> - </TR> - <TR> - <TD>@bug_severity</TD> - <TD>The severity of the bug</TD> - <TD>no. <br> If you don't give a value, this field is set to - <I>normal</I></TD> - </TR> - <TR> - <TD>@priority</TD> - <TD>The priority of the bug</TD> - <TD>no.<br>If you don't give a value, this field is set to <I>P3</I></TD> - </TR> - <TR> - <TD>@op_sys</TD> - <TD>The operating system</TD> - <TD>no.<br>If you don't give a value, this field is set to <I>Linux</I>.</TD> - </TR> - <TR> - <TD>@assigned_to</TD> - <TD>The one to whom the bug is assigned to</TD> - <TD>no. <br>There is a default assignee for every product/version/component. - He owns the bug by default. The default assignee can only be found if - product, version and component are valid.</TD> - </TR> - <TR> - <TD>@bug_file_loc</TD> - <TD>?</TD> - <TD>no.</TD> - </TR> - <TR> - <TD>@status_whiteboard</TD> - <TD>?</TD> - <TD>no.</TD> - </TR> - <TR> - <TD>@target_milestone</TD> - <TD>?</TD> - <TD>no.</TD> - </TR> - <TR> - <TD>@groupset</TD> - <TD>rules the visibility of the bug.</TD> - <TD>no.<br>This value defaults to the smallest of the available groups, - which is <I>readInternal</I>.</TD> - </TR> - <TR> - <TD>@qa_contact</TD> - <TD>the quality manager for the product</TD> - <TD>no.<br>This value can be retrieved from product, component and - version</TD> - </TR> - -</TABLE> -<H2>Valid values</H2> -Give string values for the most keys above. Some keywords require special values:<br> -<ol> -<li>E-Mail addresses: If you want to set the qa-contact, specify an email-address for @qa_contact. The email must be known by bugzilla of course.</li> -<li>Listvalues: Most of the values have to be one of a list of valid values. Try by sending -a mail and read the reply. Skip fields if you don't get help for them unless you don't know -which values you may choose.</li> -<li>free Text: The descriptions may be free text. </li> -<li>Special: The field groupset may be specified in different in three different kinds: - <ol> - <li> A plain numeric way, which is one usually huge number, e. g. <I>65536</I></li> - <li> a string with added numbers e.g. <I>65536+131072</I></li> - <li> a string list, e.g. <I>ReadInternal, ReadBeta </I></li> - </ol> -</li> -</ol> - -<p> - -But most of them need <b>valid</b> values. -<p> -Sorry, you will not find lists of valid products, components and the other stuff -here. Send a mail to with any text, and you will get a list of valid keywords in the reply. - -<p> -Some of the values must be choosen from a list:<br> -<ol> - <li>bug_severity: blocker, critical, major, normal, minor, trivial, enhancement</li> - <li>op_sys: Linux </li> - <li>priority: P1, P2, P3, P4, P5</li> - <li>rep_platform: All, i386, AXP, i686, Other</li></ol> - - -<p> - -After you have specified the required keywords and maybe some other value, you may -describe your bug. You don't need a keyword for starting your bug description. All -text which follows the keyword block is handled as long description of the bug. -<p> - -The bugmail interface is able to find required information by itself. E.g. if you specify -a product which has exactly one component, this component will be found by the interface -automatically. - -<H1>Attachments</H1> - -The mail interface is able to cope with MIME-attachments. -People could for example add a logfile as a mail attachment, and it will appear in -bugzilla as attachment. A comment for the attachment should be added, it will describe -the attachment in bugzilla. - -<H1><A NAME="examplemail">Example Mail</A></H1> - -See the example of the mail <b>body</b> (Don't forget to specify the short description -in the mail subject):<hr><pre> - - @product = Bugzilla - @component = general - @version = All - @groupset = ReadWorld ReadPartners - @op_sys = Linux - @priority = P3 - @rep_platform = i386 - - - This is the description of the bug I found. It is not neccessary to start - it with a keyword. - - Note: The short_description is neccessary and may be given with the keyword - @short_description or will be retrieved from the mail subject. - - -</pre><hr> - -</BODY> -</HTML> diff --git a/contrib/bugzilla-submit/CVS/Entries b/contrib/bugzilla-submit/CVS/Entries index b5f76487e..d90103e7d 100644 --- a/contrib/bugzilla-submit/CVS/Entries +++ b/contrib/bugzilla-submit/CVS/Entries @@ -1,5 +1,5 @@ -/README/1.2/Wed Dec 10 23:36:21 2003//TBUGZILLA-2_22_3 -/bugdata.txt/1.2/Fri Jan 16 22:26:49 2004//TBUGZILLA-2_22_3 -/bugzilla-submit/1.6/Fri Jul 16 03:56:35 2004//TBUGZILLA-2_22_3 -/bugzilla-submit.xml/1.7/Mon Apr 11 14:23:32 2005//TBUGZILLA-2_22_3 +/README/1.2/Wed Dec 10 23:36:21 2003//TBUGZILLA-3_0 +/bugdata.txt/1.2/Fri Jan 16 22:26:49 2004//TBUGZILLA-3_0 +/bugzilla-submit/1.6/Fri Jul 16 03:56:35 2004//TBUGZILLA-3_0 +/bugzilla-submit.xml/1.7/Mon Apr 11 14:23:32 2005//TBUGZILLA-3_0 D diff --git a/contrib/bugzilla-submit/CVS/Tag b/contrib/bugzilla-submit/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/contrib/bugzilla-submit/CVS/Tag +++ b/contrib/bugzilla-submit/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/contrib/bugzilla.procmailrc b/contrib/bugzilla.procmailrc deleted file mode 100644 index 36656b4d2..000000000 --- a/contrib/bugzilla.procmailrc +++ /dev/null @@ -1,30 +0,0 @@ -:0 fhw -| formail -I "From " -a "From " - -BUGZILLA_HOME=/home/bugzilla/WEB/bugzilla/contrib - -:0 -* ^Subject: .*\[Bug .*\] -RESULT=|(cd $BUGZILLA_HOME && ./bugzilla_email_append.pl) - - -# Feed mail to stdin of bug_email.pl -:0 Ec -#* !^Subject: .*[Bug .*] -RESULT=|(cd $BUGZILLA_HOME && ./bug_email.pl ) - -# write result to a logfile -:0 c -|echo `date '+%d.%m.%y %H:%M: '` $RESULT >> $HOME/bug_email.log - - -:0 c -|echo "----------------------------------" >> $HOME/bug_email.log - -:0 c -$HOME/bug_email.log - -# Move mail to the inbox -:0 -$HOME/Mail/INBOX - diff --git a/contrib/bugzilla_email_append.pl b/contrib/bugzilla_email_append.pl deleted file mode 100755 index abf2c0b78..000000000 --- a/contrib/bugzilla_email_append.pl +++ /dev/null @@ -1,197 +0,0 @@ -#!/usr/bin/perl -w -# -*- Mode: perl; indent-tabs-mode: nil -*- - -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. - -# The purpose of this script is to take an email message, which -# specifies a bugid and append it to the bug as part of the longdesc -# table - -# Contributor : Seth M. Landsman <seth@dworkin.net> - -# 03/15/00 : Initial version by SML -# 03/15/00 : processmail gets called - -# Email subject must be of format : -# .* Bug ### .* -# replying to a typical bugzilla email should be valid - -# TODO : -# 1. better way to get the body text (I don't know what dump_entity() is -# actually doing - -use strict; -use MIME::Parser; - -BEGIN { - chdir ".."; # this script lives in contrib, change to main - push @INC, "contrib"; - push @INC, "."; # this script lives in contrib -} - -require "globals.pl"; -use BugzillaEmail; -use Bugzilla::Config qw(:DEFAULT $datadir); -use Bugzilla::BugMail; - -my $dbh = Bugzilla->dbh; - -# Create a new MIME parser: -my $parser = new MIME::Parser; - -my $Comment = ""; - -# Create and set the output directory: -# FIXME: There should be a $BUGZILLA_HOME variable (SML) -(-d "$datadir/mimedump-tmp") or mkdir "$datadir/mimedump-tmp",0755 or die "mkdir: $!"; -(-w "$datadir/mimedump-tmp") or die "can't write to directory"; - -$parser->output_dir("$datadir/mimedump-tmp"); - -# Read the MIME message: -my $entity = $parser->read(\*STDIN) or die "couldn't parse MIME stream"; -$entity->remove_sig(10); # Removes the signature in the last 10 lines - -# Getting values from parsed mail -my $Sender = $entity->get( 'From' ); -$Sender ||= $entity->get( 'Reply-To' ); -my $Message_ID = $entity->get( 'Message-Id' ); - -die (" *** Can't find Sender-address in sent mail ! ***\n" ) unless defined( $Sender ); -chomp( $Sender ); -chomp( $Message_ID ); - -print "Dealing with the sender $Sender\n"; - -my $SenderShort = $Sender; -$SenderShort =~ s/^.*?([a-zA-Z0-9_.-]+?\@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+).*$/$1/; - -$SenderShort = findUser($SenderShort); - -print "SenderShort is $SenderShort\n"; -if (!defined($SenderShort)) { - $SenderShort = $Sender; - $SenderShort =~ s/^.*?([a-zA-Z0-9_.-]+?\@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+).*$/$1/; -} -print "The sendershort is now $SenderShort\n"; - -if (!defined($SenderShort)) { - DealWithError("No such user $SenderShort exists."); -} - -my $Subject = $entity->get('Subject'); -print "The subject is $Subject\n"; - -my ($bugid) = ($Subject =~ /\[Bug ([\d]+)\]/); -print "The bugid is $bugid\n"; - -# make sure the bug exists - -SendSQL("SELECT bug_id FROM bugs WHERE bug_id = $bugid;"); -my $found_id = FetchOneColumn(); -print "Did we find the bug? $found_id-\n"; -if (!defined($found_id)) { - DealWithError("Bug $bugid does not exist"); -} - -# get the user id -SendSQL("SELECT userid FROM profiles WHERE " . - $dbh->sql_istrcmp('login_name', $dbh->quote($SenderShort))); -my $userid = FetchOneColumn(); -if (!defined($userid)) { - DealWithError("Userid not found for $SenderShort"); -} - -# parse out the text of the message -dump_entity($entity); - -# Get rid of the bug id -$Subject =~ s/\[Bug [\d]+\]//; -#my $Comment = "This is only a test ..."; -my $Body = "Subject: " . $Subject . "\n" . $Comment; - -# shove it in the table -my $long_desc_query = "INSERT INTO longdescs SET bug_id=$found_id, who=$userid, bug_when=NOW(), thetext=" . SqlQuote($Body) . ";"; -SendSQL($long_desc_query); - -Bugzilla::BugMail::Send( $found_id, { changer => $SenderShort } ); - -sub DealWithError { - my ($reason) = @_; - print $reason . "\n"; - exit 100; -} - -# Yanking this wholesale from bug_email, 'cause I know this works. I'll -# figure out what it really does later -#------------------------------ -# -# dump_entity ENTITY, NAME -# -# Recursive routine for parsing a mime coded mail. -# One mail may contain more than one mime blocks, which need to be -# handled. Therefore, this function is called recursively. -# -# It gets the for bugzilla important information from the mailbody and -# stores them into the global attachment-list @attachments. The attachment-list -# is needed in storeAttachments. -# -sub dump_entity { - my ($entity, $name) = @_; - defined($name) or $name = "'anonymous'"; - my $IO; - - - # Output the body: - my @parts = $entity->parts; - if (@parts) { # multipart... - my $i; - foreach $i (0 .. $#parts) { # dump each part... - dump_entity($parts[$i], ("$name, part ".(1+$i))); - } - } else { # single part... - - # Get MIME type, and display accordingly... - my $msg_part = $entity->head->get( 'Content-Disposition' ); - - $msg_part ||= ""; - - my ($type, $subtype) = split('/', $entity->head->mime_type); - my $body = $entity->bodyhandle; - my ($data, $on_disk ); - - if( $msg_part =~ /^attachment/ ) { - # Attached File - my $des = $entity->head->get('Content-Description'); - $des ||= ""; - - if( defined( $body->path )) { # Data is on disk - $on_disk = 1; - $data = $body->path; - - } else { # Data is in core - $on_disk = 0; - $data = $body->as_string; - } -# push ( @attachments, [ $data, $entity->head->mime_type, $on_disk, $des ] ); - } else { - # Real Message - if ($type =~ /^(text|message)$/) { # text: display it... - if ($IO = $body->open("r")) { - $Comment .= $_ while (defined($_ = $IO->getline)); - $IO->close; - } else { # d'oh! - print "$0: couldn't find/open '$name': $!"; - } - } else { print "Oooops - no Body !\n"; } - } - } -} diff --git a/contrib/bz_webservice_demo.pl b/contrib/bz_webservice_demo.pl new file mode 100755 index 000000000..aa92d1dd9 --- /dev/null +++ b/contrib/bz_webservice_demo.pl @@ -0,0 +1,322 @@ +#!/usr/bin/perl -w +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the “License”); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an “AS +# IS” basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Marc Schumann <wurblzap@gmail.com> +# Mads Bondo Dydensborg <mbd@dbc.dk> + +=head1 NAME + +bz_webservice_demo.pl - Show how to talk to Bugzilla via XMLRPC + +=head1 SYNOPSIS + +C<bz_webservice_demo.pl [options]> + +C<bz_webservice_demo.pl --help> for detailed help + +=cut + +use strict; +use Getopt::Long; +use Pod::Usage; +use File::Basename qw(dirname); +use File::Spec; +use HTTP::Cookies; +use XMLRPC::Lite; + +# If you want, say “use Bugzilla::WebService::Constants” here to get access +# to Bugzilla's web service error code constants. +# If you do this, remember to issue a “use lib” pointing to your Bugzilla +# installation directory, too. + +my $help; +my $Bugzilla_uri; +my $Bugzilla_login; +my $Bugzilla_password; +my $Bugzilla_remember; +my $bug_id; +my $product_name; +my $create_file_name; + +GetOptions('help|h|?' => \$help, + 'uri=s' => \$Bugzilla_uri, + 'login:s' => \$Bugzilla_login, + 'password=s' => \$Bugzilla_password, + 'rememberlogin!' => \$Bugzilla_remember, + 'bug_id:s' => \$bug_id, + 'product_name:s' => \$product_name, + 'create:s' => \$create_file_name + ) or pod2usage({'-verbose' => 0, '-exitval' => 1}); + +=head1 OPTIONS + +=over + +=item --help, -h, -? + +Print a short help message and exit. + +=item --uri + +URI to Bugzilla's C<xmlrpc.cgi> script, along the lines of +C<http://your.bugzilla.installation/path/to/bugzilla/xmlrpc.cgi>. + +=item --login + +Bugzilla login name. Specify this together with B<--password> in order to log in. + +Specify this without a value in order to log out. + +=item --password + +Bugzilla password. Specify this together with B<--login> in order to log in. + +=item --rememberlogin + +Gives access to Bugzilla's “Bugzilla_remember” option. +Specify this option while logging in to do the same thing as ticking the +C<Bugzilla_remember> box on Bugilla's log in form. +Don't specify this option to do the same thing as unchecking the box. + +See Bugzilla's rememberlogin parameter for details. + +=item --bug_id + +Pass a bug ID to have C<bz_webservice_demo.pl> do some bug-related test calls. + +=item --product_name + +Pass a product name to have C<bz_webservice_demo.pl> do some product-related +test calls. + +=item --create + +Specify a file that contains settings for the creating of a new bug. + +=back + +=head1 DESCRIPTION + +=cut + +pod2usage({'-verbose' => 1, '-exitval' => 0}) if $help; +_syntaxhelp('URI unspecified') unless $Bugzilla_uri; + +# We will use this variable for SOAP call results. +my $soapresult; + +# We will use this variable for function call results. +my $result; + +# Open our cookie jar. We save it into a file so that we may re-use cookies +# to avoid the need of logging in every time. You're encouraged, but not +# required, to do this in your applications, too. +# Cookies are only saved if Bugzilla's rememberlogin parameter is set to one of +# - on +# - defaulton (and you didn't pass 0 as third parameter to User.login) +# - defaultoff (and you passed 1 as third parameter to User.login) +my $cookie_jar = + new HTTP::Cookies('file' => File::Spec->catdir(dirname($0), 'cookies.txt'), + 'autosave' => 1); + +=head2 Initialization + +Using the XMLRPC::Lite class, you set up a proxy, as shown in this script. +Bugzilla's XMLRPC URI ends in C<xmlrpc.cgi>, so your URI looks along the lines +of C<http://your.bugzilla.installation/path/to/bugzilla/xmlrpc.cgi>. + +=cut + +my $proxy = XMLRPC::Lite->proxy($Bugzilla_uri, + 'cookie_jar' => $cookie_jar); + +=head2 Checking Bugzilla's version + +To make sure the Bugzilla you're connecting to supports the methods you wish to +call, you may want to compare the result of C<Bugzilla.version> to the +minimum required version your application needs. + +=cut + +$soapresult = $proxy->call('Bugzilla.version'); +_die_on_fault($soapresult); +print 'Connecting to a Bugzilla of version ' . $soapresult->result()->{version} . ".\n"; + +=head2 Checking Bugzilla's timezone + +To make sure that you understand the dates and times that Bugzilla returns to you, you may want to call C<Bugzilla.timezone>. + +=cut + +$soapresult = $proxy->call('Bugzilla.timezone'); +_die_on_fault($soapresult); +print 'Bugzilla\'s timezone is ' . $soapresult->result()->{timezone} . ".\n"; + +=head2 Logging In and Out + +=head3 Using Bugzilla's Environment Authentication + +Use a +C<http://login:password@your.bugzilla.installation/path/to/bugzilla/xmlrpc.cgi> +style URI. +You don't log out if you're using this kind of authentication. + +=head3 Using Bugzilla's CGI Variable Authentication + +Use the C<User.login> and C<User.logout> calls to log in and out, as shown +in this script. + +The C<Bugzilla_remember> parameter is optional. +If omitted, Bugzilla's defaults apply (as specified by its C<rememberlogin> +parameter). + +Bugzilla hands back cookies you'll need to pass along during your work calls. + +=cut + +if (defined($Bugzilla_login)) { + if ($Bugzilla_login ne '') { + # Log in. + $soapresult = $proxy->call('User.login', + { login => $Bugzilla_login, + password => $Bugzilla_password, + remember => $Bugzilla_remember } ); + _die_on_fault($soapresult); + print "Login successful.\n"; + } + else { + # Log out. + $soapresult = $proxy->call('User.logout'); + _die_on_fault($soapresult); + print "Logout successful.\n"; + } +} + +=head2 Retrieving Bug Information + +Call C<Bug.get_bug> with the ID of the bug you want to know more of. +The call will return a C<Bugzilla::Bug> object. + +=cut + +if ($bug_id) { + $soapresult = $proxy->call('Bug.get_bugs', { ids => [$bug_id] }); + _die_on_fault($soapresult); + $result = $soapresult->result; + my $bug = $result->{bugs}->[0]; + foreach (keys(%$bug)) { + print "$_: $$bug{$_}\n"; + } +} + +=head2 Retrieving Product Information + +Call C<Product.get_product> with the name of the product you want to know more +of. +The call will return a C<Bugzilla::Product> object. + +=cut + +if ($product_name) { + $soapresult = $proxy->call('Product.get_product', $product_name); + _die_on_fault($soapresult); + $result = $soapresult->result; + + if (ref($result) eq 'HASH') { + foreach (keys(%$result)) { + print "$_: $$result{$_}\n"; + } + } + else { + print "$result\n"; + } +} + +=head2 Creating A Bug + +Call C<Bug.create> with the settings read from the file indicated on +the command line. The file must contain a valid anonymous hash to use +as argument for the call to C<Bug.create>. +The call will return a hash with a bug id for the newly created bug. + +=cut + +if ($create_file_name) { + $soapresult = $proxy->call('Bug.create', do "$create_file_name" ); + _die_on_fault($soapresult); + $result = $soapresult->result; + + if (ref($result) eq 'HASH') { + foreach (keys(%$result)) { + print "$_: $$result{$_}\n"; + } + } + else { + print "$result\n"; + } + +} + + + +=head1 NOTES + +=head2 Character Set Encoding + +Make sure that your application either uses the same character set +encoding as Bugzilla does, or that it converts correspondingly when using the +web service API. +By default, Bugzilla uses UTF-8 as its character set encoding. + +=head2 Format For Create File + +The create format file is a piece of Perl code, that should look something like +this: + + { + product => "TestProduct", + component => "TestComponent", + summary => "TestBug - created from bz_webservice_demo.pl", + version => "unspecified", + description => "This is a description of the bug... hohoho", + op_sys => "All", + platform => "All", + priority => "P4", + severity => "normal" + }; + +=head1 SEE ALSO + +There are code comments in C<bz_webservice_demo.pl> which might be of further +help to you. + +=cut + +sub _die_on_fault { + my $soapresult = shift; + + if ($soapresult->fault) { + my ($package, $filename, $line) = caller; + die $soapresult->faultcode . ' ' . $soapresult->faultstring . + " in SOAP call near $filename line $line.\n"; + } +} + +sub _syntaxhelp { + my $msg = shift; + + print "Error: $msg\n"; + pod2usage({'-verbose' => 0, '-exitval' => 1}); +} diff --git a/contrib/bzdbcopy.pl b/contrib/bzdbcopy.pl index ac3ba8248..ebfe3e45b 100755 --- a/contrib/bzdbcopy.pl +++ b/contrib/bzdbcopy.pl @@ -1,36 +1,26 @@ #!/usr/bin/perl -w # -# bzdbcopy.pl - Copies data from one Bugzilla database to another. +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ # -# Author: Max Kanat-Alexander <mkanat@bugzilla.org> +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. # -# The intended use of this script is to copy data from an installation -# running on one DB platform to an installation running on another -# DB platform. +# The Original Code is the Bugzilla Bug Tracking System. # -# It must be run from the directory containing your Bugzilla installation. -# That means if this script is in the contrib/ directory, you should -# be running it as: ./contrib/bzdbcopy.pl -# -# Note: Both schemas must already exist and be IDENTICAL. (That is, -# they must have both been created/updated by the same version of -# checksetup.pl.) This script will DESTROY ALL CURRENT DATA in the -# target database. -# -# Both Schemas must be at least from Bugzilla 2.19.3, but if you're -# running a Bugzilla from before 2.20rc2, you'll need the patch at: -# https://bugzilla.mozilla.org/show_bug.cgi?id=300311 in order to -# be able to run this script. -# -# Before you using it, you have to correctly set all the variables -# in the "User-Configurable Settings" section, below. The "SOURCE" -# settings are for the database you're copying from, and the "TARGET" -# settings are for the database you're copying to. The DB_TYPE is -# the name of a DB driver from the Bugzilla/DB/ directory. +# The Initial Developer of the Original Code is Everything Solved. +# Portions created by Everything Solved are Copyright (C) 2006 +# Everything Solved. All Rights Reserved. # +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> use strict; use lib "."; +use Bugzilla; use Bugzilla::DB; use Bugzilla::Util; @@ -178,4 +168,38 @@ $target_db->commit; print "All done! Make sure to run checksetup on the new DB.\n"; $source_db->disconnect; $target_db->disconnect; + 1; + +__END__ + +=head1 NAME + +bzdbcopy.pl - Copies data from one Bugzilla database to another. + +=head1 DESCRIPTION + +The intended use of this script is to copy data from an installation +running on one DB platform to an installation running on another +DB platform. + +It must be run from the directory containing your Bugzilla installation. +That means if this script is in the contrib/ directory, you should +be running it as: C<./contrib/bzdbcopy.pl> + +Note: Both schemas must already exist and be B<IDENTICAL>. (That is, +they must have both been created/updated by the same version of +checksetup.pl.) This script will B<DESTROY ALL CURRENT DATA> in the +target database. + +Both Schemas must be at least from Bugzilla 2.19.3, but if you're +running a Bugzilla from before 2.20rc2, you'll need the patch at: +L<http://bugzilla.mozilla.org/show_bug.cgi?id=300311> in order to +be able to run this script. + +Before you using it, you have to correctly set all the variables +in the "User-Configurable Settings" section at the top of the script. +The C<SOURCE> settings are for the database you're copying from, and +the C<TARGET> settings are for the database you're copying to. The +C<DB_TYPE> is the name of a DB driver from the F<Bugzilla/DB/> directory. + diff --git a/contrib/cmdline/CVS/Entries b/contrib/cmdline/CVS/Entries index f71789a07..d59c96443 100644 --- a/contrib/cmdline/CVS/Entries +++ b/contrib/cmdline/CVS/Entries @@ -1,8 +1,8 @@ -/bugcount/1.1/Thu Jan 27 19:42:34 2005//TBUGZILLA-2_22_3 -/bugids/1.1/Thu Jan 27 19:42:34 2005//TBUGZILLA-2_22_3 -/buglist/1.2/Thu Jan 27 19:42:34 2005//TBUGZILLA-2_22_3 -/bugs/1.2/Thu Jan 27 19:42:34 2005//TBUGZILLA-2_22_3 -/bugslink/1.1/Thu Jan 27 19:42:34 2005//TBUGZILLA-2_22_3 -/makequery/1.1/Thu Jan 27 19:42:34 2005//TBUGZILLA-2_22_3 -/query.conf/1.3/Fri Aug 26 23:11:32 2005//TBUGZILLA-2_22_3 +/bugcount/1.1/Thu Jan 27 19:42:34 2005//TBUGZILLA-3_0 +/bugids/1.1/Thu Jan 27 19:42:34 2005//TBUGZILLA-3_0 +/buglist/1.2/Thu Jan 27 19:42:34 2005//TBUGZILLA-3_0 +/bugs/1.2/Thu Jan 27 19:42:34 2005//TBUGZILLA-3_0 +/bugslink/1.1/Thu Jan 27 19:42:34 2005//TBUGZILLA-3_0 +/makequery/1.1/Thu Jan 27 19:42:34 2005//TBUGZILLA-3_0 +/query.conf/1.3/Fri Aug 26 23:11:32 2005//TBUGZILLA-3_0 D diff --git a/contrib/cmdline/CVS/Tag b/contrib/cmdline/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/contrib/cmdline/CVS/Tag +++ b/contrib/cmdline/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/contrib/gnats2bz.pl b/contrib/gnats2bz.pl index c343f5750..95ae32ad9 100644 --- a/contrib/gnats2bz.pl +++ b/contrib/gnats2bz.pl @@ -649,7 +649,7 @@ sub write_bugs { } } elsif ($pr_data{"State"} eq "suspended") { $bug_status = "RESOLVED"; - $resolution = "LATER"; + $resolution = "WONTFIX"; } else { $bug_status = "NEW"; $resolution = ""; @@ -861,8 +861,6 @@ sub map_username_to_realname() { return(""); } -# This routine was copied from globals.pl which was largely copied -# from Mysql.pm. sub detaint_string { my ($str) = @_; $str =~ m/^(.*)$/s; diff --git a/contrib/gnatsparse/CVS/Entries b/contrib/gnatsparse/CVS/Entries index 2b540b98a..0e4fc9f93 100644 --- a/contrib/gnatsparse/CVS/Entries +++ b/contrib/gnatsparse/CVS/Entries @@ -1,5 +1,5 @@ -/README/1.2/Tue Mar 23 17:59:11 2004//TBUGZILLA-2_22_3 -/gnatsparse.py/1.3.2.1/Mon Jun 19 15:58:20 2006//TBUGZILLA-2_22_3 -/magic.py/1.1/Sun Mar 21 21:32:16 2004//TBUGZILLA-2_22_3 -/specialuu.py/1.1/Sun Mar 21 21:32:16 2004//TBUGZILLA-2_22_3 +/README/1.2/Tue Mar 23 17:59:11 2004//TBUGZILLA-3_0 +/gnatsparse.py/1.4/Mon Jun 19 15:58:33 2006//TBUGZILLA-3_0 +/magic.py/1.1/Sun Mar 21 21:32:16 2004//TBUGZILLA-3_0 +/specialuu.py/1.1/Sun Mar 21 21:32:16 2004//TBUGZILLA-3_0 D diff --git a/contrib/gnatsparse/CVS/Tag b/contrib/gnatsparse/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/contrib/gnatsparse/CVS/Tag +++ b/contrib/gnatsparse/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/contrib/merge-users.pl b/contrib/merge-users.pl index c8537c661..c5d48737a 100644 --- a/contrib/merge-users.pl +++ b/contrib/merge-users.pl @@ -47,7 +47,7 @@ merge-users.pl - Merge two user accounts. use lib qw(.); use Bugzilla; -use Bugzilla::Config qw(:DEFAULT); +use Bugzilla::Constants; use Bugzilla::Util; use Getopt::Long; @@ -61,17 +61,6 @@ my $result = GetOptions("help|?" => \$help); pod2usage(0) if $help; -# We require Bugzilla 2.20 or higher (including 2.22+). -my $current_version = $Bugzilla::Config::VERSION; -if ($current_version =~ /^2\.2[0123]/) { - print "OK, you are using Bugzilla $current_version\n" -} -else { - die "You are using Bugzilla $current_version but Bugzilla " . - "2.20 - 2.23 is required.\n"; -} - - # Make sure accounts were specified on the command line and exist. my $old = $ARGV[0] || die "You must specify an old user account.\n"; my $old_id; diff --git a/contrib/recode.pl b/contrib/recode.pl new file mode 100755 index 000000000..49e824f6d --- /dev/null +++ b/contrib/recode.pl @@ -0,0 +1,385 @@ +#!/usr/bin/perl -w +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Everything Solved. +# Portions created by Everything Solved are Copyright (C) 2006 +# Everything Solved. All Rights Reserved. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + +use strict; +# Allow the script to be run from contrib or as contrib/recode.pl +use lib '..'; + +use Bugzilla; +use Bugzilla::Constants; + +use Digest::MD5 qw(md5_base64); +use Encode qw(encode decode resolve_alias is_utf8); +use Encode::Guess; +use Getopt::Long; +use Pod::Usage; + +############# +# Constants # +############# + +use constant IGNORE_ENCODINGS => qw(utf8 ascii iso-8859-1); + +use constant MAX_STRING_LEN => 25; + +# For certain tables, we can't automatically determine their Primary Key. +# So, we specify it here as a string. +use constant SPECIAL_KEYS => { + bugs_activity => 'bug_id,bug_when,fieldid', + profile_setting => 'user_id,setting_name', + profiles_activity => 'userid,profiles_when,fieldid', + setting_value => 'name,value', + # longdescs didn't used to have a PK, before 2.20. + longdescs => 'bug_id,bug_when', + # The 2.16 versions table lacked a PK + versions => 'product_id,value', + # These are all for earlier versions of Bugzilla. On a modern + # version of Bugzilla, this script will ignore these (thanks to + # code further down). + components => 'program,value', + products => 'product', +}; + +############### +# Subroutines # +############### + +# "truncate" is a file operation in perl, so we can't use that name. +sub trunc { + my ($str) = @_; + my $truncated = substr($str, 0, MAX_STRING_LEN); + if (length($truncated) ne length($str)) { + $truncated .= '...'; + } + return $truncated; +} + +sub do_guess { + my ($data) = @_; + + my $encoding = detect($data); + $encoding = resolve_alias($encoding) if $encoding; + + # Encode::Detect is bad at detecting certain charsets, but Encode::Guess + # is better at them. Here's the details: + + # shiftjis, big5-eten, euc-kr, and euc-jp: (Encode::Detect + # tends to accidentally mis-detect UTF-8 strings as being + # these encodings.) + my @utf8_accidental = qw(shiftjis big5-eten euc-kr euc-jp); + if ($encoding && grep($_ eq $encoding, @utf8_accidental)) { + $encoding = undef; + my $decoder = guess_encoding($data, @utf8_accidental); + $encoding = $decoder->name if ref $decoder; + } + + # Encode::Detect sometimes mis-detects various ISO encodings as iso-8859-8, + # but Encode::Guess can usually tell which one it is. + if ($encoding && $encoding eq 'iso-8859-8') { + my $decoded_as = guess_iso($data, 'iso-8859-8', + # These are ordered this way because it gives the most + # accurate results. + qw(iso-8859-7 iso-8859-2)); + $encoding = $decoded_as if $decoded_as; + } + + return $encoding; +} + +# A helper for do_guess. +sub guess_iso { + my ($data, $versus, @isos) = @_; + + my $encoding; + foreach my $iso (@isos) { + my $decoder = guess_encoding($data, ($iso, $versus)); + if (ref $decoder) { + $encoding = $decoder->name if ref $decoder; + last; + } + } + return $encoding; +} + +sub is_valid_utf8 { + my ($str) = @_; + Encode::_utf8_on($str); + return is_utf8($str, 1); +} + +############### +# Main Script # +############### + +my %switch; +GetOptions(\%switch, 'dry-run', 'guess', 'charset=s', 'show-failures', + 'overrides=s', 'help|h'); + +pod2usage({ -verbose => 1 }) if $switch{'help'}; + +# You have to specify at least one of these switches. +pod2usage({ -verbose => 0 }) if (!$switch{'charset'} && !$switch{'guess'}); + +if (exists $switch{'charset'}) { + $switch{'charset'} = resolve_alias($switch{'charset'}) + || die "'$switch{charset}' is not a valid charset."; +} + +if ($switch{'guess'}) { + # Encode::Detect::Detector doesn't seem to return a true value. + # So we have to check if we can run detect. + if (!eval { require Encode::Detect::Detector }) { + my $root = ROOT_USER; + print STDERR <<EOT; +Using --guess requires that Encode::Detect be installed. To install +Encode::Detect, first download it from: + + http://search.cpan.org/dist/Encode-Detect/ + +Then, unpack it into its own directory and run the following commands +in that directory, as $root: + + ./Build.PL + ./Build + ./Build install + +EOT + exit; + } + + import Encode::Detect::Detector qw(detect); +} + +my %overrides; +if (exists $switch{'overrides'}) { + my $file = new IO::File($switch{'overrides'}, 'r') + || die "$switch{overrides}: $!"; + my @lines = $file->getlines(); + $file->close(); + foreach my $line (@lines) { + chomp($line); + my ($digest, $encoding) = split(' ', $line); + $overrides{$digest} = $encoding; + } +} + +my $dbh = Bugzilla->dbh; + +if ($dbh->isa('Bugzilla::DB::Mysql')) { + # Get the actual current encoding of the DB. + my $collation_data = $dbh->selectrow_arrayref( + "SHOW VARIABLES LIKE 'character_set_database'"); + my $db_charset = $collation_data->[1]; + # Set our connection encoding to *that* encoding, so that MySQL + # correctly accepts our changes. + $dbh->do("SET NAMES $db_charset"); + # Make the database give us raw bytes. + $dbh->do('SET character_set_results = NULL') +} + +$dbh->begin_work; + +foreach my $table ($dbh->bz_table_list_real) { + my @columns = $dbh->bz_table_columns($table); + + my $pk = SPECIAL_KEYS->{$table}; + if ($pk) { + # Assure that we're on a version of Bugzilla where those keys + # actually exist. + foreach my $column (split ',', $pk) { + $pk = undef if !$dbh->bz_column_info($table, $column); + } + } + + # Figure out the primary key. + foreach my $column (@columns) { + my $def = $dbh->bz_column_info($table, $column); + $pk = $column if $def->{PRIMARYKEY}; + } + # If there's no PK, it's defined by a UNIQUE index. + if (!$pk) { + foreach my $column (@columns) { + my $index = $dbh->bz_index_info($table, "${table}_${column}_idx"); + if ($index && ref($index) eq 'HASH') { + $pk = join(',', @{$index->{FIELDS}}) + if $index->{TYPE} eq 'UNIQUE'; + } + } + } + + foreach my $column (@columns) { + my $def = $dbh->bz_column_info($table, $column); + # If this is a text column, it may need work. + if ($def->{TYPE} =~ /text|char/i) { + # If there's still no PK, we're upgrading from 2.14 or earlier. + # We can't reliably determine the PK (or at least, I don't want to + # maintain code to record what the PK was at all points in history). + # So instead we just use the field itself. + $pk = $column if !$pk; + + print "Converting $table.$column...\n"; + my $sth = $dbh->prepare("SELECT $column, $pk FROM $table + WHERE $column IS NOT NULL + AND $column != ''"); + + my @pk_array = map {"$_ = ?"} split(',', $pk); + my $pk_where = join(' AND ', @pk_array); + my $update_sth = $dbh->prepare( + "UPDATE $table SET $column = ? WHERE $pk_where"); + + $sth->execute(); + + while (my @result = $sth->fetchrow_array) { + my $data = shift @result; + my $digest = md5_base64($data); + + my @primary_keys = reverse split(',', $pk); + # We copy the array so that we can pop things from it without + # affecting the original. + my @pk_data = @result; + my $pk_line = join (', ', + map { "$_ = " . pop @pk_data } @primary_keys); + + my $encoding; + if ($switch{'guess'}) { + $encoding = do_guess($data); + + # We only show failures if they don't appear to be + # ASCII. + if ($switch{'show-failures'} && !$encoding + && !is_valid_utf8($data)) + { + my $truncated = trunc($data); + print "Row: [$pk_line]\n", + "Failed to guess: Key: $digest", + " DATA: $truncated\n"; + } + + # If we fail a guess, and the data is valid UTF-8, + # just assume we failed because it's UTF-8. + next if is_valid_utf8($data); + } + + # If we couldn't detect the charset (or were instructed + # not to try), we fall back to --charset. If there's no + # fallback, we just do nothing. + if (!$encoding && $switch{'charset'}) { + $encoding = $switch{'charset'}; + } + + $encoding = $overrides{$digest} if $overrides{$digest}; + + # We only fix it if it's not ASCII or UTF-8 already. + if ($encoding && !grep($_ eq $encoding, IGNORE_ENCODINGS)) { + my $decoded = encode('utf8', decode($encoding, $data)); + if ($switch{'dry-run'} && $data ne $decoded) { + print "Row: [$pk_line]\n", + "From: [" . trunc($data) . "] Key: $digest\n", + "To: [" . trunc($decoded) . "]", + " Encoding : $encoding\n"; + } + else { + $update_sth->execute($decoded, @result); + } + } + } # while (my @result = $sth->fetchrow_array) + } # if ($column->{TYPE} =~ /text|char/i) + } # foreach my $column (@columns) +} + +$dbh->commit; + +__END__ + +=head1 NAME + +recode.pl - Converts a database from one encoding (or multiple encodings) +to UTF-8. + +=head1 SYNOPSIS + + contrib/recode.pl [--guess [--show-failures]] [--charset=iso-8859-2] + [--overrides=file_name] + + --dry-run Don't modify the database. + + --charset Primary charset your data is currently in. This can be + optionally omitted if you do --guess. + + --guess Try to guess the charset of the data. + + --show-failures If we fail to guess, show where we failed. + + --overrides Specify a file containing overrides. See --help + for more info. + + --help Display detailed help. + + If you aren't sure what to do, try: + + contrib/recode.pl --guess --charset=cp1252 + +=head1 OPTIONS + +=over + +=item --dry-run + +Don't modify the database, just print out what the conversions will be. + +recode.pl will print out a Key for each item. You can use this in the +overrides file, described below. + +=item --guess + +If your database is in multiple different encodings, specify this switch +and recode.pl will do its best to determine the original charset of the data. +The detection is usually very reliable. + +If recode.pl cannot guess the charset, it will leave the data alone, unless +you've specified --charset. + +=item --charset=charset-name + +If you do not specify --guess, then your database is converted +from this character set into the UTF-8. + +If you have specified --guess, recode.pl will use this charset as +a fallback--when it cannot guess the charset of a particular piece +of data, it will guess that the data is in this charset and convert +it from this charset to UTF-8. + +charset-name must be a charset that is known to perl's Encode +module. To see a list of available charsets, do: + +C<perl -MEncode -e 'print join("\n", Encode-E<gt>encodings(":all"))'> + +=item --show-failures + +If --guess fails to guess a charset, print out the data it failed on. + +=item --overrides=file_name + +This is a way of specifying certain encodings to override the encodings of +--guess. The file is a series of lines. The line should start with the Key +from --dry-run, and then a space, and then the encoding you'd like to use. + +=back diff --git a/contrib/sendbugmail.pl b/contrib/sendbugmail.pl index ad9642895..ae282ca4a 100644 --- a/contrib/sendbugmail.pl +++ b/contrib/sendbugmail.pl @@ -4,7 +4,7 @@ # # Nick Barnes, Ravenbrook Limited, 2004-04-01. # -# $Id: sendbugmail.pl,v 1.3 2005/02/24 23:42:48 mkanat%kerio.com Exp $ +# $Id: sendbugmail.pl,v 1.7 2006/07/03 21:42:47 mkanat%bugzilla.org Exp $ # # Bugzilla email script for Bugzilla 2.17.4 and later. Invoke this to send # bugmail for a bug which has been changed directly in the database. @@ -16,10 +16,13 @@ use lib qw(.); -require "globals.pl"; +use Bugzilla; +use Bugzilla::Util; use Bugzilla::BugMail; use Bugzilla::User; +my $dbh = Bugzilla->dbh; + sub usage { print STDERR "Usage: $0 bug_id user_email\n"; exit; @@ -41,15 +44,16 @@ if (!($bugnum =~ /^(\d+)$/)) { detaint_natural($bugnum); -SendSQL("SELECT bug_id FROM bugs WHERE bug_id = $bugnum"); +my ($id) = $dbh->selectrow_array("SELECT bug_id FROM bugs WHERE bug_id = ?", + undef, $bugnum); -if (!FetchOneColumn()) { +if (!$id) { print STDERR "Bug number $bugnum does not exist.\n"; usage(); } # Validate the changer address. -my $match = Param('emailregexp'); +my $match = Bugzilla->params->{'emailregexp'}; if ($changer !~ /$match/) { print STDERR "Changer \"$changer\" doesn't match email regular expression.\n"; usage(); diff --git a/contrib/sendunsentbugmail.pl b/contrib/sendunsentbugmail.pl index bf31f2d4b..5ed49b22e 100644 --- a/contrib/sendunsentbugmail.pl +++ b/contrib/sendunsentbugmail.pl @@ -25,25 +25,23 @@ use strict; use lib qw(.); -require "globals.pl"; +use Bugzilla; use Bugzilla::Constants; use Bugzilla::BugMail; my $dbh = Bugzilla->dbh; -SendSQL("SELECT bug_id FROM bugs + +my $list = $dbh->selectcol_arrayref( + 'SELECT bug_id FROM bugs WHERE lastdiffed IS NULL - OR lastdiffed < delta_ts AND delta_ts < NOW() - " - . $dbh->sql_interval(30, 'MINUTE') . - " ORDER BY bug_id"); -my @list; -while (MoreSQLData()) { - push (@list, FetchOneColumn()); -} + OR lastdiffed < delta_ts + AND delta_ts < NOW() - ' . $dbh->sql_interval(30, 'MINUTE') . + ' ORDER BY bug_id'); -if (scalar(@list) > 0) { +if (scalar(@$list) > 0) { print "OK, now attempting to send unsent mail\n"; - print scalar(@list) . " bugs found with possibly unsent mail.\n\n"; - foreach my $bugid (@list) { + print scalar(@$list) . " bugs found with possibly unsent mail.\n\n"; + foreach my $bugid (@$list) { my $start_time = time; print "Sending mail for bug $bugid...\n"; my $outputref = Bugzilla::BugMail::Send($bugid); diff --git a/contrib/syncLDAP.pl b/contrib/syncLDAP.pl index 6e78854e0..72ea91798 100755 --- a/contrib/syncLDAP.pl +++ b/contrib/syncLDAP.pl @@ -13,21 +13,20 @@ # # The Original Code is the LDAP to Bugzilla User Sync Tool. # -# The Initial Developer of the Original Code is Andreas H�fler. -# Portions created by Andreas H�fler are Copyright (C) 2003 -# Andreas H�fler. All -# Rights Reserved. +# The Initial Developer of the Original Code is Andreas Höfler. +# Portions created by Andreas Höfler are Copyright (C) 2003 +# Andreas Höfler. All Rights Reserved. # -# Contributor(s): Andreas H�fler <andreas.hoefler@bearingpoint.com> +# Contributor(s): Andreas Höfler <andreas.hoefler@bearingpoint.com> # use strict; -require "globals.pl"; - use lib qw(.); use Net::LDAP; +use Bugzilla; +use Bugzilla::User; my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; @@ -75,30 +74,24 @@ foreach my $arg (@ARGV) } } -my %bugzilla_users; my %ldap_users; ### # Get current bugzilla users ### -SendSQL("SELECT login_name, realname, disabledtext " . - "FROM profiles" ); -while (MoreSQLData()) { - my ($login_name, $realname, $disabledtext) - = FetchSQLData(); - +my $bugzilla_users = $dbh->selectall_hashref( + 'SELECT login_name AS new_login_name, realname, disabledtext ' . + 'FROM profiles', 'new_login_name'); + +foreach my $login_name (keys %$bugzilla_users) { # remove whitespaces - $realname =~ s/^\s+|\s+$//g; - - $bugzilla_users{$login_name} = { realname => $realname, - new_login_name => $login_name, - disabledtext => $disabledtext }; + $bugzilla_users->{$login_name}{'realname'} =~ s/^\s+|\s+$//g; } ### # Get current LDAP users ### -my $LDAPserver = Param("LDAPserver"); +my $LDAPserver = Bugzilla->params->{"LDAPserver"}; if ($LDAPserver eq "") { print "No LDAP server defined in bugzilla preferences.\n"; exit; @@ -114,8 +107,8 @@ if(!$LDAPconn) { exit; } my $mesg; -if (Param("LDAPbinddn")) { - my ($LDAPbinddn,$LDAPbindpass) = split(":",Param("LDAPbinddn")); +if (Bugzilla->params->{"LDAPbinddn"}) { + my ($LDAPbinddn,$LDAPbindpass) = split(":",Bugzilla->params->{"LDAPbinddn"}); $mesg = $LDAPconn->bind($LDAPbinddn, password => $LDAPbindpass); } else { @@ -127,9 +120,9 @@ if($mesg->code) { } # We've got our anonymous bind; let's look up the users. -$mesg = $LDAPconn->search( base => Param("LDAPBaseDN"), +$mesg = $LDAPconn->search( base => Bugzilla->params->{"LDAPBaseDN"}, scope => "sub", - filter => '(&(' . Param("LDAPuidattribute") . "=*)" . Param("LDAPfilter") . ')', + filter => '(&(' . Bugzilla->params->{"LDAPuidattribute"} . "=*)" . Bugzilla->params->{"LDAPfilter"} . ')', ); @@ -142,7 +135,7 @@ my $val = $mesg->as_struct; while( my ($key, $value) = each(%$val) ) { - my $login_name = @$value{Param("LDAPmailattribute")}; + my $login_name = @$value{Bugzilla->params->{"LDAPmailattribute"}}; my $realname = @$value{"cn"}; # no mail entered? go to next @@ -153,7 +146,7 @@ while( my ($key, $value) = each(%$val) ) { # no cn entered? use uid instead if(! defined $realname) { - $realname = @$value{Param("LDAPuidattribute")}; + $realname = @$value{Bugzilla->params->{"LDAPuidattribute"}}; } my $login = shift @$login_name; @@ -171,7 +164,7 @@ my %update_users; my %create_users; print "Bugzilla-Users: \n" unless $quiet; -while( my ($key, $value) = each(%bugzilla_users) ) { +while( my ($key, $value) = each(%$bugzilla_users) ) { print " " . $key . " '" . @$value{'realname'} . "' " . @$value{'disabledtext'} ."\n" unless $quiet==1; if(!exists $ldap_users{$key}){ if(@$value{'disabledtext'} eq '') { @@ -183,11 +176,11 @@ while( my ($key, $value) = each(%bugzilla_users) ) { print "\nLDAP-Users: \n" unless $quiet; while( my ($key, $value) = each(%ldap_users) ) { print " " . $key . " '" . @$value{'realname'} . "'\n" unless $quiet==1; - if(!exists $bugzilla_users{$key}){ + if(!defined $bugzilla_users->{$key}){ $create_users{$key} = $value; } else { - my $bugzilla_user_value = $bugzilla_users{$key}; + my $bugzilla_user_value = $bugzilla_users->{$key}; if(@$bugzilla_user_value{'realname'} ne @$value{'realname'}) { $update_users{$key} = $value; } @@ -236,11 +229,15 @@ if($quiet == 0) { ### if($readonly == 0) { print "Performing DB update:\nPhase 1: disabling not-existing users... " unless $quiet; + + my $sth_disable = $dbh->prepare( + 'UPDATE profiles + SET disabledtext = ? + WHERE ' . $dbh->sql_istrcmp('login_name', '?')); + if($nodisable == 0) { while( my ($key, $value) = each(%disable_users) ) { - SendSQL("UPDATE profiles SET disabledtext = 'auto-disabled by ldap " . - "sync' WHERE " . $dbh->sql_istrcmp('login_name', - $dbh->quote($key))); + $sth_disable->execute('auto-disabled by ldap sync', $key); } print "done!\n" unless $quiet; } @@ -249,15 +246,22 @@ if($readonly == 0) { } print "Phase 2: updating existing users... " unless $quiet; + + my $sth_update_login = $dbh->prepare( + 'UPDATE profiles + SET login_name = ? + WHERE ' . $dbh->sql_istrcmp('login_name', '?')); + my $sth_update_realname = $dbh->prepare( + 'UPDATE profiles + SET realname = ? + WHERE ' . $dbh->sql_istrcmp('login_name', '?')); + if($noupdate == 0) { while( my ($key, $value) = each(%update_users) ) { if(defined @$value{'new_login_name'}) { - SendSQL("UPDATE profiles SET login_name = '" . - @$value{'new_login_name'} . "' WHERE " . - $dbh->sql_istrcmp('login_name', $dbh->quote($key))); + $sth_update_login->execute(@$value{'new_login_name'}, $key); } else { - SendSQL("UPDATE profiles SET realname = '" . @$value{'realname'} . - "' WHERE " . $dbh->sql_istrcmp('login_name', $dbh->quote($key))); + $sth_update_realname->execute(@$value{'realname'}, $key); } } print "done!\n" unless $quiet; @@ -269,14 +273,10 @@ if($readonly == 0) { print "Phase 3: creating new users... " unless $quiet; if($nocreate == 0) { while( my ($key, $value) = each(%create_users) ) { - SendSQL("INSERT INTO profiles VALUES ('', - '$key', - 'xxKFIy4WR66mA', - '" . @$value{'realname'} . "', - '', - 1, - 'ExcludeSelf~on~emailOwnerRemoveme~on~emailOwnerComments~on~emailOwnerAttachments~on~emailOwnerStatus~on~emailOwnerResolved~on~emailOwnerKeywords~on~emailOwnerCC~on~emailOwnerOther~on~emailOwnerUnconfirmed~on~emailReporterRemoveme~on~emailReporterComments~on~emailReporterAttachments~on~emailReporterStatus~on~emailReporterResolved~on~emailReporterKeywords~on~emailReporterCC~on~emailReporterOther~on~emailReporterUnconfirmed~on~emailQAcontactRemoveme~on~emailQAcontactComments~on~emailQAcontactAttachments~on~emailQAcontactStatus~on~emailQAcontactResolved~on~emailQAcontactKeywords~on~emailQAcontactCC~on~emailQAcontactOther~on~emailQAcontactUnconfirmed~on~emailCClistRemoveme~on~emailCClistComments~on~emailCClistAttachments~on~emailCClistStatus~on~emailCClistResolved~on~emailCClistKeywords~on~emailCClistCC~on~emailCClistOther~on~emailCClistUnconfirmed~on~emailVoterRemoveme~on~emailVoterComments~on~emailVoterAttachments~on~emailVoterStatus~on~emailVoterResolved~on~emailVoterKeywords~on~emailVoterCC~on~emailVoterOther~on~emailVoterUnconfirmed~on', - sysdate())"); + Bugzilla::User->create({ + login_name => $key, + realname => @$value{'realname'}, + password => '*'}); } print "done!\n" unless $quiet; } diff --git a/createaccount.cgi b/createaccount.cgi index 01b746c89..1f372fe7e 100755 --- a/createaccount.cgi +++ b/createaccount.cgi @@ -28,10 +28,9 @@ use strict; use lib qw(.); -require "globals.pl"; - use Bugzilla; use Bugzilla::Constants; +use Bugzilla::Error; use Bugzilla::User; use Bugzilla::BugMail; use Bugzilla::Util; @@ -49,11 +48,11 @@ my $vars = {}; print $cgi->header(); # If we're using LDAP for login, then we can't create a new account here. -unless (Bugzilla::Auth->can_edit('new')) { +unless (Bugzilla->user->authorizer->user_can_create_account) { ThrowUserError("auth_cant_create_account"); } -my $createexp = Param('createemailregexp'); +my $createexp = Bugzilla->params->{'createemailregexp'}; unless ($createexp) { ThrowUserError("account_creation_disabled"); } @@ -61,40 +60,16 @@ unless ($createexp) { my $login = $cgi->param('login'); if (defined($login)) { - # We've been asked to create an account. - my $realname = trim($cgi->param('realname')); - - validate_email_syntax($login) - || ThrowUserError('illegal_email_address', {addr => $login}); - + $login = Bugzilla::User->check_login_name_for_creation($login); $vars->{'login'} = $login; - $dbh->bz_lock_tables('profiles WRITE', 'groups READ', - 'user_group_map WRITE', 'email_setting WRITE', - 'tokens READ'); - - if (!is_available_username($login)) { - # Account already exists - $dbh->bz_unlock_tables(); - $template->process("account/exists.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - exit; - } - if ($login !~ /$createexp/) { ThrowUserError("account_creation_disabled"); } - - # Create account - my $password = insert_new_user($login, $realname); - - $dbh->bz_unlock_tables(); - # Clear out the login cookies in case the user is currently logged in. - Bugzilla->logout(); + # Create and send a token for this new account. + Bugzilla::Token::issue_new_user_account_token($login); - Bugzilla::BugMail::MailPassword($login, $password); - $template->process("account/created.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; diff --git a/describecomponents.cgi b/describecomponents.cgi index 1b1ccbfe0..b282040c5 100755 --- a/describecomponents.cgi +++ b/describecomponents.cgi @@ -20,96 +20,68 @@ # # Contributor(s): Terry Weissman <terry@mozilla.org> # Bradley Baetz <bbaetz@student.usyd.edu.au> +# Frédéric Buclin <LpSolit@gmail.com> use strict; use lib qw(.); use Bugzilla; use Bugzilla::Constants; -require "globals.pl"; - -use vars qw(@legal_product); +use Bugzilla::Util; +use Bugzilla::Error; +use Bugzilla::Product; my $user = Bugzilla->login(); -GetVersionTable(); - my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; my $template = Bugzilla->template; my $vars = {}; -my $product = trim($cgi->param('product') || ''); -my $product_id = get_product_id($product); -if (!$product_id || !$user->can_enter_product($product)) { - # Reference to a subset of %::proddesc, which the user is allowed to see - my %products; +print $cgi->header(); - if (AnyEntryGroups()) { - # OK, now only add products the user can see - Bugzilla->login(LOGIN_REQUIRED); - foreach my $p (@::legal_product) { - if ($user->can_enter_product($p)) { - $products{$p} = $::proddesc{$p}; - } - } - } - else { - %products = %::proddesc; - } +my $product_name = trim($cgi->param('product') || ''); +my $product = new Bugzilla::Product({'name' => $product_name}); - my $prodsize = scalar(keys %products); - if ($prodsize == 0) { +unless ($product && $user->can_enter_product($product->name)) { + # Products which the user is allowed to see. + my @products = @{$user->get_enterable_products}; + + if (scalar(@products) == 0) { ThrowUserError("no_products"); } - elsif ($prodsize > 1) { - $vars->{'proddesc'} = \%products; + # If there is only one product available but the user entered + # another product name, we display a list with this single + # product only, to not confuse the user with components of a + # product he didn't request. + elsif (scalar(@products) > 1 || $product_name) { + $vars->{'classifications'} = [{object => undef, products => \@products}]; $vars->{'target'} = "describecomponents.cgi"; # If an invalid product name is given, or the user is not # allowed to access that product, a message is displayed # with a list of the products the user can choose from. - if ($product) { + if ($product_name) { $vars->{'message'} = "product_invalid"; - $vars->{'product'} = $product; + # Do not use $product->name here, else you could use + # this way to determine whether the product exists or not. + $vars->{'product'} = $product_name; } - print $cgi->header(); $template->process("global/choose-product.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; } - $product = (keys %products)[0]; - $product_id = get_product_id($product); + # If there is only one product available and the user didn't specify + # any product name, we show this product. + $product = $products[0]; } ###################################################################### # End Data/Security Validation ###################################################################### -my @components; -my $comps = $dbh->selectall_arrayref( - q{SELECT name, initialowner, initialqacontact, description - FROM components - WHERE product_id = ? - ORDER BY name}, undef, $product_id); -foreach my $comp (@$comps) { - my ($name, $initialowner, $initialqacontact, $description) = @$comp; - my %component; - - $component{'name'} = $name; - $component{'initialowner'} = $initialowner ? - DBID_to_name($initialowner) : ''; - $component{'initialqacontact'} = $initialqacontact ? - DBID_to_name($initialqacontact) : ''; - $component{'description'} = $description; - - push @components, \%component; -} - $vars->{'product'} = $product; -$vars->{'components'} = \@components; -print $cgi->header(); $template->process("reports/components.html.tmpl", $vars) || ThrowTemplateError($template->error()); diff --git a/describekeywords.cgi b/describekeywords.cgi index 2b21e712c..70c0ba4e0 100755 --- a/describekeywords.cgi +++ b/describekeywords.cgi @@ -25,29 +25,18 @@ use strict; use lib "."; use Bugzilla; +use Bugzilla::Error; use Bugzilla::User; - -require "globals.pl"; +use Bugzilla::Keyword; Bugzilla->login(); my $cgi = Bugzilla->cgi; -my $dbh = Bugzilla->dbh; my $template = Bugzilla->template; my $vars = {}; -my $keywords = $dbh->selectall_arrayref( - q{SELECT keyworddefs.name, keyworddefs.description, - COUNT(keywords.bug_id) AS bugcount - FROM keyworddefs - LEFT JOIN keywords - ON keyworddefs.id = keywords.keywordid } . - $dbh->sql_group_by('keyworddefs.id', - 'keyworddefs.name, keyworddefs.description') . - " ORDER BY keyworddefs.name", {'Slice' => {}}); - -$vars->{'keywords'} = $keywords; -$vars->{'caneditkeywords'} = UserInGroup("editkeywords"); +$vars->{'keywords'} = Bugzilla::Keyword->get_all_with_bug_count(); +$vars->{'caneditkeywords'} = Bugzilla->user->in_group("editkeywords"); print Bugzilla->cgi->header(); $template->process("reports/keywords.html.tmpl", $vars) diff --git a/docs/.cvsignore b/docs/.cvsignore index e5004814b..8453d5c46 100644 --- a/docs/.cvsignore +++ b/docs/.cvsignore @@ -1,3 +1,2 @@ txt -html pdf diff --git a/docs/CVS/Entries b/docs/CVS/Entries index f3173d5f4..6da81263d 100644 --- a/docs/CVS/Entries +++ b/docs/CVS/Entries @@ -1,6 +1,8 @@ -/.cvsignore/1.2/Wed Mar 17 05:15:41 2004//TBUGZILLA-2_22_3 -/README.docs/1.10/Sun May 30 21:46:07 2004//TBUGZILLA-2_22_3 -/makedocs.pl/1.10.2.1/Fri Apr 6 10:13:15 2007//TBUGZILLA-2_22_3 -/rel_notes.txt/1.36.2.9/Wed Aug 22 19:45:10 2007//TBUGZILLA-2_22_3 +/.cvsignore/1.3/Tue Sep 5 19:00:55 2006//TBUGZILLA-3_0 +/README.docs/1.10/Sun May 30 21:46:07 2004//TBUGZILLA-3_0 +/makedocs.pl/1.16.2.1/Fri Apr 6 10:11:46 2007//TBUGZILLA-3_0 +/rel_notes.txt/1.44/Thu Feb 22 18:41:29 2007//TBUGZILLA-3_0 +D/html//// D/images//// +D/lib//// D/xml//// diff --git a/docs/CVS/Tag b/docs/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/docs/CVS/Tag +++ b/docs/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/docs/html/.cvsignore b/docs/html/.cvsignore new file mode 100644 index 000000000..2d19fc766 --- /dev/null +++ b/docs/html/.cvsignore @@ -0,0 +1 @@ +*.html diff --git a/docs/html/Bugzilla-Guide.html b/docs/html/Bugzilla-Guide.html index 3bc1ee27c..cda5c479a 100644 --- a/docs/html/Bugzilla-Guide.html +++ b/docs/html/Bugzilla-Guide.html @@ -2,8 +2,7 @@ <HTML ><HEAD ><TITLE ->The Bugzilla Guide - 2.22.3 - Release</TITLE +>The Bugzilla Guide - 3.0 Release</TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><META @@ -43,15 +42,14 @@ CLASS="TITLEPAGE" CLASS="title" ><A NAME="AEN2" ->The Bugzilla Guide - 2.22.3 - Release</A +>The Bugzilla Guide - 3.0 Release</A ></H1 ><H3 CLASS="corpauthor" >The Bugzilla Team</H3 ><P CLASS="pubdate" ->2007-08-23<BR></P +>2007-05-09<BR></P ><DIV ><DIV CLASS="abstract" @@ -70,7 +68,7 @@ NAME="AEN7" ><P > The most current version of this document can always be found on the <A -HREF="http://www.bugzilla.org/documentation.html" +HREF="http://www.bugzilla.org/docs/" TARGET="_top" >Bugzilla Documentation Page</A @@ -146,7 +144,7 @@ HREF="#extraconfig" ></DT ><DT >2.4. <A -HREF="#AEN763" +HREF="#AEN834" >Multiple Bugzilla databases with a single installation</A ></DT ><DT @@ -210,26 +208,31 @@ HREF="#flags-overview" ></DT ><DT >3.9. <A +HREF="#custom-fields" +>Custom Fields</A +></DT +><DT +>3.10. <A HREF="#edit-values" >Legal Values</A ></DT ><DT ->3.10. <A +>3.11. <A HREF="#voting" >Voting</A ></DT ><DT ->3.11. <A +>3.12. <A HREF="#quips" >Quips</A ></DT ><DT ->3.12. <A +>3.13. <A HREF="#groups" >Groups and Group Security</A ></DT ><DT ->3.13. <A +>3.14. <A HREF="#upgrading" >Upgrading to New Releases</A ></DT @@ -341,29 +344,29 @@ HREF="#whining" ><DT >6. <A HREF="#customization" ->Customizing Bugzilla</A +>Customising Bugzilla</A ></DT ><DD ><DL ><DT >6.1. <A -HREF="#cust-templates" ->Template Customization</A +HREF="#cust-skins" +>Custom Skins</A ></DT ><DT >6.2. <A -HREF="#cust-hooks" ->Template Hooks</A +HREF="#cust-templates" +>Template Customization</A ></DT ><DT >6.3. <A -HREF="#cust-change-permissions" ->Customizing Who Can Change What</A +HREF="#cust-hooks" +>The Bugzilla Extension Mechanism</A ></DT ><DT >6.4. <A -HREF="#dbmodify" ->Modifying Your Running System</A +HREF="#cust-change-permissions" +>Customizing Who Can Change What</A ></DT ><DT >6.5. <A @@ -415,21 +418,16 @@ HREF="#paranoid-security" ></DT ><DT >B.6. <A -HREF="#trouble-filetemp" ->Your vendor has not defined Fcntl macro O_NOINHERIT</A -></DT -><DT ->B.7. <A HREF="#trbl-relogin-everyone" >Everybody is constantly being forced to relogin</A ></DT ><DT ->B.8. <A +>B.7. <A HREF="#trbl-relogin-some" >Some users are constantly being forced to relogin</A ></DT ><DT ->B.9. <A +>B.8. <A HREF="#trbl-index" ><TT CLASS="filename" @@ -437,7 +435,7 @@ CLASS="filename" > doesn't show up unless specified in the URL</A ></DT ><DT ->B.10. <A +>B.9. <A HREF="#trbl-passwd-encryption" >checksetup.pl reports "Client does not support authentication protocol requested by server..."</A @@ -704,7 +702,7 @@ NAME="newversions" >1.3. New Versions</A ></H2 ><P -> This is the 2.22.3 version of The Bugzilla Guide. It is so named +> This is the 3.0 version of The Bugzilla Guide. It is so named to match the current version of Bugzilla. </P ><P @@ -748,7 +746,7 @@ TARGET="_top" </P ><P > - In addition, there are Bugzilla template localization projects in + In addition, there are Bugzilla template localisation projects in the following languages. They may have translated documentation available: <A @@ -782,7 +780,7 @@ TARGET="_top" >French</A >, <A -HREF="http://germzilla.ganderbay.net/" +HREF="http://germzilla.wurblzap.net/" TARGET="_top" >German</A >, @@ -1232,7 +1230,7 @@ CLASS="sgmltag" This documentation is maintained in DocBook 4.1.2 XML format. Changes are best submitted as plain text or XML diffs, attached to a bug filed in the <A -HREF="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=Documentation" +HREF="https://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=Documentation" TARGET="_top" >Bugzilla Documentation</A > component. @@ -1360,7 +1358,7 @@ TYPE="1" HREF="#install-perl" >Install Perl</A > - (5.6.1 or above for non-Windows platforms; 5.8.1 + (5.8.0 or above for non-Windows platforms; 5.8.1 for Windows) </P ></LI @@ -1433,7 +1431,7 @@ HREF="http://www.perl.com" TARGET="_top" >http://www.perl.com</A >. - Although Bugzilla runs with Perl 5.6.1, + Although Bugzilla runs with Perl 5.8.0, it's a good idea to be using the latest stable version. </P ></DIV @@ -1469,7 +1467,7 @@ HREF="http://www.mysql.com" TARGET="_top" >http://www.mysql.com</A >. You need MySQL version - 4.0.14 or higher. + 4.1.2 or higher. </P ><DIV CLASS="note" @@ -1536,7 +1534,7 @@ HREF="http://www.postgresql.org/" TARGET="_top" >http://www.postgresql.org/</A >. You need PostgreSQL - version 7.3.x or higher. + version 8.00.0000 or higher. </P ><P >If you install from something other than a packaging/installation @@ -1572,7 +1570,7 @@ CLASS="glossterm" the installation instructions usually assume you are using it. If you have got Bugzilla working using another webserver, please share your experiences with us by filing a bug in <A -HREF="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=Documentation" +HREF="https://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=Documentation" TARGET="_top" >Bugzilla Documentation</A >. @@ -1789,7 +1787,7 @@ VALIGN="TOP" <SPAN CLASS="QUOTE" >"@INC"</SPAN ->. +>. Virtually every time, this error is due to permissions being set too restrictively for you to compile Perl modules or not having the necessary Perl development libraries installed on your system. @@ -1849,17 +1847,7 @@ CLASS="filename" TYPE="1" ><LI ><P -> AppConfig (1.52) - </P -></LI -><LI -><P -> CGI (2.93) - </P -></LI -><LI -><P -> Data::Dumper (any) +> CGI 2.93 or CGI 3.11 if using mod_perl </P ></LI ><LI @@ -1869,7 +1857,7 @@ TYPE="1" ></LI ><LI ><P -> DBI (1.38) +> DBI (1.41) </P ></LI ><LI @@ -1883,7 +1871,7 @@ HREF="#install-modules-dbd-mysql" ></LI ><LI ><P -> DBD::Pg (1.31) if using PostgreSQL +> DBD::Pg (1.45) if using PostgreSQL </P ></LI ><LI @@ -1893,41 +1881,21 @@ HREF="#install-modules-dbd-mysql" ></LI ><LI ><P -> File::Temp (any) - </P -></LI -><LI -><P > <A HREF="#install-modules-template" >Template</A > - (2.10) - </P -></LI -><LI -><P -> Text::Wrap (2001.0131) - </P -></LI -><LI -><P -> Mail::Mailer (1.67) - </P -></LI -><LI -><P -> MIME::Base64 (3.01) + (2.12) </P ></LI ><LI ><P -> MIME::Parser (5.406) +> Email::Send (2.00) </P ></LI ><LI ><P -> Storable (any) +> Email::MIME::Modifier (any) </P ></LI ></OL @@ -1949,6 +1917,12 @@ HREF="#install-modules-gd" ></LI ><LI ><P +> Template::Plugin::GD::Image + (1.20) for Graphical Reports + </P +></LI +><LI +><P > <A HREF="#install-modules-chart-base" >Chart::Base</A @@ -1968,8 +1942,8 @@ HREF="#install-modules-gd-graph" ><LI ><P > <A -HREF="#install-modules-gd-text-align" ->GD::Text::Align</A +HREF="#install-modules-gd-text" +>GD::Text</A > (any) for bug charting </P @@ -1980,7 +1954,18 @@ HREF="#install-modules-gd-text-align" HREF="#install-modules-xml-twig" >XML::Twig</A > - (any) for the XML interface + (any) for bug import/export + </P +></LI +><LI +><P +> MIME::Parser (5.406) for bug import/export + </P +></LI +><LI +><P +> LWP::UserAgent + (any) for Automatic Update Notifications </P ></LI ><LI @@ -1997,8 +1982,65 @@ HREF="#install-modules-patchreader" > Image::Magick (any) for converting BMP image attachments to PNG </P ></LI +><LI +><P +> Net::LDAP + (any) for LDAP Authentication + </P +></LI +><LI +><P +> <A +HREF="#install-modules-soap-lite" +>SOAP::Lite</A +> + (any) for the web service interface + </P +></LI +><LI +><P +> HTML::Parser + (3.40) for More HTML in Product/Group Descriptions + </P +></LI +><LI +><P +> HTML::Scrubber + (any) for More HTML in Product/Group Descriptions + </P +></LI +><LI +><P +> Email::MIME::Attachment::Stripper + (any) for Inbound Email + </P +></LI +><LI +><P +> Email::Reply + (any) for Inbound Email + </P +></LI +><LI +><P +> mod_perl2 + (1.999022) for mod_perl + </P +></LI +><LI +><P +> CGI + (2.93) for mod_perl + </P +></LI +><LI +><P +> Apache::DBI + (0.96) for mod_perl2 + </P +></LI ></OL -> +> </P ><DIV CLASS="section" @@ -2028,7 +2070,7 @@ CLASS="section" CLASS="section" ><A NAME="install-modules-template" ->2.1.5.2. Template Toolkit (2.10)</A +>2.1.5.2. Template Toolkit (2.12)</A ></H4 ><P >When you install Template Toolkit, you'll get asked various @@ -2156,11 +2198,11 @@ CLASS="section" ><HR><H4 CLASS="section" ><A -NAME="install-modules-gd-text-align" ->2.1.5.6. GD::Text::Align (any)</A +NAME="install-modules-gd-text" +>2.1.5.6. GD::Text (any)</A ></H4 ><P ->The GD::Text::Align module is only required if you want graphical +>The GD::Text module is only required if you want graphical reports. </P ></DIV @@ -2187,8 +2229,22 @@ CLASS="section" ><HR><H4 CLASS="section" ><A +NAME="install-modules-soap-lite" +>2.1.5.8. SOAP::Lite (any)</A +></H4 +><P +>Installing SOAP::Lite enables your Bugzilla installation to be + accessible at a standardized Web Service interface (SOAP/XML-RPC) + by third-party applications via HTTP(S). + </P +></DIV +><DIV +CLASS="section" +><HR><H4 +CLASS="section" +><A NAME="install-modules-patchreader" ->2.1.5.8. PatchReader (0.9.4)</A +>2.1.5.9. PatchReader (0.9.4)</A ></H4 ><P >The PatchReader module is only required if you want to use @@ -2278,6 +2334,49 @@ HREF="#parameters" succeeds, then Bugzilla should also be fine. </P ></DIV +><DIV +CLASS="section" +><HR><H3 +CLASS="section" +><A +NAME="using-mod_perl-with-bugzilla" +>2.1.7. Installing Bugzilla on mod_perl</A +></H3 +><P +>It is now possible to run the Bugzilla software under <VAR +CLASS="literal" +>mod_perl</VAR +> on + Apache. <VAR +CLASS="literal" +>mod_perl</VAR +> has some additional requirements to that of running + Bugzilla under <VAR +CLASS="literal" +>mod_cgi</VAR +> (the standard and previous way).</P +><P +>Bugzilla requires <VAR +CLASS="literal" +>mod_perl</VAR +> to be installed, which can be + obtained from <A +HREF="http://perl.apache.org" +TARGET="_top" +>http://perl.apache.org</A +> - Bugzilla requires + version 1.999022 (AKA 2.0.0-RC5) to be installed.</P +><P +>Bugzilla also requires a more up-to-date version of the CGI + perl module to be installed, version 3.11 as opposed to 2.93 + </P +><P +>Finally, Bugzilla also requires <VAR +CLASS="literal" +>Apache::DBI</VAR +> + (0.96) to be installed as well.</P +></DIV ></DIV ><DIV CLASS="section" @@ -2573,7 +2672,7 @@ CLASS="section" ><HR><H5 CLASS="section" ><A -NAME="AEN445" +NAME="AEN473" >2.2.2.2.2. Allow small words in full-text indexes</A ></H5 ><P @@ -2709,7 +2808,7 @@ CLASS="section" ><HR><H5 CLASS="section" ><A -NAME="AEN472" +NAME="AEN500" >2.2.2.2.4. Permit attachments table to grow beyond 4GB</A ></H5 ><P @@ -2803,40 +2902,11 @@ NAME="postgresql" >2.2.2.3. PostgreSQL</A ></H4 ><DIV -CLASS="note" -><P -></P -><TABLE -CLASS="note" -WIDTH="100%" -BORDER="0" -><TR -><TD -WIDTH="25" -ALIGN="CENTER" -VALIGN="TOP" -><IMG -SRC="../images/note.gif" -HSPACE="5" -ALT="Note"></TD -><TD -ALIGN="LEFT" -VALIGN="TOP" -><P ->If you are using PostgreSQL 8.0.1 or higher, then you - will require to use a version of DBD::Pg which is equal to or - greater than version 1.41 - </P -></TD -></TR -></TABLE -></DIV -><DIV CLASS="section" -><HR><H5 +><H5 CLASS="section" ><A -NAME="AEN490" +NAME="AEN516" >2.2.2.3.1. Add a User to PostgreSQL</A ></H5 ><P @@ -2917,7 +2987,7 @@ CLASS="section" ><HR><H5 CLASS="section" ><A -NAME="AEN506" +NAME="AEN532" >2.2.2.3.2. Configure PostgreSQL</A ></H5 ><P @@ -2931,7 +3001,7 @@ CLASS="filename" >. In this file, you will need to add a new line to it as follows:</P ><P -> <SAMP +> <SAMP CLASS="computeroutput" >host all bugs 127.0.0.1 255.255.255.255 md5</SAMP > @@ -2941,33 +3011,6 @@ CLASS="computeroutput" '127.0.0.1' to 'all' databases on this server from the 'bugs' user, and use password authentication (md5) for that user.</P ><P ->If you are using <EM ->versions of PostgreSQL - before version 8</EM ->, you may also need to edit <TT -CLASS="filename" ->postgresql.conf</TT -> - , also usually found in the <TT -CLASS="filename" ->/var/lib/pgsql/data/</TT -> folder. - You will need to make a single line change, changing</P -><P -> <SAMP -CLASS="computeroutput" -># tcpip_socket = false</SAMP -> - </P -><P ->to</P -><P -> <SAMP -CLASS="computeroutput" ->tcpip_socket = true</SAMP -> - </P -><P >Now, you will need to restart PostgreSQL, but you will need to fully stop and start the server rather than just restarting due to the possibility of a change to <TT @@ -2998,7 +3041,7 @@ CLASS="section" ><HR><H3 CLASS="section" ><A -NAME="AEN529" +NAME="AEN546" >2.2.3. checksetup.pl</A ></H3 ><P @@ -3067,48 +3110,68 @@ CLASS="section" CLASS="section" ><A NAME="http-apache" ->2.2.4.1. Apache <SPAN -CLASS="productname" ->httpd</SPAN -></A +>2.2.4.1. Bugzilla using Apache</A ></H4 ><P -> To configure your Apache web server to work with Bugzilla, - do the following: +>You have two options for running Bugzilla under Apache - + <A +HREF="#http-apache-mod_cgi" +>mod_cgi</A +> (the default) and + <A +HREF="#http-apache-mod_perl" +>mod_perl</A +> (new in Bugzilla + 2.23) </P ><DIV +CLASS="section" +><HR><H5 +CLASS="section" +><A +NAME="http-apache-mod_cgi" +>2.2.4.1.1. Apache <SPAN +CLASS="productname" +>httpd</SPAN +> with mod_cgi</A +></H5 +><P +> To configure your Apache web server to work with Bugzilla while using + mod_cgi, do the following: + </P +><DIV CLASS="procedure" ><OL TYPE="1" ><LI ><P -> Load <TT +> Load <TT CLASS="filename" >httpd.conf</TT > in your editor. - In Fedora and Red Hat Linux, this file is found in - <TT + In Fedora and Red Hat Linux, this file is found in + <TT CLASS="filename" >/etc/httpd/conf</TT >. - </P + </P ></LI ><LI ><P -> Apache uses <SAMP +> Apache uses <SAMP CLASS="computeroutput" ><Directory></SAMP > - directives to permit fine-grained permission setting. Add the - following lines to a directive that applies to the location - of your Bugzilla installation. (If such a section does not - exist, you'll want to add one.) In this example, Bugzilla has - been installed at - <TT + directives to permit fine-grained permission setting. Add the + following lines to a directive that applies to the location + of your Bugzilla installation. (If such a section does not + exist, you'll want to add one.) In this example, Bugzilla has + been installed at + <TT CLASS="filename" >/var/www/html/bugzilla</TT >. - </P + </P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" @@ -3119,31 +3182,31 @@ WIDTH="100%" COLOR="#000000" ><PRE CLASS="programlisting" -> <Directory /var/www/html/bugzilla> - AddHandler cgi-script .cgi - Options +Indexes +ExecCGI - DirectoryIndex index.cgi - AllowOverride Limit -</Directory> - </PRE +> <Directory /var/www/html/bugzilla> + AddHandler cgi-script .cgi + Options +Indexes +ExecCGI + DirectoryIndex index.cgi + AllowOverride Limit + </Directory> + </PRE ></FONT ></TD ></TR ></TABLE ><P -> These instructions: allow apache to run .cgi files found - within the bugzilla directory; instructs the server to look - for a file called <TT +> These instructions: allow apache to run .cgi files found + within the bugzilla directory; instructs the server to look + for a file called <TT CLASS="filename" >index.cgi</TT > if someone - only types the directory name into the browser; and allows - Bugzilla's <TT + only types the directory name into the browser; and allows + Bugzilla's <TT CLASS="filename" >.htaccess</TT > files to override - global permissions. - </P + global permissions. + </P ><DIV CLASS="note" ><P @@ -3165,18 +3228,18 @@ ALT="Note"></TD ALIGN="LEFT" VALIGN="TOP" ><P -> It is possible to make these changes globally, or to the - directive controlling Bugzilla's parent directory (e.g. - <SAMP +> It is possible to make these changes globally, or to the + directive controlling Bugzilla's parent directory (e.g. + <SAMP CLASS="computeroutput" ><Directory /var/www/html/></SAMP >). - Such changes would also apply to the Bugzilla directory... - but they would also apply to many other places where they - may or may not be appropriate. In most cases, including - this one, it is better to be as restrictive as possible - when granting extra access. - </P + Such changes would also apply to the Bugzilla directory... + but they would also apply to many other places where they + may or may not be appropriate. In most cases, including + this one, it is better to be as restrictive as possible + when granting extra access. + </P ></TD ></TR ></TABLE @@ -3184,71 +3247,304 @@ CLASS="computeroutput" ></LI ><LI ><P -> <TT +> <TT CLASS="filename" >checksetup.pl</TT > can set tighter permissions - on Bugzilla's files and directories if it knows what group the - webserver runs as. Find the <SAMP + on Bugzilla's files and directories if it knows what group the + webserver runs as. Find the <SAMP CLASS="computeroutput" >Group</SAMP > - line in <TT + line in <TT CLASS="filename" >httpd.conf</TT >, place the value found - there in the <VAR + there in the <VAR CLASS="replaceable" >$webservergroup</VAR > variable - in <TT + in <TT CLASS="filename" >localconfig</TT >, then rerun - <TT + <TT CLASS="filename" >checksetup.pl</TT >. - </P + </P +></LI +><LI +><P +> Optional: If Bugzilla does not actually reside in the webspace + directory, but instead has been symbolically linked there, you + will need to add the following to the + <SAMP +CLASS="computeroutput" +>Options</SAMP +> line of the Bugzilla + <SAMP +CLASS="computeroutput" +><Directory></SAMP +> directive + (the same one as in the step above): + </P +><TABLE +BORDER="0" +BGCOLOR="#E0E0E0" +WIDTH="100%" +><TR +><TD +><FONT +COLOR="#000000" +><PRE +CLASS="programlisting" +> +FollowSymLinks + </PRE +></FONT +></TD +></TR +></TABLE +><P +> Without this directive, Apache will not follow symbolic links + to places outside its own directory structure, and you will be + unable to run Bugzilla. + </P +></LI +></OL +></DIV +></DIV +><DIV +CLASS="section" +><HR><H5 +CLASS="section" +><A +NAME="http-apache-mod_perl" +>2.2.4.1.2. Apache <SPAN +CLASS="productname" +>httpd</SPAN +> with mod_perl</A +></H5 +><P +>Some configuration is required to make Bugzilla work with Apache + and mod_perl</P +><DIV +CLASS="procedure" +><OL +TYPE="1" +><LI +><P +> Load <TT +CLASS="filename" +>httpd.conf</TT +> in your editor. + In Fedora and Red Hat Linux, this file is found in + <TT +CLASS="filename" +>/etc/httpd/conf</TT +>. + </P +></LI +><LI +><P +>Add the following information to your httpd.conf file, substituting + where appropriate with your own local paths.</P +><DIV +CLASS="note" +><P +></P +><TABLE +CLASS="note" +WIDTH="100%" +BORDER="0" +><TR +><TD +WIDTH="25" +ALIGN="CENTER" +VALIGN="TOP" +><IMG +SRC="../images/note.gif" +HSPACE="5" +ALT="Note"></TD +><TD +ALIGN="LEFT" +VALIGN="TOP" +><P +>This should be used instead of the <Directory> block + shown above. This should also be above any other <VAR +CLASS="literal" +>mod_perl</VAR +> + directives within the <TT +CLASS="filename" +>httpd.conf</TT +> and must be specified + in the order as below.</P +></TD +></TR +></TABLE +></DIV +><DIV +CLASS="warning" +><P +></P +><TABLE +CLASS="warning" +WIDTH="100%" +BORDER="0" +><TR +><TD +WIDTH="25" +ALIGN="CENTER" +VALIGN="TOP" +><IMG +SRC="../images/warning.gif" +HSPACE="5" +ALT="Warning"></TD +><TD +ALIGN="LEFT" +VALIGN="TOP" +><P +>You should also ensure that you have disabled <VAR +CLASS="literal" +>KeepAlive</VAR +> + support in your Apache install when utilizing Bugzilla under mod_perl</P +></TD +></TR +></TABLE +></DIV +><TABLE +BORDER="0" +BGCOLOR="#E0E0E0" +WIDTH="100%" +><TR +><TD +><FONT +COLOR="#000000" +><PRE +CLASS="programlisting" +> PerlSwitches -I/var/www/html/bugzilla -w -T + PerlConfigRequire /var/www/html/bugzilla/mod_perl.pl + </PRE +></FONT +></TD +></TR +></TABLE +></LI +><LI +><P +> <TT +CLASS="filename" +>checksetup.pl</TT +> can set tighter permissions + on Bugzilla's files and directories if it knows what group the + webserver runs as. Find the <SAMP +CLASS="computeroutput" +>Group</SAMP +> + line in <TT +CLASS="filename" +>httpd.conf</TT +>, place the value found + there in the <VAR +CLASS="replaceable" +>$webservergroup</VAR +> variable + in <TT +CLASS="filename" +>localconfig</TT +>, then rerun + <TT +CLASS="filename" +>checksetup.pl</TT +>. + </P +></LI +></OL +></DIV +><P +>On restarting Apache, Bugzilla should now be running within the + mod_perl environment. Please ensure you have run checksetup.pl to set + permissions before you restart Apache.</P +><DIV +CLASS="note" +><P +></P +><TABLE +CLASS="note" +WIDTH="100%" +BORDER="0" +><TR +><TD +WIDTH="25" +ALIGN="CENTER" +VALIGN="TOP" +><IMG +SRC="../images/note.gif" +HSPACE="5" +ALT="Note"></TD +><TD +ALIGN="LEFT" +VALIGN="TOP" +><P +>Please bear the following points in mind when looking at using + Bugzilla under mod_perl: + <P +></P +><UL +><LI +><P +> mod_perl support in Bugzilla can take up a HUGE amount of RAM. You could be + looking at 30MB per httpd child, easily. Basically, you just need a lot of RAM. + The more RAM you can get, the better. mod_perl is basically trading RAM for + speed. At least 2GB total system RAM is recommended for running Bugzilla under + mod_perl. + </P ></LI ><LI ><P -> Optional: If Bugzilla does not actually reside in the webspace - directory, but instead has been symbolically linked there, you - will need to add the following to the - <SAMP -CLASS="computeroutput" ->Options</SAMP -> line of the Bugzilla - <SAMP -CLASS="computeroutput" -><Directory></SAMP -> directive - (the same one as in the step above): +> Under mod_perl, you have to restart Apache if you make any manual change to + any Bugzilla file. You can't just reload--you have to actually + <EM +>restart</EM +> the server (as in make sure it stops and starts + again). You <EM +>can</EM +> change localconfig and the params file + manually, if you want, because those are re-read every time you load a page. + </P +></LI +><LI +><P +> You must run in Apache's Prefork MPM (this is the default). The Worker MPM + may not work--we haven't tested Bugzilla's mod_perl support under threads. + (And, in fact, we're fairly sure it <EM +>won't</EM +> work.) + </P +></LI +><LI +><P +> Bugzilla generally expects to be the only mod_perl application running on + your entire server. It may or may not work if there are other applications also + running under mod_perl. It does try its best to play nice with other mod_perl + applications, but it still may have conflicts. + </P +></LI +><LI +><P +> It is recommended that you have one Bugzilla instance running under mod_perl + on your server. Bugzilla has not been tested with more than one instance running. + </P +></LI +></UL +> </P -><TABLE -BORDER="0" -BGCOLOR="#E0E0E0" -WIDTH="100%" -><TR -><TD -><FONT -COLOR="#000000" -><PRE -CLASS="programlisting" -> +FollowSymLinks - </PRE -></FONT ></TD ></TR ></TABLE -><P -> Without this directive, Apache will not follow symbolic links - to places outside its own directory structure, and you will be - unable to run Bugzilla. - </P -></LI -></OL +></DIV ></DIV ></DIV ><DIV @@ -3554,7 +3850,7 @@ CLASS="section" ><HR><H3 CLASS="section" ><A -NAME="AEN630" +NAME="AEN696" >2.3.1. Bug Graphs</A ></H3 ><P @@ -3686,7 +3982,7 @@ CLASS="section" ><HR><H3 CLASS="section" ><A -NAME="AEN649" +NAME="AEN715" >2.3.2. Dependency Charts</A ></H3 ><P @@ -3998,16 +4294,18 @@ NAME="bzldap" you need to deal with user ID (e.g assigning a bug) use the email address. The LDAP authentication builds on top of this scheme, rather than replacing it. The initial log in is done with a username and - password for the LDAP directory. This then fetches the email address - from LDAP and authenticates seamlessly in the standard Bugzilla - authentication scheme using this email address. If an account for this - address already exists in your Bugzilla system, it will log in to that - account. If no account for that email address exists, one is created at - the time of login. (In this case, Bugzilla will attempt to use the - "displayName" or "cn" attribute to determine the user's full name.) - After authentication, all other user-related tasks are still handled by - email address, not LDAP username. You still assign bugs by email - address, query on users by email address, etc. + password for the LDAP directory. Bugzilla tries to bind to LDAP using + those credentials, and if successful, try to map this account to a + Bugzilla account. If a LDAP mail attribute is defined, the value of this + attribute is used, otherwise emailsuffix parameter is appended to LDAP + username to form a full email address. If an account for this address + already exists in your Bugzilla system, it will log in to that account. + If no account for that email address exists, one is created at the time + of login. (In this case, Bugzilla will attempt to use the "displayName" + or "cn" attribute to determine the user's full name.) After + authentication, all other user-related tasks are still handled by email + address, not LDAP username. You still assign bugs by email address, query + on users by email address, etc. </P ><DIV CLASS="caution" @@ -4117,6 +4415,26 @@ CLASS="QUOTE" or <SPAN CLASS="QUOTE" >"ldap.company.com:3268"</SPAN +> + </P +><P +>You can also specify a LDAP URI, so as to use other + protocols, such as LDAPS or LDAPI. If port was not specified in + the URI, the default is either 389 or 636 for 'LDAP' and 'LDAPS' + schemes respectively. + </P +><P +>Ex. <SPAN +CLASS="QUOTE" +>"ldap://ldap.company.com"</SPAN +>, + <SPAN +CLASS="QUOTE" +>"ldaps://ldap.company.com"</SPAN +> or + <SPAN +CLASS="QUOTE" +>"ldapi://%2fvar%2flib%2fldap_sock"</SPAN > </P ></DD @@ -4267,7 +4585,7 @@ CLASS="section" ><HR><H2 CLASS="section" ><A -NAME="AEN763" +NAME="AEN834" >2.4. Multiple Bugzilla databases with a single installation</A ></H2 ><P @@ -4370,7 +4688,7 @@ NAME="os-specific" ><P >If you have anything to add or notes for an operating system not covered, please file a bug in <A -HREF="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=Documentation" +HREF="https://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=Documentation" TARGET="_top" >Bugzilla Documentation</A >. @@ -4989,7 +5307,7 @@ CLASS="section" ><H3 CLASS="section" ><A -NAME="AEN885" +NAME="AEN956" >2.6.1. Introduction</A ></H3 ><P @@ -5009,7 +5327,7 @@ CLASS="section" ><HR><H3 CLASS="section" ><A -NAME="AEN889" +NAME="AEN960" >2.6.2. MySQL</A ></H3 ><P @@ -5065,7 +5383,7 @@ CLASS="section" ><HR><H4 CLASS="section" ><A -NAME="AEN897" +NAME="AEN968" >2.6.2.1. Running MySQL as Non-Root</A ></H4 ><DIV @@ -5073,7 +5391,7 @@ CLASS="section" ><H5 CLASS="section" ><A -NAME="AEN899" +NAME="AEN970" >2.6.2.1.1. The Custom Configuration Method</A ></H5 ><P @@ -5117,7 +5435,7 @@ CLASS="section" ><HR><H5 CLASS="section" ><A -NAME="AEN903" +NAME="AEN974" >2.6.2.1.2. The Custom Built Method</A ></H5 ><P @@ -5140,7 +5458,7 @@ CLASS="section" ><HR><H5 CLASS="section" ><A -NAME="AEN908" +NAME="AEN979" >2.6.2.1.3. Starting the Server</A ></H5 ><P @@ -5268,7 +5586,7 @@ CLASS="section" ><HR><H3 CLASS="section" ><A -NAME="AEN924" +NAME="AEN995" >2.6.3. Perl</A ></H3 ><P @@ -5361,7 +5679,7 @@ CLASS="section" ><HR><H4 CLASS="section" ><A -NAME="AEN943" +NAME="AEN1014" >2.6.4.1. The Independant Method</A ></H4 ><P @@ -5433,7 +5751,7 @@ CLASS="section" ><HR><H4 CLASS="section" ><A -NAME="AEN956" +NAME="AEN1027" >2.6.4.2. The Mixed Method</A ></H4 ><P @@ -5638,7 +5956,7 @@ CLASS="section" ><HR><H3 CLASS="section" ><A -NAME="AEN989" +NAME="AEN1060" >2.6.5. HTTP Server</A ></H3 ><P @@ -5652,7 +5970,7 @@ CLASS="section" ><HR><H4 CLASS="section" ><A -NAME="AEN992" +NAME="AEN1063" >2.6.5.1. Running Apache as Non-Root</A ></H4 ><P @@ -5734,7 +6052,7 @@ CLASS="section" ><HR><H3 CLASS="section" ><A -NAME="AEN1001" +NAME="AEN1072" >2.6.6. Bugzilla</A ></H3 ><P @@ -6022,20 +6340,6 @@ CLASS="filename" ></DIV ></DD ><DT ->passwordmail</DT -><DD -><P -> Every time a user creates an account, the text of this parameter - (with substitutions) is sent to the new user along with their - password message. - </P -><P -> Add any text you wish to the "passwordmail" parameter box. For - instance, many people choose to use this box to give a quick - training blurb about how to use Bugzilla at your site. - </P -></DD -><DT >movebugs</DT ><DD ><P @@ -6059,6 +6363,17 @@ CLASS="filename" </P ></DD ><DT +>globalwatcher</DT +><DD +><P +> This allows to define specific users that will + receive notification each time a new bug in entered, or when + an existing bug changes, according to the normal groupset + permissions. It may be useful for sending notifications to a + mailing-list, for instance. + </P +></DD +><DT >usestatuswhiteboard</DT ><DD ><P @@ -6426,6 +6741,16 @@ CLASS="QUOTE" ><LI ><P > <EM +>Bugmail Disabled</EM +>: + Mark this checkbox to disable bugmail and whinemail completely + for this account. This checkbox replaces the data/nomail file + which existed in older versions of Bugzilla. + </P +></LI +><LI +><P +> <EM >Disable Text</EM >: If you type anything in this box, including just a space, the @@ -6440,11 +6765,11 @@ CLASS="QUOTE" mail from Bugzilla; furthermore, they will not be able to log in themselves to change their own preferences and stop it. If you want an account (disabled or active) to - stop receiving mail, add the account name (one account - per line) to the file <TT -CLASS="filename" ->data/nomail</TT ->. + stop receiving mail, simply check the + <SPAN +CLASS="QUOTE" +>"Bugmail Disabled"</SPAN +> checkbox above. </P ><DIV CLASS="note" @@ -7816,8 +8141,174 @@ CLASS="section" ><HR><H2 CLASS="section" ><A +NAME="custom-fields" +>3.9. Custom Fields</A +></H2 +><P +> One of the most requested features was the ability to add your own custom + fields to bugs, based on your needs. With the release of Bugzilla 3.0, this + dream finally comes true. Administrators can manage these fields using the + <SPAN +CLASS="QUOTE" +>"Custom Fields"</SPAN +> link in the footer of pages. The first thing + they will see is the list of existing custom fields (which is empty by default). + </P +><DIV +CLASS="section" +><HR><H3 +CLASS="section" +><A +NAME="add-custom-fields" +>3.9.1. Adding Custom Fields</A +></H3 +><P +> The <SPAN +CLASS="QUOTE" +>"Add a new custom field"</SPAN +> link permits you to add a + new field which can be either a free text box or a drop down menu. + More field types will be available in future releases. + </P +><P +> The following attributes must be set for each new custom field: + <P +></P +><UL +><LI +><P +> <EM +>Name:</EM +> + the name of the field, used internally. This name MUST begin + with <SPAN +CLASS="QUOTE" +>"cf_"</SPAN +>. If you omit this string, it will + be automatically added to the name you entered. This way, all + custom fields added to Bugzilla begin with <SPAN +CLASS="QUOTE" +>"cf_"</SPAN +>, + avoiding any conflict with default fields. + </P +></LI +><LI +><P +> <EM +>Description:</EM +> + the string which is used as a label for this custom field. + That is the string that users will see, and so should be + short and explicit. + </P +></LI +><LI +><P +> <EM +>Type:</EM +> + as mentioned above, only two types are implemented so far. + Free text boxes let you type any string, while drop down menus + only let you choose one value in the list provided. The list of + legal values for this field can be created and edited as soon as + this custom field is added to the DB. See + <A +HREF="#edit-values-list" +>Section 3.10.1</A +> for information about editing + legal values. + </P +></LI +><LI +><P +> <EM +>Sortkey:</EM +> + this integer determines in which order custom fields are + displayed in the UI, especially when viewing a bug. Fields + with lower values are displayed first. + </P +></LI +><LI +><P +> <EM +>Can be set on bug creation:</EM +> + this boolean determines whether this field can be set on + bug creation or not. If not, then you have to create the + bug first before being able to set this field. Else you + can set its value at the same time you file a bug, + see <A +HREF="#bugreports" +>Section 5.6</A +> about filing bugs. + </P +></LI +><LI +><P +> <EM +>Displayed in bugmail for new bugs:</EM +> + this boolean determines whether the value set on this field + should appear in bugmail when the bug is filed. This attribute + has no effect if the field cannot be set on bug creation. + </P +></LI +><LI +><P +> <EM +>Is obsolete:</EM +> + this boolean determines whether or not this field should + be displayed at all. Obsolete custom fields are hidden. + </P +></LI +></UL +> + </P +></DIV +><DIV +CLASS="section" +><HR><H3 +CLASS="section" +><A +NAME="edit-custom-fields" +>3.9.2. Editing Custom Fields</A +></H3 +><P +> As soon as a custom field is created, its name and type cannot be + changed. If this field is a drop down menu, its legal values can + be set as described in <A +HREF="#edit-values-list" +>Section 3.10.1</A +>. All + other attributes can be edited as described above. + </P +></DIV +><DIV +CLASS="section" +><HR><H3 +CLASS="section" +><A +NAME="delete-custom-fields" +>3.9.3. Deleting Custom Fields</A +></H3 +><P +> At this point, it is not possible to delete custom fields from + your web browser. If you don't want to make one available anymore, + mark it as obsolete. This way, you will preserve your DB + referential integrity. + </P +></DIV +></DIV +><DIV +CLASS="section" +><HR><H2 +CLASS="section" +><A NAME="edit-values" ->3.9. Legal Values</A +>3.10. Legal Values</A ></H2 ><P > Since Bugzilla 2.20 RC1, legal values for Operating Systems, platforms, @@ -7826,7 +8317,8 @@ NAME="edit-values" <TT CLASS="filename" >localconfig</TT ->. +>. Starting with Bugzilla 2.23.3, you + can also customize the list of valid resolutions from the same interface. </P ><DIV CLASS="section" @@ -7834,12 +8326,12 @@ CLASS="section" CLASS="section" ><A NAME="edit-values-list" ->3.9.1. Viewing/Editing legal values</A +>3.10.1. Viewing/Editing legal values</A ></H3 ><P > Editing legal values requires <SPAN CLASS="QUOTE" ->"editcomponents"</SPAN +>"admin"</SPAN > privileges. A link named <SPAN CLASS="QUOTE" @@ -7859,7 +8351,7 @@ CLASS="section" CLASS="section" ><A NAME="edit-values-delete" ->3.9.2. Deleting legal values</A +>3.10.2. Deleting legal values</A ></H3 ><P > You can also delete legal values, but only if the two following conditions @@ -7891,7 +8383,7 @@ CLASS="section" CLASS="section" ><A NAME="voting" ->3.10. Voting</A +>3.11. Voting</A ></H2 ><P >Voting allows users to be given a pot of votes which they can allocate @@ -7953,7 +8445,7 @@ CLASS="section" CLASS="section" ><A NAME="quips" ->3.11. Quips</A +>3.12. Quips</A ></H2 ><P > Quips are small text messages that can be configured to appear @@ -8000,7 +8492,7 @@ CLASS="section" CLASS="section" ><A NAME="groups" ->3.12. Groups and Group Security</A +>3.13. Groups and Group Security</A ></H2 ><P >Groups allow the administrator @@ -8074,8 +8566,8 @@ CLASS="section" ><HR><H3 CLASS="section" ><A -NAME="AEN1545" ->3.12.1. Creating Groups</A +NAME="AEN1660" +>3.13.1. Creating Groups</A ></H3 ><P >To create Groups:</P @@ -8212,8 +8704,8 @@ CLASS="section" ><HR><H3 CLASS="section" ><A -NAME="AEN1572" ->3.12.2. Assigning Users to Groups</A +NAME="AEN1687" +>3.13.2. Assigning Users to Groups</A ></H3 ><P >Users can become a member of a group in several ways.</P @@ -8244,8 +8736,8 @@ CLASS="section" ><HR><H3 CLASS="section" ><A -NAME="AEN1582" ->3.12.3. Assigning Group Controls to Products</A +NAME="AEN1697" +>3.13.3. Assigning Group Controls to Products</A ></H3 ><P > On the product edit page, there is a page to edit the @@ -8336,16 +8828,16 @@ CLASS="section" ><HR><H3 CLASS="section" ><A -NAME="AEN1600" ->3.12.4. Common Applications of Group Controls</A +NAME="AEN1715" +>3.13.4. Common Applications of Group Controls</A ></H3 ><DIV CLASS="section" ><H4 CLASS="section" ><A -NAME="AEN1602" ->3.12.4.1. General User Access With Security Group</A +NAME="AEN1717" +>3.13.4.1. General User Access With Security Group</A ></H4 ><P >To permit any user to file bugs in each product (A, B, C...) @@ -8379,8 +8871,8 @@ CLASS="section" ><HR><H4 CLASS="section" ><A -NAME="AEN1606" ->3.12.4.2. General User Access With A Security Product</A +NAME="AEN1721" +>3.13.4.2. General User Access With A Security Product</A ></H4 ><P >To permit any user to file bugs in a Security product @@ -8411,8 +8903,8 @@ CLASS="section" ><HR><H4 CLASS="section" ><A -NAME="AEN1610" ->3.12.4.3. Product Isolation With Common Group</A +NAME="AEN1725" +>3.13.4.3. Product Isolation With Common Group</A ></H4 ><P >To permit users of product A to access the bugs for @@ -8495,7 +8987,7 @@ CLASS="section" CLASS="section" ><A NAME="upgrading" ->3.13. Upgrading to New Releases</A +>3.14. Upgrading to New Releases</A ></H2 ><P > Upgrading Bugzilla is something we all want to do from time to time, @@ -8522,24 +9014,26 @@ CLASS="section" CLASS="section" ><A NAME="upgrading-version-defns" ->3.13.1. Version Definitions</A +>3.14.1. Version Definitions</A ></H3 ><P -> Bugzilla displays the version you are using at the top of most - pages you load. It will look something like '2.16.7' or '2.18rc3' - or '2.19.1+'. The first number in this series is the Major Version. - This does not change very often (that is to say, almost never); +> Bugzilla displays the version you are using at the top of the home + page <TT +CLASS="filename" +>index.cgi</TT +>. It looks something like + '2.20.3', '2.22.1' or '3.0rc1'. The first number in this series is + the Major Version. This does not change very often; Bugzilla was 1.x.x when it was first created, and went to 2.x.x - when it was re-written in perl in Sept 1998. If/When the major version - is changed to 3.x.x, it will signify a significant structural change - and will be accompanied by much fanfare and many instructions on - how to upgrade, including a revision to this page. :) + when it was re-written in perl in Sept 1998. The major version + 3.x.x, released in early 2007, is pretty far from what the 2.x.x + series looked like, both about its UI and its code. </P ><P > The second number in the version is called the 'minor number', and a release that changes the minor number is called a 'point release'. - An even number in this position (2.14, 2.16, 2.18, 2.20, etc.) - represents a stable version, while an odd number (2.17, 2.19, etc.) + An even number in this position (2.18, 2.20, 2.22, 3.0, 3.2, etc.) + represents a stable version, while an odd number (2.19, 2.21, 2.23, etc.) represents a development version. In the past, stable point releases were feature-based, coming when certain enhancements had been completed, or the Bugzilla development team felt that enough @@ -8550,13 +9044,11 @@ NAME="upgrading-version-defns" </P ><P > The third number in the Bugzilla version represents a bugfix version. - Bugfix Revisions are normally released only to address security - vulnerabilities; in the future, it is likely that the Bugzilla - development team will back-port bugfixes in a new point release to - the old point release for a limited period. Once enough of these + Bugfix Revisions are released only to address security vulnerabilities + and, for a limited period, bug fixes. Once enough of these bugfixes have accumulated (or a new security vulnerability is - identified and closed), a bugfix release will be made. As an - example, 2.16.6 was a bugfix release, and improved on 2.16.5. + identified and closed), a bugfix release is made. As an + example, 2.20.3 was a bugfix release, and improved on 2.20.2. </P ><DIV CLASS="note" @@ -8583,9 +9075,9 @@ VALIGN="TOP" should be read as a single number. It is <EM >not</EM > - the same as decimal. 2.14 is newer than 2.8 because minor version - 14 is greater than minor version 8. 2.24.11 would be newer than - 2.24.9 (because bugfix 11 is greater than bugfix 9. This is + the same as decimal. 2.22 is newer than 2.8 because minor version + 22 is greater than minor version 8. The now unsupported release 2.16.11 + was newer than 2.16.9 (because bugfix 11 is greater than bugfix 9. This is confusing to some people who aren't used to dealing with software. </P ></TD @@ -8598,8 +9090,39 @@ CLASS="section" ><HR><H3 CLASS="section" ><A +NAME="upgrading-notifications" +>3.14.2. Upgrading - Notifications</A +></H3 +><P +> Bugzilla 3.0 introduces the ability to automatically notify + administrators when new releases are available, based on the + <VAR +CLASS="literal" +>upgrade_notification</VAR +> parameter, see + <A +HREF="#parameters" +>Section 3.1</A +>. Administrators will see these + notifications when they access the <TT +CLASS="filename" +>index.cgi</TT +> + page, i.e. generally when logging in. Bugzilla will check once a + week for new releases, unless the parameter is set to + <SPAN +CLASS="QUOTE" +>"disabled"</SPAN +>. + </P +></DIV +><DIV +CLASS="section" +><HR><H3 +CLASS="section" +><A NAME="upgrading-methods" ->3.13.2. Upgrading - Methods and Procedure</A +>3.14.3. Upgrading - Methods and Procedure</A ></H3 ><P > There are three different ways to upgrade your installation. @@ -8612,7 +9135,7 @@ TYPE="1" ><P > Using CVS (<A HREF="#upgrade-cvs" ->Section 3.13.2.1</A +>Section 3.14.3.1</A >) </P ></LI @@ -8620,7 +9143,7 @@ HREF="#upgrade-cvs" ><P > Downloading a new tarball (<A HREF="#upgrade-tarball" ->Section 3.13.2.2</A +>Section 3.14.3.2</A >) </P ></LI @@ -8628,7 +9151,7 @@ HREF="#upgrade-tarball" ><P > Applying the relevant patches (<A HREF="#upgrade-patches" ->Section 3.13.2.3</A +>Section 3.14.3.3</A >) </P ></LI @@ -8641,14 +9164,14 @@ HREF="#upgrade-patches" methods of updating compared with degree and methods of local customization can be found in <A HREF="#template-method" ->Section 6.1.2</A +>Section 6.2.2</A >.) </P ><P > The larger the jump you are trying to make, the more difficult it is going to be to upgrade if you have made local customizations. - Upgrading from 2.18 to 2.18.1 should be fairly painless even if - you are heavily customized, but going from 2.14 to 2.18 is going + Upgrading from 2.22 to 2.22.1 should be fairly painless even if + you are heavily customized, but going from 2.18 to 3.0 is going to mean a fair bit of work re-writing your local changes to use the new files, logic, templates, etc. If you have done no local changes at all, however, then upgrading should be approximately @@ -8687,7 +9210,7 @@ VALIGN="TOP" ></DIV ><P > The examples in the following sections are written as though the - user were updating to version 2.18.1, but the procedures are the + user were updating to version 2.22.1, but the procedures are the same regardless of whether one is updating to a new point release or simply trying to obtain a new bugfix release. Also, in the examples the user's Bugzilla installation is found at @@ -8704,7 +9227,7 @@ CLASS="section" CLASS="section" ><A NAME="upgrade-cvs" ->3.13.2.1. Upgrading using CVS</A +>3.14.3.1. Upgrading using CVS</A ></H4 ><P > Every release of Bugzilla, whether it is a point release or a bugfix, @@ -8771,11 +9294,10 @@ CVS password: <EM > bash$ <B CLASS="command" ->cvs -q update -r BUGZILLA-2_18_1 -dP</B +>cvs -q update -r BUGZILLA-2_22_1 -dP</B > P checksetup.pl P collectstats.pl -P globals.pl P docs/rel_notes.txt P template/en/default/list/quips.html.tmpl <EM @@ -8830,7 +9352,7 @@ CLASS="section" CLASS="section" ><A NAME="upgrade-tarball" ->3.13.2.2. Upgrading using the tarball</A +>3.14.3.2. Upgrading using the tarball</A ></H4 ><P > If you are unable (or unwilling) to use CVS, another option that's @@ -8868,24 +9390,23 @@ CLASS="command" > bash$ <B CLASS="command" ->wget ftp://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.18.1.tar.gz</B +>wget http://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.22.1.tar.gz</B > <EM >(Output omitted)</EM > bash$ <B CLASS="command" ->tar xzvf bugzilla-2.18.1.tar.gz</B +>tar xzvf bugzilla-2.22.1.tar.gz</B > -bugzilla-2.18.1/ -bugzilla-2.18.1/.cvsignore -bugzilla-2.18.1/1x1.gif +bugzilla-2.22.1/ +bugzilla-2.22.1/.cvsignore <EM >(Output truncated)</EM > bash$ <B CLASS="command" ->cd bugzilla-2.18.1</B +>cd bugzilla-2.22.1</B > bash$ <B CLASS="command" @@ -8905,7 +9426,7 @@ CLASS="command" > bash$ <B CLASS="command" ->mv bugzilla-2.18.1 bugzilla</B +>mv bugzilla-2.22.1 bugzilla</B > </PRE ></FONT @@ -8962,11 +9483,11 @@ CLASS="section" CLASS="section" ><A NAME="upgrade-patches" ->3.13.2.3. Upgrading using patches</A +>3.14.3.3. Upgrading using patches</A ></H4 ><P > If you are doing a bugfix upgrade -- that is, one where only the - last number of the revision changes, such as from 2.16.6 to 2.16.7 + last number of the revision changes, such as from 2.22 to 2.22.1 -- then you have the option of obtaining and applying a patch file from the <A HREF="http://www.bugzilla.org/download/" @@ -9006,22 +9527,21 @@ CLASS="command" > bash$ <B CLASS="command" ->wget ftp://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.18.0-to-2.18.1.diff.gz</B +>wget http://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.22-to-2.22.1.diff.gz</B > <EM >(Output omitted)</EM > bash$ <B CLASS="command" ->gunzip bugzilla-2.18.0-to-2.18.1.diff.gz</B +>gunzip bugzilla-2.22-to-2.22.1.diff.gz</B > bash$ <B CLASS="command" ->patch -p1 < bugzilla-2.18.0-to-2.18.1.diff</B +>patch -p1 < bugzilla-2.22-to-2.22.1.diff</B > patching file checksetup.pl patching file collectstats.pl -patching file globals.pl <EM >(etc.)</EM > @@ -9059,7 +9579,7 @@ CLASS="filename" This could make it more difficult to upgrade using CVS (<A HREF="#upgrade-cvs" ->Section 3.13.2.1</A +>Section 3.14.3.1</A >) in the future. </P ></TD @@ -9074,7 +9594,7 @@ CLASS="section" CLASS="section" ><A NAME="upgrading-completion" ->3.13.3. Completing Your Upgrade</A +>3.14.4. Completing Your Upgrade</A ></H3 ><P > Regardless of which upgrade method you choose, you will need to @@ -10005,74 +10525,158 @@ TARGET="_top" quite work as this document describes.</P ></DIV ><DIV -CLASS="section" -><HR><H2 -CLASS="section" -><A -NAME="myaccount" ->5.2. Create a Bugzilla Account</A -></H2 -><P ->If you want to use Bugzilla, first you need to create an account. - Consult with the administrator responsible for your installation of - Bugzilla for the URL you should use to access it. If you're - test-driving Bugzilla, use this URL: - <A -HREF="http://landfill.bugzilla.org/bugzilla-2.22-branch/" -TARGET="_top" ->http://landfill.bugzilla.org/bugzilla-2.22-branch/</A ->. - </P +CLASS="section" +><HR><H2 +CLASS="section" +><A +NAME="myaccount" +>5.2. Create a Bugzilla Account</A +></H2 +><P +>If you want to use Bugzilla, first you need to create an account. + Consult with the administrator responsible for your installation of + Bugzilla for the URL you should use to access it. If you're + test-driving Bugzilla, use this URL: + <A +HREF="http://landfill.bugzilla.org/bugzilla-tip/" +TARGET="_top" +>http://landfill.bugzilla.org/bugzilla-tip/</A +>. + </P +><P +></P +><OL +TYPE="1" +><LI +><P +> On the home page <TT +CLASS="filename" +>index.cgi</TT +>, click the + <SPAN +CLASS="QUOTE" +>"Open a new Bugzilla account"</SPAN +> link, or the + <SPAN +CLASS="QUOTE" +>"New Account"</SPAN +> link available in the footer of pages. + Now enter your email address, then click the <SPAN +CLASS="QUOTE" +>"Send"</SPAN +> + button. + </P +><DIV +CLASS="note" +><P +></P +><TABLE +CLASS="note" +WIDTH="100%" +BORDER="0" +><TR +><TD +WIDTH="25" +ALIGN="CENTER" +VALIGN="TOP" +><IMG +SRC="../images/note.gif" +HSPACE="5" +ALT="Note"></TD +><TD +ALIGN="LEFT" +VALIGN="TOP" +><P +> If none of these links is available, this means that the + administrator of the installation has disabled self-registration. + This means that only an administrator can create accounts + for other users. One reason could be that this installation is + private. + </P +></TD +></TR +></TABLE +></DIV +><DIV +CLASS="note" ><P ></P -><OL -TYPE="1" +><TABLE +CLASS="note" +WIDTH="100%" +BORDER="0" +><TR +><TD +WIDTH="25" +ALIGN="CENTER" +VALIGN="TOP" +><IMG +SRC="../images/note.gif" +HSPACE="5" +ALT="Note"></TD +><TD +ALIGN="LEFT" +VALIGN="TOP" +><P +> Also, if only some users are allowed to create an account on + the installation, you may see these links but your registration + may fail if your email address doesn't match the ones accepted + by the installation. This is another way to restrict who can + access and edit bugs in this installation. + </P +></TD +></TR +></TABLE +></DIV +></LI ><LI ><P ->Click the - <SPAN -CLASS="QUOTE" ->"Open a new Bugzilla account"</SPAN -> - - link, enter your email address and, optionally, your name in the - spaces provided, then click - <SPAN -CLASS="QUOTE" ->"Create Account"</SPAN -> - - .</P +> Within moments, and if your registration is accepted, you should + receive an email to the address you provided, which contains your + login name (generally the same as the email address), and two URLs + with a token (a random string generated by the installation) to + confirm, respectively cancel, your registration. This is a way to + prevent users from abusing the generation of user accounts, for + instance by entering inexistent email addresses, or email addresses + which do not belong to them. + </P ></LI ><LI ><P ->Within moments, you should receive an email to the address - you provided, which contains your login name (generally the - same as the email address), and a password. - This password is randomly generated, but can be - changed to something more memorable.</P +> By default, you have 3 days to confirm your registration. Past this + timeframe, the token is invalidated and the registration is + automatically canceled. You can also cancel this registration sooner + by using the appropriate URL in the email you got. + </P ></LI ><LI ><P ->Click the - <SPAN +> If you confirm your registration, Bugzilla will ask you your real name + (optional, but recommended) and your password, which must be between + 3 and 16 characters long. + </P +></LI +><LI +><P +> Now all you need to do is to click the <SPAN CLASS="QUOTE" >"Log In"</SPAN > - link in the footer at the bottom of the page in your browser, - enter your email address and password into the spaces provided, and - click - <SPAN + link in the footer at the bottom of the page in your browser, + enter your email address and password you just chose into the + login form, and click the <SPAN CLASS="QUOTE" ->"Login"</SPAN ->. +>"Log in"</SPAN +> button. </P ></LI ></OL ><P ->You are now logged in. Bugzilla uses cookies to remember you are - logged in so, unless you have cookies disabled or your IP address changes, - you should not have to log in again.</P +> You are now logged in. Bugzilla uses cookies to remember you are + logged in so, unless you have cookies disabled or your IP address changes, + you should not have to log in again during your session. + </P ></DIV ><DIV CLASS="section" @@ -10086,7 +10690,7 @@ NAME="bug_page" >The core of Bugzilla is the screen which displays a particular bug. It's a good place to explain some Bugzilla concepts. <A -HREF="http://landfill.bugzilla.org/bugzilla-2.22-branch/show_bug.cgi?id=1" +HREF="http://landfill.bugzilla.org/bugzilla-tip/show_bug.cgi?id=1" TARGET="_top" > Bug 1 on Landfill</A > @@ -10276,7 +10880,7 @@ BORDER="0" > <EM >Priority:</EM > - The bug assignee uses this field to prioritize his or her bugs. + The bug assignee uses this field to prioritise his or her bugs. It's a good idea not to change this on other people's bugs.</P ></LI ><LI @@ -10418,8 +11022,7 @@ CLASS="QUOTE" You can attach files (e.g. testcases or patches) to bugs. If there are any attachments, they are listed in this section. Attachments are normally stored in the Bugzilla database, unless they are marked as - Big Files, which are stored directly on disk and (unlike attachments - kept in the database) may be deleted at some future time. + Big Files, which are stored directly on disk. </P ></LI ><LI @@ -10505,9 +11108,9 @@ NAME="query" any bug report, comment, or patch currently in the Bugzilla system. You can play with it here: <A -HREF="http://landfill.bugzilla.org/bugzilla-2.22-branch/query.cgi" +HREF="http://landfill.bugzilla.org/bugzilla-tip/query.cgi" TARGET="_top" ->http://landfill.bugzilla.org/bugzilla-2.22-branch/query.cgi</A +>http://landfill.bugzilla.org/bugzilla-tip/query.cgi</A >.</P ><P >The Search page has controls for selecting different possible @@ -10516,8 +11119,22 @@ TARGET="_top" returns bugs where the content of the field matches any one of the selected values. If none is selected, then the field can take any value.</P ><P ->Once you've run a search, you can save it as a Saved Search, which - appears in the page footer.</P +> Once you've run a search, you can save it as a Saved Search, which + appears in the page footer. + On the Saved Searches tab of your User Preferences page (the Prefs link + in Bugzilla's footer), members of the group defined in the + querysharegroup parameter can share such Saved Searches with user groups + so that other users may use them. + At the same place, you can see Saved Searches other users are sharing, and + have them show up in your personal Bugzilla footer along with your own + Saved Searches. + If somebody is sharing a Search with a group she or he is allowed to + <A +HREF="#groups" +>assign users to</A +>, it will show up in the + group's direct members' footers by default. + </P ><DIV CLASS="section" ><HR><H3 @@ -10614,7 +11231,7 @@ NAME="negation" > At first glance, negation seems redundant. Rather than searching for <A -NAME="AEN2088" +NAME="AEN2222" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -10625,7 +11242,7 @@ CLASS="BLOCKQUOTE" > one could search for <A -NAME="AEN2090" +NAME="AEN2224" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -10636,7 +11253,7 @@ CLASS="BLOCKQUOTE" > However, the search <A -NAME="AEN2092" +NAME="AEN2226" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -10648,7 +11265,7 @@ CLASS="BLOCKQUOTE" would find every bug where anyone on the CC list did not contain "@mozilla.org" while <A -NAME="AEN2094" +NAME="AEN2228" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -10662,7 +11279,7 @@ CLASS="BLOCKQUOTE" complex expressions to be built using terms OR'd together and then negated. Negation permits queries such as <A -NAME="AEN2096" +NAME="AEN2230" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -10675,7 +11292,7 @@ CLASS="BLOCKQUOTE" to find bugs that are neither in the update product or in the documentation component or <A -NAME="AEN2098" +NAME="AEN2232" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -10703,7 +11320,7 @@ NAME="multiplecharts" a bug that has two different people cc'd on it, then you need to use two boolean charts. A search for <A -NAME="AEN2103" +NAME="AEN2237" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -10718,7 +11335,7 @@ CLASS="BLOCKQUOTE" containing "foo@" and someone else containing "@mozilla.org", then you would need two boolean charts. <A -NAME="AEN2105" +NAME="AEN2239" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -10907,46 +11524,46 @@ CLASS="section" CLASS="section" ><A NAME="individual-buglists" ->5.5.4. Adding individual bugs from bug lists</A +>5.5.4. Adding/removing tags to/from bugs</A ></H3 ><P -> You can at any time add individual bugs to a special type - of saved searches, known as <SPAN -CLASS="QUOTE" ->"lists of bugs"</SPAN ->. The distinction - between both types is that saved searches, as described in the previous - section, are stored in the form of a list of matching criteria, while - a list of bugs is an enumerated list of bug numbers. As it is a simple - list of bug numbers, you can easily edit this list by adding - bugs to it. To enable this feature, you have to turn on the - <SPAN -CLASS="QUOTE" ->"Add individual bugs to saved searches"</SPAN -> user preference, - see <A +> You can add and remove tags from individual bugs, which let you find and + manage them more easily. Creating a new tag automatically generates a saved + search - whose name is the name of the tag - which lists bugs with this tag. + This saved search will be displayed in the footer of pages by default, as + all other saved searches. The main difference between tags and normal saved + searches is that saved searches, as described in the previous section, are + stored in the form of a list of matching criteria, while the saved search + generated by tags is a list of bug numbers. Consequently, you can easily + edit this list by either adding or removing tags from bugs. To enable this + feature, you have to turn on the <SPAN +CLASS="QUOTE" +>"Enable tags for bugs"</SPAN +> user + preference, see <A HREF="#userpreferences" >Section 5.10</A ->. +>. This feature is disabled + by default. </P ><P > This feature is useful when you want to keep track of several bugs, but for different reasons. Instead of adding yourself to the CC list of all these bugs and mixing all these reasons, you can now store these bugs in - different lists, e.g. <SPAN + separate lists, e.g. <SPAN CLASS="QUOTE" ->"Bugs I want to see fixed before the next - release"</SPAN +>"Keep in mind"</SPAN >, <SPAN CLASS="QUOTE" >"Interesting bugs"</SPAN ->, or <SPAN +>, + or <SPAN CLASS="QUOTE" ->"Bugs I have - to think about"</SPAN ->. One big advantage of this way to manage bug lists - is that you can easily add bugs one by one, which is not possible to do - with saved searches without having to edit the search criteria again. +>"Triage"</SPAN +>. One big advantage of this way to manage bugs + is that you can easily add or remove bugs one by one, which is not + possible to do with saved searches without having to edit the search + criteria again. </P ></DIV ></DIV @@ -10970,7 +11587,7 @@ NAME="fillingbugs" >Years of bug writing experience has been distilled for your reading pleasure into the <A -HREF="http://landfill.bugzilla.org/bugzilla-2.22-branch/page.cgi?id=bug-writing.html" +HREF="http://landfill.bugzilla.org/bugzilla-tip/page.cgi?id=bug-writing.html" TARGET="_top" > Bug Writing Guidelines</A >. @@ -11022,7 +11639,7 @@ VALIGN="TOP" > If you want to file a test bug to see how Bugzilla works, you can do it on one of our test installations on <A -HREF="http://landfill.bugzilla.org/bugzilla-2.22-branch/" +HREF="http://landfill.bugzilla.org/bugzilla-tip/" TARGET="_top" >Landfill</A >. @@ -11099,6 +11716,21 @@ VALIGN="TOP" ></LI ><LI ><P +> As you file the bug, you can also attach a document (testcase, patch, + or screenshot of the problem). + </P +></LI +><LI +><P +> Depending on the Bugzilla installation you are using and the product in + which you are filing the bug, you can also request developers to consider + your bug in different ways (such as requesting review for the patch you + just attached, requesting your bug to block the next release of the + product, and many other product specific requests). + </P +></LI +><LI +><P > Now is a good time to read your bug report again. Remove all misspellings, otherwise your bug may not be found by developers running queries for some specific words, and so your bug would not get any attention. @@ -11181,18 +11813,25 @@ CLASS="filename" </P ><P > If you have a really large attachment, something that does not need to - be recorded forever (as most attachments are), you can mark your - attachment as a <SPAN + be recorded forever (as most attachments are), or something that is too + big for your database, you can mark your attachment as a + <SPAN CLASS="QUOTE" >"Big File"</SPAN ->, assuming the administrator of the - installation has enabled this feature. Big Files are stored directly on - disk instead of in the database, and can be deleted when it is no longer - needed. The maximum size of a <SPAN +>, assuming the administrator of the installation + has enabled this feature. Big Files are stored directly on disk instead + of in the database. The maximum size of a <SPAN CLASS="QUOTE" >"Big File"</SPAN -> is normally larger - than the maximum size of a regular attachment. +> is + normally larger than the maximum size of a regular attachment. Independently + of the storage system used, an administrator can delete these attachments + at any time. Nevertheless, if these files are stored in the database, the + <SPAN +CLASS="QUOTE" +>"allow_attachment_deletion"</SPAN +> parameter (which is turned off + by default) must be enabled in order to delete them. </P ><P > Also, if the administrator turned on the <SPAN @@ -11387,7 +12026,7 @@ CLASS="section" ><HR><H3 CLASS="section" ><A -NAME="AEN2234" +NAME="AEN2372" >5.8.1. Autolinkification</A ></H3 ><P @@ -11551,7 +12190,7 @@ NAME="userpreferences" >5.10. User Preferences</A ></H2 ><P ->Once you have logged in, you can customize various aspects of +>Once you have logged in, you can customise various aspects of Bugzilla via the "Edit prefs" link in the page footer. The preferences are split into three tabs:</P ><DIV @@ -12080,7 +12719,7 @@ CLASS="section" ><HR><H4 CLASS="section" ><A -NAME="AEN2362" +NAME="AEN2500" >5.11.2.1. Creating Charts</A ></H4 ><P @@ -12120,7 +12759,7 @@ CLASS="section" ><HR><H4 CLASS="section" ><A -NAME="AEN2369" +NAME="AEN2507" >5.11.2.2. Creating New Data Sets</A ></H4 ><P @@ -12338,7 +12977,7 @@ NAME="whining-overview" </P ><P > The next step is to specify when the Event is to be run (the Schedule) - and what searches are to be performed (the Queries). + and what searches are to be performed (the Searches). </P ></DIV ><DIV @@ -12446,20 +13085,20 @@ CLASS="section" CLASS="section" ><A NAME="whining-query" ->5.13.3. Whining Queries</A +>5.13.3. Whining Searches</A ></H3 ><P -> Each whining event is associated with zero or more queries. A query is - a saved search that is executed on the schedule specified (see above). - You start out with zero queries attached to the event (which means that - the event will not run, as there will never be any results to return). - To add a query, press the "Add a new query" button. +> Each whining event is associated with zero or more searches. A search + is any saved search to be run as part of the specified schedule (see + above). You start out without any searches associated with the event + (which means that the event will not run, as there will never be any + results to return). To add a search, press the "Include search" button. </P ><P -> The first field to examine in your new query is the Sort field. Queries - are executed, and results returned, in the order specified by the Sort - field. Queries with lower Sort values will run before queries with - higher Sort values. +> The first field to examine in your newly added search is the Sort field. + Searches are run, and results included, in the order specified by the + Sort field. Searches with smaller Sort values will run before searches + with bigger Sort values. </P ><P > The next field to examine is the Search field. This is where you @@ -12549,7 +13188,7 @@ CLASS="section" ><HR><H3 CLASS="section" ><A -NAME="AEN2422" +NAME="AEN2560" >5.13.4. Saving Your Changes</A ></H3 ><P @@ -12596,14 +13235,65 @@ CLASS="chapter" ><A NAME="customization" ></A ->Chapter 6. Customizing Bugzilla</H1 +>Chapter 6. Customising Bugzilla</H1 ><DIV CLASS="section" ><H2 CLASS="section" ><A +NAME="cust-skins" +>6.1. Custom Skins</A +></H2 +><P +> Bugzilla allows you to have multiple skins. These are custom CSS and possibly + also custom images for Bugzilla. To create a new custom skin, you have two + choices: + <P +></P +><UL +><LI +><P +> Make a single CSS file, and put it in the + <TT +CLASS="filename" +>skins/contrib</TT +> directory. + </P +></LI +><LI +><P +> Make a directory that contains all the same CSS file + names as <TT +CLASS="filename" +>skins/standard/</TT +>, and put + your directory in <TT +CLASS="filename" +>skins/contrib/</TT +>. + </P +></LI +></UL +> + </P +><P +> After you put the file or the directory there, make sure to run checksetup.pl + so that it can reset the file permissions correctly. + </P +><P +> After you have installed the new skin, it will show up as an option in the + user's General Preferences. If you would like to force a particular skin on all + users, just select it in the Default Preferences and then uncheck "Enabled" on + the preference. + </P +></DIV +><DIV +CLASS="section" +><HR><H2 +CLASS="section" +><A NAME="cust-templates" ->6.1. Template Customization</A +>6.2. Template Customization</A ></H2 ><P > Administrators can configure the look and feel of Bugzilla without @@ -12616,7 +13306,7 @@ NAME="cust-templates" determined by the user's browser. More information is available in <A HREF="#template-http-accept" ->Section 6.1.6</A +>Section 6.2.6</A >. </P ><DIV @@ -12625,7 +13315,7 @@ CLASS="section" CLASS="section" ><A NAME="template-directory" ->6.1.1. Template Directory Structure</A +>6.2.1. Template Directory Structure</A ></H3 ><P > The template directory structure starts with top level directory @@ -12697,7 +13387,7 @@ CLASS="section" CLASS="section" ><A NAME="template-method" ->6.1.2. Choosing a Customization Method</A +>6.2.2. Choosing a Customization Method</A ></H3 ><P > If you want to edit Bugzilla's templates, the first decision @@ -12897,7 +13587,7 @@ CLASS="section" CLASS="section" ><A NAME="template-edit" ->6.1.3. How To Edit Templates</A +>6.2.3. How To Edit Templates</A ></H3 ><DIV CLASS="note" @@ -12985,7 +13675,7 @@ CLASS="section" CLASS="section" ><A NAME="template-formats" ->6.1.4. Template Formats and Types</A +>6.2.4. Template Formats and Types</A ></H3 ><P > Some CGI's have the ability to use more than one template. For example, @@ -13093,7 +13783,7 @@ CLASS="section" CLASS="section" ><A NAME="template-specific" ->6.1.5. Particular Templates</A +>6.2.5. Particular Templates</A ></H3 ><P > There are a few templates you may be particularly interested in @@ -13361,7 +14051,7 @@ CLASS="section" CLASS="section" ><A NAME="template-http-accept" ->6.1.6. Configuring Bugzilla to Detect the User's Language</A +>6.2.6. Configuring Bugzilla to Detect the User's Language</A ></H3 ><P >Bugzilla honours the user's Accept: HTTP header. You can install @@ -13402,7 +14092,7 @@ CLASS="section" CLASS="section" ><A NAME="cust-hooks" ->6.2. Template Hooks</A +>6.3. The Bugzilla Extension Mechanism</A ></H2 ><DIV CLASS="warning" @@ -13425,7 +14115,7 @@ ALT="Warning"></TD ALIGN="LEFT" VALIGN="TOP" ><P -> Template Hooks require Template Toolkit version 2.12 or +> Custom extensions require Template Toolkit version 2.12 or above, or the application of a patch. See <A HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=239112" TARGET="_top" @@ -13438,29 +14128,71 @@ TARGET="_top" ></TABLE ></DIV ><P -> Template hooks are a way for extensions to Bugzilla to insert code - into the standard Bugzilla templates without modifying the template files - themselves. The hooks mechanism defines a consistent API for extending - the standard templates in a way that cleanly separates standard code - from extension code. Hooks reduce merge conflicts and make it easier - to write extensions that work across multiple versions of Bugzilla, - making upgrading a Bugzilla installation with installed extensions easier. +> Extensions are a way for extensions to Bugzilla to insert code + into the standard Bugzilla templates and source files + without modifying these files themselves. The extension mechanism + defines a consistent API for extending the standard templates and source files + in a way that cleanly separates standard code from extension code. + Hooks reduce merge conflicts and make it easier to write extensions that work + across multiple versions of Bugzilla, making upgrading a Bugzilla installation + with installed extensions easier. Furthermore, they make it easy to install + and remove extensions as each extension is nothing more than a + simple directory structure. + </P +><P +> There are two main types of hooks: code hooks and template hooks. Code + hooks allow extensions to invoke code at specific points in various + source files, while template hooks allow extensions to add elements to + the Bugzilla user interface. + </P +><P +> A hook is just a named place in a standard source or template file + where extension source code or template files for that hook get processed. + Each extension has a corresponding directory in the Bugzilla directory + tree (<TT +CLASS="filename" +>BUGZILLA_ROOT/extensions/extension_name</TT +>). Hooking + an extension source file or template to a hook is as simple as putting + the extension file into extension's template or code directory. + When Bugzilla processes the source file or template and reaches the hook, + it will process all extension files in the hook's directory. + The hooks themselves can be added into any source file or standard template + upon request by extension authors. + </P +><P +> To use hooks to extend Bugzilla, first make sure there is + a hook at the appropriate place within the source file or template you + want to extend. The exact appearance of a hook depends on if the hook + is a code hook or a template hook. </P ><P -> A template hook is just a named place in a standard template file - where extension template files for that hook get processed. Each hook - has a corresponding directory in the Bugzilla directory tree. Hooking an - extension template to a hook is as simple as putting the extension file - into the hook's directory. When Bugzilla processes the standard template - and reaches the hook, it will process all extension templates in the - hook's directory. The hooks themselves can be added into any standard - template upon request by extension authors. +> Code hooks appear in Bugzilla source files as a single method call + in the format <VAR +CLASS="literal" +>Bugzilla::Hook->process("<VAR +CLASS="varname" +>name</VAR +>");</VAR +>. + for instance, <TT +CLASS="filename" +>enter_bug.cgi</TT +> may invoke the hook + "<VAR +CLASS="varname" +>enter_bug-defaultvars</VAR +>". Thus, a source file at + <TT +CLASS="filename" +>BUGZILLA_ROOT/extensions/EXTENSION_NAME/code/enter_bug-entrydefaultvars.pl</TT +> + will be automatically invoked when the code hook is reached. </P ><P -> To use hooks to extend a Bugzilla template, first make sure there is - a hook at the appropriate place within the template you want to extend. - Hooks appear in the standard Bugzilla templates as a single directive - in the format +> + Template hooks appear in the standard Bugzilla templates as a + single directive in the format <VAR CLASS="literal" >[% Hook.process("<VAR @@ -13471,12 +14203,11 @@ CLASS="varname" where <VAR CLASS="varname" >name</VAR -> is the unique (within that template) - name of the hook. +> is the unique name of the hook. </P ><P -> If you aren't sure which template you want to extend or just want - to browse the available hooks, either use your favorite multi-file search +> If you aren't sure what you want to extend or just want to browse the + available hooks, either use your favorite multi-file search tool (e.g. <B CLASS="command" >grep</B @@ -13484,23 +14215,15 @@ CLASS="command" for occurrences of <CODE CLASS="methodname" >Hook.process</CODE -> or browse - the directory tree in - <TT -CLASS="filename" ->BUGZILLA_ROOT/template/en/extension/hook/</TT ->, - which contains a directory for each hook in the following location: - </P -><P -> <TT -CLASS="filename" ->BUGZILLA_ROOT/template/en/extension/hook/PATH_TO_STANDARD_TEMPLATE/STANDARD_TEMPLATE_NAME/HOOK_NAME/</TT -> +> or the source + files for occurrences of <CODE +CLASS="methodname" +>Bugzilla::Hook::process</CODE +>. </P ><P -> If there is no hook at the appropriate place within the Bugzilla template - you want to extend, +> If there is no hook at the appropriate place within the Bugzilla + source file or template you want to extend, <A HREF="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=User%20Interface" TARGET="_top" @@ -13515,12 +14238,13 @@ BORDER="0" ><TBODY ><TR ><TD ->the template for which you are requesting a hook;</TD +>the source or template file for which you are + requesting a hook;</TD ></TR ><TR ><TD -> where in the template you would like the hook to be placed - (line number/position for latest version of template in CVS +> where in the file you would like the hook to be placed + (line number/position for latest version of the file in CVS or description of location); </TD ></TR @@ -13538,12 +14262,8 @@ BORDER="0" ></P ><P > The Bugzilla reviewers will promptly review each hook request, - name the hook, add it to the template, check the new version - of the template into CVS, and create the corresponding directory in - <TT -CLASS="filename" ->BUGZILLA_ROOT/template/en/extension/hook/</TT ->. + name the hook, add it to the template or source file, and check + the new version of the template into CVS. </P ><P > You may optionally attach a patch to the bug which implements the hook @@ -13557,12 +14277,12 @@ CLASS="filename" </P ><P > After making sure the hook you need exists (or getting it added if not), - add your extension template to the directory within the Bugzilla - directory tree corresponding to the hook. + add your extension to the directory within the Bugzilla + extensions tree corresponding to the hook. </P ><P -> That's it! Now, when the standard template containing the hook - is processed, your extension template will be processed at the point +> That's it! Now, when the source file or template containing the hook + is processed, your extension file will be processed at the point where the hook appears. </P ><P @@ -13618,19 +14338,12 @@ CLASS="programlisting" ></TR ></TABLE ><P -> The corresponding directory for this hook is +> The corresponding extension file for this hook is <TT CLASS="filename" ->BUGZILLA_ROOT/template/en/extension/hook/global/useful-links.html.tmpl/edit/</TT +>BUGZILLA_ROOT/extensions/projman/template/en/hook/global/useful-links-edit.html.tmpl</TT >. - </P -><P -> You put a template named - <TT -CLASS="filename" ->projman-edit-projects.html.tmpl</TT -> - into that directory with the following content: + You then create that template file and add the following constant: </P ><TABLE BORDER="0" @@ -13655,6 +14368,44 @@ CLASS="literal" > group. </P ><P +> Now, let us say your extension adds a custom "project_manager" field + to enter_bug.cgi. You want to modify the CGI script to set the default + project manager to be productname@company.com. Looking at + <TT +CLASS="filename" +>enter_bug.cgi</TT +>, you see the enter_bug-entrydefaultvars + hook near the bottom of the file before the default form values are set. + The corresponding extension source file for this hook is located at + <TT +CLASS="filename" +>BUGZILLA_ROOT/extensions/projman/code/enter_bug-entrydefaultvars.pl</TT +>. + You then create that file and add the following: + </P +><TABLE +BORDER="0" +BGCOLOR="#E0E0E0" +WIDTH="100%" +><TR +><TD +><FONT +COLOR="#000000" +><PRE +CLASS="programlisting" +>$default{'project_manager'} = $product.'@company.com';</PRE +></FONT +></TD +></TR +></TABLE +><P +> This code will be invoked whenever enter_bug.cgi is executed. + Assuming that the rest of the customization was completed (e.g. the + custom field was added to the enter_bug template and the required hooks + were used in process_bug.cgi), the new field will now have this + default value. + </P +><P > Notes: </P ><P @@ -13662,29 +14413,14 @@ CLASS="literal" ><UL ><LI ><P -> You may want to prefix your extension template names - with the name of your extension, e.g. - <TT -CLASS="filename" ->projman-foo.html.tmpl</TT ->, - so they do not conflict with the names of templates installed by - other extensions. - </P -></LI -><LI -><P > If your extension includes entirely new templates in addition to - extensions of standard templates, it should install those new - templates into an extension-specific subdirectory of the + extensions of standard templates, it should store those new + templates in its <TT CLASS="filename" ->BUGZILLA_ROOT/template/en/extension/</TT +>BUGZILLA_ROOT/extensions/template/en/</TT > - directory. The <TT -CLASS="filename" ->extension/</TT -> directory, like the + directory. Extension template directories, like the <TT CLASS="filename" >default/</TT @@ -13692,7 +14428,7 @@ CLASS="filename" CLASS="filename" >custom/</TT > - directories, is part of the template search path, so putting templates + directories, are part of the template search path, so putting templates there enables them to be found by the template processor. </P ><P @@ -13703,45 +14439,45 @@ CLASS="filename" > directory (i.e. templates added by the specific installation), then in the <TT CLASS="filename" ->extension/</TT -> - directory (i.e. templates added by extensions), and finally in the +>extensions/</TT +> + directory (i.e. templates added by extensions), and finally in the <TT CLASS="filename" >default/</TT > directory (i.e. the standard Bugzilla - templates). Thus extension templates can override standard templates, - but installation-specific templates override both. - </P -><P -> Note that overriding standard templates with extension templates - gives you great power but also makes upgrading an installation harder. - As with custom templates, we recommend using this functionality - sparingly and only when absolutely necessary. + templates). Thus, installation-specific templates override both + default and extension templates. </P ></LI ><LI ><P -> Installation customizers can also take advantage of hooks when adding - code to a Bugzilla template. To do so, create directories in +> If you are looking to customize Bugzilla, you can also take advantage + of template hooks. To do so, create a directory in <TT CLASS="filename" >BUGZILLA_ROOT/template/en/custom/hook/</TT > - equivalent to the directories in + that corresponds to the hook you wish to use, then place your + customization templates into those directories. For example, + if you wanted to use the hook "end" in <TT CLASS="filename" ->BUGZILLA_ROOT/template/en/extension/hook/</TT -> - for the hooks you want to use, then place your customization templates - into those directories. +>global/useful-links.html.tmpl</TT +>, you would + create the directory <TT +CLASS="filename" +>BUGZILLA_ROOT/template/en/custom/hook/ + global/useful-links.html.tmpl/end/</TT +> and add your customization + template to this directory. </P ><P > Obviously this method of customizing Bugzilla only lets you add code - to the standard templates; you cannot change the existing code. - Nevertheless, for those customizations that only add code, this method - can reduce conflicts when merging changes, making upgrading - your customized Bugzilla installation easier. + to the standard source files and templates; you cannot change the + existing code. Nevertheless, for those customizations that only add + code, this method can reduce conflicts when merging changes, + making upgrading your customized Bugzilla installation easier. </P ></LI ></UL @@ -13752,7 +14488,7 @@ CLASS="section" CLASS="section" ><A NAME="cust-change-permissions" ->6.3. Customizing Who Can Change What</A +>6.4. Customizing Who Can Change What</A ></H2 ><DIV CLASS="warning" @@ -13797,19 +14533,19 @@ VALIGN="TOP" ><P > For maximum flexibility, customizing this means editing Bugzilla's Perl code. This gives the administrator complete control over exactly who is - allowed to do what. The relevant function is called + allowed to do what. The relevant method is called <TT CLASS="filename" ->CheckCanChangeField()</TT +>check_can_change_field()</TT >, and is found in <TT CLASS="filename" ->process_bug.cgi</TT -> in your - Bugzilla directory. If you open that file and search for +>Bug.pm</TT +> in your + Bugzilla/ directory. If you open that file and search for <SPAN CLASS="QUOTE" ->"sub CheckCanChangeField"</SPAN +>"sub check_can_change_field"</SPAN >, you'll find it. </P ><P @@ -13951,86 +14687,10 @@ CLASS="filename" ></TABLE ></DIV ><P -> For a list of possible field names, look in - <TT -CLASS="filename" ->data/versioncache</TT -> for the list called - <TT -CLASS="filename" ->@::log_columns</TT ->. If you need help writing custom - rules for your organization, ask in the newsgroup. +> For a list of possible field names, look at the bugs table in the + database. If you need help writing custom rules for your organization, + ask in the newsgroup. </P -><DIV -CLASS="section" -><HR><H3 -CLASS="section" -><A -NAME="cust-group-check" ->6.3.1. Modification in UserInGroup()</A -></H3 -><P -> The <TT -CLASS="filename" ->UserInGroup()</TT -> function in the - <TT -CLASS="filename" ->Bugzilla/User.pm</TT -> module only accepts - one argument since 2.17.5: the name of a group. This check - is now always done against the current user, and a second - argument specifying the user ID to check this group against - is no longer valid and an error is thrown if you try to. - </P -></DIV -></DIV -><DIV -CLASS="section" -><HR><H2 -CLASS="section" -><A -NAME="dbmodify" ->6.4. Modifying Your Running System</A -></H2 -><P -> Bugzilla optimizes database lookups by storing all relatively - static information in the <TT -CLASS="filename" ->versioncache</TT -> - file, located in the <TT -CLASS="filename" ->data/</TT -> - subdirectory under your installation directory. - </P -><P -> If you make a change to the structural data in your database (the - versions table for example), or to the <SPAN -CLASS="QUOTE" ->"constants"</SPAN -> - encoded in <TT -CLASS="filename" ->defparams.pl</TT ->, you will need to remove - the cached content from the data directory (by doing a - <B -CLASS="command" ->rm data/versioncache</B ->), or your changes won't show up. - </P -><P -> <TT -CLASS="filename" ->versioncache</TT -> gets regenerated automatically - whenever it's more than an hour old, so Bugzilla will eventually - notice your changes by itself, but generally you want it to notice - right away, so that you can test things. - </P ></DIV ><DIV CLASS="section" @@ -14218,51 +14878,57 @@ HREF="#faq-general" ><DL ><DT >A.1.1. <A +HREF="#faq-general-tryout" +> Can I try out Bugzilla somewhere? + </A +></DT +><DT +>A.1.2. <A HREF="#faq-general-license" > What license is Bugzilla distributed under? </A ></DT ><DT ->A.1.2. <A +>A.1.3. <A HREF="#faq-general-support" > How do I get commercial support for Bugzilla? </A ></DT ><DT ->A.1.3. <A +>A.1.4. <A HREF="#faq-general-companies" > What major companies or projects are currently using Bugzilla for bug-tracking? </A ></DT ><DT ->A.1.4. <A +>A.1.5. <A HREF="#faq-general-maintainers" > Who maintains Bugzilla? </A ></DT ><DT ->A.1.5. <A +>A.1.6. <A HREF="#faq-general-compare" > How does Bugzilla stack up against other bug-tracking databases? </A ></DT ><DT ->A.1.6. <A +>A.1.7. <A HREF="#faq-general-bzmissing" > Why doesn't Bugzilla offer this or that feature or compatibility with this other tracking software? </A ></DT ><DT ->A.1.7. <A +>A.1.8. <A HREF="#faq-general-mysql" > Why MySQL? I'm interested in seeing Bugzilla run on PostgreSQL/Sybase/Oracle/Msql/MSSQL. </A ></DT ><DT ->A.1.8. <A +>A.1.9. <A HREF="#faq-general-bonsaitools" > What is <TT CLASS="filename" @@ -14271,7 +14937,7 @@ CLASS="filename" </A ></DT ><DT ->A.1.9. <A +>A.1.10. <A HREF="#faq-general-perlpath" > My perl is located at <TT CLASS="filename" @@ -14285,13 +14951,13 @@ CLASS="filename" </A ></DT ><DT ->A.1.10. <A +>A.1.11. <A HREF="#faq-general-cookie" > Is there an easy way to change the Bugzilla cookie name? </A ></DT ><DT ->A.1.11. <A +>A.1.12. <A HREF="#faq-mod-perl" > Does bugzilla run under <TT CLASS="filename" @@ -14299,6 +14965,12 @@ CLASS="filename" >? </A ></DT +><DT +>A.1.13. <A +HREF="#faq-general-selinux" +> How can Bugzilla be made to work under SELinux? + </A +></DT ></DL ></DD ><DT @@ -14718,10 +15390,40 @@ CLASS="qandaentry" CLASS="question" ><P ><A -NAME="faq-general-license" +NAME="faq-general-tryout" ></A ><B >A.1.1. </B +> + Can I try out Bugzilla somewhere? + </P +></DIV +><DIV +CLASS="answer" +><P +><B +> </B +> + If you want to take a test ride, there are test installations + at <A +HREF="http://landfill.bugzilla.org/" +TARGET="_top" +>http://landfill.bugzilla.org/</A +>, + ready to play with directly from your browser. + </P +></DIV +></DIV +><DIV +CLASS="qandaentry" +><DIV +CLASS="question" +><P +><A +NAME="faq-general-license" +></A +><B +>A.1.2. </B > What license is Bugzilla distributed under? </P @@ -14750,7 +15452,7 @@ CLASS="question" NAME="faq-general-support" ></A ><B ->A.1.2. </B +>A.1.3. </B > How do I get commercial support for Bugzilla? </P @@ -14786,7 +15488,7 @@ CLASS="question" NAME="faq-general-companies" ></A ><B ->A.1.3. </B +>A.1.4. </B > What major companies or projects are currently using Bugzilla for bug-tracking? @@ -14829,7 +15531,7 @@ CLASS="question" NAME="faq-general-maintainers" ></A ><B ->A.1.4. </B +>A.1.5. </B > Who maintains Bugzilla? </P @@ -14858,7 +15560,7 @@ CLASS="question" NAME="faq-general-compare" ></A ><B ->A.1.5. </B +>A.1.6. </B > How does Bugzilla stack up against other bug-tracking databases? </P @@ -14903,7 +15605,7 @@ CLASS="question" NAME="faq-general-bzmissing" ></A ><B ->A.1.6. </B +>A.1.7. </B > Why doesn't Bugzilla offer this or that feature or compatibility with this other tracking software? @@ -14922,7 +15624,7 @@ CLASS="answer" </P ><P > The best way to make an enhancement request is to <A -HREF="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla" +HREF="https://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla" TARGET="_top" >file a bug at bugzilla.mozilla.org</A @@ -14973,7 +15675,7 @@ CLASS="question" NAME="faq-general-mysql" ></A ><B ->A.1.7. </B +>A.1.8. </B > Why MySQL? I'm interested in seeing Bugzilla run on PostgreSQL/Sybase/Oracle/Msql/MSSQL. @@ -14989,46 +15691,53 @@ CLASS="answer" and was available for the hardware Netscape intended to run it on. </P ><P -> There is currently work in progress to make Bugzilla work on - PostgreSQL; track the progress of this initiative in <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=98304" +> Bugzilla 2.20 contains experimental support for PostgreSQL. + Bugzilla 2.22 contains complete, stable support for PostgreSQL. + As of this release, using PostgreSQL with Bugzilla should + be as stable as using MySQL. If you experience any problems + with PostgreSQL compatibility, they will be taken as + seriously as if you were running MySQL. + </P +><P +> Red Hat once ran a version of Bugzilla that worked on Oracle, + but that was long, long ago; that version (Bugzilla 2.8) is + now obsolete, insecure, and totally unsupported. + </P +><P +> In August of 2005, Wim Coekaerts (Director of Linux + Engineering at Oracle Corporation) wrote to Dave Miller + confirming that Oracle intends to implement and support + Bugzilla. Since then, no further information has been + forthcoming. Track progress at + <A +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=189947" TARGET="_top" ->bug 98304</A +> Bug 189947</A >. </P ><P -> Sybase support is no longer being worked on. Even if it eventually - happens, it's VERY unlikely to work without the end-user-company - having to stick a few developers on making several manual changes. - Sybase is just NOT very standards-compliant (despite all the hype), - and it turned out that way too much had to be changed to make it - work -- like moving half of the application logic into stored +> Sybase support is no longer being worked on. Even if it + eventually happens, it's VERY unlikely to work without + the end-user-company having to stick a few developers on + making several manual changes. Sybase is just NOT very + standards-compliant (despite all the hype), and it turned + out that way too much had to be changed to make it work -- + like moving half of the application logic into stored procedures to get any kind of decent performance out of it. <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=173130" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=173130" TARGET="_top" ->Bug - 173130</A +> Bug 173130</A > is the relevant bug. </P ><P -> Red Hat once ran a version of Bugzilla that worked on Oracle, - but that was long, long ago; that version (Bugzilla 2.8) is - now obsolete, insecure, and totally unsupported. Red Hat's - current Bugzilla (based on Bugzilla 2.17.1) uses PostgreSQL, - and work is being done to merge those changes into the main - distribution. (See above.) At this time we know of no recent - ports of Bugzilla to Oracle. (In our honest opinion, Bugzilla - doesn't need what Oracle offers.) - </P -><P > <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=237862" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=237862" TARGET="_top" ->Bug - 237862</A -> is a good bug to read through if you'd like to see - what progress is being made on general database compatibility. +> Bug 237862</A +> is a good bug to read through if you'd + like to see what progress is being made on general database + compatibility. </P ></DIV ></DIV @@ -15041,7 +15750,7 @@ CLASS="question" NAME="faq-general-bonsaitools" ></A ><B ->A.1.8. </B +>A.1.9. </B > What is <TT CLASS="filename" @@ -15083,7 +15792,7 @@ CLASS="question" NAME="faq-general-perlpath" ></A ><B ->A.1.9. </B +>A.1.10. </B > My perl is located at <TT CLASS="filename" @@ -15256,7 +15965,7 @@ CLASS="question" NAME="faq-general-cookie" ></A ><B ->A.1.10. </B +>A.1.11. </B > Is there an easy way to change the Bugzilla cookie name? </P @@ -15280,7 +15989,7 @@ CLASS="question" NAME="faq-mod-perl" ></A ><B ->A.1.11. </B +>A.1.12. </B > Does bugzilla run under <TT CLASS="filename" @@ -15305,6 +16014,36 @@ TARGET="_top" </P ></DIV ></DIV +><DIV +CLASS="qandaentry" +><DIV +CLASS="question" +><P +><A +NAME="faq-general-selinux" +></A +><B +>A.1.13. </B +> + How can Bugzilla be made to work under SELinux? + </P +></DIV +><DIV +CLASS="answer" +><P +><B +> </B +> + Unfortunately there are no step-by-step instructions, + but the following URL contains hints on how to do it: + <A +HREF="http://fedora.redhat.com/docs/selinux-apache-fc3/sn-debugging-and-customizing.html" +TARGET="_top" +>http://fedora.redhat.com/docs/selinux-apache-fc3/sn-debugging-and-customizing.html</A +> + </P +></DIV +></DIV ></DIV ><DIV CLASS="qandadiv" @@ -15368,7 +16107,7 @@ CLASS="answer" > There is no GUI for adding fields to Bugzilla at this time. You can follow development of this feature in <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=91037" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=91037" TARGET="_top" >bug 91037</A > @@ -15397,9 +16136,9 @@ CLASS="answer" > </B > Yes. Look at <A -HREF="http://bugzilla.mozilla.org/report.cgi" +HREF="https://bugzilla.mozilla.org/report.cgi" TARGET="_top" ->http://bugzilla.mozilla.org/report.cgi</A +>https://bugzilla.mozilla.org/report.cgi</A > for samples of what Bugzilla can do in reporting and graphing. Fuller documentation is provided in <A @@ -15603,7 +16342,7 @@ TARGET="_top" Some admin interfaces have been templatized (for easy localization) but many of them are still available in English only. Also, there may be issues with the charset not being declared. See <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=126266" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=126266" TARGET="_top" >bug 126226</A > @@ -15795,7 +16534,7 @@ CLASS="answer" See the documentation on Customization for more details, specifically <A HREF="#template-specific" ->Section 6.1.5</A +>Section 6.2.5</A >. </P ></DIV @@ -15985,7 +16724,7 @@ CLASS="QUOTE" ><P > See also the instructions in <A HREF="#upgrade-cvs" ->Section 3.13.2.1</A +>Section 3.14.3.1</A >. </P ></DIV @@ -16250,7 +16989,7 @@ CLASS="command" >this makes MySQL as secure as taping a $100 to the floor of a football stadium bathroom for safekeeping.</EM -> +> </P ><DIV CLASS="warning" @@ -16550,7 +17289,7 @@ CLASS="QUOTE" >, which can be found in <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=6679" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=6679" TARGET="_top" >bug 6679</A @@ -16562,7 +17301,7 @@ TARGET="_top" > An updated (and much-expanded) version of this functionality is due to be released as part of Bugzilla 2.20; see <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=185090" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=185090" TARGET="_top" >bug 185090</A @@ -16894,6 +17633,99 @@ VALIGN="TOP" ></TR ></TABLE ></DIV +><P +> You may also be suffering from a client version mismatch: + </P +><P +> MySQL 4.1 and up uses an authentication protocol based on + a password hashing algorithm that is incompatible with that + used by older clients. If you upgrade the server to 4.1, + attempts to connect to it with an older client may fail + with the following message: + </P +><P +> <TABLE +BORDER="0" +BGCOLOR="#E0E0E0" +WIDTH="100%" +><TR +><TD +><FONT +COLOR="#000000" +><PRE +CLASS="screen" +><SAMP +CLASS="prompt" +>shell></SAMP +> mysql + Client does not support authentication protocol requested + by server; consider upgrading MySQL client + </PRE +></FONT +></TD +></TR +></TABLE +> + </P +><P +> To solve this problem, you should use one of the following + approaches: + </P +><P +> <P +></P +><UL +><LI +><P +> Upgrade all client programs to use a 4.1.1 or newer + client library. + </P +></LI +><LI +><P +> When connecting to the server with a pre-4.1 client + program, use an account that still has a + pre-4.1-style password. + </P +></LI +><LI +><P +> Reset the password to pre-4.1 style for each user + that needs to use a pre-4.1 client program. + This can be done using the SET PASSWORD statement + and the OLD_PASSWORD() function: + <TABLE +BORDER="0" +BGCOLOR="#E0E0E0" +WIDTH="100%" +><TR +><TD +><FONT +COLOR="#000000" +><PRE +CLASS="screen" +> <SAMP +CLASS="prompt" +>mysql></SAMP +> SET PASSWORD FOR + <SAMP +CLASS="prompt" +> -></SAMP +> ' some_user '@' some_host ' = OLD_PASSWORD(' newpwd '); + </PRE +></FONT +></TD +></TR +></TABLE +> + </P +></LI +></UL +> + + </P +><P +> </P ></DIV ></DIV ><DIV @@ -17051,7 +17883,7 @@ CLASS="answer" ><P > Microsoft has some advice on this matter, as well: <A -NAME="AEN3115" +NAME="AEN3284" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -17138,7 +17970,7 @@ CLASS="command" ></LI ></OL > - I reckon TimeDate and Data::Dumper come with the activeperl. + I reckon TimeDate comes with the activeperl. You can check the ActiveState site for packages for installation through PPM. <A HREF="http://www.activestate.com/Packages/" @@ -17297,7 +18129,7 @@ BORDER="0" ><TR ><TD > <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=35195" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=35195" TARGET="_top" >Bug 35195</A > @@ -17307,13 +18139,13 @@ CLASS="QUOTE" > checkbox to the UI. It has two patches attached to it: <A -HREF="http://bugzilla.mozilla.org/showattachment.cgi?attach_id=8029" +HREF="https://bugzilla.mozilla.org/showattachment.cgi?attach_id=8029" TARGET="_top" >attachment 8029</A > was originally created for Bugzilla 2.12, while <A -HREF="http://bugzilla.mozilla.org/showattachment.cgi?attach_id=91372" +HREF="https://bugzilla.mozilla.org/showattachment.cgi?attach_id=91372" TARGET="_top" >attachment 91372</A > @@ -17323,7 +18155,7 @@ TARGET="_top" ><TR ><TD > <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=37613" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=37613" TARGET="_top" >Bug 37613</A @@ -17546,20 +18378,20 @@ CLASS="answer" > </B > Try <A -HREF="http://bugzilla.mozilla.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=Bugzilla" +HREF="https://bugzilla.mozilla.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=Bugzilla" TARGET="_top" > this link</A > to view current bugs or requests for enhancement for Bugzilla. </P ><P -> You can view bugs marked for 3.0 release +> You can view bugs marked for 3.2 release <A -HREF="http://bugzilla.mozilla.org/buglist.cgi?product=Bugzilla&target_milestone=Bugzilla+&bz-nextver;" +HREF="https://bugzilla.mozilla.org/buglist.cgi?product=Bugzilla&target_milestone=Bugzilla+&bz-nextver;" TARGET="_top" >here</A >. - This list includes bugs for the 3.0 release that have already + This list includes bugs for the 3.2 release that have already been fixed and checked into CVS. Please consult the <A HREF="http://www.bugzilla.org/" @@ -17600,7 +18432,7 @@ CLASS="answer" > </B > This is well-documented in <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=49862" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=49862" TARGET="_top" >bug 49862</A @@ -17647,7 +18479,7 @@ TYPE="1" > Enter a bug into bugzilla.mozilla.org for the <SPAN CLASS="QUOTE" >"<A -HREF="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla" +HREF="https://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla" TARGET="_top" >Bugzilla</A >"</SPAN @@ -17681,7 +18513,7 @@ CLASS="QUOTE" ><LI ><P > Announce your patch and the associated URL - (http://bugzilla.mozilla.org/show_bug.cgi?id=XXXXXX) + (https://bugzilla.mozilla.org/show_bug.cgi?id=XXXXXX) for discussion in the newsgroup (mozilla.support.bugzilla). You'll get a really good, fairly immediate reaction to the @@ -18018,89 +18850,8 @@ CLASS="section" ><HR><H2 CLASS="section" ><A -NAME="trouble-filetemp" ->B.6. Your vendor has not defined Fcntl macro O_NOINHERIT</A -></H2 -><P ->This is caused by a bug in the version of - <SPAN -CLASS="productname" ->File::Temp</SPAN -> that is distributed with perl - 5.6.0. Many minor variations of this error have been reported: - </P -><TABLE -BORDER="0" -BGCOLOR="#E0E0E0" -WIDTH="100%" -><TR -><TD -><FONT -COLOR="#000000" -><PRE -CLASS="programlisting" ->Your vendor has not defined Fcntl macro O_NOINHERIT, used -at /usr/lib/perl5/site_perl/5.6.0/File/Temp.pm line 208. - -Your vendor has not defined Fcntl macro O_EXLOCK, used -at /usr/lib/perl5/site_perl/5.6.0/File/Temp.pm line 210. - -Your vendor has not defined Fcntl macro O_TEMPORARY, used -at /usr/lib/perl5/site_perl/5.6.0/File/Temp.pm line 233.</PRE -></FONT -></TD -></TR -></TABLE -><P ->Numerous people have reported that upgrading to version 5.6.1 - or higher solved the problem for them. A less involved fix is to apply - the following patch, which is also - available as a <A -HREF="../xml/filetemp.patch" -TARGET="_top" ->patch file</A ->. - </P -><TABLE -BORDER="0" -BGCOLOR="#E0E0E0" -WIDTH="100%" -><TR -><TD -><FONT -COLOR="#000000" -><PRE -CLASS="programlisting" ->--- File/Temp.pm.orig Thu Feb 6 16:26:00 2003 -+++ File/Temp.pm Thu Feb 6 16:26:23 2003 -@@ -205,6 +205,7 @@ - # eg CGI::Carp - local $SIG{__DIE__} = sub {}; - local $SIG{__WARN__} = sub {}; -+ local *CORE::GLOBAL::die = sub {}; - $bit = &$func(); - 1; - }; -@@ -226,6 +227,7 @@ - # eg CGI::Carp - local $SIG{__DIE__} = sub {}; - local $SIG{__WARN__} = sub {}; -+ local *CORE::GLOBAL::die = sub {}; - $bit = &$func(); - 1; - };</PRE -></FONT -></TD -></TR -></TABLE -></DIV -><DIV -CLASS="section" -><HR><H2 -CLASS="section" -><A NAME="trbl-relogin-everyone" ->B.7. Everybody is constantly being forced to relogin</A +>B.6. Everybody is constantly being forced to relogin</A ></H2 ><P >The most-likely cause is that the <SPAN @@ -18144,7 +18895,7 @@ NAME="trbl-relogin-everyone-share" >Example B-1. Examples of urlbase/cookiepath pairs for sharing login cookies</B ></P ><A -NAME="AEN3317" +NAME="AEN3478" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -18185,7 +18936,7 @@ NAME="trbl-relogin-everyone-restrict" >Example B-2. Examples of urlbase/cookiepath pairs to restrict the login cookie</B ></P ><A -NAME="AEN3324" +NAME="AEN3485" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -18228,7 +18979,7 @@ CLASS="section" CLASS="section" ><A NAME="trbl-relogin-some" ->B.8. Some users are constantly being forced to relogin</A +>B.7. Some users are constantly being forced to relogin</A ></H2 ><P >First, make sure cookies are enabled in the user's browser. @@ -18267,7 +19018,7 @@ CLASS="section" CLASS="section" ><A NAME="trbl-index" ->B.9. <TT +>B.8. <TT CLASS="filename" >index.cgi</TT > doesn't show up unless specified in the URL</A @@ -18298,7 +19049,7 @@ CLASS="section" CLASS="section" ><A NAME="trbl-passwd-encryption" ->B.10. checksetup.pl reports "Client does not support authentication protocol +>B.9. checksetup.pl reports "Client does not support authentication protocol requested by server..."</A ></H2 ><P @@ -18391,7 +19142,7 @@ ALT="Warning"></TD ALIGN="LEFT" VALIGN="TOP" ><P -> These files pre-date the templatization work done as part of the +> These files pre-date the templatisation work done as part of the 2.16 release, and have not been updated. </P ></TD @@ -18703,29 +19454,6 @@ VALIGN="TOP" ></TABLE ></DIV ><P -> AppConfig: - <P -CLASS="literallayout" -><br> - CPAN Download Page: <A -HREF="http://search.cpan.org/src/ABW/AppConfig-1.56/lib/AppConfig.pm" -TARGET="_top" ->http://search.cpan.org/src/ABW/AppConfig-1.56/lib/AppConfig.pm</A -><br> - PPM Download Link: <A -HREF="http://landfill.bugzilla.org/ppm/AppConfig.ppd" -TARGET="_top" ->http://landfill.bugzilla.org/ppm/AppConfig.ppd</A -><br> - Documentation: <A -HREF="http://search.cpan.org/~abw/AppConfig-1.56/lib/AppConfig.pm" -TARGET="_top" ->http://search.cpan.org/~abw/AppConfig-1.56/lib/AppConfig.pm</A -><br> - </P -> - </P -><P > CGI: <P CLASS="literallayout" @@ -18875,25 +19603,6 @@ TARGET="_top" > </P ><P -> File::Temp: - <P -CLASS="literallayout" -><br> - CPAN Download Page: <A -HREF="http://search.cpan.org/dist/File-Temp/" -TARGET="_top" ->http://search.cpan.org/dist/File-Temp/</A -><br> - PPM Download Page: Part of core distribution.<br> - Documentation: <A -HREF="http://www.perldoc.com/perl5.8.0/lib/File/Temp.html" -TARGET="_top" ->http://www.perldoc.com/perl5.8.0/lib/File/Temp.html</A -><br> - </P -> - </P -><P > Template-Toolkit: <P CLASS="literallayout" @@ -18917,25 +19626,6 @@ TARGET="_top" > </P ><P -> Text::Wrap: - <P -CLASS="literallayout" -><br> - CPAN Download Page: <A -HREF="http://search.cpan.org/dist/Text-Tabs+Wrap/" -TARGET="_top" ->http://search.cpan.org/dist/Text-Tabs+Wrap/</A -><br> - PPM Download Link: Part of core distribution.<br> - Documentation: <A -HREF="http://www.perldoc.com/perl5.8.0/lib/Text/Wrap.html" -TARGET="_top" ->http://www.perldoc.com/perl5.8.0/lib/Text/Wrap.html</A -><br> - </P -> - </P -><P > GD: <P CLASS="literallayout" @@ -18978,29 +19668,6 @@ TARGET="_top" > </P ><P -> MIME::Base64: - <P -CLASS="literallayout" -><br> - CPAN Download Page: <A -HREF="http://search.cpan.org/dist/MIME-Base64/" -TARGET="_top" ->http://search.cpan.org/dist/MIME-Base64/</A -><br> - PPM Download Link: <A -HREF="http://ppm.activestate.com/PPMPackages/zips/8xx-builds-only/Windows/MIME-Base64-2.20.zip" -TARGET="_top" ->http://ppm.activestate.com/PPMPackages/zips/8xx-builds-only/Windows/MIME-Base64-2.20.zip</A -><br> - Documentation: <A -HREF="http://search.cpan.org/dist/MIME-Base64/Base64.pm" -TARGET="_top" ->http://search.cpan.org/dist/MIME-Base64/Base64.pm</A -><br> - </P -> - </P -><P > MIME::Parser (part of MIME-tools): <P CLASS="literallayout" @@ -19178,7 +19845,7 @@ NAME="gfdl" ><P >Version 1.1, March 2000</P ><A -NAME="AEN3526" +NAME="AEN3669" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -19641,7 +20308,7 @@ NAME="gfdl-howto" of the License in the document and put the following copyright and license notices just after the title page:</P ><A -NAME="AEN3616" +NAME="AEN3759" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -19678,7 +20345,7 @@ CLASS="glossdiv" ><H1 CLASS="glossdiv" ><A -NAME="AEN3621" +NAME="AEN3764" >0-9, high ascii</A ></H1 ><DL @@ -20184,11 +20851,11 @@ NAME="gloss-mta" ></DT > (MTA)<DD ><P ->A Message Transport Agent is used to control the flow of email - on a system. The <A -HREF="http://search.cpan.org/dist/MailTools/Mail/Mailer.pm" +>A Message Transport Agent is used to control the flow of email on a system. + The <A +HREF="http://search.cpan.org/dist/Email-Send/lib/Email/Send.pm" TARGET="_top" ->Mail::Mailer</A +>Email::Send</A > Perl module, which Bugzilla uses to send email, can be configured to use many different underlying implementations for actually sending the @@ -20596,7 +21263,7 @@ NAME="gloss-zarro" Terry had the following to say: </P ><A -NAME="AEN3868" +NAME="AEN4011" ></A ><TABLE BORDER="0" diff --git a/docs/html/CVS/Entries b/docs/html/CVS/Entries new file mode 100644 index 000000000..90c8bc96d --- /dev/null +++ b/docs/html/CVS/Entries @@ -0,0 +1,2 @@ +/.cvsignore/1.1/Tue Sep 5 19:00:55 2006//TBUGZILLA-3_0 +D/api//// diff --git a/docs/html/CVS/Repository b/docs/html/CVS/Repository new file mode 100644 index 000000000..937103c2e --- /dev/null +++ b/docs/html/CVS/Repository @@ -0,0 +1 @@ +mozilla/webtools/bugzilla/docs/html diff --git a/docs/html/CVS/Root b/docs/html/CVS/Root new file mode 100644 index 000000000..cdb6f4a07 --- /dev/null +++ b/docs/html/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot diff --git a/docs/html/CVS/Tag b/docs/html/CVS/Tag new file mode 100644 index 000000000..efdc1ff3e --- /dev/null +++ b/docs/html/CVS/Tag @@ -0,0 +1 @@ +NBUGZILLA-3_0 diff --git a/docs/html/about.html b/docs/html/about.html index b8bba1c9e..f5d213c05 100644 --- a/docs/html/about.html +++ b/docs/html/about.html @@ -7,12 +7,10 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="PREVIOUS" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="NEXT" TITLE="Copyright Information" @@ -36,8 +34,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -154,8 +151,7 @@ ACCESSKEY="N" WIDTH="33%" ALIGN="left" VALIGN="top" ->The Bugzilla Guide - 2.22.3 - Release</TD +>The Bugzilla Guide - 3.0 Release</TD ><TD WIDTH="34%" ALIGN="center" diff --git a/docs/html/administration.html b/docs/html/administration.html index 18a6db5ef..17c8e2d00 100644 --- a/docs/html/administration.html +++ b/docs/html/administration.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="PREVIOUS" TITLE="UNIX (non-root) Installation Notes" @@ -35,8 +34,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -166,81 +164,110 @@ HREF="flags-overview.html#flags-admin" ></DD ><DT >3.9. <A +HREF="custom-fields.html" +>Custom Fields</A +></DT +><DD +><DL +><DT +>3.9.1. <A +HREF="custom-fields.html#add-custom-fields" +>Adding Custom Fields</A +></DT +><DT +>3.9.2. <A +HREF="custom-fields.html#edit-custom-fields" +>Editing Custom Fields</A +></DT +><DT +>3.9.3. <A +HREF="custom-fields.html#delete-custom-fields" +>Deleting Custom Fields</A +></DT +></DL +></DD +><DT +>3.10. <A HREF="edit-values.html" >Legal Values</A ></DT ><DD ><DL ><DT ->3.9.1. <A +>3.10.1. <A HREF="edit-values.html#edit-values-list" >Viewing/Editing legal values</A ></DT ><DT ->3.9.2. <A +>3.10.2. <A HREF="edit-values.html#edit-values-delete" >Deleting legal values</A ></DT ></DL ></DD ><DT ->3.10. <A +>3.11. <A HREF="voting.html" >Voting</A ></DT ><DT ->3.11. <A +>3.12. <A HREF="quips.html" >Quips</A ></DT ><DT ->3.12. <A +>3.13. <A HREF="groups.html" >Groups and Group Security</A ></DT ><DD ><DL ><DT ->3.12.1. <A -HREF="groups.html#AEN1545" +>3.13.1. <A +HREF="groups.html#AEN1660" >Creating Groups</A ></DT ><DT ->3.12.2. <A -HREF="groups.html#AEN1572" +>3.13.2. <A +HREF="groups.html#AEN1687" >Assigning Users to Groups</A ></DT ><DT ->3.12.3. <A -HREF="groups.html#AEN1582" +>3.13.3. <A +HREF="groups.html#AEN1697" >Assigning Group Controls to Products</A ></DT ><DT ->3.12.4. <A -HREF="groups.html#AEN1600" +>3.13.4. <A +HREF="groups.html#AEN1715" >Common Applications of Group Controls</A ></DT ></DL ></DD ><DT ->3.13. <A +>3.14. <A HREF="upgrading.html" >Upgrading to New Releases</A ></DT ><DD ><DL ><DT ->3.13.1. <A +>3.14.1. <A HREF="upgrading.html#upgrading-version-defns" >Version Definitions</A ></DT ><DT ->3.13.2. <A +>3.14.2. <A +HREF="upgrading.html#upgrading-notifications" +>Upgrading - Notifications</A +></DT +><DT +>3.14.3. <A HREF="upgrading.html#upgrading-methods" >Upgrading - Methods and Procedure</A ></DT ><DT ->3.13.3. <A +>3.14.4. <A HREF="upgrading.html#upgrading-completion" >Completing Your Upgrade</A ></DT diff --git a/docs/html/api/.cvsignore b/docs/html/api/.cvsignore new file mode 100644 index 000000000..10d63bfdf --- /dev/null +++ b/docs/html/api/.cvsignore @@ -0,0 +1,3 @@ +*.html +Bugzilla +contrib diff --git a/docs/html/api/Bugzilla.html b/docs/html/api/Bugzilla.html new file mode 100644 index 000000000..3f9a373b4 --- /dev/null +++ b/docs/html/api/Bugzilla.html @@ -0,0 +1,213 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla - Semi-persistent collection of various objects used by scripts and modules</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla; + + sub someModulesSub { + Bugzilla->dbh->prepare(...); + Bugzilla->template->process(...); + }</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Several Bugzilla 'things' are used by a variety of modules and scripts. This includes database handles, template objects, and so on.</p> + +<p>This module is a singleton intended as a central place to store these objects. This approach has several advantages:</p> + +<ul> +<li>They're not global variables, so we don't have issues with them staying around with mod_perl</li> + +<li>Everything is in one central place, so it's easy to access, modify, and maintain</li> + +<li>Code in modules can get access to these objects without having to have them all passed from the caller, and the caller's caller, and....</li> + +<li>We can reuse objects across requests using mod_perl where appropriate (eg templates), whilst destroying those which are only valid for a single request (such as the current user)</li> +</ul> + +<p>Note that items accessible via this object are demand-loaded when requested.</p> + +<p>For something to be added to this object, it should either be able to benefit from persistence when run under mod_perl (such as the a <code class="code">template</code> object), or should be something which is globally required by a large ammount of code (such as the current <code class="code">user</code> object).</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<p>Note that all <code class="code">Bugzilla</code> functionality is method based; use <code class="code">Bugzilla->dbh</code> rather than <code class="code">Bugzilla::dbh</code>. Nothing cares about this now, but don't rely on that.</p> + +<dl> +<dt><a name="template" +><code class="code">template</code></a></dt> + +<dd> +<p>The current <code class="code">Template</code> object, to be used for output</p> + +<dt><a name="template_inner" +><code class="code">template_inner</code></a></dt> + +<dd> +<p>If you ever need a <a href="./Bugzilla/Template.html" class="podlinkpod" +>Bugzilla::Template</a> object while you're already processing a template, use this. Also use it if you want to specify the language to use. If no argument is passed, it uses the last language set. If the argument is "" (empty string), the language is reset to the current one (the one used by Bugzilla->template).</p> + +<dt><a name="cgi" +><code class="code">cgi</code></a></dt> + +<dd> +<p>The current <code class="code">cgi</code> object. Note that modules should <b>not</b> be using this in general. Not all Bugzilla actions are cgi requests. Its useful as a convenience method for those scripts/templates which are only use via CGI, though.</p> + +<dt><a name="user" +><code class="code">user</code></a></dt> + +<dd> +<p><code class="code">undef</code> if there is no currently logged in user or if the login code has not yet been run. If an sudo session is in progress, the <code class="code">Bugzilla::User</code> corresponding to the person who is being impersonated. If no session is in progress, the current <code class="code">Bugzilla::User</code>.</p> + +<dt><a name="set_user" +><code class="code">set_user</code></a></dt> + +<dd> +<p>Allows you to directly set what <a href="#user" class="podlinkpod" +>"user"</a> will return. You can use this if you want to bypass <a href="#login" class="podlinkpod" +>"login"</a> for some reason and directly "log in" a specific <a href="./Bugzilla/User.html" class="podlinkpod" +>Bugzilla::User</a>. Be careful with it, though!</p> + +<dt><a name="sudoer" +><code class="code">sudoer</code></a></dt> + +<dd> +<p><code class="code">undef</code> if there is no currently logged in user, the currently logged in user is not in the <i>sudoer</i> group, or there is no session in progress. If an sudo session is in progress, returns the <code class="code">Bugzilla::User</code> object corresponding to the person who logged in and initiated the session. If no session is in progress, returns the <code class="code">Bugzilla::User</code> object corresponding to the currently logged in user.</p> + +<dt><a +><code class="code">sudo_request</code> This begins an sudo session for the current request. It is meant to be used when a session has just started. For normal use, sudo access should normally be set at login time. +<dt><a name="login" +><code class="code">login</code></a></dt> + +<dd> +<p>Logs in a user, returning a <code class="code">Bugzilla::User</code> object, or <code class="code">undef</code> if there is no logged in user. See <a href="./Bugzilla/Auth.html" class="podlinkpod" +>Bugzilla::Auth</a>, and <a href="./Bugzilla/User.html" class="podlinkpod" +>Bugzilla::User</a>.</p> + +<dt><a name="logout($option)" +><code class="code">logout($option)</code></a></dt> + +<dd> +<p>Logs out the current user, which involves invalidating user sessions and cookies. Three options are available from <a href="./Bugzilla/Constants.html" class="podlinkpod" +>Bugzilla::Constants</a>: LOGOUT_CURRENT (the default), LOGOUT_ALL or LOGOUT_KEEP_CURRENT.</p> + +<dt><a name="logout_user($user)" +><code class="code">logout_user($user)</code></a></dt> + +<dd> +<p>Logs out the specified user (invalidating all his sessions), taking a Bugzilla::User instance.</p> + +<dt><a name="logout_by_id($id)" +><code class="code">logout_by_id($id)</code></a></dt> + +<dd> +<p>Logs out the user with the id specified. This is a compatibility function to be used in callsites where there is only a userid and no Bugzilla::User instance.</p> + +<dt><a name="logout_request" +><code class="code">logout_request</code></a></dt> + +<dd> +<p>Essentially, causes calls to <code class="code">Bugzilla->user</code> to return <code class="code">undef</code>. This has the effect of logging out a user for the current request only; cookies and database sessions are left intact.</p> + +<dt><a name="error_mode" +><code class="code">error_mode</code></a></dt> + +<dd> +<p>Call either <code class="code">Bugzilla-</code>error_mode(Bugzilla::Constants::ERROR_MODE_DIE)> or <code class="code">Bugzilla-</code>error_mode(Bugzilla::Constants::ERROR_MODE_DIE_SOAP_FAULT)> to change this flag's default of <code class="code">Bugzilla::Constants::ERROR_MODE_WEBPAGE</code> and to indicate that errors should be passed to error mode specific error handlers rather than being sent to a browser and finished with an exit().</p> + +<p>This is useful, for example, to keep <code class="code">eval</code> blocks from producing wild HTML on errors, making it easier for you to catch them. (Remember to reset the error mode to its previous value afterwards, though.)</p> + +<p><code class="code">Bugzilla-</code>error_mode> will return the current state of this flag.</p> + +<p>Note that <code class="code">Bugzilla-</code>error_mode> is being called by <code class="code">Bugzilla-</code>usage_mode> on usage mode changes.</p> + +<dt><a name="usage_mode" +><code class="code">usage_mode</code></a></dt> + +<dd> +<p>Call either <code class="code">Bugzilla-</code>usage_mode(Bugzilla::Constants::USAGE_MODE_CMDLINE)> or <code class="code">Bugzilla-</code>usage_mode(Bugzilla::Constants::USAGE_MODE_WEBSERVICE)> near the beginning of your script to change this flag's default of <code class="code">Bugzilla::Constants::USAGE_MODE_BROWSER</code> and to indicate that Bugzilla is being called in a non-interactive manner. This influences error handling because on usage mode changes, <code class="code">usage_mode</code> calls <code class="code">Bugzilla-</code>error_mode> to set an error mode which makes sense for the usage mode.</p> + +<p><code class="code">Bugzilla-</code>usage_mode> will return the current state of this flag.</p> + +<dt><a name="installation_mode" +><code class="code">installation_mode</code></a></dt> + +<dd> +<p>Determines whether or not installation should be silent. See <a href="./Bugzilla/Constants.html" class="podlinkpod" +>Bugzilla::Constants</a> for the <code class="code">INSTALLATION_MODE</code> constants.</p> + +<dt><a name="installation_answers" +><code class="code">installation_answers</code></a></dt> + +<dd> +<p>Returns a hashref representing any "answers" file passed to <em class="code">checksetup.pl</em>, used to automatically answer or skip prompts.</p> + +<dt><a name="dbh" +><code class="code">dbh</code></a></dt> + +<dd> +<p>The current database handle. See <a href="./DBI.html" class="podlinkpod" +>DBI</a>.</p> + +<dt><a name="switch_to_shadow_db" +><code class="code">switch_to_shadow_db</code></a></dt> + +<dd> +<p>Switch from using the main database to using the shadow database.</p> + +<dt><a name="switch_to_main_db" +><code class="code">switch_to_main_db</code></a></dt> + +<dd> +<p>Change the database object to refer to the main database.</p> + +<dt><a name="params" +><code class="code">params</code></a></dt> + +<dd> +<p>The current Parameters of Bugzilla, as a hashref. If <code class="code">data/params</code> does not exist, then we return an empty hashref. If <code class="code">data/params</code> is unreadable or is not valid perl, we <code class="code">die</code>.</p> + +<dt><a name="hook_args" +><code class="code">hook_args</code></a></dt> + +<dd> +<p>If you are running inside a code hook (see <a href="./Bugzilla/Hook.html" class="podlinkpod" +>Bugzilla::Hook</a>) this is how you get the arguments passed to the hook.</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Attachment.html b/docs/html/api/Bugzilla/Attachment.html new file mode 100644 index 000000000..179c3251a --- /dev/null +++ b/docs/html/api/Bugzilla/Attachment.html @@ -0,0 +1,253 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Attachment</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Attachment</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Instance_Properties'>Instance Properties</a> + <li class='indexItem indexItem2'><a href='#Class_Methods'>Class Methods</a> + </ul> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Attachment - a file related to a bug that a user has uploaded to the Bugzilla server</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Attachment; + + # Get the attachment with the given ID. + my $attachment = Bugzilla::Attachment->get($attach_id); + + # Get the attachments with the given IDs. + my $attachments = Bugzilla::Attachment->get_list($attach_ids);</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This module defines attachment objects, which represent files related to bugs that users upload to the Bugzilla server.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Instance_Properties" +>Instance Properties</a></h2> + +<dl> +<dt><a name="id" +><code class="code">id</code></a></dt> + +<dd> +<p>the unique identifier for the attachment</p> +</dd> +</dl> + +<dl> +<dt><a name="bug_id" +><code class="code">bug_id</code></a></dt> + +<dd> +<p>the ID of the bug to which the attachment is attached</p> +</dd> +</dl> + +<dl> +<dt><a name="description" +><code class="code">description</code></a></dt> + +<dd> +<p>user-provided text describing the attachment</p> +</dd> +</dl> + +<dl> +<dt><a name="contenttype" +><code class="code">contenttype</code></a></dt> + +<dd> +<p>the attachment's MIME media type</p> +</dd> +</dl> + +<dl> +<dt><a name="attacher" +><code class="code">attacher</code></a></dt> + +<dd> +<p>the user who attached the attachment</p> +</dd> +</dl> + +<dl> +<dt><a name="attached" +><code class="code">attached</code></a></dt> + +<dd> +<p>the date and time on which the attacher attached the attachment</p> +</dd> +</dl> + +<dl> +<dt><a name="filename" +><code class="code">filename</code></a></dt> + +<dd> +<p>the name of the file the attacher attached</p> +</dd> +</dl> + +<dl> +<dt><a name="ispatch" +><code class="code">ispatch</code></a></dt> + +<dd> +<p>whether or not the attachment is a patch</p> +</dd> +</dl> + +<dl> +<dt><a name="isurl" +><code class="code">isurl</code></a></dt> + +<dd> +<p>whether or not the attachment is a URL</p> +</dd> +</dl> + +<dl> +<dt><a name="isobsolete" +><code class="code">isobsolete</code></a></dt> + +<dd> +<p>whether or not the attachment is obsolete</p> +</dd> +</dl> + +<dl> +<dt><a name="isprivate" +><code class="code">isprivate</code></a></dt> + +<dd> +<p>whether or not the attachment is private</p> +</dd> +</dl> + +<dl> +<dt><a name="data" +><code class="code">data</code></a></dt> + +<dd> +<p>the content of the attachment</p> +</dd> +</dl> + +<dl> +<dt><a name="datasize" +><code class="code">datasize</code></a></dt> + +<dd> +<p>the length (in characters) of the attachment content</p> +</dd> +</dl> + +<dl> +<dt><a name="flags" +><code class="code">flags</code></a></dt> + +<dd> +<p>flags that have been set on the attachment</p> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Class_Methods" +>Class Methods</a></h2> + +<dl> +<dt><a name="get_attachments_by_bug($bug_id)" +><code class="code">get_attachments_by_bug($bug_id)</code></a></dt> + +<dd> +<p>Description: retrieves and returns the attachments the currently logged in user can view for the given bug.</p> + +<p>Params: <code class="code">$bug_id</code> - integer - the ID of the bug for which to retrieve and return attachments.</p> + +<p>Returns: a reference to an array of attachment objects.</p> + +<dt><a name="validate_is_patch()" +><code class="code">validate_is_patch()</code></a></dt> + +<dd> +<p>Description: validates the "patch" flag passed in by CGI.</p> + +<p>Returns: 1 on success.</p> + +<dt><a name="validate_description()" +><code class="code">validate_description()</code></a></dt> + +<dd> +<p>Description: validates the description passed in by CGI.</p> + +<p>Returns: 1 on success.</p> + +<dt><a name="validate_content_type()" +><code class="code">validate_content_type()</code></a></dt> + +<dd> +<p>Description: validates the content type passed in by CGI.</p> + +<p>Returns: 1 on success.</p> + +<dt><a name="validate_can_edit($attachment,_$product_id)" +><code class="code">validate_can_edit($attachment, $product_id)</code></a></dt> + +<dd> +<p>Description: validates if the user is allowed to view and edit the attachment. Only the submitter or someone with editbugs privs can edit it. Only the submitter and users in the insider group can view private attachments.</p> + +<p>Params: $attachment - the attachment object being edited. $product_id - the product ID the attachment belongs to.</p> + +<p>Returns: 1 on success. Else an error is thrown.</p> + +<dt><a name="validate_obsolete($bug)" +><code class="code">validate_obsolete($bug)</code></a></dt> + +<dd> +<p>Description: validates if attachments the user wants to mark as obsolete really belong to the given bug and are not already obsolete. Moreover, a user cannot mark an attachment as obsolete if he cannot view it (due to restrictions on it).</p> + +<p>Params: $bug - The bug object obsolete attachments should belong to.</p> + +<p>Returns: 1 on success. Else an error is thrown.</p> + +<dt><a name="insert_attachment_for_bug($throw_error,_$bug,_$user,_$timestamp,_$hr_vars)" +><code class="code">insert_attachment_for_bug($throw_error, $bug, $user, $timestamp, $hr_vars)</code></a></dt> + +<dd> +<p>Description: inserts an attachment from CGI input for the given bug.</p> + +<p>Params: <code class="code">$bug</code> - Bugzilla::Bug object - the bug for which to insert the attachment. <code class="code">$user</code> - Bugzilla::User object - the user we're inserting an attachment for. <code class="code">$timestamp</code> - scalar - timestamp of the insert as returned by SELECT NOW(). <code class="code">$hr_vars</code> - hash reference - reference to a hash of template variables.</p> + +<p>Returns: the ID of the new attachment.</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Auth.html b/docs/html/api/Bugzilla/Auth.html new file mode 100644 index 000000000..68d1f406f --- /dev/null +++ b/docs/html/api/Bugzilla/Auth.html @@ -0,0 +1,394 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Auth</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Auth</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#AUTHENTICATION_ERROR_CODES'>AUTHENTICATION ERROR CODES</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#AUTH_NODATA'>AUTH_NODATA</a> + <li class='indexItem indexItem2'><a href='#AUTH_ERROR'>AUTH_ERROR</a> + <li class='indexItem indexItem2'><a href='#AUTH_LOGINFAILED'>AUTH_LOGINFAILED</a> + <li class='indexItem indexItem2'><a href='#AUTH_NO_SUCH_USER'>AUTH_NO_SUCH_USER</a> + <li class='indexItem indexItem2'><a href='#AUTH_DISABLED'>AUTH_DISABLED</a> + </ul> + <li class='indexItem indexItem1'><a href='#LOGIN_TYPES'>LOGIN TYPES</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#LOGIN_OPTIONAL'>LOGIN_OPTIONAL</a> + <li class='indexItem indexItem2'><a href='#LOGIN_NORMAL'>LOGIN_NORMAL</a> + <li class='indexItem indexItem2'><a href='#LOGIN_REQUIRED'>LOGIN_REQUIRED</a> + </ul> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Login'>Login</a> + <li class='indexItem indexItem2'><a href='#Info_Methods'>Info Methods</a> + </ul> + <li class='indexItem indexItem1'><a href='#STRUCTURE'>STRUCTURE</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#The_Info_Getter'>The Info Getter</a> + <li class='indexItem indexItem2'><a href='#The_Verifier'>The Verifier</a> + <li class='indexItem indexItem2'><a href='#The_Persistence_Mechanism'>The Persistence Mechanism</a> + <li class='indexItem indexItem2'><a href='#Other_Things_We_Do'>Other Things We Do</a> + <li class='indexItem indexItem2'><a href='#The_%24login_data_Hash'>The $login_data Hash</a> + </ul> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Auth - An object that authenticates the login credentials for a user.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Handles authentication for Bugzilla users.</p> + +<p>Authentication from Bugzilla involves two sets of modules. +One set is used to obtain the username/password (from CGI, +email, +etc), +and the other set uses this data to authenticate against the datasource (the Bugzilla DB, +LDAP, +PAM, +etc.).</p> + +<p>Modules for obtaining the username/password are subclasses of <a href="../Bugzilla/Auth/Login.html" class="podlinkpod" +>Bugzilla::Auth::Login</a>, +and modules for authenticating are subclasses of <a href="../Bugzilla/Auth/Verify.html" class="podlinkpod" +>Bugzilla::Auth::Verify</a>.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="AUTHENTICATION_ERROR_CODES" +>AUTHENTICATION ERROR CODES</a></h1> + +<p>Whenever a method in the <code class="code">Bugzilla::Auth</code> family fails in some way, +it will return a hashref containing at least a single key called <code class="code">failure</code>. +<code class="code">failure</code> will point to an integer error code, +and depending on the error code the hashref may contain more data.</p> + +<p>The error codes are explained here below.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="AUTH_NODATA" +><code class="code">AUTH_NODATA</code></a></h2> + +<p>Insufficient login data was provided by the user. +This may happen in several cases, +such as cookie authentication when the cookie is not present.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="AUTH_ERROR" +><code class="code">AUTH_ERROR</code></a></h2> + +<p>An error occurred when trying to use the login mechanism.</p> + +<p>The hashref will also contain an <code class="code">error</code> element, +which is the name of an error from <code class="code">template/en/default/global/code-error.html</code> -- the same type of error that would be thrown by <a href="../Bugzilla/Error/ThrowCodeError.html" class="podlinkpod" +>Bugzilla::Error::ThrowCodeError</a>.</p> + +<p>The hashref *may* contain an element called <code class="code">details</code>, +which is a hashref that should be passed to <a href="../Bugzilla/Error/ThrowCodeError.html" class="podlinkpod" +>Bugzilla::Error::ThrowCodeError</a> as the various fields to be used in the error message.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="AUTH_LOGINFAILED" +><code class="code">AUTH_LOGINFAILED</code></a></h2> + +<p>An incorrect username or password was given.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="AUTH_NO_SUCH_USER" +><code class="code">AUTH_NO_SUCH_USER</code></a></h2> + +<p>This is an optional more-specific version of <code class="code">AUTH_LOGINFAILED</code>. +Modules should throw this error when they discover that the requested user account actually does not exist, +according to them.</p> + +<p>That is, +for example, +<a href="../Bugzilla/Auth/Verify/LDAP.html" class="podlinkpod" +>Bugzilla::Auth::Verify::LDAP</a> would throw this if the user didn't exist in LDAP.</p> + +<p>The difference between <code class="code">AUTH_NO_SUCH_USER</code> and <code class="code">AUTH_LOGINFAILED</code> should never be communicated to the user, +for security reasons.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="AUTH_DISABLED" +><code class="code">AUTH_DISABLED</code></a></h2> + +<p>The user successfully logged in, +but their account has been disabled. +Usually this is throw only by <code class="code">Bugzilla::Auth::login</code>.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="LOGIN_TYPES" +>LOGIN TYPES</a></h1> + +<p>The <code class="code">login</code> function (below) can do different types of login, +depending on what constant you pass into it:</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="LOGIN_OPTIONAL" +><code class="code">LOGIN_OPTIONAL</code></a></h2> + +<p>A login is never required to access this data. +Attempting to login is still useful, +because this allows the page to be personalised. +Note that an incorrect login will still trigger an error, +even though the lack of a login will be OK.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="LOGIN_NORMAL" +><code class="code">LOGIN_NORMAL</code></a></h2> + +<p>A login may or may not be required, +depending on the setting of the <i>requirelogin</i> parameter. +This is the default if you don't specify a type.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="LOGIN_REQUIRED" +><code class="code">LOGIN_REQUIRED</code></a></h2> + +<p>A login is always required to access this data.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<p>These are methods that can be called on a <code class="code">Bugzilla::Auth</code> object itself.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Login" +>Login</a></h2> + +<dl> +<dt><a name="login($type)" +><code class="code">login($type)</code></a></dt> + +<dd> +<p>Description: Logs a user in. +For more details on how this works internally, +see the section entitled "STRUCTURE." Params: $type - One of the Login Types from above. +Returns: An authenticated <code class="code">Bugzilla::User</code>. +Or, +if the type was not <code class="code">LOGIN_REQUIRED</code>, +then we return an empty <code class="code">Bugzilla::User</code> if no login data was passed in.</p> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Info_Methods" +>Info Methods</a></h2> + +<p>These are methods that give information about the Bugzilla::Auth object.</p> + +<dl> +<dt><a name="can_change_password" +><code class="code">can_change_password</code></a></dt> + +<dd> +<p>Description: Tells you whether or not the current login system allows changing passwords. +Params: None Returns: <code class="code">true</code> if users and administrators should be allowed to change passwords, +<code class="code">false</code> otherwise.</p> + +<dt><a name="can_login" +><code class="code">can_login</code></a></dt> + +<dd> +<p>Description: Tells you whether or not the current login system allows users to log in through the web interface. +Params: None Returns: <code class="code">true</code> if users can log in through the web interface, +<code class="code">false</code> otherwise.</p> + +<dt><a name="can_logout" +><code class="code">can_logout</code></a></dt> + +<dd> +<p>Description: Tells you whether or not the current login system allows users to log themselves out. +Params: None Returns: <code class="code">true</code> if users can log themselves out, +<code class="code">false</code> otherwise. +If a user isn't logged in, +we always return <code class="code">false</code>.</p> + +<dt><a name="user_can_create_account" +><code class="code">user_can_create_account</code></a></dt> + +<dd> +<p>Description: Tells you whether or not users are allowed to manually create their own accounts, +based on the current login system in use. +Note that this doesn't check the <code class="code">createemailregexp</code> parameter--you have to do that by yourself in your code. +Params: None Returns: <code class="code">true</code> if users are allowed to create new Bugzilla accounts, +<code class="code">false</code> otherwise.</p> + +<dt><a name="can_change_email" +><code class="code">can_change_email</code></a></dt> + +<dd> +<p>Description: Whether or not the current login system allows users to change their own email address. +Params: None Returns: <code class="code">true</code> if users can change their own email address, +<code class="code">false</code> otherwise.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="STRUCTURE" +>STRUCTURE</a></h1> + +<p>This section is mostly interesting to developers who want to implement a new authentication type. +It describes the general structure of the Bugzilla::Auth family, +and how the <code class="code">login</code> function works.</p> + +<p>A <code class="code">Bugzilla::Auth</code> object is essentially a collection of a few other objects: the "Info Getter," the "Verifier," and the "Persistence Mechanism."</p> + +<p>They are used inside the <code class="code">login</code> function in the following order:</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="The_Info_Getter" +>The Info Getter</a></h2> + +<p>This is a <code class="code">Bugzilla::Auth::Login</code> object. +Basically, +it gets the username and password from the user, +somehow. +Or, +it just gets enough information to uniquely identify a user, +and passes that on down the line. +(For example, +a <code class="code">user_id</code> is enough to uniquely identify a user, +even without a username and password.)</p> + +<p>Some Info Getters don't require any verification. +For example, +if we got the <code class="code">user_id</code> from a Cookie, +we don't need to check the username and password.</p> + +<p>If an Info Getter returns only a <code class="code">user_id</code> and no username/password, +then it MUST NOT require verification. +If an Info Getter requires verfication, +then it MUST return at least a <code class="code">username</code>.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="The_Verifier" +>The Verifier</a></h2> + +<p>This verifies that the username and password are valid.</p> + +<p>It's possible that some methods of verification don't require a password.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="The_Persistence_Mechanism" +>The Persistence Mechanism</a></h2> + +<p>This makes it so that the user doesn't have to log in on every page. +Normally this object just sends a cookie to the user's web browser, +as that's the most common method of "login persistence."</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Other_Things_We_Do" +>Other Things We Do</a></h2> + +<p>After we verify the username and password, +sometimes we automatically create an account in the Bugzilla database, +for certain authentication types. +We use the "Account Source" to get data about the user, +and create them in the database. +(Or, +if their data has changed since the last time they logged in, +their data gets updated.)</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="The_$login_data_Hash" +>The <code class="code">$login_data</code> Hash</a></h2> + +<p>All of the <code class="code">Bugzilla::Auth::Login</code> and <code class="code">Bugzilla::Auth::Verify</code> methods take an argument called <code class="code">$login_data</code>. +This is basically a hash that becomes more and more populated as we go through the <code class="code">login</code> function.</p> + +<p>All <code class="code">Bugzilla::Auth::Login</code> and <code class="code">Bugzilla::Auth::Verify</code> methods also *return* the <code class="code">$login_data</code> structure, +when they succeed. +They may have added new data to it.</p> + +<p>For all <code class="code">Bugzilla::Auth::Login</code> and <code class="code">Bugzilla::Auth::Verify</code> methods, +the rule is "you must return the same hashref you were passed in." You can modify the hashref all you want, +but you can't create a new one. +The only time you can return a new one is if you're returning some error code instead of the <code class="code">$login_data</code> structure.</p> + +<p>Each <code class="code">Bugzilla::Auth::Login</code> or <code class="code">Bugzilla::Auth::Verify</code> method explains in its documentation which <code class="code">$login_data</code> elements are required by it, +and which are set by it.</p> + +<p>Here are all of the elements that *may* be in <code class="code">$login_data</code>:</p> + +<dl> +<dt><a name="user_id" +><code class="code">user_id</code></a></dt> + +<dd> +<p>A Bugzilla <code class="code">user_id</code> that uniquely identifies a user.</p> + +<dt><a name="username" +><code class="code">username</code></a></dt> + +<dd> +<p>The username that was provided by the user.</p> + +<dt><a name="bz_username" +><code class="code">bz_username</code></a></dt> + +<dd> +<p>The username of this user inside of Bugzilla. +Sometimes this differs from <code class="code">username</code>.</p> + +<dt><a name="password" +><code class="code">password</code></a></dt> + +<dd> +<p>The password provided by the user.</p> + +<dt><a name="realname" +><code class="code">realname</code></a></dt> + +<dd> +<p>The real name of the user.</p> + +<dt><a name="extern_id" +><code class="code">extern_id</code></a></dt> + +<dd> +<p>Some string that uniquely identifies the user in an external account source. +If this <code class="code">extern_id</code> already exists in the database with a different username, +the username will be *changed* to be the username specified in this <code class="code">$login_data</code>.</p> + +<p>That is, +let's my extern_id is <code class="code">mkanat</code>. +I already have an account in Bugzilla with the username of <code class="code">mkanat@foo.com</code>. +But this time, +when I log in, +I have an extern_id of <code class="code">mkanat</code> and a <code class="code">username</code> of <code class="code">mkanat@bar.org</code>. +So now, +Bugzilla will automatically change my username to <code class="code">mkanat@bar.org</code> instead of <code class="code">mkanat@foo.com</code>.</p> + +<dt><a name="user" +><code class="code">user</code></a></dt> + +<dd> +<p>A <a href="../Bugzilla/User.html" class="podlinkpod" +>Bugzilla::User</a> object representing the authenticated user. +Note that <code class="code">Bugzilla::Auth::login</code> may modify this object at various points.</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Auth/Login.html b/docs/html/api/Bugzilla/Auth/Login.html new file mode 100644 index 000000000..977366ce7 --- /dev/null +++ b/docs/html/api/Bugzilla/Auth/Login.html @@ -0,0 +1,120 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Auth::Login</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Auth::Login</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#LOGIN_METHODS'>LOGIN METHODS</a> + <li class='indexItem indexItem1'><a href='#INFO_METHODS'>INFO METHODS</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Auth::Login - Gets username/password data from the user.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Bugzilla::Auth::Login is used to get information that uniquely identifies a user and allows us to authorize their Bugzilla access.</p> + +<p>It is mostly an abstract class, +requiring subclasses to implement most methods.</p> + +<p>Note that callers outside of the <code class="code">Bugzilla::Auth</code> package should never create this object directly. +Just create a <code class="code">Bugzilla::Auth</code> object and call <code class="code">login</code> on it.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="LOGIN_METHODS" +>LOGIN METHODS</a></h1> + +<p>These are methods that have to do with getting the actual login data from the user or handling a login somehow.</p> + +<p>These methods are abstract -- they MUST be implemented by a subclass.</p> + +<dl> +<dt><a name="get_login_info()" +><code class="code">get_login_info()</code></a></dt> + +<dd> +<p>Description: Gets a username/password from the user, +or some other information that uniquely identifies them. +Params: None Returns: A <code class="code">$login_data</code> hashref. +(See <a href="../../Bugzilla/Auth.html" class="podlinkpod" +>Bugzilla::Auth</a> for details.) The hashref MUST contain: <code class="code">user_id</code> *or* <code class="code">username</code> If this is a login method that requires verification, +the hashref MUST contain <code class="code">password</code>. +The hashref MAY contain <code class="code">realname</code> and <code class="code">extern_id</code>.</p> + +<dt><a name="fail_nodata()" +><code class="code">fail_nodata()</code></a></dt> + +<dd> +<p>Description: This function is called when Bugzilla doesn't get a username/password and the login type is <code class="code">LOGIN_REQUIRED</code> (See <a href="../../Bugzilla/Auth.html" class="podlinkpod" +>Bugzilla::Auth</a> for a description of <code class="code">LOGIN_REQUIRED</code>). +That is, +this handles <code class="code">AUTH_NODATA</code> in that situation.</p> + +<pre class="code"> This function MUST stop CGI execution when it is complete. + That is, it must call C<exit> or C<ThrowUserError> or some + such thing. +Params: None +Returns: Never Returns.</pre> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="INFO_METHODS" +>INFO METHODS</a></h1> + +<p>These are methods that describe the capabilities of this <code class="code">Bugzilla::Auth::Login</code> object. These are all no-parameter methods that return either <code class="code">true</code> or <code class="code">false</code>.</p> + +<dl> +<dt><a name="can_logout" +><code class="code">can_logout</code></a></dt> + +<dd> +<p>Whether or not users can log out if they logged in using this object. Defaults to <code class="code">true</code>.</p> + +<dt><a name="can_login" +><code class="code">can_login</code></a></dt> + +<dd> +<p>Whether or not users can log in through the web interface using this object. Defaults to <code class="code">true</code>.</p> + +<dt><a name="requires_persistence" +><code class="code">requires_persistence</code></a></dt> + +<dd> +<p>Whether or not we should send the user a cookie if they logged in with this method. Defaults to <code class="code">true</code>.</p> + +<dt><a name="requires_verification" +><code class="code">requires_verification</code></a></dt> + +<dd> +<p>Whether or not we should check the username/password that we got from this login method. Defaults to <code class="code">true</code>.</p> + +<dt><a name="user_can_create_account" +><code class="code">user_can_create_account</code></a></dt> + +<dd> +<p>Whether or not users can create accounts, if this login method is currently being used by the system. Defaults to <code class="code">false</code>.</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Auth/Verify.html b/docs/html/api/Bugzilla/Auth/Verify.html new file mode 100644 index 000000000..6152ab38a --- /dev/null +++ b/docs/html/api/Bugzilla/Auth/Verify.html @@ -0,0 +1,142 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Auth::Verify</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Auth::Verify</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#VERIFICATION_METHODS'>VERIFICATION METHODS</a> + <li class='indexItem indexItem1'><a href='#MODIFICATION_METHODS'>MODIFICATION METHODS</a> + <li class='indexItem indexItem1'><a href='#INFO_METHODS'>INFO METHODS</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Auth::Verify - An object that verifies usernames and passwords.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Bugzilla::Auth::Verify provides the "Verifier" part of the Bugzilla login process. +(For details, +see the "STRUCTURE" section of <a href="../../Bugzilla/Auth.html" class="podlinkpod" +>Bugzilla::Auth</a>.)</p> + +<p>It is mostly an abstract class, +requiring subclasses to implement most methods.</p> + +<p>Note that callers outside of the <code class="code">Bugzilla::Auth</code> package should never create this object directly. +Just create a <code class="code">Bugzilla::Auth</code> object and call <code class="code">login</code> on it.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="VERIFICATION_METHODS" +>VERIFICATION METHODS</a></h1> + +<p>These are the methods that have to do with the actual verification.</p> + +<p>Subclasses MUST implement these methods.</p> + +<dl> +<dt><a name="check_credentials($login_data)" +><code class="code">check_credentials($login_data)</code></a></dt> + +<dd> +<p>Description: Checks whether or not a username is valid. +Params: $login_data - A <code class="code">$login_data</code> hashref, +as described in <a href="../../Bugzilla/Auth.html" class="podlinkpod" +>Bugzilla::Auth</a>. +This <code class="code">$login_data</code> hashref MUST contain <code class="code">username</code>, +and SHOULD also contain <code class="code">password</code>. +Returns: A <code class="code">$login_data</code> hashref with <code class="code">bz_username</code> set. +This method may also set <code class="code">realname</code>. +It must avoid changing anything that is already set.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="MODIFICATION_METHODS" +>MODIFICATION METHODS</a></h1> + +<p>These are methods that change data in the actual authentication backend.</p> + +<p>These methods are optional, +they do not have to be implemented by subclasses.</p> + +<dl> +<dt><a name="create_or_update_user($login_data)" +><code class="code">create_or_update_user($login_data)</code></a></dt> + +<dd> +<p>Description: Automatically creates a user account in the database if it doesn't already exist, +or updates the account data if <code class="code">$login_data</code> contains newer information.</p> + +<p>Params: $login_data - A <code class="code">$login_data</code> hashref, +as described in <a href="../../Bugzilla/Auth.html" class="podlinkpod" +>Bugzilla::Auth</a>. +This <code class="code">$login_data</code> hashref MUST contain either <code class="code">user_id</code>, +<code class="code">bz_username</code>, +or <code class="code">username</code>. +If both <code class="code">username</code> and <code class="code">bz_username</code> are specified, +<code class="code">bz_username</code> is used as the login name of the user to create in the database. +It MAY also contain <code class="code">extern_id</code>, +in which case it still MUST contain <code class="code">bz_username</code> or <code class="code">username</code>. +It MAY contain <code class="code">password</code> and <code class="code">realname</code>.</p> + +<p>Returns: A hashref with one element, +<code class="code">user</code>, +which is a <a href="../../Bugzilla/User.html" class="podlinkpod" +>Bugzilla::User</a> object. +May also return a login error as described in <a href="../../Bugzilla/Auth.html" class="podlinkpod" +>Bugzilla::Auth</a>.</p> + +<p>Note: This method is not abstract, +it is actually implemented and creates accounts in the Bugzilla database. +Subclasses should probably all call the <code class="code">Bugzilla::Auth::Verify</code> version of this function at the end of their own <code class="code">create_or_update_user</code>.</p> + +<dt><a name="change_password($user,_$password)" +><code class="code">change_password($user, +$password)</code></a></dt> + +<dd> +<p>Description: Modifies the user's password in the authentication backend. +Params: $user - A <a href="../../Bugzilla/User.html" class="podlinkpod" +>Bugzilla::User</a> object representing the user whose password we want to change. +$password - The user's new password. +Returns: Nothing.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="INFO_METHODS" +>INFO METHODS</a></h1> + +<p>These are methods that describe the capabilities of this object. +These are all no-parameter methods that return either <code class="code">true</code> or <code class="code">false</code>.</p> + +<dl> +<dt><a name="user_can_create_account" +><code class="code">user_can_create_account</code></a></dt> + +<dd> +<p>Whether or not users can manually create accounts in this type of account source. +Defaults to <code class="code">true</code>.</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/CGI.html b/docs/html/api/Bugzilla/CGI.html new file mode 100644 index 000000000..35e13741c --- /dev/null +++ b/docs/html/api/Bugzilla/CGI.html @@ -0,0 +1,112 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::CGI</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::CGI</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#CHANGES_FROM_CGI.PM'>CHANGES FROM CGI.PM</a> + <li class='indexItem indexItem1'><a href='#ADDITIONAL_FUNCTIONS'>ADDITIONAL FUNCTIONS</a> + <li class='indexItem indexItem1'><a href='#SEE_ALSO'>SEE ALSO</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::CGI - CGI handling for Bugzilla</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::CGI; + + my $cgi = new Bugzilla::CGI();</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This package inherits from the standard CGI module, to provide additional Bugzilla-specific functionality. In general, see <a href="../CGI.html" class="podlinkpod" +>the CGI.pm docs</a> for documention.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="CHANGES_FROM_CGI.PM" +>CHANGES FROM <a href="../CGI.html" class="podlinkpod" +>CGI.PM</a></a></h1> + +<p>Bugzilla::CGI has some differences from <a href="../CGI.html" class="podlinkpod" +>CGI.pm</a>.</p> + +<dl> +<dt><a name="cgi_error_is_automatically_checked" +><code class="code">cgi_error</code> is automatically checked</a></dt> + +<dd> +<p>After creating the CGI object, <code class="code">Bugzilla::CGI</code> automatically checks <i>cgi_error</i>, and throws a CodeError if a problem is detected.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="ADDITIONAL_FUNCTIONS" +>ADDITIONAL FUNCTIONS</a></h1> + +<p><i>Bugzilla::CGI</i> also includes additional functions.</p> + +<dl> +<dt><a name="canonicalise_query(@exclude)" +><code class="code">canonicalise_query(@exclude)</code></a></dt> + +<dd> +<p>This returns a sorted string of the parameters, suitable for use in a url. Values in <code class="code">@exclude</code> are not included in the result.</p> + +<dt><a name="send_cookie" +><code class="code">send_cookie</code></a></dt> + +<dd> +<p>This routine is identical to the cookie generation part of CGI.pm's <code class="code">cookie</code> routine, except that it knows about Bugzilla's cookie_path and cookie_domain parameters and takes them into account if necessary. This should be used by all Bugzilla code (instead of <code class="code">cookie</code> or the <code class="code">-cookie</code> argument to <code class="code">header</code>), so that under mod_perl the headers can be sent correctly, using <code class="code">print</code> or the mod_perl APIs as appropriate.</p> + +<p>To remove (expire) a cookie, use <code class="code">remove_cookie</code>.</p> + +<dt><a name="remove_cookie" +><code class="code">remove_cookie</code></a></dt> + +<dd> +<p>This is a wrapper around send_cookie, setting an expiry date in the past, effectively removing the cookie.</p> + +<p>As its only argument, it takes the name of the cookie to expire.</p> + +<dt><a name="require_https($baseurl)" +><code class="code">require_https($baseurl)</code></a></dt> + +<dd> +<p>This routine checks if the current page is being served over https, and redirects to the https protocol if required, retaining QUERY_STRING.</p> + +<p>It takes an option argument which will be used as the base URL. If $baseurl is not provided, the current URL is used.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SEE_ALSO" +>SEE ALSO</a></h1> + +<p><a href="../CGI.html" class="podlinkpod" +>CGI</a>, <a href="../CGI/Cookie.html" class="podlinkpod" +>CGI::Cookie</a></p> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Classification.html b/docs/html/api/Bugzilla/Classification.html new file mode 100644 index 000000000..63da6863f --- /dev/null +++ b/docs/html/api/Bugzilla/Classification.html @@ -0,0 +1,133 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Classification</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Classification</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> + <li class='indexItem indexItem1'><a href='#SUBROUTINES'>SUBROUTINES</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Classification - Bugzilla classification class.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Classification; + + my $classification = new Bugzilla::Classification(1); + my $classification = new Bugzilla::Classification({name => 'Acme'}); + + my $id = $classification->id; + my $name = $classification->name; + my $description = $classification->description; + my $product_count = $classification->product_count; + my $products = $classification->products; + + my $hash_ref = Bugzilla::Classification::get_all_classifications(); + my $classification = $hash_ref->{1}; + + my $classification = + Bugzilla::Classification::check_classification('AcmeClass');</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Classification.pm represents a Classification object.</p> + +<p>A Classification is a higher-level grouping of Products.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<dl> +<dt><a name="new($param)" +><code class="code">new($param)</code></a></dt> + +<dd> +<pre class="code"> Description: The constructor is used to load an existing + classification by passing a classification + id or classification name using a hash. + + Params: $param - If you pass an integer, the integer is the + classification_id from the database that we + want to read in. If you pass in a hash with + 'name' key, then the value of the name key + is the name of a classification from the DB. + + Returns: A Bugzilla::Classification object.</pre> + +<dt><a name="product_count()" +><code class="code">product_count()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns the total number of products that belong to + the classification. + + Params: none. + + Returns: Integer - The total of products inside the classification.</pre> + +<dt><a name="products" +><code class="code">products</code></a></dt> + +<dd> +<pre class="code"> Description: Returns all products of the classification. + + Params: none. + + Returns: A reference to an array of Bugzilla::Product objects.</pre> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBROUTINES" +>SUBROUTINES</a></h1> + +<dl> +<dt><a name="get_all_classifications()" +><code class="code">get_all_classifications()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns all classifications. + + Params: none. + + Returns: Bugzilla::Classification object list.</pre> + +<dt><a name="check_classification($classification_name)" +><code class="code">check_classification($classification_name)</code></a></dt> + +<dd> +<pre class="code"> Description: Checks if the classification name passed in is a + valid classification. + + Params: $classification_name - String with a classification name. + + Returns: Bugzilla::Classification object.</pre> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Component.html b/docs/html/api/Bugzilla/Component.html new file mode 100644 index 000000000..d46690090 --- /dev/null +++ b/docs/html/api/Bugzilla/Component.html @@ -0,0 +1,175 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Component</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Component</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> + <li class='indexItem indexItem1'><a href='#SUBROUTINES'>SUBROUTINES</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Component - Bugzilla product component class.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Component; + + my $component = new Bugzilla::Component(1); + my $component = new Bugzilla::Component({product => $product, + name => 'AcmeComp'}); + + my $bug_count = $component->bug_count(); + my $bug_ids = $component->bug_ids(); + my $id = $component->id; + my $name = $component->name; + my $description = $component->description; + my $product_id = $component->product_id; + my $default_assignee = $component->default_assignee; + my $default_qa_contact = $component->default_qa_contact; + my $initial_cc = $component->initial_cc; + my $product = $component->product; + my $bug_flag_types = $component->flag_types->{'bug'}; + my $attach_flag_types = $component->flag_types->{'attachment'}; + + my $component = Bugzilla::Component::check_component($product, 'AcmeComp');</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Component.pm represents a Product Component object.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<dl> +<dt><a name="new($param)" +><code class="code">new($param)</code></a></dt> + +<dd> +<pre class="code"> Description: The constructor is used to load an existing component + by passing a component id or a hash with the product + id and the component name. + + Params: $param - If you pass an integer, the integer is the + component id from the database that we want to + read in. If you pass in a hash with 'name' key, + then the value of the name key is the name of a + component from the DB. + + Returns: A Bugzilla::Component object.</pre> + +<dt><a name="bug_count()" +><code class="code">bug_count()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns the total of bugs that belong to the component. + + Params: none. + + Returns: Integer with the number of bugs.</pre> + +<dt><a name="bugs_ids()" +><code class="code">bugs_ids()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns all bug IDs that belong to the component. + + Params: none. + + Returns: A reference to an array of bug IDs.</pre> + +<dt><a name="default_assignee()" +><code class="code">default_assignee()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns a user object that represents the default assignee for + the component. + + Params: none. + + Returns: A Bugzilla::User object.</pre> + +<dt><a name="default_qa_contact()" +><code class="code">default_qa_contact()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns a user object that represents the default QA contact for + the component. + + Params: none. + + Returns: A Bugzilla::User object.</pre> + +<dt><a name="initial_cc" +><code class="code">initial_cc</code></a></dt> + +<dd> +<p>Returns an arrayref of <a href="../Bugzilla/User.html" class="podlinkpod" +>Bugzilla::User</a> objects representing the Initial CC List.</p> + +<dt><a name="flag_types()" +><code class="code">flag_types()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns all bug and attachment flagtypes available for + the component. + + Params: none. + + Returns: Two references to an array of flagtype objects.</pre> + +<dt><a name="product()" +><code class="code">product()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns the product the component belongs to. + + Params: none. + + Returns: A Bugzilla::Product object.</pre> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBROUTINES" +>SUBROUTINES</a></h1> + +<dl> +<dt><a name="check_component($product,_$comp_name)" +><code class="code">check_component($product, $comp_name)</code></a></dt> + +<dd> +<pre class="code"> Description: Checks if the component name was passed in and if it is a valid + component. + + Params: $product - A Bugzilla::Product object. + $comp_name - String with a component name. + + Returns: Bugzilla::Component object.</pre> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Config.html b/docs/html/api/Bugzilla/Config.html new file mode 100644 index 000000000..3abc4cf0d --- /dev/null +++ b/docs/html/api/Bugzilla/Config.html @@ -0,0 +1,100 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Config</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Config</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#FUNCTIONS'>FUNCTIONS</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Parameters'>Parameters</a> + </ul> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Config - Configuration parameters for Bugzilla</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> # Administration functions + use Bugzilla::Config qw(:admin); + + update_params(); + SetParam($param, $value); + write_params();</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This package contains ways to access Bugzilla configuration parameters.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="FUNCTIONS" +>FUNCTIONS</a></h1> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Parameters" +>Parameters</a></h2> + +<p>Parameters can be set, retrieved, and updated.</p> + +<dl> +<dt><a name="SetParam($name,_$value)" +><code class="code">SetParam($name, $value)</code></a></dt> + +<dd> +<p>Sets the param named $name to $value. Values are checked using the checker function for the given param if one exists.</p> + +<dt><a name="update_params()" +><code class="code">update_params()</code></a></dt> + +<dd> +<p>Updates the parameters, by transitioning old params to new formats, setting defaults for new params, and removing obsolete ones. Used by <em class="code">checksetup.pl</em> in the process of an installation or upgrade.</p> + +<p>Prints out information about what it's doing, if it makes any changes.</p> + +<p>May prompt the user for input, if certain required parameters are not specified.</p> + +<dt><a name="write_params($params)" +><code class="code">write_params($params)</code></a></dt> + +<dd> +<p>Description: Writes the parameters to disk.</p> + +<p>Params: <code class="code">$params</code> (optional) - A hashref to write to the disk instead of <code class="code">Bugzilla-</code>params>. Used only by <code class="code">update_params</code>.</p> + +<p>Returns: nothing</p> + +<dt><a name="read_param_file()" +><code class="code">read_param_file()</code></a></dt> + +<dd> +<p>Description: Most callers should never need this. This is used by <code class="code">Bugzilla-</code>params> to directly read <code class="code">$datadir/params</code> and load it into memory. Use <code class="code">Bugzilla-</code>params> instead.</p> + +<p>Params: none</p> + +<p>Returns: A hashref containing the current params in <code class="code">$datadir/params</code>.</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Config/Common.html b/docs/html/api/Bugzilla/Config/Common.html new file mode 100644 index 000000000..9310546e9 --- /dev/null +++ b/docs/html/api/Bugzilla/Config/Common.html @@ -0,0 +1,63 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Config::Common</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Config::Common</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Functions'>Functions</a> + </ul> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Config::Common - Parameter checking functions</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>All parameter checking functions are called with two parameters:</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Functions" +>Functions</a></h2> + +<dl> +<dt><a name="check_multi" +><code class="code">check_multi</code></a></dt> + +<dd> +<p>Checks that a multi-valued parameter (ie type <code class="code">s</code> or type <code class="code">m</code>) satisfies its contraints.</p> + +<dt><a name="check_numeric" +><code class="code">check_numeric</code></a></dt> + +<dd> +<p>Checks that the value is a valid number</p> + +<dt><a name="check_regexp" +><code class="code">check_regexp</code></a></dt> + +<dd> +<p>Checks that the value is a valid regexp</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/DB.html b/docs/html/api/Bugzilla/DB.html new file mode 100644 index 000000000..c5d1dcb51 --- /dev/null +++ b/docs/html/api/Bugzilla/DB.html @@ -0,0 +1,1326 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::DB</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::DB</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#CONSTANTS'>CONSTANTS</a> + <li class='indexItem indexItem1'><a href='#CONNECTION'>CONNECTION</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Functions'>Functions</a> + </ul> + <li class='indexItem indexItem1'><a href='#ABSTRACT_METHODS'>ABSTRACT METHODS</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Constructor'>Constructor</a> + <li class='indexItem indexItem2'><a href='#SQL_Generation'>SQL Generation</a> + </ul> + <li class='indexItem indexItem1'><a href='#IMPLEMENTED_METHODS'>IMPLEMENTED METHODS</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#General_Information_Methods'>General Information Methods</a> + <li class='indexItem indexItem2'><a href='#Database_Setup_Methods'>Database Setup Methods</a> + <li class='indexItem indexItem2'><a href='#Schema_Modification_Methods'>Schema Modification Methods</a> + <li class='indexItem indexItem2'><a href='#Schema_Information_Methods'>Schema Information Methods</a> + <li class='indexItem indexItem2'><a href='#Transaction_Methods'>Transaction Methods</a> + </ul> + <li class='indexItem indexItem1'><a href='#SUBCLASS_HELPERS'>SUBCLASS HELPERS</a> + <li class='indexItem indexItem1'><a href='#SEE_ALSO'>SEE ALSO</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::DB - Database access routines, +using <a href="../DBI.html" class="podlinkpod" +>DBI</a></p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> # Obtain db handle + use Bugzilla::DB; + my $dbh = Bugzilla->dbh; + + # prepare a query using DB methods + my $sth = $dbh->prepare("SELECT " . + $dbh->sql_date_format("creation_ts", "%Y%m%d") . + " FROM bugs WHERE bug_status != 'RESOLVED' " . + $dbh->sql_limit(1)); + + # Execute the query + $sth->execute; + + # Get the results + my @result = $sth->fetchrow_array; + + # Schema Modification + $dbh->bz_add_column($table, $name, \%definition, $init_value); + $dbh->bz_add_index($table, $name, $definition); + $dbh->bz_add_table($name); + $dbh->bz_drop_index($table, $name); + $dbh->bz_drop_table($name); + $dbh->bz_alter_column($table, $name, \%new_def, $set_nulls_to); + $dbh->bz_drop_column($table, $column); + $dbh->bz_rename_column($table, $old_name, $new_name); + + # Schema Information + my $column = $dbh->bz_column_info($table, $column); + my $index = $dbh->bz_index_info($table, $index); + + # General Information + my @fields = $dbh->bz_get_field_defs();</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Functions in this module allows creation of a database handle to connect to the Bugzilla database. This should never be done directly; all users should use the <a href="../Bugzilla.html" class="podlinkpod" +>Bugzilla</a> module to access the current <code class="code">dbh</code> instead.</p> + +<p>This module also contains methods extending the returned handle with functionality which is different between databases allowing for easy customization for particular database via inheritance. These methods should be always preffered over hard-coding SQL commands.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="CONSTANTS" +>CONSTANTS</a></h1> + +<p>Subclasses of Bugzilla::DB are required to define certain constants. These constants are required to be subroutines or "use constant" variables.</p> + +<dl> +<dt><a name="BLOB_TYPE" +><code class="code">BLOB_TYPE</code></a></dt> + +<dd> +<p>The <code class="code">\%attr</code> argument that must be passed to bind_param in order to correctly escape a <code class="code">LONGBLOB</code> type.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="CONNECTION" +>CONNECTION</a></h1> + +<p>A new database handle to the required database can be created using this module. This is normally done by the <a href="../Bugzilla.html" class="podlinkpod" +>Bugzilla</a> module, and so these routines should not be called from anywhere else.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Functions" +>Functions</a></h2> + +<dl> +<dt><a name="connect_main" +><code class="code">connect_main</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Function to connect to the main database, returning a new database handle.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a +><code class="code">$no_db_name</code> (optional) - If true, connect to the database server, but don't connect to a specific database. This is only used when creating a database. After you create the database, you should re-create a new Bugzilla::DB object without using this parameter.</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>New instance of the DB class</p> +</dd> +</dl> + +<dt><a name="connect_shadow" +><code class="code">connect_shadow</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Function to connect to the shadow database, returning a new database handle. This routine <code class="code">die</code>s if no shadow database is configured.</p> + +<dt><a name="Params_(none)" +><b>Params</b> (none) +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A new instance of the DB class</p> +</dd> +</dl> + +<dt><a name="bz_check_requirements" +><code class="code">bz_check_requirements</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Checks to make sure that you have the correct DBD and database version installed for the database that Bugzilla will be using. Prints a message and exits if you don't pass the requirements.</p> + +<p>If <code class="code">$db_check</code> is false (from <em class="code">localconfig</em>), we won't check the database version.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$output_-_true_if_the_function_should_display_informational_output_about_what_it's_doing,_such_as_versions_found." +><code class="code">$output</code> - <code class="code">true</code> if the function should display informational output about what it's doing, such as versions found.</a></dt> +</dl> + +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> + +<dt><a name="bz_create_database" +><code class="code">bz_create_database</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Creates an empty database with the name <code class="code">$db_name</code>, if that database doesn't already exist. Prints an error message and exits if we can't create the database.</p> + +<dt><a name="Params_(none)" +><b>Params</b> (none) +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> + +<dt><a name="_connect" +><code class="code">_connect</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Internal function, creates and returns a new, connected instance of the correct DB class. This routine <code class="code">die</code>s if no driver is specified.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$driver_-_name_of_the_database_driver_to_use" +><code class="code">$driver</code> - name of the database driver to use +<dt><a name="$host_-_host_running_the_database_we_are_connecting_to" +><code class="code">$host</code> - host running the database we are connecting to +<dt><a name="$dbname_-_name_of_the_database_to_connect_to" +><code class="code">$dbname</code> - name of the database to connect to +<dt><a name="$port_-_port_the_database_is_listening_on" +><code class="code">$port</code> - port the database is listening on +<dt><a name="$sock_-_socket_the_database_is_listening_on" +><code class="code">$sock</code> - socket the database is listening on +<dt><a name="$user_-_username_used_to_log_in_to_the_database" +><code class="code">$user</code> - username used to log in to the database +<dt><a name="$pass_-_password_used_to_log_in_to_the_database" +><code class="code">$pass</code> - password used to log in to the database</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A new instance of the DB class</p> +</dd> +</dl> + +<dt><a name="_handle_error" +><code class="code">_handle_error</code></a></dt> + +<dd> +<p>Function passed to the DBI::connect call for error handling. It shortens the error for printing.</p> + +<dt><a name="import" +><code class="code">import</code></a></dt> + +<dd> +<p>Overrides the standard import method to check that derived class implements all required abstract methods. Also calls original implementation in its super class.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="ABSTRACT_METHODS" +>ABSTRACT METHODS</a></h1> + +<p>Note: Methods which can be implemented generically for all DBs are implemented in this module. If needed, they can be overridden with DB specific code. Methods which do not have standard implementation are abstract and must be implemented for all supported databases separately. To avoid confusion with standard DBI methods, all methods returning string with formatted SQL command have prefix <code class="code">sql_</code>. All other methods have prefix <code class="code">bz_</code>.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Constructor" +>Constructor</a></h2> + +<dl> +<dt><a name="new" +><code class="code">new</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Constructor. Abstract method, should be overridden by database specific code.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$user_-_username_used_to_log_in_to_the_database" +><code class="code">$user</code> - username used to log in to the database +<dt><a name="$pass_-_password_used_to_log_in_to_the_database" +><code class="code">$pass</code> - password used to log in to the database +<dt><a name="$host_-_host_running_the_database_we_are_connecting_to" +><code class="code">$host</code> - host running the database we are connecting to +<dt><a name="$dbname_-_name_of_the_database_to_connect_to" +><code class="code">$dbname</code> - name of the database to connect to +<dt><a name="$port_-_port_the_database_is_listening_on" +><code class="code">$port</code> - port the database is listening on +<dt><a name="$sock_-_socket_the_database_is_listening_on" +><code class="code">$sock</code> - socket the database is listening on</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A new instance of the DB class</p> + +<dt><a name="Note" +><b>Note</b></a></dt> + +<dd> +<p>The constructor should create a DSN from the parameters provided and then call <code class="code">db_new()</code> method of its super class to create a new class instance. See <a href="../db_new.html" class="podlinkpod" +>db_new</a> description in this module. As per DBI documentation, all class variables must be prefixed with "private_". See <a href="../DBI.html" class="podlinkpod" +>DBI</a>.</p> +</dd> +</dl> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="SQL_Generation" +>SQL Generation</a></h2> + +<dl> +<dt><a name="sql_regexp" +><code class="code">sql_regexp</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Outputs SQL regular expression operator for POSIX regex searches (case insensitive) in format suitable for a given database.</p> + +<p>Abstract method, should be overridden by database specific code.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$expr_-_SQL_expression_for_the_text_to_be_searched_(scalar)" +><code class="code">$expr</code> - SQL expression for the text to be searched (scalar) +<dt><a name="$pattern_-_the_regular_expression_to_search_for_(scalar)" +><code class="code">$pattern</code> - the regular expression to search for (scalar)</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>Formatted SQL for regular expression search (e.g. REGEXP) (scalar)</p> +</dd> +</dl> + +<dt><a name="sql_not_regexp" +><code class="code">sql_not_regexp</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Outputs SQL regular expression operator for negative POSIX regex searches (case insensitive) in format suitable for a given database.</p> + +<p>Abstract method, should be overridden by database specific code.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$expr_-_SQL_expression_for_the_text_to_be_searched_(scalar)" +><code class="code">$expr</code> - SQL expression for the text to be searched (scalar) +<dt><a name="$pattern_-_the_regular_expression_to_search_for_(scalar)" +><code class="code">$pattern</code> - the regular expression to search for (scalar)</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>Formatted SQL for negative regular expression search (e.g. NOT REGEXP) (scalar)</p> +</dd> +</dl> + +<dt><a name="sql_limit" +><code class="code">sql_limit</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Returns SQL syntax for limiting results to some number of rows with optional offset if not starting from the begining.</p> + +<p>Abstract method, should be overridden by database specific code.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$limit_-_number_of_rows_to_return_from_query_(scalar)" +><code class="code">$limit</code> - number of rows to return from query (scalar) +<dt><a name="$offset_-_number_of_rows_to_skip_prior_counting_(scalar)" +><code class="code">$offset</code> - number of rows to skip prior counting (scalar)</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>Formatted SQL for limiting number of rows returned from query with optional offset (e.g. LIMIT 1, 1) (scalar)</p> +</dd> +</dl> + +<dt><a name="sql_from_days" +><code class="code">sql_from_days</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Outputs SQL syntax for converting Julian days to date.</p> + +<p>Abstract method, should be overridden by database specific code.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$days_-_days_to_convert_to_date" +><code class="code">$days</code> - days to convert to date</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>Formatted SQL for returning Julian days in dates. (scalar)</p> +</dd> +</dl> + +<dt><a name="sql_to_days" +><code class="code">sql_to_days</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Outputs SQL syntax for converting date to Julian days.</p> + +<p>Abstract method, should be overridden by database specific code.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$date_-_date_to_convert_to_days" +><code class="code">$date</code> - date to convert to days</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>Formatted SQL for returning date fields in Julian days. (scalar)</p> +</dd> +</dl> + +<dt><a name="sql_date_format" +><code class="code">sql_date_format</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Outputs SQL syntax for formatting dates.</p> + +<p>Abstract method, should be overridden by database specific code.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$date_-_date_or_name_of_date_type_column_(scalar)" +><code class="code">$date</code> - date or name of date type column (scalar) +<dt><a +><code class="code">$format</code> - format string for date output (scalar) (<code class="code">%Y</code> = year, four digits, <code class="code">%y</code> = year, two digits, <code class="code">%m</code> = month, <code class="code">%d</code> = day, <code class="code">%a</code> = weekday name, 3 letters, <code class="code">%H</code> = hour 00-23, <code class="code">%i</code> = minute, <code class="code">%s</code> = second)</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>Formatted SQL for date formatting (scalar)</p> +</dd> +</dl> + +<dt><a name="sql_interval" +><code class="code">sql_interval</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Outputs proper SQL syntax for a time interval function.</p> + +<p>Abstract method, should be overridden by database specific code.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$interval_-_the_time_interval_requested_(e.g._'30')_(integer)" +><code class="code">$interval</code> - the time interval requested (e.g. '30') (integer) +<dt><a name="$units_-_the_units_the_interval_is_in_(e.g._'MINUTE')_(string)" +><code class="code">$units</code> - the units the interval is in (e.g. 'MINUTE') (string)</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>Formatted SQL for interval function (scalar)</p> +</dd> +</dl> + +<dt><a name="sql_position" +><code class="code">sql_position</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Outputs proper SQL syntax determinig position of a substring (fragment) withing a string (text). Note: if the substring or text are string constants, they must be properly quoted (e.g. "'pattern'").</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$fragment_-_the_string_fragment_we_are_searching_for_(scalar)" +><code class="code">$fragment</code> - the string fragment we are searching for (scalar) +<dt><a name="$text_-_the_text_to_search_(scalar)" +><code class="code">$text</code> - the text to search (scalar)</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>Formatted SQL for substring search (scalar)</p> +</dd> +</dl> + +<dt><a name="sql_group_by" +><code class="code">sql_group_by</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Outputs proper SQL syntax for grouping the result of a query.</p> + +<p>For ANSI SQL databases, we need to group by all columns we are querying for (except for columns used in aggregate functions). Some databases require (or even allow) to specify only one or few columns if the result is uniquely defined. For those databases, the default implementation needs to be overloaded.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$needed_columns_-_string_with_comma_separated_list_of_columns_we_need_to_group_by_to_get_expected_result_(scalar)" +><code class="code">$needed_columns</code> - string with comma separated list of columns we need to group by to get expected result (scalar) +<dt><a +><code class="code">$optional_columns</code> - string with comma separated list of all other columns we are querying for, but which are not in the required list.</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>Formatted SQL for row grouping (scalar)</p> +</dd> +</dl> + +<dt><a name="sql_string_concat" +><code class="code">sql_string_concat</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Returns SQL syntax for concatenating multiple strings (constants or values from table columns) together.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="@params_-_array_of_column_names_or_strings_to_concatenate" +><code class="code">@params</code> - array of column names or strings to concatenate</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>Formatted SQL for concatenating specified strings</p> +</dd> +</dl> + +<dt><a name="sql_fulltext_search" +><code class="code">sql_fulltext_search</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Returns SQL syntax for performing a full text search for specified text on a given column.</p> + +<p>There is a ANSI SQL version of this method implemented using LIKE operator, but it's not a real full text search. DB specific modules should override this, as this generic implementation will be always much slower. This generic implementation returns 'relevance' as 0 for no match, or 1 for a match.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$column_-_name_of_column_to_search_(scalar)" +><code class="code">$column</code> - name of column to search (scalar) +<dt><a name="$text_-_text_to_search_for_(scalar)" +><code class="code">$text</code> - text to search for (scalar)</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>Formatted SQL for full text search</p> +</dd> +</dl> + +<dt><a name="sql_istrcmp" +><code class="code">sql_istrcmp</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Returns SQL for a case-insensitive string comparison.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$left_-_What_should_be_on_the_left-hand-side_of_the_operation." +><code class="code">$left</code> - What should be on the left-hand-side of the operation. +<dt><a name="$right_-_What_should_be_on_the_right-hand-side_of_the_operation." +><code class="code">$right</code> - What should be on the right-hand-side of the operation. +<dt><a +><code class="code">$op</code> (optional) - What the operation is. Should be a valid ANSI SQL comparison operator, such as <code class="code">=</code>, <code class="code"><</code>, <code class="code">LIKE</code>, etc. Defaults to <code class="code">=</code> if not specified.</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A SQL statement that will run the comparison in a case-insensitive fashion.</p> + +<dt><a name="Note" +><b>Note</b></a></dt> + +<dd> +<p>Uses <a href="#sql_istring" class="podlinkpod" +>"sql_istring"</a>, so it has the same performance concerns. Try to avoid using this function unless absolutely necessary.</p> + +<p>Subclass Implementors: Override sql_istring instead of this function, most of the time (this function uses sql_istring).</p> +</dd> +</dl> + +<dt><a name="sql_istring" +><code class="code">sql_istring</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Returns SQL syntax "preparing" a string or text column for case-insensitive comparison.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$string_-_string_to_convert_(scalar)" +><code class="code">$string</code> - string to convert (scalar)</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>Formatted SQL making the string case insensitive.</p> + +<dt><a name="Note" +><b>Note</b></a></dt> + +<dd> +<p>The default implementation simply calls LOWER on the parameter. If this is used to search on a text column with index, the index will not be usually used unless it was created as LOWER(column).</p> +</dd> +</dl> + +<dt><a name="bz_lock_tables" +><code class="code">bz_lock_tables</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Performs a table lock operation on specified tables. If the underlying database supports transactions, it should also implicitly start a new transaction.</p> + +<p>Abstract method, should be overridden by database specific code.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="@tables_-_list_of_names_of_tables_to_lock_in_MySQL_notation_(ex._'bugs_AS_bugs2_READ',_'logincookies_WRITE')" +><code class="code">@tables</code> - list of names of tables to lock in MySQL notation (ex. 'bugs AS bugs2 READ', 'logincookies WRITE')</a></dt> +</dl> + +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> + +<dt><a name="bz_unlock_tables" +><code class="code">bz_unlock_tables</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Performs a table unlock operation.</p> + +<p>If the underlying database supports transactions, it should also implicitly commit or rollback the transaction.</p> + +<p>Also, this function should allow to be called with the abort flag set even without locking tables first without raising an error to simplify error handling.</p> + +<p>Abstract method, should be overridden by database specific code.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a +><code class="code">$abort</code> - <code class="code">UNLOCK_ABORT</code> if the operation on locked tables failed (if transactions are supported, the action will be rolled back). No param if the operation succeeded. This is only used by <a href="../Bugzilla/Error.html#throw_error" class="podlinkpod" +>"throw_error" in Bugzilla::Error</a>.</a></dt> +</dl> + +<dt><a name="Returns_(none)" +><b>Returns</b> (none)</a></dt> +</dl> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="IMPLEMENTED_METHODS" +>IMPLEMENTED METHODS</a></h1> + +<p>These methods are implemented in Bugzilla::DB, and only need to be implemented in subclasses if you need to override them for database-compatibility reasons.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="General_Information_Methods" +>General Information Methods</a></h2> + +<p>These methods return information about data in the database.</p> + +<dl> +<dt><a name="bz_last_key" +><code class="code">bz_last_key</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Returns the last serial number, usually from a previous INSERT.</p> + +<p>Must be executed directly following the relevant INSERT. This base implementation uses <a href="../DBI.html#last_insert_id" class="podlinkpod" +>"last_insert_id" in DBI</a>. If the DBD supports it, it is the preffered way to obtain the last serial index. If it is not supported, the DB-specific code needs to override this function.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$table_-_name_of_table_containing_serial_column_(scalar)" +><code class="code">$table</code> - name of table containing serial column (scalar) +<dt><a name="$column_-_name_of_column_containing_serial_data_type_(scalar)" +><code class="code">$column</code> - name of column containing serial data type (scalar)</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>Last inserted ID (scalar)</p> +</dd> +</dl> + +<dt><a name="bz_get_field_defs" +><code class="code">bz_get_field_defs</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Returns a list of all the "bug" fields in Bugzilla. The list contains hashes, with a <code class="code">name</code> key and a <code class="code">description</code> key.</p> + +<dt><a name="Params_(none)" +><b>Params</b> (none) +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>List of all the "bug" fields</p> +</dd> +</dl> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Database_Setup_Methods" +>Database Setup Methods</a></h2> + +<p>These methods are used by the Bugzilla installation programs to set up the database.</p> + +<dl> +<dt><a name="bz_populate_enum_tables" +><code class="code">bz_populate_enum_tables</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>For an upgrade or an initial installation, populates the tables that hold the legal values for the old "enum" fields: <code class="code">bug_severity</code>, <code class="code">resolution</code>, etc. Prints out information if it inserts anything into the DB.</p> + +<dt><a name="Params_(none)" +><b>Params</b> (none) +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Schema_Modification_Methods" +>Schema Modification Methods</a></h2> + +<p>These methods modify the current Bugzilla Schema.</p> + +<p>Where a parameter says "Abstract index/column definition", it returns/takes information in the formats defined for indexes and columns in <code class="code">Bugzilla::DB::Schema::ABSTRACT_SCHEMA</code>.</p> + +<dl> +<dt><a name="bz_add_column" +><code class="code">bz_add_column</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Adds a new column to a table in the database. Prints out a brief statement that it did so, to stdout. Note that you cannot add a NOT NULL column that has no default -- the database won't know what to set all the NULL values to.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$table_-_the_table_where_the_column_is_being_added" +><code class="code">$table</code> - the table where the column is being added +<dt><a name="$name_-_the_name_of_the_new_column" +><code class="code">$name</code> - the name of the new column +<dt><a name="\%definition_-_Abstract_column_definition_for_the_new_column" +><code class="code">\%definition</code> - Abstract column definition for the new column +<dt><a +><code class="code">$init_value</code> (optional) - An initial value to set the column to. Required if your column is NOT NULL and has no DEFAULT set.</a></dt> +</dl> + +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> + +<dt><a name="bz_add_index" +><code class="code">bz_add_index</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Adds a new index to a table in the database. Prints out a brief statement that it did so, to stdout. If the index already exists, we will do nothing.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$table_-_The_table_the_new_index_is_on." +><code class="code">$table</code> - The table the new index is on. +<dt><a name="$name_-_A_name_for_the_new_index." +><code class="code">$name</code> - A name for the new index. +<dt><a name="$definition_-_An_abstract_index_definition._Either_a_hashref_or_an_arrayref." +><code class="code">$definition</code> - An abstract index definition. Either a hashref or an arrayref.</a></dt> +</dl> + +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> + +<dt><a name="bz_add_table" +><code class="code">bz_add_table</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Creates a new table in the database, based on the definition for that table in the abstract schema.</p> + +<p>Note that unlike the other 'add' functions, this does not take a definition, but always creates the table as it exists in <a href="../Bugzilla/DB/Schema.html#ABSTRACT_SCHEMA" class="podlinkpod" +>"ABSTRACT_SCHEMA" in Bugzilla::DB::Schema</a>.</p> + +<p>If a table with that name already exists, then this function returns silently.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$name_-_The_name_of_the_table_you_want_to_create." +><code class="code">$name</code> - The name of the table you want to create.</a></dt> +</dl> + +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> + +<dt><a name="bz_drop_index" +><code class="code">bz_drop_index</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Removes an index from the database. Prints out a brief statement that it did so, to stdout. If the index doesn't exist, we do nothing.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$table_-_The_table_that_the_index_is_on." +><code class="code">$table</code> - The table that the index is on. +<dt><a name="$name_-_The_name_of_the_index_that_you_want_to_drop." +><code class="code">$name</code> - The name of the index that you want to drop.</a></dt> +</dl> + +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> + +<dt><a name="bz_drop_table" +><code class="code">bz_drop_table</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Drops a table from the database. If the table doesn't exist, we just return silently.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$name_-_The_name_of_the_table_to_drop." +><code class="code">$name</code> - The name of the table to drop.</a></dt> +</dl> + +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> + +<dt><a name="bz_alter_column" +><code class="code">bz_alter_column</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Changes the data type of a column in a table. Prints out the changes being made to stdout. If the new type is the same as the old type, the function returns without changing anything.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$table_-_the_table_where_the_column_is" +><code class="code">$table</code> - the table where the column is +<dt><a name="$name_-_the_name_of_the_column_you_want_to_change" +><code class="code">$name</code> - the name of the column you want to change +<dt><a name="\%new_def_-_An_abstract_column_definition_for_the_new_data_type_of_the_columm" +><code class="code">\%new_def</code> - An abstract column definition for the new data type of the columm +<dt><a +><code class="code">$set_nulls_to</code> (Optional) - If you are changing the column to be NOT NULL, you probably also want to set any existing NULL columns to a particular value. Specify that value here. <b>NOTE</b>: The value should not already be SQL-quoted.</a></dt> +</dl> + +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> + +<dt><a name="bz_drop_column" +><code class="code">bz_drop_column</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Removes a column from a database table. If the column doesn't exist, we return without doing anything. If we do anything, we print a short message to <code class="code">stdout</code> about the change.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$table_-_The_table_where_the_column_is" +><code class="code">$table</code> - The table where the column is +<dt><a name="$column_-_The_name_of_the_column_you_want_to_drop" +><code class="code">$column</code> - The name of the column you want to drop</a></dt> +</dl> + +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> + +<dt><a name="bz_rename_column" +><code class="code">bz_rename_column</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Renames a column in a database table. If the <code class="code">$old_name</code> column doesn't exist, we return without doing anything. If <code class="code">$old_name</code> and <code class="code">$new_name</code> both already exist in the table specified, we fail.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$table_-_The_name_of_the_table_containing_the_column_that_you_want_to_rename" +><code class="code">$table</code> - The name of the table containing the column that you want to rename +<dt><a name="$old_name_-_The_current_name_of_the_column_that_you_want_to_rename" +><code class="code">$old_name</code> - The current name of the column that you want to rename +<dt><a name="$new_name_-_The_new_name_of_the_column" +><code class="code">$new_name</code> - The new name of the column</a></dt> +</dl> + +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> + +<dt><a name="bz_rename_table" +><code class="code">bz_rename_table</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Renames a table in the database. Does nothing if the table doesn't exist.</p> + +<p>Throws an error if the old table exists and there is already a table with the new name.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$old_name_-_The_current_name_of_the_table." +><code class="code">$old_name</code> - The current name of the table. +<dt><a name="$new_name_-_What_you're_renaming_the_table_to." +><code class="code">$new_name</code> - What you're renaming the table to.</a></dt> +</dl> + +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Schema_Information_Methods" +>Schema Information Methods</a></h2> + +<p>These methods return information about the current Bugzilla database schema, as it currently exists on the disk.</p> + +<p>Where a parameter says "Abstract index/column definition", it returns/takes information in the formats defined for indexes and columns for <a href="../Bugzilla/DB/Schema.html#ABSTRACT_SCHEMA" class="podlinkpod" +>"ABSTRACT_SCHEMA" in Bugzilla::DB::Schema</a>.</p> + +<dl> +<dt><a name="bz_column_info" +><code class="code">bz_column_info</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Get abstract column definition.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$table_-_The_name_of_the_table_the_column_is_in." +><code class="code">$table</code> - The name of the table the column is in. +<dt><a name="$column_-_The_name_of_the_column." +><code class="code">$column</code> - The name of the column.</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>An abstract column definition for that column. If the table or column does not exist, we return <code class="code">undef</code>.</p> +</dd> +</dl> + +<dt><a name="bz_index_info" +><code class="code">bz_index_info</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Get abstract index definition.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$table_-_The_table_the_index_is_on." +><code class="code">$table</code> - The table the index is on. +<dt><a name="$index_-_The_name_of_the_index." +><code class="code">$index</code> - The name of the index.</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>An abstract index definition for that index, always in hashref format. The hashref will always contain the <code class="code">TYPE</code> element, but it will be an empty string if it's just a normal index.</p> + +<p>If the index does not exist, we return <code class="code">undef</code>.</p> +</dd> +</dl> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Transaction_Methods" +>Transaction Methods</a></h2> + +<p>These methods deal with the starting and stopping of transactions in the database.</p> + +<dl> +<dt><a name="bz_start_transaction" +><code class="code">bz_start_transaction</code></a></dt> + +<dd> +<p>Starts a transaction if supported by the database being used. Returns nothing and takes no parameters.</p> + +<dt><a name="bz_commit_transaction" +><code class="code">bz_commit_transaction</code></a></dt> + +<dd> +<p>Ends a transaction, commiting all changes, if supported by the database being used. Returns nothing and takes no parameters.</p> + +<dt><a name="bz_rollback_transaction" +><code class="code">bz_rollback_transaction</code></a></dt> + +<dd> +<p>Ends a transaction, rolling back all changes, if supported by the database being used. Returns nothing and takes no parameters.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBCLASS_HELPERS" +>SUBCLASS HELPERS</a></h1> + +<p>Methods in this class are intended to be used by subclasses to help them with their functions.</p> + +<dl> +<dt><a name="db_new" +><code class="code">db_new</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Constructor</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$dsn_-_database_connection_string" +><code class="code">$dsn</code> - database connection string +<dt><a name="$user_-_username_used_to_log_in_to_the_database" +><code class="code">$user</code> - username used to log in to the database +<dt><a name="$pass_-_password_used_to_log_in_to_the_database" +><code class="code">$pass</code> - password used to log in to the database +<dt><a name="\%attributes_-_set_of_attributes_for_DB_connection_(optional)" +><code class="code">\%attributes</code> - set of attributes for DB connection (optional)</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A new instance of the DB class</p> + +<dt><a name="Note" +><b>Note</b></a></dt> + +<dd> +<p>The name of this constructor is not <code class="code">new</code>, as that would make our check for implementation of <code class="code">new</code> by derived class useless.</p> +</dd> +</dl> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SEE_ALSO" +>SEE ALSO</a></h1> + +<p><a href="../DBI.html" class="podlinkpod" +>DBI</a></p> + +<p><a href="../Bugzilla/Constants.html#DB_MODULE" class="podlinkpod" +>"DB_MODULE" in Bugzilla::Constants</a></p> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/DB/Mysql.html b/docs/html/api/Bugzilla/DB/Mysql.html new file mode 100644 index 000000000..37519eca4 --- /dev/null +++ b/docs/html/api/Bugzilla/DB/Mysql.html @@ -0,0 +1,40 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::DB::Mysql</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::DB::Mysql</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::DB::Mysql - Bugzilla database compatibility layer for MySQL</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This module overrides methods of the Bugzilla::DB module with MySQL specific implementation. +It is instantiated by the Bugzilla::DB module and should never be used directly.</p> + +<p>For interface details see <a href="../../Bugzilla/DB.html" class="podlinkpod" +>Bugzilla::DB</a> and <a href="../../DBI.html" class="podlinkpod" +>DBI</a>.</p> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/DB/Pg.html b/docs/html/api/Bugzilla/DB/Pg.html new file mode 100644 index 000000000..f66b7ba79 --- /dev/null +++ b/docs/html/api/Bugzilla/DB/Pg.html @@ -0,0 +1,40 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::DB::Pg</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::DB::Pg</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::DB::Pg - Bugzilla database compatibility layer for PostgreSQL</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This module overrides methods of the Bugzilla::DB module with PostgreSQL specific implementation. +It is instantiated by the Bugzilla::DB module and should never be used directly.</p> + +<p>For interface details see <a href="../../Bugzilla/DB.html" class="podlinkpod" +>Bugzilla::DB</a> and <a href="../../DBI.html" class="podlinkpod" +>DBI</a>.</p> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/DB/Schema.html b/docs/html/api/Bugzilla/DB/Schema.html new file mode 100644 index 000000000..93a228215 --- /dev/null +++ b/docs/html/api/Bugzilla/DB/Schema.html @@ -0,0 +1,676 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::DB::Schema</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::DB::Schema</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#NEW_TO_SCHEMA.PM%3F'>NEW TO SCHEMA.PM?</a> + <li class='indexItem indexItem1'><a href='#CONSTANTS'>CONSTANTS</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> + <li class='indexItem indexItem1'><a href='#SERIALIZATION%2FDESERIALIZATION'>SERIALIZATION/DESERIALIZATION</a> + <li class='indexItem indexItem1'><a href='#CLASS_METHODS'>CLASS METHODS</a> + <li class='indexItem indexItem1'><a href='#ABSTRACT_DATA_TYPES'>ABSTRACT DATA TYPES</a> + <li class='indexItem indexItem1'><a href='#SEE_ALSO'>SEE ALSO</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::DB::Schema - Abstract database schema for Bugzilla</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> # Obtain MySQL database schema. + # Do not do this. Use Bugzilla::DB instead. + use Bugzilla::DB::Schema; + my $mysql_schema = new Bugzilla::DB::Schema('Mysql'); + + # Recommended way to obtain database schema. + use Bugzilla::DB; + my $dbh = Bugzilla->dbh; + my $schema = $dbh->_bz_schema(); + + # Get the list of tables in the Bugzilla database. + my @tables = $schema->get_table_list(); + + # Get the SQL statements need to create the bugs table. + my @statements = $schema->get_table_ddl('bugs'); + + # Get the database-specific SQL data type used to implement + # the abstract data type INT1. + my $db_specific_type = $schema->sql_type('INT1');</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This module implements an object-oriented, abstract database schema. It should be considered package-private to the Bugzilla::DB module. That means that CGI scripts should never call any function in this module directly, but should instead rely on methods provided by Bugzilla::DB.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NEW_TO_SCHEMA.PM?" +>NEW TO SCHEMA.PM?</a></h1> + +<p>If this is your first time looking at Schema.pm, especially if you are making changes to the database, please take a look at <a href="http://www.bugzilla.org/docs/developer.html#sql-schema" class="podlinkurl" +>http://www.bugzilla.org/docs/developer.html#sql-schema</a> to learn more about how this integrates into the rest of Bugzilla.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="CONSTANTS" +>CONSTANTS</a></h1> + +<dl> +<dt><a name="SCHEMA_VERSION" +><code class="code">SCHEMA_VERSION</code></a></dt> + +<dd> +<p>The 'version' of the internal schema structure. This version number is incremented every time the the fundamental structure of Schema internals changes.</p> + +<p>This is NOT changed every time a table or a column is added. This number is incremented only if the internal structures of this Schema would be incompatible with the internal structures of a previous Schema version.</p> + +<p>In general, unless you are messing around with serialization and deserialization of the schema, you don't need to worry about this constant.</p> + +<dt><a name="ABSTRACT_SCHEMA" +><code class="code">ABSTRACT_SCHEMA</code></a></dt> + +<dd> +<p>The abstract database schema structure consists of a hash reference in which each key is the name of a table in the Bugzilla database.</p> + +<p>The value for each key is a hash reference containing the keys <code class="code">FIELDS</code> and <code class="code">INDEXES</code> which in turn point to array references containing information on the table's fields and indexes.</p> + +<p>A field hash reference should must contain the key <code class="code">TYPE</code>. Optional field keys include <code class="code">PRIMARYKEY</code>, <code class="code">NOTNULL</code>, and <code class="code">DEFAULT</code>.</p> + +<p>The <code class="code">INDEXES</code> array reference contains index names and information regarding the index. If the index name points to an array reference, then the index is a regular index and the array contains the indexed columns. If the index name points to a hash reference, then the hash must contain the key <code class="code">FIELDS</code>. It may also contain the key <code class="code">TYPE</code>, which can be used to specify the type of index such as UNIQUE or FULLTEXT.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<p>Note: Methods which can be implemented generically for all DBs are implemented in this module. If needed, they can be overridden with DB-specific code in a subclass. Methods which are prefixed with <code class="code">_</code> are considered protected. Subclasses may override these methods, but other modules should not invoke these methods directly.</p> + +<dl> +<dt><a name="new" +><code class="code">new</code></a></dt> + +<dd> +<pre class="code"> Description: Public constructor method used to instantiate objects of this + class. However, it also can be used as a factory method to + instantiate database-specific subclasses when an optional + driver argument is supplied. + Parameters: $driver (optional) - Used to specify the type of database. + This routine C<die>s if no subclass is found for the specified + driver. + $schema (optional) - A reference to a hash. Callers external + to this package should never use this parameter. + Returns: new instance of the Schema class or a database-specific subclass</pre> + +<dt><a name="_initialize" +><code class="code">_initialize</code></a></dt> + +<dd> +<pre class="code"> Description: Protected method that initializes an object after + instantiation with the abstract schema. All subclasses should + override this method. The typical subclass implementation + should first call the C<_initialize> method of the superclass, + then do any database-specific initialization (especially + define the database-specific implementation of the all + abstract data types), and then call the C<_adjust_schema> + method. + Parameters: $abstract_schema (optional) - A reference to a hash. If + provided, this hash will be used as the internal + representation of the abstract schema instead of our + default abstract schema. This is intended for internal + use only by deserialize_abstract. + Returns: the instance of the Schema class</pre> + +<dt><a name="_adjust_schema" +><code class="code">_adjust_schema</code></a></dt> + +<dd> +<pre class="code"> Description: Protected method that alters the abstract schema at + instantiation-time to be database-specific. It is a generic + enough routine that it can be defined here in the base class. + It takes the abstract schema and replaces the abstract data + types with database-specific data types. + Parameters: none + Returns: the instance of the Schema class</pre> + +<dt><a name="get_type_ddl" +><code class="code">get_type_ddl</code></a></dt> + +<dd> +<pre class="code"> Description: Public method to convert abstract (database-generic) field + specifiers to database-specific data types suitable for use + in a C<CREATE TABLE> or C<ALTER TABLE> SQL statment. If no + database-specific field type has been defined for the given + field type, then it will just return the same field type. + Parameters: a hash or a reference to a hash of a field containing the + following keys: C<TYPE> (required), C<NOTNULL> (optional), + C<DEFAULT> (optional), C<PRIMARYKEY> (optional), C<REFERENCES> + (optional) + Returns: a DDL string suitable for describing a field in a + C<CREATE TABLE> or C<ALTER TABLE> SQL statement</pre> + +<dt><a name="convert_type" +><code class="code">convert_type</code></a></dt> + +<dd> +<p>Converts a TYPE from the <a href="#ABSTRACT_SCHEMA" class="podlinkpod" +>"ABSTRACT_SCHEMA"</a> format into the real SQL type.</p> + +<dt><a name="get_column($table,_$column)" +><code class="code">get_column($table, $column)</code></a></dt> + +<dd> +<pre class="code"> Description: Public method to get the abstract definition of a column. + Parameters: $table - the table name + $column - a column in the table + Returns: a hashref containing information about the column, including its + type (C<TYPE>), whether or not it can be null (C<NOTNULL>), + its default value if it has one (C<DEFAULT), etc. + Returns undef if the table or column does not exist.</pre> + +<dt><a name="get_table_list" +><code class="code">get_table_list</code></a></dt> + +<dd> +<pre class="code"> Description: Public method for discovering what tables should exist in the + Bugzilla database. + Parameters: none + Returns: an array of table names</pre> + +<dt><a name="get_table_columns" +><code class="code">get_table_columns</code></a></dt> + +<dd> +<pre class="code"> Description: Public method for discovering what columns are in a given + table in the Bugzilla database. + Parameters: $table - the table name + Returns: array of column names</pre> + +<dt><a name="get_table_ddl" +><code class="code">get_table_ddl</code></a></dt> + +<dd> +<pre class="code"> Description: Public method to generate the SQL statements needed to create + the a given table and its indexes in the Bugzilla database. + Subclasses may override or extend this method, if needed, but + subclasses probably should override C<_get_create_table_ddl> + or C<_get_create_index_ddl> instead. + Parameters: $table - the table name + Returns: an array of strings containing SQL statements</pre> + +<dt><a name="_get_create_table_ddl" +><code class="code">_get_create_table_ddl</code></a></dt> + +<dd> +<pre class="code"> Description: Protected method to generate the "create table" SQL statement + for a given table. + Parameters: $table - the table name + Returns: a string containing the DDL statement for the specified table</pre> + +<dt><a name="_get_create_index_ddl" +><code class="code">_get_create_index_ddl</code></a></dt> + +<dd> +<pre class="code"> Description: Protected method to generate a "create index" SQL statement + for a given table and index. + Parameters: $table_name - the name of the table + $index_name - the name of the index + $index_fields - a reference to an array of field names + $index_type (optional) - specify type of index (e.g., UNIQUE) + Returns: a string containing the DDL statement</pre> + +<dt><a name="get_add_column_ddl($table,_$column,_\%definition,_$init_value)" +><code class="code">get_add_column_ddl($table, $column, \%definition, $init_value)</code></a></dt> + +<dd> +<pre class="code"> Description: Generate SQL to add a column to a table. + Params: $table - The table containing the column. + $column - The name of the column being added. + \%definition - The new definition for the column, + in standard C<ABSTRACT_SCHEMA> format. + $init_value - (optional) An initial value to set + the column to. Should already be SQL-quoted + if necessary. + Returns: An array of SQL statements.</pre> + +<dt><a name="get_add_index_ddl" +><code class="code">get_add_index_ddl</code></a></dt> + +<dd> +<pre class="code"> Description: Gets SQL for creating an index. + NOTE: Subclasses should not override this function. Instead, + if they need to specify a custom CREATE INDEX statement, + they should override C<_get_create_index_ddl> + Params: $table - The name of the table the index will be on. + $name - The name of the new index. + $definition - An index definition. Either a hashref + with FIELDS and TYPE or an arrayref + containing a list of columns. + Returns: An array of SQL statements that will create the + requested index.</pre> + +<dt><a name="get_alter_column_ddl($table,_$column,_\%definition)" +><code class="code">get_alter_column_ddl($table, $column, \%definition)</code></a></dt> + +<dd> +<pre class="code"> Description: Generate SQL to alter a column in a table. + The column that you are altering must exist, + and the table that it lives in must exist. + Params: $table - The table containing the column. + $column - The name of the column being changed. + \%definition - The new definition for the column, + in standard C<ABSTRACT_SCHEMA> format. + $set_nulls_to - A value to set NULL values to, if + your new definition is NOT NULL and contains + no DEFAULT, and when there is a possibility + that the column could contain NULLs. $set_nulls_to + should be already SQL-quoted if necessary. + Returns: An array of SQL statements.</pre> + +<dt><a name="get_drop_index_ddl($table,_$name)" +><code class="code">get_drop_index_ddl($table, $name)</code></a></dt> + +<dd> +<pre class="code"> Description: Generates SQL statements to drop an index. + Params: $table - The table the index is on. + $name - The name of the index being dropped. + Returns: An array of SQL statements.</pre> + +<dt><a name="get_drop_column_ddl($table,_$column)" +><code class="code">get_drop_column_ddl($table, $column)</code></a></dt> + +<dd> +<pre class="code"> Description: Generate SQL to drop a column from a table. + Params: $table - The table containing the column. + $column - The name of the column being dropped. + Returns: An array of SQL statements.</pre> + +<dt><a name="get_drop_table_ddl($table)" +><code class="code">get_drop_table_ddl($table)</code></a></dt> + +<dd> +<pre class="code"> Description: Generate SQL to drop a table from the database. + Params: $table - The name of the table to drop. + Returns: An array of SQL statements.</pre> + +<dt><a name="get_rename_column_ddl($table,_$old_name,_$new_name)" +><code class="code">get_rename_column_ddl($table, $old_name, $new_name)</code></a></dt> + +<dd> +<pre class="code"> Description: Generate SQL to change the name of a column in a table. + NOTE: ANSI SQL contains no simple way to rename a column, + so this function is ABSTRACT and must be implemented + by subclasses. + Params: $table - The table containing the column to be renamed. + $old_name - The name of the column being renamed. + $new_name - The name the column is changing to. + Returns: An array of SQL statements.</pre> + +<dt><a name="get_rename_table_sql" +><code class="code">get_rename_table_sql</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Gets SQL to rename a table in the database.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$old_name_-_The_current_name_of_the_table." +><code class="code">$old_name</code> - The current name of the table. +<dt><a name="$new_name_-_The_new_name_of_the_table." +><code class="code">$new_name</code> - The new name of the table.</a></dt> +</dl> + +<dt><a name="Returns:_An_array_of_SQL_statements_to_rename_a_table." +><b>Returns</b>: An array of SQL statements to rename a table.</a></dt> +</dl> + +<dt><a name="delete_table($name)" +><code class="code">delete_table($name)</code></a></dt> + +<dd> +<pre class="code"> Description: Deletes a table from this Schema object. + Dies if you try to delete a table that doesn't exist. + Params: $name - The name of the table to delete. + Returns: nothing</pre> + +<dt><a name="get_column_abstract($table,_$column)" +><code class="code">get_column_abstract($table, $column)</code></a></dt> + +<dd> +<pre class="code"> Description: A column definition from the abstract internal schema. + cross-database format. + Params: $table - The name of the table + $column - The name of the column that you want + Returns: A hash reference. For the format, see the docs for + C<ABSTRACT_SCHEMA>. + Returns undef if the column or table does not exist.</pre> + +<dt><a name="get_indexes_on_column_abstract($table,_$column)" +><code class="code">get_indexes_on_column_abstract($table, $column)</code></a></dt> + +<dd> +<pre class="code"> Description: Gets a list of indexes that are on a given column. + Params: $table - The table the column is on. + $column - The name of the column. + Returns: Indexes in the standard format of an INDEX + entry on a table. That is, key-value pairs + where the key is the index name and the value + is the index definition. + If there are no indexes on that column, we return + undef.</pre> + +<dt><a name="get_index_abstract($table,_$index)" +><code class="code">get_index_abstract($table, $index)</code></a></dt> + +<dd> +<pre class="code"> Description: Returns an index definition from the internal abstract schema. + Params: $table - The table the index is on. + $index - The name of the index. + Returns: A hash reference representing an index definition. + See the C<ABSTRACT_SCHEMA> docs for details. + Returns undef if the index does not exist.</pre> + +<dt><a name="get_table_abstract($table)" +><code class="code">get_table_abstract($table)</code></a></dt> + +<dd> +<pre class="code"> Description: Gets the abstract definition for a table in this Schema + object. + Params: $table - The name of the table you want a definition for. + Returns: An abstract table definition, or undef if the table doesn't + exist.</pre> + +<dt><a name="add_table($name,_\%definition)" +><code class="code">add_table($name, \%definition)</code></a></dt> + +<dd> +<pre class="code"> Description: Creates a new table in this Schema object. + If you do not specify a definition, we will + simply create an empty table. + Params: $name - The name for the new table. + \%definition (optional) - An abstract definition for + the new table. + Returns: nothing</pre> + +<dt><a name="rename_table" +><code class="code">rename_table</code></a></dt> + +<dd> +<p>Renames a table from <code class="code">$old_name</code> to <code class="code">$new_name</code> in this Schema object.</p> + +<dt><a name="delete_column($table,_$column)" +><code class="code">delete_column($table, $column)</code></a></dt> + +<dd> +<pre class="code"> Description: Deletes a column from this Schema object. + Params: $table - Name of the table that the column is in. + The table must exist, or we will fail. + $column - Name of the column to delete. + Returns: nothing</pre> + +<dt><a name="rename_column($table,_$old_name,_$new_name)" +><code class="code">rename_column($table, $old_name, $new_name)</code></a></dt> + +<dd> +<pre class="code"> Description: Renames a column on a table in the Schema object. + The column that you are renaming must exist. + Params: $table - The table the column is on. + $old_name - The current name of the column. + $new_name - The new name of hte column. + Returns: nothing</pre> + +<dt><a name="set_column($table,_$column,_\%new_def)" +><code class="code">set_column($table, $column, \%new_def)</code></a></dt> + +<dd> +<pre class="code"> Description: Changes the definition of a column in this Schema object. + If the column doesn't exist, it will be added. + The table that you specify must already exist in the Schema. + NOTE: This does not affect the database on the disk. + Use the C<Bugzilla::DB> "Schema Modification Methods" + if you want to do that. + Params: $table - The name of the table that the column is on. + $column - The name of the column. + \%new_def - The new definition for the column, in + C<ABSTRACT_SCHEMA> format. + Returns: nothing</pre> + +<dt><a name="set_index($table,_$name,_$definition)" +><code class="code">set_index($table, $name, $definition)</code></a></dt> + +<dd> +<pre class="code"> Description: Changes the definition of an index in this Schema object. + If the index doesn't exist, it will be added. + The table that you specify must already exist in the Schema. + NOTE: This does not affect the database on the disk. + Use the C<Bugzilla::DB> "Schema Modification Methods" + if you want to do that. + Params: $table - The table the index is on. + $name - The name of the index. + $definition - A hashref or an arrayref. An index + definition in C<ABSTRACT_SCHEMA> format. + Returns: nothing</pre> + +<dt><a name="delete_index($table,_$name)" +><code class="code">delete_index($table, $name)</code></a></dt> + +<dd> +<pre class="code"> Description: Removes an index definition from this Schema object. + If the index doesn't exist, we will fail. + The table that you specify must exist in the Schema. + NOTE: This does not affect the database on the disk. + Use the C<Bugzilla::DB> "Schema Modification Methods" + if you want to do that. + Params: $table - The table the index is on. + $name - The name of the index that we're removing. + Returns: nothing</pre> + +<dt><a name="columns_equal($col_one,_$col_two)" +><code class="code">columns_equal($col_one, $col_two)</code></a></dt> + +<dd> +<pre class="code"> Description: Tells you if two columns have entirely identical definitions. + The TYPE field's value will be compared case-insensitive. + However, all other fields will be case-sensitive. + Params: $col_one, $col_two - The columns to compare. Hash + references, in C<ABSTRACT_SCHEMA> format. + Returns: C<1> if the columns are identical, C<0> if they are not.</pre> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SERIALIZATION/DESERIALIZATION" +>SERIALIZATION/DESERIALIZATION</a></h1> + +<dl> +<dt><a name="serialize_abstract()" +><code class="code">serialize_abstract()</code></a></dt> + +<dd> +<pre class="code"> Description: Serializes the "abstract" schema into a format + that deserialize_abstract() can read in. This is + a method, called on a Schema instance. + Parameters: none + Returns: A scalar containing the serialized, abstract schema. + Do not attempt to manipulate this data directly, + as the format may change at any time in the future. + The only thing you should do with the returned value + is either store it somewhere (coupled with appropriate + SCHEMA_VERSION) or deserialize it.</pre> + +<dt><a name="deserialize_abstract($serialized,_$version)" +><code class="code">deserialize_abstract($serialized, $version)</code></a></dt> + +<dd> +<pre class="code"> Description: Used for when you've read a serialized Schema off the disk, + and you want a Schema object that represents that data. + Params: $serialized - scalar. The serialized data. + $version - A number in the format X.YZ. The "version" + of the Schema that did the serialization. + See the docs for C<SCHEMA_VERSION> for more details. + Returns: A Schema object. It will have the methods of (and work + in the same fashion as) the current version of Schema. + However, it will represent the serialized data instead of + ABSTRACT_SCHEMA.</pre> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="CLASS_METHODS" +>CLASS METHODS</a></h1> + +<p>These methods are generally called on the class instead of on a specific object.</p> + +<dl> +<dt><a name="get_empty_schema()" +><code class="code">get_empty_schema()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns a Schema that has no tables. In effect, this + Schema is totally "empty." + Params: none + Returns: A "empty" Schema object.</pre> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="ABSTRACT_DATA_TYPES" +>ABSTRACT DATA TYPES</a></h1> + +<p>The size and range data provided here is only intended as a guide. See your database's Bugzilla module (in this directory) for the most up-to-date values for these data types. The following abstract data types are used:</p> + +<dl> +<dt><a name="BOOLEAN" +><code class="code">BOOLEAN</code></a></dt> + +<dd> +<p>Logical value 0 or 1 where 1 is true, 0 is false.</p> + +<dt><a name="INT1" +><code class="code">INT1</code></a></dt> + +<dd> +<p>Integer values (-128 - 127 or 0 - 255 unsigned).</p> + +<dt><a name="INT2" +><code class="code">INT2</code></a></dt> + +<dd> +<p>Integer values (-32,768 - 32767 or 0 - 65,535 unsigned).</p> + +<dt><a name="INT3" +><code class="code">INT3</code></a></dt> + +<dd> +<p>Integer values (-8,388,608 - 8,388,607 or 0 - 16,777,215 unsigned)</p> + +<dt><a name="INT4" +><code class="code">INT4</code></a></dt> + +<dd> +<p>Integer values (-2,147,483,648 - 2,147,483,647 or 0 - 4,294,967,295 unsigned)</p> + +<dt><a name="SMALLSERIAL" +><code class="code">SMALLSERIAL</code></a></dt> + +<dd> +<p>An auto-increment <a href="#INT1" class="podlinkpod" +>"INT1"</a></p> + +<dt><a name="MEDIUMSERIAL" +><code class="code">MEDIUMSERIAL</code></a></dt> + +<dd> +<p>An auto-increment <a href="#INT3" class="podlinkpod" +>"INT3"</a></p> + +<dt><a name="INTSERIAL" +><code class="code">INTSERIAL</code></a></dt> + +<dd> +<p>An auto-increment <a href="#INT4" class="podlinkpod" +>"INT4"</a></p> + +<dt><a name="TINYTEXT" +><code class="code">TINYTEXT</code></a></dt> + +<dd> +<p>Variable length string of characters up to 255 (2^8 - 1) characters wide or more depending on the character set used.</p> + +<dt><a name="MEDIUMTEXT" +><code class="code">MEDIUMTEXT</code></a></dt> + +<dd> +<p>Variable length string of characters up to 16M (2^24 - 1) characters wide or more depending on the character set used.</p> + +<dt><a name="TEXT" +><code class="code">TEXT</code></a></dt> + +<dd> +<p>Variable length string of characters up to 64K (2^16 - 1) characters wide or more depending on the character set used.</p> + +<dt><a name="LONGBLOB" +><code class="code">LONGBLOB</code></a></dt> + +<dd> +<p>Variable length string of binary data up to 4M (2^32 - 1) bytes wide</p> + +<dt><a name="DATETIME" +><code class="code">DATETIME</code></a></dt> + +<dd> +<p>DATETIME support varies from database to database, however, it's generally safe to say that DATETIME entries support all date/time combinations greater than 1900-01-01 00:00:00. Note that the format used is <code class="code">YYYY-MM-DD hh:mm:ss</code> to be safe, though it's possible that your database may not require leading zeros. For greatest compatibility, however, please make sure dates are formatted as above for queries to guarantee consistent results.</p> +</dd> +</dl> + +<p>Database-specific subclasses should define the implementation for these data types as a hash reference stored internally in the schema object as <code class="code">db_specific</code>. This is typically done in overridden <a href="../../_initialize.html" class="podlinkpod" +>_initialize</a> method.</p> + +<p>The following abstract boolean values should also be defined on a database-specific basis:</p> + +<dl> +<dt><a name="TRUE" +><code class="code">TRUE</code> +<dt><a name="FALSE" +><code class="code">FALSE</code></a></dt> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SEE_ALSO" +>SEE ALSO</a></h1> + +<p><a href="../../Bugzilla/DB.html" class="podlinkpod" +>Bugzilla::DB</a></p> + +<p><a href="http://www.bugzilla.org/docs/developer.html#sql-schema" class="podlinkurl" +>http://www.bugzilla.org/docs/developer.html#sql-schema</a></p> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Error.html b/docs/html/api/Bugzilla/Error.html new file mode 100644 index 000000000..b034ef54b --- /dev/null +++ b/docs/html/api/Bugzilla/Error.html @@ -0,0 +1,83 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Error</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Error</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#FUNCTIONS'>FUNCTIONS</a> + <li class='indexItem indexItem1'><a href='#SEE_ALSO'>SEE ALSO</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Error - Error handling utilities for Bugzilla</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Error; + + ThrowUserError("error_tag", + { foo => 'bar' });</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Various places throughout the Bugzilla codebase need to report errors to the user. The <code class="code">Throw*Error</code> family of functions allow this to be done in a generic and localisable manner.</p> + +<p>These functions automatically unlock the database tables, if there were any locked. They will also roll back the transaction, if it is supported by the underlying DB.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="FUNCTIONS" +>FUNCTIONS</a></h1> + +<dl> +<dt><a name="ThrowUserError" +><code class="code">ThrowUserError</code></a></dt> + +<dd> +<p>This function takes an error tag as the first argument, and an optional hashref of variables as a second argument. These are used by the <i>global/user-error.html.tmpl</i> template to format the error, using the passed in variables as required.</p> + +<dt><a name="ThrowCodeError" +><code class="code">ThrowCodeError</code></a></dt> + +<dd> +<p>This function is used when an internal check detects an error of some sort. This usually indicates a bug in Bugzilla, although it can occur if the user manually constructs urls without correct parameters.</p> + +<p>This function's behaviour is similar to <code class="code">ThrowUserError</code>, except that the template used to display errors is <i>global/code-error.html.tmpl</i>. In addition if the hashref used as the optional second argument contains a key <i>variables</i> then the contents of the hashref (which is expected to be another hashref) will be displayed after the error message, as a debugging aid.</p> + +<dt><a name="ThrowTemplateError" +><code class="code">ThrowTemplateError</code></a></dt> + +<dd> +<p>This function should only be called if a <code class="code">template-<gt</code>process()> fails. It tries another template first, because often one template being broken or missing doesn't mean that they all are. But it falls back to a print statement as a last-ditch error.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SEE_ALSO" +>SEE ALSO</a></h1> + +<p><a href="../Bugzilla.html" class="podlinkpod" +>Bugzilla</a></p> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Field.html b/docs/html/api/Bugzilla/Field.html new file mode 100644 index 000000000..632fef733 --- /dev/null +++ b/docs/html/api/Bugzilla/Field.html @@ -0,0 +1,325 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Field</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Field</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Instance_Properties'>Instance Properties</a> + <li class='indexItem indexItem2'><a href='#Instance_Mutators'>Instance Mutators</a> + <li class='indexItem indexItem2'><a href='#Class_Methods'>Class Methods</a> + <li class='indexItem indexItem2'><a href='#Data_Validation'>Data Validation</a> + </ul> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Field - a particular piece of information about bugs and useful routines for form field manipulation</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla; + use Data::Dumper; + + # Display information about all fields. + print Dumper(Bugzilla->get_fields()); + + # Display information about non-obsolete custom fields. + print Dumper(Bugzilla->get_fields({ obsolete => 1, custom => 1 })); + + # Display a list of the names of non-obsolete custom fields. + print Bugzilla->custom_field_names; + + use Bugzilla::Field; + + # Display information about non-obsolete custom fields. + # Bugzilla->get_fields() is a wrapper around Bugzilla::Field->match(), + # so both methods take the same arguments. + print Dumper(Bugzilla::Field->match({ obsolete => 1, custom => 1 })); + + # Create or update a custom field or field definition. + my $field = Bugzilla::Field->create( + {name => 'cf_silly', description => 'Silly', custom => 1}); + + # Instantiate a Field object for an existing field. + my $field = new Bugzilla::Field({name => 'qacontact_accessible'}); + if ($field->obsolete) { + print $field->description . " is obsolete\n"; + } + + # Validation Routines + check_field($name, $value, \@legal_values, $no_warn); + $fieldid = get_field_id($fieldname);</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Field.pm defines field objects, which represent the particular pieces of information that Bugzilla stores about bugs.</p> + +<p>This package also provides functions for dealing with CGI form fields.</p> + +<p><code class="code">Bugzilla::Field</code> is an implementation of <a href="../Bugzilla/Object.html" class="podlinkpod" +>Bugzilla::Object</a>, and so provides all of the methods available in <a href="../Bugzilla/Object.html" class="podlinkpod" +>Bugzilla::Object</a>, in addition to what is documented here.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Instance_Properties" +>Instance Properties</a></h2> + +<dl> +<dt><a name="name" +><code class="code">name</code></a></dt> + +<dd> +<p>the name of the field in the database; begins with "cf_" if field is a custom field, but test the value of the boolean "custom" property to determine if a given field is a custom field;</p> + +<dt><a name="description" +><code class="code">description</code></a></dt> + +<dd> +<p>a short string describing the field; displayed to Bugzilla users in several places within Bugzilla's UI, f.e. as the form field label on the "show bug" page;</p> +</dd> +</dl> + +<dl> +<dt><a name="type" +><code class="code">type</code></a></dt> + +<dd> +<p>an integer specifying the kind of field this is; values correspond to the FIELD_TYPE_* constants in Constants.pm</p> +</dd> +</dl> + +<dl> +<dt><a name="custom" +><code class="code">custom</code></a></dt> + +<dd> +<p>a boolean specifying whether or not the field is a custom field; if true, field name should start "cf_", but use this property to determine which fields are custom fields;</p> +</dd> +</dl> + +<dl> +<dt><a name="in_new_bugmail" +><code class="code">in_new_bugmail</code></a></dt> + +<dd> +<p>a boolean specifying whether or not the field is displayed in bugmail for newly-created bugs;</p> +</dd> +</dl> + +<dl> +<dt><a name="sortkey" +><code class="code">sortkey</code></a></dt> + +<dd> +<p>an integer specifying the sortkey of the field.</p> +</dd> +</dl> + +<dl> +<dt><a name="obsolete" +><code class="code">obsolete</code></a></dt> + +<dd> +<p>a boolean specifying whether or not the field is obsolete;</p> +</dd> +</dl> + +<dl> +<dt><a name="enter_bug" +><code class="code">enter_bug</code></a></dt> + +<dd> +<p>A boolean specifying whether or not this field should appear on enter_bug.cgi</p> +</dd> +</dl> + +<dl> +<dt><a name="legal_values" +><code class="code">legal_values</code></a></dt> + +<dd> +<p>A reference to an array with valid active values for this field.</p> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Instance_Mutators" +>Instance Mutators</a></h2> + +<p>These set the particular field that they are named after.</p> + +<p>They take a single value--the new value for that field.</p> + +<p>They will throw an error if you try to set the values to something invalid.</p> + +<dl> +<dt><a name="set_description" +><code class="code">set_description</code> +<dt><a name="set_enter_bug" +><code class="code">set_enter_bug</code> +<dt><a name="set_obsolete" +><code class="code">set_obsolete</code> +<dt><a name="set_sortkey" +><code class="code">set_sortkey</code> +<dt><a name="set_in_new_bugmail" +><code class="code">set_in_new_bugmail</code></a></dt> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Class_Methods" +>Class Methods</a></h2> + +<dl> +<dt><a name="create" +><code class="code">create</code></a></dt> + +<dd> +<p>Just like <a href="../Bugzilla/Object.html#create" class="podlinkpod" +>"create" in Bugzilla::Object</a>. Takes the following parameters:</p> + +<dl> +<dt><a name="name_Required_-_The_name_of_the_field." +><code class="code">name</code> <b>Required</b> - The name of the field. +<dt><a name="description_Required_-_The_field_label_to_display_in_the_UI." +><code class="code">description</code> <b>Required</b> - The field label to display in the UI. +<dt><a name="mailhead_-_boolean_-_Whether_this_field_appears_at_the_top_of_the_bugmail_for_a_newly-filed_bug._Defaults_to_0." +><code class="code">mailhead</code> - boolean - Whether this field appears at the top of the bugmail for a newly-filed bug. Defaults to 0. +<dt><a +><code class="code">custom</code> - boolean - True if this is a Custom Field. The field will be added to the <code class="code">bugs</code> table if it does not exist. Defaults to 0. +<dt><a name="sortkey_-_integer_-_The_sortkey_of_the_field._Defaults_to_0." +><code class="code">sortkey</code> - integer - The sortkey of the field. Defaults to 0. +<dt><a name="enter_bug_-_boolean_-_Whether_this_field_is_editable_on_the_bug_creation_form._Defaults_to_0." +><code class="code">enter_bug</code> - boolean - Whether this field is editable on the bug creation form. Defaults to 0.</a></dt> + +<dd> +<p><code class="code">obsolete</code> - boolean - Whether this field is obsolete. Defaults to 0.</p> +</dd> +</dl> +</dd> +</dl> + +<dl> +<dt><a name="match" +><code class="code">match</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Returns a list of fields that match the specified criteria.</p> + +<p>You should be using <a href="../Bugzilla.html#get_fields" class="podlinkpod" +>"get_fields" in Bugzilla</a> and <a href="../Bugzilla.html#get_custom_field_names" class="podlinkpod" +>"get_custom_field_names" in Bugzilla</a> instead of this function.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<p>Takes named parameters in a hashref:</p> + +<dl> +<dt><a name="name_-_The_name_of_the_field." +><code class="code">name</code> - The name of the field. +<dt><a name="custom_-_Boolean._True_to_only_return_custom_fields._False_to_only_return_non-custom_fields." +><code class="code">custom</code> - Boolean. True to only return custom fields. False to only return non-custom fields. +<dt><a name="obsolete_-_Boolean._True_to_only_return_obsolete_fields._False_to_not_return_obsolete_fields." +><code class="code">obsolete</code> - Boolean. True to only return obsolete fields. False to not return obsolete fields. +<dt><a name="type_-_The_type_of_the_field._A_FIELD_TYPE_constant_from_Bugzilla::Constants." +><code class="code">type</code> - The type of the field. A <code class="code">FIELD_TYPE</code> constant from <a href="../Bugzilla/Constants.html" class="podlinkpod" +>Bugzilla::Constants</a>. +<dt><a +><code class="code">enter_bug</code> - Boolean. True to only return fields that appear on <em class="code">enter_bug.cgi</em>. False to only return fields that <i>don't</i> appear on <em class="code">enter_bug.cgi</em>.</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A reference to an array of <code class="code">Bugzilla::Field</code> objects.</p> +</dd> +</dl> +</dd> +</dl> + +<dl> +<dt><a name="get_legal_field_values($field)" +><code class="code">get_legal_field_values($field)</code></a></dt> + +<dd> +<p>Description: returns all the legal values for a field that has a list of legal values, like rep_platform or resolution. The table where these values are stored must at least have the following columns: value, isactive, sortkey.</p> + +<p>Params: <code class="code">$field</code> - Name of the table where valid values are.</p> + +<p>Returns: a reference to a list of valid values.</p> +</dd> +</dl> + +<dl> +<dt><a name="populate_field_definitions()" +><code class="code">populate_field_definitions()</code></a></dt> + +<dd> +<p>Description: Populates the fielddefs table during an installation or upgrade.</p> + +<p>Params: none</p> + +<p>Returns: nothing</p> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Data_Validation" +>Data Validation</a></h2> + +<dl> +<dt><a name="check_field($name,_$value,_\@legal_values,_$no_warn)" +><code class="code">check_field($name, $value, \@legal_values, $no_warn)</code></a></dt> + +<dd> +<p>Description: Makes sure the field $name is defined and its $value is non empty. If @legal_values is defined, this routine checks whether its value is one of the legal values associated with this field, else it checks against the default valid values for this field obtained by <code class="code">get_legal_field_values($name)</code>. If the test is successful, the function returns 1. If the test fails, an error is thrown (by default), unless $no_warn is true, in which case the function returns 0.</p> + +<p>Params: $name - the field name $value - the field value @legal_values - (optional) list of legal values $no_warn - (optional) do not throw an error if true</p> + +<p>Returns: 1 on success; 0 on failure if $no_warn is true (else an error is thrown).</p> +</dd> +</dl> + +<dl> +<dt><a name="get_field_id($fieldname)" +><code class="code">get_field_id($fieldname)</code></a></dt> + +<dd> +<p>Description: Returns the ID of the specified field name and throws an error if this field does not exist.</p> + +<p>Params: $name - a field name</p> + +<p>Returns: the corresponding field ID or an error if the field name does not exist.</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Flag.html b/docs/html/api/Bugzilla/Flag.html new file mode 100644 index 000000000..f9273f9e3 --- /dev/null +++ b/docs/html/api/Bugzilla/Flag.html @@ -0,0 +1,254 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Flag</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Flag</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#NOTES'>NOTES</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#METHODS'>METHODS</a> + </ul> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Flag - A module to deal with Bugzilla flag values.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<p>Flag.pm provides an interface to flags as stored in Bugzilla. +See below for more information.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NOTES" +>NOTES</a></h1> + +<ul> +<li>Import relevant functions from that script.</li> + +<li>Use of private functions / variables outside this module may lead to unexpected results after an upgrade. +Please avoid using private functions in other files/modules. +Private functions are functions whose names start with _ or a re specifically noted as being private.</li> +</ul> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h2> + +<dl> +<dt><a name="id" +><code class="code">id</code></a></dt> + +<dd> +<p>Returns the ID of the flag.</p> + +<dt><a name="name" +><code class="code">name</code></a></dt> + +<dd> +<p>Returns the name of the flagtype the flag belongs to.</p> + +<dt><a name="bug_id" +><code class="code">bug_id</code></a></dt> + +<dd> +<p>Returns the ID of the bug this flag belongs to.</p> + +<dt><a name="attach_id" +><code class="code">attach_id</code></a></dt> + +<dd> +<p>Returns the ID of the attachment this flag belongs to, +if any.</p> + +<dt><a name="status" +><code class="code">status</code></a></dt> + +<dd> +<p>Returns the status '+', +'-', +'?' of the flag.</p> +</dd> +</dl> + +<dl> +<dt><a name="type" +><code class="code">type</code></a></dt> + +<dd> +<p>Returns the type of the flag, +as a Bugzilla::FlagType object.</p> + +<dt><a name="setter" +><code class="code">setter</code></a></dt> + +<dd> +<p>Returns the user who set the flag, +as a Bugzilla::User object.</p> + +<dt><a name="requestee" +><code class="code">requestee</code></a></dt> + +<dd> +<p>Returns the user who has been requested to set the flag, +as a Bugzilla::User object.</p> + +<dt><a name="attachment" +><code class="code">attachment</code></a></dt> + +<dd> +<p>Returns the attachment object the flag belongs to if the flag is an attachment flag, +else undefined.</p> +</dd> +</dl> + +<dl> +<dt><a name="match($criteria)" +><code class="code">match($criteria)</code></a></dt> + +<dd> +<p>Queries the database for flags matching the given criteria (specified as a hash of field names and their matching values) and returns an array of matching records.</p> +</dd> +</dl> + +<dl> +<dt><a name="count($criteria)" +><code class="code">count($criteria)</code></a></dt> + +<dd> +<p>Queries the database for flags matching the given criteria (specified as a hash of field names and their matching values) and returns an array of matching records.</p> +</dd> +</dl> + +<dl> +<dt><a name="validate($cgi,_$bug_id,_$attach_id,_$skip_requestee_on_error)" +><code class="code">validate($cgi, +$bug_id, +$attach_id, +$skip_requestee_on_error)</code></a></dt> + +<dd> +<p>Validates fields containing flag modifications.</p> + +<p>If the attachment is new, +it has no ID yet and $attach_id is set to -1 to force its check anyway.</p> +</dd> +</dl> + +<dl> +<dt><a name="process($bug,_$attachment,_$timestamp,_$cgi)" +><code class="code">process($bug, +$attachment, +$timestamp, +$cgi)</code></a></dt> + +<dd> +<p>Processes changes to flags.</p> + +<p>The bug and/or the attachment objects are the ones this flag is about, +the timestamp is the date/time the bug was last touched (so that changes to the flag can be stamped with the same date/time), +the cgi is the CGI object used to obtain the flag fields that the user submitted.</p> +</dd> +</dl> + +<dl> +<dt><a name="create($flag,_$bug,_$attachment,_$timestamp)" +><code class="code">create($flag, +$bug, +$attachment, +$timestamp)</code></a></dt> + +<dd> +<p>Creates a flag record in the database.</p> +</dd> +</dl> + +<dl> +<dt><a name="modify($bug,_$attachment,_$cgi,_$timestamp)" +><code class="code">modify($bug, +$attachment, +$cgi, +$timestamp)</code></a></dt> + +<dd> +<p>Modifies flags in the database when a user changes them.</p> +</dd> +</dl> + +<dl> +<dt><a name="retarget($flag,_$bug)" +><code class="code">retarget($flag, +$bug)</code></a></dt> + +<dd> +<p>Change the type of the flag, +if possible. +The new flag type must have the same name as the current flag type, +must exist in the product and component the bug is in, +and the current settings of the flag must pass validation. +If no such flag type can be found, +the type remains unchanged.</p> + +<p>Retargetting flags is a good way to keep flags when moving bugs from one product where a flag type is available to another product where the flag type is unavailable, +but another flag type having the same name exists. +Most of the time, +if they have the same name, +this means that they have the same meaning, +but with different settings.</p> +</dd> +</dl> + +<dl> +<dt><a name="clear($flag,_$bug,_$attachment)" +><code class="code">clear($flag, +$bug, +$attachment)</code></a></dt> + +<dd> +<p>Remove a flag from the DB.</p> +</dd> +</dl> + +<dl> +<dt><a name="FormToNewFlags($bug,_$attachment,_$cgi)" +><code class="code">FormToNewFlags($bug, +$attachment, +$cgi)</code></a></dt> + +<dd> +<p>Checks whether or not there are new flags to create and returns an array of flag objects. +This array is then passed to Flag::create().</p> +</dd> +</dl> + +<dl> +<dt><a name="notify($flag,_$bug,_$attachment)" +><code class="code">notify($flag, +$bug, +$attachment)</code></a></dt> + +<dd> +<p>Sends an email notification about a flag being created, +fulfilled or deleted.</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/FlagType.html b/docs/html/api/Bugzilla/FlagType.html new file mode 100644 index 000000000..0832c13dc --- /dev/null +++ b/docs/html/api/Bugzilla/FlagType.html @@ -0,0 +1,211 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::FlagType</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::FlagType</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#NOTES'>NOTES</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#METHODS'>METHODS</a> + </ul> + <li class='indexItem indexItem1'><a href='#PUBLIC_FUNCTIONS%2FMETHODS'>PUBLIC FUNCTIONS/METHODS</a> + <li class='indexItem indexItem1'><a href='#SEE_ALSO'>SEE ALSO</a> + <li class='indexItem indexItem1'><a href='#CONTRIBUTORS'>CONTRIBUTORS</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::FlagType - A module to deal with Bugzilla flag types.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<p>FlagType.pm provides an interface to flag types as stored in Bugzilla. +See below for more information.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NOTES" +>NOTES</a></h1> + +<ul> +<li>Use of private functions/variables outside this module may lead to unexpected results after an upgrade. +Please avoid using private functions in other files/modules. +Private functions are functions whose names start with _ or are specifically noted as being private.</li> +</ul> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h2> + +<dl> +<dt><a name="id" +><code class="code">id</code></a></dt> + +<dd> +<p>Returns the ID of the flagtype.</p> + +<dt><a name="name" +><code class="code">name</code></a></dt> + +<dd> +<p>Returns the name of the flagtype.</p> + +<dt><a name="description" +><code class="code">description</code></a></dt> + +<dd> +<p>Returns the description of the flagtype.</p> + +<dt><a name="cc_list" +><code class="code">cc_list</code></a></dt> + +<dd> +<p>Returns the concatenated CC list for the flagtype, +as a single string.</p> + +<dt><a name="target_type" +><code class="code">target_type</code></a></dt> + +<dd> +<p>Returns whether the flagtype applies to bugs or attachments.</p> + +<dt><a name="is_active" +><code class="code">is_active</code></a></dt> + +<dd> +<p>Returns whether the flagtype is active or disabled. +Flags being in a disabled flagtype are not deleted. +It only prevents you from adding new flags to it.</p> + +<dt><a name="is_requestable" +><code class="code">is_requestable</code></a></dt> + +<dd> +<p>Returns whether you can request for the given flagtype (i.e. +whether the '?' flag is available or not).</p> + +<dt><a name="is_requesteeble" +><code class="code">is_requesteeble</code></a></dt> + +<dd> +<p>Returns whether you can ask someone specifically or not.</p> + +<dt><a name="is_multiplicable" +><code class="code">is_multiplicable</code></a></dt> + +<dd> +<p>Returns whether you can have more than one flag for the given flagtype in a given bug/attachment.</p> + +<dt><a name="sortkey" +><code class="code">sortkey</code></a></dt> + +<dd> +<p>Returns the sortkey of the flagtype.</p> +</dd> +</dl> + +<dl> +<dt><a name="grant_group" +><code class="code">grant_group</code></a></dt> + +<dd> +<p>Returns the group (as a Bugzilla::Group object) in which a user must be in order to grant or deny a request.</p> + +<dt><a name="request_group" +><code class="code">request_group</code></a></dt> + +<dd> +<p>Returns the group (as a Bugzilla::Group object) in which a user must be in order to request or clear a flag.</p> + +<dt><a name="flag_count" +><code class="code">flag_count</code></a></dt> + +<dd> +<p>Returns the number of flags belonging to the flagtype.</p> + +<dt><a name="inclusions" +><code class="code">inclusions</code></a></dt> + +<dd> +<p>Return a hash of product/component IDs and names explicitly associated with the flagtype.</p> + +<dt><a name="exclusions" +><code class="code">exclusions</code></a></dt> + +<dd> +<p>Return a hash of product/component IDs and names explicitly excluded from the flagtype.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="PUBLIC_FUNCTIONS/METHODS" +>PUBLIC FUNCTIONS/METHODS</a></h1> + +<dl> +<dt><a name="get_clusions($id,_$type)" +><code class="code">get_clusions($id, +$type)</code></a></dt> + +<dd> +<p>Return a hash of product/component IDs and names associated with the flagtype: $clusions{'product_name:component_name'} = "product_ID:component_ID"</p> +</dd> +</dl> + +<dl> +<dt><a name="match($criteria)" +><code class="code">match($criteria)</code></a></dt> + +<dd> +<p>Queries the database for flag types matching the given criteria and returns a list of matching flagtype objects.</p> +</dd> +</dl> + +<dl> +<dt><a name="count($criteria)" +><code class="code">count($criteria)</code></a></dt> + +<dd> +<p>Returns the total number of flag types matching the given criteria.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SEE_ALSO" +>SEE ALSO</a></h1> + +<dl> +<dt><a name="Bugzilla::Flags" +><b>Bugzilla::Flags</b></a></dt> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="CONTRIBUTORS" +>CONTRIBUTORS</a></h1> + +<dl> +<dt><a name="Myk_Melez_<myk@mozilla.org>" +>Myk Melez <myk@mozilla.org> +<dt><a name="Kevin_Benton_<kevin.benton@amd.com>" +>Kevin Benton <kevin.benton@amd.com> +<dt><a name="Frédéric_Buclin_<LpSolit@gmail.com>" +>Frédéric Buclin <LpSolit@gmail.com></a></dt> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Group.html b/docs/html/api/Bugzilla/Group.html new file mode 100644 index 000000000..bb57ecb44 --- /dev/null +++ b/docs/html/api/Bugzilla/Group.html @@ -0,0 +1,101 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Group</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Group</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#SUBROUTINES'>SUBROUTINES</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Group - Bugzilla group class.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Group; + + my $group = new Bugzilla::Group(1); + my $group = new Bugzilla::Group({name => 'AcmeGroup'}); + + my $id = $group->id; + my $name = $group->name; + my $description = $group->description; + my $user_reg_exp = $group->user_reg_exp; + my $is_active = $group->is_active; + my $is_active_bug_group = $group->is_active_bug_group; + + my $group_id = Bugzilla::Group::ValidateGroupName('admin', @users); + my @groups = Bugzilla::Group->get_all;</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Group.pm represents a Bugzilla Group object. It is an implementation of <a href="../Bugzilla/Object.html" class="podlinkpod" +>Bugzilla::Object</a>, and thus has all the methods that <a href="../Bugzilla/Object.html" class="podlinkpod" +>Bugzilla::Object</a> provides, in addition to any methods documented below.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBROUTINES" +>SUBROUTINES</a></h1> + +<dl> +<dt><a name="create" +><code class="code">create</code></a></dt> + +<dd> +<p>Note that in addition to what <a href="../Bugzilla/Object.html#create(%24params)" class="podlinkpod" +>"create($params)" in Bugzilla::Object</a> normally does, this function also makes the new group be inherited by the <code class="code">admin</code> group. That is, the <code class="code">admin</code> group will automatically be a member of this group.</p> + +<dt><a name="ValidateGroupName($name,_@users)" +><code class="code">ValidateGroupName($name, @users)</code></a></dt> + +<dd> +<pre class="code"> Description: ValidateGroupName checks to see if ANY of the users + in the provided list of user objects can see the + named group. + + Params: $name - String with the group name. + @users - An array with Bugzilla::User objects. + + Returns: It returns the group id if successful + and undef otherwise.</pre> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<dl> +<dt><a name="members_non_inherited" +><code class="code">members_non_inherited</code></a></dt> + +<dd> +<p>Returns an arrayref of <a href="../Bugzilla/User.html" class="podlinkpod" +>Bugzilla::User</a> objects representing people who are "directly" in this group, meaning that they're in it because they match the group regular expression, or they have been actually added to the group manually.</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Hook.html b/docs/html/api/Bugzilla/Hook.html new file mode 100644 index 000000000..8e29cedb7 --- /dev/null +++ b/docs/html/api/Bugzilla/Hook.html @@ -0,0 +1,169 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Hook</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Hook</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#How_Hooks_Work'>How Hooks Work</a> + <li class='indexItem indexItem2'><a href='#Arguments_Passed_to_Hooks'>Arguments Passed to Hooks</a> + </ul> + <li class='indexItem indexItem1'><a href='#SUBROUTINES'>SUBROUTINES</a> + <li class='indexItem indexItem1'><a href='#HOOKS'>HOOKS</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#enter_bug-entrydefaultvars'>enter_bug-entrydefaultvars</a> + <li class='indexItem indexItem2'><a href='#install-requirements'>install-requirements</a> + <li class='indexItem indexItem2'><a href='#install-update_db'>install-update_db</a> + <li class='indexItem indexItem2'><a href='#db_schema-abstract_schema'>db_schema-abstract_schema</a> + </ul> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Hook - Extendible extension hooks for Bugzilla code</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Hook; + + Bugzilla::Hook::process("hookname", { arg => $value, arg2 => $value2 });</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Bugzilla allows extension modules to drop in and add routines at arbitrary points in Bugzilla code. These points are refered to as hooks. When a piece of standard Bugzilla code wants to allow an extension to perform additional functions, it uses Bugzilla::Hook's <a href="#process" class="podlinkpod" +>"process"</a> subroutine to invoke any extension code if installed.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="How_Hooks_Work" +>How Hooks Work</a></h2> + +<p>When a hook named <code class="code">HOOK_NAME</code> is run, Bugzilla will attempt to invoke any source files named <em class="code">extensions/*/code/HOOK_NAME.pl</em>.</p> + +<p>So, for example, if your extension is called "testopia", and you want to have code run during the <a href="#install-update_db" class="podlinkpod" +>"install-update_db"</a> hook, you would have a file called <em class="code">extensions/testopia/code/install-update_db.pl</em> that contained perl code to run during that hook.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Arguments_Passed_to_Hooks" +>Arguments Passed to Hooks</a></h2> + +<p>Some <a href="#HOOKS" class="podlinkpod" +>hooks</a> have params that are passed to them.</p> + +<p>These params are accessible through <a href="../Bugzilla.html#hook_args" class="podlinkpod" +>"hook_args" in Bugzilla</a>. That returns a hashref. Very frequently, if you want your hook to do anything, you have to modify these variables.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBROUTINES" +>SUBROUTINES</a></h1> + +<dl> +<dt><a name="process" +><code class="code">process</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Invoke any code hooks with a matching name from any installed extensions.</p> + +<p>See <code class="code">customization.xml</code> in the Bugzilla Guide for more information on Bugzilla's extension mechanism.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$name_-_The_name_of_the_hook_to_invoke." +><code class="code">$name</code> - The name of the hook to invoke. +<dt><a name="$args_-_A_hashref._The_named_args_to_pass_to_the_hook._They_will_be_accessible_to_the_hook_via_"hook_args"_in_Bugzilla." +><code class="code">$args</code> - A hashref. The named args to pass to the hook. They will be accessible to the hook via <a href="../Bugzilla.html#hook_args" class="podlinkpod" +>"hook_args" in Bugzilla</a>.</a></dt> +</dl> + +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="HOOKS" +>HOOKS</a></h1> + +<p>This describes what hooks exist in Bugzilla currently.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="enter_bug-entrydefaultvars" +>enter_bug-entrydefaultvars</a></h2> + +<p>This happens right before the template is loaded on enter_bug.cgi.</p> + +<p>Params:</p> + +<dl> +<dt><a name="vars_-_A_hashref._The_variables_that_will_be_passed_into_the_template." +><code class="code">vars</code> - A hashref. The variables that will be passed into the template.</a></dt> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="install-requirements" +>install-requirements</a></h2> + +<p>Because of the way Bugzilla installation works, there can't be a normal hook during the time that <em class="code">checksetup.pl</em> checks what modules are installed. (<code class="code">Bugzilla::Hook</code> needs to have those modules installed--it's a chicken-and-egg problem.)</p> + +<p>So instead of the way hooks normally work, this hook just looks for two subroutines (or constants, since all constants are just subroutines) in your file, called <code class="code">OPTIONAL_MODULES</code> and <code class="code">REQUIRED_MODULES</code>, which should return arrayrefs in the same format as <code class="code">OPTIONAL_MODULES</code> and <code class="code">REQUIRED_MODULES</code> in <a href="../Bugzilla/Install/Requirements.html" class="podlinkpod" +>Bugzilla::Install::Requirements</a>.</p> + +<p>These subroutines will be passed an arrayref that contains the current Bugzilla requirements of the same type, in case you want to modify Bugzilla's requirements somehow. (Probably the most common would be to alter a version number or the "feature" element of <code class="code">OPTIONAL_MODULES</code>.)</p> + +<p><em class="code">checksetup.pl</em> will add these requirements to its own.</p> + +<p>Please remember--if you put something in <code class="code">REQUIRED_MODULES</code>, then <em class="code">checksetup.pl</em> <b>cannot complete</b> unless the user has that module installed! So use <code class="code">OPTIONAL_MODULES</code> whenever you can.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="install-update_db" +>install-update_db</a></h2> + +<p>This happens at the very end of all the tables being updated during an installation or upgrade. If you need to modify your custom schema, do it here. No params are passed.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="db_schema-abstract_schema" +>db_schema-abstract_schema</a></h2> + +<p>This allows you to add tables to Bugzilla. Note that we recommend that you prefix the names of your tables with some word, so that they don't conflict with any future Bugzilla tables.</p> + +<p>If you wish to add new <i>columns</i> to existing Bugzilla tables, do that in <a href="#install-update_db" class="podlinkpod" +>"install-update_db"</a>.</p> + +<p>Params:</p> + +<dl> +<dt><a +><code class="code">schema</code> - A hashref, in the format of <a href="../Bugzilla/DB/Schema.html#ABSTRACT_SCHEMA" class="podlinkpod" +>"ABSTRACT_SCHEMA" in Bugzilla::DB::Schema</a>. Add new hash keys to make new table definitions. <em class="code">checksetup.pl</em> will automatically add these tables to the database when run.</a></dt> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Install.html b/docs/html/api/Bugzilla/Install.html new file mode 100644 index 000000000..44b231942 --- /dev/null +++ b/docs/html/api/Bugzilla/Install.html @@ -0,0 +1,87 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Install</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Install</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#CONSTANTS'>CONSTANTS</a> + <li class='indexItem indexItem1'><a href='#SUBROUTINES'>SUBROUTINES</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Install - Functions and variables having to do with installation.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Install; + Bugzilla::Install::update_settings();</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This module is used primarily by <a href="../checksetup.pl.html" class="podlinkpod" +>checksetup.pl</a> during installation. This module contains functions that deal with general installation issues after the database is completely set up and configured.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="CONSTANTS" +>CONSTANTS</a></h1> + +<dl> +<dt><a name="SETTINGS" +><code class="code">SETTINGS</code></a></dt> + +<dd> +<p>Contains information about Settings, used by <a href="#update_settings()" class="podlinkpod" +>"update_settings()"</a>.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBROUTINES" +>SUBROUTINES</a></h1> + +<dl> +<dt><a name="update_settings()" +><code class="code">update_settings()</code></a></dt> + +<dd> +<p>Description: Adds and updates Settings for users.</p> + +<p>Params: none</p> + +<p>Returns: nothing.</p> + +<dt><a name="create_default_product()" +><code class="code">create_default_product()</code></a></dt> + +<dd> +<p>Description: Creates the default product and classification if they don't exist.</p> + +<p>Params: none</p> + +<p>Returns: nothing</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Install/DB.html b/docs/html/api/Bugzilla/Install/DB.html new file mode 100644 index 000000000..fe810f1b1 --- /dev/null +++ b/docs/html/api/Bugzilla/Install/DB.html @@ -0,0 +1,86 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Install::DB</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Install::DB</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#SUBROUTINES'>SUBROUTINES</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Install::DB - Fix up the database during installation.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Install::DB qw(indicate_progress); + Bugzilla::Install::DB::update_table_definitions(); + + indicate_progress({ total => $total, current => $count, every => 10 });</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This module is used primarily by <a href="../../checksetup.pl.html" class="podlinkpod" +>checksetup.pl</a> to modify the database during upgrades.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBROUTINES" +>SUBROUTINES</a></h1> + +<dl> +<dt><a name="update_table_definitions()" +><code class="code">update_table_definitions()</code></a></dt> + +<dd> +<p>Description: This is the primary code that updates table definitions during upgrades. If you modify the schema in some way, you should add code to the end of this function to make sure that your modifications happen over all installations.</p> + +<p>Params: none</p> + +<p>Returns: nothing</p> + +<dt><a name="update_fielddefs_definition()" +><code class="code">update_fielddefs_definition()</code></a></dt> + +<dd> +<p>Description: <a href="../../checksetup.pl.html" class="podlinkpod" +>checksetup.pl</a> depends on the fielddefs table having its schema adjusted before the rest of the tables. So these schema updates happen in a separate function from <a href="#update_table_definitions()" class="podlinkpod" +>"update_table_definitions()"</a>.</p> + +<p>Params: none</p> + +<p>Returns: nothing</p> + +<dt><a name="indicate_progress({_total_=_$total,_current_=>_$count,_every_=>_1_})>" +><code class="code">indicate_progress({ total =</code> $total, current => $count, every => 1 })></a></dt> + +<dd> +<p>Description: This prints out lines of dots as a long update is going on, to let the user know where we are and that we're not frozen. A new line of dots will start every 60 dots.</p> + +<p>Params: <code class="code">total</code> - The total number of items we're processing. <code class="code">current</code> - The number of the current item we're processing. <code class="code">every</code> - How often the function should print out a dot. For example, if this is 10, the function will print out a dot every ten items.</p> + +<p>Returns: nothing</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Install/Filesystem.html b/docs/html/api/Bugzilla/Install/Filesystem.html new file mode 100644 index 000000000..8fd4b8c34 --- /dev/null +++ b/docs/html/api/Bugzilla/Install/Filesystem.html @@ -0,0 +1,79 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Install::Filesystem</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Install::Filesystem</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#SUBROUTINES'>SUBROUTINES</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Install::Filesystem - Fix up the filesystem during installation.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This module is used primarily by <a href="../../checksetup.pl.html" class="podlinkpod" +>checksetup.pl</a> to modify the filesystem during installation, +including creating the data/ directory.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBROUTINES" +>SUBROUTINES</a></h1> + +<dl> +<dt><a name="update_filesystem({_index_html_=_0_})>" +><code class="code">update_filesystem({ index_html =</code> 0 })></a></dt> + +<dd> +<p>Description: Creates all the directories and files that Bugzilla needs to function but doesn't ship with. +Also does any updates to these files as necessary during an upgrade.</p> + +<p>Params: <code class="code">index_html</code> - Whether or not we should create the <em class="code">index.html</em> file.</p> + +<p>Returns: nothing</p> + +<dt><a name="create_htaccess()" +><code class="code">create_htaccess()</code></a></dt> + +<dd> +<p>Description: Creates all of the .htaccess files for Apache, +in the various Bugzilla directories. +Also updates the .htaccess files if they need updating.</p> + +<p>Params: none</p> + +<p>Returns: nothing</p> + +<dt><a name="fix_all_file_permissions($output)" +><code class="code">fix_all_file_permissions($output)</code></a></dt> + +<dd> +<p>Description: Sets all the file permissions on all of Bugzilla's files to what they should be. +Note that permissions are different depending on whether or not <code class="code">$webservergroup</code> is set in <em class="code">localconfig</em>.</p> + +<p>Params: <code class="code">$output</code> - <code class="code">true</code> if you want this function to print out information about what it's doing.</p> + +<p>Returns: nothing</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Install/Localconfig.html b/docs/html/api/Bugzilla/Install/Localconfig.html new file mode 100644 index 000000000..186786f5d --- /dev/null +++ b/docs/html/api/Bugzilla/Install/Localconfig.html @@ -0,0 +1,101 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Install::Localconfig</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1></h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#CONSTANTS'>CONSTANTS</a> + <li class='indexItem indexItem1'><a href='#SUBROUTINES'>SUBROUTINES</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Install::Localconfig - Functions and variables dealing with the manipulation and creation of the <em class="code">localconfig</em> file.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Install::Requirements qw(update_localconfig); + update_localconfig({ output => 1 });</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This module is used primarily by <a href="../../checksetup.pl.html" class="podlinkpod" +>checksetup.pl</a> to create and modify the localconfig file. Most scripts should use <a href="../../Bugzilla.html#localconfig" class="podlinkpod" +>"localconfig" in Bugzilla</a> to access localconfig variables.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="CONSTANTS" +>CONSTANTS</a></h1> + +<dl> +<dt><a name="LOCALCONFIG_VARS" +><code class="code">LOCALCONFIG_VARS</code></a></dt> + +<dd> +<p>An array of hashrefs. These hashrefs contain three keys:</p> + +<pre class="code"> name - The name of the variable. + default - The default value for the variable. Should always be + something that can fit in a scalar. + desc - Additional text to put in localconfig before the variable + definition. Must end in a newline. Each line should start + with "#" unless you have some REALLY good reason not + to do that.</pre> + +<dt><a name="OLD_LOCALCONFIG_VARS" +><code class="code">OLD_LOCALCONFIG_VARS</code></a></dt> + +<dd> +<p>An array of names of variables. If <code class="code">update_localconfig</code> finds these variables defined in localconfig, it will print out a warning.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBROUTINES" +>SUBROUTINES</a></h1> + +<dl> +<dt><a name="read_localconfig($include_deprecated)" +><code class="code">read_localconfig($include_deprecated)</code></a></dt> + +<dd> +<p>Description: Reads the localconfig file and returns all valid values in a hashref.</p> + +<p>Params: <code class="code">$include_deprecated</code> - <code class="code">true</code> if you want the returned hashref to also include variables listed in <code class="code">OLD_LOCALCONFIG_VARS</code>, if they exist. Generally this is only for use by <code class="code">update_localconfig</code>.</p> + +<p>Returns: A hashref of the localconfig variables. If an array is defined, it will be an arrayref in the returned hash. If a hash is defined, it will be a hashref in the returned hash. Only includes variables specified in <code class="code">LOCALCONFIG_VARS</code> (and <code class="code">OLD_LOCALCONFIG_VARS</code> if <code class="code">$include_deprecated</code> is specified).</p> + +<dt><a name="update_localconfig({_output_=>_1_})" +><code class="code">update_localconfig({ output => 1 })</code></a></dt> + +<dd> +<p>Description: Adds any new variables to localconfig that aren't currently defined there. Also optionally prints out a message about vars that *should* be there and aren't. Exits the program if it adds any new vars.</p> + +<p>Params: <code class="code">output</code> - <code class="code">true</code> if the function should display informational output and warnings. It will always display errors or any message which would cause program execution to halt.</p> + +<p>Returns: A hashref, with <code class="code">old_vals</code> being an array of names of variables that were removed, and <code class="code">new_vals</code> being an array of names of variables that were added to localconfig.</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Install/Requirements.html b/docs/html/api/Bugzilla/Install/Requirements.html new file mode 100644 index 000000000..acaeeb055 --- /dev/null +++ b/docs/html/api/Bugzilla/Install/Requirements.html @@ -0,0 +1,140 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Install::Requirements</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Install::Requirements</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#CONSTANTS'>CONSTANTS</a> + <li class='indexItem indexItem1'><a href='#SUBROUTINES'>SUBROUTINES</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Install::Requirements - Functions and variables dealing with Bugzilla's perl-module requirements.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This module is used primarily by <code class="code">checksetup.pl</code> to determine whether or not all of Bugzilla's prerequisites are installed. +(That is, +all the perl modules it requires.)</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="CONSTANTS" +>CONSTANTS</a></h1> + +<dl> +<dt><a name="REQUIRED_MODULES" +><code class="code">REQUIRED_MODULES</code></a></dt> + +<dd> +<p>An arrayref of hashrefs that describes the perl modules required by Bugzilla. +The hashes have two keys, +<code class="code">name</code> and <code class="code">version</code>, +which represent the name of the module and the version that we require.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBROUTINES" +>SUBROUTINES</a></h1> + +<dl> +<dt><a name="check_requirements($output)" +><code class="code">check_requirements($output)</code></a></dt> + +<dd> +<pre class="code"> Description: This checks what optional or required perl modules + are installed, like C<checksetup.pl> does. + + Params: C<$output> - C<true> if you want the function to print + out information about what it's doing, + and the versions of everything installed. + If you don't pass the minimum requirements, + the will always print out something, + regardless of this parameter. + + Returns: A hashref containing three values: + C<pass> - Whether or not we have all the mandatory + requirements. + C<missing> - A hash showing which mandatory requirements + are missing. The key is the module name, + and the value is the version we require. + C<optional> - Which optional modules are installed and + up-to-date enough for Bugzilla.</pre> + +<dt><a name="check_graphviz($output)" +><code class="code">check_graphviz($output)</code></a></dt> + +<dd> +<p>Description: Checks if the graphviz binary specified in the <code class="code">webdotbase</code> parameter is a valid binary, or a valid URL.</p> + +<p>Params: <code class="code">$output</code> - <code class="code">$true</code> if you want the function to print out information about what it's doing.</p> + +<p>Returns: <code class="code">1</code> if the check was successful, <code class="code">0</code> otherwise.</p> + +<dt><a name="vers_cmp($a,_$b)" +><code class="code">vers_cmp($a, $b)</code></a></dt> + +<dd> +<pre class="code"> Description: This is a comparison function, like you would use in + C<sort>, except that it compares two version numbers. + It's actually identical to versioncmp from + L<Sort::Versions>. + + Params: c<$a> and C<$b> are versions you want to compare. + + Returns: -1 if $a is less than $b, 0 if they are equal, and + 1 if $a is greater than $b.</pre> + +<dt><a name="have_vers($module,_$output)" +><code class="code">have_vers($module, $output)</code></a></dt> + +<dd> +<pre class="code"> Description: Tells you whether or not you have the appropriate + version of the module requested. It also prints + out a message to the user explaining the check + and the result. + + Params: C<$module> - A hashref, in the format of an item from + L</REQUIRED_MODULES>. + C<$output> - Set to true if you want this function to + print information to STDOUT about what it's + doing. + + Returns: C<1> if you have the module installed and you have the + appropriate version. C<0> otherwise.</pre> + +<dt><a name="install_command($module)" +><code class="code">install_command($module)</code></a></dt> + +<dd> +<pre class="code"> Description: Prints out the appropriate command to install the + module specified, depending on whether you're + on Windows or Linux. + + Params: C<$module> - A hashref, in the format of an item from + L</REQUIRED_MODULES>. + + Returns: nothing</pre> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Keyword.html b/docs/html/api/Bugzilla/Keyword.html new file mode 100644 index 000000000..73c7153da --- /dev/null +++ b/docs/html/api/Bugzilla/Keyword.html @@ -0,0 +1,84 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Keyword</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Keyword</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#SUBROUTINES'>SUBROUTINES</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Keyword - A Keyword that can be added to a bug.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Keyword; + + my $count = Bugzilla::Keyword::keyword_count; + + my $description = $keyword->description; + + my $keywords = Bugzilla::Keyword->get_all_with_bug_count();</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Bugzilla::Keyword represents a keyword that can be added to a bug.</p> + +<p>This implements all standard <code class="code">Bugzilla::Object</code> methods. See <a href="../Bugzilla/Object.html" class="podlinkpod" +>Bugzilla::Object</a> for more details.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBROUTINES" +>SUBROUTINES</a></h1> + +<p>This is only a list of subroutines specific to <code class="code">Bugzilla::Keyword</code>. See <a href="../Bugzilla/Object.html" class="podlinkpod" +>Bugzilla::Object</a> for more subroutines that this object implements.</p> + +<dl> +<dt><a name="keyword_count()" +><code class="code">keyword_count()</code></a></dt> + +<dd> +<pre class="code"> Description: A utility function to get the total number + of keywords defined. Mostly used to see + if there are any keywords defined at all. + Params: none + Returns: An integer, the count of keywords.</pre> + +<dt><a name="get_all_with_bug_count()" +><code class="code">get_all_with_bug_count()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns all defined keywords. This is an efficient way + to get the associated bug counts, as only one SQL query + is executed with this method, instead of one per keyword + when calling get_all and then bug_count. + Params: none + Returns: A reference to an array of Keyword objects, or an empty + arrayref if there are no keywords.</pre> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Milestone.html b/docs/html/api/Bugzilla/Milestone.html new file mode 100644 index 000000000..d3f2077a5 --- /dev/null +++ b/docs/html/api/Bugzilla/Milestone.html @@ -0,0 +1,100 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Milestone</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Milestone</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> + <li class='indexItem indexItem1'><a href='#SUBROUTINES'>SUBROUTINES</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Milestone - Bugzilla product milestone class.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Milestone; + + my $milestone = new Bugzilla::Milestone( + { product => $product, name => 'milestone_value' }); + + my $product_id = $milestone->product_id; + my $value = $milestone->value; + + my $milestone = $hash_ref->{'milestone_value'};</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Milestone.pm represents a Product Milestone object.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<dl> +<dt><a name="new($product_id,_$value)" +><code class="code">new($product_id, $value)</code></a></dt> + +<dd> +<pre class="code"> Description: The constructor is used to load an existing milestone + by passing a product id and a milestone value. + + Params: $product_id - Integer with a Bugzilla product id. + $value - String with a milestone value. + + Returns: A Bugzilla::Milestone object.</pre> + +<dt><a name="bug_count()" +><code class="code">bug_count()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns the total of bugs that belong to the milestone. + + Params: none. + + Returns: Integer with the number of bugs.</pre> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBROUTINES" +>SUBROUTINES</a></h1> + +<dl> +<dt><a name="check_milestone($product,_$milestone_name)" +><code class="code">check_milestone($product, $milestone_name)</code></a></dt> + +<dd> +<pre class="code"> Description: Checks if a milestone name was passed in + and if it is a valid milestone. + + Params: $product - Bugzilla::Product object. + $milestone_name - String with a milestone name. + + Returns: Bugzilla::Milestone object.</pre> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Object.html b/docs/html/api/Bugzilla/Object.html new file mode 100644 index 000000000..10c447625 --- /dev/null +++ b/docs/html/api/Bugzilla/Object.html @@ -0,0 +1,370 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Object</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Object</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#CONSTANTS'>CONSTANTS</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Constructors'>Constructors</a> + <li class='indexItem indexItem2'><a href='#Database_Manipulation'>Database Manipulation</a> + <li class='indexItem indexItem2'><a href='#Subclass_Helpers'>Subclass Helpers</a> + </ul> + <li class='indexItem indexItem1'><a href='#CLASS_FUNCTIONS'>CLASS FUNCTIONS</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Object - A base class for objects in Bugzilla.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> my $object = new Bugzilla::Object(1); + my $object = new Bugzilla::Object({name => 'TestProduct'}); + + my $id = $object->id; + my $name = $object->name;</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Bugzilla::Object is a base class for Bugzilla objects. You never actually create a Bugzilla::Object directly, you only make subclasses of it.</p> + +<p>Basically, Bugzilla::Object exists to allow developers to create objects more easily. All you have to do is define <code class="code">DB_TABLE</code>, <code class="code">DB_COLUMNS</code>, and sometimes <code class="code">LIST_ORDER</code> and you have a whole new object.</p> + +<p>You should also define accessors for any columns other than <code class="code">name</code> or <code class="code">id</code>.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="CONSTANTS" +>CONSTANTS</a></h1> + +<p>Frequently, these will be the only things you have to define in your subclass in order to have a fully-functioning object. <code class="code">DB_TABLE</code> and <code class="code">DB_COLUMNS</code> are required.</p> + +<dl> +<dt><a name="DB_TABLE" +><code class="code">DB_TABLE</code></a></dt> + +<dd> +<p>The name of the table that these objects are stored in. For example, for <code class="code">Bugzilla::Keyword</code> this would be <code class="code">keyworddefs</code>.</p> + +<dt><a name="DB_COLUMNS" +><code class="code">DB_COLUMNS</code></a></dt> + +<dd> +<p>The names of the columns that you want to read out of the database and into this object. This should be an array.</p> + +<dt><a name="NAME_FIELD" +><code class="code">NAME_FIELD</code></a></dt> + +<dd> +<p>The name of the column that should be considered to be the unique "name" of this object. The 'name' is a <b>string</b> that uniquely identifies this Object in the database. Defaults to 'name'. When you specify <code class="code">{name =</code> $name}> to <code class="code">new()</code>, this is the column that will be matched against in the DB.</p> + +<dt><a name="ID_FIELD" +><code class="code">ID_FIELD</code></a></dt> + +<dd> +<p>The name of the column that represents the unique <b>integer</b> ID of this object in the database. Defaults to 'id'.</p> + +<dt><a name="LIST_ORDER" +><code class="code">LIST_ORDER</code></a></dt> + +<dd> +<p>The order that <code class="code">new_from_list</code> and <code class="code">get_all</code> should return objects in. This should be the name of a database column. Defaults to <a href="#NAME_FIELD" class="podlinkpod" +>"NAME_FIELD"</a>.</p> + +<dt><a name="REQUIRED_CREATE_FIELDS" +><code class="code">REQUIRED_CREATE_FIELDS</code></a></dt> + +<dd> +<p>The list of fields that <b>must</b> be specified when the user calls <code class="code">create()</code>. This should be an array.</p> + +<dt><a name="VALIDATORS" +><code class="code">VALIDATORS</code></a></dt> + +<dd> +<p>A hashref that points to a function that will validate each param to <a href="#create" class="podlinkpod" +>"create"</a>.</p> + +<p>Validators are called both by <a href="#create" class="podlinkpod" +>"create"</a> and <a href="#set" class="podlinkpod" +>"set"</a>. When they are called by <a href="#create" class="podlinkpod" +>"create"</a>, the first argument will be the name of the class (what we normally call <code class="code">$class</code>).</p> + +<p>When they are called by <a href="#set" class="podlinkpod" +>"set"</a>, the first argument will be a reference to the current object (what we normally call <code class="code">$self</code>).</p> + +<p>The second argument will be the value passed to <a href="#create" class="podlinkpod" +>"create"</a> or <a href="#set" class="podlinkpod" +>"set"</a>for that field.</p> + +<p>The third argument will be the name of the field being validated. This may be required by validators which validate several distinct fields.</p> + +<p>These functions should call <a href="../Bugzilla/Error.html#ThrowUserError" class="podlinkpod" +>"ThrowUserError" in Bugzilla::Error</a> if they fail.</p> + +<p>The validator must return the validated value.</p> + +<dt><a name="UPDATE_COLUMNS" +><code class="code">UPDATE_COLUMNS</code></a></dt> + +<dd> +<p>A list of columns to update when <a href="#update" class="podlinkpod" +>"update"</a> is called. If a field can't be changed, it shouldn't be listed here. (For example, the <a href="#ID_FIELD" class="podlinkpod" +>"ID_FIELD"</a> usually can't be updated.)</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Constructors" +>Constructors</a></h2> + +<dl> +<dt><a name="new($param)" +><code class="code">new($param)</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>The constructor is used to load an existing object from the database, by id or by name.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<p>If you pass an integer, the integer is the id of the object, from the database, that we want to read in. (id is defined as the value in the <a href="#ID_FIELD" class="podlinkpod" +>"ID_FIELD"</a> column).</p> + +<p>If you pass in a hash, you can pass a <code class="code">name</code> key. The value of the <code class="code">name</code> key is the case-insensitive name of the object (from <a href="#NAME_FIELD" class="podlinkpod" +>"NAME_FIELD"</a>) in the DB.</p> + +<p><b>Additional Parameters Available for Subclasses</b></p> + +<p>If you are a subclass of <code class="code">Bugzilla::Object</code>, you can pass <code class="code">condition</code> and <code class="code">values</code> as hash keys, instead of the above.</p> + +<p><code class="code">condition</code> is a set of SQL conditions for the WHERE clause, which contain placeholders.</p> + +<p><code class="code">values</code> is a reference to an array. The array contains the values for each placeholder in <code class="code">condition</code>, in order.</p> + +<p>This is to allow subclasses to have complex parameters, and then to translate those parameters into <code class="code">condition</code> and <code class="code">values</code> when they call <code class="code">$self-</code>SUPER::new> (which is this function, usually).</p> + +<p>If you try to call <code class="code">new</code> outside of a subclass with the <code class="code">condition</code> and <code class="code">values</code> parameters, Bugzilla will throw an error. These parameters are intended <b>only</b> for use by subclasses.</p> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A fully-initialized object.</p> +</dd> +</dl> + +<dt><a name="new_from_list(\@id_list)" +><code class="code">new_from_list(\@id_list)</code></a></dt> + +<dd> +<pre class="code"> Description: Creates an array of objects, given an array of ids. + + Params: \@id_list - A reference to an array of numbers, database ids. + If any of these are not numeric, the function + will throw an error. If any of these are not + valid ids in the database, they will simply + be skipped. + + Returns: A reference to an array of objects.</pre> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Database_Manipulation" +>Database Manipulation</a></h2> + +<dl> +<dt><a name="create" +><code class="code">create</code></a></dt> + +<dd> +<p>Description: Creates a new item in the database. Throws a User Error if any of the passed-in params are invalid.</p> + +<p>Params: <code class="code">$params</code> - hashref - A value to put in each database field for this object. Certain values must be set (the ones specified in <a href="#REQUIRED_CREATE_FIELDS" class="podlinkpod" +>"REQUIRED_CREATE_FIELDS"</a>), and the function will throw a Code Error if you don't set them.</p> + +<p>Returns: The Object just created in the database.</p> + +<p>Notes: In order for this function to work in your subclass, your subclass's <a href="#ID_FIELD" class="podlinkpod" +>"ID_FIELD"</a> must be of <code class="code">SERIAL</code> type in the database. Your subclass also must define <a href="#REQUIRED_CREATE_FIELDS" class="podlinkpod" +>"REQUIRED_CREATE_FIELDS"</a> and <a href="#VALIDATORS" class="podlinkpod" +>"VALIDATORS"</a>.</p> + +<pre class="code"> Subclass Implementors: This function basically just + calls L</check_required_create_fields>, then + L</run_create_validators>, and then finally + L</insert_create_data>. So if you have a complex system that + you need to implement, you can do it by calling these + three functions instead of C<SUPER::create>.</pre> + +<dt><a name="check_required_create_fields" +><code class="code">check_required_create_fields</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Part of <a href="#create" class="podlinkpod" +>"create"</a>. Throws an error if any of the <a href="#REQUIRED_CREATE_FIELDS" class="podlinkpod" +>"REQUIRED_CREATE_FIELDS"</a> have not been specified in <code class="code">$params</code></p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$params_-_The_same_as_$params_from_"create"." +><code class="code">$params</code> - The same as <code class="code">$params</code> from <a href="#create" class="podlinkpod" +>"create"</a>.</a></dt> +</dl> + +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> + +<dt><a name="run_create_validators" +><code class="code">run_create_validators</code></a></dt> + +<dd> +<p>Description: Runs the validation of input parameters for <a href="#create" class="podlinkpod" +>"create"</a>. This subroutine exists so that it can be overridden by subclasses who need to do special validations of their input parameters. This method is <b>only</b> called by <a href="#create" class="podlinkpod" +>"create"</a>.</p> + +<p>Params: The same as <a href="#create" class="podlinkpod" +>"create"</a>.</p> + +<p>Returns: A hash, in a similar format as <code class="code">$params</code>, except that these are the values to be inserted into the database, not the values that were input to <a href="#create" class="podlinkpod" +>"create"</a>.</p> + +<dt><a name="insert_create_data" +><code class="code">insert_create_data</code></a></dt> + +<dd> +<p>Part of <a href="#create" class="podlinkpod" +>"create"</a>.</p> + +<p>Takes the return value from <a href="#run_create_validators" class="podlinkpod" +>"run_create_validators"</a> and inserts the data into the database. Returns a newly created object.</p> + +<dt><a name="update" +><code class="code">update</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Saves the values currently in this object to the database. Only the fields specified in <a href="#UPDATE_COLUMNS" class="podlinkpod" +>"UPDATE_COLUMNS"</a> will be updated, and they will only be updated if their values have changed.</p> + +<dt><a name="Params_(none)" +><b>Params</b> (none) +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A hashref showing what changed during the update. The keys are the column names from <a href="#UPDATE_COLUMNS" class="podlinkpod" +>"UPDATE_COLUMNS"</a>. If a field was not changed, it will not be in the hash at all. If the field was changed, the key will point to an arrayref. The first item of the arrayref will be the old value, and the second item will be the new value.</p> + +<p>If there were no changes, we return a reference to an empty hash.</p> +</dd> +</dl> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Subclass_Helpers" +>Subclass Helpers</a></h2> + +<p>These functions are intended only for use by subclasses. If you call them from anywhere else, they will throw a <code class="code">CodeError</code>.</p> + +<dl> +<dt><a name="set" +><code class="code">set</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Sets a certain hash member of this class to a certain value. Used for updating fields. Calls the validator for this field, if it exists. Subclasses should use this function to implement the various <code class="code">set_</code> mutators for their different fields.</p> + +<p>See <a href="#VALIDATORS" class="podlinkpod" +>"VALIDATORS"</a> for more information.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a +><code class="code">$field</code> - The name of the hash member to update. This should be the same as the name of the field in <a href="#VALIDATORS" class="podlinkpod" +>"VALIDATORS"</a>, if it exists there. +<dt><a name="$value_-_The_value_that_you're_setting_the_field_to." +><code class="code">$value</code> - The value that you're setting the field to.</a></dt> +</dl> + +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing)</a></dt> +</dl> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="CLASS_FUNCTIONS" +>CLASS FUNCTIONS</a></h1> + +<dl> +<dt><a name="get_all" +><code class="code">get_all</code></a></dt> + +<dd> +<pre class="code"> Description: Returns all objects in this table from the database. + + Params: none. + + Returns: A list of objects, or an empty list if there are none. + + Notes: Note that you must call this as C<$class->get_all>. For + example, C<Bugzilla::Keyword->get_all>. + C<Bugzilla::Keyword::get_all> will not work.</pre> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Product.html b/docs/html/api/Bugzilla/Product.html new file mode 100644 index 000000000..60227fe61 --- /dev/null +++ b/docs/html/api/Bugzilla/Product.html @@ -0,0 +1,193 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Product</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Product</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> + <li class='indexItem indexItem1'><a href='#SUBROUTINES'>SUBROUTINES</a> + <li class='indexItem indexItem1'><a href='#SEE_ALSO'>SEE ALSO</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Product - Bugzilla product class.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Product; + + my $product = new Bugzilla::Product(1); + my $product = new Bugzilla::Product({ name => 'AcmeProduct' }); + + my @components = $product->components(); + my $groups_controls = $product->group_controls(); + my @milestones = $product->milestones(); + my @versions = $product->versions(); + my $bugcount = $product->bug_count(); + my $bug_ids = $product->bug_ids(); + my $has_access = $product->user_has_access($user); + my $flag_types = $product->flag_types(); + + my $id = $product->id; + my $name = $product->name; + my $description = $product->description; + my $milestoneurl = $product->milestone_url; + my disallownew = $product->disallow_new; + my votesperuser = $product->votes_per_user; + my maxvotesperbug = $product->max_votes_per_bug; + my votestoconfirm = $product->votes_to_confirm; + my $defaultmilestone = $product->default_milestone; + my $classificationid = $product->classification_id;</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Product.pm represents a product object. It is an implementation of <a href="../Bugzilla/Object.html" class="podlinkpod" +>Bugzilla::Object</a>, and thus provides all methods that <a href="../Bugzilla/Object.html" class="podlinkpod" +>Bugzilla::Object</a> provides.</p> + +<p>The methods that are specific to <code class="code">Bugzilla::Product</code> are listed below.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<dl> +<dt><a name="components()" +><code class="code">components()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns an array of component objects belonging to + the product. + + Params: none. + + Returns: An array of Bugzilla::Component object.</pre> + +<dt><a name="group_controls()" +><code class="code">group_controls()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns a hash (group id as key) with all product + group controls. + + Params: none. + + Returns: A hash with group id as key and hash containing + a Bugzilla::Group object and the properties of group + relative to the product.</pre> + +<dt><a name="versions()" +><code class="code">versions()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns all valid versions for that product. + + Params: none. + + Returns: An array of Bugzilla::Version objects.</pre> + +<dt><a name="milestones()" +><code class="code">milestones()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns all valid milestones for that product. + + Params: none. + + Returns: An array of Bugzilla::Milestone objects.</pre> + +<dt><a name="bug_count()" +><code class="code">bug_count()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns the total of bugs that belong to the product. + + Params: none. + + Returns: Integer with the number of bugs.</pre> + +<dt><a name="bug_ids()" +><code class="code">bug_ids()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns the IDs of bugs that belong to the product. + + Params: none. + + Returns: An array of integer.</pre> + +<dt><a name="user_has_access()" +><code class="code">user_has_access()</code></a></dt> + +<dd> +<pre class="code"> Description: Tells you whether or not the user is allowed to enter + bugs into this product, based on the C<entry> group + control. To see whether or not a user can actually + enter a bug into a product, use C<$user-&gt;can_enter_product>. + + Params: C<$user> - A Bugzilla::User object. + + Returns C<1> If this user's groups allow him C<entry> access to + this Product, C<0> otherwise.</pre> + +<dt><a name="flag_types()" +><code class="code">flag_types()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns flag types available for at least one of + its components. + + Params: none. + + Returns: Two references to an array of flagtype objects.</pre> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBROUTINES" +>SUBROUTINES</a></h1> + +<dl> +<dt><a name="check_product($product_name)" +><code class="code">check_product($product_name)</code></a></dt> + +<dd> +<pre class="code"> Description: Checks if the product name was passed in and if is a valid + product. + + Params: $product_name - String with a product name. + + Returns: Bugzilla::Product object.</pre> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SEE_ALSO" +>SEE ALSO</a></h1> + +<p><a href="../Bugzilla/Object.html" class="podlinkpod" +>Bugzilla::Object</a></p> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Search/Saved.html b/docs/html/api/Bugzilla/Search/Saved.html new file mode 100644 index 000000000..49fef8a87 --- /dev/null +++ b/docs/html/api/Bugzilla/Search/Saved.html @@ -0,0 +1,118 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Search::Saved</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1></h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Constructors_and_Database_Manipulation'>Constructors and Database Manipulation</a> + <li class='indexItem indexItem2'><a href='#Accessors'>Accessors</a> + </ul> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<pre class="code"> Bugzilla::Search::Saved - A saved search</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Search::Saved; + + my $query = new Bugzilla::Search::Saved($query_id); + + my $edit_link = $query->edit_link; + my $search_url = $query->url; + my $owner = $query->user;</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This module exists to represent a <a href="../../Bugzilla/Search.html" class="podlinkpod" +>Bugzilla::Search</a> that has been saved to the database.</p> + +<p>This is an implementation of <a href="../../Bugzilla/Object.html" class="podlinkpod" +>Bugzilla::Object</a>, and so has all the same methods available as <a href="../../Bugzilla/Object.html" class="podlinkpod" +>Bugzilla::Object</a>, in addition to what is documented below.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Constructors_and_Database_Manipulation" +>Constructors and Database Manipulation</a></h2> + +<dl> +<dt><a name="new" +><code class="code">new</code></a></dt> + +<dd> +<p>Does not accept a bare <code class="code">name</code> argument. Instead, accepts only an id.</p> + +<p>See also: <a href="../../Bugzilla/Object.html#new" class="podlinkpod" +>"new" in Bugzilla::Object</a>.</p> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Accessors" +>Accessors</a></h2> + +<p>These return data about the object, without modifying the object.</p> + +<dl> +<dt><a name="edit_link" +><code class="code">edit_link</code></a></dt> + +<dd> +<p>A url with which you can edit the search.</p> + +<dt><a name="url" +><code class="code">url</code></a></dt> + +<dd> +<p>The CGI parameters for the search, as a string.</p> + +<dt><a name="link_in_footer" +><code class="code">link_in_footer</code></a></dt> + +<dd> +<p>Whether or not this search should be displayed in the footer for the <i>current user</i> (not the owner of the search, but the person actually using Bugzilla right now).</p> + +<dt><a name="bug_ids_only" +><code class="code">bug_ids_only</code></a></dt> + +<dd> +<p>True if the search contains only a list of Bug IDs.</p> + +<dt><a name="shared_with_group" +><code class="code">shared_with_group</code></a></dt> + +<dd> +<p>The <a href="../../Bugzilla/Group.html" class="podlinkpod" +>Bugzilla::Group</a> that this search is shared with. <code class="code">undef</code> if this search isn't shared.</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Template.html b/docs/html/api/Bugzilla/Template.html new file mode 100644 index 000000000..490432224 --- /dev/null +++ b/docs/html/api/Bugzilla/Template.html @@ -0,0 +1,121 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Template</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Template</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#SUBROUTINES'>SUBROUTINES</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> + <li class='indexItem indexItem1'><a href='#SEE_ALSO'>SEE ALSO</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Template - Wrapper around the Template Toolkit <code class="code">Template</code> object</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> my $template = Bugzilla::Template->create; + + $template->put_header($title, $h1, $h2); + $template->put_footer(); + + my $format = $template->get_format("foo/bar", + scalar($cgi->param('format')), + scalar($cgi->param('ctype')));</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This is basically a wrapper so that the correct arguments get passed into the <code class="code">Template</code> constructor.</p> + +<p>It should not be used directly by scripts or modules - instead, use <code class="code">Bugzilla->instance->template</code> to get an already created module.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBROUTINES" +>SUBROUTINES</a></h1> + +<dl> +<dt><a name="precompile_templates($output)" +><code class="code">precompile_templates($output)</code></a></dt> + +<dd> +<p>Description: Compiles all of Bugzilla's templates in every language. Used mostly by <em class="code">checksetup.pl</em>.</p> + +<p>Params: <code class="code">$output</code> - <code class="code">true</code> if you want the function to print out information about what it's doing.</p> + +<p>Returns: nothing</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<dl> +<dt><a name="put_header($title,_$h1,_$h2)" +><code class="code">put_header($title, $h1, $h2)</code></a></dt> + +<dd> +<pre class="code"> Description: Display the header of the page for non yet templatized .cgi files. + + Params: $title - Page title. + $h1 - Main page header. + $h2 - Page subheader. + + Returns: nothing</pre> + +<dt><a name="put_footer()" +><code class="code">put_footer()</code></a></dt> + +<dd> +<pre class="code"> Description: Display the footer of the page for non yet templatized .cgi files. + + Params: none + + Returns: nothing</pre> + +<dt><a name="get_format($file,_$format,_$ctype)" +><code class="code">get_format($file, $format, $ctype)</code></a></dt> + +<dd> +<pre class="code"> Description: Construct a format object from URL parameters. + + Params: $file - Name of the template to display. + $format - When the template exists under several formats + (e.g. table or graph), specify the one to choose. + $ctype - Content type, see Bugzilla::Constants::contenttypes. + + Returns: A format object.</pre> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SEE_ALSO" +>SEE ALSO</a></h1> + +<p><a href="../Bugzilla.html" class="podlinkpod" +>Bugzilla</a>, <a href="../Template.html" class="podlinkpod" +>Template</a></p> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Template/Plugin/Bugzilla.html b/docs/html/api/Bugzilla/Template/Plugin/Bugzilla.html new file mode 100644 index 000000000..8b0b1a7a4 --- /dev/null +++ b/docs/html/api/Bugzilla/Template/Plugin/Bugzilla.html @@ -0,0 +1,45 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Template::Plugin::Bugzilla</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Template::Plugin::Bugzilla</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#SEE_ALSO'>SEE ALSO</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Template::Plugin::Bugzilla</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Template Toolkit plugin to allow access to the persistent <code class="code">Bugzilla</code> object.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SEE_ALSO" +>SEE ALSO</a></h1> + +<p><a href="../../../Bugzilla.html" class="podlinkpod" +>Bugzilla</a>, +<a href="../../../Template/Plugin.html" class="podlinkpod" +>Template::Plugin</a></p> +<p class="backlinkbottom"><b><a name="___bottom" href="../../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Template/Plugin/Hook.html b/docs/html/api/Bugzilla/Template/Plugin/Hook.html new file mode 100644 index 000000000..43f1ea2cf --- /dev/null +++ b/docs/html/api/Bugzilla/Template/Plugin/Hook.html @@ -0,0 +1,46 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Template::Plugin::Hook</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Template::Plugin::Hook</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#SEE_ALSO'>SEE ALSO</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Template::Plugin::Hook</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Template Toolkit plugin to process hooks added into templates by extensions.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SEE_ALSO" +>SEE ALSO</a></h1> + +<p><a href="../../../Template/Plugin.html" class="podlinkpod" +>Template::Plugin</a> <a href="../../../http%3A%2F%2Fwww.bugzilla.org%2Fdocs%2Ftip%2Fhtml%2Fcustomization.html.html" class="podlinkpod" +>http://www.bugzilla.org/docs/tip/html/customization.html</a> <a href="../../../http%3A%2F%2Fbugzilla.mozilla.org%2Fshow_bug.cgi%3Fid%3D229658.html" class="podlinkpod" +>http://bugzilla.mozilla.org/show_bug.cgi?id=229658</a> <a href="../../../http%3A%2F%2Fbugzilla.mozilla.org%2Fshow_bug.cgi%3Fid%3D298341.html" class="podlinkpod" +>http://bugzilla.mozilla.org/show_bug.cgi?id=298341</a></p> +<p class="backlinkbottom"><b><a name="___bottom" href="../../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Template/Plugin/User.html b/docs/html/api/Bugzilla/Template/Plugin/User.html new file mode 100644 index 000000000..a96dedd92 --- /dev/null +++ b/docs/html/api/Bugzilla/Template/Plugin/User.html @@ -0,0 +1,45 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Template::Plugin::User</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Template::Plugin::User</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#SEE_ALSO'>SEE ALSO</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Template::Plugin::User</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Template Toolkit plugin to allow access to the <code class="code">User</code> object.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SEE_ALSO" +>SEE ALSO</a></h1> + +<p><a href="../../../Bugzilla/User.html" class="podlinkpod" +>Bugzilla::User</a>, +<a href="../../../Template/Plugin.html" class="podlinkpod" +>Template::Plugin</a></p> +<p class="backlinkbottom"><b><a name="___bottom" href="../../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Token.html b/docs/html/api/Bugzilla/Token.html new file mode 100644 index 000000000..dc5cdf8f2 --- /dev/null +++ b/docs/html/api/Bugzilla/Token.html @@ -0,0 +1,233 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Token</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Token</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#SUBROUTINES'>SUBROUTINES</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Security_related_routines'>Security related routines</a> + </ul> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Token - Provides different routines to manage tokens.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Token; + + Bugzilla::Token::issue_new_user_account_token($login_name); + Bugzilla::Token::IssueEmailChangeToken($user_id, $old_email, $new_email); + Bugzilla::Token::IssuePasswordToken($login_name); + Bugzilla::Token::DeletePasswordTokens($user_id, $reason); + Bugzilla::Token::Cancel($token, $cancelaction, $vars); + + Bugzilla::Token::CleanTokenTable(); + + my $token = issue_session_token($event); + check_token_data($token, $event) + delete_token($token); + + my $token = Bugzilla::Token::GenerateUniqueToken($table, $column); + my $token = Bugzilla::Token::HasEmailChangeToken($user_id); + my ($token, $date, $data) = Bugzilla::Token::GetTokenData($token);</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBROUTINES" +>SUBROUTINES</a></h1> + +<dl> +<dt><a name="issue_new_user_account_token($login_name)" +><code class="code">issue_new_user_account_token($login_name)</code></a></dt> + +<dd> +<pre class="code"> Description: Creates and sends a token per email to the email address + requesting a new user account. It doesn't check whether + the user account already exists. The user will have to + use this token to confirm the creation of his user account. + + Params: $login_name - The new login name requested by the user. + + Returns: Nothing. It throws an error if the same user made the same + request in the last few minutes.</pre> + +<dt><a name="sub_IssueEmailChangeToken($user_id,_$old_email,_$new_email)" +><code class="code">sub IssueEmailChangeToken($user_id, $old_email, $new_email)</code></a></dt> + +<dd> +<pre class="code"> Description: Sends two distinct tokens per email to the old and new email + addresses to confirm the email address change for the given + user ID. These tokens remain valid for the next MAX_TOKEN_AGE days. + + Params: $user_id - The user ID of the user account requesting a new + email address. + $old_email - The current (old) email address of the user. + $new_email - The new email address of the user. + + Returns: Nothing.</pre> + +<dt><a name="IssuePasswordToken($login_name)" +><code class="code">IssuePasswordToken($login_name)</code></a></dt> + +<dd> +<pre class="code"> Description: Sends a token per email to the given login name. This token + can be used to change the password (e.g. in case the user + cannot remember his password and wishes to enter a new one). + + Params: $login_name - The login name of the user requesting a new password. + + Returns: Nothing. It throws an error if the same user made the same + request in the last few minutes.</pre> + +<dt><a name="CleanTokenTable()" +><code class="code">CleanTokenTable()</code></a></dt> + +<dd> +<pre class="code"> Description: Removes all tokens older than MAX_TOKEN_AGE days from the DB. + This means that these tokens will now be considered as invalid. + + Params: None. + + Returns: Nothing.</pre> + +<dt><a name="GenerateUniqueToken($table,_$column)" +><code class="code">GenerateUniqueToken($table, $column)</code></a></dt> + +<dd> +<pre class="code"> Description: Generates and returns a unique token. This token is unique + in the $column of the $table. This token is NOT stored in the DB. + + Params: $table (optional): The table to look at (default: tokens). + $column (optional): The column to look at for uniqueness (default: token). + + Returns: A token which is unique in $column.</pre> + +<dt><a name="Cancel($token,_$cancelaction,_$vars)" +><code class="code">Cancel($token, $cancelaction, $vars)</code></a></dt> + +<dd> +<pre class="code"> Description: Invalidates an existing token, generally when the token is used + for an action which is not the one expected. An email is sent + to the user who originally requested this token to inform him + that this token has been invalidated (e.g. because an hacker + tried to use this token for some malicious action). + + Params: $token: The token to invalidate. + $cancelaction: The reason why this token is invalidated. + $vars: Some additional information about this action. + + Returns: Nothing.</pre> + +<dt><a name="DeletePasswordTokens($user_id,_$reason)" +><code class="code">DeletePasswordTokens($user_id, $reason)</code></a></dt> + +<dd> +<pre class="code"> Description: Cancels all password tokens for the given user. Emails are sent + to the user to inform him about this action. + + Params: $user_id: The user ID of the user account whose password tokens + are canceled. + $reason: The reason why these tokens are canceled. + + Returns: Nothing.</pre> + +<dt><a name="HasEmailChangeToken($user_id)" +><code class="code">HasEmailChangeToken($user_id)</code></a></dt> + +<dd> +<pre class="code"> Description: Returns any existing token currently used for an email change + for the given user. + + Params: $user_id - A user ID. + + Returns: A token if it exists, else undef.</pre> + +<dt><a name="GetTokenData($token)" +><code class="code">GetTokenData($token)</code></a></dt> + +<dd> +<pre class="code"> Description: Returns all stored data for the given token. + + Params: $token - A valid token. + + Returns: The user ID, the date and time when the token was created and + the (event)data stored with that token.</pre> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Security_related_routines" +>Security related routines</a></h2> + +<p>The following routines have been written to be used together as described below, although they can be used separately.</p> + +<dl> +<dt><a name="issue_session_token($event)" +><code class="code">issue_session_token($event)</code></a></dt> + +<dd> +<pre class="code"> Description: Creates and returns a token used internally. + + Params: $event - The event which needs to be stored in the DB for future + reference/checks. + + Returns: A unique token.</pre> + +<dt><a name="check_token_data($token,_$event)" +><code class="code">check_token_data($token, $event)</code></a></dt> + +<dd> +<pre class="code"> Description: Makes sure the $token has been created by the currently logged in + user and to be used for the given $event. If this token is used for + an unexpected action (i.e. $event doesn't match the information stored + with the token), a warning is displayed asking whether the user really + wants to continue. On success, it returns 1. + This is the routine to use for security checks, combined with + issue_session_token() and delete_token() as follows: + + 1. First, create a token for some coming action. + my $token = issue_session_token($action); + 2. Some time later, it's time to make sure that the expected action + is going to be executed, and by the expected user. + check_token_data($token, $action); + 3. The check has been done and we no longer need this token. + delete_token($token); + + Params: $token - The token used for security checks. + $event - The expected event to be run. + + Returns: 1 on success, else a warning is thrown.</pre> + +<dt><a name="delete_token($token)" +><code class="code">delete_token($token)</code></a></dt> + +<dd> +<pre class="code"> Description: Deletes the specified token. No notification is sent. + + Params: $token - The token to delete. + + Returns: Nothing.</pre> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Update.html b/docs/html/api/Bugzilla/Update.html new file mode 100644 index 000000000..5bbbe72b7 --- /dev/null +++ b/docs/html/api/Bugzilla/Update.html @@ -0,0 +1,66 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Update</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Update</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#FUNCTIONS'>FUNCTIONS</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Update - Update routines for Bugzilla</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Update; + + # Get information about new releases + my $new_release = Bugzilla::Update::get_notifications();</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This module contains all required routines to notify you about new releases. It downloads an XML file from bugzilla.org and parses it, in order to display information based on your preferences. Absolutely no information about the Bugzilla version you are running is sent to bugzilla.org.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="FUNCTIONS" +>FUNCTIONS</a></h1> + +<dl> +<dt><a name="get_notifications()" +><code class="code">get_notifications()</code></a></dt> + +<dd> +<pre class="code"> Description: This function informs you about new releases, if any. + + Params: None. + + Returns: On success, a reference to a hash with data about + new releases, if any. + On failure, a reference to a hash with the reason + of the failure and the name of the unusable XML file.</pre> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/User.html b/docs/html/api/Bugzilla/User.html new file mode 100644 index 000000000..6cc5ef786 --- /dev/null +++ b/docs/html/api/Bugzilla/User.html @@ -0,0 +1,501 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::User</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::User</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#CONSTANTS'>CONSTANTS</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Saved_and_Shared_Queries'>Saved and Shared Queries</a> + <li class='indexItem indexItem2'><a href='#Other_Methods'>Other Methods</a> + </ul> + <li class='indexItem indexItem1'><a href='#CLASS_FUNCTIONS'>CLASS FUNCTIONS</a> + <li class='indexItem indexItem1'><a href='#SEE_ALSO'>SEE ALSO</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::User - Object for a Bugzilla user</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::User; + + my $user = new Bugzilla::User($id); + + my @get_selectable_classifications = + $user->get_selectable_classifications; + + # Class Functions + $user = Bugzilla::User->create({ + login_name => $username, + realname => $realname, + cryptpassword => $plaintext_password, + disabledtext => $disabledtext, + disable_mail => 0});</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This package handles Bugzilla users. Data obtained from here is read-only; there is currently no way to modify a user from this package.</p> + +<p>Note that the currently logged in user (if any) is available via <a href="../Bugzilla.html#user" class="podlinkpod" +>Bugzilla->user</a>.</p> + +<p><code class="code">Bugzilla::User</code> is an implementation of <a href="../Bugzilla/Object.html" class="podlinkpod" +>Bugzilla::Object</a>, and thus provides all the methods of <a href="../Bugzilla/Object.html" class="podlinkpod" +>Bugzilla::Object</a> in addition to the methods listed below.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="CONSTANTS" +>CONSTANTS</a></h1> + +<dl> +<dt><a name="USER_MATCH_MULTIPLE" +><code class="code">USER_MATCH_MULTIPLE</code></a></dt> + +<dd> +<p>Returned by <code class="code">match_field()</code> when at least one field matched more than one user, but no matches failed.</p> + +<dt><a name="USER_MATCH_FAILED" +><code class="code">USER_MATCH_FAILED</code></a></dt> + +<dd> +<p>Returned by <code class="code">match_field()</code> when at least one field failed to match anything.</p> + +<dt><a name="USER_MATCH_SUCCESS" +><code class="code">USER_MATCH_SUCCESS</code></a></dt> + +<dd> +<p>Returned by <code class="code">match_field()</code> when all fields successfully matched only one user.</p> + +<dt><a name="MATCH_SKIP_CONFIRM" +><code class="code">MATCH_SKIP_CONFIRM</code></a></dt> + +<dd> +<p>Passed in to match_field to tell match_field to never display a confirmation screen.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Saved_and_Shared_Queries" +>Saved and Shared Queries</a></h2> + +<dl> +<dt><a name="queries" +><code class="code">queries</code></a></dt> + +<dd> +<p>Returns an arrayref of the user's own saved queries, sorted by name. The array contains <a href="../Bugzilla/Search/Saved.html" class="podlinkpod" +>Bugzilla::Search::Saved</a> objects.</p> + +<dt><a name="queries_subscribed" +><code class="code">queries_subscribed</code></a></dt> + +<dd> +<p>Returns an arrayref of shared queries that the user has subscribed to. That is, these are shared queries that the user sees in their footer. This array contains <a href="../Bugzilla/Search/Saved.html" class="podlinkpod" +>Bugzilla::Search::Saved</a> objects.</p> + +<dt><a name="queries_available" +><code class="code">queries_available</code></a></dt> + +<dd> +<p>Returns an arrayref of all queries to which the user could possibly subscribe. This includes the contents of <a href="#queries_subscribed" class="podlinkpod" +>"queries_subscribed"</a>. An array of <a href="../Bugzilla/Search/Saved.html" class="podlinkpod" +>Bugzilla::Search::Saved</a> objects.</p> + +<dt><a name="flush_queries_cache" +><code class="code">flush_queries_cache</code></a></dt> + +<dd> +<p>Some code modifies the set of stored queries. Because <code class="code">Bugzilla::User</code> does not handle these modifications, but does cache the result of calling <code class="code">queries</code> internally, such code must call this method to flush the cached result.</p> + +<dt><a name="queryshare_groups" +><code class="code">queryshare_groups</code></a></dt> + +<dd> +<p>An arrayref of group ids. The user can share their own queries with these groups.</p> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Other_Methods" +>Other Methods</a></h2> + +<dl> +<dt><a name="id" +><code class="code">id</code></a></dt> + +<dd> +<p>Returns the userid for this user.</p> + +<dt><a name="login" +><code class="code">login</code></a></dt> + +<dd> +<p>Returns the login name for this user.</p> + +<dt><a name="email" +><code class="code">email</code></a></dt> + +<dd> +<p>Returns the user's email address. Currently this is the same value as the login.</p> + +<dt><a name="name" +><code class="code">name</code></a></dt> + +<dd> +<p>Returns the 'real' name for this user, if any.</p> + +<dt><a name="showmybugslink" +><code class="code">showmybugslink</code></a></dt> + +<dd> +<p>Returns <code class="code">1</code> if the user has set his preference to show the 'My Bugs' link in the page footer, and <code class="code">0</code> otherwise.</p> + +<dt><a name="identity" +><code class="code">identity</code></a></dt> + +<dd> +<p>Returns a string for the identity of the user. This will be of the form <code class="code">name <email></code> if the user has specified a name, and <code class="code">email</code> otherwise.</p> + +<dt><a name="nick" +><code class="code">nick</code></a></dt> + +<dd> +<p>Returns a user "nickname" -- i.e. a shorter, not-necessarily-unique name by which to identify the user. Currently the part of the user's email address before the at sign (@), but that could change, especially if we implement usernames not dependent on email address.</p> + +<dt><a name="authorizer" +><code class="code">authorizer</code></a></dt> + +<dd> +<p>This is the <a href="../Bugzilla/Auth.html" class="podlinkpod" +>Bugzilla::Auth</a> object that the User logged in with. If the user hasn't logged in yet, a new, empty Bugzilla::Auth() object is returned.</p> + +<dt><a name="set_authorizer($authorizer)" +><code class="code">set_authorizer($authorizer)</code></a></dt> + +<dd> +<p>Sets the <a href="../Bugzilla/Auth.html" class="podlinkpod" +>Bugzilla::Auth</a> object to be returned by <code class="code">authorizer()</code>. Should only be called by <code class="code">Bugzilla::Auth::login</code>, for the most part.</p> + +<dt><a name="disabledtext" +><code class="code">disabledtext</code></a></dt> + +<dd> +<p>Returns the disable text of the user, if any.</p> + +<dt><a name="settings" +><code class="code">settings</code></a></dt> + +<dd> +<p>Returns a hash of hashes which holds the user's settings. The first key is the name of the setting, as found in setting.name. The second key is one of: is_enabled - true if the user is allowed to set the preference themselves; false to force the site defaults for themselves or must accept the global site default value default_value - the global site default for this setting value - the value of this setting for this user. Will be the same as the default_value if the user is not logged in, or if is_default is true. is_default - a boolean to indicate whether the user has chosen to make a preference for themself or use the site default.</p> + +<dt><a name="groups" +><code class="code">groups</code></a></dt> + +<dd> +<p>Returns a hashref of group names for groups the user is a member of. The keys are the names of the groups, whilst the values are the respective group ids. (This is so that a set of all groupids for groups the user is in can be obtained by <code class="code">values(%{$user->groups})</code>.)</p> + +<dt><a name="groups_as_string" +><code class="code">groups_as_string</code></a></dt> + +<dd> +<p>Returns a string containing a comma-separated list of numeric group ids. If the user is not a member of any groups, returns "-1". This is most often used within an SQL IN() function.</p> + +<dt><a name="in_group($group_name,_$product_id)" +><code class="code">in_group($group_name, $product_id)</code></a></dt> + +<dd> +<p>Determines whether or not a user is in the given group by name. If $product_id is given, it also checks for local privileges for this product.</p> + +<dt><a name="in_group_id" +><code class="code">in_group_id</code></a></dt> + +<dd> +<p>Determines whether or not a user is in the given group by id.</p> + +<dt><a name="bless_groups" +><code class="code">bless_groups</code></a></dt> + +<dd> +<p>Returns an arrayref of hashes of <code class="code">groups</code> entries, where the keys of each hash are the names of <code class="code">id</code>, <code class="code">name</code> and <code class="code">description</code> columns of the <code class="code">groups</code> table. The arrayref consists of the groups the user can bless, taking into account that having editusers permissions means that you can bless all groups, and that you need to be aware of a group in order to bless a group.</p> + +<dt><a name="get_products_by_permission($group)" +><code class="code">get_products_by_permission($group)</code></a></dt> + +<dd> +<p>Returns a list of product objects for which the user has $group privileges and which he can access. $group must be one of the groups defined in PER_PRODUCT_PRIVILEGES.</p> + +<dt><a name="can_see_user(user)" +><code class="code">can_see_user(user)</code></a></dt> + +<dd> +<p>Returns 1 if the specified user account exists and is visible to the user, 0 otherwise.</p> + +<dt><a name="can_edit_product(prod_id)" +><code class="code">can_edit_product(prod_id)</code></a></dt> + +<dd> +<p>Determines if, given a product id, the user can edit bugs in this product at all.</p> + +<dt><a name="can_see_bug(bug_id)" +><code class="code">can_see_bug(bug_id)</code></a></dt> + +<dd> +<p>Determines if the user can see the specified bug.</p> + +<dt><a name="can_see_product(product_name)" +><code class="code">can_see_product(product_name)</code></a></dt> + +<dd> +<p>Returns 1 if the user can access the specified product, and 0 if the user should not be aware of the existence of the product.</p> + +<dt><a name="derive_regexp_groups" +><code class="code">derive_regexp_groups</code></a></dt> + +<dd> +<p>Bugzilla allows for group inheritance. When data about the user (or any of the groups) changes, the database must be updated. Handling updated groups is taken care of by the constructor. However, when updating the email address, the user may be placed into different groups, based on a new email regexp. This method should be called in such a case to force reresolution of these groups.</p> + +<dt><a name="get_selectable_products" +><code class="code">get_selectable_products</code></a></dt> + +<dd> +<pre class="code"> Description: Returns all products the user is allowed to access. This list + is restricted to some given classification if $classification_id + is given. + + Params: $classification_id - (optional) The ID of the classification + the products belong to. + + Returns: An array of product objects, sorted by the product name.</pre> + +<dt><a name="get_selectable_classifications" +><code class="code">get_selectable_classifications</code></a></dt> + +<dd> +<pre class="code"> Description: Returns all classifications containing at least one product + the user is allowed to view. + + Params: none + + Returns: An array of Bugzilla::Classification objects, sorted by + the classification name.</pre> + +<dt><a name="can_enter_product($product_name,_$warn)" +><code class="code">can_enter_product($product_name, $warn)</code></a></dt> + +<dd> +<pre class="code"> Description: Returns 1 if the user can enter bugs into the specified product. + If the user cannot enter bugs into the product, the behavior of + this method depends on the value of $warn: + - if $warn is false (or not given), a 'false' value is returned; + - if $warn is true, an error is thrown. + + Params: $product_name - a product name. + $warn - optional parameter, indicating whether an error + must be thrown if the user cannot enter bugs + into the specified product. + + Returns: 1 if the user can enter bugs into the product, + 0 if the user cannot enter bugs into the product and if $warn + is false (an error is thrown if $warn is true).</pre> + +<dt><a name="get_enterable_products" +><code class="code">get_enterable_products</code></a></dt> + +<dd> +<pre class="code"> Description: Returns an array of product objects into which the user is + allowed to enter bugs. + + Params: none + + Returns: an array of product objects.</pre> + +<dt><a name="check_can_admin_product($product_name)" +><code class="code">check_can_admin_product($product_name)</code></a></dt> + +<dd> +<pre class="code"> Description: Checks whether the user is allowed to administrate the product. + + Params: $product_name - a product name. + + Returns: On success, a product object. On failure, an error is thrown.</pre> + +<dt><a name="can_request_flag($flag_type)" +><code class="code">can_request_flag($flag_type)</code></a></dt> + +<dd> +<pre class="code"> Description: Checks whether the user can request flags of the given type. + + Params: $flag_type - a Bugzilla::FlagType object. + + Returns: 1 if the user can request flags of the given type, + 0 otherwise.</pre> + +<dt><a name="can_set_flag($flag_type)" +><code class="code">can_set_flag($flag_type)</code></a></dt> + +<dd> +<pre class="code"> Description: Checks whether the user can set flags of the given type. + + Params: $flag_type - a Bugzilla::FlagType object. + + Returns: 1 if the user can set flags of the given type, + 0 otherwise.</pre> + +<dt><a name="get_userlist" +><code class="code">get_userlist</code></a></dt> + +<dd> +<p>Returns a reference to an array of users. The array is populated with hashrefs containing the login, identity and visibility. Users that are not visible to this user will have 'visible' set to zero.</p> + +<dt><a name="flatten_group_membership" +><code class="code">flatten_group_membership</code></a></dt> + +<dd> +<p>Accepts a list of groups and returns a list of all the groups whose members inherit membership in any group on the list. So, we can determine if a user is in any of the groups input to flatten_group_membership by querying the user_group_map for any user with DIRECT or REGEXP membership IN() the list of groups returned.</p> + +<dt><a name="visible_groups_inherited" +><code class="code">visible_groups_inherited</code></a></dt> + +<dd> +<p>Returns a list of all groups whose members should be visible to this user. Since this list is flattened already, there is no need for all users to be have derived groups up-to-date to select the users meeting this criteria.</p> + +<dt><a name="visible_groups_direct" +><code class="code">visible_groups_direct</code></a></dt> + +<dd> +<p>Returns a list of groups that the user is aware of.</p> + +<dt><a name="visible_groups_as_string" +><code class="code">visible_groups_as_string</code></a></dt> + +<dd> +<p>Returns the result of <code class="code">visible_groups_direct</code> as a string (a comma-separated list).</p> + +<dt><a name="product_responsibilities" +><code class="code">product_responsibilities</code></a></dt> + +<dd> +<p>Retrieve user's product responsibilities as a list of component objects. Each object is a component the user has a responsibility for.</p> + +<dt><a name="can_bless" +><code class="code">can_bless</code></a></dt> + +<dd> +<p>When called with no arguments: Returns <code class="code">1</code> if the user can bless at least one group, returns <code class="code">0</code> otherwise.</p> + +<p>When called with one argument: Returns <code class="code">1</code> if the user can bless the group with that id, returns <code class="code">0</code> otherwise.</p> + +<dt><a name="wants_bug_mail" +><code class="code">wants_bug_mail</code></a></dt> + +<dd> +<p>Returns true if the user wants mail for a given bug change.</p> + +<dt><a name="wants_mail" +><code class="code">wants_mail</code></a></dt> + +<dd> +<p>Returns true if the user wants mail for a given set of events. This method is more general than <code class="code">wants_bug_mail</code>, allowing you to check e.g. permissions for flag mail.</p> + +<dt><a name="is_mover" +><code class="code">is_mover</code></a></dt> + +<dd> +<p>Returns true if the user is in the list of users allowed to move bugs to another database. Note that this method doesn't check whether bug moving is enabled.</p> + +<dt><a name="is_insider" +><code class="code">is_insider</code></a></dt> + +<dd> +<p>Returns true if the user can access private comments and attachments, i.e. if the 'insidergroup' parameter is set and the user belongs to this group.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="CLASS_FUNCTIONS" +>CLASS FUNCTIONS</a></h1> + +<p>These are functions that are not called on a User object, but instead are called "statically," just like a normal procedural function.</p> + +<dl> +<dt><a name="create" +><code class="code">create</code></a></dt> + +<dd> +<p>The same as <a href="../Bugzilla/Object.html#create" class="podlinkpod" +>"create" in Bugzilla::Object</a>.</p> + +<p>Params: login_name - <b>Required</b> The login name for the new user. realname - The full name for the new user. cryptpassword - <b>Required</b> The password for the new user. Even though the name says "crypt", you should just specify a plain-text password. If you specify '*', the user will not be able to log in using DB authentication. disabledtext - The disable-text for the new user. If given, the user will be disabled, meaning he cannot log in. Defaults to an empty string. disable_mail - If 1, bug-related mail will not be sent to this user; if 0, mail will be sent depending on the user's email preferences.</p> + +<dt><a name="is_available_username" +><code class="code">is_available_username</code></a></dt> + +<dd> +<p>Returns a boolean indicating whether or not the supplied username is already taken in Bugzilla.</p> + +<p>Params: $username (scalar, string) - The full login name of the username that you are checking. $old_username (scalar, string) - If you are checking an email-change token, insert the "old" username that the user is changing from, here. Then, as long as it's the right user for that token, he can change his username to $username. (That is, this function will return a boolean true value).</p> + +<dt><a name="login_to_id($login,_$throw_error)" +><code class="code">login_to_id($login, $throw_error)</code></a></dt> + +<dd> +<p>Takes a login name of a Bugzilla user and changes that into a numeric ID for that user. This ID can then be passed to Bugzilla::User::new to create a new user.</p> + +<p>If no valid user exists with that login name, then the function returns 0. However, if $throw_error is set, the function will throw a user error instead of returning.</p> + +<p>This function can also be used when you want to just find out the userid of a user, but you don't want the full weight of Bugzilla::User.</p> + +<p>However, consider using a Bugzilla::User object instead of this function if you need more information about the user than just their ID.</p> + +<dt><a name="user_id_to_login($user_id)" +><code class="code">user_id_to_login($user_id)</code></a></dt> + +<dd> +<p>Returns the login name of the user account for the given user ID. If no valid user ID is given or the user has no entry in the profiles table, we return an empty string.</p> + +<dt><a name="validate_password($passwd1,_$passwd2)" +><code class="code">validate_password($passwd1, $passwd2)</code></a></dt> + +<dd> +<p>Returns true if a password is valid (i.e. meets Bugzilla's requirements for length and content), else returns false. Untaints <code class="code">$passwd1</code> if successful.</p> + +<p>If a second password is passed in, this function also verifies that the two passwords match.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SEE_ALSO" +>SEE ALSO</a></h1> + +<p><a href="../Bugzilla.html" class="podlinkpod" +>Bugzilla</a></p> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/User/Setting.html b/docs/html/api/Bugzilla/User/Setting.html new file mode 100644 index 000000000..8c39224fc --- /dev/null +++ b/docs/html/api/Bugzilla/User/Setting.html @@ -0,0 +1,171 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::User::Setting</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::User::Setting</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#CLASS_FUNCTIONS'>CLASS FUNCTIONS</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> + <li class='indexItem indexItem1'><a href='#POD_ERRORS'>POD ERRORS</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::User::Setting - Object for a user preference setting</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<p>Setting.pm creates a setting object, +which is a hash containing the user preference information for a single preference for a single user. +These are usually accessed through the "settings" object of a user, +and not directly.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>use Bugzilla::User::Setting; my $settings;</p> + +<p>$settings->{$setting_name} = new Bugzilla::User::Setting( $setting_name, +$user_id);</p> + +<p>OR</p> + +<p>$settings->{$setting_name} = new Bugzilla::User::Setting( $setting_name, +$user_id, +$is_enabled, +$default_value, +$value, +$is_default);</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="CLASS_FUNCTIONS" +>CLASS FUNCTIONS</a></h1> + +<dl> +<dt><a name="add_setting($name,_\@values,_$default_value)" +><code class="code">add_setting($name, +\@values, +$default_value)</code></a></dt> + +<dd> +<p>Description: Checks for the existence of a setting, +and adds it to the database if it does not yet exist.</p> + +<p>Params: <code class="code">$name</code> - string - the name of the new setting <code class="code">$values</code> - arrayref - contains the new choices for the new Setting. +<code class="code">$default_value</code> - string - the site default</p> + +<p>Returns: a pointer to a hash of settings</p> + +<dt><a name="get_all_settings($user_id)" +><code class="code">get_all_settings($user_id)</code></a></dt> + +<dd> +<p>Description: Provides the user's choices for each setting in the system; if the user has made no choice, +uses the site default instead. +Params: <code class="code">$user_id</code> - integer - the user id. +Returns: a pointer to a hash of settings</p> + +<dt><a name="get_defaults($user_id)" +><code class="code">get_defaults($user_id)</code></a></dt> + +<dd> +<p>Description: When a user is not logged in, +they must use the site defaults for every settings; this subroutine provides them. +Params: <code class="code">$user_id</code> (optional) - integer - the user id. +Note that this optional parameter is mainly for internal use only. +Returns: A pointer to a hash of settings. +If $user_id was passed, +set the user_id value for each setting.</p> + +<dt><a name="set_default($setting_name,_$default_value,_$is_enabled)" +><code class="code">set_default($setting_name, +$default_value, +$is_enabled)</code></a></dt> + +<dd> +<p>Description: Sets the global default for a given setting. +Also sets whether users are allowed to choose their own value for this setting, +or if they must use the global default. +Params: <code class="code">$setting_name</code> - string - the name of the setting <code class="code">$default_value</code> - string - the new default value for this setting <code class="code">$is_enabled</code> - boolean - if false, +all users must use the global default Returns: nothing</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<dl> +<dt><a name="legal_values($setting_name)" +><code class="code">legal_values($setting_name)</code></a></dt> + +<dd> +<p>Description: Returns all legal values for this setting Params: none Returns: A reference to an array containing all legal values</p> + +<dt><a name="validate_value" +><code class="code">validate_value</code></a></dt> + +<dd> +<p>Description: Determines whether a value is valid for the setting by checking against the list of legal values. +Untaints the parameter if the value is indeed valid, +and throws a setting_value_invalid code error if not. +Params: An lvalue containing a candidate for a setting value Returns: nothing</p> + +<dt><a name="reset_to_default" +><code class="code">reset_to_default</code></a></dt> + +<dd> +<p>Description: If a user chooses to use the global default for a given setting, +their saved entry is removed from the database via this subroutine. +Params: none Returns: nothing</p> + +<dt><a name="set($value)" +><code class="code">set($value)</code></a></dt> + +<dd> +<p>Description: If a user chooses to use their own value rather than the global value for a given setting, +OR changes their value for a given setting, +this subroutine is called to insert or update the database as appropriate. +Params: <code class="code">$value</code> - string - the new value for this setting for this user. +Returns: nothing</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="POD_ERRORS" +>POD ERRORS</a></h1> + +<p>Hey! +<b>The above document had some coding errors, +which are explained below:</b></p> + +<dl> +<dt><a name="Around_line_390:" +>Around line 390:</a></dt> + +<dd> +<p>You forgot a '=back' before '=head1'</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/User/Setting/Skin.html b/docs/html/api/Bugzilla/User/Setting/Skin.html new file mode 100644 index 000000000..8b76859b2 --- /dev/null +++ b/docs/html/api/Bugzilla/User/Setting/Skin.html @@ -0,0 +1,54 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::User::Setting::Skin</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::User::Setting::Skin</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::User::Setting::Skin - Object for a user preference setting for skins</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Skin.pm extends Bugzilla::User::Setting and implements a class specialized for skins settings.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<dl> +<dt><a name="legal_values()" +><code class="code">legal_values()</code></a></dt> + +<dd> +<p>Description: Returns all legal skins Params: none Returns: A reference to an array containing the names of all legal skins</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Util.html b/docs/html/api/Bugzilla/Util.html new file mode 100644 index 000000000..3a0ad7563 --- /dev/null +++ b/docs/html/api/Bugzilla/Util.html @@ -0,0 +1,421 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Util</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Util</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#FUNCTIONS'>FUNCTIONS</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Tainting'>Tainting</a> + <li class='indexItem indexItem2'><a href='#Quoting'>Quoting</a> + <li class='indexItem indexItem2'><a href='#Environment_and_Location'>Environment and Location</a> + <li class='indexItem indexItem2'><a href='#Searching'>Searching</a> + <li class='indexItem indexItem2'><a href='#Data_Manipulation'>Data Manipulation</a> + <li class='indexItem indexItem2'><a href='#String_Manipulation'>String Manipulation</a> + <li class='indexItem indexItem2'><a href='#Formatting_Time'>Formatting Time</a> + <li class='indexItem indexItem2'><a href='#Files'>Files</a> + <li class='indexItem indexItem2'><a href='#Cryptography'>Cryptography</a> + <li class='indexItem indexItem2'><a href='#Validation'>Validation</a> + </ul> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Util - Generic utility functions for bugzilla</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Util; + + # Functions for dealing with variable tainting + $rv = is_tainted($var); + trick_taint($var); + detaint_natural($var); + detaint_signed($var); + + # Functions for quoting + html_quote($var); + url_quote($var); + value_quote($var); + xml_quote($var); + + # Functions for decoding + $rv = url_decode($var); + + # Functions that tell you about your environment + my $is_cgi = i_am_cgi(); + my $net_addr = get_netaddr($ip_addr); + my $urlbase = correct_urlbase(); + + # Functions for searching + $loc = lsearch(\@arr, $val); + + # Data manipulation + ($removed, $added) = diff_arrays(\@old, \@new); + + # Functions for manipulating strings + $val = trim(" abc "); + ($removed, $added) = diff_strings($old, $new); + $wrapped = wrap_comment($comment); + $msg = perform_substs($str, $substs); + + # Functions for formatting time + format_time($time); + + # Functions for dealing with files + $time = file_mod_time($filename); + + # Cryptographic Functions + $crypted_password = bz_crypt($password); + $new_password = generate_random_password($password_length); + + # Validation Functions + validate_email_syntax($email); + validate_date($date);</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This package contains various utility functions which do not belong anywhere else.</p> + +<p><b>It is not intended as a general dumping group for something which people feel might be useful somewhere, someday</b>. Do not add methods to this package unless it is intended to be used for a significant number of files, and it does not belong anywhere else.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="FUNCTIONS" +>FUNCTIONS</a></h1> + +<p>This package provides several types of routines:</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Tainting" +>Tainting</a></h2> + +<p>Several functions are available to deal with tainted variables. <b>Use these with care</b> to avoid security holes.</p> + +<dl> +<dt><a name="is_tainted" +><code class="code">is_tainted</code></a></dt> + +<dd> +<p>Determines whether a particular variable is tainted</p> + +<dt><a name="trick_taint($val)" +><code class="code">trick_taint($val)</code></a></dt> + +<dd> +<p>Tricks perl into untainting a particular variable.</p> + +<p>Use trick_taint() when you know that there is no way that the data in a scalar can be tainted, but taint mode still bails on it.</p> + +<p><b>WARNING!! Using this routine on data that really could be tainted defeats the purpose of taint mode. It should only be used on variables that have been sanity checked in some way and have been determined to be OK.</b></p> + +<dt><a name="detaint_natural($num)" +><code class="code">detaint_natural($num)</code></a></dt> + +<dd> +<p>This routine detaints a natural number. It returns a true value if the value passed in was a valid natural number, else it returns false. You <b>MUST</b> check the result of this routine to avoid security holes.</p> + +<dt><a name="detaint_signed($num)" +><code class="code">detaint_signed($num)</code></a></dt> + +<dd> +<p>This routine detaints a signed integer. It returns a true value if the value passed in was a valid signed integer, else it returns false. You <b>MUST</b> check the result of this routine to avoid security holes.</p> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Quoting" +>Quoting</a></h2> + +<p>Some values may need to be quoted from perl. However, this should in general be done in the template where possible.</p> + +<dl> +<dt><a name="html_quote($val)" +><code class="code">html_quote($val)</code></a></dt> + +<dd> +<p>Returns a value quoted for use in HTML, with &, <, >, and " being replaced with their appropriate HTML entities.</p> + +<dt><a name="html_light_quote($val)" +><code class="code">html_light_quote($val)</code></a></dt> + +<dd> +<p>Returns a string where only explicitly allowed HTML elements and attributes are kept. All HTML elements and attributes not being in the whitelist are either escaped (if HTML::Scrubber is not installed) or removed.</p> + +<dt><a name="url_quote($val)" +><code class="code">url_quote($val)</code></a></dt> + +<dd> +<p>Quotes characters so that they may be included as part of a url.</p> + +<dt><a name="css_class_quote($val)" +><code class="code">css_class_quote($val)</code></a></dt> + +<dd> +<p>Quotes characters so that they may be used as CSS class names. Spaces are replaced by underscores.</p> + +<dt><a name="value_quote($val)" +><code class="code">value_quote($val)</code></a></dt> + +<dd> +<p>As well as escaping html like <code class="code">html_quote</code>, this routine converts newlines into &#013;, suitable for use in html attributes.</p> + +<dt><a name="xml_quote($val)" +><code class="code">xml_quote($val)</code></a></dt> + +<dd> +<p>This is similar to <code class="code">html_quote</code>, except that ' is escaped to &apos;. This is kept separate from html_quote partly for compatibility with previous code (for &apos;) and partly for future handling of non-ASCII characters.</p> + +<dt><a name="url_decode($val)" +><code class="code">url_decode($val)</code></a></dt> + +<dd> +<p>Converts the %xx encoding from the given URL back to its original form.</p> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Environment_and_Location" +>Environment and Location</a></h2> + +<p>Functions returning information about your environment or location.</p> + +<dl> +<dt><a name="i_am_cgi()" +><code class="code">i_am_cgi()</code></a></dt> + +<dd> +<p>Tells you whether or not you are being run as a CGI script in a web server. For example, it would return false if the caller is running in a command-line script.</p> + +<dt><a name="get_netaddr($ipaddr)" +><code class="code">get_netaddr($ipaddr)</code></a></dt> + +<dd> +<p>Given an IP address, this returns the associated network address, using <code class="code">Bugzilla-</code>params->{'loginnetmask'}> as the netmask. This can be used to obtain data in order to restrict weak authentication methods (such as cookies) to only some addresses.</p> + +<dt><a name="correct_urlbase()" +><code class="code">correct_urlbase()</code></a></dt> + +<dd> +<p>Returns either the <code class="code">sslbase</code> or <code class="code">urlbase</code> parameter, depending on the current setting for the <code class="code">ssl</code> parameter.</p> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Searching" +>Searching</a></h2> + +<p>Functions for searching within a set of values.</p> + +<dl> +<dt><a name="lsearch($list,_$item)" +><code class="code">lsearch($list, $item)</code></a></dt> + +<dd> +<p>Returns the position of <code class="code">$item</code> in <code class="code">$list</code>. <code class="code">$list</code> must be a list reference.</p> + +<p>If the item is not in the list, returns -1.</p> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Data_Manipulation" +>Data Manipulation</a></h2> + +<dl> +<dt><a name="diff_arrays(\@old,_\@new)" +><code class="code">diff_arrays(\@old, \@new)</code></a></dt> + +<dd> +<pre class="code"> Description: Takes two arrayrefs, and will tell you what it takes to + get from @old to @new. + Params: @old = array that you are changing from + @new = array that you are changing to + Returns: A list of two arrayrefs. The first is a reference to an + array containing items that were removed from @old. The + second is a reference to an array containing items + that were added to @old. If both returned arrays are + empty, @old and @new contain the same values.</pre> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="String_Manipulation" +>String Manipulation</a></h2> + +<dl> +<dt><a name="trim($str)" +><code class="code">trim($str)</code></a></dt> + +<dd> +<p>Removes any leading or trailing whitespace from a string. This routine does not modify the existing string.</p> + +<dt><a name="diff_strings($oldstr,_$newstr)" +><code class="code">diff_strings($oldstr, $newstr)</code></a></dt> + +<dd> +<p>Takes two strings containing a list of comma- or space-separated items and returns what items were removed from or added to the new one, compared to the old one. Returns a list, where the first entry is a scalar containing removed items, and the second entry is a scalar containing added items.</p> + +<dt><a name="wrap_comment($comment)" +><code class="code">wrap_comment($comment)</code></a></dt> + +<dd> +<p>Takes a bug comment, and wraps it to the appropriate length. The length is currently specified in <code class="code">Bugzilla::Constants::COMMENT_COLS</code>. Lines beginning with ">" are assumed to be quotes, and they will not be wrapped.</p> + +<p>The intended use of this function is to wrap comments that are about to be displayed or emailed. Generally, wrapped text should not be stored in the database.</p> + +<dt><a name="find_wrap_point($string,_$maxpos)" +><code class="code">find_wrap_point($string, $maxpos)</code></a></dt> + +<dd> +<p>Search for a comma, a whitespace or a hyphen to split $string, within the first $maxpos characters. If none of them is found, just split $string at $maxpos. The search starts at $maxpos and goes back to the beginning of the string.</p> + +<dt><a name="perform_substs($str,_$substs)" +><code class="code">perform_substs($str, $substs)</code></a></dt> + +<dd> +<p>Performs substitutions for sending out email with variables in it, or for inserting a parameter into some other string.</p> + +<p>Takes a string and a reference to a hash containing substitution variables and their values.</p> + +<p>If the hash is not specified, or if we need to substitute something that's not in the hash, then we will use parameters to do the substitution instead.</p> + +<p>Substitutions are always enclosed with '%' symbols. So they look like: %some_variable_name%. If "some_variable_name" is a key in the hash, then its value will be placed into the string. If it's not a key in the hash, then the value of the parameter called "some_variable_name" will be placed into the string.</p> + +<dt><a name="is_7bit_clean($str)" +><code class="code">is_7bit_clean($str)</code></a></dt> + +<dd> +<p>Returns true is the string contains only 7-bit characters (ASCII 32 through 126, ASCII 10 (LineFeed) and ASCII 13 (Carrage Return).</p> + +<dt><a +><code class="code">clean_text($str)</code> Returns the parameter "cleaned" by exchanging non-printable characters with spaces. Specifically characters (ASCII 0 through 31) and (ASCII 127) will become ASCII 32 (Space). +<dt><a name="get_text" +><code class="code">get_text</code></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>This is a method of getting localized strings within Bugzilla code. Use this when you don't want to display a whole template, you just want a particular string.</p> + +<p>It uses the <em class="code">global/message.txt.tmpl</em> template to return a string.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="$message_-_The_identifier_for_the_message." +><code class="code">$message</code> - The identifier for the message. +<dt><a name="$vars_-_A_hashref._Any_variables_you_want_to_pass_to_the_template." +><code class="code">$vars</code> - A hashref. Any variables you want to pass to the template.</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A string.</p> +</dd> +</dl> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Formatting_Time" +>Formatting Time</a></h2> + +<dl> +<dt><a name="format_time($time)" +><code class="code">format_time($time)</code></a></dt> + +<dd> +<p>Takes a time, converts it to the desired format and appends the timezone as defined in editparams.cgi, if desired. This routine will be expanded in the future to adjust for user preferences regarding what timezone to display times in.</p> + +<p>This routine is mainly called from templates to filter dates, see "FILTER time" in Templates.pm. In this case, $format is undefined and the routine has to "guess" the date format that was passed to $dbh->sql_date_format().</p> + +<dt><a name="format_time_decimal($time)" +><code class="code">format_time_decimal($time)</code></a></dt> + +<dd> +<p>Returns a number with 2 digit precision, unless the last digit is a 0. Then it returns only 1 digit precision.</p> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Files" +>Files</a></h2> + +<dl> +<dt><a name="file_mod_time($filename)" +><code class="code">file_mod_time($filename)</code></a></dt> + +<dd> +<p>Takes a filename and returns the modification time. It returns it in the format of the "mtime" parameter of the perl "stat" function.</p> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Cryptography" +>Cryptography</a></h2> + +<dl> +<dt><a name="bz_crypt($password)" +><code class="code">bz_crypt($password)</code></a></dt> + +<dd> +<p>Takes a string and returns a <code class="code">crypt</code>ed value for it, using a random salt.</p> + +<p>Please always use this function instead of the built-in perl "crypt" when initially encrypting a password.</p> + +<dt><a name="generate_random_password($password_length)" +><code class="code">generate_random_password($password_length)</code></a></dt> + +<dd> +<p>Returns an alphanumeric string with the specified length (10 characters by default). Use this function to generate passwords and tokens.</p> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Validation" +>Validation</a></h2> + +<dl> +<dt><a name="validate_email_syntax($email)" +><code class="code">validate_email_syntax($email)</code></a></dt> + +<dd> +<p>Do a syntax checking for a legal email address and returns 1 if the check is successful, else returns 0. Untaints <code class="code">$email</code> if successful.</p> + +<dt><a name="validate_date($date)" +><code class="code">validate_date($date)</code></a></dt> + +<dd> +<p>Make sure the date has the correct format and returns 1 if the check is successful, else returns 0.</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/Version.html b/docs/html/api/Bugzilla/Version.html new file mode 100644 index 000000000..c59a764cf --- /dev/null +++ b/docs/html/api/Bugzilla/Version.html @@ -0,0 +1,139 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Version</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Version</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> + <li class='indexItem indexItem1'><a href='#SUBROUTINES'>SUBROUTINES</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Version - Bugzilla product version class.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> use Bugzilla::Version; + + my $version = new Bugzilla::Version(1, 'version_value'); + + my $product_id = $version->product_id; + my $value = $version->value; + + $version->remove_from_db; + + my $updated = $version->update($version_name, $product); + + my $version = $hash_ref->{'version_value'}; + + my $version = Bugzilla::Version::check_version($product_obj, + 'acme_version'); + + my $version = Bugzilla::Version::create($version_name, $product);</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Version.pm represents a Product Version object.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<dl> +<dt><a name="new($product_id,_$value)" +><code class="code">new($product_id, $value)</code></a></dt> + +<dd> +<pre class="code"> Description: The constructor is used to load an existing version + by passing a product id and a version value. + + Params: $product_id - Integer with a product id. + $value - String with a version value. + + Returns: A Bugzilla::Version object.</pre> + +<dt><a name="bug_count()" +><code class="code">bug_count()</code></a></dt> + +<dd> +<pre class="code"> Description: Returns the total of bugs that belong to the version. + + Params: none. + + Returns: Integer with the number of bugs.</pre> + +<dt><a name="remove_from_db()" +><code class="code">remove_from_db()</code></a></dt> + +<dd> +<pre class="code"> Description: Removes the version from the database. + + Params: none. + + Retruns: none.</pre> + +<dt><a name="update($name,_$product)" +><code class="code">update($name, $product)</code></a></dt> + +<dd> +<pre class="code"> Description: Update the value of the version. + + Params: $name - String with the new version value. + $product - Bugzilla::Product object the version belongs to. + + Returns: An integer - 1 if the version has been updated, else 0.</pre> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SUBROUTINES" +>SUBROUTINES</a></h1> + +<dl> +<dt><a name="check_version($product,_$version_name)" +><code class="code">check_version($product, $version_name)</code></a></dt> + +<dd> +<pre class="code"> Description: Checks if the version name exists for the product name. + + Params: $product - A Bugzilla::Product object. + $version_name - String with a version name. + + Returns: Bugzilla::Version object.</pre> + +<dt><a name="create($version_name,_$product)" +><code class="code">create($version_name, $product)</code></a></dt> + +<dd> +<pre class="code"> Description: Create a new version for the given product. + + Params: $version_name - String with a version value. + $product - A Bugzilla::Product object. + + Returns: A Bugzilla::Version object.</pre> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/WebService.html b/docs/html/api/Bugzilla/WebService.html new file mode 100644 index 000000000..058bfdbba --- /dev/null +++ b/docs/html/api/Bugzilla/WebService.html @@ -0,0 +1,109 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::WebService</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::WebService</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#STABLE%2C_EXPERIMENTAL%2C_and_UNSTABLE'>STABLE, EXPERIMENTAL, and UNSTABLE</a> + <li class='indexItem indexItem1'><a href='#ERRORS'>ERRORS</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Transient_vs._Fatal_Errors'>Transient vs. Fatal Errors</a> + <li class='indexItem indexItem2'><a href='#Unknown_Errors'>Unknown Errors</a> + </ul> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::WebService - The Web Service interface to Bugzilla</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This is the standard API for external programs that want to interact with Bugzilla. +It provides various methods in various modules.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="STABLE,_EXPERIMENTAL,_and_UNSTABLE" +>STABLE, +EXPERIMENTAL, +and UNSTABLE</a></h1> + +<p>Methods are marked <b>STABLE</b> if you can expect their parameters and return values not to change between versions of Bugzilla. +You are best off always using methods marked <b>STABLE</b>. +We may add parameters and additional items to the return values, +but your old code will always continue to work with any new changes we make. +If we ever break a <b>STABLE</b> interface, +we'll post a big notice in the Release Notes, +and it will only happen during a major new release.</p> + +<p>Methods (or parts of methods) are marked <b>EXPERIMENTAL</b> if we <i>believe</i> they will be stable, +but there's a slight chance that small parts will change in the future.</p> + +<p>Certain parts of a method's description may be marked as <b>UNSTABLE</b>, +in which case those parts are not guaranteed to stay the same between Bugzilla versions.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="ERRORS" +>ERRORS</a></h1> + +<p>If a particular webservice call fails, +it will throw a standard XML-RPC error. +There will be a numeric error code, +and then the description field will contain descriptive text of the error. +Each error that Bugzilla can throw has a specific code that will not change between versions of Bugzilla.</p> + +<p>The various errors that functions can throw are specified by the documentation of those functions.</p> + +<p>If your code needs to know what error Bugzilla threw, +use the numeric code. +Don't try to parse the description, +because that may change from version to version of Bugzilla.</p> + +<p>Note that if you display the error to the user in an HTML program, +make sure that you properly escape the error, +as it will not be HTML-escaped.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Transient_vs._Fatal_Errors" +>Transient vs. +Fatal Errors</a></h2> + +<p>If the error code is a number greater than 0, +the error is considered "transient," which means that it was an error made by the user, +not some problem with Bugzilla itself.</p> + +<p>If the error code is a number less than 0, +the error is "fatal," which means that it's some error in Bugzilla itself that probably requires administrative attention.</p> + +<p>Negative numbers and positive numbers don't overlap. +That is, +if there's an error 302, +there won't be an error -302.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Unknown_Errors" +>Unknown Errors</a></h2> + +<p>Sometimes a function will throw an error that doesn't have a specific error code. +In this case, +the code will be <code class="code">-32000</code> if it's a "fatal" error, +and <code class="code">32000</code> if it's a "transient" error.</p> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/WebService/Bug.html b/docs/html/api/Bugzilla/WebService/Bug.html new file mode 100644 index 000000000..c28cad7f9 --- /dev/null +++ b/docs/html/api/Bugzilla/WebService/Bug.html @@ -0,0 +1,383 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Webservice::Bug</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Webservice::Bug</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Utility_Functions'>Utility Functions</a> + <li class='indexItem indexItem2'><a href='#Bug_Creation_and_Modification'>Bug Creation and Modification</a> + </ul> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Webservice::Bug - The API for creating, +changing, +and getting the details of bugs.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This part of the Bugzilla API allows you to file a new bug in Bugzilla, +or get information about bugs that have already been filed.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<p>See <a href="../../Bugzilla/WebService.html" class="podlinkpod" +>Bugzilla::WebService</a> for a description of <b>STABLE</b>, +<b>UNSTABLE</b>, +and <b>EXPERIMENTAL</b>.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Utility_Functions" +>Utility Functions</a></h2> + +<dl> +<dt><a name="legal_values_EXPERIMENTAL" +><code class="code">legal_values</code> <b>EXPERIMENTAL</b></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Tells you what values are allowed for a particular field.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a +><code class="code">field</code> - The name of the field you want information about. +This should be the same as the name you would use in <a href="#create" class="podlinkpod" +>"create"</a>, +below. +<dt><a +><code class="code">product_id</code> - If you're picking a product-specific field, +you have to specify the id of the product you want the values for.</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p><code class="code">values</code> - An array of strings: the legal values for this field. +The values will be sorted as they normally would be in Bugzilla.</p> + +<dt><a name="Errors" +><b>Errors</b></a></dt> + +<dd> +<dl> +<dt><a name="106_(Invalid_Product)" +>106 (Invalid Product)</a></dt> + +<dd> +<p>You were required to specify a product, +and either you didn't, +or you specified an invalid product (or a product that you can't access).</p> + +<dt><a name="108_(Invalid_Field_Name)" +>108 (Invalid Field Name)</a></dt> + +<dd> +<p>You specified a field that doesn't exist or isn't a drop-down field.</p> +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Bug_Creation_and_Modification" +>Bug Creation and Modification</a></h2> + +<dl> +<dt><a name="get_bugs_EXPERIMENTAL" +><code class="code">get_bugs</code> <b>EXPERIMENTAL</b></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Gets information about particular bugs in the database.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="ids" +><code class="code">ids</code></a></dt> + +<dd> +<p>An array of numbers and strings.</p> + +<p>If an element in the array is entirely numeric, +it represents a bug_id from the Bugzilla database to fetch. +If it contains any non-numeric characters, +it is considered to be a bug alias instead, +and the bug with that alias will be loaded.</p> + +<p>Note that it's possible for aliases to be disabled in Bugzilla, +in which case you will be told that you have specified an invalid bug_id if you try to specify an alias. +(It will be error 100.)</p> +</dd> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A hash containing a single element, +<code class="code">bugs</code>. +This is an array of hashes. +Each hash contains the following items:</p> + +<dl> +<dt><a name="id" +>id</a></dt> + +<dd> +<p><code class="code">int</code> The numeric bug_id of this bug.</p> + +<dt><a name="alias" +>alias</a></dt> + +<dd> +<p><code class="code">string</code> The alias of this bug. +If there is no alias or aliases are disabled in this Bugzilla, +this will be an empty string.</p> + +<dt><a name="summary" +>summary</a></dt> + +<dd> +<p><code class="code">string</code> The summary of this bug.</p> + +<dt><a name="creation_time" +>creation_time</a></dt> + +<dd> +<p><code class="code">dateTime</code> When the bug was created.</p> + +<dt><a name="last_change_time" +>last_change_time</a></dt> + +<dd> +<p><code class="code">dateTime</code> When the bug was last changed.</p> + +<dt><a name="internals_UNSTABLE" +>internals <b>UNSTABLE</b></a></dt> + +<dd> +<p>A hash. +The internals of a <a href="../../Bugzilla/Bug.html" class="podlinkpod" +>Bugzilla::Bug</a> object. +This is extremely unstable, +and you should only rely on this if you absolutely have to. +The structure of the hash may even change between point releases of Bugzilla.</p> +</dd> +</dl> + +<dt><a name="Errors" +><b>Errors</b></a></dt> + +<dd> +<dl> +<dt><a name="100_(Invalid_Bug_Alias)" +>100 (Invalid Bug Alias)</a></dt> + +<dd> +<p>If you specified an alias and either: (a) the Bugzilla you're querying doesn't support aliases or (b) there is no bug with that alias.</p> + +<dt><a name="101_(Invalid_Bug_ID)" +>101 (Invalid Bug ID)</a></dt> + +<dd> +<p>The bug_id you specified doesn't exist in the database.</p> + +<dt><a name="102_(Access_Denied)" +>102 (Access Denied)</a></dt> + +<dd> +<p>You do not have access to the bug_id you specified.</p> +</dd> +</dl> +</dd> +</dl> + +<dt><a name="create_EXPERIMENTAL" +><code class="code">create</code> <b>EXPERIMENTAL</b></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>This allows you to create a new bug in Bugzilla. +If you specify any invalid fields, +they will be ignored. +If you specify any fields you are not allowed to set, +they will just be set to their defaults or ignored.</p> + +<p>You cannot currently set all the items here that you can set on enter_bug.cgi.</p> + +<p>The WebService interface may allow you to set things other than those listed here, +but realize that anything undocumented is <b>UNSTABLE</b> and will very likely change in the future.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<p>Some params must be set, +or an error will be thrown. +These params are marked <b>Required</b>.</p> + +<p>Some parameters can have defaults set in Bugzilla, +by the administrator. +If these parameters have defaults set, +you can omit them. +These parameters are marked <b>Defaulted</b>.</p> + +<p>Clients that want to be able to interact uniformly with multiple Bugzillas should always set both the params marked <b>Required</b> and those marked <b>Defaulted</b>, +because some Bugzillas may not have defaults set for <b>Defaulted</b> parameters, +and then this method will throw an error if you don't specify them.</p> + +<p>The descriptions of the parameters below are what they mean when Bugzilla is being used to track software bugs. +They may have other meanings in some installations.</p> + +<dl> +<dt><a name="product_(string)_Required_-_The_name_of_the_product_the_bug_is_being_filed_against." +><code class="code">product</code> (string) <b>Required</b> - The name of the product the bug is being filed against. +<dt><a name="component_(string)_Required_-_The_name_of_a_component_in_the_product_above." +><code class="code">component</code> (string) <b>Required</b> - The name of a component in the product above. +<dt><a name="summary_(string)_Required_-_A_brief_description_of_the_bug_being_filed." +><code class="code">summary</code> (string) <b>Required</b> - A brief description of the bug being filed. +<dt><a name="version_(string)_Required_-_A_version_of_the_product_above;_the_version_the_bug_was_found_in." +><code class="code">version</code> (string) <b>Required</b> - A version of the product above; the version the bug was found in. +<dt><a +><code class="code">description</code> (string) <b>Defaulted</b> - The initial description for this bug. +Some Bugzilla installations require this to not be blank. +<dt><a name="op_sys_(string)_Defaulted_-_The_operating_system_the_bug_was_discovered_on." +><code class="code">op_sys</code> (string) <b>Defaulted</b> - The operating system the bug was discovered on. +<dt><a name="platform_(string)_Defaulted_-_What_type_of_hardware_the_bug_was_experienced_on." +><code class="code">platform</code> (string) <b>Defaulted</b> - What type of hardware the bug was experienced on. +<dt><a +><code class="code">priority</code> (string) <b>Defaulted</b> - What order the bug will be fixed in by the developer, +compared to the developer's other bugs. +<dt><a name="severity_(string)_Defaulted_-_How_severe_the_bug_is." +><code class="code">severity</code> (string) <b>Defaulted</b> - How severe the bug is. +<dt><a +><code class="code">alias</code> (string) - A brief alias for the bug that can be used instead of a bug number when accessing this bug. +Must be unique in all of this Bugzilla. +<dt><a name="assigned_to_(username)_-_A_user_to_assign_this_bug_to,_if_you_don't_want_it_to_be_assigned_to_the_component_owner." +><code class="code">assigned_to</code> (username) - A user to assign this bug to, +if you don't want it to be assigned to the component owner. +<dt><a name="cc_(array)_-_An_array_of_usernames_to_CC_on_this_bug." +><code class="code">cc</code> (array) - An array of usernames to CC on this bug. +<dt><a +><code class="code">qa_contact</code> (username) - If this installation has QA Contacts enabled, +you can set the QA Contact here if you don't want to use the component's default QA Contact. +<dt><a +><code class="code">status</code> (string) - The status that this bug should start out as. +Note that only certain statuses can be set on bug creation. +<dt><a name="target_milestone_(string)_-_A_valid_target_milestone_for_this_product." +><code class="code">target_milestone</code> (string) - A valid target milestone for this product.</a></dt> +</dl> + +<p>In addition to the above parameters, +if your installation has any custom fields, +you can set them just by passing in the name of the field and its value as a string.</p> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A hash with one element, +<code class="code">id</code>. +This is the id of the newly-filed bug.</p> + +<dt><a name="Errors" +><b>Errors</b></a></dt> + +<dd> +<dl> +<dt><a name="103_(Invalid_Alias)" +>103 (Invalid Alias)</a></dt> + +<dd> +<p>The alias you specified is invalid for some reason. +See the error message for more details.</p> + +<dt><a name="104_(Invalid_Field)" +>104 (Invalid Field)</a></dt> + +<dd> +<p>One of the drop-down fields has an invalid value. +The error message will have more detail.</p> + +<dt><a name="105_(Invalid_Component)" +>105 (Invalid Component)</a></dt> + +<dd> +<p>Either you didn't specify a component, +or the component you specified was invalid.</p> + +<dt><a name="106_(Invalid_Product)" +>106 (Invalid Product)</a></dt> + +<dd> +<p>Either you didn't specify a product, +this product doesn't exist, +or you don't have permission to enter bugs in this product.</p> + +<dt><a name="107_(Invalid_Summary)" +>107 (Invalid Summary)</a></dt> + +<dd> +<p>You didn't specify a summary for the bug.</p> + +<dt><a name="504_(Invalid_User)" +>504 (Invalid User)</a></dt> + +<dd> +<p>Either the QA Contact, +Assignee, +or CC lists have some invalid user in them. +The error message will have more details.</p> +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/WebService/Bugzilla.html b/docs/html/api/Bugzilla/WebService/Bugzilla.html new file mode 100644 index 000000000..e4d88f3a1 --- /dev/null +++ b/docs/html/api/Bugzilla/WebService/Bugzilla.html @@ -0,0 +1,97 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::WebService::Bugzilla</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::WebService::Bugzilla</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::WebService::Bugzilla - Global functions for the webservice interface.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This provides functions that tell you about Bugzilla in general.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<p>See <a href="../../Bugzilla/WebService.html" class="podlinkpod" +>Bugzilla::WebService</a> for a description of what <b>STABLE</b>, +<b>UNSTABLE</b>, +and <b>EXPERIMENTAL</b> mean.</p> + +<dl> +<dt><a name="version_EXPERIMENTAL" +><code class="code">version</code> <b>EXPERIMENTAL</b></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Returns the current version of Bugzilla.</p> + +<dt><a name="Params_(none)" +><b>Params</b> (none) +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A hash with a single item, +<code class="code">version</code>, +that is the version as a string.</p> + +<dt><a name="Errors_(none)" +><b>Errors</b> (none)</a></dt> +</dl> + +<dt><a name="timezone_EXPERIMENTAL" +><code class="code">timezone</code> <b>EXPERIMENTAL</b></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Returns the timezone of the server Bugzilla is running on. +This is important because all dates/times that the webservice interface returns will be in this timezone.</p> + +<dt><a name="Params_(none)" +><b>Params</b> (none) +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A hash with a single item, +<code class="code">timezone</code>, +that is the timezone as a string in (+/-)XXXX (RFC 2822) format.</p> +</dd> +</dl> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/WebService/Product.html b/docs/html/api/Bugzilla/WebService/Product.html new file mode 100644 index 000000000..5219a031f --- /dev/null +++ b/docs/html/api/Bugzilla/WebService/Product.html @@ -0,0 +1,178 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Webservice::Product</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Webservice::Product</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#List_Products'>List Products</a> + </ul> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Webservice::Product - The Product API</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This part of the Bugzilla API allows you to list the available Products and get information about them.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<p>See <a href="../../Bugzilla/WebService.html" class="podlinkpod" +>Bugzilla::WebService</a> for a description of what <b>STABLE</b>, +<b>UNSTABLE</b>, +and <b>EXPERIMENTAL</b> mean, +and for more information about error codes.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="List_Products" +>List Products</a></h2> + +<dl> +<dt><a name="get_selectable_products_UNSTABLE" +><code class="code">get_selectable_products</code> <b>UNSTABLE</b></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Returns a list of the ids of the products the user can search on.</p> + +<dt><a name="Params_(none)" +><b>Params</b> (none) +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A hash containing one item, +<code class="code">ids</code>, +that contains an array of product ids.</p> + +<dt><a name="Errors_(none)" +><b>Errors</b> (none)</a></dt> +</dl> + +<dt><a name="get_enterable_products_UNSTABLE" +><code class="code">get_enterable_products</code> <b>UNSTABLE</b></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Returns a list of the ids of the products the user can enter bugs against.</p> + +<dt><a name="Params_(none)" +><b>Params</b> (none) +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A hash containing one item, +<code class="code">ids</code>, +that contains an array of product ids.</p> + +<dt><a name="Errors_(none)" +><b>Errors</b> (none)</a></dt> +</dl> + +<dt><a name="get_accessible_products_UNSTABLE" +><code class="code">get_accessible_products</code> <b>UNSTABLE</b></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Returns a list of the ids of the products the user can search or enter bugs against.</p> + +<dt><a name="Params_(none)" +><b>Params</b> (none) +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A hash containing one item, +<code class="code">ids</code>, +that contains an array of product ids.</p> + +<dt><a name="Errors_(none)" +><b>Errors</b> (none)</a></dt> +</dl> + +<dt><a name="get_products_UNSTABLE" +><code class="code">get_products</code> <b>UNSTABLE</b></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Returns a list of information about the products passed to it.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<p>A hash containing one item, +<code class="code">ids</code>, +that is an array of product ids.</p> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A hash containing one item, +<code class="code">products</code>, +that is an array of hashes. +Each hash describes a product, +and has the following items: <code class="code">id</code>, +<code class="code">name</code>, +<code class="code">description</code>, +and <code class="code">internals</code>. +The <code class="code">id</code> item is the id of the product. +The <code class="code">name</code> item is the name of the product. +The <code class="code">description</code> is the description of the product. +Finally, +the <code class="code">internals</code> is an internal representation of the product.</p> + +<p>Note, +that if the user tries to access a product that is not in the list of accessible products for the user, +or a product that does not exist, +that is silently ignored, +and no information about that product is returned.</p> + +<dt><a name="Errors_(none)" +><b>Errors</b> (none)</a></dt> +</dl> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/Bugzilla/WebService/User.html b/docs/html/api/Bugzilla/WebService/User.html new file mode 100644 index 000000000..f14ef6d85 --- /dev/null +++ b/docs/html/api/Bugzilla/WebService/User.html @@ -0,0 +1,275 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +Bugzilla::Webservice::User</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>Bugzilla::Webservice::User</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#METHODS'>METHODS</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Logging_In_and_Out'>Logging In and Out</a> + <li class='indexItem indexItem2'><a href='#Account_Creation'>Account Creation</a> + </ul> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>Bugzilla::Webservice::User - The User Account and Login API</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This part of the Bugzilla API allows you to create User Accounts and log in/out using an existing account.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="METHODS" +>METHODS</a></h1> + +<p>See <a href="../../Bugzilla/WebService.html" class="podlinkpod" +>Bugzilla::WebService</a> for a description of what <b>STABLE</b>, +<b>UNSTABLE</b>, +and <b>EXPERIMENTAL</b> mean, +and for more information about error codes.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Logging_In_and_Out" +>Logging In and Out</a></h2> + +<dl> +<dt><a name="login_EXPERIMENTAL" +><code class="code">login</code> <b>EXPERIMENTAL</b></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Logging in, +with a username and password, +is required for many Bugzilla installations, +in order to search for bugs, +post new bugs, +etc. +This method logs in an user.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="login_(string)_-_The_user's_login_name." +><code class="code">login</code> (string) - The user's login name. +<dt><a name="password_(string)_-_The_user's_password." +><code class="code">password</code> (string) - The user's password. +<dt><a +><code class="code">remember</code> (bool) <b>Optional</b> - if the cookies returned by the call to login should expire with the session or not. +In order for this option to have effect the Bugzilla server must be configured to allow the user to set this option - the Bugzilla parameter <i>rememberlogin</i> must be set to "defaulton" or "defaultoff". +Addionally, +the client application must implement management of cookies across sessions.</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>On success, +a hash containing one item, +<code class="code">id</code>, +the numeric id of the user that was logged in. +A set of http cookies is also sent with the response. +These cookies must be sent along with any future requests to the webservice, +for the duration of the session.</p> + +<dt><a name="Errors" +><b>Errors</b></a></dt> + +<dd> +<dl> +<dt><a name="300_(Invalid_Username_or_Password)" +>300 (Invalid Username or Password)</a></dt> + +<dd> +<p>The username does not exist, +or the password is wrong.</p> + +<dt><a name="301_(Account_Disabled)" +>301 (Account Disabled)</a></dt> + +<dd> +<p>The account has been disabled. +A reason may be specified with the error.</p> +</dd> +</dl> +</dd> +</dl> + +<dt><a name="logout_EXPERIMENTAL" +><code class="code">logout</code> <b>EXPERIMENTAL</b></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Log out the user. +Does nothing if there is no user logged in.</p> + +<dt><a name="Params_(none)" +><b>Params</b> (none) +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing) +<dt><a name="Errors_(none)" +><b>Errors</b> (none)</a></dt> +</dl> +</dd> +</dl> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Account_Creation" +>Account Creation</a></h2> + +<dl> +<dt><a name="offer_account_by_email_EXPERIMENTAL" +><code class="code">offer_account_by_email</code> <b>EXPERIMENTAL</b></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Sends an email to the user, +offering to create an account. +The user will have to click on a URL in the email, +and choose their password and real name.</p> + +<p>This is the recommended way to create a Bugzilla account.</p> + +<dt><a name="Param" +><b>Param</b></a></dt> + +<dd> +<dl> +<dt><a name="email_(string)_-_the_email_to_send_the_offer_to." +><code class="code">email</code> (string) - the email to send the offer to.</a></dt> +</dl> + +<dt><a name="Returns_(nothing)" +><b>Returns</b> (nothing) +<dt><a name="Errors" +><b>Errors</b></a></dt> + +<dd> +<dl> +<dt><a name="500_(Illegal_Email_Address)" +>500 (Illegal Email Address)</a></dt> + +<dd> +<p>This Bugzilla does not allow you to create accounts with the format of email address you specified. +Account creation may be entirely disabled.</p> + +<dt><a name="501_(Account_Already_Exists)" +>501 (Account Already Exists)</a></dt> + +<dd> +<p>An account with that email address already exists in Bugzilla.</p> +</dd> +</dl> +</dd> +</dl> + +<dt><a name="create_EXPERIMENTAL" +><code class="code">create</code> <b>EXPERIMENTAL</b></a></dt> + +<dd> +<dl> +<dt><a name="Description" +><b>Description</b></a></dt> + +<dd> +<p>Creates a user account directly in Bugzilla, +password and all. +Instead of this, +you should use <a href="#offer_account_by_email" class="podlinkpod" +>"offer_account_by_email"</a> when possible, +because that makes sure that the email address specified can actually receive an email. +This function does not check that.</p> + +<dt><a name="Params" +><b>Params</b></a></dt> + +<dd> +<dl> +<dt><a name="email_(string)_-_The_email_address_for_the_new_user." +><code class="code">email</code> (string) - The email address for the new user. +<dt><a name="full_name_(string)_Optional_-_The_user's_full_name._Will_be_set_to_empty_if_not_specified." +><code class="code">full_name</code> (string) <b>Optional</b> - The user's full name. +Will be set to empty if not specified. +<dt><a +><code class="code">password</code> (string) <b>Optional</b> - The password for the new user account, +in plain text. +It will be stripped of leading and trailing whitespace. +If blank or not specified, +the newly created account will exist in Bugzilla, +but will not be allowed to log in using DB authentication until a password is set either by the user (through resetting their password) or by the administrator.</a></dt> +</dl> + +<dt><a name="Returns" +><b>Returns</b></a></dt> + +<dd> +<p>A hash containing one item, +<code class="code">id</code>, +the numeric id of the user that was created.</p> + +<dt><a name="Errors" +><b>Errors</b></a></dt> + +<dd> +<p>The same as <a href="#offer_account_by_email" class="podlinkpod" +>"offer_account_by_email"</a>. +If a password is specified, +the function may also throw:</p> + +<dl> +<dt><a name="502_(Password_Too_Short)" +>502 (Password Too Short)</a></dt> + +<dd> +<p>The password specified is too short. +(Usually, +this means the password is under three characters.)</p> + +<dt><a name="503_(Password_Too_Long)" +>503 (Password Too Long)</a></dt> + +<dd> +<p>The password specified is too long. +(Usually, +this means the password is over ten characters.)</p> +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/CVS/Entries b/docs/html/api/CVS/Entries new file mode 100644 index 000000000..1f43397f6 --- /dev/null +++ b/docs/html/api/CVS/Entries @@ -0,0 +1,3 @@ +/.cvsignore/1.1/Tue Sep 5 19:00:55 2006//TBUGZILLA-3_0 +/style.css/1.1/Tue Sep 5 19:00:55 2006//TBUGZILLA-3_0 +D diff --git a/docs/html/api/CVS/Repository b/docs/html/api/CVS/Repository new file mode 100644 index 000000000..18c4008f9 --- /dev/null +++ b/docs/html/api/CVS/Repository @@ -0,0 +1 @@ +mozilla/webtools/bugzilla/docs/html/api diff --git a/docs/html/api/CVS/Root b/docs/html/api/CVS/Root new file mode 100644 index 000000000..cdb6f4a07 --- /dev/null +++ b/docs/html/api/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot diff --git a/docs/html/api/CVS/Tag b/docs/html/api/CVS/Tag new file mode 100644 index 000000000..efdc1ff3e --- /dev/null +++ b/docs/html/api/CVS/Tag @@ -0,0 +1 @@ +NBUGZILLA-3_0 diff --git a/docs/html/api/checksetup.html b/docs/html/api/checksetup.html new file mode 100644 index 000000000..77275aa59 --- /dev/null +++ b/docs/html/api/checksetup.html @@ -0,0 +1,250 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +checksetup.pl</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>checksetup.pl</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#OPTIONS'>OPTIONS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <li class='indexItem indexItem1'><a href='#MODIFYING_CHECKSETUP'>MODIFYING CHECKSETUP</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#How_Checksetup_Works'>How Checksetup Works</a> + <li class='indexItem indexItem2'><a href='#Modifying_the_Database'>Modifying the Database</a> + </ul> + <li class='indexItem indexItem1'><a href='#RUNNING_CHECKSETUP_NON-INTERACTIVELY'>RUNNING CHECKSETUP NON-INTERACTIVELY</a> + <li class='indexItem indexItem1'><a href='#SEE_ALSO'>SEE ALSO</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>checksetup.pl - A do-it-all upgrade and installation script for Bugzilla.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> ./checksetup.pl [--help|--check-modules] + ./checksetup.pl [SCRIPT [--verbose]] [--no-templates|-t] + [--make-admin=user@domain.com]</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="OPTIONS" +>OPTIONS</a></h1> + +<dl> +<dt><a name="SCRIPT" +><em class="code">SCRIPT</em></a></dt> + +<dd> +<p>Name of script to drive non-interactive mode. This script should define an <code class="code">%answer</code> hash whose keys are variable names and the values answers to all the questions checksetup.pl asks. For details on the format of this script, do <code class="code">perldoc checksetup.pl</code> and look for the <a href="#RUNNING_CHECKSETUP_NON-INTERACTIVELY" class="podlinkpod" +>"RUNNING CHECKSETUP NON-INTERACTIVELY"</a> section.</p> + +<dt><a name="--help" +><b>--help</b></a></dt> + +<dd> +<p>Display this help text</p> + +<dt><a name="--check-modules" +><b>--check-modules</b></a></dt> + +<dd> +<p>Only check for correct module dependencies and quit afterward.</p> + +<dt><a name="--make-admin=username@domain.com" +><b>--make-admin</b>=username@domain.com</a></dt> + +<dd> +<p>Makes the specified user into a Bugzilla administrator. This is in case you accidentally lock yourself out of the Bugzilla administrative interface.</p> + +<dt><a name="--no-templates_(-t)" +><b>--no-templates</b> (<b>-t</b>)</a></dt> + +<dd> +<p>Don't compile the templates at all. Existing compiled templates will remain; missing compiled templates will not be created. (Used primarily by developers to speed up checksetup.) Use this switch at your own risk.</p> + +<dt><a name="--verbose" +><b>--verbose</b></a></dt> + +<dd> +<p>Output results of SCRIPT being processed.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>Hey, what's this?</p> + +<p><em class="code">checksetup.pl</em> is a script that is supposed to run during installation time and also after every upgrade.</p> + +<p>The goal of this script is to make the installation even easier. It does this by doing things for you as well as testing for problems in advance.</p> + +<p>You can run the script whenever you like. You MUST run it after you update Bugzilla, because it will then update your SQL table definitions to resync them with the code.</p> + +<p>You can see all the details of what the script does at <a href="#How_Checksetup_Works" class="podlinkpod" +>"How Checksetup Works"</a>.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="MODIFYING_CHECKSETUP" +>MODIFYING CHECKSETUP</a></h1> + +<p>There should be no need for Bugzilla Administrators to modify this script; all user-configurable stuff has been moved into a local configuration file called <em class="code">localconfig</em>. When that file in changed and <em class="code">checksetup.pl</em> is run, then the user's changes will be reflected back into the database.</p> + +<p>However, developers often need to modify the installation process. This section explains how <em class="code">checksetup.pl</em> works, so that you know the right part to modify.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="How_Checksetup_Works" +>How Checksetup Works</a></h2> + +<p><em class="code">checksetup.pl</em> runs through several stages during installation:</p> + +<ol> +<li>Checks if the required and optional perl modules are installed, using <a href="./Bugzilla/Install/Requirements.html#check_requirements" class="podlinkpod" +>"check_requirements" in Bugzilla::Install::Requirements</a>.</li> + +<li>Creates or updates the <em class="code">localconfig</em> file, using <a href="./Bugzilla/Install/Localconfig.html#update_localconfig" class="podlinkpod" +>"update_localconfig" in Bugzilla::Install::Localconfig</a>.</li> + +<li>Checks the DBD and database version, using <a href="./Bugzilla/DB.html#bz_check_requirements" class="podlinkpod" +>"bz_check_requirements" in Bugzilla::DB</a>.</li> + +<li>Creates the Bugzilla database if it doesn't exist, using <a href="./Bugzilla/DB.html#bz_create_database" class="podlinkpod" +>"bz_create_database" in Bugzilla::DB</a>.</li> + +<li>Creates all of the tables in the Bugzilla database, using <a href="./Bugzilla/DB.html#bz_setup_database" class="podlinkpod" +>"bz_setup_database" in Bugzilla::DB</a>. +<p>Note that all the table definitions are stored in <a href="./Bugzilla/DB/Schema.html#ABSTRACT_SCHEMA" class="podlinkpod" +>"ABSTRACT_SCHEMA" in Bugzilla::DB::Schema</a>.</p> +</li> + +<li>Puts the values into the enum tables (like <code class="code">resolution</code>, <code class="code">bug_status</code>, etc.) using <a href="./Bugzilla/DB.html#bz_populate_enum_tables" class="podlinkpod" +>"bz_populate_enum_tables" in Bugzilla::DB</a>.</li> + +<li>Creates any files that Bugzilla needs but doesn't ship with, using <a href="./Bugzilla/Install/Filesystem.html#update_filesystem" class="podlinkpod" +>"update_filesystem" in Bugzilla::Install::Filesystem</a>.</li> + +<li>Creates the <em class="code">.htaccess</em> files if you haven't specified not to in <em class="code">localconfig</em>. It does this with <a href="./Bugzilla/Install/Filesystem.html#create_htaccess" class="podlinkpod" +>"create_htaccess" in Bugzilla::Install::Filesystem</a>.</li> + +<li>Updates the system parameters (stored in <em class="code">data/params</em>), using <a href="./Bugzilla/Config.html#update_params" class="podlinkpod" +>"update_params" in Bugzilla::Config</a>.</li> + +<li>Pre-compiles all templates, to improve the speed of Bugzilla. It uses <a href="./Bugzilla/Template.html#precompile_templates" class="podlinkpod" +>"precompile_templates" in Bugzilla::Template</a> to do this.</li> + +<li>Fixes all file permissions to be secure. It does this differently depending on whether or not you've specified <code class="code">$webservergroup</code> in <em class="code">localconfig</em>. +<p>The function that does this is <a href="./Bugzilla/Install/Filesystem.html#fix_all_file_permissions" class="podlinkpod" +>"fix_all_file_permissions" in Bugzilla::Install::Filesystem</a>.</p> +</li> + +<li>Populates the <code class="code">fielddefs</code> table, using <a href="./Bugzilla/Field.html#populate_field_definitions" class="podlinkpod" +>"populate_field_definitions" in Bugzilla::Field</a>.</li> + +<li>This is the major part of checksetup--updating the table definitions from one version of Bugzilla to another. +<p>The code for this is in <a href="./Bugzilla/Install/DB.html#update_table_definitions" class="podlinkpod" +>"update_table_definitions" in Bugzilla::Install::DB</a>.</p> +</li> + +<li>Creates the system groups--the ones like <code class="code">editbugs</code>, <code class="code">admin</code>, and so on. This is <a href="./Bugzilla/Install.html#update_system_groups" class="podlinkpod" +>"update_system_groups" in Bugzilla::Install</a>.</li> + +<li>Creates all of the user-adjustable preferences that appear on the "General Preferences" screen. This is <a href="./Bugzilla/Install.html#update_settings" class="podlinkpod" +>"update_settings" in Bugzilla::Install</a>.</li> + +<li>Creates an administrator, if one doesn't already exist, using <a href="./Bugzilla/Install.html#create_admin" class="podlinkpod" +>"create_admin" in Bugzilla::Install</a>. +<p>We also can make somebody an admin at this step, if the user specified the <code class="code">--make-admin</code> switch.</p> +</li> + +<li>Creates the default Classification, Product, and Component, using <a href="./Bugzilla/Install.html#create_default_product" class="podlinkpod" +>"create_default_product" in Bugzilla::Install</a>.</li> +</ol> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Modifying_the_Database" +>Modifying the Database</a></h2> + +<p>Sometimes you'll want to modify the database. In fact, that's mostly what checksetup does, is upgrade old Bugzilla databases to the modern format.</p> + +<p>If you'd like to know how to make changes to the datbase, see the information in the Bugzilla Developer's Guide, at: <a href="http://www.bugzilla.org/docs/developer.html#sql-schema" class="podlinkurl" +>http://www.bugzilla.org/docs/developer.html#sql-schema</a></p> + +<p>Also see <a href="./Bugzilla/DB.html#Schema_Modification_Methods" class="podlinkpod" +>"Schema Modification Methods" in Bugzilla::DB</a> and <a href="./Bugzilla/DB.html#Schema_Information_Methods" class="podlinkpod" +>"Schema Information Methods" in Bugzilla::DB</a>.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="RUNNING_CHECKSETUP_NON-INTERACTIVELY" +>RUNNING CHECKSETUP NON-INTERACTIVELY</a></h1> + +<p>To operate checksetup non-interactively, run it with a single argument specifying a filename that contains the information usually obtained by prompting the user or by editing localconfig.</p> + +<p>The format of that file is as follows:</p> + +<pre class="code"> $answer{'db_host'} = 'localhost'; + $answer{'db_driver'} = 'mydbdriver'; + $answer{'db_port'} = 0; + $answer{'db_name'} = 'mydbname'; + $answer{'db_user'} = 'mydbuser'; + $answer{'db_pass'} = 'mydbpass'; + + $answer{'urlbase'} = 'http://bugzilla.mydomain.com/'; + + (Any localconfig variable or parameter can be specified as above.) + + $answer{'ADMIN_EMAIL'} = 'myadmin@mydomain.net'; + $answer{'ADMIN_PASSWORD'} = 'fooey'; + $answer{'ADMIN_REALNAME'} = 'Joel Peshkin'; + + $answer{'SMTP_SERVER'} = 'mail.mydomain.net'; + + $answer{'NO_PAUSE'} = 1</pre> + +<p><code class="code">NO_PAUSE</code> means "never stop and prompt the user to hit Enter to continue, just go ahead and do things, even if they are potentially dangerous." Don't set this to 1 unless you know what you are doing.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SEE_ALSO" +>SEE ALSO</a></h1> + +<ul> +<li><a href="./Bugzilla/Install/Requirements.html" class="podlinkpod" +>Bugzilla::Install::Requirements</a></li> + +<li><a href="./Bugzilla/Install/Localconfig.html" class="podlinkpod" +>Bugzilla::Install::Localconfig</a></li> + +<li><a href="./Bugzilla/Install/Filesystem.html" class="podlinkpod" +>Bugzilla::Install::Filesystem</a></li> + +<li><a href="./Bugzilla/Install/DB.html" class="podlinkpod" +>Bugzilla::Install::DB</a></li> + +<li><a href="./Bugzilla/Install.html" class="podlinkpod" +>Bugzilla::Install</a></li> + +<li><a href="./Bugzilla/Config.html#update_params" class="podlinkpod" +>"update_params" in Bugzilla::Config</a></li> + +<li><a href="./Bugzilla/DB.html#CONNECTION" class="podlinkpod" +>"CONNECTION" in Bugzilla::DB</a></li> +</ul> +<p class="backlinkbottom"><b><a name="___bottom" href="index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/contrib/bz_webservice_demo.html b/docs/html/api/contrib/bz_webservice_demo.html new file mode 100644 index 000000000..1d82b3a67 --- /dev/null +++ b/docs/html/api/contrib/bz_webservice_demo.html @@ -0,0 +1,236 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +bz_webservice_demo.pl</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>bz_webservice_demo.pl</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#OPTIONS'>OPTIONS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Initialization'>Initialization</a> + <li class='indexItem indexItem2'><a href='#Checking_Bugzilla%27s_version'>Checking Bugzilla's version</a> + <li class='indexItem indexItem2'><a href='#Checking_Bugzilla%27s_timezone'>Checking Bugzilla's timezone</a> + <li class='indexItem indexItem2'><a href='#Logging_In_and_Out'>Logging In and Out</a> + <ul class='indexList indexList3'> + <li class='indexItem indexItem3'><a href='#Using_Bugzilla%27s_Environment_Authentication'>Using Bugzilla's Environment Authentication</a> + <li class='indexItem indexItem3'><a href='#Using_Bugzilla%27s_CGI_Variable_Authentication'>Using Bugzilla's CGI Variable Authentication</a> + </ul> + <li class='indexItem indexItem2'><a href='#Retrieving_Bug_Information'>Retrieving Bug Information</a> + <li class='indexItem indexItem2'><a href='#Retrieving_Product_Information'>Retrieving Product Information</a> + <li class='indexItem indexItem2'><a href='#Creating_A_Bug'>Creating A Bug</a> + </ul> + <li class='indexItem indexItem1'><a href='#NOTES'>NOTES</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Character_Set_Encoding'>Character Set Encoding</a> + <li class='indexItem indexItem2'><a href='#Format_For_Create_File'>Format For Create File</a> + </ul> + <li class='indexItem indexItem1'><a href='#SEE_ALSO'>SEE ALSO</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>bz_webservice_demo.pl - Show how to talk to Bugzilla via XMLRPC</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<p><code class="code">bz_webservice_demo.pl [options]</code></p> + +<p><code class="code">bz_webservice_demo.pl --help</code> for detailed help</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="OPTIONS" +>OPTIONS</a></h1> + +<dl> +<dt><a name="--help,_-h,_-?" +>--help, +-h, +-?</a></dt> + +<dd> +<p>Print a short help message and exit.</p> + +<dt><a name="--uri" +>--uri</a></dt> + +<dd> +<p>URI to Bugzilla's <code class="code">xmlrpc.cgi</code> script, +along the lines of <code class="code">http://your.bugzilla.installation/path/to/bugzilla/xmlrpc.cgi</code>.</p> + +<dt><a name="--login" +>--login</a></dt> + +<dd> +<p>Bugzilla login name. +Specify this together with <b>--password</b> in order to log in.</p> + +<p>Specify this without a value in order to log out.</p> + +<dt><a name="--password" +>--password</a></dt> + +<dd> +<p>Bugzilla password. +Specify this together with <b>--login</b> in order to log in.</p> + +<dt><a name="--rememberlogin" +>--rememberlogin</a></dt> + +<dd> +<p>Gives access to Bugzilla's “Bugzilla_remember” option. +Specify this option while logging in to do the same thing as ticking the <code class="code">Bugzilla_remember</code> box on Bugilla's log in form. +Don't specify this option to do the same thing as unchecking the box.</p> + +<p>See Bugzilla's rememberlogin parameter for details.</p> + +<dt><a name="--bug_id" +>--bug_id</a></dt> + +<dd> +<p>Pass a bug ID to have <code class="code">bz_webservice_demo.pl</code> do some bug-related test calls.</p> + +<dt><a name="--product_name" +>--product_name</a></dt> + +<dd> +<p>Pass a product name to have <code class="code">bz_webservice_demo.pl</code> do some product-related test calls.</p> + +<dt><a name="--create" +>--create</a></dt> + +<dd> +<p>Specify a file that contains settings for the creating of a new bug.</p> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Initialization" +>Initialization</a></h2> + +<p>Using the XMLRPC::Lite class, +you set up a proxy, +as shown in this script. +Bugzilla's XMLRPC URI ends in <code class="code">xmlrpc.cgi</code>, +so your URI looks along the lines of <code class="code">http://your.bugzilla.installation/path/to/bugzilla/xmlrpc.cgi</code>.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Checking_Bugzilla's_version" +>Checking Bugzilla's version</a></h2> + +<p>To make sure the Bugzilla you're connecting to supports the methods you wish to call, +you may want to compare the result of <code class="code">Bugzilla.version</code> to the minimum required version your application needs.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Checking_Bugzilla's_timezone" +>Checking Bugzilla's timezone</a></h2> + +<p>To make sure that you understand the dates and times that Bugzilla returns to you, +you may want to call <code class="code">Bugzilla.timezone</code>.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Logging_In_and_Out" +>Logging In and Out</a></h2> + +<h3><a class='u' href='#___top' title='click to go to top of document' +name="Using_Bugzilla's_Environment_Authentication" +>Using Bugzilla's Environment Authentication</a></h3> + +<p>Use a <code class="code">http://login:password@your.bugzilla.installation/path/to/bugzilla/xmlrpc.cgi</code> style URI. +You don't log out if you're using this kind of authentication.</p> + +<h3><a class='u' href='#___top' title='click to go to top of document' +name="Using_Bugzilla's_CGI_Variable_Authentication" +>Using Bugzilla's CGI Variable Authentication</a></h3> + +<p>Use the <code class="code">User.login</code> and <code class="code">User.logout</code> calls to log in and out, +as shown in this script.</p> + +<p>The <code class="code">Bugzilla_remember</code> parameter is optional. +If omitted, +Bugzilla's defaults apply (as specified by its <code class="code">rememberlogin</code> parameter).</p> + +<p>Bugzilla hands back cookies you'll need to pass along during your work calls.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Retrieving_Bug_Information" +>Retrieving Bug Information</a></h2> + +<p>Call <code class="code">Bug.get_bug</code> with the ID of the bug you want to know more of. +The call will return a <code class="code">Bugzilla::Bug</code> object.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Retrieving_Product_Information" +>Retrieving Product Information</a></h2> + +<p>Call <code class="code">Product.get_product</code> with the name of the product you want to know more of. +The call will return a <code class="code">Bugzilla::Product</code> object.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Creating_A_Bug" +>Creating A Bug</a></h2> + +<p>Call <code class="code">Bug.create</code> with the settings read from the file indicated on the command line. +The file must contain a valid anonymous hash to use as argument for the call to <code class="code">Bug.create</code>. +The call will return a hash with a bug id for the newly created bug.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NOTES" +>NOTES</a></h1> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Character_Set_Encoding" +>Character Set Encoding</a></h2> + +<p>Make sure that your application either uses the same character set encoding as Bugzilla does, +or that it converts correspondingly when using the web service API. +By default, +Bugzilla uses UTF-8 as its character set encoding.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Format_For_Create_File" +>Format For Create File</a></h2> + +<p>The create format file is a piece of Perl code, +that should look something like this:</p> + +<pre class="code"> { + product => "TestProduct", + component => "TestComponent", + summary => "TestBug - created from bz_webservice_demo.pl", + version => "unspecified", + description => "This is a description of the bug... hohoho", + op_sys => "All", + platform => "All", + priority => "P4", + severity => "normal" + };</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SEE_ALSO" +>SEE ALSO</a></h1> + +<p>There are code comments in <code class="code">bz_webservice_demo.pl</code> which might be of further help to you.</p> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/contrib/bzdbcopy.html b/docs/html/api/contrib/bzdbcopy.html new file mode 100644 index 000000000..331bd039b --- /dev/null +++ b/docs/html/api/contrib/bzdbcopy.html @@ -0,0 +1,54 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +bzdbcopy.pl</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>bzdbcopy.pl</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>bzdbcopy.pl - Copies data from one Bugzilla database to another.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>The intended use of this script is to copy data from an installation running on one DB platform to an installation running on another DB platform.</p> + +<p>It must be run from the directory containing your Bugzilla installation. +That means if this script is in the contrib/ directory, +you should be running it as: <code class="code">./contrib/bzdbcopy.pl</code></p> + +<p>Note: Both schemas must already exist and be <b>IDENTICAL</b>. +(That is, +they must have both been created/updated by the same version of checksetup.pl.) This script will <b>DESTROY ALL CURRENT DATA</b> in the target database.</p> + +<p>Both Schemas must be at least from Bugzilla 2.19.3, +but if you're running a Bugzilla from before 2.20rc2, +you'll need the patch at: <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=300311" class="podlinkurl" +>http://bugzilla.mozilla.org/show_bug.cgi?id=300311</a> in order to be able to run this script.</p> + +<p>Before you using it, +you have to correctly set all the variables in the "User-Configurable Settings" section at the top of the script. +The <code class="code">SOURCE</code> settings are for the database you're copying from, +and the <code class="code">TARGET</code> settings are for the database you're copying to. +The <code class="code">DB_TYPE</code> is the name of a DB driver from the <em class="code">Bugzilla/DB/</em> directory.</p> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/contrib/merge-users.html b/docs/html/api/contrib/merge-users.html new file mode 100644 index 000000000..e95c7008a --- /dev/null +++ b/docs/html/api/contrib/merge-users.html @@ -0,0 +1,46 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +merge-users.pl</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>merge-users.pl</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>merge-users.pl - Merge two user accounts.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> This script moves activity from one user account to another. + Specify the two accounts on the command line, e.g.: + + ./merge-users.pl old_account@foo.com new_account@bar.com + or: + ./merge-users.pl id:old_userid id:new_userid + or: + ./merge-users.pl id:old_userid new_account@bar.com + + Notes: - the new account must already exist. + - the id:old_userid syntax permits you to migrate + activity from a deleted account to an existing one.</pre> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/contrib/recode.html b/docs/html/api/contrib/recode.html new file mode 100644 index 000000000..b8fc46bd2 --- /dev/null +++ b/docs/html/api/contrib/recode.html @@ -0,0 +1,102 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +recode.pl</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="../style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="../index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>recode.pl</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#OPTIONS'>OPTIONS</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>recode.pl - Converts a database from one encoding (or multiple encodings) to UTF-8.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> contrib/recode.pl [--guess [--show-failures]] [--charset=iso-8859-2] + [--overrides=file_name] + + --dry-run Don't modify the database. + + --charset Primary charset your data is currently in. This can be + optionally omitted if you do --guess. + + --guess Try to guess the charset of the data. + + --show-failures If we fail to guess, show where we failed. + + --overrides Specify a file containing overrides. See --help + for more info. + + --help Display detailed help. + + If you aren't sure what to do, try: + + contrib/recode.pl --guess --charset=cp1252</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="OPTIONS" +>OPTIONS</a></h1> + +<dl> +<dt><a name="--dry-run" +>--dry-run</a></dt> + +<dd> +<p>Don't modify the database, just print out what the conversions will be.</p> + +<p>recode.pl will print out a Key for each item. You can use this in the overrides file, described below.</p> + +<dt><a name="--guess" +>--guess</a></dt> + +<dd> +<p>If your database is in multiple different encodings, specify this switch and recode.pl will do its best to determine the original charset of the data. The detection is usually very reliable.</p> + +<p>If recode.pl cannot guess the charset, it will leave the data alone, unless you've specified --charset.</p> + +<dt><a name="--charset=charset-name" +>--charset=charset-name</a></dt> + +<dd> +<p>If you do not specify --guess, then your database is converted from this character set into the UTF-8.</p> + +<p>If you have specified --guess, recode.pl will use this charset as a fallback--when it cannot guess the charset of a particular piece of data, it will guess that the data is in this charset and convert it from this charset to UTF-8.</p> + +<p>charset-name must be a charset that is known to perl's Encode module. To see a list of available charsets, do:</p> + +<p><code class="code">perl -MEncode -e 'print join("\n", Encode->encodings(":all"))'</code></p> + +<dt><a name="--show-failures" +>--show-failures</a></dt> + +<dd> +<p>If --guess fails to guess a charset, print out the data it failed on.</p> + +<dt><a name="--overrides=file_name" +>--overrides=file_name</a></dt> + +<dd> +<p>This is a way of specifying certain encodings to override the encodings of --guess. The file is a series of lines. The line should start with the Key from --dry-run, and then a space, and then the encoding you'd like to use.</p> +</dd> +</dl> +<p class="backlinkbottom"><b><a name="___bottom" href="../index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/email_in.html b/docs/html/api/email_in.html new file mode 100644 index 000000000..2f8603588 --- /dev/null +++ b/docs/html/api/email_in.html @@ -0,0 +1,152 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +email_in.pl</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>email_in.pl</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> + <ul class='indexList indexList2'> + <li class='indexItem indexItem2'><a href='#Creating_a_New_Bug'>Creating a New Bug</a> + <li class='indexItem indexItem2'><a href='#Modifying_an_Existing_Bug'>Modifying an Existing Bug</a> + <ul class='indexList indexList3'> + <li class='indexItem indexItem3'><a href='#Adding%2FRemoving_CCs'>Adding/Removing CCs</a> + </ul> + <li class='indexItem indexItem2'><a href='#Errors'>Errors</a> + </ul> + <li class='indexItem indexItem1'><a href='#CAUTION'>CAUTION</a> + <li class='indexItem indexItem1'><a href='#LIMITATIONS'>LIMITATIONS</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>email_in.pl - The Bugzilla Inbound Email Interface</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> ./email_in.pl [-vvv] < email.txt + + Reads an email on STDIN (the standard input). + + Options: + --verbose (-v) - Make the script print more to STDERR. + Specify multiple times to print even more.</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<p>This script processes inbound email and creates a bug, or appends data to an existing bug.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Creating_a_New_Bug" +>Creating a New Bug</a></h2> + +<p>The script expects to read an email with the following format:</p> + +<pre class="code"> From: account@domain.com + Subject: Bug Summary + + @product = ProductName + @component = ComponentName + @version = 1.0 + + This is a bug description. It will be entered into the bug exactly as + written here. + + It can be multiple paragraphs. + + -- + This is a signature line, and will be removed automatically, It will not + be included in the bug description.</pre> + +<p>The <code class="code">@</code> labels can be any valid field name in Bugzilla that can be set on <code class="code">enter_bug.cgi</code>. For the list of field names, see the <code class="code">fielddefs</code> table in the database. The above example shows the minimum fields you <b>must</b> specify.</p> + +<p>The values for the fields can be split across multiple lines, but note that a newline will be parsed as a single space, for the value. So, for example:</p> + +<pre class="code"> @short_desc = This is a very long + description</pre> + +<p>Will be parsed as "This is a very long description".</p> + +<p>If you specify <code class="code">@short_desc</code>, it will override the summary you specify in the Subject header.</p> + +<p><code class="code">account@domain.com</code> must be a valid Bugzilla account.</p> + +<p>Note that signatures must start with '-- ', the standard signature border.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Modifying_an_Existing_Bug" +>Modifying an Existing Bug</a></h2> + +<p>Bugzilla determines what bug you want to modify in one of two ways:</p> + +<ul> +<li>Your subject starts with [Bug 123456] -- then it modifies bug 123456.</li> + +<li>You include <code class="code">@bug_id = 123456</code> in the first lines of the email.</li> +</ul> + +<p>If you do both, <code class="code">@bug_id</code> takes precedence.</p> + +<p>You send your email in the same format as for creating a bug, except that you only specify the fields you want to change. If the very first non-blank line of the email doesn't begin with <code class="code">@</code>, then it will be assumed that you are only adding a comment to the bug.</p> + +<p>Note that when updating a bug, the <code class="code">Subject</code> header is ignored, except for getting the bug ID. If you want to change the bug's summary, you have to specify <code class="code">@short_desc</code> as one of the fields to change.</p> + +<p>Please remember not to include any extra text in your emails, as that text will also be added as a comment. This includes any text that your email client automatically quoted and included, if this is a reply to another email.</p> + +<h3><a class='u' href='#___top' title='click to go to top of document' +name="Adding/Removing_CCs" +>Adding/Removing CCs</a></h3> + +<p>You can't just add CCs to a bug by using the <code class="code">@cc</code> parameter like you can when you're filing a bug. To add CCs, you can specify them in a comma-separated list in <code class="code">@newcc</code>.</p> + +<p>To remove CCs, specify them as a comma-separated list in <code class="code">@removecc</code>.</p> + +<h2><a class='u' href='#___top' title='click to go to top of document' +name="Errors" +>Errors</a></h2> + +<p>If your request cannot be completed for any reason, Bugzilla will send an email back to you. If your request succeeds, Bugzilla will not send you anything.</p> + +<p>If any part of your request fails, all of it will fail. No partial changes will happen. The only exception is attachments--one attachment may succeed, and be inserted into the database, and a later attachment may fail.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="CAUTION" +>CAUTION</a></h1> + +<p>The script does not do any validation that the user is who they say they are. That is, it accepts <i>any</i> 'From' address, as long as it's a valid Bugzilla account. So make sure that your MTA validates that the message is actually coming from who it says it's coming from, and only allow access to the inbound email system from people you trust.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="LIMITATIONS" +>LIMITATIONS</a></h1> + +<p>Note that the email interface has the same limitations as the normal Bugzilla interface. So, for example, you cannot reassign a bug and change its status at the same time.</p> + +<p>The email interface only accepts emails that are correctly formatted perl RFC2822. If you send it an incorrectly formatted message, it may behave in an unpredictable fashion.</p> + +<p>You cannot send an HTML mail along with attachments. If you do, Bugzilla will reject your email, saying that it doesn't contain any text. This is a bug in <a href="./Email/MIME/Attachment/Stripper.html" class="podlinkpod" +>Email::MIME::Attachment::Stripper</a> that we can't work around.</p> + +<p>If you send multiple attachments in one email, they will all be attached, but Bugzilla may not send an email notice out for all of them.</p> + +<p>You cannot modify Flags through the email interface.</p> +<p class="backlinkbottom"><b><a name="___bottom" href="index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/importxml.html b/docs/html/api/importxml.html new file mode 100644 index 000000000..8ab2638d7 --- /dev/null +++ b/docs/html/api/importxml.html @@ -0,0 +1,93 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <title> +importxml</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <link rel="stylesheet" title="style" type="text/css" href="style.css" media="all" > + +</head> + <body id="pod"> +<p class="backlinktop"><b><a name="___top" href="index.html" accesskey="1" title="All Documents"><<</a></b></p> +<h1>importxml</h1> +<div class='indexgroup'> +<ul class='indexList indexList1'> + <li class='indexItem indexItem1'><a href='#NAME'>NAME</a> + <li class='indexItem indexItem1'><a href='#SYNOPSIS'>SYNOPSIS</a> + <li class='indexItem indexItem1'><a href='#OPTIONS'>OPTIONS</a> + <li class='indexItem indexItem1'><a href='#DESCRIPTION'>DESCRIPTION</a> +</ul> +</div> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="NAME" +>NAME</a></h1> + +<p>importxml - Import bugzilla bug data from xml.</p> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="SYNOPSIS" +>SYNOPSIS</a></h1> + +<pre class="code"> importxml.pl [options] [file ...] + + Options: + -? --help brief help message + -v --verbose print error and debug information. + Mulltiple -v increases verbosity + -m --sendmail send mail to recipients with log of bugs imported + --attach_path The path to the attachment files. + (Required if encoding="filename" is used for attachments.)</pre> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="OPTIONS" +>OPTIONS</a></h1> + +<dl> +<dt><a name="-?" +><b>-?</b></a></dt> + +<dd> +<pre class="code"> Print a brief help message and exits.</pre> + +<dt><a name="-v" +><b>-v</b></a></dt> + +<dd> +<pre class="code"> Print error and debug information. Mulltiple -v increases verbosity</pre> + +<dt><a name="-m" +><b>-m</b></a></dt> + +<dd> +<pre class="code"> Send mail to exporter with a log of bugs imported and any errors.</pre> +</dd> +</dl> + +<h1><a class='u' href='#___top' title='click to go to top of document' +name="DESCRIPTION" +>DESCRIPTION</a></h1> + +<pre class="code"> This script is used to import bugs from another installation of bugzilla. + It can be used in two ways. + First using the move function of bugzilla + on another system will send mail to an alias provided by + the administrator of the target installation (you). Set up an alias + similar to the one given below so this mail will be automatically + run by this script and imported into your database. Run 'newaliases' + after adding this alias to your aliases file. Make sure your sendmail + installation is configured to allow mail aliases to execute code. + + bugzilla-import: "|/usr/bin/perl /opt/bugzilla/importxml.pl --mail" + + Second it can be run from the command line with any xml file from + STDIN that conforms to the bugzilla DTD. In this case you can pass + an argument to set whether you want to send the + mail that will be sent to the exporter and maintainer normally. + + importxml.pl [options] bugsfile.xml</pre> +<p class="backlinkbottom"><b><a name="___bottom" href="index.html" title="All Documents"><<</a></b></p> + +<!-- end doc --> + +</body></html> diff --git a/docs/html/api/index.html b/docs/html/api/index.html new file mode 100644 index 000000000..ee2251548 --- /dev/null +++ b/docs/html/api/index.html @@ -0,0 +1,236 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <title>Bugzilla 3.0 API Documentation</title> + +<link rel="stylesheet" title="style" type="text/css" href="style.css" media="all" > + +</head> + <body class="contentspage"> + <h1>Bugzilla 3.0 API Documentation</h1> +<dl class='superindex'> +<dt><a name="Files">Files</a></dt> +<dd> +<table class="pod_desc_table"> +<tr class="even"> + <th><a href="./checksetup.html">checksetup</a></th> + <td>A do-it-all upgrade and installation script for Bugzilla.</td> +</tr> +<tr class="odd"> + <th><a href="./contrib/bz_webservice_demo.html">contrib::bz_webservice_demo</a></th> + <td>Show how to talk to Bugzilla via XMLRPC</td> +</tr> +<tr class="even"> + <th><a href="./contrib/bzdbcopy.html">contrib::bzdbcopy</a></th> + <td>Copies data from one Bugzilla database to another.</td> +</tr> +<tr class="odd"> + <th><a href="./contrib/merge-users.html">contrib::merge-users</a></th> + <td>Merge two user accounts.</td> +</tr> +<tr class="even"> + <th><a href="./contrib/recode.html">contrib::recode</a></th> + <td>Converts a database from one encoding (or multiple encodings) to UTF-8.</td> +</tr> +<tr class="odd"> + <th><a href="./email_in.html">email_in</a></th> + <td>The Bugzilla Inbound Email Interface</td> +</tr> +<tr class="even"> + <th><a href="./importxml.html">importxml</a></th> + <td>Import bugzilla bug data from xml.</td> +</tr> +</table></dd> + +<dt><a name="Modules">Modules</a></dt> +<dd> +<table class="pod_desc_table"> +<tr class="even"> + <th><a href="./Bugzilla.html">Bugzilla</a></th> + <td>Semi-persistent collection of various objects used by scripts and modules</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/Attachment.html">Bugzilla::Attachment</a></th> + <td>a file related to a bug that a user has uploaded to the Bugzilla server</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Auth.html">Bugzilla::Auth</a></th> + <td>An object that authenticates the login credentials for a user.</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/Auth/Login.html">Bugzilla::Auth::Login</a></th> + <td>Gets username/password data from the user.</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Auth/Verify.html">Bugzilla::Auth::Verify</a></th> + <td>An object that verifies usernames and passwords.</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/CGI.html">Bugzilla::CGI</a></th> + <td>CGI handling for Bugzilla</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Classification.html">Bugzilla::Classification</a></th> + <td>Bugzilla classification class.</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/Component.html">Bugzilla::Component</a></th> + <td>Bugzilla product component class.</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Config.html">Bugzilla::Config</a></th> + <td>Configuration parameters for Bugzilla</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/Config/Common.html">Bugzilla::Config::Common</a></th> + <td>Parameter checking functions</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/DB.html">Bugzilla::DB</a></th> + <td>Database access routines, using DBI</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/DB/Mysql.html">Bugzilla::DB::Mysql</a></th> + <td>Bugzilla database compatibility layer for MySQL</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/DB/Pg.html">Bugzilla::DB::Pg</a></th> + <td>Bugzilla database compatibility layer for PostgreSQL</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/DB/Schema.html">Bugzilla::DB::Schema</a></th> + <td>Abstract database schema for Bugzilla</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Error.html">Bugzilla::Error</a></th> + <td>Error handling utilities for Bugzilla</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/Field.html">Bugzilla::Field</a></th> + <td>a particular piece of information about bugs and useful routines for form field manipulation</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Flag.html">Bugzilla::Flag</a></th> + <td>A module to deal with Bugzilla flag values.</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/FlagType.html">Bugzilla::FlagType</a></th> + <td>A module to deal with Bugzilla flag types.</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Group.html">Bugzilla::Group</a></th> + <td>Bugzilla group class.</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/Hook.html">Bugzilla::Hook</a></th> + <td>Extendible extension hooks for Bugzilla code</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Install.html">Bugzilla::Install</a></th> + <td>Functions and variables having to do with installation.</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/Install/DB.html">Bugzilla::Install::DB</a></th> + <td>Fix up the database during installation.</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Install/Filesystem.html">Bugzilla::Install::Filesystem</a></th> + <td>Fix up the filesystem during installation.</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/Install/Localconfig.html">Bugzilla::Install::Localconfig</a></th> + <td></td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Install/Requirements.html">Bugzilla::Install::Requirements</a></th> + <td>Functions and variables dealing with Bugzilla's perl-module requirements.</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/Keyword.html">Bugzilla::Keyword</a></th> + <td>A Keyword that can be added to a bug.</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Milestone.html">Bugzilla::Milestone</a></th> + <td>Bugzilla product milestone class.</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/Object.html">Bugzilla::Object</a></th> + <td>A base class for objects in Bugzilla.</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Product.html">Bugzilla::Product</a></th> + <td>Bugzilla product class.</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/Search/Saved.html">Bugzilla::Search::Saved</a></th> + <td></td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Template.html">Bugzilla::Template</a></th> + <td>Wrapper around the Template Toolkit Template object</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/Template/Plugin/Bugzilla.html">Bugzilla::Template::Plugin::Bugzilla</a></th> + <td></td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Template/Plugin/Hook.html">Bugzilla::Template::Plugin::Hook</a></th> + <td></td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/Template/Plugin/User.html">Bugzilla::Template::Plugin::User</a></th> + <td></td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Token.html">Bugzilla::Token</a></th> + <td>Provides different routines to manage tokens.</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/Update.html">Bugzilla::Update</a></th> + <td>Update routines for Bugzilla</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/User.html">Bugzilla::User</a></th> + <td>Object for a Bugzilla user</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/User/Setting.html">Bugzilla::User::Setting</a></th> + <td>Object for a user preference setting</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/User/Setting/Skin.html">Bugzilla::User::Setting::Skin</a></th> + <td>Object for a user preference setting for skins</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/Util.html">Bugzilla::Util</a></th> + <td>Generic utility functions for bugzilla</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/Version.html">Bugzilla::Version</a></th> + <td>Bugzilla product version class.</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/WebService.html">Bugzilla::WebService</a></th> + <td>The Web Service interface to Bugzilla</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/WebService/Bug.html">Bugzilla::WebService::Bug</a></th> + <td>The API for creating, changing, and getting the details of bugs.</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/WebService/Bugzilla.html">Bugzilla::WebService::Bugzilla</a></th> + <td>Global functions for the webservice interface.</td> +</tr> +<tr class="even"> + <th><a href="./Bugzilla/WebService/Product.html">Bugzilla::WebService::Product</a></th> + <td>The Product API</td> +</tr> +<tr class="odd"> + <th><a href="./Bugzilla/WebService/User.html">Bugzilla::WebService::User</a></th> + <td>The User Account and Login API</td> +</tr> +</table></dd> + +</dl> +</body></html> \ No newline at end of file diff --git a/docs/html/api/style.css b/docs/html/api/style.css new file mode 100644 index 000000000..1c9a6bcb1 --- /dev/null +++ b/docs/html/api/style.css @@ -0,0 +1,107 @@ +/* The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Bugzilla Bug Tracking System. + * + * The Initial Developer of the Original Code is Everything Solved. + * Portions created by Everything Solved are Copyright (C) 2006 + * Everything Solved. All Rights Reserved. + * + * Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + */ + +body { + background: white; + color: #111; + padding: 0 1em; + margin: 0; + font-family: Verdana, Arial, sans-serif; + font-size: small; +} + +a:link, a:active { color: #36415c; } +a:visited { color: #666; } +a:hover { color: #888; } + +h1 { + font-size: 150%; + font-weight: bold; + border-bottom: 2px solid #ccc; +} +h2 { + font-size: 125%; + font-weight: bold; + border-bottom: 1px solid #ccc; + margin-bottom: 8px; +} +h3 { + font-size: 115%; + font-weight: bold; + margin-bottom: 0; + padding-bottom: 0; +} + +/* This makes Description/Params/Returns look nice. */ +dd { margin-top: .2em; } +dd p { margin-top: 0; } +dl { margin-bottom: 1em; } + +/* This makes the names of functions slightly larger, in Gecko. */ +body > dl > dt code { font-size: 1.35em; } + +#pod h1 a, #pod h2 a, #pod h3 a { + color: #36415c; + text-decoration: none; +} + +pre, code, tt, kbd, samp { + /* Unfortunately, the default monospace fonts on most browsers + look odd with relative sizing. */ + font-size: 12px; +} + +.code { + background: #eed; + border: 1px solid #ccc; +} + +pre.code { + margin-left: 10px; + width: 90%; + padding: 10px; +} + +/* Special styles for the Contents page */ + +.contentspage dt { + font-size: large; + font-weight: bold; +} + +.pod_desc_table { + border-collapse: collapse; + table-layout: auto; + border: 1px solid #ccc; +} + +.pod_desc_table th { + text-align: left; +} + +.pod_desc_table td, .pod_desc_table th { + padding: .25em; + border-top: 1px solid #ccc; +} + +.pod_desc_table .odd th, .pod_desc_table .odd td { + background-color: #eee; +} + +.pod_desc_table diff --git a/docs/html/attachments.html b/docs/html/attachments.html index 2778c88c4..7a40b63c6 100644 --- a/docs/html/attachments.html +++ b/docs/html/attachments.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Using Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -100,18 +98,25 @@ CLASS="filename" </P ><P > If you have a really large attachment, something that does not need to - be recorded forever (as most attachments are), you can mark your - attachment as a <SPAN + be recorded forever (as most attachments are), or something that is too + big for your database, you can mark your attachment as a + <SPAN CLASS="QUOTE" >"Big File"</SPAN ->, assuming the administrator of the - installation has enabled this feature. Big Files are stored directly on - disk instead of in the database, and can be deleted when it is no longer - needed. The maximum size of a <SPAN +>, assuming the administrator of the installation + has enabled this feature. Big Files are stored directly on disk instead + of in the database. The maximum size of a <SPAN CLASS="QUOTE" >"Big File"</SPAN -> is normally larger - than the maximum size of a regular attachment. +> is + normally larger than the maximum size of a regular attachment. Independently + of the storage system used, an administrator can delete these attachments + at any time. Nevertheless, if these files are stored in the database, the + <SPAN +CLASS="QUOTE" +>"allow_attachment_deletion"</SPAN +> parameter (which is turned off + by default) must be enabled in order to delete them. </P ><P > Also, if the administrator turned on the <SPAN diff --git a/docs/html/bug_page.html b/docs/html/bug_page.html index 3fa486a59..7ad071d77 100644 --- a/docs/html/bug_page.html +++ b/docs/html/bug_page.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Using Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -82,7 +80,7 @@ NAME="bug_page" >The core of Bugzilla is the screen which displays a particular bug. It's a good place to explain some Bugzilla concepts. <A -HREF="http://landfill.bugzilla.org/bugzilla-2.22-branch/show_bug.cgi?id=1" +HREF="http://landfill.bugzilla.org/bugzilla-tip/show_bug.cgi?id=1" TARGET="_top" > Bug 1 on Landfill</A > @@ -272,7 +270,7 @@ BORDER="0" > <EM >Priority:</EM > - The bug assignee uses this field to prioritize his or her bugs. + The bug assignee uses this field to prioritise his or her bugs. It's a good idea not to change this on other people's bugs.</P ></LI ><LI @@ -414,8 +412,7 @@ CLASS="QUOTE" You can attach files (e.g. testcases or patches) to bugs. If there are any attachments, they are listed in this section. Attachments are normally stored in the Bugzilla database, unless they are marked as - Big Files, which are stored directly on disk and (unlike attachments - kept in the database) may be deleted at some future time. + Big Files, which are stored directly on disk. </P ></LI ><LI diff --git a/docs/html/bugreports.html b/docs/html/bugreports.html index 650497473..218b91cb4 100644 --- a/docs/html/bugreports.html +++ b/docs/html/bugreports.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Using Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -90,7 +88,7 @@ NAME="fillingbugs" >Years of bug writing experience has been distilled for your reading pleasure into the <A -HREF="http://landfill.bugzilla.org/bugzilla-2.22-branch/page.cgi?id=bug-writing.html" +HREF="http://landfill.bugzilla.org/bugzilla-tip/page.cgi?id=bug-writing.html" TARGET="_top" > Bug Writing Guidelines</A >. @@ -142,7 +140,7 @@ VALIGN="TOP" > If you want to file a test bug to see how Bugzilla works, you can do it on one of our test installations on <A -HREF="http://landfill.bugzilla.org/bugzilla-2.22-branch/" +HREF="http://landfill.bugzilla.org/bugzilla-tip/" TARGET="_top" >Landfill</A >. @@ -219,6 +217,21 @@ VALIGN="TOP" ></LI ><LI ><P +> As you file the bug, you can also attach a document (testcase, patch, + or screenshot of the problem). + </P +></LI +><LI +><P +> Depending on the Bugzilla installation you are using and the product in + which you are filing the bug, you can also request developers to consider + your bug in different ways (such as requesting review for the patch you + just attached, requesting your bug to block the next release of the + product, and many other product specific requests). + </P +></LI +><LI +><P > Now is a good time to read your bug report again. Remove all misspellings, otherwise your bug may not be found by developers running queries for some specific words, and so your bug would not get any attention. diff --git a/docs/html/classifications.html b/docs/html/classifications.html index d678ff2e5..5905fcce4 100644 --- a/docs/html/classifications.html +++ b/docs/html/classifications.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Administering Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/cmdline-bugmail.html b/docs/html/cmdline-bugmail.html index 430ead8cc..6ceb1c5d0 100644 --- a/docs/html/cmdline-bugmail.html +++ b/docs/html/cmdline-bugmail.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Contrib" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/cmdline.html b/docs/html/cmdline.html index 681bf9299..90c8f64c7 100644 --- a/docs/html/cmdline.html +++ b/docs/html/cmdline.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Contrib" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -118,7 +116,7 @@ ALT="Warning"></TD ALIGN="LEFT" VALIGN="TOP" ><P -> These files pre-date the templatization work done as part of the +> These files pre-date the templatisation work done as part of the 2.16 release, and have not been updated. </P ></TD diff --git a/docs/html/components.html b/docs/html/components.html index 08eaf33fb..af447cd75 100644 --- a/docs/html/components.html +++ b/docs/html/components.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Administering Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/configuration.html b/docs/html/configuration.html index 5c1ff1c34..48f855598 100644 --- a/docs/html/configuration.html +++ b/docs/html/configuration.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Installing Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -364,7 +362,7 @@ CLASS="section" ><H4 CLASS="section" ><A -NAME="AEN445" +NAME="AEN473" >2.2.2.2.2. Allow small words in full-text indexes</A ></H4 ><P @@ -500,7 +498,7 @@ CLASS="section" ><H4 CLASS="section" ><A -NAME="AEN472" +NAME="AEN500" >2.2.2.2.4. Permit attachments table to grow beyond 4GB</A ></H4 ><P @@ -594,40 +592,11 @@ NAME="postgresql" >2.2.2.3. PostgreSQL</A ></H3 ><DIV -CLASS="note" -><P -></P -><TABLE -CLASS="note" -WIDTH="100%" -BORDER="0" -><TR -><TD -WIDTH="25" -ALIGN="CENTER" -VALIGN="TOP" -><IMG -SRC="../images/note.gif" -HSPACE="5" -ALT="Note"></TD -><TD -ALIGN="LEFT" -VALIGN="TOP" -><P ->If you are using PostgreSQL 8.0.1 or higher, then you - will require to use a version of DBD::Pg which is equal to or - greater than version 1.41 - </P -></TD -></TR -></TABLE -></DIV -><DIV CLASS="section" ><H4 CLASS="section" ><A -NAME="AEN490" +NAME="AEN516" >2.2.2.3.1. Add a User to PostgreSQL</A ></H4 ><P @@ -708,7 +677,7 @@ CLASS="section" ><H4 CLASS="section" ><A -NAME="AEN506" +NAME="AEN532" >2.2.2.3.2. Configure PostgreSQL</A ></H4 ><P @@ -722,7 +691,7 @@ CLASS="filename" >. In this file, you will need to add a new line to it as follows:</P ><P -> <SAMP +> <SAMP CLASS="computeroutput" >host all bugs 127.0.0.1 255.255.255.255 md5</SAMP > @@ -732,33 +701,6 @@ CLASS="computeroutput" '127.0.0.1' to 'all' databases on this server from the 'bugs' user, and use password authentication (md5) for that user.</P ><P ->If you are using <EM ->versions of PostgreSQL - before version 8</EM ->, you may also need to edit <TT -CLASS="filename" ->postgresql.conf</TT -> - , also usually found in the <TT -CLASS="filename" ->/var/lib/pgsql/data/</TT -> folder. - You will need to make a single line change, changing</P -><P -> <SAMP -CLASS="computeroutput" -># tcpip_socket = false</SAMP -> - </P -><P ->to</P -><P -> <SAMP -CLASS="computeroutput" ->tcpip_socket = true</SAMP -> - </P -><P >Now, you will need to restart PostgreSQL, but you will need to fully stop and start the server rather than just restarting due to the possibility of a change to <TT @@ -789,7 +731,7 @@ CLASS="section" ><H2 CLASS="section" ><A -NAME="AEN529" +NAME="AEN546" >2.2.3. checksetup.pl</A ></H2 ><P @@ -858,48 +800,68 @@ CLASS="section" CLASS="section" ><A NAME="http-apache" ->2.2.4.1. Apache <SPAN -CLASS="productname" ->httpd</SPAN -></A +>2.2.4.1. Bugzilla using Apache</A ></H3 ><P -> To configure your Apache web server to work with Bugzilla, - do the following: +>You have two options for running Bugzilla under Apache - + <A +HREF="configuration.html#http-apache-mod_cgi" +>mod_cgi</A +> (the default) and + <A +HREF="configuration.html#http-apache-mod_perl" +>mod_perl</A +> (new in Bugzilla + 2.23) </P ><DIV +CLASS="section" +><H4 +CLASS="section" +><A +NAME="http-apache-mod_cgi" +>2.2.4.1.1. Apache <SPAN +CLASS="productname" +>httpd</SPAN +> with mod_cgi</A +></H4 +><P +> To configure your Apache web server to work with Bugzilla while using + mod_cgi, do the following: + </P +><DIV CLASS="procedure" ><OL TYPE="1" ><LI ><P -> Load <TT +> Load <TT CLASS="filename" >httpd.conf</TT > in your editor. - In Fedora and Red Hat Linux, this file is found in - <TT + In Fedora and Red Hat Linux, this file is found in + <TT CLASS="filename" >/etc/httpd/conf</TT >. - </P + </P ></LI ><LI ><P -> Apache uses <SAMP +> Apache uses <SAMP CLASS="computeroutput" ><Directory></SAMP > - directives to permit fine-grained permission setting. Add the - following lines to a directive that applies to the location - of your Bugzilla installation. (If such a section does not - exist, you'll want to add one.) In this example, Bugzilla has - been installed at - <TT + directives to permit fine-grained permission setting. Add the + following lines to a directive that applies to the location + of your Bugzilla installation. (If such a section does not + exist, you'll want to add one.) In this example, Bugzilla has + been installed at + <TT CLASS="filename" >/var/www/html/bugzilla</TT >. - </P + </P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" @@ -910,31 +872,31 @@ WIDTH="100%" COLOR="#000000" ><PRE CLASS="programlisting" -> <Directory /var/www/html/bugzilla> - AddHandler cgi-script .cgi - Options +Indexes +ExecCGI - DirectoryIndex index.cgi - AllowOverride Limit -</Directory> - </PRE +> <Directory /var/www/html/bugzilla> + AddHandler cgi-script .cgi + Options +Indexes +ExecCGI + DirectoryIndex index.cgi + AllowOverride Limit + </Directory> + </PRE ></FONT ></TD ></TR ></TABLE ><P -> These instructions: allow apache to run .cgi files found - within the bugzilla directory; instructs the server to look - for a file called <TT +> These instructions: allow apache to run .cgi files found + within the bugzilla directory; instructs the server to look + for a file called <TT CLASS="filename" >index.cgi</TT > if someone - only types the directory name into the browser; and allows - Bugzilla's <TT + only types the directory name into the browser; and allows + Bugzilla's <TT CLASS="filename" >.htaccess</TT > files to override - global permissions. - </P + global permissions. + </P ><DIV CLASS="note" ><P @@ -956,18 +918,18 @@ ALT="Note"></TD ALIGN="LEFT" VALIGN="TOP" ><P -> It is possible to make these changes globally, or to the - directive controlling Bugzilla's parent directory (e.g. - <SAMP +> It is possible to make these changes globally, or to the + directive controlling Bugzilla's parent directory (e.g. + <SAMP CLASS="computeroutput" ><Directory /var/www/html/></SAMP >). - Such changes would also apply to the Bugzilla directory... - but they would also apply to many other places where they - may or may not be appropriate. In most cases, including - this one, it is better to be as restrictive as possible - when granting extra access. - </P + Such changes would also apply to the Bugzilla directory... + but they would also apply to many other places where they + may or may not be appropriate. In most cases, including + this one, it is better to be as restrictive as possible + when granting extra access. + </P ></TD ></TR ></TABLE @@ -975,48 +937,48 @@ CLASS="computeroutput" ></LI ><LI ><P -> <TT +> <TT CLASS="filename" >checksetup.pl</TT > can set tighter permissions - on Bugzilla's files and directories if it knows what group the - webserver runs as. Find the <SAMP + on Bugzilla's files and directories if it knows what group the + webserver runs as. Find the <SAMP CLASS="computeroutput" >Group</SAMP > - line in <TT + line in <TT CLASS="filename" >httpd.conf</TT >, place the value found - there in the <VAR + there in the <VAR CLASS="replaceable" >$webservergroup</VAR > variable - in <TT + in <TT CLASS="filename" >localconfig</TT >, then rerun - <TT + <TT CLASS="filename" >checksetup.pl</TT >. - </P + </P ></LI ><LI ><P -> Optional: If Bugzilla does not actually reside in the webspace - directory, but instead has been symbolically linked there, you - will need to add the following to the - <SAMP +> Optional: If Bugzilla does not actually reside in the webspace + directory, but instead has been symbolically linked there, you + will need to add the following to the + <SAMP CLASS="computeroutput" >Options</SAMP > line of the Bugzilla - <SAMP + <SAMP CLASS="computeroutput" ><Directory></SAMP > directive - (the same one as in the step above): - </P + (the same one as in the step above): + </P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" @@ -1027,23 +989,256 @@ WIDTH="100%" COLOR="#000000" ><PRE CLASS="programlisting" -> +FollowSymLinks - </PRE +> +FollowSymLinks + </PRE ></FONT ></TD ></TR ></TABLE ><P -> Without this directive, Apache will not follow symbolic links - to places outside its own directory structure, and you will be - unable to run Bugzilla. - </P +> Without this directive, Apache will not follow symbolic links + to places outside its own directory structure, and you will be + unable to run Bugzilla. + </P ></LI ></OL ></DIV ></DIV ><DIV CLASS="section" +><H4 +CLASS="section" +><A +NAME="http-apache-mod_perl" +>2.2.4.1.2. Apache <SPAN +CLASS="productname" +>httpd</SPAN +> with mod_perl</A +></H4 +><P +>Some configuration is required to make Bugzilla work with Apache + and mod_perl</P +><DIV +CLASS="procedure" +><OL +TYPE="1" +><LI +><P +> Load <TT +CLASS="filename" +>httpd.conf</TT +> in your editor. + In Fedora and Red Hat Linux, this file is found in + <TT +CLASS="filename" +>/etc/httpd/conf</TT +>. + </P +></LI +><LI +><P +>Add the following information to your httpd.conf file, substituting + where appropriate with your own local paths.</P +><DIV +CLASS="note" +><P +></P +><TABLE +CLASS="note" +WIDTH="100%" +BORDER="0" +><TR +><TD +WIDTH="25" +ALIGN="CENTER" +VALIGN="TOP" +><IMG +SRC="../images/note.gif" +HSPACE="5" +ALT="Note"></TD +><TD +ALIGN="LEFT" +VALIGN="TOP" +><P +>This should be used instead of the <Directory> block + shown above. This should also be above any other <VAR +CLASS="literal" +>mod_perl</VAR +> + directives within the <TT +CLASS="filename" +>httpd.conf</TT +> and must be specified + in the order as below.</P +></TD +></TR +></TABLE +></DIV +><DIV +CLASS="warning" +><P +></P +><TABLE +CLASS="warning" +WIDTH="100%" +BORDER="0" +><TR +><TD +WIDTH="25" +ALIGN="CENTER" +VALIGN="TOP" +><IMG +SRC="../images/warning.gif" +HSPACE="5" +ALT="Warning"></TD +><TD +ALIGN="LEFT" +VALIGN="TOP" +><P +>You should also ensure that you have disabled <VAR +CLASS="literal" +>KeepAlive</VAR +> + support in your Apache install when utilizing Bugzilla under mod_perl</P +></TD +></TR +></TABLE +></DIV +><TABLE +BORDER="0" +BGCOLOR="#E0E0E0" +WIDTH="100%" +><TR +><TD +><FONT +COLOR="#000000" +><PRE +CLASS="programlisting" +> PerlSwitches -I/var/www/html/bugzilla -w -T + PerlConfigRequire /var/www/html/bugzilla/mod_perl.pl + </PRE +></FONT +></TD +></TR +></TABLE +></LI +><LI +><P +> <TT +CLASS="filename" +>checksetup.pl</TT +> can set tighter permissions + on Bugzilla's files and directories if it knows what group the + webserver runs as. Find the <SAMP +CLASS="computeroutput" +>Group</SAMP +> + line in <TT +CLASS="filename" +>httpd.conf</TT +>, place the value found + there in the <VAR +CLASS="replaceable" +>$webservergroup</VAR +> variable + in <TT +CLASS="filename" +>localconfig</TT +>, then rerun + <TT +CLASS="filename" +>checksetup.pl</TT +>. + </P +></LI +></OL +></DIV +><P +>On restarting Apache, Bugzilla should now be running within the + mod_perl environment. Please ensure you have run checksetup.pl to set + permissions before you restart Apache.</P +><DIV +CLASS="note" +><P +></P +><TABLE +CLASS="note" +WIDTH="100%" +BORDER="0" +><TR +><TD +WIDTH="25" +ALIGN="CENTER" +VALIGN="TOP" +><IMG +SRC="../images/note.gif" +HSPACE="5" +ALT="Note"></TD +><TD +ALIGN="LEFT" +VALIGN="TOP" +><P +>Please bear the following points in mind when looking at using + Bugzilla under mod_perl: + <P +></P +><UL +><LI +><P +> mod_perl support in Bugzilla can take up a HUGE amount of RAM. You could be + looking at 30MB per httpd child, easily. Basically, you just need a lot of RAM. + The more RAM you can get, the better. mod_perl is basically trading RAM for + speed. At least 2GB total system RAM is recommended for running Bugzilla under + mod_perl. + </P +></LI +><LI +><P +> Under mod_perl, you have to restart Apache if you make any manual change to + any Bugzilla file. You can't just reload--you have to actually + <EM +>restart</EM +> the server (as in make sure it stops and starts + again). You <EM +>can</EM +> change localconfig and the params file + manually, if you want, because those are re-read every time you load a page. + </P +></LI +><LI +><P +> You must run in Apache's Prefork MPM (this is the default). The Worker MPM + may not work--we haven't tested Bugzilla's mod_perl support under threads. + (And, in fact, we're fairly sure it <EM +>won't</EM +> work.) + </P +></LI +><LI +><P +> Bugzilla generally expects to be the only mod_perl application running on + your entire server. It may or may not work if there are other applications also + running under mod_perl. It does try its best to play nice with other mod_perl + applications, but it still may have conflicts. + </P +></LI +><LI +><P +> It is recommended that you have one Bugzilla instance running under mod_perl + on your server. Bugzilla has not been tested with more than one instance running. + </P +></LI +></UL +> + </P +></TD +></TR +></TABLE +></DIV +></DIV +></DIV +><DIV +CLASS="section" ><H3 CLASS="section" ><A diff --git a/docs/html/conventions.html b/docs/html/conventions.html index 8ee2ae338..5e1b7ee15 100644 --- a/docs/html/conventions.html +++ b/docs/html/conventions.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="About This Guide" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -343,7 +341,7 @@ CLASS="sgmltag" This documentation is maintained in DocBook 4.1.2 XML format. Changes are best submitted as plain text or XML diffs, attached to a bug filed in the <A -HREF="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=Documentation" +HREF="https://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=Documentation" TARGET="_top" >Bugzilla Documentation</A > component. diff --git a/docs/html/copyright.html b/docs/html/copyright.html index 1b2c8e0f8..ff895b721 100644 --- a/docs/html/copyright.html +++ b/docs/html/copyright.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="About This Guide" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/credits.html b/docs/html/credits.html index 0694e18eb..8a50361e6 100644 --- a/docs/html/credits.html +++ b/docs/html/credits.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="About This Guide" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/cust-change-permissions.html b/docs/html/cust-change-permissions.html index bbe61560c..0f23761c5 100644 --- a/docs/html/cust-change-permissions.html +++ b/docs/html/cust-change-permissions.html @@ -7,18 +7,17 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" -TITLE="Customizing Bugzilla" +TITLE="Customising Bugzilla" HREF="customization.html"><LINK REL="PREVIOUS" -TITLE="Template Hooks" +TITLE="The Bugzilla Extension Mechanism" HREF="cust-hooks.html"><LINK REL="NEXT" -TITLE="Modifying Your Running System" -HREF="dbmodify.html"></HEAD +TITLE="Integrating Bugzilla with Third-Party Tools" +HREF="integration.html"></HEAD ><BODY CLASS="section" BGCOLOR="#FFFFFF" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -55,13 +53,13 @@ ACCESSKEY="P" WIDTH="80%" ALIGN="center" VALIGN="bottom" ->Chapter 6. Customizing Bugzilla</TD +>Chapter 6. Customising Bugzilla</TD ><TD WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A -HREF="dbmodify.html" +HREF="integration.html" ACCESSKEY="N" >Next</A ></TD @@ -76,7 +74,7 @@ CLASS="section" CLASS="section" ><A NAME="cust-change-permissions" ->6.3. Customizing Who Can Change What</A +>6.4. Customizing Who Can Change What</A ></H1 ><DIV CLASS="warning" @@ -121,19 +119,19 @@ VALIGN="TOP" ><P > For maximum flexibility, customizing this means editing Bugzilla's Perl code. This gives the administrator complete control over exactly who is - allowed to do what. The relevant function is called + allowed to do what. The relevant method is called <TT CLASS="filename" ->CheckCanChangeField()</TT +>check_can_change_field()</TT >, and is found in <TT CLASS="filename" ->process_bug.cgi</TT -> in your - Bugzilla directory. If you open that file and search for +>Bug.pm</TT +> in your + Bugzilla/ directory. If you open that file and search for <SPAN CLASS="QUOTE" ->"sub CheckCanChangeField"</SPAN +>"sub check_can_change_field"</SPAN >, you'll find it. </P ><P @@ -275,40 +273,10 @@ CLASS="filename" ></TABLE ></DIV ><P -> For a list of possible field names, look in - <TT -CLASS="filename" ->data/versioncache</TT -> for the list called - <TT -CLASS="filename" ->@::log_columns</TT ->. If you need help writing custom - rules for your organization, ask in the newsgroup. +> For a list of possible field names, look at the bugs table in the + database. If you need help writing custom rules for your organization, + ask in the newsgroup. </P -><DIV -CLASS="section" -><H2 -CLASS="section" -><A -NAME="cust-group-check" ->6.3.1. Modification in UserInGroup()</A -></H2 -><P -> The <TT -CLASS="filename" ->UserInGroup()</TT -> function in the - <TT -CLASS="filename" ->Bugzilla/User.pm</TT -> module only accepts - one argument since 2.17.5: the name of a group. This check - is now always done against the current user, and a second - argument specifying the user ID to check this group against - is no longer valid and an error is thrown if you try to. - </P -></DIV ></DIV ><DIV CLASS="NAVFOOTER" @@ -344,7 +312,7 @@ WIDTH="33%" ALIGN="right" VALIGN="top" ><A -HREF="dbmodify.html" +HREF="integration.html" ACCESSKEY="N" >Next</A ></TD @@ -354,7 +322,7 @@ ACCESSKEY="N" WIDTH="33%" ALIGN="left" VALIGN="top" ->Template Hooks</TD +>The Bugzilla Extension Mechanism</TD ><TD WIDTH="34%" ALIGN="center" @@ -368,7 +336,7 @@ ACCESSKEY="U" WIDTH="33%" ALIGN="right" VALIGN="top" ->Modifying Your Running System</TD +>Integrating Bugzilla with Third-Party Tools</TD ></TR ></TABLE ></DIV diff --git a/docs/html/cust-hooks.html b/docs/html/cust-hooks.html index f6b8f41cb..72d8cac2f 100644 --- a/docs/html/cust-hooks.html +++ b/docs/html/cust-hooks.html @@ -2,16 +2,15 @@ <HTML ><HEAD ><TITLE ->Template Hooks</TITLE +>The Bugzilla Extension Mechanism</TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" -TITLE="Customizing Bugzilla" +TITLE="Customising Bugzilla" HREF="customization.html"><LINK REL="PREVIOUS" TITLE="Template Customization" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -55,7 +53,7 @@ ACCESSKEY="P" WIDTH="80%" ALIGN="center" VALIGN="bottom" ->Chapter 6. Customizing Bugzilla</TD +>Chapter 6. Customising Bugzilla</TD ><TD WIDTH="10%" ALIGN="right" @@ -76,7 +74,7 @@ CLASS="section" CLASS="section" ><A NAME="cust-hooks" ->6.2. Template Hooks</A +>6.3. The Bugzilla Extension Mechanism</A ></H1 ><DIV CLASS="warning" @@ -99,7 +97,7 @@ ALT="Warning"></TD ALIGN="LEFT" VALIGN="TOP" ><P -> Template Hooks require Template Toolkit version 2.12 or +> Custom extensions require Template Toolkit version 2.12 or above, or the application of a patch. See <A HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=239112" TARGET="_top" @@ -112,29 +110,71 @@ TARGET="_top" ></TABLE ></DIV ><P -> Template hooks are a way for extensions to Bugzilla to insert code - into the standard Bugzilla templates without modifying the template files - themselves. The hooks mechanism defines a consistent API for extending - the standard templates in a way that cleanly separates standard code - from extension code. Hooks reduce merge conflicts and make it easier - to write extensions that work across multiple versions of Bugzilla, - making upgrading a Bugzilla installation with installed extensions easier. +> Extensions are a way for extensions to Bugzilla to insert code + into the standard Bugzilla templates and source files + without modifying these files themselves. The extension mechanism + defines a consistent API for extending the standard templates and source files + in a way that cleanly separates standard code from extension code. + Hooks reduce merge conflicts and make it easier to write extensions that work + across multiple versions of Bugzilla, making upgrading a Bugzilla installation + with installed extensions easier. Furthermore, they make it easy to install + and remove extensions as each extension is nothing more than a + simple directory structure. </P ><P -> A template hook is just a named place in a standard template file - where extension template files for that hook get processed. Each hook - has a corresponding directory in the Bugzilla directory tree. Hooking an - extension template to a hook is as simple as putting the extension file - into the hook's directory. When Bugzilla processes the standard template - and reaches the hook, it will process all extension templates in the - hook's directory. The hooks themselves can be added into any standard - template upon request by extension authors. +> There are two main types of hooks: code hooks and template hooks. Code + hooks allow extensions to invoke code at specific points in various + source files, while template hooks allow extensions to add elements to + the Bugzilla user interface. </P ><P -> To use hooks to extend a Bugzilla template, first make sure there is - a hook at the appropriate place within the template you want to extend. - Hooks appear in the standard Bugzilla templates as a single directive - in the format +> A hook is just a named place in a standard source or template file + where extension source code or template files for that hook get processed. + Each extension has a corresponding directory in the Bugzilla directory + tree (<TT +CLASS="filename" +>BUGZILLA_ROOT/extensions/extension_name</TT +>). Hooking + an extension source file or template to a hook is as simple as putting + the extension file into extension's template or code directory. + When Bugzilla processes the source file or template and reaches the hook, + it will process all extension files in the hook's directory. + The hooks themselves can be added into any source file or standard template + upon request by extension authors. + </P +><P +> To use hooks to extend Bugzilla, first make sure there is + a hook at the appropriate place within the source file or template you + want to extend. The exact appearance of a hook depends on if the hook + is a code hook or a template hook. + </P +><P +> Code hooks appear in Bugzilla source files as a single method call + in the format <VAR +CLASS="literal" +>Bugzilla::Hook->process("<VAR +CLASS="varname" +>name</VAR +>");</VAR +>. + for instance, <TT +CLASS="filename" +>enter_bug.cgi</TT +> may invoke the hook + "<VAR +CLASS="varname" +>enter_bug-defaultvars</VAR +>". Thus, a source file at + <TT +CLASS="filename" +>BUGZILLA_ROOT/extensions/EXTENSION_NAME/code/enter_bug-entrydefaultvars.pl</TT +> + will be automatically invoked when the code hook is reached. + </P +><P +> + Template hooks appear in the standard Bugzilla templates as a + single directive in the format <VAR CLASS="literal" >[% Hook.process("<VAR @@ -145,12 +185,11 @@ CLASS="varname" where <VAR CLASS="varname" >name</VAR -> is the unique (within that template) - name of the hook. +> is the unique name of the hook. </P ><P -> If you aren't sure which template you want to extend or just want - to browse the available hooks, either use your favorite multi-file search +> If you aren't sure what you want to extend or just want to browse the + available hooks, either use your favorite multi-file search tool (e.g. <B CLASS="command" >grep</B @@ -158,23 +197,15 @@ CLASS="command" for occurrences of <CODE CLASS="methodname" >Hook.process</CODE -> or browse - the directory tree in - <TT -CLASS="filename" ->BUGZILLA_ROOT/template/en/extension/hook/</TT ->, - which contains a directory for each hook in the following location: - </P -><P -> <TT -CLASS="filename" ->BUGZILLA_ROOT/template/en/extension/hook/PATH_TO_STANDARD_TEMPLATE/STANDARD_TEMPLATE_NAME/HOOK_NAME/</TT -> +> or the source + files for occurrences of <CODE +CLASS="methodname" +>Bugzilla::Hook::process</CODE +>. </P ><P -> If there is no hook at the appropriate place within the Bugzilla template - you want to extend, +> If there is no hook at the appropriate place within the Bugzilla + source file or template you want to extend, <A HREF="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=User%20Interface" TARGET="_top" @@ -189,12 +220,13 @@ BORDER="0" ><TBODY ><TR ><TD ->the template for which you are requesting a hook;</TD +>the source or template file for which you are + requesting a hook;</TD ></TR ><TR ><TD -> where in the template you would like the hook to be placed - (line number/position for latest version of template in CVS +> where in the file you would like the hook to be placed + (line number/position for latest version of the file in CVS or description of location); </TD ></TR @@ -212,12 +244,8 @@ BORDER="0" ></P ><P > The Bugzilla reviewers will promptly review each hook request, - name the hook, add it to the template, check the new version - of the template into CVS, and create the corresponding directory in - <TT -CLASS="filename" ->BUGZILLA_ROOT/template/en/extension/hook/</TT ->. + name the hook, add it to the template or source file, and check + the new version of the template into CVS. </P ><P > You may optionally attach a patch to the bug which implements the hook @@ -231,12 +259,12 @@ CLASS="filename" </P ><P > After making sure the hook you need exists (or getting it added if not), - add your extension template to the directory within the Bugzilla - directory tree corresponding to the hook. + add your extension to the directory within the Bugzilla + extensions tree corresponding to the hook. </P ><P -> That's it! Now, when the standard template containing the hook - is processed, your extension template will be processed at the point +> That's it! Now, when the source file or template containing the hook + is processed, your extension file will be processed at the point where the hook appears. </P ><P @@ -292,19 +320,12 @@ CLASS="programlisting" ></TR ></TABLE ><P -> The corresponding directory for this hook is +> The corresponding extension file for this hook is <TT CLASS="filename" ->BUGZILLA_ROOT/template/en/extension/hook/global/useful-links.html.tmpl/edit/</TT +>BUGZILLA_ROOT/extensions/projman/template/en/hook/global/useful-links-edit.html.tmpl</TT >. - </P -><P -> You put a template named - <TT -CLASS="filename" ->projman-edit-projects.html.tmpl</TT -> - into that directory with the following content: + You then create that template file and add the following constant: </P ><TABLE BORDER="0" @@ -329,6 +350,44 @@ CLASS="literal" > group. </P ><P +> Now, let us say your extension adds a custom "project_manager" field + to enter_bug.cgi. You want to modify the CGI script to set the default + project manager to be productname@company.com. Looking at + <TT +CLASS="filename" +>enter_bug.cgi</TT +>, you see the enter_bug-entrydefaultvars + hook near the bottom of the file before the default form values are set. + The corresponding extension source file for this hook is located at + <TT +CLASS="filename" +>BUGZILLA_ROOT/extensions/projman/code/enter_bug-entrydefaultvars.pl</TT +>. + You then create that file and add the following: + </P +><TABLE +BORDER="0" +BGCOLOR="#E0E0E0" +WIDTH="100%" +><TR +><TD +><FONT +COLOR="#000000" +><PRE +CLASS="programlisting" +>$default{'project_manager'} = $product.'@company.com';</PRE +></FONT +></TD +></TR +></TABLE +><P +> This code will be invoked whenever enter_bug.cgi is executed. + Assuming that the rest of the customization was completed (e.g. the + custom field was added to the enter_bug template and the required hooks + were used in process_bug.cgi), the new field will now have this + default value. + </P +><P > Notes: </P ><P @@ -336,29 +395,14 @@ CLASS="literal" ><UL ><LI ><P -> You may want to prefix your extension template names - with the name of your extension, e.g. - <TT -CLASS="filename" ->projman-foo.html.tmpl</TT ->, - so they do not conflict with the names of templates installed by - other extensions. - </P -></LI -><LI -><P > If your extension includes entirely new templates in addition to - extensions of standard templates, it should install those new - templates into an extension-specific subdirectory of the + extensions of standard templates, it should store those new + templates in its <TT CLASS="filename" ->BUGZILLA_ROOT/template/en/extension/</TT +>BUGZILLA_ROOT/extensions/template/en/</TT > - directory. The <TT -CLASS="filename" ->extension/</TT -> directory, like the + directory. Extension template directories, like the <TT CLASS="filename" >default/</TT @@ -366,7 +410,7 @@ CLASS="filename" CLASS="filename" >custom/</TT > - directories, is part of the template search path, so putting templates + directories, are part of the template search path, so putting templates there enables them to be found by the template processor. </P ><P @@ -377,45 +421,45 @@ CLASS="filename" > directory (i.e. templates added by the specific installation), then in the <TT CLASS="filename" ->extension/</TT -> - directory (i.e. templates added by extensions), and finally in the +>extensions/</TT +> + directory (i.e. templates added by extensions), and finally in the <TT CLASS="filename" >default/</TT > directory (i.e. the standard Bugzilla - templates). Thus extension templates can override standard templates, - but installation-specific templates override both. - </P -><P -> Note that overriding standard templates with extension templates - gives you great power but also makes upgrading an installation harder. - As with custom templates, we recommend using this functionality - sparingly and only when absolutely necessary. + templates). Thus, installation-specific templates override both + default and extension templates. </P ></LI ><LI ><P -> Installation customizers can also take advantage of hooks when adding - code to a Bugzilla template. To do so, create directories in +> If you are looking to customize Bugzilla, you can also take advantage + of template hooks. To do so, create a directory in <TT CLASS="filename" >BUGZILLA_ROOT/template/en/custom/hook/</TT > - equivalent to the directories in + that corresponds to the hook you wish to use, then place your + customization templates into those directories. For example, + if you wanted to use the hook "end" in <TT CLASS="filename" ->BUGZILLA_ROOT/template/en/extension/hook/</TT -> - for the hooks you want to use, then place your customization templates - into those directories. +>global/useful-links.html.tmpl</TT +>, you would + create the directory <TT +CLASS="filename" +>BUGZILLA_ROOT/template/en/custom/hook/ + global/useful-links.html.tmpl/end/</TT +> and add your customization + template to this directory. </P ><P > Obviously this method of customizing Bugzilla only lets you add code - to the standard templates; you cannot change the existing code. - Nevertheless, for those customizations that only add code, this method - can reduce conflicts when merging changes, making upgrading - your customized Bugzilla installation easier. + to the standard source files and templates; you cannot change the + existing code. Nevertheless, for those customizations that only add + code, this method can reduce conflicts when merging changes, + making upgrading your customized Bugzilla installation easier. </P ></LI ></UL diff --git a/docs/html/dbmodify.html b/docs/html/cust-skins.html similarity index 50% rename from docs/html/dbmodify.html rename to docs/html/cust-skins.html index 579444d54..ad006c335 100644 --- a/docs/html/dbmodify.html +++ b/docs/html/cust-skins.html @@ -2,23 +2,22 @@ <HTML ><HEAD ><TITLE ->Modifying Your Running System</TITLE +>Custom Skins</TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" -TITLE="Customizing Bugzilla" +TITLE="Customising Bugzilla" HREF="customization.html"><LINK REL="PREVIOUS" -TITLE="Customizing Who Can Change What" -HREF="cust-change-permissions.html"><LINK +TITLE="Customising Bugzilla" +HREF="customization.html"><LINK REL="NEXT" -TITLE="Integrating Bugzilla with Third-Party Tools" -HREF="integration.html"></HEAD +TITLE="Template Customization" +HREF="cust-templates.html"></HEAD ><BODY CLASS="section" BGCOLOR="#FFFFFF" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -47,7 +45,7 @@ WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A -HREF="cust-change-permissions.html" +HREF="customization.html" ACCESSKEY="P" >Prev</A ></TD @@ -55,13 +53,13 @@ ACCESSKEY="P" WIDTH="80%" ALIGN="center" VALIGN="bottom" ->Chapter 6. Customizing Bugzilla</TD +>Chapter 6. Customising Bugzilla</TD ><TD WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A -HREF="integration.html" +HREF="cust-templates.html" ACCESSKEY="N" >Next</A ></TD @@ -75,46 +73,51 @@ CLASS="section" ><H1 CLASS="section" ><A -NAME="dbmodify" ->6.4. Modifying Your Running System</A +NAME="cust-skins" +>6.1. Custom Skins</A ></H1 ><P -> Bugzilla optimizes database lookups by storing all relatively - static information in the <TT +> Bugzilla allows you to have multiple skins. These are custom CSS and possibly + also custom images for Bugzilla. To create a new custom skin, you have two + choices: + <P +></P +><UL +><LI +><P +> Make a single CSS file, and put it in the + <TT CLASS="filename" ->versioncache</TT -> - file, located in the <TT +>skins/contrib</TT +> directory. + </P +></LI +><LI +><P +> Make a directory that contains all the same CSS file + names as <TT CLASS="filename" ->data/</TT +>skins/standard/</TT +>, and put + your directory in <TT +CLASS="filename" +>skins/contrib/</TT +>. + </P +></LI +></UL > - subdirectory under your installation directory. - </P + </P ><P -> If you make a change to the structural data in your database (the - versions table for example), or to the <SPAN -CLASS="QUOTE" ->"constants"</SPAN -> - encoded in <TT -CLASS="filename" ->defparams.pl</TT ->, you will need to remove - the cached content from the data directory (by doing a - <B -CLASS="command" ->rm data/versioncache</B ->), or your changes won't show up. - </P +> After you put the file or the directory there, make sure to run checksetup.pl + so that it can reset the file permissions correctly. + </P ><P -> <TT -CLASS="filename" ->versioncache</TT -> gets regenerated automatically - whenever it's more than an hour old, so Bugzilla will eventually - notice your changes by itself, but generally you want it to notice - right away, so that you can test things. - </P +> After you have installed the new skin, it will show up as an option in the + user's General Preferences. If you would like to force a particular skin on all + users, just select it in the Default Preferences and then uncheck "Enabled" on + the preference. + </P ></DIV ><DIV CLASS="NAVFOOTER" @@ -132,7 +135,7 @@ WIDTH="33%" ALIGN="left" VALIGN="top" ><A -HREF="cust-change-permissions.html" +HREF="customization.html" ACCESSKEY="P" >Prev</A ></TD @@ -150,7 +153,7 @@ WIDTH="33%" ALIGN="right" VALIGN="top" ><A -HREF="integration.html" +HREF="cust-templates.html" ACCESSKEY="N" >Next</A ></TD @@ -160,7 +163,7 @@ ACCESSKEY="N" WIDTH="33%" ALIGN="left" VALIGN="top" ->Customizing Who Can Change What</TD +>Customising Bugzilla</TD ><TD WIDTH="34%" ALIGN="center" @@ -174,7 +177,7 @@ ACCESSKEY="U" WIDTH="33%" ALIGN="right" VALIGN="top" ->Integrating Bugzilla with Third-Party Tools</TD +>Template Customization</TD ></TR ></TABLE ></DIV diff --git a/docs/html/cust-templates.html b/docs/html/cust-templates.html index e535baee6..d2a06bee8 100644 --- a/docs/html/cust-templates.html +++ b/docs/html/cust-templates.html @@ -7,17 +7,16 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" -TITLE="Customizing Bugzilla" +TITLE="Customising Bugzilla" HREF="customization.html"><LINK REL="PREVIOUS" -TITLE="Customizing Bugzilla" -HREF="customization.html"><LINK +TITLE="Custom Skins" +HREF="cust-skins.html"><LINK REL="NEXT" -TITLE="Template Hooks" +TITLE="The Bugzilla Extension Mechanism" HREF="cust-hooks.html"></HEAD ><BODY CLASS="section" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -47,7 +45,7 @@ WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A -HREF="customization.html" +HREF="cust-skins.html" ACCESSKEY="P" >Prev</A ></TD @@ -55,7 +53,7 @@ ACCESSKEY="P" WIDTH="80%" ALIGN="center" VALIGN="bottom" ->Chapter 6. Customizing Bugzilla</TD +>Chapter 6. Customising Bugzilla</TD ><TD WIDTH="10%" ALIGN="right" @@ -76,7 +74,7 @@ CLASS="section" CLASS="section" ><A NAME="cust-templates" ->6.1. Template Customization</A +>6.2. Template Customization</A ></H1 ><P > Administrators can configure the look and feel of Bugzilla without @@ -89,7 +87,7 @@ NAME="cust-templates" determined by the user's browser. More information is available in <A HREF="cust-templates.html#template-http-accept" ->Section 6.1.6</A +>Section 6.2.6</A >. </P ><DIV @@ -98,7 +96,7 @@ CLASS="section" CLASS="section" ><A NAME="template-directory" ->6.1.1. Template Directory Structure</A +>6.2.1. Template Directory Structure</A ></H2 ><P > The template directory structure starts with top level directory @@ -170,7 +168,7 @@ CLASS="section" CLASS="section" ><A NAME="template-method" ->6.1.2. Choosing a Customization Method</A +>6.2.2. Choosing a Customization Method</A ></H2 ><P > If you want to edit Bugzilla's templates, the first decision @@ -370,7 +368,7 @@ CLASS="section" CLASS="section" ><A NAME="template-edit" ->6.1.3. How To Edit Templates</A +>6.2.3. How To Edit Templates</A ></H2 ><DIV CLASS="note" @@ -458,7 +456,7 @@ CLASS="section" CLASS="section" ><A NAME="template-formats" ->6.1.4. Template Formats and Types</A +>6.2.4. Template Formats and Types</A ></H2 ><P > Some CGI's have the ability to use more than one template. For example, @@ -566,7 +564,7 @@ CLASS="section" CLASS="section" ><A NAME="template-specific" ->6.1.5. Particular Templates</A +>6.2.5. Particular Templates</A ></H2 ><P > There are a few templates you may be particularly interested in @@ -834,7 +832,7 @@ CLASS="section" CLASS="section" ><A NAME="template-http-accept" ->6.1.6. Configuring Bugzilla to Detect the User's Language</A +>6.2.6. Configuring Bugzilla to Detect the User's Language</A ></H2 ><P >Bugzilla honours the user's Accept: HTTP header. You can install @@ -885,7 +883,7 @@ WIDTH="33%" ALIGN="left" VALIGN="top" ><A -HREF="customization.html" +HREF="cust-skins.html" ACCESSKEY="P" >Prev</A ></TD @@ -913,7 +911,7 @@ ACCESSKEY="N" WIDTH="33%" ALIGN="left" VALIGN="top" ->Customizing Bugzilla</TD +>Custom Skins</TD ><TD WIDTH="34%" ALIGN="center" @@ -927,7 +925,7 @@ ACCESSKEY="U" WIDTH="33%" ALIGN="right" VALIGN="top" ->Template Hooks</TD +>The Bugzilla Extension Mechanism</TD ></TR ></TABLE ></DIV diff --git a/docs/html/custom-fields.html b/docs/html/custom-fields.html new file mode 100644 index 000000000..0c76c6526 --- /dev/null +++ b/docs/html/custom-fields.html @@ -0,0 +1,301 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML +><HEAD +><TITLE +>Custom Fields</TITLE +><META +NAME="GENERATOR" +CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK +REL="HOME" +TITLE="The Bugzilla Guide - 3.0 Release" +HREF="index.html"><LINK +REL="UP" +TITLE="Administering Bugzilla" +HREF="administration.html"><LINK +REL="PREVIOUS" +TITLE="Flags" +HREF="flags-overview.html"><LINK +REL="NEXT" +TITLE="Legal Values" +HREF="edit-values.html"></HEAD +><BODY +CLASS="section" +BGCOLOR="#FFFFFF" +TEXT="#000000" +LINK="#0000FF" +VLINK="#840084" +ALINK="#0000FF" +><DIV +CLASS="NAVHEADER" +><TABLE +SUMMARY="Header navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TH +COLSPAN="3" +ALIGN="center" +>The Bugzilla Guide - 3.0 Release</TH +></TR +><TR +><TD +WIDTH="10%" +ALIGN="left" +VALIGN="bottom" +><A +HREF="flags-overview.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="80%" +ALIGN="center" +VALIGN="bottom" +>Chapter 3. Administering Bugzilla</TD +><TD +WIDTH="10%" +ALIGN="right" +VALIGN="bottom" +><A +HREF="edit-values.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +></TABLE +><HR +ALIGN="LEFT" +WIDTH="100%"></DIV +><DIV +CLASS="section" +><H1 +CLASS="section" +><A +NAME="custom-fields" +>3.9. Custom Fields</A +></H1 +><P +> One of the most requested features was the ability to add your own custom + fields to bugs, based on your needs. With the release of Bugzilla 3.0, this + dream finally comes true. Administrators can manage these fields using the + <SPAN +CLASS="QUOTE" +>"Custom Fields"</SPAN +> link in the footer of pages. The first thing + they will see is the list of existing custom fields (which is empty by default). + </P +><DIV +CLASS="section" +><H2 +CLASS="section" +><A +NAME="add-custom-fields" +>3.9.1. Adding Custom Fields</A +></H2 +><P +> The <SPAN +CLASS="QUOTE" +>"Add a new custom field"</SPAN +> link permits you to add a + new field which can be either a free text box or a drop down menu. + More field types will be available in future releases. + </P +><P +> The following attributes must be set for each new custom field: + <P +></P +><UL +><LI +><P +> <EM +>Name:</EM +> + the name of the field, used internally. This name MUST begin + with <SPAN +CLASS="QUOTE" +>"cf_"</SPAN +>. If you omit this string, it will + be automatically added to the name you entered. This way, all + custom fields added to Bugzilla begin with <SPAN +CLASS="QUOTE" +>"cf_"</SPAN +>, + avoiding any conflict with default fields. + </P +></LI +><LI +><P +> <EM +>Description:</EM +> + the string which is used as a label for this custom field. + That is the string that users will see, and so should be + short and explicit. + </P +></LI +><LI +><P +> <EM +>Type:</EM +> + as mentioned above, only two types are implemented so far. + Free text boxes let you type any string, while drop down menus + only let you choose one value in the list provided. The list of + legal values for this field can be created and edited as soon as + this custom field is added to the DB. See + <A +HREF="edit-values.html#edit-values-list" +>Section 3.10.1</A +> for information about editing + legal values. + </P +></LI +><LI +><P +> <EM +>Sortkey:</EM +> + this integer determines in which order custom fields are + displayed in the UI, especially when viewing a bug. Fields + with lower values are displayed first. + </P +></LI +><LI +><P +> <EM +>Can be set on bug creation:</EM +> + this boolean determines whether this field can be set on + bug creation or not. If not, then you have to create the + bug first before being able to set this field. Else you + can set its value at the same time you file a bug, + see <A +HREF="bugreports.html" +>Section 5.6</A +> about filing bugs. + </P +></LI +><LI +><P +> <EM +>Displayed in bugmail for new bugs:</EM +> + this boolean determines whether the value set on this field + should appear in bugmail when the bug is filed. This attribute + has no effect if the field cannot be set on bug creation. + </P +></LI +><LI +><P +> <EM +>Is obsolete:</EM +> + this boolean determines whether or not this field should + be displayed at all. Obsolete custom fields are hidden. + </P +></LI +></UL +> + </P +></DIV +><DIV +CLASS="section" +><H2 +CLASS="section" +><A +NAME="edit-custom-fields" +>3.9.2. Editing Custom Fields</A +></H2 +><P +> As soon as a custom field is created, its name and type cannot be + changed. If this field is a drop down menu, its legal values can + be set as described in <A +HREF="edit-values.html#edit-values-list" +>Section 3.10.1</A +>. All + other attributes can be edited as described above. + </P +></DIV +><DIV +CLASS="section" +><H2 +CLASS="section" +><A +NAME="delete-custom-fields" +>3.9.3. Deleting Custom Fields</A +></H2 +><P +> At this point, it is not possible to delete custom fields from + your web browser. If you don't want to make one available anymore, + mark it as obsolete. This way, you will preserve your DB + referential integrity. + </P +></DIV +></DIV +><DIV +CLASS="NAVFOOTER" +><HR +ALIGN="LEFT" +WIDTH="100%"><TABLE +SUMMARY="Footer navigation table" +WIDTH="100%" +BORDER="0" +CELLPADDING="0" +CELLSPACING="0" +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +><A +HREF="flags-overview.html" +ACCESSKEY="P" +>Prev</A +></TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="index.html" +ACCESSKEY="H" +>Home</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +><A +HREF="edit-values.html" +ACCESSKEY="N" +>Next</A +></TD +></TR +><TR +><TD +WIDTH="33%" +ALIGN="left" +VALIGN="top" +>Flags</TD +><TD +WIDTH="34%" +ALIGN="center" +VALIGN="top" +><A +HREF="administration.html" +ACCESSKEY="U" +>Up</A +></TD +><TD +WIDTH="33%" +ALIGN="right" +VALIGN="top" +>Legal Values</TD +></TR +></TABLE +></DIV +></BODY +></HTML +> \ No newline at end of file diff --git a/docs/html/customization.html b/docs/html/customization.html index 2aca636d4..6275a7827 100644 --- a/docs/html/customization.html +++ b/docs/html/customization.html @@ -2,20 +2,19 @@ <HTML ><HEAD ><TITLE ->Customizing Bugzilla</TITLE +>Customising Bugzilla</TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="PREVIOUS" TITLE="Whining" HREF="whining.html"><LINK REL="NEXT" -TITLE="Template Customization" -HREF="cust-templates.html"></HEAD +TITLE="Custom Skins" +HREF="cust-skins.html"></HEAD ><BODY CLASS="chapter" BGCOLOR="#FFFFFF" @@ -35,8 +34,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -58,7 +56,7 @@ WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A -HREF="cust-templates.html" +HREF="cust-skins.html" ACCESSKEY="N" >Next</A ></TD @@ -73,7 +71,7 @@ CLASS="chapter" ><A NAME="customization" ></A ->Chapter 6. Customizing Bugzilla</H1 +>Chapter 6. Customising Bugzilla</H1 ><DIV CLASS="TOC" ><DL @@ -83,59 +81,59 @@ CLASS="TOC" ></DT ><DT >6.1. <A +HREF="cust-skins.html" +>Custom Skins</A +></DT +><DT +>6.2. <A HREF="cust-templates.html" >Template Customization</A ></DT ><DD ><DL ><DT ->6.1.1. <A +>6.2.1. <A HREF="cust-templates.html#template-directory" >Template Directory Structure</A ></DT ><DT ->6.1.2. <A +>6.2.2. <A HREF="cust-templates.html#template-method" >Choosing a Customization Method</A ></DT ><DT ->6.1.3. <A +>6.2.3. <A HREF="cust-templates.html#template-edit" >How To Edit Templates</A ></DT ><DT ->6.1.4. <A +>6.2.4. <A HREF="cust-templates.html#template-formats" >Template Formats and Types</A ></DT ><DT ->6.1.5. <A +>6.2.5. <A HREF="cust-templates.html#template-specific" >Particular Templates</A ></DT ><DT ->6.1.6. <A +>6.2.6. <A HREF="cust-templates.html#template-http-accept" >Configuring Bugzilla to Detect the User's Language</A ></DT ></DL ></DD ><DT ->6.2. <A +>6.3. <A HREF="cust-hooks.html" ->Template Hooks</A +>The Bugzilla Extension Mechanism</A ></DT ><DT ->6.3. <A +>6.4. <A HREF="cust-change-permissions.html" >Customizing Who Can Change What</A ></DT ><DT ->6.4. <A -HREF="dbmodify.html" ->Modifying Your Running System</A -></DT -><DT >6.5. <A HREF="integration.html" >Integrating Bugzilla with Third-Party Tools</A @@ -206,7 +204,7 @@ WIDTH="33%" ALIGN="right" VALIGN="top" ><A -HREF="cust-templates.html" +HREF="cust-skins.html" ACCESSKEY="N" >Next</A ></TD @@ -226,7 +224,7 @@ VALIGN="top" WIDTH="33%" ALIGN="right" VALIGN="top" ->Template Customization</TD +>Custom Skins</TD ></TR ></TABLE ></DIV diff --git a/docs/html/disclaimer.html b/docs/html/disclaimer.html index 9d7eac643..55493e80d 100644 --- a/docs/html/disclaimer.html +++ b/docs/html/disclaimer.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="About This Guide" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/edit-values.html b/docs/html/edit-values.html index c90ba1b7d..d00f20e35 100644 --- a/docs/html/edit-values.html +++ b/docs/html/edit-values.html @@ -7,15 +7,14 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Administering Bugzilla" HREF="administration.html"><LINK REL="PREVIOUS" -TITLE="Flags" -HREF="flags-overview.html"><LINK +TITLE="Custom Fields" +HREF="custom-fields.html"><LINK REL="NEXT" TITLE="Voting" HREF="voting.html"></HEAD @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -47,7 +45,7 @@ WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A -HREF="flags-overview.html" +HREF="custom-fields.html" ACCESSKEY="P" >Prev</A ></TD @@ -76,7 +74,7 @@ CLASS="section" CLASS="section" ><A NAME="edit-values" ->3.9. Legal Values</A +>3.10. Legal Values</A ></H1 ><P > Since Bugzilla 2.20 RC1, legal values for Operating Systems, platforms, @@ -85,7 +83,8 @@ NAME="edit-values" <TT CLASS="filename" >localconfig</TT ->. +>. Starting with Bugzilla 2.23.3, you + can also customize the list of valid resolutions from the same interface. </P ><DIV CLASS="section" @@ -93,12 +92,12 @@ CLASS="section" CLASS="section" ><A NAME="edit-values-list" ->3.9.1. Viewing/Editing legal values</A +>3.10.1. Viewing/Editing legal values</A ></H2 ><P > Editing legal values requires <SPAN CLASS="QUOTE" ->"editcomponents"</SPAN +>"admin"</SPAN > privileges. A link named <SPAN CLASS="QUOTE" @@ -118,7 +117,7 @@ CLASS="section" CLASS="section" ><A NAME="edit-values-delete" ->3.9.2. Deleting legal values</A +>3.10.2. Deleting legal values</A ></H2 ><P > You can also delete legal values, but only if the two following conditions @@ -160,7 +159,7 @@ WIDTH="33%" ALIGN="left" VALIGN="top" ><A -HREF="flags-overview.html" +HREF="custom-fields.html" ACCESSKEY="P" >Prev</A ></TD @@ -188,7 +187,7 @@ ACCESSKEY="N" WIDTH="33%" ALIGN="left" VALIGN="top" ->Flags</TD +>Custom Fields</TD ><TD WIDTH="34%" ALIGN="center" diff --git a/docs/html/extraconfig.html b/docs/html/extraconfig.html index 027f99a36..a9decf332 100644 --- a/docs/html/extraconfig.html +++ b/docs/html/extraconfig.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Installing Bugzilla" @@ -18,7 +17,7 @@ TITLE="Configuration" HREF="configuration.html"><LINK REL="NEXT" TITLE="Multiple Bugzilla databases with a single installation" -HREF="x763.html"></HEAD +HREF="x834.html"></HEAD ><BODY CLASS="section" BGCOLOR="#FFFFFF" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -61,7 +59,7 @@ WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A -HREF="x763.html" +HREF="x834.html" ACCESSKEY="N" >Next</A ></TD @@ -87,7 +85,7 @@ CLASS="section" ><H2 CLASS="section" ><A -NAME="AEN630" +NAME="AEN696" >2.3.1. Bug Graphs</A ></H2 ><P @@ -219,7 +217,7 @@ CLASS="section" ><H2 CLASS="section" ><A -NAME="AEN649" +NAME="AEN715" >2.3.2. Dependency Charts</A ></H2 ><P @@ -531,16 +529,18 @@ NAME="bzldap" you need to deal with user ID (e.g assigning a bug) use the email address. The LDAP authentication builds on top of this scheme, rather than replacing it. The initial log in is done with a username and - password for the LDAP directory. This then fetches the email address - from LDAP and authenticates seamlessly in the standard Bugzilla - authentication scheme using this email address. If an account for this - address already exists in your Bugzilla system, it will log in to that - account. If no account for that email address exists, one is created at - the time of login. (In this case, Bugzilla will attempt to use the - "displayName" or "cn" attribute to determine the user's full name.) - After authentication, all other user-related tasks are still handled by - email address, not LDAP username. You still assign bugs by email - address, query on users by email address, etc. + password for the LDAP directory. Bugzilla tries to bind to LDAP using + those credentials, and if successful, try to map this account to a + Bugzilla account. If a LDAP mail attribute is defined, the value of this + attribute is used, otherwise emailsuffix parameter is appended to LDAP + username to form a full email address. If an account for this address + already exists in your Bugzilla system, it will log in to that account. + If no account for that email address exists, one is created at the time + of login. (In this case, Bugzilla will attempt to use the "displayName" + or "cn" attribute to determine the user's full name.) After + authentication, all other user-related tasks are still handled by email + address, not LDAP username. You still assign bugs by email address, query + on users by email address, etc. </P ><DIV CLASS="caution" @@ -650,6 +650,26 @@ CLASS="QUOTE" or <SPAN CLASS="QUOTE" >"ldap.company.com:3268"</SPAN +> + </P +><P +>You can also specify a LDAP URI, so as to use other + protocols, such as LDAPS or LDAPI. If port was not specified in + the URI, the default is either 389 or 636 for 'LDAP' and 'LDAPS' + schemes respectively. + </P +><P +>Ex. <SPAN +CLASS="QUOTE" +>"ldap://ldap.company.com"</SPAN +>, + <SPAN +CLASS="QUOTE" +>"ldaps://ldap.company.com"</SPAN +> or + <SPAN +CLASS="QUOTE" +>"ldapi://%2fvar%2flib%2fldap_sock"</SPAN > </P ></DD @@ -829,7 +849,7 @@ WIDTH="33%" ALIGN="right" VALIGN="top" ><A -HREF="x763.html" +HREF="x834.html" ACCESSKEY="N" >Next</A ></TD diff --git a/docs/html/faq.html b/docs/html/faq.html index 76340fb33..7fc1413b1 100644 --- a/docs/html/faq.html +++ b/docs/html/faq.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="PREVIOUS" TITLE="Integrating Bugzilla with Third-Party Tools" @@ -35,8 +34,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -89,51 +87,57 @@ HREF="faq.html#faq-general" ><DL ><DT >A.1.1. <A +HREF="faq.html#faq-general-tryout" +> Can I try out Bugzilla somewhere? + </A +></DT +><DT +>A.1.2. <A HREF="faq.html#faq-general-license" > What license is Bugzilla distributed under? </A ></DT ><DT ->A.1.2. <A +>A.1.3. <A HREF="faq.html#faq-general-support" > How do I get commercial support for Bugzilla? </A ></DT ><DT ->A.1.3. <A +>A.1.4. <A HREF="faq.html#faq-general-companies" > What major companies or projects are currently using Bugzilla for bug-tracking? </A ></DT ><DT ->A.1.4. <A +>A.1.5. <A HREF="faq.html#faq-general-maintainers" > Who maintains Bugzilla? </A ></DT ><DT ->A.1.5. <A +>A.1.6. <A HREF="faq.html#faq-general-compare" > How does Bugzilla stack up against other bug-tracking databases? </A ></DT ><DT ->A.1.6. <A +>A.1.7. <A HREF="faq.html#faq-general-bzmissing" > Why doesn't Bugzilla offer this or that feature or compatibility with this other tracking software? </A ></DT ><DT ->A.1.7. <A +>A.1.8. <A HREF="faq.html#faq-general-mysql" > Why MySQL? I'm interested in seeing Bugzilla run on PostgreSQL/Sybase/Oracle/Msql/MSSQL. </A ></DT ><DT ->A.1.8. <A +>A.1.9. <A HREF="faq.html#faq-general-bonsaitools" > What is <TT CLASS="filename" @@ -142,7 +146,7 @@ CLASS="filename" </A ></DT ><DT ->A.1.9. <A +>A.1.10. <A HREF="faq.html#faq-general-perlpath" > My perl is located at <TT CLASS="filename" @@ -156,13 +160,13 @@ CLASS="filename" </A ></DT ><DT ->A.1.10. <A +>A.1.11. <A HREF="faq.html#faq-general-cookie" > Is there an easy way to change the Bugzilla cookie name? </A ></DT ><DT ->A.1.11. <A +>A.1.12. <A HREF="faq.html#faq-mod-perl" > Does bugzilla run under <TT CLASS="filename" @@ -170,6 +174,12 @@ CLASS="filename" >? </A ></DT +><DT +>A.1.13. <A +HREF="faq.html#faq-general-selinux" +> How can Bugzilla be made to work under SELinux? + </A +></DT ></DL ></DD ><DT @@ -589,10 +599,40 @@ CLASS="qandaentry" CLASS="question" ><P ><A -NAME="faq-general-license" +NAME="faq-general-tryout" ></A ><B >A.1.1. </B +> + Can I try out Bugzilla somewhere? + </P +></DIV +><DIV +CLASS="answer" +><P +><B +> </B +> + If you want to take a test ride, there are test installations + at <A +HREF="http://landfill.bugzilla.org/" +TARGET="_top" +>http://landfill.bugzilla.org/</A +>, + ready to play with directly from your browser. + </P +></DIV +></DIV +><DIV +CLASS="qandaentry" +><DIV +CLASS="question" +><P +><A +NAME="faq-general-license" +></A +><B +>A.1.2. </B > What license is Bugzilla distributed under? </P @@ -621,7 +661,7 @@ CLASS="question" NAME="faq-general-support" ></A ><B ->A.1.2. </B +>A.1.3. </B > How do I get commercial support for Bugzilla? </P @@ -657,7 +697,7 @@ CLASS="question" NAME="faq-general-companies" ></A ><B ->A.1.3. </B +>A.1.4. </B > What major companies or projects are currently using Bugzilla for bug-tracking? @@ -700,7 +740,7 @@ CLASS="question" NAME="faq-general-maintainers" ></A ><B ->A.1.4. </B +>A.1.5. </B > Who maintains Bugzilla? </P @@ -729,7 +769,7 @@ CLASS="question" NAME="faq-general-compare" ></A ><B ->A.1.5. </B +>A.1.6. </B > How does Bugzilla stack up against other bug-tracking databases? </P @@ -774,7 +814,7 @@ CLASS="question" NAME="faq-general-bzmissing" ></A ><B ->A.1.6. </B +>A.1.7. </B > Why doesn't Bugzilla offer this or that feature or compatibility with this other tracking software? @@ -793,7 +833,7 @@ CLASS="answer" </P ><P > The best way to make an enhancement request is to <A -HREF="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla" +HREF="https://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla" TARGET="_top" >file a bug at bugzilla.mozilla.org</A @@ -844,7 +884,7 @@ CLASS="question" NAME="faq-general-mysql" ></A ><B ->A.1.7. </B +>A.1.8. </B > Why MySQL? I'm interested in seeing Bugzilla run on PostgreSQL/Sybase/Oracle/Msql/MSSQL. @@ -860,46 +900,53 @@ CLASS="answer" and was available for the hardware Netscape intended to run it on. </P ><P -> There is currently work in progress to make Bugzilla work on - PostgreSQL; track the progress of this initiative in <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=98304" +> Bugzilla 2.20 contains experimental support for PostgreSQL. + Bugzilla 2.22 contains complete, stable support for PostgreSQL. + As of this release, using PostgreSQL with Bugzilla should + be as stable as using MySQL. If you experience any problems + with PostgreSQL compatibility, they will be taken as + seriously as if you were running MySQL. + </P +><P +> Red Hat once ran a version of Bugzilla that worked on Oracle, + but that was long, long ago; that version (Bugzilla 2.8) is + now obsolete, insecure, and totally unsupported. + </P +><P +> In August of 2005, Wim Coekaerts (Director of Linux + Engineering at Oracle Corporation) wrote to Dave Miller + confirming that Oracle intends to implement and support + Bugzilla. Since then, no further information has been + forthcoming. Track progress at + <A +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=189947" TARGET="_top" ->bug 98304</A +> Bug 189947</A >. </P ><P -> Sybase support is no longer being worked on. Even if it eventually - happens, it's VERY unlikely to work without the end-user-company - having to stick a few developers on making several manual changes. - Sybase is just NOT very standards-compliant (despite all the hype), - and it turned out that way too much had to be changed to make it - work -- like moving half of the application logic into stored +> Sybase support is no longer being worked on. Even if it + eventually happens, it's VERY unlikely to work without + the end-user-company having to stick a few developers on + making several manual changes. Sybase is just NOT very + standards-compliant (despite all the hype), and it turned + out that way too much had to be changed to make it work -- + like moving half of the application logic into stored procedures to get any kind of decent performance out of it. <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=173130" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=173130" TARGET="_top" ->Bug - 173130</A +> Bug 173130</A > is the relevant bug. </P ><P -> Red Hat once ran a version of Bugzilla that worked on Oracle, - but that was long, long ago; that version (Bugzilla 2.8) is - now obsolete, insecure, and totally unsupported. Red Hat's - current Bugzilla (based on Bugzilla 2.17.1) uses PostgreSQL, - and work is being done to merge those changes into the main - distribution. (See above.) At this time we know of no recent - ports of Bugzilla to Oracle. (In our honest opinion, Bugzilla - doesn't need what Oracle offers.) - </P -><P > <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=237862" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=237862" TARGET="_top" ->Bug - 237862</A -> is a good bug to read through if you'd like to see - what progress is being made on general database compatibility. +> Bug 237862</A +> is a good bug to read through if you'd + like to see what progress is being made on general database + compatibility. </P ></DIV ></DIV @@ -912,7 +959,7 @@ CLASS="question" NAME="faq-general-bonsaitools" ></A ><B ->A.1.8. </B +>A.1.9. </B > What is <TT CLASS="filename" @@ -954,7 +1001,7 @@ CLASS="question" NAME="faq-general-perlpath" ></A ><B ->A.1.9. </B +>A.1.10. </B > My perl is located at <TT CLASS="filename" @@ -1127,7 +1174,7 @@ CLASS="question" NAME="faq-general-cookie" ></A ><B ->A.1.10. </B +>A.1.11. </B > Is there an easy way to change the Bugzilla cookie name? </P @@ -1151,7 +1198,7 @@ CLASS="question" NAME="faq-mod-perl" ></A ><B ->A.1.11. </B +>A.1.12. </B > Does bugzilla run under <TT CLASS="filename" @@ -1176,6 +1223,36 @@ TARGET="_top" </P ></DIV ></DIV +><DIV +CLASS="qandaentry" +><DIV +CLASS="question" +><P +><A +NAME="faq-general-selinux" +></A +><B +>A.1.13. </B +> + How can Bugzilla be made to work under SELinux? + </P +></DIV +><DIV +CLASS="answer" +><P +><B +> </B +> + Unfortunately there are no step-by-step instructions, + but the following URL contains hints on how to do it: + <A +HREF="http://fedora.redhat.com/docs/selinux-apache-fc3/sn-debugging-and-customizing.html" +TARGET="_top" +>http://fedora.redhat.com/docs/selinux-apache-fc3/sn-debugging-and-customizing.html</A +> + </P +></DIV +></DIV ></DIV ><DIV CLASS="qandadiv" @@ -1239,7 +1316,7 @@ CLASS="answer" > There is no GUI for adding fields to Bugzilla at this time. You can follow development of this feature in <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=91037" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=91037" TARGET="_top" >bug 91037</A > @@ -1268,9 +1345,9 @@ CLASS="answer" > </B > Yes. Look at <A -HREF="http://bugzilla.mozilla.org/report.cgi" +HREF="https://bugzilla.mozilla.org/report.cgi" TARGET="_top" ->http://bugzilla.mozilla.org/report.cgi</A +>https://bugzilla.mozilla.org/report.cgi</A > for samples of what Bugzilla can do in reporting and graphing. Fuller documentation is provided in <A @@ -1474,7 +1551,7 @@ TARGET="_top" Some admin interfaces have been templatized (for easy localization) but many of them are still available in English only. Also, there may be issues with the charset not being declared. See <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=126266" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=126266" TARGET="_top" >bug 126226</A > @@ -1666,7 +1743,7 @@ CLASS="answer" See the documentation on Customization for more details, specifically <A HREF="cust-templates.html#template-specific" ->Section 6.1.5</A +>Section 6.2.5</A >. </P ></DIV @@ -1856,7 +1933,7 @@ CLASS="QUOTE" ><P > See also the instructions in <A HREF="upgrading.html#upgrade-cvs" ->Section 3.13.2.1</A +>Section 3.14.3.1</A >. </P ></DIV @@ -2121,7 +2198,7 @@ CLASS="command" >this makes MySQL as secure as taping a $100 to the floor of a football stadium bathroom for safekeeping.</EM -> +> </P ><DIV CLASS="warning" @@ -2421,7 +2498,7 @@ CLASS="QUOTE" >, which can be found in <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=6679" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=6679" TARGET="_top" >bug 6679</A @@ -2433,7 +2510,7 @@ TARGET="_top" > An updated (and much-expanded) version of this functionality is due to be released as part of Bugzilla 2.20; see <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=185090" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=185090" TARGET="_top" >bug 185090</A @@ -2765,6 +2842,99 @@ VALIGN="TOP" ></TR ></TABLE ></DIV +><P +> You may also be suffering from a client version mismatch: + </P +><P +> MySQL 4.1 and up uses an authentication protocol based on + a password hashing algorithm that is incompatible with that + used by older clients. If you upgrade the server to 4.1, + attempts to connect to it with an older client may fail + with the following message: + </P +><P +> <TABLE +BORDER="0" +BGCOLOR="#E0E0E0" +WIDTH="100%" +><TR +><TD +><FONT +COLOR="#000000" +><PRE +CLASS="screen" +><SAMP +CLASS="prompt" +>shell></SAMP +> mysql + Client does not support authentication protocol requested + by server; consider upgrading MySQL client + </PRE +></FONT +></TD +></TR +></TABLE +> + </P +><P +> To solve this problem, you should use one of the following + approaches: + </P +><P +> <P +></P +><UL +><LI +><P +> Upgrade all client programs to use a 4.1.1 or newer + client library. + </P +></LI +><LI +><P +> When connecting to the server with a pre-4.1 client + program, use an account that still has a + pre-4.1-style password. + </P +></LI +><LI +><P +> Reset the password to pre-4.1 style for each user + that needs to use a pre-4.1 client program. + This can be done using the SET PASSWORD statement + and the OLD_PASSWORD() function: + <TABLE +BORDER="0" +BGCOLOR="#E0E0E0" +WIDTH="100%" +><TR +><TD +><FONT +COLOR="#000000" +><PRE +CLASS="screen" +> <SAMP +CLASS="prompt" +>mysql></SAMP +> SET PASSWORD FOR + <SAMP +CLASS="prompt" +> -></SAMP +> ' some_user '@' some_host ' = OLD_PASSWORD(' newpwd '); + </PRE +></FONT +></TD +></TR +></TABLE +> + </P +></LI +></UL +> + + </P +><P +> </P ></DIV ></DIV ><DIV @@ -2922,7 +3092,7 @@ CLASS="answer" ><P > Microsoft has some advice on this matter, as well: <A -NAME="AEN3115" +NAME="AEN3284" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -3009,7 +3179,7 @@ CLASS="command" ></LI ></OL > - I reckon TimeDate and Data::Dumper come with the activeperl. + I reckon TimeDate comes with the activeperl. You can check the ActiveState site for packages for installation through PPM. <A HREF="http://www.activestate.com/Packages/" @@ -3168,7 +3338,7 @@ BORDER="0" ><TR ><TD > <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=35195" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=35195" TARGET="_top" >Bug 35195</A > @@ -3178,13 +3348,13 @@ CLASS="QUOTE" > checkbox to the UI. It has two patches attached to it: <A -HREF="http://bugzilla.mozilla.org/showattachment.cgi?attach_id=8029" +HREF="https://bugzilla.mozilla.org/showattachment.cgi?attach_id=8029" TARGET="_top" >attachment 8029</A > was originally created for Bugzilla 2.12, while <A -HREF="http://bugzilla.mozilla.org/showattachment.cgi?attach_id=91372" +HREF="https://bugzilla.mozilla.org/showattachment.cgi?attach_id=91372" TARGET="_top" >attachment 91372</A > @@ -3194,7 +3364,7 @@ TARGET="_top" ><TR ><TD > <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=37613" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=37613" TARGET="_top" >Bug 37613</A @@ -3417,20 +3587,20 @@ CLASS="answer" > </B > Try <A -HREF="http://bugzilla.mozilla.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=Bugzilla" +HREF="https://bugzilla.mozilla.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=Bugzilla" TARGET="_top" > this link</A > to view current bugs or requests for enhancement for Bugzilla. </P ><P -> You can view bugs marked for 3.0 release +> You can view bugs marked for 3.2 release <A -HREF="http://bugzilla.mozilla.org/buglist.cgi?product=Bugzilla&target_milestone=Bugzilla+&bz-nextver;" +HREF="https://bugzilla.mozilla.org/buglist.cgi?product=Bugzilla&target_milestone=Bugzilla+&bz-nextver;" TARGET="_top" >here</A >. - This list includes bugs for the 3.0 release that have already + This list includes bugs for the 3.2 release that have already been fixed and checked into CVS. Please consult the <A HREF="http://www.bugzilla.org/" @@ -3471,7 +3641,7 @@ CLASS="answer" > </B > This is well-documented in <A -HREF="http://bugzilla.mozilla.org/show_bug.cgi?id=49862" +HREF="https://bugzilla.mozilla.org/show_bug.cgi?id=49862" TARGET="_top" >bug 49862</A @@ -3518,7 +3688,7 @@ TYPE="1" > Enter a bug into bugzilla.mozilla.org for the <SPAN CLASS="QUOTE" >"<A -HREF="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla" +HREF="https://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla" TARGET="_top" >Bugzilla</A >"</SPAN @@ -3552,7 +3722,7 @@ CLASS="QUOTE" ><LI ><P > Announce your patch and the associated URL - (http://bugzilla.mozilla.org/show_bug.cgi?id=XXXXXX) + (https://bugzilla.mozilla.org/show_bug.cgi?id=XXXXXX) for discussion in the newsgroup (mozilla.support.bugzilla). You'll get a really good, fairly immediate reaction to the diff --git a/docs/html/flags-overview.html b/docs/html/flags-overview.html index e932f1cb4..c07a819c0 100644 --- a/docs/html/flags-overview.html +++ b/docs/html/flags-overview.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Administering Bugzilla" @@ -17,8 +16,8 @@ REL="PREVIOUS" TITLE="Milestones" HREF="milestones.html"><LINK REL="NEXT" -TITLE="Legal Values" -HREF="edit-values.html"></HEAD +TITLE="Custom Fields" +HREF="custom-fields.html"></HEAD ><BODY CLASS="section" BGCOLOR="#FFFFFF" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -61,7 +59,7 @@ WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A -HREF="edit-values.html" +HREF="custom-fields.html" ACCESSKEY="N" >Next</A ></TD @@ -951,7 +949,7 @@ WIDTH="33%" ALIGN="right" VALIGN="top" ><A -HREF="edit-values.html" +HREF="custom-fields.html" ACCESSKEY="N" >Next</A ></TD @@ -975,7 +973,7 @@ ACCESSKEY="U" WIDTH="33%" ALIGN="right" VALIGN="top" ->Legal Values</TD +>Custom Fields</TD ></TR ></TABLE ></DIV diff --git a/docs/html/flags.html b/docs/html/flags.html index ba8f0532a..c0eac0934 100644 --- a/docs/html/flags.html +++ b/docs/html/flags.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Using Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/general-advice.html b/docs/html/general-advice.html index 850e10b74..a98de2e7f 100644 --- a/docs/html/general-advice.html +++ b/docs/html/general-advice.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Troubleshooting" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/gfdl-0.html b/docs/html/gfdl-0.html index e10bca88d..85489562f 100644 --- a/docs/html/gfdl-0.html +++ b/docs/html/gfdl-0.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="GNU Free Documentation License" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/gfdl-1.html b/docs/html/gfdl-1.html index ba7571bd6..431b1bf0e 100644 --- a/docs/html/gfdl-1.html +++ b/docs/html/gfdl-1.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="GNU Free Documentation License" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/gfdl-10.html b/docs/html/gfdl-10.html index 385e8664f..791d71c02 100644 --- a/docs/html/gfdl-10.html +++ b/docs/html/gfdl-10.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="GNU Free Documentation License" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/gfdl-2.html b/docs/html/gfdl-2.html index 60d047dfa..e273f82ab 100644 --- a/docs/html/gfdl-2.html +++ b/docs/html/gfdl-2.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="GNU Free Documentation License" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/gfdl-3.html b/docs/html/gfdl-3.html index 5a34f2845..53a23ed07 100644 --- a/docs/html/gfdl-3.html +++ b/docs/html/gfdl-3.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="GNU Free Documentation License" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/gfdl-4.html b/docs/html/gfdl-4.html index c16d86939..862ad55ad 100644 --- a/docs/html/gfdl-4.html +++ b/docs/html/gfdl-4.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="GNU Free Documentation License" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/gfdl-5.html b/docs/html/gfdl-5.html index b256df0fa..750b25374 100644 --- a/docs/html/gfdl-5.html +++ b/docs/html/gfdl-5.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="GNU Free Documentation License" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/gfdl-6.html b/docs/html/gfdl-6.html index 94b33e187..ca2e7818b 100644 --- a/docs/html/gfdl-6.html +++ b/docs/html/gfdl-6.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="GNU Free Documentation License" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/gfdl-7.html b/docs/html/gfdl-7.html index d470ff615..a41e12cc1 100644 --- a/docs/html/gfdl-7.html +++ b/docs/html/gfdl-7.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="GNU Free Documentation License" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/gfdl-8.html b/docs/html/gfdl-8.html index b9040d884..4aefba342 100644 --- a/docs/html/gfdl-8.html +++ b/docs/html/gfdl-8.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="GNU Free Documentation License" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/gfdl-9.html b/docs/html/gfdl-9.html index ce2a1d54f..20b7f9f7d 100644 --- a/docs/html/gfdl-9.html +++ b/docs/html/gfdl-9.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="GNU Free Documentation License" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/gfdl-howto.html b/docs/html/gfdl-howto.html index 65c5560fd..eb3e8ca5d 100644 --- a/docs/html/gfdl-howto.html +++ b/docs/html/gfdl-howto.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="GNU Free Documentation License" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -83,7 +81,7 @@ NAME="gfdl-howto" of the License in the document and put the following copyright and license notices just after the title page:</P ><A -NAME="AEN3616" +NAME="AEN3759" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" diff --git a/docs/html/gfdl.html b/docs/html/gfdl.html index 51c3d037a..eb67ad525 100644 --- a/docs/html/gfdl.html +++ b/docs/html/gfdl.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="PREVIOUS" TITLE="Optional Modules" @@ -35,8 +34,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -146,7 +144,7 @@ HREF="gfdl-howto.html" ><P >Version 1.1, March 2000</P ><A -NAME="AEN3526" +NAME="AEN3669" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" diff --git a/docs/html/glossary.html b/docs/html/glossary.html index 4eec65b92..907d4a56d 100644 --- a/docs/html/glossary.html +++ b/docs/html/glossary.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="PREVIOUS" TITLE="How to use this License for your documents" @@ -32,8 +31,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -72,7 +70,7 @@ CLASS="glossdiv" ><H1 CLASS="glossdiv" ><A -NAME="AEN3621" +NAME="AEN3764" >0-9, high ascii</A ></H1 ><DL @@ -578,11 +576,11 @@ NAME="gloss-mta" ></DT > (MTA)<DD ><P ->A Message Transport Agent is used to control the flow of email - on a system. The <A -HREF="http://search.cpan.org/dist/MailTools/Mail/Mailer.pm" +>A Message Transport Agent is used to control the flow of email on a system. + The <A +HREF="http://search.cpan.org/dist/Email-Send/lib/Email/Send.pm" TARGET="_top" ->Mail::Mailer</A +>Email::Send</A > Perl module, which Bugzilla uses to send email, can be configured to use many different underlying implementations for actually sending the @@ -990,7 +988,7 @@ NAME="gloss-zarro" Terry had the following to say: </P ><A -NAME="AEN3868" +NAME="AEN4011" ></A ><TABLE BORDER="0" diff --git a/docs/html/groups.html b/docs/html/groups.html index cb170afd6..cf1c6bc2f 100644 --- a/docs/html/groups.html +++ b/docs/html/groups.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Administering Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -76,7 +74,7 @@ CLASS="section" CLASS="section" ><A NAME="groups" ->3.12. Groups and Group Security</A +>3.13. Groups and Group Security</A ></H1 ><P >Groups allow the administrator @@ -150,8 +148,8 @@ CLASS="section" ><H2 CLASS="section" ><A -NAME="AEN1545" ->3.12.1. Creating Groups</A +NAME="AEN1660" +>3.13.1. Creating Groups</A ></H2 ><P >To create Groups:</P @@ -288,8 +286,8 @@ CLASS="section" ><H2 CLASS="section" ><A -NAME="AEN1572" ->3.12.2. Assigning Users to Groups</A +NAME="AEN1687" +>3.13.2. Assigning Users to Groups</A ></H2 ><P >Users can become a member of a group in several ways.</P @@ -320,8 +318,8 @@ CLASS="section" ><H2 CLASS="section" ><A -NAME="AEN1582" ->3.12.3. Assigning Group Controls to Products</A +NAME="AEN1697" +>3.13.3. Assigning Group Controls to Products</A ></H2 ><P > On the product edit page, there is a page to edit the @@ -412,16 +410,16 @@ CLASS="section" ><H2 CLASS="section" ><A -NAME="AEN1600" ->3.12.4. Common Applications of Group Controls</A +NAME="AEN1715" +>3.13.4. Common Applications of Group Controls</A ></H2 ><DIV CLASS="section" ><H3 CLASS="section" ><A -NAME="AEN1602" ->3.12.4.1. General User Access With Security Group</A +NAME="AEN1717" +>3.13.4.1. General User Access With Security Group</A ></H3 ><P >To permit any user to file bugs in each product (A, B, C...) @@ -455,8 +453,8 @@ CLASS="section" ><H3 CLASS="section" ><A -NAME="AEN1606" ->3.12.4.2. General User Access With A Security Product</A +NAME="AEN1721" +>3.13.4.2. General User Access With A Security Product</A ></H3 ><P >To permit any user to file bugs in a Security product @@ -487,8 +485,8 @@ CLASS="section" ><H3 CLASS="section" ><A -NAME="AEN1610" ->3.12.4.3. Product Isolation With Common Group</A +NAME="AEN1725" +>3.13.4.3. Product Isolation With Common Group</A ></H3 ><P >To permit users of product A to access the bugs for diff --git a/docs/html/hintsandtips.html b/docs/html/hintsandtips.html index b56df4c16..9854670f3 100644 --- a/docs/html/hintsandtips.html +++ b/docs/html/hintsandtips.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Using Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -86,7 +84,7 @@ CLASS="section" ><H2 CLASS="section" ><A -NAME="AEN2234" +NAME="AEN2372" >5.8.1. Autolinkification</A ></H2 ><P diff --git a/docs/html/index.html b/docs/html/index.html index d7c06a560..fd6df2602 100644 --- a/docs/html/index.html +++ b/docs/html/index.html @@ -2,8 +2,7 @@ <HTML ><HEAD ><TITLE ->The Bugzilla Guide - 2.22.3 - Release</TITLE +>The Bugzilla Guide - 3.0 Release</TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK @@ -46,15 +45,14 @@ CLASS="TITLEPAGE" CLASS="title" ><A NAME="AEN2" ->The Bugzilla Guide - 2.22.3 - Release</A +>The Bugzilla Guide - 3.0 Release</A ></H1 ><H3 CLASS="corpauthor" >The Bugzilla Team</H3 ><P CLASS="pubdate" ->2007-08-23<BR></P +>2007-05-09<BR></P ><DIV ><DIV CLASS="abstract" @@ -73,7 +71,7 @@ NAME="AEN7" ><P > The most current version of this document can always be found on the <A -HREF="http://www.bugzilla.org/documentation.html" +HREF="http://www.bugzilla.org/docs/" TARGET="_top" >Bugzilla Documentation Page</A @@ -149,7 +147,7 @@ HREF="extraconfig.html" ></DT ><DT >2.4. <A -HREF="x763.html" +HREF="x834.html" >Multiple Bugzilla databases with a single installation</A ></DT ><DT @@ -213,26 +211,31 @@ HREF="flags-overview.html" ></DT ><DT >3.9. <A +HREF="custom-fields.html" +>Custom Fields</A +></DT +><DT +>3.10. <A HREF="edit-values.html" >Legal Values</A ></DT ><DT ->3.10. <A +>3.11. <A HREF="voting.html" >Voting</A ></DT ><DT ->3.11. <A +>3.12. <A HREF="quips.html" >Quips</A ></DT ><DT ->3.12. <A +>3.13. <A HREF="groups.html" >Groups and Group Security</A ></DT ><DT ->3.13. <A +>3.14. <A HREF="upgrading.html" >Upgrading to New Releases</A ></DT @@ -344,29 +347,29 @@ HREF="whining.html" ><DT >6. <A HREF="customization.html" ->Customizing Bugzilla</A +>Customising Bugzilla</A ></DT ><DD ><DL ><DT >6.1. <A -HREF="cust-templates.html" ->Template Customization</A +HREF="cust-skins.html" +>Custom Skins</A ></DT ><DT >6.2. <A -HREF="cust-hooks.html" ->Template Hooks</A +HREF="cust-templates.html" +>Template Customization</A ></DT ><DT >6.3. <A -HREF="cust-change-permissions.html" ->Customizing Who Can Change What</A +HREF="cust-hooks.html" +>The Bugzilla Extension Mechanism</A ></DT ><DT >6.4. <A -HREF="dbmodify.html" ->Modifying Your Running System</A +HREF="cust-change-permissions.html" +>Customizing Who Can Change What</A ></DT ><DT >6.5. <A @@ -418,21 +421,16 @@ HREF="paranoid-security.html" ></DT ><DT >B.6. <A -HREF="trouble-filetemp.html" ->Your vendor has not defined Fcntl macro O_NOINHERIT</A -></DT -><DT ->B.7. <A HREF="trbl-relogin-everyone.html" >Everybody is constantly being forced to relogin</A ></DT ><DT ->B.8. <A +>B.7. <A HREF="trbl-relogin-some.html" >Some users are constantly being forced to relogin</A ></DT ><DT ->B.9. <A +>B.8. <A HREF="trbl-index.html" ><TT CLASS="filename" @@ -440,7 +438,7 @@ CLASS="filename" > doesn't show up unless specified in the URL</A ></DT ><DT ->B.10. <A +>B.9. <A HREF="trbl-passwd-encryption.html" >checksetup.pl reports "Client does not support authentication protocol requested by server..."</A diff --git a/docs/html/install-perlmodules-manual.html b/docs/html/install-perlmodules-manual.html index 5bf17dd06..7f935a1a9 100644 --- a/docs/html/install-perlmodules-manual.html +++ b/docs/html/install-perlmodules-manual.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="PREVIOUS" TITLE="Command-line 'Send Unsent Bug-mail' tool" @@ -35,8 +34,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/installation.html b/docs/html/installation.html index 175d01b32..1da267e6f 100644 --- a/docs/html/installation.html +++ b/docs/html/installation.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Installing Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -184,7 +182,7 @@ TYPE="1" HREF="installation.html#install-perl" >Install Perl</A > - (5.6.1 or above for non-Windows platforms; 5.8.1 + (5.8.0 or above for non-Windows platforms; 5.8.1 for Windows) </P ></LI @@ -257,7 +255,7 @@ HREF="http://www.perl.com" TARGET="_top" >http://www.perl.com</A >. - Although Bugzilla runs with Perl 5.6.1, + Although Bugzilla runs with Perl 5.8.0, it's a good idea to be using the latest stable version. </P ></DIV @@ -293,7 +291,7 @@ HREF="http://www.mysql.com" TARGET="_top" >http://www.mysql.com</A >. You need MySQL version - 4.0.14 or higher. + 4.1.2 or higher. </P ><DIV CLASS="note" @@ -360,7 +358,7 @@ HREF="http://www.postgresql.org/" TARGET="_top" >http://www.postgresql.org/</A >. You need PostgreSQL - version 7.3.x or higher. + version 8.00.0000 or higher. </P ><P >If you install from something other than a packaging/installation @@ -396,7 +394,7 @@ CLASS="glossterm" the installation instructions usually assume you are using it. If you have got Bugzilla working using another webserver, please share your experiences with us by filing a bug in <A -HREF="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=Documentation" +HREF="https://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=Documentation" TARGET="_top" >Bugzilla Documentation</A >. @@ -613,7 +611,7 @@ VALIGN="TOP" <SPAN CLASS="QUOTE" >"@INC"</SPAN ->. +>. Virtually every time, this error is due to permissions being set too restrictively for you to compile Perl modules or not having the necessary Perl development libraries installed on your system. @@ -673,17 +671,7 @@ CLASS="filename" TYPE="1" ><LI ><P -> AppConfig (1.52) - </P -></LI -><LI -><P -> CGI (2.93) - </P -></LI -><LI -><P -> Data::Dumper (any) +> CGI 2.93 or CGI 3.11 if using mod_perl </P ></LI ><LI @@ -693,7 +681,7 @@ TYPE="1" ></LI ><LI ><P -> DBI (1.38) +> DBI (1.41) </P ></LI ><LI @@ -707,7 +695,7 @@ HREF="installation.html#install-modules-dbd-mysql" ></LI ><LI ><P -> DBD::Pg (1.31) if using PostgreSQL +> DBD::Pg (1.45) if using PostgreSQL </P ></LI ><LI @@ -717,41 +705,21 @@ HREF="installation.html#install-modules-dbd-mysql" ></LI ><LI ><P -> File::Temp (any) - </P -></LI -><LI -><P > <A HREF="installation.html#install-modules-template" >Template</A > - (2.10) - </P -></LI -><LI -><P -> Text::Wrap (2001.0131) - </P -></LI -><LI -><P -> Mail::Mailer (1.67) - </P -></LI -><LI -><P -> MIME::Base64 (3.01) + (2.12) </P ></LI ><LI ><P -> MIME::Parser (5.406) +> Email::Send (2.00) </P ></LI ><LI ><P -> Storable (any) +> Email::MIME::Modifier (any) </P ></LI ></OL @@ -773,6 +741,12 @@ HREF="installation.html#install-modules-gd" ></LI ><LI ><P +> Template::Plugin::GD::Image + (1.20) for Graphical Reports + </P +></LI +><LI +><P > <A HREF="installation.html#install-modules-chart-base" >Chart::Base</A @@ -792,8 +766,8 @@ HREF="installation.html#install-modules-gd-graph" ><LI ><P > <A -HREF="installation.html#install-modules-gd-text-align" ->GD::Text::Align</A +HREF="installation.html#install-modules-gd-text" +>GD::Text</A > (any) for bug charting </P @@ -804,7 +778,18 @@ HREF="installation.html#install-modules-gd-text-align" HREF="installation.html#install-modules-xml-twig" >XML::Twig</A > - (any) for the XML interface + (any) for bug import/export + </P +></LI +><LI +><P +> MIME::Parser (5.406) for bug import/export + </P +></LI +><LI +><P +> LWP::UserAgent + (any) for Automatic Update Notifications </P ></LI ><LI @@ -821,8 +806,65 @@ HREF="installation.html#install-modules-patchreader" > Image::Magick (any) for converting BMP image attachments to PNG </P ></LI +><LI +><P +> Net::LDAP + (any) for LDAP Authentication + </P +></LI +><LI +><P +> <A +HREF="installation.html#install-modules-soap-lite" +>SOAP::Lite</A +> + (any) for the web service interface + </P +></LI +><LI +><P +> HTML::Parser + (3.40) for More HTML in Product/Group Descriptions + </P +></LI +><LI +><P +> HTML::Scrubber + (any) for More HTML in Product/Group Descriptions + </P +></LI +><LI +><P +> Email::MIME::Attachment::Stripper + (any) for Inbound Email + </P +></LI +><LI +><P +> Email::Reply + (any) for Inbound Email + </P +></LI +><LI +><P +> mod_perl2 + (1.999022) for mod_perl + </P +></LI +><LI +><P +> CGI + (2.93) for mod_perl + </P +></LI +><LI +><P +> Apache::DBI + (0.96) for mod_perl2 + </P +></LI ></OL -> +> </P ><DIV CLASS="section" @@ -852,7 +894,7 @@ CLASS="section" CLASS="section" ><A NAME="install-modules-template" ->2.1.5.2. Template Toolkit (2.10)</A +>2.1.5.2. Template Toolkit (2.12)</A ></H3 ><P >When you install Template Toolkit, you'll get asked various @@ -980,11 +1022,11 @@ CLASS="section" ><H3 CLASS="section" ><A -NAME="install-modules-gd-text-align" ->2.1.5.6. GD::Text::Align (any)</A +NAME="install-modules-gd-text" +>2.1.5.6. GD::Text (any)</A ></H3 ><P ->The GD::Text::Align module is only required if you want graphical +>The GD::Text module is only required if you want graphical reports. </P ></DIV @@ -1011,8 +1053,22 @@ CLASS="section" ><H3 CLASS="section" ><A +NAME="install-modules-soap-lite" +>2.1.5.8. SOAP::Lite (any)</A +></H3 +><P +>Installing SOAP::Lite enables your Bugzilla installation to be + accessible at a standardized Web Service interface (SOAP/XML-RPC) + by third-party applications via HTTP(S). + </P +></DIV +><DIV +CLASS="section" +><H3 +CLASS="section" +><A NAME="install-modules-patchreader" ->2.1.5.8. PatchReader (0.9.4)</A +>2.1.5.9. PatchReader (0.9.4)</A ></H3 ><P >The PatchReader module is only required if you want to use @@ -1102,6 +1158,49 @@ HREF="parameters.html" succeeds, then Bugzilla should also be fine. </P ></DIV +><DIV +CLASS="section" +><H2 +CLASS="section" +><A +NAME="using-mod_perl-with-bugzilla" +>2.1.7. Installing Bugzilla on mod_perl</A +></H2 +><P +>It is now possible to run the Bugzilla software under <VAR +CLASS="literal" +>mod_perl</VAR +> on + Apache. <VAR +CLASS="literal" +>mod_perl</VAR +> has some additional requirements to that of running + Bugzilla under <VAR +CLASS="literal" +>mod_cgi</VAR +> (the standard and previous way).</P +><P +>Bugzilla requires <VAR +CLASS="literal" +>mod_perl</VAR +> to be installed, which can be + obtained from <A +HREF="http://perl.apache.org" +TARGET="_top" +>http://perl.apache.org</A +> - Bugzilla requires + version 1.999022 (AKA 2.0.0-RC5) to be installed.</P +><P +>Bugzilla also requires a more up-to-date version of the CGI + perl module to be installed, version 3.11 as opposed to 2.93 + </P +><P +>Finally, Bugzilla also requires <VAR +CLASS="literal" +>Apache::DBI</VAR +> + (0.96) to be installed as well.</P +></DIV ></DIV ><DIV CLASS="NAVFOOTER" diff --git a/docs/html/installing-bugzilla.html b/docs/html/installing-bugzilla.html index 817d56e79..1ecfc448b 100644 --- a/docs/html/installing-bugzilla.html +++ b/docs/html/installing-bugzilla.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="PREVIOUS" TITLE="Document Conventions" @@ -35,8 +34,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -118,6 +116,11 @@ HREF="installation.html#install-perlmodules" HREF="installation.html#install-MTA" >Mail Transfer Agent (MTA)</A ></DT +><DT +>2.1.7. <A +HREF="installation.html#using-mod_perl-with-bugzilla" +>Installing Bugzilla on mod_perl</A +></DT ></DL ></DD ><DT @@ -139,7 +142,7 @@ HREF="configuration.html#database-engine" ></DT ><DT >2.2.3. <A -HREF="configuration.html#AEN529" +HREF="configuration.html#AEN546" >checksetup.pl</A ></DT ><DT @@ -163,12 +166,12 @@ HREF="extraconfig.html" ><DL ><DT >2.3.1. <A -HREF="extraconfig.html#AEN630" +HREF="extraconfig.html#AEN696" >Bug Graphs</A ></DT ><DT >2.3.2. <A -HREF="extraconfig.html#AEN649" +HREF="extraconfig.html#AEN715" >Dependency Charts</A ></DT ><DT @@ -200,7 +203,7 @@ HREF="extraconfig.html#apache-addtype" ></DD ><DT >2.4. <A -HREF="x763.html" +HREF="x834.html" >Multiple Bugzilla databases with a single installation</A ></DT ><DT @@ -239,17 +242,17 @@ HREF="nonroot.html" ><DL ><DT >2.6.1. <A -HREF="nonroot.html#AEN885" +HREF="nonroot.html#AEN956" >Introduction</A ></DT ><DT >2.6.2. <A -HREF="nonroot.html#AEN889" +HREF="nonroot.html#AEN960" >MySQL</A ></DT ><DT >2.6.3. <A -HREF="nonroot.html#AEN924" +HREF="nonroot.html#AEN995" >Perl</A ></DT ><DT @@ -259,12 +262,12 @@ HREF="nonroot.html#install-perlmodules-nonroot" ></DT ><DT >2.6.5. <A -HREF="nonroot.html#AEN989" +HREF="nonroot.html#AEN1060" >HTTP Server</A ></DT ><DT >2.6.6. <A -HREF="nonroot.html#AEN1001" +HREF="nonroot.html#AEN1072" >Bugzilla</A ></DT ></DL diff --git a/docs/html/integration.html b/docs/html/integration.html index 4c2f98d15..e39aa4023 100644 --- a/docs/html/integration.html +++ b/docs/html/integration.html @@ -7,15 +7,14 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" -TITLE="Customizing Bugzilla" +TITLE="Customising Bugzilla" HREF="customization.html"><LINK REL="PREVIOUS" -TITLE="Modifying Your Running System" -HREF="dbmodify.html"><LINK +TITLE="Customizing Who Can Change What" +HREF="cust-change-permissions.html"><LINK REL="NEXT" TITLE="The Bugzilla FAQ" HREF="faq.html"></HEAD @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -47,7 +45,7 @@ WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A -HREF="dbmodify.html" +HREF="cust-change-permissions.html" ACCESSKEY="P" >Prev</A ></TD @@ -55,7 +53,7 @@ ACCESSKEY="P" WIDTH="80%" ALIGN="center" VALIGN="bottom" ->Chapter 6. Customizing Bugzilla</TD +>Chapter 6. Customising Bugzilla</TD ><TD WIDTH="10%" ALIGN="right" @@ -249,7 +247,7 @@ WIDTH="33%" ALIGN="left" VALIGN="top" ><A -HREF="dbmodify.html" +HREF="cust-change-permissions.html" ACCESSKEY="P" >Prev</A ></TD @@ -277,7 +275,7 @@ ACCESSKEY="N" WIDTH="33%" ALIGN="left" VALIGN="top" ->Modifying Your Running System</TD +>Customizing Who Can Change What</TD ><TD WIDTH="34%" ALIGN="center" diff --git a/docs/html/lifecycle.html b/docs/html/lifecycle.html index 7a1039f4c..080f4c49c 100644 --- a/docs/html/lifecycle.html +++ b/docs/html/lifecycle.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Using Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/milestones.html b/docs/html/milestones.html index 3a5add646..47b83af26 100644 --- a/docs/html/milestones.html +++ b/docs/html/milestones.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Administering Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/modules-manual-download.html b/docs/html/modules-manual-download.html index d9a9e4c29..5ae65dde3 100644 --- a/docs/html/modules-manual-download.html +++ b/docs/html/modules-manual-download.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Manual Installation of Perl Modules" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -109,29 +107,6 @@ VALIGN="TOP" ></TABLE ></DIV ><P -> AppConfig: - <P -CLASS="literallayout" -><br> - CPAN Download Page: <A -HREF="http://search.cpan.org/src/ABW/AppConfig-1.56/lib/AppConfig.pm" -TARGET="_top" ->http://search.cpan.org/src/ABW/AppConfig-1.56/lib/AppConfig.pm</A -><br> - PPM Download Link: <A -HREF="http://landfill.bugzilla.org/ppm/AppConfig.ppd" -TARGET="_top" ->http://landfill.bugzilla.org/ppm/AppConfig.ppd</A -><br> - Documentation: <A -HREF="http://search.cpan.org/~abw/AppConfig-1.56/lib/AppConfig.pm" -TARGET="_top" ->http://search.cpan.org/~abw/AppConfig-1.56/lib/AppConfig.pm</A -><br> - </P -> - </P -><P > CGI: <P CLASS="literallayout" @@ -281,25 +256,6 @@ TARGET="_top" > </P ><P -> File::Temp: - <P -CLASS="literallayout" -><br> - CPAN Download Page: <A -HREF="http://search.cpan.org/dist/File-Temp/" -TARGET="_top" ->http://search.cpan.org/dist/File-Temp/</A -><br> - PPM Download Page: Part of core distribution.<br> - Documentation: <A -HREF="http://www.perldoc.com/perl5.8.0/lib/File/Temp.html" -TARGET="_top" ->http://www.perldoc.com/perl5.8.0/lib/File/Temp.html</A -><br> - </P -> - </P -><P > Template-Toolkit: <P CLASS="literallayout" @@ -323,25 +279,6 @@ TARGET="_top" > </P ><P -> Text::Wrap: - <P -CLASS="literallayout" -><br> - CPAN Download Page: <A -HREF="http://search.cpan.org/dist/Text-Tabs+Wrap/" -TARGET="_top" ->http://search.cpan.org/dist/Text-Tabs+Wrap/</A -><br> - PPM Download Link: Part of core distribution.<br> - Documentation: <A -HREF="http://www.perldoc.com/perl5.8.0/lib/Text/Wrap.html" -TARGET="_top" ->http://www.perldoc.com/perl5.8.0/lib/Text/Wrap.html</A -><br> - </P -> - </P -><P > GD: <P CLASS="literallayout" @@ -384,29 +321,6 @@ TARGET="_top" > </P ><P -> MIME::Base64: - <P -CLASS="literallayout" -><br> - CPAN Download Page: <A -HREF="http://search.cpan.org/dist/MIME-Base64/" -TARGET="_top" ->http://search.cpan.org/dist/MIME-Base64/</A -><br> - PPM Download Link: <A -HREF="http://ppm.activestate.com/PPMPackages/zips/8xx-builds-only/Windows/MIME-Base64-2.20.zip" -TARGET="_top" ->http://ppm.activestate.com/PPMPackages/zips/8xx-builds-only/Windows/MIME-Base64-2.20.zip</A -><br> - Documentation: <A -HREF="http://search.cpan.org/dist/MIME-Base64/Base64.pm" -TARGET="_top" ->http://search.cpan.org/dist/MIME-Base64/Base64.pm</A -><br> - </P -> - </P -><P > MIME::Parser (part of MIME-tools): <P CLASS="literallayout" diff --git a/docs/html/modules-manual-instructions.html b/docs/html/modules-manual-instructions.html index 8fd8c899c..dec9ce176 100644 --- a/docs/html/modules-manual-instructions.html +++ b/docs/html/modules-manual-instructions.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Manual Installation of Perl Modules" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/modules-manual-optional.html b/docs/html/modules-manual-optional.html index 13e93e881..cc82ea361 100644 --- a/docs/html/modules-manual-optional.html +++ b/docs/html/modules-manual-optional.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Manual Installation of Perl Modules" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/myaccount.html b/docs/html/myaccount.html index 3d98c0a72..e0c7d7ada 100644 --- a/docs/html/myaccount.html +++ b/docs/html/myaccount.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Using Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -84,9 +82,9 @@ NAME="myaccount" Bugzilla for the URL you should use to access it. If you're test-driving Bugzilla, use this URL: <A -HREF="http://landfill.bugzilla.org/bugzilla-2.22-branch/" +HREF="http://landfill.bugzilla.org/bugzilla-tip/" TARGET="_top" ->http://landfill.bugzilla.org/bugzilla-2.22-branch/</A +>http://landfill.bugzilla.org/bugzilla-tip/</A >. </P ><P @@ -95,50 +93,134 @@ TARGET="_top" TYPE="1" ><LI ><P ->Click the - <SPAN +> On the home page <TT +CLASS="filename" +>index.cgi</TT +>, click the + <SPAN CLASS="QUOTE" >"Open a new Bugzilla account"</SPAN -> - - link, enter your email address and, optionally, your name in the - spaces provided, then click - <SPAN +> link, or the + <SPAN +CLASS="QUOTE" +>"New Account"</SPAN +> link available in the footer of pages. + Now enter your email address, then click the <SPAN CLASS="QUOTE" ->"Create Account"</SPAN +>"Send"</SPAN > - - .</P + button. + </P +><DIV +CLASS="note" +><P +></P +><TABLE +CLASS="note" +WIDTH="100%" +BORDER="0" +><TR +><TD +WIDTH="25" +ALIGN="CENTER" +VALIGN="TOP" +><IMG +SRC="../images/note.gif" +HSPACE="5" +ALT="Note"></TD +><TD +ALIGN="LEFT" +VALIGN="TOP" +><P +> If none of these links is available, this means that the + administrator of the installation has disabled self-registration. + This means that only an administrator can create accounts + for other users. One reason could be that this installation is + private. + </P +></TD +></TR +></TABLE +></DIV +><DIV +CLASS="note" +><P +></P +><TABLE +CLASS="note" +WIDTH="100%" +BORDER="0" +><TR +><TD +WIDTH="25" +ALIGN="CENTER" +VALIGN="TOP" +><IMG +SRC="../images/note.gif" +HSPACE="5" +ALT="Note"></TD +><TD +ALIGN="LEFT" +VALIGN="TOP" +><P +> Also, if only some users are allowed to create an account on + the installation, you may see these links but your registration + may fail if your email address doesn't match the ones accepted + by the installation. This is another way to restrict who can + access and edit bugs in this installation. + </P +></TD +></TR +></TABLE +></DIV ></LI ><LI ><P ->Within moments, you should receive an email to the address - you provided, which contains your login name (generally the - same as the email address), and a password. - This password is randomly generated, but can be - changed to something more memorable.</P +> Within moments, and if your registration is accepted, you should + receive an email to the address you provided, which contains your + login name (generally the same as the email address), and two URLs + with a token (a random string generated by the installation) to + confirm, respectively cancel, your registration. This is a way to + prevent users from abusing the generation of user accounts, for + instance by entering inexistent email addresses, or email addresses + which do not belong to them. + </P +></LI +><LI +><P +> By default, you have 3 days to confirm your registration. Past this + timeframe, the token is invalidated and the registration is + automatically canceled. You can also cancel this registration sooner + by using the appropriate URL in the email you got. + </P ></LI ><LI ><P ->Click the - <SPAN +> If you confirm your registration, Bugzilla will ask you your real name + (optional, but recommended) and your password, which must be between + 3 and 16 characters long. + </P +></LI +><LI +><P +> Now all you need to do is to click the <SPAN CLASS="QUOTE" >"Log In"</SPAN > - link in the footer at the bottom of the page in your browser, - enter your email address and password into the spaces provided, and - click - <SPAN + link in the footer at the bottom of the page in your browser, + enter your email address and password you just chose into the + login form, and click the <SPAN CLASS="QUOTE" ->"Login"</SPAN ->. +>"Log in"</SPAN +> button. </P ></LI ></OL ><P ->You are now logged in. Bugzilla uses cookies to remember you are - logged in so, unless you have cookies disabled or your IP address changes, - you should not have to log in again.</P +> You are now logged in. Bugzilla uses cookies to remember you are + logged in so, unless you have cookies disabled or your IP address changes, + you should not have to log in again during your session. + </P ></DIV ><DIV CLASS="NAVFOOTER" diff --git a/docs/html/newversions.html b/docs/html/newversions.html index a46b24c00..d171a7e79 100644 --- a/docs/html/newversions.html +++ b/docs/html/newversions.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="About This Guide" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -79,7 +77,7 @@ NAME="newversions" >1.3. New Versions</A ></H1 ><P -> This is the 2.22.3 version of The Bugzilla Guide. It is so named +> This is the 3.0 version of The Bugzilla Guide. It is so named to match the current version of Bugzilla. </P ><P @@ -123,7 +121,7 @@ TARGET="_top" </P ><P > - In addition, there are Bugzilla template localization projects in + In addition, there are Bugzilla template localisation projects in the following languages. They may have translated documentation available: <A @@ -157,7 +155,7 @@ TARGET="_top" >French</A >, <A -HREF="http://germzilla.ganderbay.net/" +HREF="http://germzilla.wurblzap.net/" TARGET="_top" >German</A >, diff --git a/docs/html/nonroot.html b/docs/html/nonroot.html index 0c0eba2fb..835867e58 100644 --- a/docs/html/nonroot.html +++ b/docs/html/nonroot.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Installing Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -83,7 +81,7 @@ CLASS="section" ><H2 CLASS="section" ><A -NAME="AEN885" +NAME="AEN956" >2.6.1. Introduction</A ></H2 ><P @@ -103,7 +101,7 @@ CLASS="section" ><H2 CLASS="section" ><A -NAME="AEN889" +NAME="AEN960" >2.6.2. MySQL</A ></H2 ><P @@ -159,7 +157,7 @@ CLASS="section" ><H3 CLASS="section" ><A -NAME="AEN897" +NAME="AEN968" >2.6.2.1. Running MySQL as Non-Root</A ></H3 ><DIV @@ -167,7 +165,7 @@ CLASS="section" ><H4 CLASS="section" ><A -NAME="AEN899" +NAME="AEN970" >2.6.2.1.1. The Custom Configuration Method</A ></H4 ><P @@ -211,7 +209,7 @@ CLASS="section" ><H4 CLASS="section" ><A -NAME="AEN903" +NAME="AEN974" >2.6.2.1.2. The Custom Built Method</A ></H4 ><P @@ -234,7 +232,7 @@ CLASS="section" ><H4 CLASS="section" ><A -NAME="AEN908" +NAME="AEN979" >2.6.2.1.3. Starting the Server</A ></H4 ><P @@ -362,7 +360,7 @@ CLASS="section" ><H2 CLASS="section" ><A -NAME="AEN924" +NAME="AEN995" >2.6.3. Perl</A ></H2 ><P @@ -455,7 +453,7 @@ CLASS="section" ><H3 CLASS="section" ><A -NAME="AEN943" +NAME="AEN1014" >2.6.4.1. The Independant Method</A ></H3 ><P @@ -527,7 +525,7 @@ CLASS="section" ><H3 CLASS="section" ><A -NAME="AEN956" +NAME="AEN1027" >2.6.4.2. The Mixed Method</A ></H3 ><P @@ -732,7 +730,7 @@ CLASS="section" ><H2 CLASS="section" ><A -NAME="AEN989" +NAME="AEN1060" >2.6.5. HTTP Server</A ></H2 ><P @@ -746,7 +744,7 @@ CLASS="section" ><H3 CLASS="section" ><A -NAME="AEN992" +NAME="AEN1063" >2.6.5.1. Running Apache as Non-Root</A ></H3 ><P @@ -828,7 +826,7 @@ CLASS="section" ><H2 CLASS="section" ><A -NAME="AEN1001" +NAME="AEN1072" >2.6.6. Bugzilla</A ></H2 ><P diff --git a/docs/html/os-specific.html b/docs/html/os-specific.html index 0e14c0fd5..7684f0304 100644 --- a/docs/html/os-specific.html +++ b/docs/html/os-specific.html @@ -7,15 +7,14 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Installing Bugzilla" HREF="installing-bugzilla.html"><LINK REL="PREVIOUS" TITLE="Multiple Bugzilla databases with a single installation" -HREF="x763.html"><LINK +HREF="x834.html"><LINK REL="NEXT" TITLE="UNIX (non-root) Installation Notes" HREF="nonroot.html"></HEAD @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -47,7 +45,7 @@ WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A -HREF="x763.html" +HREF="x834.html" ACCESSKEY="P" >Prev</A ></TD @@ -88,7 +86,7 @@ NAME="os-specific" ><P >If you have anything to add or notes for an operating system not covered, please file a bug in <A -HREF="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=Documentation" +HREF="https://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=Documentation" TARGET="_top" >Bugzilla Documentation</A >. @@ -710,7 +708,7 @@ WIDTH="33%" ALIGN="left" VALIGN="top" ><A -HREF="x763.html" +HREF="x834.html" ACCESSKEY="P" >Prev</A ></TD diff --git a/docs/html/parameters.html b/docs/html/parameters.html index 5ae815d64..f52802e24 100644 --- a/docs/html/parameters.html +++ b/docs/html/parameters.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Administering Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -255,20 +253,6 @@ CLASS="filename" ></DIV ></DD ><DT ->passwordmail</DT -><DD -><P -> Every time a user creates an account, the text of this parameter - (with substitutions) is sent to the new user along with their - password message. - </P -><P -> Add any text you wish to the "passwordmail" parameter box. For - instance, many people choose to use this box to give a quick - training blurb about how to use Bugzilla at your site. - </P -></DD -><DT >movebugs</DT ><DD ><P @@ -292,6 +276,17 @@ CLASS="filename" </P ></DD ><DT +>globalwatcher</DT +><DD +><P +> This allows to define specific users that will + receive notification each time a new bug in entered, or when + an existing bug changes, according to the normal groupset + permissions. It may be useful for sending notifications to a + mailing-list, for instance. + </P +></DD +><DT >usestatuswhiteboard</DT ><DD ><P diff --git a/docs/html/paranoid-security.html b/docs/html/paranoid-security.html index 29fbd40e8..0e0317d1d 100644 --- a/docs/html/paranoid-security.html +++ b/docs/html/paranoid-security.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Troubleshooting" @@ -17,8 +16,8 @@ REL="PREVIOUS" TITLE="DBD::Sponge::db prepare failed" HREF="trbl-dbdsponge.html"><LINK REL="NEXT" -TITLE="Your vendor has not defined Fcntl macro O_NOINHERIT" -HREF="trouble-filetemp.html"></HEAD +TITLE="Everybody is constantly being forced to relogin" +HREF="trbl-relogin-everyone.html"></HEAD ><BODY CLASS="section" BGCOLOR="#FFFFFF" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -61,7 +59,7 @@ WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A -HREF="trouble-filetemp.html" +HREF="trbl-relogin-everyone.html" ACCESSKEY="N" >Next</A ></TD @@ -163,7 +161,7 @@ WIDTH="33%" ALIGN="right" VALIGN="top" ><A -HREF="trouble-filetemp.html" +HREF="trbl-relogin-everyone.html" ACCESSKEY="N" >Next</A ></TD @@ -187,7 +185,7 @@ ACCESSKEY="U" WIDTH="33%" ALIGN="right" VALIGN="top" ->Your vendor has not defined Fcntl macro O_NOINHERIT</TD +>Everybody is constantly being forced to relogin</TD ></TR ></TABLE ></DIV diff --git a/docs/html/patches.html b/docs/html/patches.html index e5effb7d7..581dcd90f 100644 --- a/docs/html/patches.html +++ b/docs/html/patches.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="PREVIOUS" TITLE=' @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/products.html b/docs/html/products.html index 9dae4fbd6..b7ea3358e 100644 --- a/docs/html/products.html +++ b/docs/html/products.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Administering Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/query.html b/docs/html/query.html index 8c4923f5c..df0b541e2 100644 --- a/docs/html/query.html +++ b/docs/html/query.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Using Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -83,9 +81,9 @@ NAME="query" any bug report, comment, or patch currently in the Bugzilla system. You can play with it here: <A -HREF="http://landfill.bugzilla.org/bugzilla-2.22-branch/query.cgi" +HREF="http://landfill.bugzilla.org/bugzilla-tip/query.cgi" TARGET="_top" ->http://landfill.bugzilla.org/bugzilla-2.22-branch/query.cgi</A +>http://landfill.bugzilla.org/bugzilla-tip/query.cgi</A >.</P ><P >The Search page has controls for selecting different possible @@ -94,8 +92,22 @@ TARGET="_top" returns bugs where the content of the field matches any one of the selected values. If none is selected, then the field can take any value.</P ><P ->Once you've run a search, you can save it as a Saved Search, which - appears in the page footer.</P +> Once you've run a search, you can save it as a Saved Search, which + appears in the page footer. + On the Saved Searches tab of your User Preferences page (the Prefs link + in Bugzilla's footer), members of the group defined in the + querysharegroup parameter can share such Saved Searches with user groups + so that other users may use them. + At the same place, you can see Saved Searches other users are sharing, and + have them show up in your personal Bugzilla footer along with your own + Saved Searches. + If somebody is sharing a Search with a group she or he is allowed to + <A +HREF="groups.html" +>assign users to</A +>, it will show up in the + group's direct members' footers by default. + </P ><DIV CLASS="section" ><H2 @@ -192,7 +204,7 @@ NAME="negation" > At first glance, negation seems redundant. Rather than searching for <A -NAME="AEN2088" +NAME="AEN2222" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -203,7 +215,7 @@ CLASS="BLOCKQUOTE" > one could search for <A -NAME="AEN2090" +NAME="AEN2224" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -214,7 +226,7 @@ CLASS="BLOCKQUOTE" > However, the search <A -NAME="AEN2092" +NAME="AEN2226" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -226,7 +238,7 @@ CLASS="BLOCKQUOTE" would find every bug where anyone on the CC list did not contain "@mozilla.org" while <A -NAME="AEN2094" +NAME="AEN2228" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -240,7 +252,7 @@ CLASS="BLOCKQUOTE" complex expressions to be built using terms OR'd together and then negated. Negation permits queries such as <A -NAME="AEN2096" +NAME="AEN2230" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -253,7 +265,7 @@ CLASS="BLOCKQUOTE" to find bugs that are neither in the update product or in the documentation component or <A -NAME="AEN2098" +NAME="AEN2232" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -281,7 +293,7 @@ NAME="multiplecharts" a bug that has two different people cc'd on it, then you need to use two boolean charts. A search for <A -NAME="AEN2103" +NAME="AEN2237" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -296,7 +308,7 @@ CLASS="BLOCKQUOTE" containing "foo@" and someone else containing "@mozilla.org", then you would need two boolean charts. <A -NAME="AEN2105" +NAME="AEN2239" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -485,46 +497,46 @@ CLASS="section" CLASS="section" ><A NAME="individual-buglists" ->5.5.4. Adding individual bugs from bug lists</A +>5.5.4. Adding/removing tags to/from bugs</A ></H2 ><P -> You can at any time add individual bugs to a special type - of saved searches, known as <SPAN +> You can add and remove tags from individual bugs, which let you find and + manage them more easily. Creating a new tag automatically generates a saved + search - whose name is the name of the tag - which lists bugs with this tag. + This saved search will be displayed in the footer of pages by default, as + all other saved searches. The main difference between tags and normal saved + searches is that saved searches, as described in the previous section, are + stored in the form of a list of matching criteria, while the saved search + generated by tags is a list of bug numbers. Consequently, you can easily + edit this list by either adding or removing tags from bugs. To enable this + feature, you have to turn on the <SPAN CLASS="QUOTE" ->"lists of bugs"</SPAN ->. The distinction - between both types is that saved searches, as described in the previous - section, are stored in the form of a list of matching criteria, while - a list of bugs is an enumerated list of bug numbers. As it is a simple - list of bug numbers, you can easily edit this list by adding - bugs to it. To enable this feature, you have to turn on the - <SPAN -CLASS="QUOTE" ->"Add individual bugs to saved searches"</SPAN -> user preference, - see <A +>"Enable tags for bugs"</SPAN +> user + preference, see <A HREF="userpreferences.html" >Section 5.10</A ->. +>. This feature is disabled + by default. </P ><P > This feature is useful when you want to keep track of several bugs, but for different reasons. Instead of adding yourself to the CC list of all these bugs and mixing all these reasons, you can now store these bugs in - different lists, e.g. <SPAN + separate lists, e.g. <SPAN CLASS="QUOTE" ->"Bugs I want to see fixed before the next - release"</SPAN +>"Keep in mind"</SPAN >, <SPAN CLASS="QUOTE" >"Interesting bugs"</SPAN ->, or <SPAN +>, + or <SPAN CLASS="QUOTE" ->"Bugs I have - to think about"</SPAN ->. One big advantage of this way to manage bug lists - is that you can easily add bugs one by one, which is not possible to do - with saved searches without having to edit the search criteria again. +>"Triage"</SPAN +>. One big advantage of this way to manage bugs + is that you can easily add or remove bugs one by one, which is not + possible to do with saved searches without having to edit the search + criteria again. </P ></DIV ></DIV diff --git a/docs/html/quips.html b/docs/html/quips.html index 17560d500..131f53203 100644 --- a/docs/html/quips.html +++ b/docs/html/quips.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Administering Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -76,7 +74,7 @@ CLASS="section" CLASS="section" ><A NAME="quips" ->3.11. Quips</A +>3.12. Quips</A ></H1 ><P > Quips are small text messages that can be configured to appear diff --git a/docs/html/reporting.html b/docs/html/reporting.html index 0711225a6..87fc46232 100644 --- a/docs/html/reporting.html +++ b/docs/html/reporting.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Using Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -193,7 +191,7 @@ CLASS="section" ><H3 CLASS="section" ><A -NAME="AEN2362" +NAME="AEN2500" >5.11.2.1. Creating Charts</A ></H3 ><P @@ -233,7 +231,7 @@ CLASS="section" ><H3 CLASS="section" ><A -NAME="AEN2369" +NAME="AEN2507" >5.11.2.2. Creating New Data Sets</A ></H3 ><P diff --git a/docs/html/security-bugzilla.html b/docs/html/security-bugzilla.html index 4ae7a0d7b..71d836739 100644 --- a/docs/html/security-bugzilla.html +++ b/docs/html/security-bugzilla.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Bugzilla Security" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/security-mysql.html b/docs/html/security-mysql.html index 5073f4658..5e9dab2e4 100644 --- a/docs/html/security-mysql.html +++ b/docs/html/security-mysql.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Bugzilla Security" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/security-os.html b/docs/html/security-os.html index e57b305d0..3014f88b8 100644 --- a/docs/html/security-os.html +++ b/docs/html/security-os.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Bugzilla Security" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/security-webserver.html b/docs/html/security-webserver.html index 8bcacfb07..e8152535f 100644 --- a/docs/html/security-webserver.html +++ b/docs/html/security-webserver.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Bugzilla Security" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/security.html b/docs/html/security.html index 79f829ae0..8f31c3a4b 100644 --- a/docs/html/security.html +++ b/docs/html/security.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="PREVIOUS" TITLE="Upgrading to New Releases" @@ -35,8 +34,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/timetracking.html b/docs/html/timetracking.html index 6528581e8..222f1d47b 100644 --- a/docs/html/timetracking.html +++ b/docs/html/timetracking.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Using Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/trbl-dbdsponge.html b/docs/html/trbl-dbdsponge.html index aab3db5a2..498c3393a 100644 --- a/docs/html/trbl-dbdsponge.html +++ b/docs/html/trbl-dbdsponge.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Troubleshooting" @@ -39,8 +38,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/trbl-index.html b/docs/html/trbl-index.html index f65875461..1877c78ce 100644 --- a/docs/html/trbl-index.html +++ b/docs/html/trbl-index.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Troubleshooting" @@ -41,8 +40,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -79,7 +77,7 @@ CLASS="section" CLASS="section" ><A NAME="trbl-index" ->B.9. <TT +>B.8. <TT CLASS="filename" >index.cgi</TT > doesn't show up unless specified in the URL</A diff --git a/docs/html/trbl-passwd-encryption.html b/docs/html/trbl-passwd-encryption.html index add7deadf..a93350581 100644 --- a/docs/html/trbl-passwd-encryption.html +++ b/docs/html/trbl-passwd-encryption.html @@ -9,8 +9,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Troubleshooting" @@ -40,8 +39,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -78,7 +76,7 @@ CLASS="section" CLASS="section" ><A NAME="trbl-passwd-encryption" ->B.10. checksetup.pl reports "Client does not support authentication protocol +>B.9. checksetup.pl reports "Client does not support authentication protocol requested by server..."</A ></H1 ><P diff --git a/docs/html/trbl-perlmodule.html b/docs/html/trbl-perlmodule.html index 4a7339c8e..4b33e3de2 100644 --- a/docs/html/trbl-perlmodule.html +++ b/docs/html/trbl-perlmodule.html @@ -8,8 +8,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Troubleshooting" @@ -39,8 +38,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/trbl-relogin-everyone.html b/docs/html/trbl-relogin-everyone.html index 6613d9d84..fd929f6a7 100644 --- a/docs/html/trbl-relogin-everyone.html +++ b/docs/html/trbl-relogin-everyone.html @@ -7,15 +7,14 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Troubleshooting" HREF="troubleshooting.html"><LINK REL="PREVIOUS" -TITLE="Your vendor has not defined Fcntl macro O_NOINHERIT" -HREF="trouble-filetemp.html"><LINK +TITLE="cannot chdir(/var/spool/mqueue)" +HREF="paranoid-security.html"><LINK REL="NEXT" TITLE="Some users are constantly being forced to relogin" HREF="trbl-relogin-some.html"></HEAD @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -47,7 +45,7 @@ WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A -HREF="trouble-filetemp.html" +HREF="paranoid-security.html" ACCESSKEY="P" >Prev</A ></TD @@ -76,7 +74,7 @@ CLASS="section" CLASS="section" ><A NAME="trbl-relogin-everyone" ->B.7. Everybody is constantly being forced to relogin</A +>B.6. Everybody is constantly being forced to relogin</A ></H1 ><P >The most-likely cause is that the <SPAN @@ -120,7 +118,7 @@ NAME="trbl-relogin-everyone-share" >Example B-1. Examples of urlbase/cookiepath pairs for sharing login cookies</B ></P ><A -NAME="AEN3317" +NAME="AEN3478" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -161,7 +159,7 @@ NAME="trbl-relogin-everyone-restrict" >Example B-2. Examples of urlbase/cookiepath pairs to restrict the login cookie</B ></P ><A -NAME="AEN3324" +NAME="AEN3485" ></A ><BLOCKQUOTE CLASS="BLOCKQUOTE" @@ -214,7 +212,7 @@ WIDTH="33%" ALIGN="left" VALIGN="top" ><A -HREF="trouble-filetemp.html" +HREF="paranoid-security.html" ACCESSKEY="P" >Prev</A ></TD @@ -242,7 +240,7 @@ ACCESSKEY="N" WIDTH="33%" ALIGN="left" VALIGN="top" ->Your vendor has not defined Fcntl macro O_NOINHERIT</TD +>cannot chdir(/var/spool/mqueue)</TD ><TD WIDTH="34%" ALIGN="center" diff --git a/docs/html/trbl-relogin-some.html b/docs/html/trbl-relogin-some.html index 6ffccc804..1885d5f5b 100644 --- a/docs/html/trbl-relogin-some.html +++ b/docs/html/trbl-relogin-some.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Troubleshooting" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -76,7 +74,7 @@ CLASS="section" CLASS="section" ><A NAME="trbl-relogin-some" ->B.8. Some users are constantly being forced to relogin</A +>B.7. Some users are constantly being forced to relogin</A ></H1 ><P >First, make sure cookies are enabled in the user's browser. diff --git a/docs/html/trbl-testserver.html b/docs/html/trbl-testserver.html index 3fcf84d0e..03913ce52 100644 --- a/docs/html/trbl-testserver.html +++ b/docs/html/trbl-testserver.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Troubleshooting" @@ -39,8 +38,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/trouble-filetemp.html b/docs/html/trouble-filetemp.html deleted file mode 100644 index e0fe71236..000000000 --- a/docs/html/trouble-filetemp.html +++ /dev/null @@ -1,218 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<HTML -><HEAD -><TITLE ->Your vendor has not defined Fcntl macro O_NOINHERIT</TITLE -><META -NAME="GENERATOR" -CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK -REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" -HREF="index.html"><LINK -REL="UP" -TITLE="Troubleshooting" -HREF="troubleshooting.html"><LINK -REL="PREVIOUS" -TITLE="cannot chdir(/var/spool/mqueue)" -HREF="paranoid-security.html"><LINK -REL="NEXT" -TITLE="Everybody is constantly being forced to relogin" -HREF="trbl-relogin-everyone.html"></HEAD -><BODY -CLASS="section" -BGCOLOR="#FFFFFF" -TEXT="#000000" -LINK="#0000FF" -VLINK="#840084" -ALINK="#0000FF" -><DIV -CLASS="NAVHEADER" -><TABLE -SUMMARY="Header navigation table" -WIDTH="100%" -BORDER="0" -CELLPADDING="0" -CELLSPACING="0" -><TR -><TH -COLSPAN="3" -ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH -></TR -><TR -><TD -WIDTH="10%" -ALIGN="left" -VALIGN="bottom" -><A -HREF="paranoid-security.html" -ACCESSKEY="P" ->Prev</A -></TD -><TD -WIDTH="80%" -ALIGN="center" -VALIGN="bottom" ->Appendix B. Troubleshooting</TD -><TD -WIDTH="10%" -ALIGN="right" -VALIGN="bottom" -><A -HREF="trbl-relogin-everyone.html" -ACCESSKEY="N" ->Next</A -></TD -></TR -></TABLE -><HR -ALIGN="LEFT" -WIDTH="100%"></DIV -><DIV -CLASS="section" -><H1 -CLASS="section" -><A -NAME="trouble-filetemp" ->B.6. Your vendor has not defined Fcntl macro O_NOINHERIT</A -></H1 -><P ->This is caused by a bug in the version of - <SPAN -CLASS="productname" ->File::Temp</SPAN -> that is distributed with perl - 5.6.0. Many minor variations of this error have been reported: - </P -><TABLE -BORDER="0" -BGCOLOR="#E0E0E0" -WIDTH="100%" -><TR -><TD -><FONT -COLOR="#000000" -><PRE -CLASS="programlisting" ->Your vendor has not defined Fcntl macro O_NOINHERIT, used -at /usr/lib/perl5/site_perl/5.6.0/File/Temp.pm line 208. - -Your vendor has not defined Fcntl macro O_EXLOCK, used -at /usr/lib/perl5/site_perl/5.6.0/File/Temp.pm line 210. - -Your vendor has not defined Fcntl macro O_TEMPORARY, used -at /usr/lib/perl5/site_perl/5.6.0/File/Temp.pm line 233.</PRE -></FONT -></TD -></TR -></TABLE -><P ->Numerous people have reported that upgrading to version 5.6.1 - or higher solved the problem for them. A less involved fix is to apply - the following patch, which is also - available as a <A -HREF="../xml/filetemp.patch" -TARGET="_top" ->patch file</A ->. - </P -><TABLE -BORDER="0" -BGCOLOR="#E0E0E0" -WIDTH="100%" -><TR -><TD -><FONT -COLOR="#000000" -><PRE -CLASS="programlisting" ->--- File/Temp.pm.orig Thu Feb 6 16:26:00 2003 -+++ File/Temp.pm Thu Feb 6 16:26:23 2003 -@@ -205,6 +205,7 @@ - # eg CGI::Carp - local $SIG{__DIE__} = sub {}; - local $SIG{__WARN__} = sub {}; -+ local *CORE::GLOBAL::die = sub {}; - $bit = &$func(); - 1; - }; -@@ -226,6 +227,7 @@ - # eg CGI::Carp - local $SIG{__DIE__} = sub {}; - local $SIG{__WARN__} = sub {}; -+ local *CORE::GLOBAL::die = sub {}; - $bit = &$func(); - 1; - };</PRE -></FONT -></TD -></TR -></TABLE -></DIV -><DIV -CLASS="NAVFOOTER" -><HR -ALIGN="LEFT" -WIDTH="100%"><TABLE -SUMMARY="Footer navigation table" -WIDTH="100%" -BORDER="0" -CELLPADDING="0" -CELLSPACING="0" -><TR -><TD -WIDTH="33%" -ALIGN="left" -VALIGN="top" -><A -HREF="paranoid-security.html" -ACCESSKEY="P" ->Prev</A -></TD -><TD -WIDTH="34%" -ALIGN="center" -VALIGN="top" -><A -HREF="index.html" -ACCESSKEY="H" ->Home</A -></TD -><TD -WIDTH="33%" -ALIGN="right" -VALIGN="top" -><A -HREF="trbl-relogin-everyone.html" -ACCESSKEY="N" ->Next</A -></TD -></TR -><TR -><TD -WIDTH="33%" -ALIGN="left" -VALIGN="top" ->cannot chdir(/var/spool/mqueue)</TD -><TD -WIDTH="34%" -ALIGN="center" -VALIGN="top" -><A -HREF="troubleshooting.html" -ACCESSKEY="U" ->Up</A -></TD -><TD -WIDTH="33%" -ALIGN="right" -VALIGN="top" ->Everybody is constantly being forced to relogin</TD -></TR -></TABLE -></DIV -></BODY -></HTML -> \ No newline at end of file diff --git a/docs/html/troubleshooting.html b/docs/html/troubleshooting.html index c03de781e..4e5db13d8 100644 --- a/docs/html/troubleshooting.html +++ b/docs/html/troubleshooting.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="PREVIOUS" TITLE="The Bugzilla FAQ" @@ -35,8 +34,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -112,21 +110,16 @@ HREF="paranoid-security.html" ></DT ><DT >B.6. <A -HREF="trouble-filetemp.html" ->Your vendor has not defined Fcntl macro O_NOINHERIT</A -></DT -><DT ->B.7. <A HREF="trbl-relogin-everyone.html" >Everybody is constantly being forced to relogin</A ></DT ><DT ->B.8. <A +>B.7. <A HREF="trbl-relogin-some.html" >Some users are constantly being forced to relogin</A ></DT ><DT ->B.9. <A +>B.8. <A HREF="trbl-index.html" ><TT CLASS="filename" @@ -134,7 +127,7 @@ CLASS="filename" > doesn't show up unless specified in the URL</A ></DT ><DT ->B.10. <A +>B.9. <A HREF="trbl-passwd-encryption.html" >checksetup.pl reports "Client does not support authentication protocol requested by server..."</A diff --git a/docs/html/upgrading.html b/docs/html/upgrading.html index a17efd1be..95aa687a5 100644 --- a/docs/html/upgrading.html +++ b/docs/html/upgrading.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Administering Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -76,7 +74,7 @@ CLASS="section" CLASS="section" ><A NAME="upgrading" ->3.13. Upgrading to New Releases</A +>3.14. Upgrading to New Releases</A ></H1 ><P > Upgrading Bugzilla is something we all want to do from time to time, @@ -103,24 +101,26 @@ CLASS="section" CLASS="section" ><A NAME="upgrading-version-defns" ->3.13.1. Version Definitions</A +>3.14.1. Version Definitions</A ></H2 ><P -> Bugzilla displays the version you are using at the top of most - pages you load. It will look something like '2.16.7' or '2.18rc3' - or '2.19.1+'. The first number in this series is the Major Version. - This does not change very often (that is to say, almost never); +> Bugzilla displays the version you are using at the top of the home + page <TT +CLASS="filename" +>index.cgi</TT +>. It looks something like + '2.20.3', '2.22.1' or '3.0rc1'. The first number in this series is + the Major Version. This does not change very often; Bugzilla was 1.x.x when it was first created, and went to 2.x.x - when it was re-written in perl in Sept 1998. If/When the major version - is changed to 3.x.x, it will signify a significant structural change - and will be accompanied by much fanfare and many instructions on - how to upgrade, including a revision to this page. :) + when it was re-written in perl in Sept 1998. The major version + 3.x.x, released in early 2007, is pretty far from what the 2.x.x + series looked like, both about its UI and its code. </P ><P > The second number in the version is called the 'minor number', and a release that changes the minor number is called a 'point release'. - An even number in this position (2.14, 2.16, 2.18, 2.20, etc.) - represents a stable version, while an odd number (2.17, 2.19, etc.) + An even number in this position (2.18, 2.20, 2.22, 3.0, 3.2, etc.) + represents a stable version, while an odd number (2.19, 2.21, 2.23, etc.) represents a development version. In the past, stable point releases were feature-based, coming when certain enhancements had been completed, or the Bugzilla development team felt that enough @@ -131,13 +131,11 @@ NAME="upgrading-version-defns" </P ><P > The third number in the Bugzilla version represents a bugfix version. - Bugfix Revisions are normally released only to address security - vulnerabilities; in the future, it is likely that the Bugzilla - development team will back-port bugfixes in a new point release to - the old point release for a limited period. Once enough of these + Bugfix Revisions are released only to address security vulnerabilities + and, for a limited period, bug fixes. Once enough of these bugfixes have accumulated (or a new security vulnerability is - identified and closed), a bugfix release will be made. As an - example, 2.16.6 was a bugfix release, and improved on 2.16.5. + identified and closed), a bugfix release is made. As an + example, 2.20.3 was a bugfix release, and improved on 2.20.2. </P ><DIV CLASS="note" @@ -164,9 +162,9 @@ VALIGN="TOP" should be read as a single number. It is <EM >not</EM > - the same as decimal. 2.14 is newer than 2.8 because minor version - 14 is greater than minor version 8. 2.24.11 would be newer than - 2.24.9 (because bugfix 11 is greater than bugfix 9. This is + the same as decimal. 2.22 is newer than 2.8 because minor version + 22 is greater than minor version 8. The now unsupported release 2.16.11 + was newer than 2.16.9 (because bugfix 11 is greater than bugfix 9. This is confusing to some people who aren't used to dealing with software. </P ></TD @@ -179,8 +177,39 @@ CLASS="section" ><H2 CLASS="section" ><A +NAME="upgrading-notifications" +>3.14.2. Upgrading - Notifications</A +></H2 +><P +> Bugzilla 3.0 introduces the ability to automatically notify + administrators when new releases are available, based on the + <VAR +CLASS="literal" +>upgrade_notification</VAR +> parameter, see + <A +HREF="parameters.html" +>Section 3.1</A +>. Administrators will see these + notifications when they access the <TT +CLASS="filename" +>index.cgi</TT +> + page, i.e. generally when logging in. Bugzilla will check once a + week for new releases, unless the parameter is set to + <SPAN +CLASS="QUOTE" +>"disabled"</SPAN +>. + </P +></DIV +><DIV +CLASS="section" +><H2 +CLASS="section" +><A NAME="upgrading-methods" ->3.13.2. Upgrading - Methods and Procedure</A +>3.14.3. Upgrading - Methods and Procedure</A ></H2 ><P > There are three different ways to upgrade your installation. @@ -193,7 +222,7 @@ TYPE="1" ><P > Using CVS (<A HREF="upgrading.html#upgrade-cvs" ->Section 3.13.2.1</A +>Section 3.14.3.1</A >) </P ></LI @@ -201,7 +230,7 @@ HREF="upgrading.html#upgrade-cvs" ><P > Downloading a new tarball (<A HREF="upgrading.html#upgrade-tarball" ->Section 3.13.2.2</A +>Section 3.14.3.2</A >) </P ></LI @@ -209,7 +238,7 @@ HREF="upgrading.html#upgrade-tarball" ><P > Applying the relevant patches (<A HREF="upgrading.html#upgrade-patches" ->Section 3.13.2.3</A +>Section 3.14.3.3</A >) </P ></LI @@ -222,14 +251,14 @@ HREF="upgrading.html#upgrade-patches" methods of updating compared with degree and methods of local customization can be found in <A HREF="cust-templates.html#template-method" ->Section 6.1.2</A +>Section 6.2.2</A >.) </P ><P > The larger the jump you are trying to make, the more difficult it is going to be to upgrade if you have made local customizations. - Upgrading from 2.18 to 2.18.1 should be fairly painless even if - you are heavily customized, but going from 2.14 to 2.18 is going + Upgrading from 2.22 to 2.22.1 should be fairly painless even if + you are heavily customized, but going from 2.18 to 3.0 is going to mean a fair bit of work re-writing your local changes to use the new files, logic, templates, etc. If you have done no local changes at all, however, then upgrading should be approximately @@ -268,7 +297,7 @@ VALIGN="TOP" ></DIV ><P > The examples in the following sections are written as though the - user were updating to version 2.18.1, but the procedures are the + user were updating to version 2.22.1, but the procedures are the same regardless of whether one is updating to a new point release or simply trying to obtain a new bugfix release. Also, in the examples the user's Bugzilla installation is found at @@ -285,7 +314,7 @@ CLASS="section" CLASS="section" ><A NAME="upgrade-cvs" ->3.13.2.1. Upgrading using CVS</A +>3.14.3.1. Upgrading using CVS</A ></H3 ><P > Every release of Bugzilla, whether it is a point release or a bugfix, @@ -352,11 +381,10 @@ CVS password: <EM > bash$ <B CLASS="command" ->cvs -q update -r BUGZILLA-2_18_1 -dP</B +>cvs -q update -r BUGZILLA-2_22_1 -dP</B > P checksetup.pl P collectstats.pl -P globals.pl P docs/rel_notes.txt P template/en/default/list/quips.html.tmpl <EM @@ -411,7 +439,7 @@ CLASS="section" CLASS="section" ><A NAME="upgrade-tarball" ->3.13.2.2. Upgrading using the tarball</A +>3.14.3.2. Upgrading using the tarball</A ></H3 ><P > If you are unable (or unwilling) to use CVS, another option that's @@ -449,24 +477,23 @@ CLASS="command" > bash$ <B CLASS="command" ->wget ftp://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.18.1.tar.gz</B +>wget http://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.22.1.tar.gz</B > <EM >(Output omitted)</EM > bash$ <B CLASS="command" ->tar xzvf bugzilla-2.18.1.tar.gz</B +>tar xzvf bugzilla-2.22.1.tar.gz</B > -bugzilla-2.18.1/ -bugzilla-2.18.1/.cvsignore -bugzilla-2.18.1/1x1.gif +bugzilla-2.22.1/ +bugzilla-2.22.1/.cvsignore <EM >(Output truncated)</EM > bash$ <B CLASS="command" ->cd bugzilla-2.18.1</B +>cd bugzilla-2.22.1</B > bash$ <B CLASS="command" @@ -486,7 +513,7 @@ CLASS="command" > bash$ <B CLASS="command" ->mv bugzilla-2.18.1 bugzilla</B +>mv bugzilla-2.22.1 bugzilla</B > </PRE ></FONT @@ -543,11 +570,11 @@ CLASS="section" CLASS="section" ><A NAME="upgrade-patches" ->3.13.2.3. Upgrading using patches</A +>3.14.3.3. Upgrading using patches</A ></H3 ><P > If you are doing a bugfix upgrade -- that is, one where only the - last number of the revision changes, such as from 2.16.6 to 2.16.7 + last number of the revision changes, such as from 2.22 to 2.22.1 -- then you have the option of obtaining and applying a patch file from the <A HREF="http://www.bugzilla.org/download/" @@ -587,22 +614,21 @@ CLASS="command" > bash$ <B CLASS="command" ->wget ftp://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.18.0-to-2.18.1.diff.gz</B +>wget http://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.22-to-2.22.1.diff.gz</B > <EM >(Output omitted)</EM > bash$ <B CLASS="command" ->gunzip bugzilla-2.18.0-to-2.18.1.diff.gz</B +>gunzip bugzilla-2.22-to-2.22.1.diff.gz</B > bash$ <B CLASS="command" ->patch -p1 < bugzilla-2.18.0-to-2.18.1.diff</B +>patch -p1 < bugzilla-2.22-to-2.22.1.diff</B > patching file checksetup.pl patching file collectstats.pl -patching file globals.pl <EM >(etc.)</EM > @@ -640,7 +666,7 @@ CLASS="filename" This could make it more difficult to upgrade using CVS (<A HREF="upgrading.html#upgrade-cvs" ->Section 3.13.2.1</A +>Section 3.14.3.1</A >) in the future. </P ></TD @@ -655,7 +681,7 @@ CLASS="section" CLASS="section" ><A NAME="upgrading-completion" ->3.13.3. Completing Your Upgrade</A +>3.14.4. Completing Your Upgrade</A ></H2 ><P > Regardless of which upgrade method you choose, you will need to diff --git a/docs/html/useradmin.html b/docs/html/useradmin.html index ce7734967..625260d3c 100644 --- a/docs/html/useradmin.html +++ b/docs/html/useradmin.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Administering Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -326,6 +324,16 @@ CLASS="QUOTE" ><LI ><P > <EM +>Bugmail Disabled</EM +>: + Mark this checkbox to disable bugmail and whinemail completely + for this account. This checkbox replaces the data/nomail file + which existed in older versions of Bugzilla. + </P +></LI +><LI +><P +> <EM >Disable Text</EM >: If you type anything in this box, including just a space, the @@ -340,11 +348,11 @@ CLASS="QUOTE" mail from Bugzilla; furthermore, they will not be able to log in themselves to change their own preferences and stop it. If you want an account (disabled or active) to - stop receiving mail, add the account name (one account - per line) to the file <TT -CLASS="filename" ->data/nomail</TT ->. + stop receiving mail, simply check the + <SPAN +CLASS="QUOTE" +>"Bugmail Disabled"</SPAN +> checkbox above. </P ><DIV CLASS="note" diff --git a/docs/html/userpreferences.html b/docs/html/userpreferences.html index d23b1fdb8..cbf52bea6 100644 --- a/docs/html/userpreferences.html +++ b/docs/html/userpreferences.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Using Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -79,7 +77,7 @@ NAME="userpreferences" >5.10. User Preferences</A ></H1 ><P ->Once you have logged in, you can customize various aspects of +>Once you have logged in, you can customise various aspects of Bugzilla via the "Edit prefs" link in the page footer. The preferences are split into three tabs:</P ><DIV diff --git a/docs/html/using-intro.html b/docs/html/using-intro.html index a9a23a913..062c74a9a 100644 --- a/docs/html/using-intro.html +++ b/docs/html/using-intro.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Using Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/using.html b/docs/html/using.html index 68148a24f..c821e2ebf 100644 --- a/docs/html/using.html +++ b/docs/html/using.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="PREVIOUS" TITLE="Bugzilla" @@ -35,8 +34,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -126,7 +124,7 @@ HREF="query.html#list" ><DT >5.5.4. <A HREF="query.html#individual-buglists" ->Adding individual bugs from bug lists</A +>Adding/removing tags to/from bugs</A ></DT ></DL ></DD @@ -163,7 +161,7 @@ HREF="hintsandtips.html" ><DL ><DT >5.8.1. <A -HREF="hintsandtips.html#AEN2234" +HREF="hintsandtips.html#AEN2372" >Autolinkification</A ></DT ><DT @@ -256,11 +254,11 @@ HREF="whining.html#whining-schedule" ><DT >5.13.3. <A HREF="whining.html#whining-query" ->Whining Queries</A +>Whining Searches</A ></DT ><DT >5.13.4. <A -HREF="whining.html#AEN2422" +HREF="whining.html#AEN2560" >Saving Your Changes</A ></DT ></DL diff --git a/docs/html/versions.html b/docs/html/versions.html index b1120407d..005881f11 100644 --- a/docs/html/versions.html +++ b/docs/html/versions.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Administering Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD diff --git a/docs/html/voting.html b/docs/html/voting.html index eb1d2534d..c46c88097 100644 --- a/docs/html/voting.html +++ b/docs/html/voting.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Administering Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -76,7 +74,7 @@ CLASS="section" CLASS="section" ><A NAME="voting" ->3.10. Voting</A +>3.11. Voting</A ></H1 ><P >Voting allows users to be given a pot of votes which they can allocate diff --git a/docs/html/whining.html b/docs/html/whining.html index 9d760f6fc..32fdddedc 100644 --- a/docs/html/whining.html +++ b/docs/html/whining.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Using Bugzilla" @@ -17,7 +16,7 @@ REL="PREVIOUS" TITLE="Flags" HREF="flags.html"><LINK REL="NEXT" -TITLE="Customizing Bugzilla" +TITLE="Customising Bugzilla" HREF="customization.html"></HEAD ><BODY CLASS="section" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -212,7 +210,7 @@ NAME="whining-overview" </P ><P > The next step is to specify when the Event is to be run (the Schedule) - and what searches are to be performed (the Queries). + and what searches are to be performed (the Searches). </P ></DIV ><DIV @@ -320,20 +318,20 @@ CLASS="section" CLASS="section" ><A NAME="whining-query" ->5.13.3. Whining Queries</A +>5.13.3. Whining Searches</A ></H2 ><P -> Each whining event is associated with zero or more queries. A query is - a saved search that is executed on the schedule specified (see above). - You start out with zero queries attached to the event (which means that - the event will not run, as there will never be any results to return). - To add a query, press the "Add a new query" button. +> Each whining event is associated with zero or more searches. A search + is any saved search to be run as part of the specified schedule (see + above). You start out without any searches associated with the event + (which means that the event will not run, as there will never be any + results to return). To add a search, press the "Include search" button. </P ><P -> The first field to examine in your new query is the Sort field. Queries - are executed, and results returned, in the order specified by the Sort - field. Queries with lower Sort values will run before queries with - higher Sort values. +> The first field to examine in your newly added search is the Sort field. + Searches are run, and results included, in the order specified by the + Sort field. Searches with smaller Sort values will run before searches + with bigger Sort values. </P ><P > The next field to examine is the Search field. This is where you @@ -423,7 +421,7 @@ CLASS="section" ><H2 CLASS="section" ><A -NAME="AEN2422" +NAME="AEN2560" >5.13.4. Saving Your Changes</A ></H2 ><P @@ -521,7 +519,7 @@ ACCESSKEY="U" WIDTH="33%" ALIGN="right" VALIGN="top" ->Customizing Bugzilla</TD +>Customising Bugzilla</TD ></TR ></TABLE ></DIV diff --git a/docs/html/x763.html b/docs/html/x834.html similarity index 97% rename from docs/html/x763.html rename to docs/html/x834.html index d253f726c..1ed02aaf6 100644 --- a/docs/html/x763.html +++ b/docs/html/x834.html @@ -7,8 +7,7 @@ NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" -TITLE="The Bugzilla Guide - 2.22.3 - Release" +TITLE="The Bugzilla Guide - 3.0 Release" HREF="index.html"><LINK REL="UP" TITLE="Installing Bugzilla" @@ -38,8 +37,7 @@ CELLSPACING="0" ><TH COLSPAN="3" ALIGN="center" ->The Bugzilla Guide - 2.22.3 - Release</TH +>The Bugzilla Guide - 3.0 Release</TH ></TR ><TR ><TD @@ -75,7 +73,7 @@ CLASS="section" ><H1 CLASS="section" ><A -NAME="AEN763" +NAME="AEN834" >2.4. Multiple Bugzilla databases with a single installation</A ></H1 ><P diff --git a/docs/images/CVS/Entries b/docs/images/CVS/Entries index b62dc9318..5e4af2591 100644 --- a/docs/images/CVS/Entries +++ b/docs/images/CVS/Entries @@ -1,7 +1,7 @@ -/bzLifecycle.png/1.3/Fri Oct 14 04:44:54 2005/-kb/TBUGZILLA-2_22_3 -/bzLifecycle.xml/1.2/Tue Jul 12 10:29:52 2005//TBUGZILLA-2_22_3 -/caution.gif/1.2/Wed May 8 21:16:44 2002/-kb/TBUGZILLA-2_22_3 -/note.gif/1.1/Thu Aug 23 14:30:18 2001/-kb/TBUGZILLA-2_22_3 -/tip.gif/1.2/Wed May 8 21:16:44 2002/-kb/TBUGZILLA-2_22_3 -/warning.gif/1.2/Wed May 8 21:16:44 2002/-kb/TBUGZILLA-2_22_3 +/bzLifecycle.png/1.4/Sun Sep 3 21:04:34 2006/-kb/TBUGZILLA-3_0 +/bzLifecycle.xml/1.3/Sun Sep 3 20:37:02 2006//TBUGZILLA-3_0 +/caution.gif/1.2/Wed May 8 21:16:44 2002/-kb/TBUGZILLA-3_0 +/note.gif/1.1/Thu Aug 23 14:30:18 2001/-kb/TBUGZILLA-3_0 +/tip.gif/1.2/Wed May 8 21:16:44 2002/-kb/TBUGZILLA-3_0 +/warning.gif/1.2/Wed May 8 21:16:44 2002/-kb/TBUGZILLA-3_0 D/callouts//// diff --git a/docs/images/CVS/Tag b/docs/images/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/docs/images/CVS/Tag +++ b/docs/images/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/docs/images/bzLifecycle.png b/docs/images/bzLifecycle.png index 33ecc77b48f89346eec6a765558e07ce019ec19f..c1d76e237d889ff322dce948d6fa3ed165ad6a0e 100644 GIT binary patch literal 74447 zcmeAS@N?(olHy`uVBq!ia0y~yVEn+qz~s!q#=yYvMapdf0|NtFlDE4H!+#K5uy^@n z1_lQ95>H=O_G_HXBG$U4AqsC87!(*hT^vIy=DfLE9uac=8vBF$JeOFOh*uwOYf{p1 z-KCMG)aBK4tS>OR)6HaCwXkrqXOc--Z>Q?s8{TgOS*4}8C62DXA>b&&GL>)hKKmcf zS`yPTn9|v<{kE|&O8<7V`mDm5o6FbeDk?E0_ZS}A(iQTCK_b~l*u~Y=QEB3V+qa|N z1W0I$`#tC}JT^n@5z9G=<ep4L^0@2THf}T&(~Hrt*|vG}>P`DrZ(9FI&3_(`x%u|2 zm$MCz%}9I5vd-=Audg4U&#!-Ub#-`Bdr)5W_jgBIxy7e!E8basOk#DdMdND4sa}F& zVr{;&%`|iN7eD7?VrG8$^eJn3d3nsvBG&l2pGz;Si{D>2!z@>dA>rGbn>RM6_Xpi~ zX?b~h`Qh8QrDJ!O9o?FJok8RLnWz2w@%wt##qK_I{5ZRD`ni_1Yu5(NudA!8`1M8e z&!0aG4BNJCn_*F?R8v#4A^*NzMO777{Pp$m;<tR}T8YlJDm`>-YqnwPDUp&_S2(r9 z*M<C?_vQ6<emOb058uAEwYRe`TD0iY?=quf605V0glyWnb?KZrGDU@j3+K#{*|c@5 zs*;kuy?s|-pPJI5=<RtEXU~?7-CH%4jaSO$=FOW|c9-XW`u0stNhv)&{nUvQ0k3YK zIMK0a(V~uy7gtsWKY932u_w}qO-aez+}x`An~tF1T-)ktJv}{Fj>XjUbc^c?2~KQp zXP;|T>Xm7eoSeL?_&MLw<;y4c_3_=^TRr{K<;yE8KR?s@?eFa^yl;QyXEjR;ixoM? zXP9;M^r$dAdHPhfOrvM2x9vuIhYX|I+S)yTzumsEuXgtaT{APW&FSaG<kC}951u^9 zX`Xk-!NrB8rlzLg^)=l&*5!Q1jvdRmu%Iz$|E^uTUR+$v&T!!NZRzd#_romh{{CP1 z{>P7sii!#b1{)ij1*=y_r@d)wYbz)%Wo5XtuU6X5&d%%c)%Ef6YooWbF+@Z~ElNE- zjiF)A9GR)L^K2@Gvahdmb#!E05~L|4EPT4B+3;Az*9R<dZJv|W6crR0jArsMJb3Y< zqxAK)g9i^XGEA5~o4eDcDevyC#EXkufBbsA{^BB6?lZGYxodxY3A~wJS7&!_o-Mb( zzyBP|Vz%5{TNnerG(Nnz*gfOY63%n;?fcK1@nLA#yVv&ITx)iIetwYme*XNKdTj0D z#mY7L`T6}TR%ldIRw^191xffTP2|Y!s$YNZ$;ruuZ*Q62xOMB%x3{+sv9lbLNH*;k zu8{2M?Y+1?KfdPc)o_Le-RNxzx3*+fe0;>paNy7(rs{8R90LLbmif=;6BifXl5vqq z*}d;bm#B8gx6G83miu+Td5fQ)b4^QA+m>^ai6LTB3MUgY^TiE`&KB0zhfkc~VAzm% z*Q!U}UhdejV+CbppuD90ManGiPDiJ(x|7nxhK?!cUQfTiCG+xy?fLN$QBj93UKC_w zW1IS_-SF6r*OLW4s-BwV_fL6}he}6J&k=U{ng;LbdYv+&$y>ccLPYlL-P@`h+LLKD zuQ9vv&Yc(*cJ{|tSBHb#Z<cpQqs*hn@R-Xn&KPb935f?UE-p@LKPZvx)BK^9K<RNc z=fVQVL*I|)`>tFkdU93tN73_L`^`W>)-7DY8v141&)D5%ocG(?+QLdLOxOMBN<SJO zT^JM9kh!U)g=J68&rOGZ-`!ETSZYz?noqA>n8LT8y8h^B_rqt;*zE1?dt|M{o_ZxW zJUSKk{oP&RUz+E&Qa)|`^XJcmY17o!h`G7UFwd8(`u3)iPuA+e^!U2KuHVOcr9XW7 z<kT-`D<C1!apz7<qE6}Rrkl5JB|SSc^TYS=;V;5N<2P>Hm=&%WeAWFV$hqrP?=S9J zS8^=E*U-$&ZMt6UhLV?;ic~)tr=MF8zCP~8#$<P1m*Wwv9ozf7&IWEj6~5T5_r=M{ z>MkxJ5fLkjmKrJ@ow~P6`@B}l(c^kMqi*ahe%{fcp{VHilq+H0ym?=)$JYxAPV`Yz zp6TP}vUEMyvUTyHwJW2SuGw<KtJ?M`%<^9^7WZ>7FfLH_o_3*ITz^WKa(7pklCZEa zlf$!T&!)_qr&n~PM|0I=&O67BwRLp#$y&Q9Dk@%C?k|69XR&%@RMe#P>(_sH`r?I$ zi%VEonAY#9CsVHMtF5*wc_C2y?Pj`3(Gw4=>Thc%obc|8{Zn1Z^D1ddzqbFaqi^r* zoc!nS-;=j*&#tMhJ$dEImNRvsUqk<to=h=%SeUtS<?nq@szdhlKf1rVYHrWfEnBvj zC^j-Hczb)#GDu`%R8Ut}=i=cBsrYx8-(JKz<=B)fonASw!hU}G^2H?~LE+Nn%MTws zSWvXo(4jDO{UfbiT#+YhPhVOWYdy!VR%+kAeF{p6^Dl+5247#lYTv2NUXhhkYx=cz zU6M>TJ$dJjjC}1ELA$?Sf*BmLvb6U7d?wA{;N#Qd6y534^z-xc>lHmcQ<wUw6qK&6 z;gz$Ih>VOpar*S(HIbVIgoG9qE!}u2Bt_InUS6Jsojv*fzS^f<)t8s~R(!u(t~k*n zAt9lmnVtX8fddPIRyVDDwR%;UX0ng;*%^k+tHahhxw*Nmd@H6G!x0>OS*ojR<EO`0 zPe>$}UOO&duXE;5sG+&}@x9gGEgFq`L)6zfrS}+yrk$A)m{p|ry7JhOBb;*#!_sHY zo}K*b%S+L^K11IFAd%%OXQzICGdt7D??KN-E8nX=v(xYUNEa}r_gt-1O}}mPJMC73 zutoBkbH?W8$Cr3cZaEGS+R;`q_v*>6^+jQVrW=EzQj?R{EIT{Xn0?u@Wj~%w_OJMM zb_>&e_J9Ao!mWfC=UZD_tEj7oulj%eW_YN4=*9V~>SliP_VYWoE_U~Z`u}xDjvhUD z>5@?W|G(RBBpRB|nKNg?lqoH3ywZp6-<MZZRQ&Mq<HJ`STV3YPXq>+7)wETi#~Ln$ z|Is>k?V8wRHQ%P`)5Uj{z3s}rzE1P&-u(M^OF!zz@8d~NPp_!1e*E|Q{qTsU;JdFf zSA~ga?>sd#rgY7eW$$W3#Mke-G2>h1w>Of@d}p^kJ3Bl1)D%sNnjZ%5?(gq^^CoAb zbMjIR4UGerm-`C}3pa<Z4m)`MJinix-;dAd?T_;HhBjImGJpT_<;bSg(+?g$Zoa(S zKl$CAofg&Kbb5Mw1qB5c26)H3`}z5~fw?(5!;zy$6F)pS_~ZHf`YE?0rKKOAn5g{X z;^OvO`$BvDT_X0??A#E)zwYmcS68(ePHhhR`B=`j>cQsocFp_u@1O8NRjBh+<h!le z*FU^mKL643`E`dH7?~%`o!fhPx&Pwq>+3o?IvkqWc(0t>)!W-!_~%FAj@`Q-UtH|| z;nSx>e}8|!y08D$qtLHWGro29^c;C`u=(Scm%$Pe5(*|JB94xZ8@6wEpRDFvVYd8W zNoncCIdgiZOc4RqVfBALwtqNSeP>5u#Qr+lFJHg9_Du>6o9pr5+O=z-c1^>gn@f9p zdFR>HuG+A7N$l>j#J9J$YG`OQglHYTx;lK~ym{-coV#;J=KOqn{jK?-kC_8*q~+!5 zeTg@EdGpq-M<*w%Z`iiY&C9FnlDto-=cJAY4<0m3)ee93e*gbtYooV+xL5r?@!T9s zi`rjXF4Y~~KfOPEQ+?_C#k(r59zC|@_(WxQ0U4Q|J$r0e*w`L*>+fq=yLRn|J?qx# zefs>_wP(WAWlzqxcWfwr?ssOsz5L9XGhbX?EzT!vwWREz+OnIkjwqJ=TouhA5_VVX zt^M04CntYAt-t@lmzS4s?5Q-qQhV;?`SZtbZcb-pNIy3x@aFbaAK$)xEBZ}aLqp)! z>2QDM1sken)wmimWIdj!y)P*0{k^?{A|fr3o6{DCua8^$PW^tkDA=hp%XSw(=WFAW z?b@@)22`O&Z_f+$xaafRLq&*3(uk${`@7b)Yjyi%t=m3)DA;&7X=;dinDXi~tD>LA zems5R1jqhApSYi$nb~~ij8D$pU0Y)wi;IaR{rU0Hz{tqyc%N*m=p}})tCz2gp6hd0 zD?M~?(5zkG17r6*eLFpKS>)z4MP+5?zrVj9Kh(<oGoVuU(n4qUn(ueZC5%!yuC0k| z-k5xRQStM0N$p3qR`|&{t@o?xm~qujTrZ|!_ipQ)oE!mB(WM_2uCcIdS$Ff)ub*pT zcZ+#X*K;i>F!=WFZglg+jjICG`4$=<({ig*$vibhGi$Q><+{hm``ec;RppbhXqYlZ zWaHsP(IcFHOh3MvebvmR<?rwB&Po#()c^mN)P8u?#KuO(s_*Z3XZp1L{r$aLmT$EJ zs7Ju+>FHVV=Z9fVPR@@-Tdf@G-u=F`)LY5@kXDzlMY4}$Qj!wGg2cmZO74fUn*MCN zwq%LQMCC-$qnvXLmnoQ=i!&@(zC1iFdS8R@=Bdx0E9*y0oi!`!?!ygQ$2jL09+SB2 zRI1jvdi8Z)k*R#KI|>$_dTy3?hr{3B|Hsdt2QOb1PE1U6x;S-f_Vq(|@5<KI)qVKz z;lQu2uSJh(tc?#24*v1;Cue+RWo6dwA3uH^IC|9ep&7rhu<)5#rrs4Ya&mma!opks zzQ3{2IkDQofnm?yy&G$O7M)1hwCTRXl=@V|xW*pCW2@rlYCH*=_Ur5G$LH<;A6XN* zIUy%UC+Gf_OkuzIcD<9;{kgt2`OmRvJaot@=iVO4i4!MUl)e)A^7ZS)>C@XMD!V&{ zhl{`8_d9RpU#5nI3l)`=l)QRZSIj<g#HFIDD(OH2BSRP0i6h63apkU$-@mS4cmJ+` z-TCKFpFX_AbMl9u&*vxK+f$jk&wt^<g->_A+PCMeL~>7P+}xRs)7`YDD(UF>taQ44 zYist$tKspQBER3?+^qiP>(`BSf2-C+Y;>yd^Y`c14qJ0zmTC5>H`|Rs1we^?-t%*F zK~2?|y;Y*IyGm9T%&)4d`tj%U`Hz3U-`BR?Uhy$$$IhLgLNxh!UuaaM&)uxtqqpzw zEM{+PZ2a))Q`7F<*6U(+27MGiCz0%<I<N8ne#7Kr3*7tVW>}T3+VJ+~=Jc%fM{0k4 z(UdaJTeD$p;p1ao-HTVe5@*=7d2?&Zi${-|*6;h}mB~{%yQhce&YntP_dc1x3Of}Q zmfhv=*#s3;R9J3r&kw(8&j9LkIk)iyN*%s+E9$9|?(6I8k5APOPe@K?p6SE3GK9<8 z+B)&uzsvsiD`VE`Dk(W-Jb(YbUw_{Zrn|dJ5C8x7-M&Z4l<WEV`QcLCSL;6A7yT*v zZq>Gv^8M20eBENYLA&E)Vr0VB#dLmteqPzuR#r?*?8BEYM|PFIZZTW#H}}x>`1;-% zGb9*XUniZPVaU91-#)L$)6L>e-Y;aBVOgwp=<s3h+||pMxAVzbC0tzOT2NRRSh270 z@i9>4^6Kj9_NFGLimEEE+K`l(l_6Zh!on67772fTe0*_vdH*H5HD!-k{{8>*_3OuP zxAV1C9JRHzRa8}1`aA*^+kbu-N||P<<aqn|v~1m4I`c1+sC~=6)YD>XA~(A|<e#v6 zx3!pV6pK=j#r3#*{}>fiRb4%f9L>GIPj<4JuTxo>*}dBDu{=^H9uI#`R`=Ihb1m!- z|C*Sb9G$fD^K@;_ojRpuEO)H#-_P_t|Ns5=+V9OEAS~QGVS>Pk6r&z#b3R$C5{IH9 zqq6t+bhlWRz7lckkznNJ=6-nP!YtElgQO!Ie||jf=i2X_+N&P^=hw8dx3{KB{r~m# zb>YWHt~qyiiC$jrFW%>OQdLbY>HWRE5;heE-`?C@{Hc7o&Es{Eo7wo~?T)nZO1CK2 z=I{HNwsPafTT9QWd@#$srC?<xb$569@twubTc&R5nr)IP#KgqZ(!Fb$-`uVb9}05r z?h3UCsr&TA6O?@}E%E&Epqc-}-|zRipC34U_^@H>sVPRk*Y*@XK9+cTn(mIm$80h( zG7KVXb*`)m)qeQ9>(uGfhwtnxHq5%BvGlo(t*xMhM8}seB^DMI8mb>oPF8<>Yiss~ zty_=2y}dnj-O6{6ZYAf(Q~CZ$YfN_S+I3?`q4K}q_y23zZcjNW^yJBtgr}#bR=i%j zz2)s>b$_va@jHuDQ;a0T)<iVUv#n-gh}x3TcyY1&<Jar=hj~3%+N=Kj?OWZN{EUo< ztUt_bJPz~iYB!X=4x4)N=GCjB(q=ga7C1I<NIcB8W7n=#x{HEt?O<l-V`12mds{3q zF%e|B`Uk6J=TtsiT^;^-@ArGnE=r9)YKM>YN>9BdAuYW)|Ng#158reOt2cEB2naC5 z#>PH*`V`bFzIX5545L)8PoF<OeEhii*Vos|>gw!=+xd?l=@dTwX8R^k+iI!z^hfRT zbpqSg#_kSFjV^7!@bvc5Ak9yoJ{cq&V3>NElMmif7G77Tzi(4S=IX5{Z|C0J#Cmy| z@8NE7eFg?GF|iw))6Zw`Wnc46+PX|<-`{W1OE3E|eE5F9o|)lZ#be&qw?QxWPyc*E z|J|F5i`zH&{@eR!LRIDQ$;BllBKxMxp9)jg)#ZJDZZ0#!!w;2(lhyr??I?Ww;p1_6 zWj#H<=xsR%cN9L>vR(Iw`Q+Kz=2wp$$x@H&?J-=Ypryri@7}!^_xA2SwD9Hiz=_2V zHg4QlP+WZY$H&JTtG;Hnn&sZw;usbtmUn+&@2{_~SIev}eSPi3$&-#XHG4iBG*VY* zUmLx>t+A2u(c{ObZRhPdyMF&atuOc2L>imq-`jKM^V4nHwpmnsSWv*__wUbQ_x_e{ zo40S@3JMA~s`<_esk*afjn0<L%We<1hPsrLm^e8(J$U-`==O#z$$eb0&930lH4PcJ zWFP67GiNgXDE~NL-G3f~hLu+Eq}Enew>}xoH63AdYTT+nJaBA%d(_|mWcu3l^YcWv zo!nnuRJ7_sMbW)`_YQ@Bes=ciHs-E#EBF6=HoM}}6V7S6(aXN<aZx(B#B(x($lN&X zw_n05kNthUem?`l+uPgqP4&WlUzzFrqQ~&#m$$dYLCqAme!1R;28M@Br}x$VUX^2? zc}XSb_BP+l-+L-Q7kqr=TJz&!dq;P7b8|CuP*4!4WhP@^C&TdJAiI3Rkq$u)etvPj z?)9;|#e!Cf7^j_CaiL=B!`H97-`(A<Y-J^7UH0a{i;IgdZp{vFH9OqKdw4_Q;Ztu` zSA1Mn_V$*h%FDgg-yi+^`}@X*#O4oD5qA%P`ZsUwem)U?@$%)v3k#hiw&%&}=;|7# zosrOq*x-;_EiEm*=kq!18=F$Q4}Ci~*ZT2;gUt~elUVEi|1D2RNjY%mj?BDy^PHsP z<Ksc4QpC<8)oD7BObar?*1cldw&~bv9cO3fGjlA3i=Ur6I!V>L#j8U!^v|O`GmX== zR6eW>UViAr2@YASk^?QA!dL1flD3M^XTF~Bsd!>dUf0znuPoTlnSey%YWN_Hk~s$? zlY0zxL0vUa8wEFanZv#U|G2ognYpE<rK_!FzDb?>{JHYqA4`S<mo9DEbvQA!2h>bz z+;gogC}`4&i5q53m^6urL2J5i+N@rXjN{=p-is>&m6t48!eM$k@@?tcTc!*FJ5>xW z=YVYGQW4_(_5D4+(xHEUe;?&*4_!QGj*N_Ll}OM^k-xvcuisP`y)}!~-rj!4u3e9w z&#$k0`!7WI@|u-*?%vJL(E&B!RFjYQu`;ZQ-p)63=1e8`!>dkjzhBpV<x0q&pU-A* z*tl`!raE069RWeX#uFzz)<kW6we|PyEt$csx5VS;t}}bga!w-n(X(f5jLd8bs;aCH zA3l7bDx5W6JA56eSe)Rs^v9RW{;N}a-n_}Nsruqk5%b4jZ_To*M@Kk872%T;6SMdq zpWdz?zfb1wu2SdqaeJpso5I?l7rQIr$A^a!b~P4yaeFw*%gaITzp^s8qo=23^Je3i zn3$HQsdMMfH7t1%02+r~?ms{5mixW5D=PvEii!?BJ3E`vVddSElhq$Sc+eoI?6zRR zf(2anc7A#Y>WFLU#_y966coI%zurD4H}~Vm<MPg0PtX6^dhqOQbI>UBoH;T+^X+8k zT9>c8^zZVeOAnquZ&&x9x1jd-w-YB$G^|{?^3*o(>3T;W9&TT_cyY6wZPk=p@6X%+ z?-5q_J8<Vt%+vN$Teg_ge7l*RadnmGuP-l~_f~&Dbl?EP;dXxaurRT2@9uKT%F6c0 z*-9Pnmv;vZPyG4h{o=(71sxq829a+czkWUX`T6;cB`<>_A|ehPKhFMs-)}u|rL*Pq z>C?h-&L5|KTqUhuaBPOxw{PEmyxo2u)W6E#|5xn$`}@bm<7*hBqoX%ECr@>8xv{fY z{n`2Xpdn2O35f-vtHVO=`u+%5G2Gc(EuMU=Cot-!-@FE6BclszB8?OGU($)+CzF_% zc;f8YqoAJFG3k5_oBY&N)jjim{HWlOwF;?tceGplkcEES9tMUPGiP$%HZn5$@aCp* zYi+}#+pnLLr@eUbV#OP4W8>f#%hmFagHwpMh6cy+e);1M4mN}OycJbdN+=y#g^3<V z_$E(PGBp*|)YP;ne#Z0f$7BAO{dKYo51u?}nK45G6d%TEXB=K%Tl?{5`g~2*4cAli z^7LffrhBNIICaXYs%lrk?^!EXYRcJGv8)W~+OlO!(C<$lJ~%iyFl^ei>A};dOQ#&@ zmRH=gef#lmZ*M0iCpUw-qpYkCA0BSMaPeYeXD4UFq9t=DOkj|el{Lw@z>t=f#`XI| zvfj#+`+t9Z75=69PfE_Vss&WiKZ?~>Pm<C$GMdCNVfysxHx_QNdiV13a+A_mA(t*+ zR%SRfy}7yhQ1ZV^YxG0y=ljjIx_GdeUDMn={HdLlmDQ6cPh5`o$*%tLfBH1t=t=9> z>;L@mW5Vjy+Ojqk6FNG~a&9=tT9+-EsO&zeyPI23P}aU~j#bGEhxdCv^I2M3uYTiy z&&<SRN=;48iPNXM&2nxm*d{A@@#^aElc!I2@7cRI^TmaQB7%aBbFItO($mvHBl}8= z^kR2i*pPU5Me^~!l21=Om)3fHd-?3yvQ7Cvvq3$~(zmxlSJswJ6!>^mbCwpQBK`2` zlT%8{k{b^V+MYZ~d2?$k_wVoT-D6^8baZt;e!pMeEh`p$_~c1WPfyQ`8ygh={QWB^ zB*Y{yFP|8enVA{+YR&ezy;TLJrAKdV&3^dkQIM{okf4eXr<{FV&qC++YcK9wg@=d7 z>?&Cq^{ej73qiB|dp-VkKbJ)PVn1M9;9K_a5G#|z-QDHl)*{EU_A;~cX`FFk=a=)@ zxpQYyd+6F@{qpheZtihWT6o}qLsx(Q`b!d*E?v?vFqm*_TdsHYw>K*<?K>S*Q?|CZ zf^FTwb@BW8+}+(lMa9OA8<W}(N37kJe4MYPt<6bkB8PYcuZ)Gj{=eU(zkK=P(zmV( zRHvLdv&QN7i`TCoZ@*u6xPg&*m8Mo$T#bJR+vaWC*cfbTe}z2pn6YfttFG|%j}P<P zw`|{T-tcPmoY1+U>z;I1ZOOYU#Q+*6w5|S@@ZrJ1r%^XtrDx8X#U)-c)y>_V9n`{| zsvSOI^5nxOqn!(wt|wf(c5OxYdbxRawNZ<YGS2w60%WqXmX?=A{mNBE(<H8L)G|sd zDl%eFFfb4ZS}9^QlSfQU%%b1{0~?P-!<;#DUU3D7I669J&3}Dut+bq7O-EA`Q_PM6 zMo<s$;E9Mxi^gn&l_6crd}lkUO;%J?bbM1VgKc$JS9tmRd#>l_*@EWN>g(&5EM2;C zZCvOkqp9=f%dd;y-xs*pO|v(CkJYrA{~I<Kl)SqmDQ%v2<j2Ry51%|~0hKupM_0$J z?ArKb#?y~KJ|;6bJU=&AP)Z6kio(Lqe)!liwswB`W1wNMsZ&GW{oCT2DgQ?=c2~>k z>H60bOm2B@S?sSgzd1dXgO5**VN3b@xQ)(<QXX}?{eFLYtEr&SaOv{pPLHo^^=+%a zEn(-EyRg{3e?{fzXI`~?KOU1Vd3VS1VPRsT;?JKyIe&k7b8~V>$1L-FzkWH}MQhgR z6qS~SN-cl#!*{k>=#CF7BR8jgd2o>V)TvWS#>U28K0Zs<tkFsQzhHram!IFVFJDSt zU0*NH%ErcJXp()+M>8+faGK0!8zv?u4u-iFg-v?#`+OKqoH^5@7q`cwtgMWsfr*(p z`)O-#TU#5K_!?F=wn=?`eFYz*eB)!n?s9Q+uij$M&)=UV?|)S{(}wwafuElrL&J<2 z5)+jZXL;0d{C#$I_KiK2#>aXj7hh@f3fYr&XUE1<UE!RZoLuuiEe%?E$nMjt&`+mA z+S=NjQdeCPS>LBxe`igkv4oV=qTJitGOnx;<l*IQef~6b9Vii;Ipecr`EqW<6|0Jt zY8{)DJPnjv89>!mL0MVb{Q2^iE?+KucgJ#$O{LJaYu7C5{#YFAl@5QMb@=y>9~w6Q zJ|34B6c%Qdm6a6`baHaqkbi$)(O1*@e>HP#tHnNk{Agfe;u04pw=MsE-`Uyb$rlzl zg35^Pd3Ot*oDgJ4y>71Wuls3b@bX88TDch-IyyK&11+hs#ij0PTfV*!K7YXU&O~K* z4u-Gq?nb`}n8BuHciGq5TR82=x^?TO%$(`j+1Ytzkt?^7)~rT#6_tRbq(!$Rf3$Lo zw;VT`>62I{Eg-PKB<*8l<1WdHlhLK8ZteG<Z};WNNns_WQ)kaEoo8Ep>2N#$)nl<? zJx?c2nBc&$!gI3Pp>4L+-vk&oZQs89&>^Q?WpAZs&YC5}Fw3^Oto7IR67&3fB5C)l zs;UlstN-`2eM!(t17ZF16A#$`|1)`-ZnRtU_PnM0YJUfXgow1Zwg$$;%qeKmu(gfV z2zdJDjZbD~rc20|`gJOy?loR=OFMgdmPi_>2?$<1(kcA%(a~<N+>R^qGcR6S>>uM5 zdbqN((lI_>J}@xw#M!g0`}Xa-p=ijf6mQbhF=6UdRgqo}Zf@uA@9u({&575n^0oUO zg~8SW+_U-e?k;E+JJganes7iOp+koz%%9J1Yis-G<8k?j9R-R_&CQBay*5^TeI-@t zdwQDg;Rgqs6(@RJSP`gvX0|!Mqod=C8ygp&lB@_lQt|GNC4=iytEa!dzvr*6uD-Lg znEm(n_s1I;nKxu#*8}wt;_H5@>gebgl)t-kYOe?H<$bl)FJ8P@uwjG1!i5VDm9ew4 zA31gmG?8dDlZTm|@5nscY5^IUHQV(4{rz)pY+wXUp_}K+fd<H;x92U4-CYK1hg@41 z%dO-T6eQHJ>GkaC%f%}D<!lYAzvVo6{v6cnE+{Px&0=0*Zxnp%qB?_@`~0rsK~kme z^BFkY=Xb3x=q)Xszi7s@2cI9T(K?ZC-r3n1GjBUfrQ_tYv(2@0K%v5@U~g}qc)Q>J zpGVNjDJnvoe}6pgH<iuW`ti#b6^1XLo_a5R?se`6zl=pdR(xGuorsi_S8Hplh=72D za~qGMl9IZ*`l(Z=7G1d#vT6HvbtO;<qNH@{%$bl#uh6T4vnRP{c61y%d^q#ppPyS2 z4l-@cy&?;aT^r`>OrWmxzS`d(KA*Rr{_EuQjhB`zU;cRQ_Irm8xAT8IDjwe<+jnfj z$rOu<4+=|yR$h9O|K`TVALr};H3u*E<J^3r{9Yxye%zh|PfkuY%)4U|5g9qPN_*P2 zAD>R^3(CmwBqt|>-TwRg`~JVbziaP}FY4>-12tSiv|RuG`r4|!g`H1^Ltb8fOZIg> zUMUj>22k_Tf1V9!bfAS(_>^e&$;Br7|NYXwSNA&?H0$u{>guf9D;BSHpI^bYj&;+f zO(#yB>Uwo`wL8C@jexbxv8<_^))~(<$((fR^S$Ed=TsR&_Se-~)&HyUZHaojXz^n2 z+I@?R3&ZyQ&??bQ$jIpUey^IJm6bJOSINp74-LXruZi5u#$ZtQr(){)_SRNLhJFA4 zRX=(Docs24oyexZ#cqn)+T4GCe|N8`srkwteRfyr>#$d!`S|#DRDIQ25~SI|0U8az zx3@Z5!zxVZy3=)`^Yd(-PfydGICpOE>FN61+ou~I(|Z5u>FI*fQrE}FdIja>*Kd2a zbMt27b#Z&U=3190fo7P$9XjO1BW1$z``g>*#fz0ev-`ikzP=vvV^L>suj_QZScS<a z6()LoIIX`w<fql6H90oS*M-8u!hU=>%pVvL(ed%|aqTlK5qHC4r_Nv1y-KS<wDjYn zqu1XxcNioe;}H-{J3lY>Rg>zc$RFkRYnN|`b$4gC|NBMQs_ae2jT;d?lE%xf-Bn)K zwRo{|QgU+Z?<4o?e&;@nOABjuv8g$)rD1J78`NH5$hfzs5;V*n5E|ZgDJ67c%i>k5 zLPWp5-F{z)A?xNQ)ztL#>9@>ub$fYuc|EnJ1|=mey7YN_{(Z4`g8%<~J|Aywmiux4 z|G)jOuC7+U<Ge5LuGL28RlydG*)w0f$hdU%>e|xn8?J=TwJu+lc)0E2g@w+VR#vm_ z+_`h&=+RasB_$0zyLn7ZOe@^`<(@o$?!I#6O0V3Gf4&{T%X|d&mRVJPQfX~(*WUX7 z(`o&aSFcWGVrHJI=MZ$Ye7at2#*-5hpS*bCalhs>ub|*uyV_a1N?tm}?k-zuoPJK@ zh{KosBHOw@7NsvPG`jUjEc{S2T`yKcN5^O3`9~pp`z9sNnlWR-`t|EieP6rfx<>iu zXTC;8MoJ7NA08Ym`nv{{R+${Yt8D(vum9(1Wo5Nw@nYw8etEs{`CAVjZs+$54-fZv z<ULJC(0Ykgv+xeFsQq<&0}M02zq^~%emKtgqnEGhYJ-)l_?E8PHO0nq+H$GT%+U2A zU)QesG-VZ6sOZYQ>(<ShI%n1Oz@jscj6ZbkaZ_3}Wr_$W|1+2*9%>1yv+8;>^`_VC zzxr`|W-v_HxzqCQzS`Y)YO{Agd6IJJ`gQS1KS1-kWgewW>IJ%>+LFm(*REY(4)fc0 z$nvdT@~Bn&&D*ypuU`-UQB+hEloh{;_u~GO!D^Ey?%r+v^y$-yyLazC^-bMx&VmUO z1YTWVKmXF3kkI?FyURr9O;=y{$guqNHD5(GrA6=V?iLo*RC)gB_lj4WEkf5Xelp|e z_tht|eSCdY#l^)H1=G{gw0hV3`T2o*@)KQ@7Va*8zbZ$0^2v-34-T?4$jHjRyt+F4 z>AU#bOP4L1)Y#ZK;Yj+qIhti2TjkUXbj|Yb**vT}V_EzxpssG;4aJRITJwH*g(U`s z%C1`TDkwE{vDVsGp^>$xCoh8qn^b6_YP|bN!>95xTA!rk?P@&y{QOuNZf(hQ*3{J0 zI<9wihG8-XgKq4uklfkR_2Yw<`_1KGXl-j-Wy2K^y|?CPkcBB@gPQ+5oidNDQtAb| z+cPh#J^V9y_H5~+M~`;O3axH<bn?xstE-<ped>De-aV6&7Xe-U{p$Ai_OC83X8-y7 z_vOv$=cnA7^5*fQquro%v2o)@t=~MnysGl@@}E9^TEr`Drg0=F?Ea?|Y4i>eue4df z@jltiCnqKzvins0;QgM@eNIZc{!IEmt-Sgy)6dCNJ?=GsvG@Bu?d#b#H9rh)-nb#a zP*hM5P^lPIDPvbNgCStLUaVJc`R{MJM#jd<3}3!pj}On%$(=fNsw=OQiNK^ED*_iE z;ahp_5lbBR9P9GFTU#=f=ZMcY%bjJQoam!7E1=p|RkhWvM?z6$^1j;NT-r&YZgq8b zk&%&t47-Y-`>o9V|L3#+BoCF8gam~eftA`^TwEs(9dfF;|8(nx$g7W7;=K1%eeHU7 zcD8$4TN_J5PjBzb$Nl!pu3QP(=$u>{5)~!I%ElISds}Yi`FXacR^L{Kug|!;Dl{cC z(-Yi`HOspbq1wLrc%Q5{14tru+g!U^EAYCEQzuVWzTLRh)6uc9;0iMXD;ryvY|z@n zoO`BK{`q0(JI5k$hk0;({Cp>8=a&x-HirZRD3n$7gs$FQ{{GURpPyTA&UaB-c;P}o z)t?`QQ+qd7e}5O0y<B|y+_}1Q_}8x%FE!1)<l^yY)jO+%smGUwWUsuvJwN&EEYlw^ zm(QOtZ5kWHhRvIuK{K@y5*-H)IGE(z2za6)S#8_e+Pb6euhqAAce`z?zdblLRhxmq z*4CCs+KlJn!-oYWC2KAj#_z3S)z;Q#a8>OKU3)Jy#>a<eSNZ$CJ$r0G17nSijiFNg zW-o4RRL;AzgK<HI?3?KAd7UzWZx3+pnRfc@*`xbve{aaWZ6;$`#M0W@dZ<{|x~ygP zZ0R|3=77c`&ds$xeCUwVk&MXFQzuV4mX(<q85>WWK3zS>*uX&G){I%RoV0XTZOBPT zU~qPJ4onJF)z;=Ne|P8LT<h|JmzPxM*w@QV*NZ)Ldb)nAnQrv9BOe|fHmv-VVv==b z#jPYxF0Mlt7rSq){+`DpW3l1PH|?-B4iyy^Qf4`z>g1}o^R*&5IXR2^e>M!DX;lvo zkA}X!z7v6&=6(-KJ&KBq`s8f89v|<2{Nv+e4==BvtmO3c_G@dS7iV5x23p-V%Pbev z13Yx+j!arwnt`!#^Uj@?KEA&3+S8hvnD*5C6mn_#@}-2q!Oe{=#Yob~$Y{d!>Fv|? z<CV0vxp(f|>EZA1o|mU*WNiHL)m7~$PoHYOWoOWj-{<1!$k?!G=A=DoHDO_5udc3M z9`gRyojWqejvYHRedS8cHEY)<rl+?r^PPR@*fF;XeUq6!YR)k+GXH))mj{hReSdfN z@ZRe0pw%SL&(BxZ)#Z(hjGX%J{*@~tY;0@>Mn+D}Y`h5x2@J`}$unlmIB?*A!;kA1 zE(rYk^=n1^e!DMUz9giiu*Am3N=Qp{|DUGvf96U12#|MHu3YKi>FJo2r8UpCy3M-$ zor0xhWM;gqtZd1vE1b-1JO>UmGCzFtCg$b!2*K6i>yLeTdD*b+O+?PkO-s*wb7@(y zKtaa3j7L#X@y6Eda9)>{mA}5eZg+0yW7PO{*W1reZ!4RvwygRGt2guO{~c`Q76;9u z&6pt(v%AdK;!d2Lo15Dq{rNLzN~#ET-rDxbWzOu`zoR-`bkx+;3JMAu7B5zok&$`u z>{;8pySo?1?X6mL#Mxy>!9ym{oP6=~a}O^q^{)8%$aUrK6T&$k=g)3zWGpHwYB4)% z&vP>U&8$Ure}8S*zP)|#UfY=1*oW`l@r8$n&zLdeN`=nHj~_wHMK-6M{qW#mbJ5$$ zQ>L)EySp!0w(QaE{QaV09xJo&RX&&f^XKz<hOU2YDr#!`zO^h^_lV`3h>E(pvYnkA zCnsmcmluLULP8TJOlSZ_i><Bf%a<=J{{68uGBS$Go>TSp)xjf2ScE!R($dlx{@K=K zXJv8O+S<;TF=Ij9-(MH5UvHl|Q}WB#uZbxsEXm2qFJ8XXe9JDP8dVuI_581fMfU$# zSy>M)Oy2qY{Cv==!b9P1Zfx`HYP+61Nl{Tz0ZnOE=zAF%8aA$9uMb+T*T~Gi$hBK+ z{nvR@jxY6|4x08${{HSRm!ap<pe_0L<z%hPTvmszy|5|OdrQtuAzo>-mYq8-b#!#% zvS*&|>EU_u<cWf@v9NyJ9tS@^zPP<rt)Qf>uI~QB+}b+&$AoFqr?;Ou;{$4@x;w}1 zty+3z`=4~R{|SjnNlf0}-ZyUCIB@9_sCftq^tp3mmp)$42g<~Me}5O0m+uc-8#Oh1 z{@vZ>puVwzp&@8M`Qnbk$60+r#?ZxKObnngrFVCCU#&W|c-teEb6RVE?7Z^j%a@?( zfm76zem)G%{ru^v_njSu%o{gu1WjM+#q4N!@gn14!QK!pR|f}%V?C11iq35g@$vh; zj@ws#(U_(e+tty*!O-BM)Hr*#^u3zTz7-V}2d-Wf<&`p7amg_9<*`25?%dnkLMzO4 z@8@4w;CN$aak{D7iko7(Q7!#;zc?H&vj37c&s*R-+f2!QX=>KLL*>V^+Qs$bF8urZ zJM&nNB&b{dFieu0n|qdZxt?wPzdu`#@2L4{v~$-kuG;OHm)pYDM!9lwa)y53y7BtP zzFKR>1%k?MAsPGA&(E8<b*m{OXb>Vaxa3yi;Wpkw|8rM{cwM}BF{yn?s70f37%LYy z_sbg_lfRs^em`N}JUK=MZEfwS?Rl|Fv#vaU{`_+K{93gsC*NLKDg5`_?flZLy9K`A z9~@+6a`2sHvhu^ePfzaesVuJg`6<=ZWw|YA<am;Y%Awld$NOZ3tyR_@<ealntL*o; zTrN&d!89>HKfjXC&(0RT|NrM_@u$z9l^H-ShvH{v1jWP?XDtm~9mcZYkazp36r)ey zzpFEtWM5m8)#X<$V_oK>*!ln0>-9<POGH7g_Vt@*qZ#th$jE5X-s<nucKTOUSy@_J z3o~Th*<m=>wt5?zQtDLGsxKK#4!5`EuKuvEu&{8+`t|-_UtL`cYSB8E+<JOxskh2h zuU7tjudl5YwpQs?U%PYj+n%esb#-+eeSK~b5fVnm#)cUe6#jfVt)F#UTucl!a2~!c zrV+k6xnHVhM(C8)tF;>z?Pk_m6}!7^hIP3f7Z;a7;Ukxa-}df0b@V7}VPWB+Se4*q zJ_nc2uhS|Dk@9=vFVJ(9b$-pK&J9s_I)&9kw*CBa*}rw>_rJftXInUhNs8;mC@@^v zTm9YZ?fl7;opWz*Q)Spv_V$)mpP#j=y87gO`}P?K&o@f#x}lh<v#+;jqm)tpJsX|q zZ9HLNVI7^Ffh%19@BjZ7v<?rnI1e-z^Y*Q7(vmfMKn0i;i=?FF)Kyw#pPqPrd2>^E z*|KFjYJYDFNZ+eh{q>dTn>TMJ%$&)|0Ga`+`}I<N;^Ip-H5_v{N^MFxDa0dTz;J$^ z?cpaUCyUOTZC`I!R9q}5CwJ~-bhm_r#DR+!1uZQtJ9>N9hRFZ>_fNtwiRIGe%Nr{` zKGNz7u$GjT2GuUlo;_n|m|y=-($UdT$$e=hC_<f8ggE#8erJ8-=FP<O^K6|0r|sBb z@#fxM>9Vr2AMfk`Yv)Z^b7)uTYc_@*6(5t9{*KsFVaUVF3tDS)XK(fPRZf?)s;a6y zyuF3Bw#eF6iM)IFPRV^~B*^Gy9bMgx85flp4s1$2&A>3*EVs!=?J&E1O~A8DQ+z&K zSXwe_M44^b1gf6D->;XitgHl$4FrcSyvo(t*_m;Doh-wHL#^Be1qA|@N@ou~KOng} z(P$>m+gn?mYiewgl9DcLPWNB3bg81Dp`e+WSyKCPtruTjUjFd)YioZ$zu#P|(3f>a zMn)HQm1cufSy@HxI5b!E<-NVT3#KggoUG>I;UQqD^zkFloQ+ay;Jp@XN{22j^`1Cs zQj?r*RYvKjysN83|NQ+6n&w>@yj;oLeEX%^(C|lE=M~?b>d~DqcyCAH;zPg1(zCL< zSh>X-It<d!&AI++wOLnRpIbtL0>gugi`_ws2on<*o(Syh7Pd%Mk}$~-V0iH1;bDe` zxV=@KlIOBFZ`g3)<Ye{2S64J|+`gUs^3u|z_9Z3pU$<mlUX?1Nt*w3I#*GIzH>Z1e zdRDI8r{+JeXPR#GqxJj$9hzVNFVa=;n%wa|*~1qWIx~V&Nb}B}JKc0Eqc2-D8ml#J z%e}p*@bR%jzg~l86)YF6GEO}u0;=1^_2WdYy|F8OB?4Mv!Y!`Hz@Vh0WRQJLXQ|my zS2wpqH*ZSn>FI%%^e`N_c~jE4ozHc--`s*<UoxluE`NE66*Tno;o)J?U%Lw*v;Fz= z=fk(#`JfsAX>@eybx@nqXQmPB#fulY{vu6y7JPW%xUjaJPnLnfJpW$J+V6hx@$&O) zzezGAyt}irbl;9{Ezqcqn(r)@1sPKvKud7GuQ(_8S*_&QtESJ-&tHCgynpI8@%7W^ zO_{Rf%O10}Ax|GYTJ+(@-Me#}nwm5$EoXvueZ=pt6OokkG)_CCptPt{SpCw`Zt<zN zMBbl1f4*PNrosU<UOvyZT1YVP@-pAnTt`Pot?&7_wrCzbeq8(Li)YW&YUa<Ir}yXe z)2B;6SY2Bi?Ji&Qfl+W`(EoGi&P|y%&CSL2>zSwbs^8l(IlR8UzP`77VoP0YOpI3S zqOI#@nCH*?@O$y<)!zK_b|ThGq{98r@bmXvWi>N1%ec44^3UJD8*^`)Eo|uCyVtg1 z(bfrX-@Ix0CT*T~q=}XL!p`FKFYoWiPni+#URP(gBuMko<HxOs=Q3Pa?9P8?o~`uH zpFek$y_JfIjh%W+WctL3jcI3RF*3yMsbFL<Fg6z6mYR|RN-<u)qa!01hOQ1<daUBl zk3!J;NSBr+OH>knuMS_oq3Uba!<x#IKc?x&_ifl<@Z{OEq)$&yRy^)CXK;{Mua(C* z*+T`iKn}E6=xDci@{<!2CwTo#$n^A{rqj4}t7+P~Ih}w0)PUL?pu&0a;>9->UX|Hs z?`RMv{^Q3Fj?Jz2_Ev*pD)ZtZSC$4JU*FCZ8M#j$X&Yr;?pgGMr{?Rct6K^lI=#BQ zoZq(cQ%i?Ogs-lR&75cF=lgSu=_n`#-E_OkW22zZ(9to=G~10|-fqc}BQCG*?k->X zd-|2N(dG}UQ3fx=D`c1Z&tC=_x(*AQ7W6+dGSbBbG{%1J+_^(_^?yFHGcHhcZVUNy zHu&)M>(d!7yx;#nF17ZW8)(sMMDU+8GmVqlLy{}l&PDLv*p@rnz}vd&i-weWUXNMs zEe4HQ8>6D4wB{UteQ&SzEVEoKuQgLAPMgM7UtfPB#i-=f6;4pUB_>9OjbDzZ)1}F+ zSL)&Q`1+%_^Y`<DwruUK5_Pz^_k-%~6S^@w1P&fNIKgXa#NH~?hDF^^K`Ury%#Z*@ z(6eXHvcBtUDkw1I@B67X%QU;Kk(nK|Z3|TFHM8-G+^VduR<^d52CXq!KEH0&h5bHi zhbOE1D@;CVka&nCQT}IOV>`cm*v)FtxaAzHQm)g}be%IYGNyiwzTG2f%=YZrGY(G9 zMjy52>C?sg<n8+!8W=V@uP&>Rw@5ZUa{apaa{u{y;kVoQ<+DPW)@!a?w{B|G&(*tZ zYk!HDnVD_awyo~1_Qmev!oq`3Pfss=azgOSySuwj{aV}WH`j`_zP?@nG~@a0&CTWq z4-z&WUKLi8)Vfh>Q|@gu50yzqw}1ZrUHs{q(Y0&W3`|UpTwd<K`pdRuJByz){n(x* zAAJ7$b#c)8-ViNT!Ndm#8gFb&ZoiQjsy(mKIIQ{9tX6LoA)AU14Z=IbvhMG*&AYp+ zb;k~ig<qb(o^&!L10-^PUvKgAbA`GeiaL6GTQ_gs9PlLd_qVqardd-?1cvg%%=!KE zXW^%7L7#SWcg0`*w`)m|rrn<p&I~r(`ugtf?x0C{D=RC8hKq~clOG@JRdNrt1=na% z+j3Tx?F{I2X?lBm`}G2sHLD_`qL>(hf`eCYxgWULZDHZ#V>h<v-_M?&y;l3y_Wb_p z@9!ML!^Igui^U(VUcXPsa@DHioO3oxEz1)-w>kf;LE)n#UT@P=Q&|_RIFcTE>GI{n zXJ#5Zy8L+5t-or^`&(-=FE86s{~y%XV_?{vcJ|ODRd1KRRau2h>1*0n&T9SqCb~H1 z)|Qn)zfX!UUU_Qug{NvhGZ>7GjsN`n{l0X2PKK&U))fv<PtOb2ud_3N78XUE+iv!N z<=hMouXBegzpafrdF#3A>&4U8_{M!IJQ?*ebu0V7*oi)|y59m9yMZ>n%{I>u>)5)B zZy|HT#*K!ccKDk&IW_<Peh<A@pPQDL*r@J5@4$r%0t_E6y30TOeBNH%a+Q`+lAz?V zS0?4<<qMmpn1#l!_EgQDKYdMq+$OWilgCr98ij}6-m@j@&Dq)J%ia6s0>i?@cJA7x zb>!D!etQ81DZ?a}t$W1H^X@1xTv_Pcp7nD7HgA7_b!KMfhvj)kyF`=Pzuej(B%Q4E z^XK#V7k8Cr&#RrjDCO<vJ9lDQf4xx6o;<xKCQP@ubnDrtkEgCVnwOc`d8}8OxuIa{ z<~iUs52Bk^Ik)r4K6v}K_rwVg7dN+6dnG2VOv}pZI&#DX6k<Df?gTA${qprIXq;lB z^J){n2R_;=>gvhY*TsU?&^&tdC?PYmbN~N;(Qh`aI&yNd`svUIu9Gb-EfqC2IYE7} z{rl}ftKl9${(Nh_wz4uaCnx8Hix(Z6*?2*t3+?>!PVVmPYHDg9kQZ#Ug2s<+wxKN8 z5D^obc57b+lewvBs06pe%Js(&9AIFWFnRLlsP#Kdgw_3AQc_gRa&H~s+#{r;qx0d% z$7GY78v>P;m7ukcpkavsvGCaiOzBdfMarNJFdxpE-&fGr_rDRhsm@gR{^jNVpe+|i zjvPt2x+?U=m6gJF|Nj(!d3}BTrP^t0YV{_1h`d_dFJ~LI5EOfIa&k+r8R_5LXA!#f zhIevG3JYjlZOxb0x~Cr;Y&NX@Rr2P}PT|#IYlY73-u!9vh7AH<qR*c{PkwZy^TOrJ zhi4cjAK_d3=!jk0`59Kr{pYJ?XJ<1xw6(RFWL{DM?Y_FZyS%@ssOSh^|I`VSCOKVS z7rS`<{(rOP%$?g>-23=g@9Hn-z3-k%n)Tw;RBe`qT_rDr);>Nn$8s{mh4A>=(6x`R zlz}RWs;{p&|NGbf`RKmUd6j|R10Q8syP6qazI@?e*!%O@>?t#5Xq0)ZVM;NQto{G@ zdrD4@55tP^^>HBq0Ra!|wrDoq-%~l6A>jA7x2sF%?AT#3$wTGJx>)OnhpfXaRVV*w zWM)6Yx6<i{nbESscXxI+FLZ8K(%0v|yxjlzy}i|-wQCy>Cy6Rd^e`xT;xWgvn5|dJ z^w7rS;{tMWaS!WE3ZEL5zPi4ipW(!*Q>(5O-rAbY9v>fnXIClra=*E&u5HZPz07y^ zqibuU53zRs{rz1$Px1=eoC7nD%{0vx1Fbx|7M-8?^wiV|UO)G*+*VXnbZA}dZqRI$ zY4)`Tx3*>{wTEb*5P$xl`cQoQ>aeu}!otj*E=)>I{r&txLPAIQR>%C%SH7$vt`~FQ z-rj1^5Y_vAzx`gXKbO`pd$zRQuNTTEQjBW8Ty#%r57usJX>suP=igoaK5WO1$)SDC z&CK84-{<diX*zVsX-np1w)Js)g{;>Y6*8qurM|wlmZ9sKqnVkRn59%$=raHLeA(IA zG8P33qP%*qnWm+sfp)ooX5`=8Fx+@}r6_1=Y|ia%ybPf2tDt4=o<Y7xIp<{ZC<)oI zwzsu)$?~msYHMrb;NxraQ9BG?@V7i{!v8+d6tI$eP<4-#DHpex4nshR^@2SU`j<Uo zIcMS)6f`LyrBOd>b?p<=V_RPyGVwJ_H~<=hNPd5B?}@W#MXl#VJ>GoY4z$~VfuUdC z-tBmwtZSc#t=|KmWEC|vriOr3ldkIVN}I6+d~sZBcIy0jc7{aWSFet>UtE2@jaOPg zLV|+<G)__V^_6Oo%PNrPo$b0O=>I*QHT_l0T5sVK`SO$R`-KVLt9q@=Z~)ZMNKU>c zdc04zdGcgoh6g`BKAvG;zwd;gCTOi#a;U?;2cEvuem*_?;_B;LTeA;Yz4xB3CpvA; zRgpOdB$L;0br>?|Us%A{)YSCh(NS(0%c3R6j;-~6cYnYB95GHlzGIJ%_q+DJh=(Xn zNl$0i*!5_i8fb+N!-n+p^Q2_AuLD)LJByzyO!QEgeDcD++UkwYLIq6eYq~sDggjJ) zzzgDUd)evz+gk9@sinQ$S!rUz-(O!Dy3UDvFAefg5d!U5VAxRn+|NTrs7KCrS6aM; z_S8Ke+<mX>Pl!)AD!wUHUR+$f=I__*3|-f%-(Oid`Glb8LzZ)^?mRm?dt>eIvLnZj zcguFI04<KTsr<C$irM}@pSnMorkoH+?0tUXga^Zcna1f3E({GTR%o<7-&5FFXAfHo zuxHOI?UFD~Nl8hDu4{tpJ$+}HG&VOggBGVro9A75aijF)@Av!r6`k7{7(m0TJ<{fW zPdY3bH)nws3I6}{+<wFM?d>i~2QMsi-k5e)DrRq0=wof^P}SJjSe^KNd#;!@HZ~p# zUmdo#Wr>derNF?zj5|9FWn^Tg2<@=BX?#{;y@C4v7c131>g-7aCB2NBn^YSXt(us0 zebIB4bF1d8U8~C{W1(R4@9+2fAOHP+fB5E2Nii|87uVOzi|NPpoH*g}<jIo`iOjFF ztV*@aa&82?$_>7D?b@O1pmmGd+S(;AE--d>cJ3&DFSlsXB2Y8GqPkjHON&cCe&3O; z+1C?NQ<nxle{^I2_Twk>r?2*$b0GWN+uPe)U&|cpkyL(lNd2pe^vtVSbFIsdy}P?x zP)KOehQCL<#Vtx+2=K{Tu`GBo@BOyi+e#W59#dv|m;QRt%)cS)s@9sAok6*?AJrFt z7R)ZlNUQz)%oj9YQ2+n0c^j`Zo42=j&aEw+)@5%T5)&7O$=mHOe9X3J@#2entIIb! zuM9eQ@+1R;we@Z(`P=8u^Z)ww3$)WOFHi4!&<ZyzE2|x)uf=AW=kqBwO`a?~&%R#I z&)|`s`?;*$s@~HC7$$kBuq?QuUtC<w<PaAZm(>0@>dE@{4h<WdIZ`GW3pT7xnLVlQ z$3u1|hqt%3Dl?S){FGYt<HN#3+n%1De*HxDO0S6%Cmwn|%|pc`;Q&KdXQ!a`8ZBV~ z0SAT`M>>TU^}K)n+@0aYlarGd^~7J#xv|0V$NxLq^Wy`P9yq^P6Log3wK!<@t3Yv@ zl~5<k{hH6dysn|eX=i7JzAEb9|L@o852b&9l`{OFcY9yyYcU@mAJ9C=GT+&YDnCEl zQTlqClXUKtC7!|(l9Gw<@9lkYX(_i`k3^$&`MVC;YuS_IH)LdIYoGeDxB5F9gN$ue z$dr$-XL(Lm18v`8D0p!}@z1y0`KEHr>IGqIRfIfeiWjl6vp+uCExt&mYE52QSs7^0 z?NvMboEruYvyb=5GBi9pI~z2e!N9=J&;R1Z3x*%&nb+6H%g636Tl?(9YX5FA-Gb-m zWI-!NckS8*no+v2(3ySD_j}b9-`>o;@i27Oo&)U>+#f$wewbDM?2M#@q$DGQTaQHG z=j_ehM(@*04{c6ApK-8>H6<x&(YFmh=U5i6*sx(j$3NR6tKPO>n3=VzZXds#&4Q1Q zj|cCq`pUr&85w!;+1c5iYLh!9GLJ4@zFe5W$kbF+x9!j&r%f9+D69<eTDfxNqN9P= z@9e1z{!x8xWAbq++1cq2)|?U*5dpO`Hf-O1{L#_wkDwJQX1{*@0*#<f(~V|ZIpx3f zwa~M(Ob<UhJG=1lF<ur{)`vGYr-Opz;oG;Mok<%HYj6Mk{XMgW)h-3Gl_6Z>;^HS# zjQ;%nejjAvmi+s15p`ccQxnH}rL%K#{+&L#D#XQwWzO8WhRMfxmMmYsIDUVfgke&P zleDz7^q;TS<3arck3b{e%gcPFW$bDs_W%E94eIzAr=L4;^eC%w`Z*D;IhjVj9uF8E zJbT8*u%qB%(~80?rqX6P4O6FzG9;XuqUjWQ_ti1ZIia0r&iMGuFkt-m?;mL1?$(yf zX6JUkhYt=m|M+-ZzO~HH&#$AePfYJ$!kQfyE(Cz~-X80bWN4VG9e(KGK}L1IIRciO zF4@-n5OBCC$ZA;n`Wi0-Xn#WB;}zX{aeFkbc$b%#ub*gW*|_<-n5=9sXyN$hXJ-wJ zj6j1|g@1pQetCJ>{o&*l^XJQ-n`7Dh?Ck7r3Ej&j$BrEXZ4%In-NoYX@2{ewvY`C^ zy&1OE+m7kYtbBjZmO)@uNvCUFer-v~mKB9pTy>+i9JsPFn32KI(9mgZ_p2kEb3&yA z6HiW3eQ|LyJE+<7?(Xi#r>1Iy#$LaC`NHt$cY6wGLu}zAmtOrZ2eyQR7DY-*cIxl{ z6Qtq&`rW&A6Tj|zy8Zjs?CXA4EZ)3%b74znu!_2Rca-9qby0h(wr-I7^Wb3f>RKDW z2Wx_ijEz5n8afA?SQV81Jh%UUaHetkg=N0dtz{Q4UVOSQ!Z*&=D>yy!&DW4+S5|~* z9bFT-x!~WQN(&2%2d}QK1}(z<_4W1XHM#+lK{Wz{1GtWFNq?9$`F{KSxpUW+{Phog z%yLfa4QMO!w{OS#WUUkO^7;<9^Cw?i<hml<f2YxV&?2JRjZu$}^)fPac6NqJ>0jpY z^z>wCXycU*tGKThyX(QFrQV=+c2QB0LFy?H9tnd7|8H2o->{<ZJ^z00js)kBH?}H) z%1T{MIUT0o;*xX%n{>Zr=yXc?hP>H$B;$?hx4bv3Z$6o3xh!_uC>`jiqv4xSSN~zR zxsJ{T?%g^M_MCsL{QaJ0dinczJB^E<6?5?Nnr@rPCM+g)teKtv#BB5RH?JRXv??fm z{OsAXEVDK7`|mAroN=kqo9EH3t=U&r1U7q5*8?s0fBgQv|6;e^NxJzSSx1wOb_MRK zC~RtK3JK)#{Pys?{ePANSFf7-e$CCzjoeY7SpDtI!h(l~-rU^GZf<VA*?(pH{yJGj z7E$f6E2n<u=}q|_Ub$aYvVZ-0eK9dH4#f{2J{UyWUuyLJ@@)P7f1nvUo61k1J@Q50 z-rQ6Pe)iIF@x=?PLbY22a&B%qn(@}_jK7NuXyfCtLx-Be)<!K|y;e*&3Y5yTuB>oO zNKkn9?%kW4n~!@;lj{4#5V$f(b@R;$6QoSD5)u;+{`~yBv%A}PyXAY;Y15{?^6Tmr z*Pr!9G1#i0GcIOFL1P=Qw2+L9&*x`ne?IO9Rs7~v_MnpZ!13ei-f#X-eQ|tG<!25) zzGbPWr@5W93SZ>H={Lv1@%y{GoZQ@tb8m0+nQeAf=k=qRnSZ4f^6%}Lq8Z$_VFPIA zeSTi?z38;_^VTkt4Nb}G?JapQDTI@UXG!Gdw3fEEOWSgz%ii2*?CtIK{8dz3yx4cP znN8&<7JdEoKB6mBJf;8r`{y&y1~j9j=07iIOIdDCPQ>mqUC<i;#TO0o?pT2OU55@I z?!DG-x1>DtfQZJ$4_+mEj@anL?h@&^e$u}9S<gr769EsyJf}UrxjFsN#fyOqi%MT# zQ?jzU^`!RRu2SzCH*az}fVM1L^_reys~5jdr%POaUEQ>0N%!~FD%Jn{!zA$T-8;!; zta8%Q+Mk}BRMyeaafyhCX#28~znP6!s3BrQLgP-~%J-T93mO<)HYOeIxwlQG(R-4r zjm?~}wNaqKz}d5<rOk2_-1}tI-e13XaiZ^Rv&7uovwJE(XIx&^%ae6Fi9-?OudUhF zpM89M+$8VLjGLR&XRq0xc6JtMDekGM+Mu0|S0Z?Wiyt53y|<^*xs^-QXzDS?RxZ(o zir*^FQjd0tI{eY=3103exi$CY0o9Y2c9-Y>`TMu9q$K71JliLyrfMJlm3M24rhA{v z!Gi}I?f?B?c6WDY<B>Sf$jrW@{QbN;+VeO$`S{cn6dEc&KMUMjRa*7!&B@v3`7bUn z=db?uCh+p2SzZ11|7HX)_XDM`bul}g=3148^cDp#%()u0EiY9J)DvRJySFDZ&08h+ z)|Q11jZ6$BFE1V4(JNi+qkmFNCuT<g!=Zck;_mD!J)Kj=!p`39*v!V6ot?ebWJ&0% z5KlALm4Bvx{9jTlH&r`ator-AvmdI}R8(B9tO#^wSme?v1j?dnuV24jzhA5&Vn@Nk zlfOK;zrVXH+@KM>tY@e1L=MHWx3`wo>F3?wm%F9R)aitVVyBt7e%z9<wNWna?wf0W zm)+Wyo1Hfqv?cEL_Wbno^K9?zC~R(G<vul~b7qHD=qdpb5l}3C`0`~*?C!EFtHaOd z{9bhU(4maGyG%jLL3JV~G_&&u?X4<Z{QdE(SEpLJ#X(0%_+F}u>g?`TE`N8&#ohh$ zx3|%gS?79vQIFqO)6&`+xHT(OFLqbT9Jk(Y8VV=HTwGi_`0f7$FeDx65PW8)9$ozD zi6>)+Rq3l4x2NQIy12AtTwOJl!R6ndpRNuL4S~1oKR#;Ruw{$L&(F`r4Gj(5a&Jpm zSXy!(c(FculG!r9xmpYhFJ`!egiHy%H6{Cjkgl5VtRriqx37rYtaf>sukm(EA<tPG zH*QS4y)Ac3{{4B=_2Vxs@f2oaX70WA@8o3l&feaod3SfI#ozbmF4B&Cmh|Sv#)!yB z#TJ8EZo5hz2u(dbUEjF+TTaoF69+#%J$<z&Nysxy)xA$9=f;Lcw_d4_PfiL;ndhBZ z?B3sVY1{ny@&fbK%#A-CWS3_s`28){I9e$%V48CI+gqtqzAa%kZ`iTJ!mU@zb#2tv z6|uX`K+7H5yhPR1MJ}$7-(Rv_x8=a?+q28x-!rWGlA#s8Zq7S1)k$X>wr(}uUH10S z*|WXX-``!_k{R68+<f`&y7lYz8RpHK_cHIah=^{Kh=TLB%bs6A>x39w+})*B<9C!i zVB3&zkSQlO*RuE-&vO6y$BrFqbL|$B+$--a&oxaaa?(3H^SnDJetv$wGGHOo{rdm4 zyKYbRFcRKb^z_k#gUuF}mY|LBQCl(&t`1*+>CU}waedId_P1}}EUc}iF9tnUl&yGn z_}aB;kB)XTuZVj2($T7b`Np0~<Hhd%Vg1K@Btb1RN%K6J^mB6_etUcS#;sdIva)Ai zU0oe2X)7)+UiIyb=TxoGE5*;x&p&?mu55UCc%QsI-;w1$Z?3JCzPqb5`P!ODP|b9# zS9){#`#6TA<m8{PR<GZ3i}CHmo!#BsvAaqZ7Ck*R$D+__{q?W!?phz~m*+q7`ny); zPSr_oTISA`1?{f5cyS_VDrjqVcv5om<tx`FD!X@dcP|cH?6&gRPIK|DXMZ-QpFfk+ zsiGLX%!l#8wYAZi`~HXY2yuO%7qGYLtIG2`ckUe7SNprAzrR0XXVKD(Yinj&l)jqs z;nOD}^SnC(P8@;Dd?Y`<xTq{BC#M$^8`~=2WRiO;#HR9-%buE_K_>b4VmK6CRt7D- zV%wyrr>A6M62hVA5)%`%>8;AP)gdc`KpQ?EU0m$GDD(2Ns=a!t=eM`Fw>Q4;P_aFs zQS!Oq`@7h{9R-Pu9r^oys`=)Ad3DvBA?fO>P`7R8DnN}{CV{D1p+?&^C%HsKMR7Uw z$XFW1zD+sje%#0F+#Jiw-{00&$;iq1^~qSS2wg3<+<*SFFE20m$XZVmR`>gG-v0lJ zzy++_VoO{)g>Kxswd&%k?fLhYc~92^ZP(4+9I()7ihjIYL*(YPhfklnc8lrW*q$H1 z>8*-d{l7m`^kQcTsd~LIb(N5nJv&7+_(F!sj~_pl{5?C-V-rW}>1nCQ`(z`cqd|G- z+Pc{6fWJF-SbTebzrVGW_3SKD<B3yW9zS@H@qotbze0}}rL2qITUEO2)<nKL3|1vC z4t#le`Re1BmzQ5&8La;1%^MDGZqPcIE9+usE4%ltc<tZdXUOgD?he`<HGjT*JD)7m zg;`y{zg+gexv$nbdRtE5^6g&*k5+trCCV>v_vGW_<4;ac*T4En+B{E1L!$#UIr{G1 zysXMj73+Z2VY;SuOY`sV`|<nt>)7vqetx#8{?;R9nkAuXx@u)XK>?^1V_|3i{O+!G z@oZ&JP=mMeNBin8K8wBC^BA1l`JSGgZJs6a>-P41Nzlx#pP%0pjX)-DZtkL|r(Eyu zDh<v#ef&7+D1?CZakf?8-pqVbwLWg|hYueXWL{qO<?Ze8d}(eGjRP+(F3!BPgfsbg zpYPT`=k5RV9Ow{K{_@UQ=_Fr8Wu;-t2>~T#<(D@$D*ylYdwty3DKn;s=|;`CWV1M6 zMSvoMlamuTA?rqM31H8etmf-g?d&$|()1LelC_uBkAHl8oK+zvCdMaYqKf4csU1H% zJ39qI%P|{3J5j%SO@IC9krG4U$45tbHW<`~tPb;K0Bu)!X68Dnqf1nq%OiePpe0j% z|IfGE?>GFI$=dm(_Q<76lg`dI|9p^LzTn%NNHw1s6Ow)&IN$)<#I$&^vYwuvWJ>C- zi4$MUoX*J1#_;m?Gj-VtGtg-vS61J-y*>Zt&SLeQ#m|=|AMaD!=B0FUkBCmh1YT*g zgxuV-XJ#5-&7HdoRH87<wJtxW@%d8gq+>=VCRff(^AIww_>iCw=c2uKk=~`o{mb9n z+S<K6|Nf<AzS2d{&*kP7s|allTI|NF<~z$JCr8J&`rDJE-QrfKbMNdBY*-h&J8em2 zrrX7mj;=1F&8kANPfku|Z<uMEzHH^bk_YcKUteF(z94#gUfMPnrIRwC!9#w2emR?p z1%CNzPkw!U9ka8jwM$g{(UT`BY}~x=p2|{^k~5QbetLTP@ynN;?d|N%Y`k965BvLl zx_M=eeZAey>|+yVo3WZ^Ut<Z{W~;h{*<bnPPDP_%Z2o&}b#!!koZI;(n&-#OGRd5@ zaGQt9Oi^!d?`!K~L6g3-&2qgqxtCvF=F0$TRLDGA${8IU4Vr}y(g|PSz*tjTYgzZl zqOY$n(nxrrk?LCR<P*NLnOtvvK0DhybCteqh1AJ4<}G$I_H}d0-`{)q@S$U$jOCf! zJ{8GLhgNvZpV++9EhTed$jYEUzh19**y9|qZ5pQ{=%^&AUN!HtQJRvhix)5cy6*GW z>+!`uK0H(@I^WF38}$A3@1H*ni=KGQopgaq-GAPZqeoj`U0q%L?2M$t_A8saySd}y z;w-GKH&=X23e~H+xhb_F?`CG~rz@a=`ntcrtfre!sScR#venYlqT$xQ+T9O%C3MyP z**f1`XIlKs=i#eYTA&j?Kr5Ek8i5w`gVO2N?CWA*UtbqLKi^*5i38NSc=+_G>YO=q zj^ywEtJWg0D0X+*qO!NQ4qd$(Dq~ULkh?hR>Z(QV{c=&M{W6wHT48H6c9p+hckAQ+ z|9|~=?A+P;>gsB4dwcuBH#ZCeHzv7)_M)iVj513(A;8#C`T5z*XJ;qAaLu}XLZ~jU z`1v_eVRb*B;`p{4eV@)7HzL+1o11Uvd2Oxy^5*8{3@+__vMmDtb9b%@Uq5fAu5r)F z$?Dt=J@WQ;M~gb`mCMV&s}!AA_n#+nxQ$oXiR0q>c>BVCe=6rry5JT4_4W1e)Vb1T zIT|e&bic;zD#<MT|F0HQoqT$JUjN_U@9~0ia_jCz@A`E?ReSEGy(?}k@m_T6&W&5Q zxE!`*T|M<+*QLhgg0*=aV!BZso72y)I)18u{<_)kpPrun>OW`wh0>|HH#RK%r3z{; z3Mjqwy|*Gzd8^OMOG~%D`SoP7Ka0Y;xV>3xwmVN^<0*V_@#4irVQZs2<*w}e_bVIJ z5Lavw*tc)rquKfUJcHB{qd_ANp{v70udWIeUhY3%%;|`|O4++Rku{%Asz3Vi@v+rw zYisN7^Y;H^N?u-aJ$-CX<!3H_e*TL~y{D(hJ5AjezAi?SjZa47&)>gWZ~4Deyb;sV z($eA7%EjsM=Js~~(if}4*PCt6WHZdYWy08Dn0#zWgx~eO&tAOHu(7eZQV&|Mb@y(p zi@Q5_d3m{FiwDR}oL^P5uB=dO5jb@6q^IrjErDyJOuxpQon?A;zi9iK)%`7{Q;L3B zd|2$>-&OYZR_C*`v(sl)`~I}m3tG}~uypMuOXd&v7H3RzcXc%^c;KL0x(qa}z1Cj) zly%oK%LQ4p<SmO@TDirQS`;)iJk~B={bqIedX3m!CLivb3A#qdK74z7d)CY*R_;~L z<M&h?ykGynckkZ4tBz}*{PX0*#O574EROZdp9dWjw{hdb=<Ru++P7EQ{L!;#$By+% zgBmqI{{4Qx^;AVg#frB+GYlF*$B<=adajS#Yf<!s<NSR4^k-*gMnpwDdis=g!jig- z3=R9gUnZ}*x;|iKkm{d5e;R)LzI5(fU-<gCi<?rtXPM=$nijn!L$I;25wtq4=G)Em zsJHB_tc71*1ipFuR?un2zq40B&3~iXUnP6??2)i2P&hx&RylrOO=RBbrJD|`B=WUi z0WIS4on`Xy&d%aBaeHSSYULJ|mF;y~ys+%;tv??Q^Mj@jJEphzMW`v3m6h34d|>eQ z_WtzjEcYMvuQ{2SE4^&hr*!!Fm01<a?>hBza@)_#{`N~9o7r00+k=<;&GlKh?D~p8 z<$wQv=g+gR&nt+1dEm0AmpQ1V^yB{jf6LvZxD+pBm{{fSJ2_ds_}v{#B_*YT;^N@* zueGw%(~mE9@87UtL%{cPwSA!e+Pb<xp?8dXYknFzEIXU1bMfr%^7k7yZ1DKBAZ&M8 zu3N9v(cR_mLG9Od>(+UmQc-z$`2Oqb>l^<IJ<z!B?Bq1*ivNrZb<0WB9JQaH@qT`O zKK%M=;oH+MId8Chd3U$DcKEs{S5^i))I7*q7qjzB&eX(+$fN&{96xeoNraw>iHN_y z|D#8bR>bTyDt>n6;jvz6&`5o+oAbv<M{n*ZRF2(UcJ%Jux%>b9;{M?;WR)n{Dqr`b z@!Hzx<ix~-e|~;${J&%#GZPc2Zx^>-ajBiqr3H@6QQLAnUtU@oI`{XHFR!k4FZZ7> zBrcvl!DXwaq*;!{=Vxb?)zsQ<+_;e<9QxA9>O;w-OT32l|7!N^*;DcTo$R%1*K%%d za?LiGGhtiq?V$B>ws!x1JPw&W0hIRCd}jr$jWR7|nfF6Y-nvZ3cedHn$^Ld1Uj<uz zSmWu|*Y)Z7`T0xgiY(U)_f<`*<~Tc9oxk|`xuxFI^>S`+)9tL?xN+mmybzX;{O7yH z^^cuA$*I`#>tCAcl=BukIyy&-%HQ4bEIN1d=FG|J{#kR2OG~d-Nn8kZ6P*0%!-oLb zy-iD(F5T5?T3Fct+C2Buda0ezG;ht>i-O_=AD#4>q8lCdxBB|JSkMUVdsxv1s#{;b zo}Cl><NdSQCYh7`0;^+FrA;ypY|Xx2@#n`zt4SA2C&%wD)Ag)ACB7=_>Z+5sbWh66 z$PP)#&tHGNgMEv;t)^|uwYAaHJ32T(11M_#^VVFgi;0O@CM~Mj(%QQ6@~_j=^_K@P z_e<M$!eEL|cw5ga70LdsTTL%sy!htM&dUnydd)XBDJ)#La8cl5w?~Wn?S!n$-<hn) zdwXjutAgKLt5l`eD!(R0PMVo=RO4e0=tw#y0ak7?kp`(N(?cV+WK3i@(!j`kCbvt4 zwM#@(iQ(f(_4yJZ{_mL2H{G~>yZFb4M9>K2tu2|!0kNs^tA!-gCwi28esGX^TmF5& zjY&sC5`}AnzND#5v3U^mUa@%bk?A&7UrsEjy41MeokI~E2&I}68~$+?+%p%`i}CRB z0c}8CQvUv4$cli*&FSYiRe#Sbp1sWc;lqavk$OMg)jA8#GECXd;KBYcPEbb1r=-M$ zkB@Ja(_|MV&r`F_^CR}vSYEq!4RkthL}cX0$Nlz9AMTdlf4MbP(|7^P9L<X_PJVp5 z{eIB)yjTbOnJ=cCl32B8dc><p`6>T|wHaSsE>8<#3u&^OI)k-#BHtfdr<0s(o^VX_ zP}vo^B|~uG!i6PoZ%tj~+RX%-goufa-C6ZjYyba$yJzZN;ZJp$9(C+s@N&PEjvIcR zaG4$L74_0y_3!63ElMl3c&<230GYSbvgEDqbPt8kX}PC7l$4Y}Bg|rAVm*?^Zno<$ zX3VfE)e_jBt+I9R)tQX7i!QvrzW)5x)!{F1ZdPAl>vVOg<-83&dbuBO+=vK0AG30D z#Q8hduTS@yss)<2n*09oj>5+l#m{)Q=ifhe?b@^#FEYZ`$F1GA{LB1^|1shBcio!| z8rOdEWXY?I>NRIi^&Ggk*nMTlN+H{-F9ttX+&y^E@vrsLnlGLPt}b&`ii_Uev1EL) zG+x)xcBU#<?4q-Oetu?Euqu1A;`6TM%a=18S>`+2=!Vf@NrQw2h9iqyyMuJ5e=t{k zxQ-<@=p5(i7n3Gk3q3BdGF`Fd#`gUAA3lB*)DB-Ka(0%f@N&PoLUD0%kB;?9NBvd* zr|W(0UdxM1$^JiPO*Jd^44W;)&CSi&;W=6DW&H6K{eqKxdV4(1MyZ^;GsR+e@S}_V zj~*XcJnzb>!}ZD&pBQ<*l<G}YU$l7fOv_?5sou8t`+obSORBOyxwEs__|g`Wg=?;= zs~?#x)iq`F+O=!X1@2k2==vg8?r(2zPtTEctzGXs+iXwm?`fbNZM#Y`y{2d^48F4} zY;DvWyV_Zom-`!+y@~LfV{y>_|DVIh<?H9@RX?<UdQeE!>%*(7t5vQa{eM10YgMbN z*OUO(%|4x<cGvv<Rl4`JhoX3=%H&BAi*2;Dyu6Rwn3#lkJJ<aA@iFT7*;%IEfyFk3 zKU-d0@~Qv$2z1ugVuwbiE33o#^YinK_ZlxtzPc*Zrsl^4G2JK??K048oL1<nBRh+q zTa>?xnbowxh|9InH!#I`%9UxiOFTVaFHWB~=gQ`$xpQSfhl<^}vBIm_OUKDch+X*A zW}6vv<f<zwEcD~|g(SC@c!tfMBx6}5AS!zF@^b&L>y%}GRJRmu){?q0>5Oku@23?j zG<0P@ACY?0*&lpa#^19!W_sGLbw{jjc6M}dm|ptx`~80ZZFAffCtg_*_~qT***lA$ zZ_2#9tjFkLg2?g7_Vsm>x2#{kZO6W#^PGi6MTah30>x#~(^E^`PO7`e|NVSKL?fV~ z@bR&a*W>FqCLCm9*t2I3Xzc6is?gxK7gZy3y>fDLDn38!P2}fZHuLQC6t{PGb}BOj zu8XlOo~<Ofa(&};z1S$5iVqGTr!4ZEtQPfis<cUl!lA>5TLql<)cy|Jv15md<-a$Z z&x6+BwF)@7xVkQlisQJubB?r0#)48`j=!H8(oNIO%ur-7eO}__;_BL&bhL|8TU)#E z|G&RH8}xER*2l#%Jo@wV^D{Hm(+k(U{Qvv?eo3L_LCbt3o9pL4<@jUkG}CRe@`p8! zNxenAZi|;D&#U+{`NxmT{`S6s#WqVXPS!j7<;|IHas3Y;KOQ`E$f?)FA2fK%#wT;) z$H&K!8xk0e)6bn@(B^%9^1jr=ld!b_lhqkSG=q+unU-Q3x39+Y`MJ53A099or=2mV ztUtxGQZY$SO3}!ZDX#NmXJ6m3YuCiMxw(~;l!8RdC(M`z8tvVl7yIhU%E>B%yhqrl zcuw8YllbPw#vea^T-aM(er;Xs>hQS}CJ1;<)9GBhR<~cy)~j^=R?8DJjnyw+yy)WQ zHpw{M4>VNJ`0MNI;y*tMKRr9U`n!U++rs_s5z*1Xn^HWJl9DQZd|0^i>_iVE)_ytL zq<?>Yf(A<}Kc(z_EvgmLacylhXur$0{QG%M+?U-lGBhq;y!hn&{CKPPIt`2ZGCNMq zFM04@^69Cm%#XI0dKj4(eVJ?6BWFA7!-s-j-`}sVv;VTxy<d)DP2}cdBFmO`KX{Pf zprxNCI%RELn@^WF`@eY~!9$hL&&e7`D@~j+f3mv&ro_W+pvph#No5hJ*(jnHGb8zU z-^!W)jJO>g9UEf)pVQK~_`Xf!k0<-Tc?&H*)c^Z={LC~Dm1nAEX44d%+Z0+7E-mql zDw_6dlCnGBuCljYpepvV`*h_GZ~CVSG?l)-wlV1_mz+&SLSD5>=7N%!m%hBb-2U$F z?&Vr30gK&u9sJIFselfgssH;`e5!VM+Jgg)nR&~@*T<ciZ$IBO``U-M+wV(VJoH7; z{XrzRs^7s0nkB1Qxy1}hUIYZ+R5{52nsS^!UtT|MPr``_ikj2bMs8LU6BGOM^ZEQE zM~<BEC^=bu^7HfalJ<2r44<E$_rLyqLDbf)kX0d|WqPx_#r1>MMwuqhoT>LjY}1<7 zNt^E~u>U))zn|e_qs+N;=hO^+lA`qD_nrCj^77B8)8m6mAC#4qftEpmM${V`8hkz{ zD^E;OQFiZp^7Hd^(1Kro|MMl=uW!u`SM!+xI)c^sZ27BeYoi%JC&{I4b6LcndGlhf zsGy+ZL?zdZ+uL*}PMoM_;GL8OngCf9y1JvI<HG8iwNYC^D~Zz2%{ggeZzkmFR`}wA zV%YjP-+Oy1XBwyX1>VZJxQJC)%_rghzS=XhOiyd%E}K5vJf8`);Bw|op-wxEf7d6J zoEHNPhP}MJ{8D9lqLQ+5<*zR*?^W-%|NX|8;oF;=$zGdPCixr(&41kAZ|}sh%zwV$ z$w{icm)3Q6b06&%fBx(1>zPW^JUBp;Zwl@YB3V-z(k3vQPc@u$#(Q(xSy1{v-Y@_B z>}>OAX6{NS4fg&2SN-nZUhliRN?+dJzyIQ`s~ILH`S)ZTe9vb2$=O!9R8&~Fc8i6o zTB**IKH7M?_Q52Platj!cSg9lx`LJs7tfyjw(`e^g|n_*6aWp}FlFD1KR3_z^r2Sn zjT<*6-rSVR)?4z$@#M2<k}^AD{-3MT__VT!MbC38Xf-zI_(<dENq<2`hOQ1vy|pE? z%JS3Y<^Gp<6ej<?DKT+-{{2r+r^gFPOP@Z{DeSvR@6L)q<)UY2PHs#-{-w{|P}Dr{ z4#R`T{q|<7Wrh9*ewv`&mGetM_DA)p=kx3PdV6_qZ_j`J^z?MlY({c^zW?`kcO}j9 zWPW~n>V0kEe7o9NH9tQEF87nwi`k*Dy<BSI!^7>xpP%_=U0HGP#6)G^OYKIRMFj;9 zZcIMzbE$pb35IQJ+Bd!R?>nHnGATdb|M$1IogE#Z^;OTz)NdQ-+%Wk1zVPuePyufG z`s(ZJ>of1{Ff4s_B~W(v_U-0nWo2m_O?PihKF&8yFV^ebot=@}^X7VP<(D$c;YcWB zU+1&%v|z<G1sj_=7cK-iSQT{6tEjAG+)(qg2oy#ew{K5B)WZ4d<LBq+K|_2D92^`M zx?C@0nDj`S>mANL(+65&@%An6fjc{keeIM=%gfmx+}T;I_Ez0=ir|jLix)?}o$%uL z)6>(h>ZEMkxUuT`WWGPP$1Y!<+$E}A^zo7F+@C8{kEPz&kXY5bs{Y4AcFSL8Oimp8 z{(SPDXJ7BPyX<X<d!AQJZ0yEOn;tzn+U?@*K6{USET}!PyZn7pZmzCuh1kPCKR;)# zQkVTv-Q%`6@yrZE2A`QmN6%bKsekkKZE)=MYs-6F?3ek>JhafcT_bFbg!gp4vlHx! zpPp*nyxDl-#EGC)9FmvPlk{SCIOOE$oI7_et1r{@*|YlpzvE}U0+nf(*G8M4nx=dD zU^9Da(_|int${oCEiUmqC1X|6Az$}{5i~TnHhTH8tTP-_GQVt2Kc5ycpEGdZantN; zCf@&r4tI2SKmPFWFq`XqZ4dT;^O93jm!<{$dbj)inH=A5>PrQ;$<#`>xAV(i+FM-? zn$h@pTt4%{0>`#*`R_^#>g($j>a5}?{oGmcQR)0V+r>3MKQX+D+F|FxuD7uK{XNi# zyK_6=#^UFGpnTz(H$~U|{!4W$t6AsfS_{j__^b|Fdqs6o&yhQPF_HeI#l^-TCxKQX zf4JY%8Im+vqNTT&*Urw4q2~A7?JlmaGjA?>)4OgW*ij3e+d<9LQ`7a&&oa&KS+{K& ze_vnUlarI%tG~Zn`6@~hbYyn<`+KVK`)Z1~BgH^#RTx6n$K3^uKY2I&C;{Cv^7Pu; z=$UG>gUZxCW<>YxyL^8A{(q+)9qrz@bt`Dy=acjE@8@jO5L(uy6y>&%#d+thUCT0k zLnm!)X=?*n&LyJZ(8?vsvrgYWkyAi^qFwpB7#&^RnKqS1jEs!W%rv8u^YhnF^>Oao zclr3k!|jqb6$VnhZJ^UxA3aJ6tDYjC>>8lDI6$VNSIX3AOT6c;ACLR(J9>MUrk<V_ z5fvpBW8caA{@PmbzKGkmLB;*DlPhj+PG4RB{q=SIlcllGeH^p?s?=HeWqkkb@%7bJ zNxK@0ix)3`d2#V@&hLo(;%@zNy>sV+4icWU_<afJ=vL4KMN)F|OoK$G_?nNcJAH%P zA9OA7a$C5j{xrvzH3wIPu4VuoR<m*AM#f8;PbQh?$AQikUgkIV)T^tjFQ;5Fzh5(X zS=GtJ6N~mKo|$hS|N6#_vUFF_=02_Pbv_Ob4bzHd?5zCsgtJ>rcTwc#v?<!*pv}xC zQohsvfyRL2_EsG|(kXm4&%5fsrL}eNj)KHFbLWCa36A&6o8SCyrg-q+!7aJBr-8<Y z)<&DF`OV4rWcSrEu;%m$!5solRv&bZ%(X86@cA<+y<J%!A1~V|{b{dfn8=NT2OC$c z&|qR>irA3ADAn5rN+Vxig@W$1n5@n(YhCu_-{0R+$KSns_vQ8VepT;j3?CIg1~2mg zP5ALhoAqdgu3AwGsu_QNel9F6efmHnb75K8wN0R14vTVbZaQ-G=*6AI>1#Kc=iRyR z$~=5sOjKFjr<3YYxvE<-9~@}ZiQ3Zf`}=!P(Z?mC0X~G(s5Abv`uv)v?c2?to}R95 zU@)QV?Jdx-ms#$uDNnYZpJ!|BZO`%K%*@H4h0gEZo$HY_22F5WJ(K!OK}Ds-bF$jU z+xh!5&vKlQIX<)h!GnaR=4MU~j)Z%ADnr)A%zSxy`Rd9|y}lI{7HgxnDj66En46nV z(~HfTw!k!2gE8g$`uOu3?3kIDI5;^M*8Kc5MJLke@UN*$dPTLv6j~Pe&$r9mmp{4m z0l%D$LixKpYhrdz(hOdfkeIkIEpV1?wOQroXRaIvyF|6O^a+3d^)(xGw)%z*3CDUQ z&&)7%e$DDL(}*=YJG<`B$Kxt|Haa>y`uh4^qT0u{->+L8YGz^*viiQDvRlT@mFG(; zW*Vjb`1ySP<T?I-W~HB>=Nl0raqr%}Cue6*U+CO^X;Z3qpPcQiCtK4~pRaxJ=uuOD zKfkhD59k7xIkwf)x<s|pcF3yx&s*Z$&Ih{7BRkvs|G&SPmzVL1YK1I_*qHR>%uM6M zxsz1<3knPz9UXuC`n9R*YnEQ@E|+dGUC;`NZZTb>SI<RdWqp_X&HeEG`|_Ndo8H{p zJ3D4)k>uLHUl#QoU}k1EUUMFFD8Pj!o|AcA2TwA4^ym?2N0XSC*q2vVwa>m)DSVKa zm<T$kLXm};jVIyU97_?s7>SPhN3sS9494l_RIIFKZOgr_W*PR)LF>uM$?j|ae|sCf zHoITmKJC&H&y!N=>FMqpla7{5^S$%__V)a(Z+tqhEYm32I#oa3j!RUF<<Io>rdzMi zn+nRy;`(tZcXyR;$-Lb5`T6<u7glc%HnV5m-31!v*^+Z}lB)N#fISr-d0xjSS@7}k zSy)&EEcFs?<B>eHtMs*mMS+5L*qR3q54XR$zu(@s(W*1hP51Y=w}%fNY&_h~zxw|5 zGfw+zeriN)P&hx|Ufse%f}Ndx^7qOg9}*d)%=2<S?NfRA_&_7GP1To<w6n98W^YsJ zWDdV}K(y%jxwD(o&u`eU;lQ<P)4Zl?J$&@YDI`RsnVmoFU=wT9@y@w7W}D|%e0w7~ zZQ3-?c@w;+XdJw;G5O?tdwWAeL(d*>i?tJW<mBY63ESWK_R7_;kPwmldwT*u$E!a- zQMz?$c9-(U>WOn@EDlUk^#(0C6xWMcka~KWj7^1svzujOV`It7ORX<nWVG?go|<D> z{AAh;oi?|{3*GzWEUc|BuZc9~lear#e!pgM@v+kZpx}7F|9{`yxw5~%zdyf))0#_E z>&WNl=PUpH*?Cg7!o`IJbVU56OGbyMK38d5d`6)D>(y|p_4}*7daY*+Ue#H+|Ia7y zW4+Stt*xxh?EJ@$A8)^KA)rNIOU_NBlZ8p2o}NCwDfKi54^PU835rqIe|>v<x`k8t zLWYTmPK3eH1uKuFwhBc3ou(P=cKX~All*&g{{8*^`J%i0%Gb;F^z=YuoJy`;8BeqQ z{>+-}d_DX8tLz7yC#PzQTbI9ka@pVh>6MkipcNr^cbCt$aXfTlqH^WeSE6&R%hTT7 z**P;UHaN*5bX7>=?{9A_s;V|69Av8c{%&r{$}<9>LRm~Nreo_?)7#tg{U`r$b$j^W z0q9J;!<*C3U)pl~x&UaAn2QU`)~u^Wum6>MzM5lM+?IU2@8OFV9<Q&hy?k{Vn*hVU zefy4W@J&*)v9)Eq?DB@4jV)+(m~K;Z^UDhhnL*n-Pib9E-*58p{rmpiyRBWj#X!~S zlarH=tNisa5|fvgKh`Jf{rcM4n_IJ|pEK&0xA!ZYnR07OCg^l}Z*T8yxwq4<J@Bdp z?RB#*dy@cJ|8j3hZLgGRSLEh2!@@@{bw3`mPyVLrDZe&q>!W`Ae+f4?rB+l{u6*u4 z*UI(ou2RN|pP!b-DHmAkYkG>hySsx<PnkPc_V%{i#j(4~RvwdFGIgqUIFmuz8HtyB zHVZnp^Bsk(uxd^}KkucEam9xOB_*YjIPVvG!a=3#T=NBK4%MLK@jK{=#nWHq&z^mH zdiu@X-P41XdR<)X-e0m^U3Q0y{+u~;EULb&_@#VjM`3c@o{GdPb}a&LZf<7pb#q?s zH@D~3wj+CP+`4sXS84X6M~`l7PWPYmnvs$5&5e!D%b60Ap6B++@9S~kTvPq)%SzAR zoLpRwUR_;%<L1rO-4=7+9J{hISkTEJ>x#x=9ak@Qy^FI!la`;Jc%GV~d3dIAI_Q|u z^7r>lqkcO&I@;9znUQp~>tx60oQ_HNg2M0p1a0@`oT!l!`kZ&g?l2!)Ci|i%98Mfk zCK(A+H0nDuLHP=FETYFmrIT#yCA&%<2sQus@wnfz_Ls?2?eJ%>uC5MQA2)Yz^>?YI zZ|nd674NuTsBp4QBigCCscFl(`#TDqWh><^3LI?z|NVY{^||V!U80evDxHt{F4Q)b z0xg-yw4e0FFzE=#qeqV<%yMR&n;XRGx#y{s<(IMtU2eZNBp$x8DV6)f{A(2n2?~#o z^)f#)U%@YDGvmR72P$8W^~tWjdhf%-!;)4d8lRt?eSCL!`L9_@hQ_L1Qy#pzxw+)c zjftRxEq0Y=gIWjyN>#BMnLbM$yuYbfwwtA%68ZWbGzlRs?Y+P5?+l|<F3X}P3144b z{qp9fv2(5|o7aNninp${efst``rEs^-BYKEzP+{8IMRO7myPxR>-c0W96E(mC%rj# zsdZiM)m;~?r&xUa_o2nY$|`6@0O*WdPz&eXyLYel9e?ub>Dk%ScNRZq0(Ia(N120q z3AJY@&X{Ra`DsJt=d@>MW`g#J&9JF7a_^H#JlZ8{#J|xcKkxp&v&VX+uRaDXSz78X zzAg8*+q#&YH@0L>KKFLzq>69v?s`{LSoqE|30(e0b!PXB84_+i5{yUmIVFR=4`&3w zh>MF`6ScLAnVk=`ySn++w%prc&v(sGDPDXr<Hxhv`5(T1U0U<=6KJ!RxVU)Q*;%QV z0^3!7KY09jvFWXjo}QH3+j2pJ`5zuQzT6X>2%EM)GtFZXXt^+`B{a)48`Sn+ylw4v z=5Up;c3$aYPft&u9J77%=EK*niKVBf7d<(#aC6)t%`Ytxk&&q$&y+edR|GHTV`OCH zku+*qu|fm1imX@4^uy=R#@jO|`J8EH=a1N&<~!;0v}x0F?(drmT2XgU>+!;#Ek0YH z8tLft)c*c9QQ4gjv<h&NoyyC{KR-YBnPtM+>vnig<>wwfuhc1;B^}}qG~)JHgs+QH zG%=aN#LD#|l>gCki6ytfuBny3yK`o?d4Hd*^`-sw^`O-q%a^Oay|wl6art_mNwR)Q zGwo`3otyJ{<Hn6!GA=gltNm?M^yGw&^pzDnDL$h2H>aPMQ&LvWytilPuWId+F+KA3 z^DbNn*j4&EZIW)C+f1ka&d$WIudY^9S6|*;o<B`DIxXPu-QDHEi`{sWXDAsOm%hIC z^wZPRI`RAFBpvMn^>9~(taO@fmTOV`tY_z0@2UI$|BF6b`1j}Y`Ps3%%ic=yN}H*a zzq<pPeGOXbmFXM1tSmOuT=Cz(f1rB=tE;Pvo}6%;X_Pw2XS3#4A-4T0dEViDd9D+^ zEw^pivII1Oygq(D=uE)hd%gG_9Ua$1Y*f1W`r*TephJPC=tNF(>y;{ee{XM(v0gVQ zJu<AEIl&Wj7f83bzFPRY7|_~am0Af`{^Hly)|zBp;jp&0j){#0t#>iczxQNuzg^Js z3yN`P94i$;Z6A5NIXiY(fChZ7$Jgib1gp$s(AL)e_2s4W^K)}Qe*BpD@6S(Ay9yL0 ztHX5J_+&hOe|sBz*DH}PY<(Q>5&y^U?(7WKUg>asUF^=Hr(BEOdJmmE*(q(F2U;w> zH81PBaPhA%nKrhz8@Fsp`S9SNg{39vMB=%ZPcfXHru%sJ`+bW+h1Ry6iHF&~zCSfp zJ3BUdd!B6hyE}>3)<kZ}z79IpcJ|xj_0P`Cba8Wg75eSP#l@geuafuo=7P3+tc$S} zj-LLr^6xKGc0L(}^mB8He%S~M2?{#Sx2qL!`tZ2lK4@1-=HxHRTQ6+pTz19DUtd3d zU&_fzs-R)L<Nfl?AHB6@tx6W8pPvUBz4!L^4&~nAH`i*8O{LM{w>`bROG8!$?Wy}a z>)+qspao@hzu%hg*}Io<!?tbD?(QxJt?16Wx=MBB{9C1|N7mH1&6_vx$IqV|)6Pn* zwLKRY7#J1(a!S?DPfr);-`{s;j-|0@^r?-TYK0$NPbhwRYU+|V=jK{xUSB7hmzOuk zx?E2;KXg`rUA(!u`JcakgLUIKBsk{e=4Rg8V>xf$ypYvlyzcJDbtccuJ3URe<lUW_ zesir>E>2Ab*;e)SmFwwgx}{pTJ<psrzh85Bj%9H{d3pHeBTL<!bie%m{{HpTFPo2< zJ5E{(YP&6V?|=60?ru=Z-c|bg)3dYEp!0&7*?2W#b{NF&E=#??uQqM#=MN7Lv#_#W zTo-Ho>)TuIKjup9KU7!*)_XjE@xtT&zS^C&zqj4HF8q1_|G)eWclZB(ch}m<$%%uT zTUkX##q+0QGuy}4>-R6y;92zKNm)SwsIy^p+9dN5i^KAqOt%Fb-&B@_tPI+ccXt-2 zuo~#3+jsZ(`+InB@XOnQq6jom*KhYr<FrM7hrB9t);H(mMQ66C#66ohWB%s!^Ptmh zKx1Z`Qcqu6(ziS#X-QjVke8>5)rM``mVpi;etEgwy8PXT-|zQt&bw=scW=+iymmwN zuFc=Rd^vLK)-2HY(629<Ow7!nh1-YQctJ&Q?C!FMuV0_OwAB0O=kxYgGe2Efr>^#~ zYKPI%brUMgQh$7ScxJY_|5g7Bpt}aH?ms<UfBoj3o#~m-!Tyy|Tea4$TNko6>gto9 zo6dsPurho(rIpH2{{G(63k#h^bRq(}wx<|@*3(^H&cAWvMxS{$mS+#{{-vj%I`?>_ z=e9*PKR<yAD$wD_(cAMjW?WR-oF`rN_0?3V8&97;b=_I?6ja|gT$@#Le_!p*-R0}6 z-oD@e|5}#%*4LaXV|SZ<xE~jno}RADK4*qgE7!&S_4Q&p5fgG|y7fw}{6DGq!6~2i z$&-UOy`3>>Rp{zXnU~c-jk?FjdN(iq%yzl=z;wM>ub3Da+v;y;rWC5YHx^d&d2p;( z8q|Qu-~ad8lfNegcN}?RVP*B`#fy%~lPB+Dn{qMd-kzB!PI%nfn!Wr~nVXy2rM1!K z*Ve_JUg9|!v|Q!xu2RsFs8?T#k9LV(H4EB3PeNWEwEG8iiu;a|mqK}Yc`NNI`(-RA z#n=5*z4@9m^sH9+x;3IFwiP~hV`63oO$!R__ft2NT_(}!?(V)h=_r?pRIgU5?nxOL zn~DjMo6|sR{7+5Q4%LheUR2Hxve9Fr(vhP_1NYTbg37Hv8B5T9NAGDmfv0(8EGD>i zi>)l>64yHeT03cwz;Ja{sCSTDz<Ex^h+QR`jEsyCQBjlZ>+6p7N-t;o!Xs-nWmV{E z&^mtx(_MeBt&Ohv@vxl%R4QlfUm*KaZ=y=OQSH6;@%EraF!Sacr}I5OKmYlUkB?0< zFSX3IF5gt}&}q$@H7ml`&%2gkvGsLlVPPR?P|;_e&CIpY+c#Bw1RZbEJbSkE{Mv6b z&sn*4iyggv+xlji@VZXFITnGZ8|yzF6$kaOwL({c?s~HPo0a5a$aH^ewz&U%yQ7yc z2YZR7E6Lf{`JA6;E9hiU`szx_`8-t-XK&8tmKdI^df_fHP0h_eUoM|t;`U4p++etI zV?)71CxyDT>S}6jb1aKL{rOqUC8l#?s&@F5PhAdY4m2`vJ(BcAuz#Y5P|>R^nsc8| zbue!D_4W1g8*W9n_luOQwGCep(D?QBb?K1&e}8_SnQw1@b=%jSYT$U%ZkAU)5tLL1 z8f|>ktq<x#>PBx1DLsF=d0*Ab%qV8_kll9<9&}v4V%Ov2{n?!HQ?$eT?(8gPe(?Oc zJE$ZIUpFVPIKW#)s8ciG(lV{gkjtmf&NjC!dn3`xExxSw_cyo9;7N6A{_}d~&zE27 zH5IfvS#p)utYw~6&Rb8*+f*#DdNift`@7gpD^<?Vw?E%+|F2{3Ufa65I?XOi6?Hk~ zi5@DFt&8Nsx8+1G-tzr+{(i+4(5|zH=xFJszMj7<%HBwT4(K{{s_X0P>#H@3jk`=N zKeXI>+9_LkDEa6_E=3801cz70A|h1<H!^T=ay~pa*ShBW-ExONSEg*@TgPqLsyET& zjAuxQh@+$9lQT0fYbbwMu|gwkeOzyAYpa%yilP4hf4}wb?k-n1Gn=+Dc)3)mc<;W& zKOnZSa*I7VH`jWKe*C=O-`{6<zLI|B0a{D2%y;$`jR)1=-#vWrpke-e`S|+3rgCy} z4u5Wa-&_5?=Ua;QL=Tl?Pwwrl=1|m#-nJ%iS%`Vw9S;u=4$yj=W_~+^rq)Sc1Ox>g z+xcWUxVS*;zk4K&kF9w7TKdO|?acmuyZ6-p{|CC9S&;>_u0h7q=xW)Nx7w^+A_4AK z8Dy<W5?)?f3Od5s+uQri+qaU|WjgA9a~>?8Ul(*bbbXv`eEj_s_lHGXu}TwX2q*i^ zKYsKm=;Q?kw|=>~@4l(LbmnN>zTN!azke21R-5wfT5V3feC2kdy0~WaGM||#+qbCP z)0-A!?Pb~Pw%B-=QQ?u?ySqxae&g1@eJyBnsM16aBc^1l4|A={i~jy9wfp-eSa+#i zXXOmLS}V}T$g;AsH+ObUc53CCc~)%Y5w(*h8XNh4y<+g*B-Yhd?Z*CV26M7iK`L9} zn;RQn=6O%DD|>(MZ2A4#_N7ZzUte46y*Xsn#tB|IlYE>zg;W{tp43x`luyoIed>%x z&@N5Qk1r2TRCWjLK`AUM0^Nyy%)oaNsIBkRFK64)-JN`_M^f#t&6k^7S&LZoPP&L_ zhxI%<+AS<1vSgX;)D(G<w;bW&;l|NPReCWy7>*o&y@WmWi*4E&iOp*_dp)}RWn1p; zY1h}sU*4SV@761odg<SnsfknhVkTu?$S~QGb(KqzC3;(q;dV<QWg$VqgYWL{-nd~y zz~yym;Z9CYpravMxkMMGoSc-Icl`eS`N_xoK*gU``MVq!Zq+u>1*uY|S)ei3g5u)j zmzS14GxK!SXSXYU=Cdw#H`{?eS?euIiod_SY!+xb+AVIJaY2ENS8B<tS<EG`u5{k7 z{~xPsU+};|A?|q1jSY!gGA=s(m45W~^3>#~?lFRI`FVI!?(8UZs7ZPD;9xT+AD`cK zX@!$98rIx3H8r5+05jK4l<2Pf{0y|_=kzq)t2V4RMOABavMya*X;}Iygu$&>YN}$V zp^9f`UmqxYv#_u{c=6)IJlkrcsU3ZB<*rM;rh*QZnyMB0=-JuXtAwHh0tAkBi>Lqo z_V&q{nZZ{LKsUWvm%jt;C3<ptI)8k8yj97IhTh)ZTWL`xXJln%HA7Yi{QLJ0wC}CF z{Cm#qt`D_G&z|iy%e@6^eeBt@=f;l0#dECAJo@qbw{hjC6dfI%88(%hcAhn~JXY`k z)Zf3kxjpG<*V0+VPDxTCy`MoryeY-APu4mus2;RV-&1khb_NCo22U5q5C$EcFY_g? zuU_)#fMT82n`VAH&<NhD;O}3*UOm+WIwK0ahH~ehXJ==x-Z|}Z_w?!FtHahlI?%{m z6s0-aDEpeun>TN6?5W(m%2wgzEEX0P(8&l&N=l%+`_7#^_ss0%6N$r({gTFPiY&@* zJr|^Yco_8^Y-ZnF`Z^4xb9+9hTr|q8zj*Ot1E);I%}uF0>;K!WkKeBrzpo}_ML=Wr z^>v^<xuCTvyUX8i$=fu?vUruhFoSONwkIbhDp%$52f0MFVfGdG2Cwtn#3v{ycxO-L z<Xxq&lTuTU653*Sdkqih@KlGIT{pHAe0dT0?frfKlao|K59)Xx`*hjg{^RTQ`zL9K z>wSB3bMm_{3zj*p*DUFEYu>xp7Ibh{($TJvH4zg-SBDk;{+7FE@7|LWmDwjwoVZH3 zzpLv~)aH%bwk^xNyzI@rz1COv1x=3s`u+RzijR*#YvwOp2+(~Q=6UVOzrVlV+}}Un zw))$K{QGua|FrQ+gYMb^9lq7q*9TheXqI~`V4)Lhm#Fr%oJZ1~m7pt7G&DHk<Kscg zu&g%O)&AO$aZyP}SNCkr!k3&}TuKH86OxX0J$&&ZqX4we1ay9cg5Bw<YuB#b=sRV} zp(a*t3Hv&mY15|V+}PmgZE|LchH`=PG@h?=tHaksOw7H#4Ya@S&D*yiv&_uIq@|^8 zY-~Umu|<{r{q@zeNPT<W-C51-{8_zccvaQZ+ODn+fBg2X@B4duBe&&5&bmEmM*oc) z;N?v-43k#`E#(4jfH}~>7<F!U#>GXTCUo}ob)W+)laiAo_f#03on^W>W@pirHIc%- zZp!~tC)J-jcMdf0ot~Z!is+@@(?JVLtG~ZX{rTzX`?H6yU0m$Wm~mr6;;dKsH#Rha zRw^v@60Q3BD%Iz*O4Wvnk4bHOvR!VA6E7}u-I90L>hLeKn<7?6);F`WvIg!d$yBg= z_@iCEj^jx740jio6@f1%PMo+U`?}xix^r_ZGjD8A)Q{hH<@SyvId^wWb?cP^o%phP zwf6e>{m-7Aot>HIKdG>#rDa3PNg>cF_74xWe*Ewu;n$a!F*}P~(<@zn?+aMyq!Y2B z;rI9VpHJ)W|8O&Xe&Dv8$elHlI13937I;n7;*qryvA4HpVq(g;w`b?hv!??3WGtB+ z7Q6NGtdo|MT=}eRhF$G0NBbv}zHBae8B{v`%AcQ~OHWnJo&-9>wK;8-Ndv=&uU}0& z11I%3Ui2_i@vn9(`1HgRbllYb{q~?a=c}MWUjKPEiuw2UsBJs9XO2~A*RImnLCgJQ z{pQ(Z<`t{BEeKf|1R8#C=a-k-!(Q|4&CMPeOK^Yw$A?7WNR5j}yF|5ryjs1U0kodb zxt;H90k}{0{@&h`bFH`Ei_UneJnzVoD{G^tn`U2I@%#JNg|)xG-Mm-ny-D6Y@6LmZ zi`_$31RP9wE-NK<YKmqsXqB>Yzo${#RPFFbZ{PL`G~L{sKKp1Tb4z<Wb6f9$rOeZ3 z%;C5D(QtCII%taQ;$ruopvwe6t8tz_-52f|reb^fdGK<-r$@WROI}~oy~|`E^fz*I z8t=V(_l_JrYM6aZr;T4e&n((!8-I+FA)A<(m`TP3&_Mx4iHBI`rg}}+(+yVh+N5%7 zOZnqty}YZ+zrG3uU3}Kt+bi{3(a;vO?$v+3-H~I*9zA}1*!+G?a#*#G)Dg9b65Xoa z(+sM<WSB_#PI~cVo^AE12eO{i9-p0UE@N5LVpI7^!h}iO>B9c{`g?n;k9P<vgSHrO zuAQQBW~MQFetv#Za`H^G+*#9XcI*sTc7gZj-^<zZKhDfF&b+vYb*ffq((yjoIo9QV zvCCgxUe14dx_<h}Nvfc$cNx^x)qj0^+wHb^Vf6Mq&?2M{9}0Gryj+yG9@=?OG%}iW zak2a5z18I)t8Z=1X4D8+z!1F5C-5~hXp>l<thLk~(Aff+mzH!&E!j}?)a%>(`{zOT z-);G|Ve8gVV+PNj^If9a5(Wtj0`e~_zq|+xUFyI1BIvl#;#ukwmvn-z$B~me_k4c6 z-@2HcU)F(IriH)0WZM0Bzzka0A{?a=IKv>3$^PFDWvSk_R&Mb$sf}~C^c?VA*Sd~l zvx}=M=n}rQe<vCm8v4w!nE37OZP19;ukY{A-`QEbaqHI5?Xy+I%5HAUoqe$O>G}Eb zXU}tgtc>Lr(^(<6Tun~dkni=iwV?3|4#gS9>3q#>yr2`pOCM~_z8<z+%}XVcGu0rW zW6$Ty%l##d(|8y_2a<^78X7urfaYgF3uHEJ0=30!J{}c+X6EfG*(g0}$FV0-FSrB+ z1*0NkS_D9Ijr{!lHa0dPhx703XcTDr^YioTEvmY;nI@pbd-(6~@1TlmsrU40oJK}7 z&dxUf{B(N!s@J|=8$1rx9=f}`+<bbakmoGWxX<tJ??D@XLH9$wuR7eu`}pbU=_RkP zoqbSR+?jaf$dL=H!}URPC!kd`+j38boRjvEXq_jgTjF|qPxbeAQTaD+Z_nrC;kgo& zBW+h>0UAiJ{{9ZMZY%1mXzrISUsyq#=lbOB&wYG+d?ly@x3#6VN7g!Q{&trnhTGfo zmsfv(cjVYHqs&VxYriggbhJBoZItPnwQIM^ol%*z=Fqvh)}38lpxdFUw9m;}6g2co zn+Gj$V0?CNZgvv){d~|+z>ST{+1J;p=HJ`%=I(BDXVGh4RCW38Jc)X7>dP1V|9=io z(~T}DE@oEnpJxLq(Lu}jGcPYo%*;H=E?;wCie@keCuicLBb_^T?NXb0&(AxaA#_#9 z!|(U&!-J2gy7(=e-M6>;`=_7J=YyIkpfoi1;&ZPW*L^iV&m=5#nPj&u=O&ZGa=*D> zwB+UF)~(z9>&K6j-+x{_Q!z1_VwQWW;MEmPP{(jz?e7(lo0si8d#O|DUecu62QRNW z{r~Z}zw+}l-t+VA!_QY%Re_eVJv%d#`N(=s$2~&fMVcy?Z%uD)Wp(WqTbglk(R<gR z)-wk-CLae)5?#D_5mX4u*Z&Dj-zlaWb>e}k=QI@+l@{lAzQ7d$inB~I7lqFS?ZbF} zPWIKcwX4~#dG(xsdwY9fdHM4zD}$%##m;(sygxnaIj@>bqw^oDAK%{I-n!*Nx0o*1 zk?e)~aeHPsHnTB)IH^AWg~(&jop`&;-!ChFfA7`Kb+NmR%HPF+Mk)UO{$Ba(i)LV8 z;FlK{otMkLe5t*&w(gXO)d`J~<ieMiRIgU@%UVsDX`HSWz0IvxN-|@nOOj34nh3{| z5|h2v->-G;_T;OtuTMKauXpQK({6G7X&Wun9=*A_88qAb;6cKw@b%~B*;Z?Wt(md& ztk=XXEE_#_zvMWjU2@{*;Q{TIXJKdmd{jJsL)qJ?pUz8}SGLaE+S%QG_~ONhzrVjP zetk{%)O7v%Nk2DiFo=nX*-`u3OjzCTNxOXA2?^)>#@q7ldYzwV+u6~vz_nW}=gtm8 z*QdwNIDLI}b!Wv#CC~*REG#cV-L=v@db|n>49?CnRkpC0ajaJwG>Y<akLt}y%<Oyx z-`~aB{eH7KWUl#v35w1jJM!}Kiq3EEoMBsS7Q3rNQAw$(k(qr{_Vsl-5BE4`E%ZKf zW_9@bj5|9F8yg#U?A!@j9JF_tsOqFOCl<MOGh7jwqPa2kv>0eu@!p=w$o+MD9WO7L zbfvSi6LfTDkBp^Ihq(Ojr_<v%h3pBAh>%FQA+l>vw~CvhmDQ|oZ*Ld>{FEvqD|>Tu zdcR{=h>&O4qjz_AgBow3g~+?U|9*J5{mbj?{2k%)SJJoWU7SB*f`C=|yPoyy_07!8 z*2M0f)+cK{>$XlaXo3~AaLzR%V#dwj{A0(CU0UqU-zRJBc5;%cWziE3K0dy*t)5DT zs@!5a3VM2d|Nj17u2Cx~F7CcQZg0iMN33(L%csr!)^q0R>FJrbx9NU=cXx5h$w_Z+ zY-A1(4=<jbYG7z+_{z*^vGzvBSHdbs-j{=RM_)}&<;pxUL9wN!WySM;IongGrfOe( z3_31SRy{BL`p&$&y9{f76o6*E_f&okxhTeIQ~z(yy}i|-9Y>pQ8CHBq0PQdaO>}>I zJDF2b<>svA{_{b@L^-*+FE20m?@CQSGox|+dVSEq$HzxUB~u>$KKShHY|scG$cbfd zZ-I)i$V-*Zf9k$&nXt_CL(R`m4`09bPDxpE?Pt~3SA~y`aDKgU{=9#0U){eymZ0H= zQ&Y9szD_mIk9&4*?&&?1pEUv(wOngH{M+wf6Dw#fl>a;%!`Yy9T%b*xPfktko@-tH z=*g25v*=CAPft%je)+O6KR-VkuarwjNXV?)M%Vjq|NQ)X^4?{y8SOS37eDh+Qc`+x zd%J!sm#EjaJFVQ}Gb{>~rcIl+CT_1(b@gwaEk?hE#Kn*AD17|l)>iHO`};tfqh+ki zdX!wdX58LlGI=52ol~bk_p7Y-)DU@fef@f?4;>vG^XzK9Zf;6#tVqANz>yg=opE<} z`Q?<H+uL$OJ3~EfrfP+Pir-fojd&*uu8H42uki6PP}$kWD?N$hmB%IjMkdw|U%x*6 z@$s>Rl~tN&Z_~kMcJ=Dqlao{>GdzD)etRRi|KBfdGcz;L^0kxGxH&l&1~2z>ad$V) zx}q`j@jZ_{RbRWVt&KL$y=Agy&6*!yug6DjO7Wb=KkaM)J0IxogFYF{MW#v`Au9x& zIGmiFEz94@%&+^kvg+-hpPzT^+<9?<W3$Rh_b;v|o76n#@yS}Hc-a5@_YZW;T1&#e zKR;&%MO*Ct2-ypp2)Z$A_ipQT>(+sG*E%+{J$(P3|A@Utzl^1k=gbz+U4r7`;-Erj zrg1t$L1E!S@9BCW>tZ5nIm!zQ51u~Fot~a9rXP1EJigX-s#a*kwj9ZZb9ON?F)waz zRtGIWczJ0lL(J|n(3RYmw`N~gS?@VhbcSiRm}%CP1%;1~y}7&lI?MZcg`lG0;lqcZ zjXEOwaWUyLZ`_Cg?QsIFyj>f$b%sf15L@(2+n=x3?_UwPn63KzyQKvW56Re8P5Jlt z_w3s`izgJkyeV)==15v@F6eNpn|rIbLz3pFC!V0?KI`N5hJdD+4wv7rWj|u?sv6>P zdHReQ5<8b$h+bP0$vnes$J>jG-9ZxwA3hZP>)&hKzgqME{~xc*E<1TG&587y<{7Ca z;=1%`f|0Lti%w#jit$aSWXanT95?kCs;Q-fH%}0{`BRIF)0J!Ot?$+M_uKz@H`8qD zo!gm~=Z`<O+x30U`A@sHSD*h~v+a8NxjB|wqudUEe7Ys$B9qfXfqC=had2=n%$Xx2 zBP;vx;X}sy`g$HY8;O7a{((+s4O<ftsMniu-2TDix)Y3yj1NBloMBa}r5C@i=gXIp zoO^pDYwYCDojWICmLp+gWCUs`u2{KpVe;|5ia$RLr%auin3vZ#(>Ois5~!f4`SF2K z+AOD`tBb3RSGp~7bDE>O`|@M6za4JpS5{GBId$q3?>9ADQ&Z91WpA6-tkK!bn-QuL zw?|^Se!Ls#X!J)%I^FJD<#4>YyIVXjFHb{9r)A+nMZdXLt>@-iZ`SqBxw4h@pX=re zxw*NZt6}w4%$hk9bd0Blre@=^WoixmYnjBw#h)pGj!Fil_Lp(%bsHNS=e$kh-I9Hs z&uO8+vSrH(N=iVRh>lcUo;-JMFX%=&RaMq&*RI_F9h7|P*@}6SCJA|XdOm!5dU`=Y zK|&wDtd&T&n68tjC#RfU4TrPyVXw?nlcr8R8ljY)p3cm0YfI)~8DZV@%-h>^i`S%| zpEosXPUzKzt5$XS&9!3uVdKoDudi=mZM}HK3XbCE=Z?O(xHx<6_I;qe`$fgYhUM>K zp4o;y`S9@YkH6pVD=I5D3#<E?RQx{I=9ibJSNG?md)m9pdn!Lac=|N-b?kj9?lmk0 zk&%%-5{696{pKe1tz5Or$;*q&&CTu1#_a3s65rn1dM2BhnK@=>5$omU{_cK$e2)Xy zEn0MF%O%$*Po97VK$`+IT9z$S+uY56eEGyllMdb7oc{3bTi%5M8fM1K7mGHoSfTOa z)vHH0HYWF;(pb0=G(#N`9sT&*+uNXfW3ODj8W<D9BiG-)(77Gdga%!ez~B%ay*p;s zCJjwZMMXu%8oT)~m!3Rz>d<WS`~%NF&y0O|>fVpgQsIbD+0doGuN-qpH8eA8Yi(uy z^!amQQqrXdOcgOPGJE#!Ra92~eDYekiwjHI*;%X)7N7LKnXPdAIcRfj;p1b9YHDm< zU0tAKHrAHcWap@;s$SKMU&~x^^Q2npeE&HX8!y?NyLa#2)qQ5BrmZViYBuzjueo|P z^lD|_tcw>e99ZT%o1tdUhkhB$Pn)Z4v^Hg2RAOOcbMp1&UG6`>ZPKJk5>tvo+}+&R z&YV4~D8jXH_3G~X_5WoJ4GlMJ-_G8D-1&H)ENI;kr?A?A6DK$(PMpYKw~lYc47Vez zLRTkbXLD<6YChY(a?zqDRqtt_&hCegA6HJ@_Ue^JcWWyvs4K1)yUXBRs_0CsQmsjo zCo76@8CHLLbN*+?E7tPzauHF{gLm)lJ+<!kl`A1PZr(IJ>~-$kIh_?bRzH6II&}0X z>(8G*U)<ks-zRI`CTCl<LDxHJ$&w{kH08I?^b}sW>#R>rP0fbF$8JZC9Jz8+yyE;k zTTs_1B_%~bN~&w2b9>#yxW2ZnGdmY9RNQ{(v2e_;5>C)r`uF$Q&a<r!%e-IJ=m45p z2c;Y}H8l=S&WFeLzV^t=1D)LR@bznM22feLE&o2BrKM$AtEYsww|7fR3&Vl*Sbhur zFKGw%RDLdaf6rD!LqkDd|NZ9A?QLy`&YtD9k>mgU{r&SMbN9^)w`>uy|NqCBA>r+< zty7!KKNQZqGgUi$!NP?HeWQLey}P%!n~|CA!1e3mTwGiqK7T$eU;pRglV)><J+;5L z`Tg9%aL-4;cNu73(=wl#K_^?D2k)u*DfI2zHw`_#W0O?94KgpOc%FKaz`5>gEcj@k z$H)5<GcqEco|?JI%}w2ZUe1*?r5r^84p1u=G~}Wmx97kD$7TUR!Ha9wnU<P9e#BH^ zeE9Zl=~b&%ojGTIb>jT_pu0{}($WsyyC?Vh`ug?ktuiva%~Pg`tclqvWFyCKUG`?h zlgfSh_xBaKxiz!#CV6H)R@KwvJKWCSzI?fQ2ZwgpnghMk<_p%YJ-cm76{r-Dx2tjJ z7Spw}*55wU)7UvKPVV-$TxN!teKnw)vn0%NBBo}7HUZew{1C9RvI5om*B%s`Xg@nQ zxBJW)9}6q1uvvj}5)vKq^?w9iT4b%u3f$aE9~@|8o?%~aw`ud{g-e&V*8ls-?%c+c z7#+43)SqII4=<?A^PZF4XkIKMBUAAG-CeKa<!^2<+S}V}Xlg#ZvNE`I-k)P1Q+49@ z%!u3=D1HCKt4lTO#H(VbId;BU|Drx__Acp5ZX%%5!cI<B2NiF+(c7k2mxIpCoMR!# z)X1P6zV65z%i@Tjn-(WeoM>onW?tqyyY0=J9G|&XqJn~gXN@YD|Ci2Ry=qlmS)5*j zc{1om@COH(d1NdEm>L^49^G5{SxrnY=7dkw>#M89PkYVQzrH>`J#ERgW9D;m^9uw2 zUi~@WyyV{gdQe}Ek)iC}oz8D>ZyP^fv}h4%*;?Ap8>>QBgRHkKe#Z0b%gg5E<9&{i zk&^EHa;@vv=TDu?Jezxw>4U4eJ)bpqFx)!>T2NSFBL_O()!5h=6xxrE_q!Js8iEd- zeZTK_UvB4FF=Jz67k78ijpYtM#j--@Jx;wG@>Ew(fJ4H*IB;H9-Lvp@F^zqFe4r`5 zOP4Nr&6=hg-8S1i|IyRa(<e-y4l<5U#^S&f^;P>9{jUry4R=uxNci;R<b}(ZlmFZ} zy)Qkm-@(I!qokw+bogQCmRsrP=k@mV@YMYO`~B&hXF|flhFMoMKv#=jyEd&@@ej|X zOP3zJcmY~8v#0*Q++w$0&{EiA{qpCxnOp-6H84!s9k@pKj)Vm}_)JX?AD<&zGB1O! zNE1|cOSrqMH0N~IwU*Y_gC|aOeB7?@4f4{;Q_+78xARBrtt#DVBl`DDcXxN;!$Yhe ze*V$gZQ|?eD<~(|SN8VS!8><kzQ4QcTv1^mrW+Na7wh`}^Qu?tJgTa!uC0%cKi9t( zbTaRO43Y1X+~VWo|NMTxKOj8(_`AEiXFguJa;1c6mWYtBFsRL-?A}+P*Ru7=kxt=) z!a_$cFRm$5r+)nXet+_<Etxr|vkdlBedS_!m9qOZYXKjFysp9JOP2&BB|H0Mtq)zh zHf^_qX+qW~nf0fl_pAcB_w%Pu68}H1I`*WEN3!Ye?sCvF%nu(v9N3zD{llA^o2A+# zvmQ^3n<`%&>0+*wy7x|KNXV+S--|2${xaSCtor-AyFSy?K$U2ZMB|GW882SGeE8+% z<&2w~mfm=kyK2djC7=^b)&1r$Fw}fLYkp&M`g!&8!t8Y_Dk=;PbEhd3G0tITD0p+j zFz4<rQPAn)A3uWDupfB-+4B8QHZNaord6NB*7wf;xgv0}g#VXSW)T5FK~8>td{3S{ zk@)|0)vkY9zvf?0V?Dh5&yCNYKTn)F^W+U*Elo|(tvo?NL8bRt7Ad*9x`K{-ZReK< zm2qh=Ui|(29aQnov#Df~m6c^-XD=2zwDrLK`|_WkpLfs7(h3O)dGPk_-8I)r>-iRm zSzK>D7pOkZw)$9w`R^Y;4xBs3H*MOqGZGn&j*L&9KD{~R#K)Oeu0`)zG=FD%J9|z} z&V}Xv^Zn0tUA=sndH(tKDN{tEw&k2WGfCe&_s@ClMT-_SrJkM!8fTP@FDolMw!pD@ z!TR;*Uwr)V0dy$am#<%sUSldREj{}G-*@{jZ*B@(m%n5Aa8Wk<NQYoYXQ$)+eYJ%@ zKc%i%xw3QVzGbIQPuG9==uuO*xIPoZn>TM}$VvCD`Z-Cj<Q(_j&Vae%Riz^0;)ieC zkl>fIIq>D><&E|K{}nx-Z(q;n?d=WfUKp<uFy=kUz1Psu<-x~_ir?RKWn^Ub{n-5b z_xt^z^J=%`+!WfLf4^<sJh@4eCM6^$Hr}`q@#Xz}`GW@!md;YW6QiN0*EW5+IOtrV zrY5G6H#Y=tZ_CZzw7b2td(9dh&>8JsUS1Z}-`=Fh^Y4g!adr-9Q_aC<_7`_|mrvcC zRsH2fqpWpV$j-1i&CR?<#>R=MsjS7t#X2!NK6Ibz>gh?D*7Nr6ZgJ2(PaYlzK0G`u zC@sxhTU*=G(o%46x751W-EIH={!ae+=_#lp`}6bj$1g8~^(wA21-{<B&f2vo_Qly5 zpP!#kzP&AX!qllpCn~#NSQWZj>vCtzvaas#jp^s*&djwIzjWzNczd(#l&Mn%Wn}&w zecGYZ^!f8=Pzw{ZpmBZt{<fVvEgwC8oS2c(;XPf?F)}ieXVq-E%*;&CRp5MbHXKS# zjg5@|emv%vkdWA*yY`|&l+(4X+1IU}K972EcFOnn_mh8pd8we3b88Fd-{0TY8~O(Z z3hKq~I-<+?Fyjj-lJ4D;D=aJo9i)40Z8XReJo0ujpgZ7=j1E0LJ$>hcSXQTn0-)`y z`+mLBma!;cSR1|l*tfU03!k5p)vKsiD=aKzV9?cFYxQ*cyW89KCrzF_ao)T*b!~IL zZ=U}C?z_w0X4wX|bb!jrB}<khoS9*`wd`!x-Cd?k%*-F3ot0*ANK8!JeB)LB;!H=E z8HUMhPR`B?7cOiBU2gg9?QPHnp>A$$K0ZDL-`+&#ZL1Uooyq?B*;!{77Z!$uJ39(* zY|EA2ZnCD&rurKX!>c!Cnzkt?z-z20tNTBDXC|!)s=X5v72mvhlQp&O@-ko0!6~47 zoA>|!_j|LM=EO;pKsPP~#>Di1nlhI!3-|T)l}<f(Fz`L-ma}#~*``U8gh1Wn*VosB zN;?fLtwW%$qrJU--c?stAt9j+B`<@1{QlkCv0(Ay=C`-EAHH;HQf_ANtQj*T7#!Z; z+xt4qAuUbK(!xSu{(1G9ITO#>O5JQe|9o<DGjnQMT9EIZoyF}bDJdQ2p9gz*c=Wzp zt*oWh6%!M)Z$-~DpNa|#Mg?JE;cZJzq|4ska%J#vb8B;Qa>{sotoO*{j~om;ckZ0% zppX!q)U0H0KmXdgSnp4tKCv`}goI=~KQ}idDCp3(EozS7OL<k*)ULg(QdqlW2}^x_ zJ?NH1Q&UlyUVc+k(=B;-cO5IadGlsZ?6UTDb{!p^eJkQ(V`G2(_`&dFhsg13*QQCg zt!y&Szqi15w%OKS@>5+?<PIsyF)=egeD#V;uD`wZ_qT^fI)!iStv3Hr10MV}H#gs= zYNi2d{<?OHf%+MjE?ojmM1`%7JA3woxbV%JH$A+(niefmvMPPm^5e&k^ZG7L=HfEE zJnHJ|Ob%{tZb|!_<Mvb-)_%Pj9ug9wa;<1Klcc2NlBG*sUteFp{LP!3XFry|+p#`= zzu&ZJ)3#K7ef4YFtrSi^zGc&NqlFlv_EwqpN*cE@OxUx>X0A=;q})p0uITM~6IZU( zynHx4EzRxX#fv$ovx@HQub<B_p|O!s@akIkKJEu+Ta44s2`~hOge>{-qoVW5$3H)d zm6Wt}bf$Rx?4223_p^1ULKjozQTaDtUteEY`uZA6!<4C0vrSbF1saR%#U$)%SnfaH z4}4uO=-%(`d3Ted<C-6yoUERbo_@T>f9uw*FR!c&&N-d6>BrBXf()}vGKB;S8Rt9} zUb1|7@b7PLIT_yG-tPbCtEGj-g!XoJ^LY_%Jv}`|pT$DHXm%UG)&hivW`28flcnL; zx3}KYrcHZ#4m3EOd(szlVc6t3b7UA7Y)n3Gw4XUQH}_fF=AEE3O+mZ1JiWbz8M5y0 zvweGK=j5*L?wixDE&2H6iweV*w6ju5kC-futAnP37#FPH|8G~^D{o)lr7MG%2US&7 z?Y(k6LgO~q`gaE(f823xy95UhkBX$E<g-N@TmjdvU7Ip(+Ocgm*M5F@$gCT`Z;oVC zKtRBPtE<C<{rvcDUz)|r$H&Lg@aON}&JOMeGNA>3eiSbAHq+ExdG9qpAK$X${qonV z_wr8c>EQ_q3R-2@P@H@}{@lvo<ue}K-JI^v<Pa1T^yKBsn{TSyK7Ib2d3u`em2J7v zX>R{OgNmxEt+|<JxnyN!nGVFr?_@X^*!Sc~N>F&XIz!2W1B_uNph><fSFXIcxjB8! zmHQV~tQ0-hTU&3*&M&t_OgGBl^gNgP^Yd&^Z!-xydH($J+}qm>4|CYa^{e^KIl-&C z!J)3s&ePj_@}505#tUa~KahF4Vf*&<WB+cbn3+v$aZ;Q*ZQ7&&jg(OC+gGk|J&(Fy z>aHO&Y58*X&FiACFkQcXeff?Z7Tca~Y||(xe{rFa^G;b=*_RIwowqGDjed7`w>!g$ z3l}C>hD~QUSGmwU5OnJArzf5(R;)-kKhJhe*2{~F*(+@1KnE@7@Bb@y^XAPpuM&k* zQ=j^;Ghg>k#{Da(BYN^ACultJu}(xx3{QG``kftx%(G_A($QX1&&9>{;O$%9+}vE9 zhz$(y@9#gp{eE3HJHOn6D=ULRL#MZeX6y3H+p#cwd42tT_o;_W6~a&c{{CK2Sjfom z=FU#xx3{;aM_zP~iHW(eH9P#sv16NbTSLWkA_A74|F*oZI0SSjrjD-e!{^W0H8nLk zTAfauJehcZUoEKPzxng)^XJc}Gi?XmS-Q8nePi<RM+ckPEoy(2tToenG(iW{EC2BH zKeuNIf5C>+H#R17GJr0q$?^WFvOaDv=;)!1y3M9qeXYgG_e+({%%*MGy7hGJv|YP) ziAYMG+_t4k-PU$4==6ZBtSq1KpEoupzdYE?p5y&^MZ*b==eM?IpE1ninbYhy&&HF% zBQ|#Kq{)+SPW$W$S`{oMB~|j}Mc}rj8=Q`AEXaGa+eY55W`*I|jmgI)9!vlEuk+cp zTg=p2d13haxQVl8OK;7(+Ql$o%N7&gITjO@l$35vI~K_5v~WVy_B>x3x%FY^dafR1 z{h;PjR%VvmSO4Qf;<l$(Jc5FRF2Bm@o2{%9xv7QIF6Q-b`$dZut=iimDke6myW4wb z*!E@1)LPryuP^rcR{7<Hpzl1JnKKLTgAPA4&yU+YZ^Ly7(3An=f_Ha!Pq#kjo0R=* zO~ghfPfyPc+qNA$(kXm%TClRLby>@#NkZ@L?q;v8t=&`eb5gG7*He>Jy%#K5(sFfm zcyaRm|Df96$Jck_oH;R1e?C7y-#I>B9@Nld_)uX3x??XeFwnrzaHapsH4ZKuoSX+= zTwHu{eZ2jTpFbS~0|od0`NSQ!zphu-y3FJ>XLT=Up>G27f!;=QQBY9U*v)_P<jISp z-Qqc?f990EzvsKV?Cq~7Kg-|Wy9ip2{^Z0&(Ap#;1A`S`%U0iU{?xy(_V=V&v!uSh zy*>TTojV#jI&1vA*-TALIDTa83lg-qw?8H(`rqD1L`3Av%~BJ$qT*uE{pMGe`^!K3 zTmJUeRM1IMJ9qBPIsNztkC=X(55tS?_v^IF=e%~xUp8ghv`PE+*)c8v9nqotyjw#{ zYY{U$pMm)QD_25hndi%GUKaiZbf*7n$L{Ko|Nk#sz4~`eXP5VMz0^;j)pC~ercDbw zsa<zxN8#B+tG*xY7XR}3ynXO&v)mcq?P`7$Sk?Wh*ep|)#Rb|I%y8lA>hROD>o3<m zc#!es$B!Qm4mPu2xOnm4p;qpj(>}X`1|yCiXBQL{{PAx0`-J@b{wr5PPMkV*=-M?g z=XO5V>3XrC4LVb%Oxd72{qg_6fB=W2BqbvwBLP7{(8?GkD=VqR?)}GlB#l7}%1)d* zRcBP6k)Z+FHSnzT`MJ4_450DZ-Mg*1xVae_-rm~UJb%8tj;^li@3x4R4$yVvpot|% zM@Ip!R?tmcn>QOjJ3s&Y+WUD&M8w4(-`iU~VdBJt2O638@37HpFfW=kY0`t2FFED< z+wbl!cXo4Y%k_+J*|p0Gw4SfNzCI!<YSE4z6331mD=05-U$shWvY(q<8}|cV(4~Q( z*1?5Kmq0C~_6H9VKsO!z{{9|x3WtD*2#ekPc+LBuK2g<|3<1I7H9K}lSXo(B{Q9EF z&~X0w<LC41kKNjuE&aFrPw<}F-(tVNzi(f^Uf)=LN%ZzS(Ae0VxpPm~{<oA;pEz-% zhK9z01&+-M`uhKmJ}qS2Gts#IU(J&zPe2<2B+POoZWkSKN=i}^(}`$!^eE}Z?c0Zs z9&IhW{wPD{LxoL5bhLAHw6ym$9mj$KgFAQcZp^*C%`20gSL(=?4X&Wwa+P@r2@R9g z{TF3lUng`u_WqP9Qy%>J`T54~a(%tHJsgb=408SK-rn9jcI<dCJAdEGPs`dD7Z$y~ zrpwT<apT5_Q;*XYnkW7H`#m0XA7NHj){QNh!ncc#96Qv?J#p$(R%2shy$bW9EnBv1 zNINTa;?yb7`jIm{F@k=6exRGcr&fxJh&*`zzW?|4_vSkv$O;QLt9nm!aCT<CU-w%V z)Eq5)dkeHz40KI*Q*$%u@Uo(VyE{Sa*ccinPMjEV>T%SA-YJI;Ih~nrFVFDc>C>wz zyRL%{lxb*S097p?A03VPkjDg?XelTv0^O|I8DIC4m64H=fx+J1{?F(0_Vdqx?s@(A z`1tkdKAn^2%;^E`{X8*I*~fd0Yqyw$b(v1u`FXt3($abf=7mS@GCgOiP(FJ4H23<r zy-hP`N`lU=*e0{_<M;dZ%nUNJvPX^Fj$AYVb&EefK3@3kP2`d#OBBq_#V;@SUvK6g z5FlV;Vp8z>nr_L<OH1cX>6*S~jSeXA{{8#M!O7X^puoWJ<=tIr(3N9bGA}P!x9;2~ zufAUjhK7Qmu2NfD+l{IzJM_M|fl6FZ-uUpdCg=XXy(hN>b#j1~L|53zojG&n#<atV zZYim$paY0GTAf%}SU}s{HFR~?8s5LXJ^$j??C?1jg^T1uy4stXm_YMh-@bjzxV}y{ z?aYiu@9BCAb8l}eC@npDcD6aFzXTe7<Gy#c19UtMLmQ8z(l(==Vin3MKR-P^arW#{ ze)~TcmQ0(nr}{fz{{4Net5#)AmK1vMqd#tM6=<bCXs6p!&umk}ygL@4wb9kz-%Xvc zOJCX8Sorz5xy}v_44`Yl=gg5|XqYrfNJduHF!2yekAz{<Yo+{Sps`%gjW&wgjHFW- zu3x$Y>c@bF!Iv*@2Q7-<-L}PwhnKhT|G!#8ZI*X;cZWZ=vh%!B`~IG-j7^0=?yW5c z*YE$Qb#2p4HBC)Uh6T%(9or<t=c%wu^Yq!XM;jQK6;xGOH8nM-Oqt@KAh2M|mMK5A zmDJVQU%q@95FG5Bkf3mDOXlSSwH!4S6$JwW0Y*l~9aUeoHm?bci<A5I?OQ=f$&nWq z7r(A~`zRxdg`J(5Va=K~N5ayYc^+tKY3(R_%EbWM&3j`*B6HZ<sH3aY76x!=uKe#N z6B8RdQ?m6dtKh-2XL(&(M76_Ab~=QIgs?n#d}Q9N6Q@s4-Xha?Ucuaa`!SQQt}X_K z*x1;X_IB^6NjC(!T0sYHwts$pUfIAvfM3og;oR2D%WR<X^Tx(x&?i9Oe)GQ7P% zepDPee%v`YICxFmS6-ur=|_(qWlc*<ld!EaiHVI3jEd^gjot>nxXdV(i;Z8dXTt`A zIkweee0+RQFY(CR&Cyi1v61=w96a6vYMm)Mw<R2CV0>|Nv$~vpT~F-pGRL^MeL?^J z{r&Ci?#}MC5VTI%r_z6(P2<d&lAzl%A3Xw12`pH#f+PF-y4K!a-<{tdynfwX{rz3y zt1Bx(!^6S<_Evuft!xF2YH*9`9C&eY@#?=iE}O%vzq~kj#^L#c2NPrp3kx~;_>Mh2 zJzY>rs;j4m=UL2jz1W28?Cy=p$CG}1c(`@f$0r%{Kr;vo3Awqt*NUWT81gSJVr_9! zw6V1n6cAvrw6wIavO0A5F!R5E|3GVj|NQ-HSp3XqO~l4UF|#%?#%!r+J^wuU)s>Z? z4m9Yh?aI$-AAZ(YSX(nYEd3)XDH*Z5On1wcEvH^yx_HqsB0{2}-`IERlqnOYPHi<z zJ~oB>0qE@iZgKq$#n1hEWGpwu{Ct0Jud{~-$CRm4Pwxx}b*-zjv$3&ZV2Iw9^H5Jr zMn*`%)>bxrT@2{fRY4h<o*g?Zp3RvuMTCt{rUP_W=e28MzkdDF(R!NU<B{}7I)jCA z&ypo9K|w(kKR>C;$jHoi4BE-P$hA8lD5$BOU;faA3mbxFZ31O}@4!u)H#63}`6eWL z`qU|>sHmu=e{yecTPw0hyXfbq)E_^7G<1A;ch~w^MP8oXp1peuLAM31SaSaKY3_69 z&Vhyi?(8gHo!gjyZ;vD=Cnu;OW`4gWc&!{CU*9Z2uGWsu&V!&OMURj1-q}^kZD?rt zG;i6~En5;&Q(3*ey(1zb99&&nU60E23N8%jm@q-W!_(7rKf}KC^K$s6?#{F?TDvw@ z&o^?)lqnM?Okl8^f4;{*H8u6&+1cg~KK~2|32~WimaFwt-}+sw*usDlHu0O&c=PV> z>uqXc;*qnNVYzO>f`+xx+YcQ)$f)i=Z_N^a1%U&H4l(`w`P0DA@Mj7`{pV-AX1TXm zGBY!CZf;uoPF~HucgF15#^<BAWH9RL>h9RJYmxtayQ$~8LG#X_`GV`~<C8&W3w(OQ z>E-RcaM7YByV_p~Pftztx%K<|`^OIsHh1*)vNC`M75)7D3`|VcEO9j9cWGI@T6@vr z#T)bP?ke&QoHKW>ptyMZ+UV_%md~&IwZtxPr;Qvx7Z(?(De?V&{e7Kp7ug!NY%y_h zaRFUxa7I~Mdv%OdXlUq+*|QH{x+D}97G`>HPjSJOBhBpm6DCe%bar;$c%Q-S1jD?E z6B&z(i#b}IKy#$u@7KHg`0%`W`}W}Dj~6y3yZ`w8JNZxxr-6}?Q%Z^oL&D=@y;CoB zL~P9x&B@JGR8?io&(CL&S3j*AxrwD;&K7j+$dsv5?Pu;+5)%`XFizvyRr0b4)GIsO z#_PO3ZtsjvD<vOa-@t%?hE8Giq_eY3pPmxuYW48*YYWgg^5*7d`^f3bm#csJ{Q2Rd zM@+G?clCc}sPYLue0FyBg{xOvCruK%UG%DF`Et;~m7w*RId^t!oRmCc`EvEoF(#U+ zXJ?sqbax+a;S^r5a%E>r3yV$tzd4@e|Nqs3=H<P-yg(}|8v656Kxf%5^PPQ)_2a4y z8#jU$l{Gat&t#Aj7jNIO!vZwB{`c3{)nW5Ho}Qi#+B|Pj^+f};rMBqlDYdQd_U+gq z(JycB77`+|Xz}8YA09fpxVlb#Ez4|oZ_eu%FF=#2&h31y8#fwOeSdd1rAE|3ifz&> zJ9eoI27T*yDvRRx*G)}ZCnY5{ExITuRO+J9x`&6`jT_@w=AQ?hbaYzwcgVjkkk{_K zzPdU*+)MdXc5d!jpST})Zf*yaj`Qcsi-?Lw&hLzuuCS52bouhdZMo4I+1ZO-yTyKd zJT9M@lEPwZyVuRQEI%=kQCL`bj$N(P$&)9io|Bf4FgXA8$rFZ}m@t)7w->wjdsXtu zSTHDo?h%&If6^ywopf_kszt?zgkHuwckakom%TY~cDDJ%`Sbgy=|&rQ2j}GEoMN4~ z>Px3UtjDg>*KGd&{xa5OYc8^WXlh~ttx?`w?b`qR{Cv=LM4_{eY{|VX#>~dkuyLc| z=ZrJvGi7?4i=Urkbm*Nt<+W2Y&jXqNpfdtFSeSO~-VM5GDd+S`(QVtdefak6*qxol zj5RTy3^g(GtJkmZcWh=${P5tQfss+xhS?#YQp&t$(Yw!^K<k6f6bFiL-MG>4(BZ>| z)!%YJBi_G${Q|9YvMPJS!Qhi!bD)9IC+?z)M&R_S(k)q6xj-|*yu3%Rt_}xPdM#~j zOe<`5Z`G<575pg?QhHb?lZ%@>Fd*Q-o^$8UwK*s_czSYPx_o)!ym@_FwwOFy|Dv*} z$mr3dN2~U%6ap=BU}R<kU5dJE*Dlba<u6~pTv+Jb{;MKeMutaIQ*%e*W40?-uY#5c zZ=8OA4f75ap130?=USH+JUb(~V)g29%WXF&%rs8t16}9&e*b@?<6K-^1)#!lM`5$& zwRN%9U*6spKitOK+|<M*9kkj-gdsFEbYsrVO<vFU?%6Zr`67nDr}g(gIMm9$qwcSj zlCm<W`Dj!9&1cQKL^Crp4qjf+fnK1EIa8*Hym<9$QSfp<(^soKe6{6Oj(&Z8egBQ; zaejV$vu4eDac{5n=51lY!NRsxUmVuQ?N!jdyGB1(hPUOw0SAs&r?ekocM9%*Vmq@b z^|XUa#IBOe#U^bQwZBaE{eEZ7!p2r-<Xco^)YRN8C?gY-`Hx{XXw?m<u@(^_@$K#H z<2nz81GjbW(n&tnb8v=X@`O2adN_sE6zuHgSzcf4&hO&xu54s9Y33V^tf$}K+}s?t zi-(sNG&_6ZgvW^!Cm0-5?>D~sGSxN3Ma3_<^Vgyc8wC94+qo7M83_pq3CPR$`^~jd zw6c<#YhB*f*2cE0{C(fL*xg0Rw`A6UiVKE@xpU{boO;ew!K|vH!m@DT!WVaT8iP)l z*fz)N;PcO*QwSp>A|9NZYi+vh{@!YHHQ!kw{HL;xUAQ1nRaMo|)pcm8_jH4@HxVyh zyfAp~8hf2##<lxDK0Z#&%;e0?%>_;0Go0cT^qFflb>;@Os`;S1O8SpCPo5mC$_tt% z_`E0m{5%6w(^k-o`<gWm-oNj+E`R6X=C<tA%#WcjwX5|sH9Kc6`MGlG^ht+~9BJ9P zQn++(_pU3fOpKd0ZwBQ;&|K<|4+~H2mz0$B@bXHUXJ7SY#i?CU+j2VN_Es%SKR*w& zq2a>r@_bO8vbXyCv$EZfCumq&T5@o5I=;TPR@JDH_W{$6BR?Ou%YQg7Utbd@r*!Dk z)6<Ng8SgbFoGT4K{`i>u;?=7#=>zQiay<tQ9Ej>=zOKG$(<V?y2s9D$e13h>>uYPz z?A&DcC3v}C>#}8Pphm~*>+2tXd3pK4=bxZavpaY0%qRhMJGNvBgQkp2R)2qSky%bo zF4QmK^XJdW^KRd`ap208DV2I$`_$CbGOn%)UAiaqrSQhGw^3ViZVKJqT@G56IHTw_ zXe_U&{<T+Bl+?X_wcRZ(EGlYhN}8ISoSd8<US5Z~#q}pln9$JC!QtZKGUfE~=btaG z4%e5Ek}~T5_xE?P<6P$)7FO1UD^_qMAMcwwL*B0ch7`x+A1aI1J-@fNT3JhL)y3ZD zs;a67&!6Ytw{KrZXXi?@wR7jnf@abyD=R^lzb{+13^c<%?N_0RENFhd{$I_E88fcT z7O#qnlS@iY{`lsmu}$qSk@NFxoqc?Gl9H28`z~T;$jr?A^71l!TU#4w&y$Xh&V{wn z+p8{~y!ZuFHvReg7nI<9W*96y_GQuQ`_KQ_Nrk8UaMG%p|G8pM(Z3hw`S*05`~Lg# z@^aDot5>g{u3Q@a#c2JEx-Ty-p6N@O|0(JE<;%_~DJn6sv7oIX94t(rk*@>C!$Oid z?>Q|LXl!h}v9nm+$=O+Q@$9m<w;sM;zrSt$`uwFf++sQhrs+nj80~CsX8vJOTz{Z} z@oCyW<^~4^2Ol4vclY<7w^347232jK6O|?Ry|}hkT1Q7GAuWxKo4ea<GV9UaY170& zwfmhrF`zx!1tlea7JYhkiCM!*X1Au4q~z7#%lvs87cEknV_z?~Y11aqjhaVZWy)N1 z^a=T5r>~`@^}K)H#EF6DX5YDddGnpupwaXw{m)%5PX|pE|J}|nzajB38>lCKV?!dS z+WzzB&xa=`g?S_l7`}b`rc)cVRo&WJ8kDJOYHDUY_1Ls&(}t~EkAnJK$;qG#Hm7nw zsIij=?N8mV$jzSp;b#pfE^2>$Ie2AdFeAg#rAs^d`i}km{T+0tC}@??`nbJ^{{8(8 zI>LrQ{<%_*jHS@FZQCU5YIfYn-w+xSA|NK#*3`r_W9H1-LWcF(AD;aH6?7Bl&h0f! zKITzUl((7df#}}z-CbR$el8CGqPG6WE;aqnulAf>{V6FtG&J?yi=Q=iUf$l4&NIHg zzHa{F=H~PB?c4kN`Tza<o&V&?69$IO-nXV`2A`5l>6p{e(6775xt$Mm6!F(}Gn*G% zEm^ws;{N)2&_u6s`Z<;lg}pTq5fV<$&V^4;i5@w2Ov%hl?B2b50fB*_p~=MT?Cy!m z?p>vlDUObeLc+o`uct;IUKEz=;lU9T8=IJr0GfmeyBQ_+^z)}rzn+|HFDxtsg>zR| z*M&u{+;eOyH_dsPe)QhqF59W1)oQIyiZL-U3)ZiXU%Jq**x|_?i_}vho!2g}VXAO_ z|M}6QM@9c$96NUG>7JAMcXkB6EA@?gCVF}L--#hlkH#4~{Qmh<(auiJ&CN~1vM6P5 zo!Qo>|Nj04E!qXuR2;2Nph2goDA4+<#csW;Hd+69aIpEz=L;7Cc%)2L*r^s5T#?k( z)y>GvOaxzzntp!X!$Ymy92^|rMG@!i|38>t|F3b*92w9+`;#XvhRMgSR2s#A7QdZ2 z1FB{2?X5PpmJK`F#w%R_SqmcN>%=E-_vhrjgFin%PrkdWw8uK(X02SqslDx@)mqx$ ze8j}Xjdz`@`erU}SM#Hxp@Bg|Tibij!b@N;7t8gBpOdeBb!Fw#JtwvInVFfbyLNg{ z(yvV*4^QNkHe+BgX5Op#@xejnHBno+($CLh6<nBldK%~)qnOy()nC)~b#z*KdU$q~ zz3p1CK%wOQy}fdw#RVPHLB)9Z`nZDPV&|$Vt8;U$+Z!4fV)j%Brk|g8^ycRDg-e#O zu(Pv+mLVNGc5MFD$!f2h*zLCUEccy#Y>ldzBG-Y`>aSV1R2J{LchEflp20!s6?+<k zkKQ{xt4i(jr%yA!tXj2dYu$U_*2V7qi&m`QxV+qd`i(cmf@ifF!k^a0U6bGYXq}J! zzaPm<jaJQ;jR^hqYR`?+WtF-S8yJMu{ap6f{Z)B1Gdf&JS$SjDRV@}awx*5?yGpY` z<7oDOzXY$Xo5L?>18VU3&9{qvJW285^u0@#EIC#by)~<K&z?QE_Hy!dE?%&p;m(~q zS(m5CT4iyqShecV$&;LZetsG{IxYnT2LFCOmuF#POL~8AFK9#&RE@6;UY_*q%*^?@ zPgkv3bEahR=L(xA&!2;af;2TX8SK8jQdLs}tsIq<l)O4EbYuC(H>S&qpP$=N{ax>} zv75`&JS(kla$!2Flg>X`5x989ymPZkOkG`U`$8+NJ7%Ye9+1{@IkIKnblvD{3di=% zx2bFr)ed`bW~Q-%5@;m#>Q&Kq@7~QXWef`qJ$kfTJiAm~YZm{6S+k<j@5=B_|MI1T zA!E|KCq+d?;G?6?n%`GYR%TZBo71p<y?)-^U9F(8L(l}&v0iC*bMx(4?Gs#LU%0gV z`BRhT*Ry%EF&nQGOKolKv+vIzK4i?!&VKRw_4OM}>(`ZExP4n1)Th?eZ0zab>65pQ zduJZE@%x5l^E~<a`ET5~0UDq4eU`R%8)#GCwYAZp;gz1=Ue!4H?R<L}KfK@nA2gD_ zx9aPm$?E<Qv0+nZ&g`739iDW3U95(#ZYtCF^Y;IBKAsKf;E<A%s`&mcc4@bV>khGs z!;8#xKb)Oy{unf@yFFii&fK}LJtcR8Y<Y0785AwW$yq5WEav9sH*Vjqzxb|Z(X>yu zx92~6@E{;R`?aOr*-uYTZ>;-UwI+J|x>L3ys}}3MKCqK@2XDjH?CVSn)AV9bMSalI z)jhf{b~p5Xb7wCvu6OU=b@cZi|Mm6t>r{0Ux&HS2eLvY;j`T1WnecXXbrpPm<_lWR zJUf41Vzl4hi<{H^*Tn7?<K*N79ew-j>+AO0+w+qj9qGJq<x0!+>EUzpU5t&97O(`I zIb~@lzA%8p-rnBB(=+kYlapVA)Wr`(f{v&IC6-;Kufy{Hf9YajXI~t@zYesVD=JFr z&6_tLetb->sI0vDTWs0o<^Jp+3a{n3F4yThcKYOG^@%fQb{ZxhbBK+dn``;CZ_XT< zW&ZQ~PMq)nElfLij_>`wy@waMb}v}Ev{g5Hn}WUl|IMdD!ou7N3JgGtm~>C)Fn|W1 zKtm-PHYBKh^pw(T*nDPJ>1zgtZgKr}<=3}v&%giZ_xt_rTeq6R)=06kf|fa6xOQz_ zxULdt{B2|MaV2GC=GkVsNx7%J`96XMU_nEfK|w(go6~r27e%E1`0&u8^p%L5T}=mQ z0kW<xFSoc}%d}}?+w$(7y1T<H2(%uSVTO5r+}^7vSqsE=7CvS>bm$Q1+Ky#UBjp7I zzrDZTZ&&;4!IP7dK?j(F7A>~(%bRt4eI6GV2U-Uf5g}3b?#@Zpk8VCOF*0>OpNfl! ziXOarRrK$#ugTFt&5q&W;>Y`BLCuyoZ{JRwG^uHR{XfaOyURgS8Q=HjyX>j>$TVFq z)@iz4?5k2yLGc5TDSv-`WoU5i7Q1@8FZtugj~g~_Y}~xr*vQ!U;fog?>i+W*-rd>B zd#pS*I$9dEII^dQ$8VlZ=hKkQCoaR*0-T<1Y&^qKiruBfd%9lYy*-s4-rmhqr;2XN zxp`>Y8n(`P^W^;ISTvqE;Q^}lLGktF<z>T^6BE*2D&Ld%`0ZO;fJV#e)!BRF+;>L4 z(E0e}r0|PZuRyEl^Y85uT+N#t%F*id<Hrxs*@`Dlp9Y;@2x?qUxn1BIbfwg}^}~mP z8@F#Oo0^J(+9?}19=x#7`QlP<@sf9Uc80w^YWa$tm6a9LtW{QK78DfRQSnh}o_#$Z z18B`p+1p#Hg~8p+4z+TNKX~`9Pu+iB!|}(7mzH?m*peAMIi~Kq$cZy&T%Mns%UEM_ zH1qN@-?^t&p4KT5VAnn~%e0%}!l71f)wuAO7#Ut!t0@cu{l^#I+?*bqmZnyG@4x|v zM^dl6va+<!&NlB)NlD>g`26DHV)vcb?=;_a5B<*{8yjm?{!Zq0{6aTRPfyOu%F4jm zX1N>;Tl4PDDtmv=*J<H|+)No!(E5Kyh4Ap}`daEXHggyzbar~K{anB}hczfT*fTC} z-jbzDUw(akU1;s=7Z(?wadq(a?p_zOGf1;nqapv^o|!znyeBVRnsjcSZS>31n_FC5 zn%Vi)lostSe}C!0!RC_(4m2D(bSNwK-*eEg<E@>=>b)|SlXjK9c4K2>Tf?sV?&E#X z?%5^Fmbumb{-$bfZqCKc{kW-D!o$~h>C4N@jpuLPxzqCK(W4u6yC44-<X~B{a;2w@ zTz^th(!LcsdJX16X1TXq7&89+_$ahmSzo_D^C|O!PGR++u&}VHnXZgw2O1csOq}TG z;^MS$!==}oGCTiqKQJ>h`||H^^{F#wmIN+#ySnSov%VMA3l=Rpv`wUs%`YH8p!D6H znG6A|!`7a-eS0<w6XWeovuxAP%~51XNlyNJH1(=#L-FJruV!Al6a-pF#8CI^rF!QT zL0Q>e$7VLr4csoP!`6Pd9$)|P!^6X-@4U5dElK$D;-W?UznZ1jMHl{`Z>M<cOv0NR z8?Vj^x)Kssy!6pKe;FB3Ny{P?(6H2DetQLbd(Z;P_Nh}v@9nQYzimqzx8TF;@%5|< zJF_cuT?(!!yZ6hfGAvoYUVq}J@9*wH)<*sM`r6%pzTH~G{uQlr=Fj(ck&k}Q%*M0g z%d8I2LX1zJK51xbc7g)m#YNe@Z^@G<DN0IOT3V}0f1aIdntcttGAJdQ%U$`=r>Cc{ ztPECXa(H`t`|=AH0=B7|db_NBzpwUp*HZV5db%IlHs-C6+*tZLjG<xn?AZ~gbu~2` zXU~={dw-9Yp`fs^ar*S@>AL=_Gp$1xyz&(_%exbiXUtq*|37N#{X2q^Wg=o?o7S`} zHUu4%>Ehy&@aoD+4lb^ysZ&Kk>z1c#hc}&nzFBvDq=O4+%#tDD>@3qaxei~CZs(QR z`s~`;XqE=6k{1D~-doo#S+;D_%$bsm3YC?WRy991+&J}Yg3RS*zRAxto;-cJQMY~Z zL`4y<%*V%iRdjWI8BQEJ)O6|c<(t#4>R8nMvA8^0Yu!(qI}#Pl?pJ=zvo6<5Nl7^p zlok>q0xFm{Y%s{k$WXAckr7t+6Y;(&GwJEg&FN=8PuGv%w4!CP;i1PLL5D50w6%c- zW;l3xTPIEw-288zvk_>-W%l)}tHU?%`fDtH;5BGW6Ex}f>C-3BK;O}zGzSOJyjs(a z9TpPO(vRQW-EClCAONzWwL?Hw_UxXzkB?Zpvn-^Hmn~a%CjbA>&(A^28LzGmzd7w{ z3g}=b<G_kDGYr>cJ!Gn|-I#yhZpyT2plif+tZV-M`~4m?CqH5KY;JXRb<nXM#aUS{ zpp#rIEiD6rgP9pXrz@no%Jk0cleK>I>gsCfg2Xjz*Md%T+qOon-9aJ2?1|vkLpNKv zAAEJl%+&n${ysm$4Abmu;!|B+K79DluzR<42S;379B4OAdhpE?0&mOhDn2AI9Jsr? zJTm0)MUjlFt3*MCvun55!W}y#jML5>c)$PuxovCITIbJ~pJ!LwrRdyd($PDA2SXe` z3oEOlrY2|Y?{BGkH%c891QM>TiM+9+P&p+f<-zmk?B(U<hFWW-+uGVnPo<}%sHCa( zwtG+4V`NbCo5Nu@zyJ33d}jrL4Qsj<Z&X%QZ3SIretlgm14DUvIcSS(YN&7Xn>RT+ zvAaYZ4rkOd$1toH|Mu=KH$(iEl2scv2s}R4dpN%SZ)@1vsE21}8W)t5h)j23n6uEM zcH-2jt=;1Kpep0rw{Hd}CN6GnZ7$|h9%jUWj!@XQZ{LH@KR<l=a%5BL=^N9oyolVK z#tYgUaB;Cac*Ue8!wv?$LLp&c&{Fmjr%xweTH;x%rEG02z1Xey(96rqL6Zv)9wgNK z{dzs=@{RrV^`Hr>ix&mIzq{K!aiSn-uJh}w(2B}R&}QHbn>HQVS^Qi;POcBMuJgbF z2GC$b_&Ly~m*?kX8RU0&i0j2ftlXm=zRtnjoqe*pzguSJ${Y8blOMgfxL89=t7-3E z+mzJQ#O!Qt2GHrvk&^DgpjLc4pR7~2m@cUI4jLE8@y^<E<j9c&w{J^t+O+9R)*`mX z2(b-?HIuHc4i{!9Dk@qP{O`;eA1RXz0mcP>bFBhPO18`p6#^BVp!5A)rq-U-{xyB} z%$XNoUth0jXgJZWN5awNzvbH2_V&w7tlS+PFWTkn7F2(K7piss(xpi!?=STh-?)Ez zTc3l10%*OP1L$;irA0q}R6P1v0a|2pPI;d58x|H8gWW&ZMsM%Swd@rtE-q$rm^W{p z(CX&fXO=W73UI8*zP^s7;n3m3_SW@&etf)=MlB2h-{0MRd3ANTP=M#t9N(>5w`PKl zCRA2YX?gSJO~#cKfhFJG+$_pu=acbp`OjLgFu=pj%`GG*#>dUgEp%FXMn**H-m|Rn z@$pO!X=!Os`=TQv1Q@uuxRN|2-GiT9Ss8rf`Daeh0+sGu%igZ!<9&h*uP!a^cHy1A zgW=u*i~4^yj0&={bI+ffJ$<_S;Wl1nhAUgM!#ne=qsrPhcI|s6`uFtdZ3lF9bhMt9 zmzOV3Jw5H>r>Cb^>*OEl5S%h$f`g~0Cs@PY<!v5*eter3Upd+>etNET?JpBXh2Y@e zX;%tOO8@=&?EmOv#gXTqEw>+wnlyd7J7_05L&=*PhMm`rRxUI*`1bZTJHrgi;%Dhk zPoF>EzILrHXypqpFE6P4@}90YX+lJ2*S=>?3pdQE{}~=%%NiXW?cwQp@b>N9LH`hY z%|fSvx;oO*(x6L$J_hCM=|pYe$iKG-bX!VdZf@+mIcwMIR(*TZ`QbwW3mco!<3}<w zk3d~OP|K~ooqd__>^8r-R*5$@B<7sXy09jCJ0Gb1yk*Og9fgl?ObeFeycb}SeQ$5I z`=v{lRJ66dGcz-{o(qqN@GvtoV`;D|d*iWj<3^#7lY#M|JIg9;<Us4!=GoWBrApP; z*E2cXx^-*H?Ag)hxh!XKgU)(oSh8%H+Q!74%N$%>SWcce5zsBBo3(ZI<LQSg7n&>Z z$yhX8x)cODi*9RPCKn4+kG#E{xPBaHWssAT6R3y7sr__<Nnl`LK~WKt;KS|r>zcQ1 zE1UWfbeFlXurR3I3u^4APn9{_`t|ko<TEo2J$!vz*RIw5^!fA6X;&U-Xlfq(^71lh zEjFkqEPsD5$9t93$-Dk0`Cq<#v8xWcG{>@dhV|nWD>OJ)Jzk-ol$^XW`FP*fxK06K zVdqbuJ{@`d@x_IO&R-WySZq0I=FF38+BR(8{yfY+B;o3+P?iSJA+)WntzU!G%{$jN zet2<FnaSbRt5+dGK|!l+q|I^?wlVLm{k^S4wCD<ZzntwNzqwX|44bxWS@TtFQ}y?E zsti{)rF!owdpoNow8$hJbkobJQ>R!O%<}J@**1sm@ZaCxSGsnKfvV5)_xILruiB~i zh3(M8!|jYUZ-k~!TUR;n!OGy}8**+MeW<VjZKRJ+*?#JxfkpK<9nfh<OO~k2m_1ur zL1DqQ=o9B=nR4st>76)#{`iZFi$TX}ajt%v(U*~(efa);c^f&<2{X^<FfcxO_UzEb zi-M}Esu7z~INA7QPHbE9YT^T4*Ud}b+<G6qJ@4v_f8XBT205I`LE0>51$(Q^Bo%x6 z`C>W|4mNWA3>Ti9oc#I<Yj{+Y7wA}rh9^&+sO)QLUHo%X%1I$62ivMI3*NlR+4gk9 zsV^@tb23OuNnP7@+$W|W_62Xlh7AU3YK6X_Imjzlu5d7%ooT#W?n<Et*TMjgc7FM^ zYdxn<p1k<&?d|;;IUBcZnGzEd!@<C)ke;4?>eMNr#aVoP{r`BBwjbYR<z~j(Cu8Zv zu%h(!wKZ%0J!Gn2P5>`$uKW3Pde-HqPoGX)w@!~yAv!u*OILTTdaKMM&`D09MhHuk zv9WR0mlqRnoVvd`ogb9O4Zm`7a|=h`l#y|9(U04s;Ogqi<dA-D4yZ%@`OC}TXMg1_ z3K~RtV;ItBE?T4%6d0(;AR;UroEzot?#|?}Yu7HJt<N7%;Aw4bE&1@kQOc@BLwLv5 zt>87=LMz`N?G{f-N;-7q>(}e?mwTnnRf5FbKR<cD|9{#abt7Zro6~~xQ_|BfhsW0* zt>R}9KM<*=pwPfDWwY4YuH4((1Q~*Yf)=HppLcb#RiD19x_bM$IhM}G>F1Vg%e`%M za7+IEeOs!(=XLha<YZyGwK<*tvM+xFs7`3-mw(n1Z*in)>sC|71vfXRZ`NHJC&1PE z<?r|V!VItO@3&vwtEtzpxu?0AnQ?(`^tKwKvtM6d_jGe>tFV!qYgfBV?rLF;USwos z$<tG!x3**oM@B{(T3azHL`Fu=GD_u&-Cwu&Ua6?4=*4}tzdeG3Cttk0DpY%xMWNEq zpFabgoSgP%Kgy6ga`foLrY5G36?@VQLpIm_tzvRGb?VfazMh=G=?v$Tm4yD^`S#4c ztjr9$zC}e%ZBgy-Z&NRUw!g8lu~q#3rfXwkv!U*9mDrS`5EWBX(T^WLcJ%kV$Hd5h zn)RTAe?jBM0U9ZnG&M95j&uluCfY%Vpn)!aalI-(_jglMQ^Ai9i7aevO8WZ!me<!t zo6ndv%PBryesA@6xA*t<g4S_;sIU<eEjD4>mV3Kxe%&w5UAuO5babq^8g%2>iI0zu zKYZ|jK~qx`wCnB1uh;7%uNMFPRXStVtV2hRusnSDaO<hVtObUktI2%k*?=yp;Nat1 zR}!Zoa_G<@rttM~ty8CpHZ?UJc>Xyu;Fo-6W+rIW$-TYR?dJLS9^Bns?&0I(5*8*_ zR8%x!?%ZB}c{>Glb@ru8monJhTfxE7RP^-3i4zM#SBIU+*3{J0(9|?s|FgzUL{wB! zSGV`t+UV;)#2KQtW*uEKd)oBr?Q`bDEZwza>C%JGKL>_{guL9_X;S~=1LM-AOV9lF z^z(D8s<OIt>C%LG^ZJe)ae4CONyyKi8d_SQ@L*==YneJ#w2far?)BC?Uwz}^KzlX{ z-`%l{*<Hq)e{avqDa%q%PkV7~t@N#}+3kI@)=sgpvaepf0xg=EGe<^5L}bB=6%jA1 zHTCuTo0^yy{{Q_CnXF^1xl^-z#R?8rSJxBg&%68i@pW}~gBpQ{4mpX4h$vWFORK7? zf|fR(I(zC=Qr?8F?(Wlf8yFJy3F}5}Y1p*M=yO0|pyTy*u?ttO?998n%hB7LJ1QzF z>95UfW2Qz1H#fH(_5bZaBQQIQpKsFjd~;`KF}s+U7^qO(mV5ibvuDS)spvIqKDndt zalxY_oIig2IB@jn(n~+j&Nff}_~_`1OG~-m-QUk|YPz-Rs<^y-|LXAdN=8OP(3K67 zCQp7H>g??5>&rW9)~pLxu7HM#N=i#XGY4|ERSsUO3ae!IR(<7q`0!!HhX;&FNl602 z!p+y$$1h&_@6ObzQ$Yvdfi}Y)Zs%{GIWux{uH`lMhYuf0nB_=ZxpGB7TDsdT_tpko z&m2(A=iJ8Qn3bjV?99yO*xh9tbvYTt4@55But6XzE9=DR(}!o9=U-SEyu9eSylqvB zV>26Q5PZ6ReA~{QJCB%(ii(1k3+^a*$mHbY^x@Of(_Wdkw&ixeySsa_b2}esj@PQ> z1p_ZHuZE`P!qV5*0zyJsHf=JxEW{L$%Dpz}wWo&2wCv2zsO&}43ViDu`*lw}dX&WA z;ONN6#m%jKH8d)UtI>fWGV-R^d*3CIk&!bqZ)$64fi9sB2n}_;y)Ad)s#RRPyu8b< z-oJA4{Q2Xn!`Fl69Jc4*SAr}O^zpVdH{X6rZdy|l(}~lknSZ?hum38P(QezD)YMc( zZSC%9y3vbDUtgOrabjZBw@;rw1%!lvZr(Zd^$aNOn|p{>7dHH_3iR^w`ta~D`?HA? zCpKPRAFpg@C$~OsuTxBn%%ew-PCX3`3p+N$F!{sZ@As3xytugLdzq=*v3~jf$H)5* z-@Pjv7Z;avT9EtX$&+W=9C??jhq%NtS(tbF^02V62{A~SWCScNZf$Knb4=~syLUp@ zKfSo99JL{Vaq}GCFBh&{S(15q*~M+Sw>2y*X58CfuV1JuBlFeO&5bQ~M?quV->>1D zwro+!%zRmNzgAveK5yr<bRltZ_oAXA6=h}T{Cj&6qtA&?o;mYm3}|n~od+?`cSOF> z0qtjGascf_FFAMj?p%fm^XAQSDc{P;#kJ^QGyC+}s=4Xu?x4dW_f~v#O8Qz<VB%tA zWb^_wJG4pT&;Msm)@5%Vl->KqBc>N~LuHQA=TDy`<XhM8`_&Z`6m(-+2&Z1dW>Bv) zxjm}z@^|g<brYsc5jlD4)TP7i{Hj6!A0O|}d~#yq8CNfN_jb^!PA^}+6k6Heym+Ia zpr9ikA779C-kCEckAen{RtHX)G|7pJi%UgW`Etf|^=HqXUD}X%n1dlRBg5pzJr=!& z%?&4h?*W}U-uL{;lYs4ccR3hxZ*B2>^L5&^X_J;OSHB#3W1%zquh;AMdngFh6y9WN zYyjQfeC*gUlavzzQJYdccZQwbka+mS<;$PDU;UVr`%CND+H)mI7Z<sn;a_C-Or)8e zf8A!izP7WV6C;bCpX<5*_2=j3H>X|E0I$TzZGHai*`$>#HHG)gx3539ZHfOO)&eom zeO`<UK<Bzy>%FovH#HUAeZI1+%q%i8QjlTNv}wykwZj7Z{Q7R3y1y+qdMCr%moGi7 z%ipOeEn2cfrKq4lp}6?7{;J2`Oi!ObF*P%r7IBle_1BJvt2}PbUU+`5XVT;|XM8|A zv=|qN=|%-OI56CvBxREt{V@OjzSL;HwI@%V(h}bz{VPC8{6M6`leW^|-*TTtq@<{T zHVpOj@Yq&<a#`~=H7#vYV<Y3`SA6{Z;@Ll4T>c-wSL^OtxV4bspKff`#s*eV0armr zMs5ubrN9uE5GApYr0W?%$(@4P8`R2r+>#BBHR-bHbaZh^L{GWl>XO+MB%b)PdcXaT zv_qFpA9{1B_T0_lX?JH<$BU)i-)X#^N5&!`CF|UsJ26HX7ZjX4GK=iX-^u)hp2nzk z_x_zbb9`nRwSq3|m9Z#j5O6xNHhO!<&YhMUw`@_FIB}wjuW#>-+qZ@N{rxA_ZqK{x zwPwwl6BiabdlnQJ6qc8(Z`-!*$f;9ZG5cy}3OH%KIqef0T^C<nUA<`8GPh+uGnF>o z-CO<LV}IRW(4qb(d!@}!e0_brv$K<Prb%W{@8t(xi<VhDObRJ$UA|7;Ge(%JHRWiR zC<{YiK){0(GuzC=TMq62|F3$T^UA4Hrigs2-W0stPiX!g&V`(NPTE#|>6rUxe&$Dx zRwtu`0}M<Jpk7JR+Vu+-G+0<!2{9bGabpJP%HK6ljkUa!{{H^1-XdU>bcAEl{Q3TQ z_xHs<?aH2OU9Q&I+3BJnAfT<S?ZlzT$H%9lr`M;VrY5AWzFaGMmzbECin4OEK+vy9 zqi(H~)YOgtZ#?~;`bc+w{?FW*Z)0L&JiNTPPM$iYr0mwC;M~rantb{C_4O|wPqg5* zd^pR#-mdzSq?nl7zMs!#bE#Xj2wYn3FK<-%=m?j(?^at+t@<KW&S&T5dNT;r*4Exi zU&8kO{(f~XF0Lh|udlf%2o%WrZN0az*1M;tN9u2N(47pX{G`?4>(v-e?5X^G<2vX7 zNWNIX?;EBr^`36#>E3fn2sB{f>Eoj!Yh9+Ir>A%1=+UL8uB}?SRQ2~9&jn&)VsEmq zUAq>l_96TFI>GYta!`N>$;kNl&A0QFk&yu%V{T|-BBD9@;E}+(`=4$b-IkP;6s)eU z{&sLq%9Q@#D3d2G+BP<GKug{QoKC#Cx%uSZ-`}<8JP>g5SnfC1<yn_rbb7AeBrWTm zkD>|-4L5GzuFh~`j%D!<KKDn4+8RdTS5-ilBX!K1C%1dW6qRpg>$!X%_@23SYZimT zbiG)mmMQnNla9s5?<jCwQ+juA_4E%FHj5T4aFDa9P`I|~w06Dcwd>cXzqzro8FVoW z=s48c+IxE{pS--hT=d)eH>daJaNoIjabiStba<3`aoPOYv%Ph6bUJ3vloaG(QL(k1 zD<LT<=;YB_JM-76_tD$_ZMt3i?PmIu!|nVn6E3Zm^7Hdkv9p_}qN+Oa++6GHUp{)w zX`55P+3EzkCnhK&;)L4YPwEyeAvPOVYBo;SU%Y9uwx@u&xO+%wXlGB4Pivsclok8` z|C=o<q}_RLo~?ICNXU)QUn;qC%6&7K@|`j>GeHAl8k(9LJ3-5+Sr|Tk_#jYS%goNF z!f@hPuk_KlvdUCz*ROAGPWG8)(kUV?E^KXWJ!#ssV|nGz&dl_RE}dGt^Zt&)X3%&- zL`1}d4<8CP<=ixS^y*dA!t~caK0ZGA;9zs-+_|zhx97`${Q6ZjEG#VL(h|>{)BFDH z^QnFMT{pV^=G#S!7In;>D=TS|ApqL+8NNPFRZUF|bjr3;IR6q?Xa61hem;}_bhrHe z#HrfhLQY!q9tZ?&oEjg@q#y5=svbTm>2Mn_3&TvaT&e2|J#5m}b>7~dUo6`Nns6+e z@jyJj=Hd(Q-)3yH4$Qvr@$qp^hDUGS_;4tK&Pi@L{#Z~{RCLme85-Ai9XfRA#&65k z*48B5-D;o<=HlYwRE&)`d%j+pwSJ*`%=h>AK})jU*nR?q`W0JPkWZXD*Vn|<v~$rS zrM=>D&CKk40t_k7&diKycjC~LU1weR$c3rl#Hmx0a&K=dlnvV3+R`GxkaA-~;?{fZ zY9Fd*+0|MxI&90k>&2m%^W3PA|GMImEvcLhEG#S?dvjJ*E>w^CYMg#fhRNZPpPmZu z{PXHsT3Rl#v9V9K@ruv0ulK9^^1_ipptQ8KbC+o_=tKe*hQiX)wO{Qn?YuIH1-z{R zbo|70z1TxvUtb3;T-Ax(<g(^#N@^--%A;l3GBwb7W*evZn%b+Wse$hFoOSh8pzp!M zhnX2b>m~b?C+56*_3Fci4-REzX3OVam9PK9C@n1wT6_2G*)vd6G$uCIvfEwe#Q*D} zk3UvGJO<iDHEGf$&}rVFg>k2+>$5X}4kdZR<@-oTM5JZWBBdTFQ?I1!i<W6*re|k! ztE#HHxVdf8z8^SswpFPX!voMQzH#RB&mX_CGT5;4Q_7PkPYxVE&R+ljulcUh*VmqG z?1(NaGh?`-*?xf~j^F3??VC42XSE!C3_i4{!?O5U$KG|Xudjz}_K7od4O|+vH4C)W z>B-Zl4?jLW9@DOTQAS4Q!ZKfJ(Du}oD_8o4<wrzFoH=s_bfJoKY^*Hkyqbf}><gDH zxsqb&AvNp3>qgH9&TTxPQwbRkoIlV1>C>mLTKbBLjj`;z_x%3;o|$3I+O^tyzW@38 zx$5fmfX(UW**?VQ@MvqVW}6-xEcx_xO47m=w^qHXczt)bIm3gKlhvobJAU<}S|%ty z-o5LaG)ZWVb@{rBuTP&mdGOKEZqORmBgc;)zIRWqU*7)M6wP3%z3-NV1OzZJ1cZdF z`D$m<cpbFCCGYMoR!K=o6;)Nxx}R&;u1VO})$BbT5*pgNbEl<Q-W`okM}vZbnqIuf z0PXd=abrfUt&x$?xpU`0TVI>&rvJLNzuul9;o+fH-?;LhRx=}3yz;!<85rxw^85Sy z_~)NiTix4L_LhsG;`g_;C%(nV=TGYRxzD=vRmkFN!ZI>E!NI|xt+}5*eF9yRwl02u z-?_Qg=2?4V67ud|dD-Rk`0L8-c{A4in>KCQn^SI&Ui^LW`t@l&&R5T$yKmaO+0)61 z$@;UDVvCE5i-4)ADN{p6X6DArJzclEM72FqQdBxSI~BdWyp}9j(D3Km?ff@9K4$_J zekz_cd-iN$d3pJXmKRQI+0RY;`SarGX|ew-jYC$hs=T1By?T@7&FEFLo>fe5agCW# zdF{24d~NOHb#E$uf4v^h$zW9btHjCUvTXjP6)RSBWMpRxTUzdPldSsw?{9V47hVR? zMbUBlYBax9sdVn&Uq3gzb}{Fkz8S3VVq;@D8Isb{)TXUeG&VB2Q6I+O;_lvF^YiI+ z76wBT6BXxnKGDkhmzS0%{m9iS|M<uibO}w-j}M7PH9rbKS2xwv)ZAe1_}QfU|7qk+ znHQ;3=lgB`^XEnCX}$k*R<2%^8KSMddRfIRZcl5&Rqt3fZ2GinR{Gx$4-cn+YM6I- zcPGWyEZg)r_tX^4H!f1Xm3ut3{r&x!8s=COI_0Etu`q#dn_skQ)v156e6m(5hL_)) zEjv5g{QA%OUbPQan>KAq3g5x#&?jrHwr$htZCtCWKUC~-%jHc;O`RCH*lnWzz8_6@ zc9nMj`1!N*3|~kn)A}5~FPl#JFORIN`?4u@dVOAUa&YF(RB<EC_%Pp(CgPLIl0xos zCZs+MH9P<7-rnkyZyzz%!qx(S&S2!o+;cQt<!Qy_uy%fVvD-XlP75c1PQ85b`n50v zs3HR0(7NiGQT~cvY4fmMCZ(lMvg$X^J$3S=V@QYy$XydAFgQCOX1n`aFaP7Cqo8$` zKWgf>-d-EInN3PcDrxn08(v=CnqOZyy}Z0Y3lnFVW-nO1Iy%vMVSvV`V&BK&>^u?- z?(Xg!EKE0U-gI<!X8!o`BWO3!tXWa5Z!2x&SeO_$ZQAtV<KyFAuXUu0e{OnZG%sjY z?(J>7c6N54MM--qKOcDhdExr?{15go)C^VpFJB!s_0%cQ{-Sn1S%xWP8Cv-d4m94_ zo-Yp?y8ta{y0$jD;_EBXUFGlNGAq|cZ*OaCWZYfv=f_v}_SVsR(?R=NY;0|BelIRA zzG+laQnIRdztyCoJ)Wx*54SZQfBf*&RBeTpE59ptm%J1L9aHgdudIyBhs*x<2M--` zn)A?W52)YVFem2iWh37Qr60cEuV1`lhlG}v7HGHMBvtQMUlOmoczbhqi|K+cS<Sk$ zY~$B=cR@2l6DCe<+_cGvjaMopQQF<zy+_7U=-01bAHIKIztJZ@KfmV32S%rb0-Mv$ zHg$G#y7kNPN=iz;xwUomp>K9}b{jTsYy`FBTw_D$W?x&ga@(3`K9~G@R#`KySz{w9 zd2!#CRjXFr*jH<9V{2RZ?2M#@q@<#P0z>ZYZLW!lif%m;jV&!KCqQjg<;8jOVUm+d z_INJ-_V)JSGiP}I|NE^E+OK9;`|C>P{|gra)<kY*+n#@)E#TMO&3SjNdL)gP86KKi zv2*861_n{lskh!=$+*ruYvHEpcfNf2;t>}&@5bvBCr&6xNlAsqor~UGw)V#BB}<}z zRvtU8FXP<tBK0%q&c3+4RTDLXmu*-dzSY6UH#M|0JL%z});C5=mEHSPtjpi639U@6 z=i}s5%*)Gra&K>S@3tR2w)dpkUM@fUr#3q%B*djp-rn!mx3{P3j;X1sfsUfeQ9m{< z>*1kR7KWQ!v%}YZU&y(K4|H7kzstF|wyeDPYUQhYGH*G(10T8fZ~w*3!=u7*;>X9w ztMB%me?Ix`?d_A#&9&Y<fBnXdhCly)zaL%mD9vDX<h9hZ+*W*hrh%4Xf#wMtnwpqu zYHFm`t~=T-9$s~R?W*gVU90S?_FSDmcdjghf|AmrOW)t$-`_veIDL_GJ0ECqx`4QN zdm}UZqcby&K|A-={O83y6!Y>v`sL_~)Bk1uKFNAHzy6<NT$~*E1e*-d#Zp&8Z`PVu z>Gv&?Vz<5b%HQ9g-_6a<!_Uvn$A^ajv=8q0x3|vs_thpQCpR~<^DF7=^UKM}b@cSO zq@<{TF540=w~UO8WC&Q^+VMg?!W(qt$b9o-bDlq)YX5urTE?y{n=cis?WLuq89-OE z7!*D6c=7TjXq`~Sj}MApzJA@9ch~C3@#CQN?Vy{1k6-j!_iM|6%9bkzeJxA@zx=EI z|En!|ae=Y3v(q=|IcViu<>xeprRnKkxLX%V@!Q^erDkd>Dy|=Q#NYm}$|i=MNt1*? z_fg8r%h!CnnZ9Ldtat40vZK4p-+%b_HX5|WH|+NXmN@Pf0nq0B6)QMahp#_2%QSn| zl6z;)_>{c8B?`KOXm<veYhZ7)T>e#Iu2#?)rcO>y0wN+U*5&U&2OHGJM@LJ8j;z0P z_wLJ+{<bSttZ+~e0PQJ0b?VgCTgz{%e3&vtWR7jMn4_a3XneM$q~ybS`~L;9Vqfdi z($YZNvgXZ`YvYk*DlaeRk+a!x)MwkJI~N}NZt8qoq1^J|Xty{AH}~PMudf$=e&)Mm z`SQ*0wY9ZDr_1^I`9<uhFx;|bi<F7pe$~@w&$g~wr4<qqGGX%M;NP;+3(adLd-?i; zPk`p);!<*UICJJqmZ`5&t;yNNoA$S_T&cOU;33oX|4t#YA*FjtUtjC}{NM1`ihu6| zFMs^@@v%FoYX&;#IwmHjW7@Q^RwEuBo)c>#H=l^F|La;*Tzs>3=E|jyA3vV`=>CSA zpo8QX9eR3tUTv8la{h>zoE#rNKmU?t%NB*M4x3?|&Ufd|9ncKji<d92X2yoD`nYu2 zG9^n($;8A&&=TXt?)?v5z3P%QPCIb_{``M?Rbp;F_6-aaT<qT8wsx)Vm#<$ht_)Te z5fv?zRr*@LYSk*x;I^9^o1AS`%Y+F6pp60R)~y5WX<8GxSwL2{7qoo&<Ye`VZ*L-( z)>ea#TT*mxJ8<!$U|(O~8<A~KOW)s<<>cf971dUyuddwKAGdk(tXW(P8KAXY-zMMk zexazS2-=9t#mx=czx3w*e)+ezw?DViSv8GA(W2^$#<R1t+vm)Yv9Pv&d}*oo)N^Zn z3)jE-XqIq*0d(e@(&q`rm$`!{IfjOYJ_*uM1nq>mu`!w5T4tM#si`Swx6$9<-`jh8 zd2@1dZdkt023?H&=I(Cs>Thoj{`vX&=qKwfD$mc&J$z$h^22xU`ZlMZzgA_xGN<wQ zks}8#Ulwj{ZH?HHAqZN~bn9~9sSg!4pz8-fOYcF4g-J<uffjXwM((UkR?XRTe0F;~ z`?K@&{eSCuNXqrMCmwD)c;W=d{kq?}Mn*;nIXOJ}`T3wmJ81Ia`nuTHe{Hjpl9(7O zK0a!-IGkr_SM!5`A>;bG*ty>(pIWm$<)qMupEW)+3>ZNd1)PlTnmKdk!#6iKgO-t$ zy}#F6|Nrmw*ArG0&3JtF;K4?<e9iQPga%$|Gl#%HK|@2sg3{8XGYpdxGBR!~cpvEO z?98xK`*>jK^eIzV7`E<vba2A1Gv(jk#e#M<?Ao=<qU43ZU!zR6UteFd$H&KWv^rVU zxF0e&K6~3XvuS#<Uj5tC4jehc61?0`^!3MO%a^k=c=-8=c~|P5-Ch2kVZpV>`z3>> zAK;g_<5^I0i8VAdv~TgkBdHe`xn^8m#@p1~d{b3V^PS=G+0&<sM{UhIT4*w5M@2=2 zLvV0#&T(nq2fUY+ge(+U9334We5?RndUO3@K+=^}q1ruiwo*<D1sok6W7?e^zf=?# z6g;q!@#+x~6*Vk);IL6PKlj#_#yxv%f`WrzX0%jw^!KwjXjT6VcU>h^QB-7fZ+|_% zt*z~?$9p6<ZQ8`dU{mqIAtzNzLgK)|gN$KeVHRa?BAQRnwyoYKu_#OG@9*#V7yh03 zxNPlO-Aj+>WXbI+f6wP&b6mRrc=Nn@avX|VMC06DU0p%PS?$?V^LZb8+<oc4Q%W*= zP8Zy|bqlmV?$F`G8;hTxW1GIc{{KI#TzwHP=@|9!8IRYlOAgk2d0@_z&es)}uU=&h zu=17<t>)z9)X>xf9ozNFrYCHbP=%u-Bf|ww`&pXLxR<^u>3uY5`gC=pK-SB**#Bj( zjN4ttYg_&8$P~?BmwWo%m9@9G<!;!vt!?vWW4)Li0g2Yd#l;nsl?P9s=KlWvzWe`w ze-l$vTW6c+E7{n{h>3~4xV>FJ@BThsh7B7wG%R1P?&IrQ`1;yfuHOc?L96i7($aoB zogUAy;80m&Vj^h$HR$xrM~@z{)ux^KsHU$U|9D#o&yJLpXG`Y1di9FoNckQ^UhQW` z`d7`}o`0W7BlgUabxVq5EL^9C$Hed~4B%j8Wu184*vRO?g9i=#@^%Z{`{f>d{u!#b zWkca(H_*ANpf#jhx31l`FZp=i!&_UkFI>9hlv=Eqnv#-mxQ*Aqz~Dgo{Mxq9&(Ax1 zdUD3a#R+h*fR>Md`gCvK_JZblY;9$ux97F4S))@^Q^VkpB41ryosyQ8^!Qlsg=^Q2 zJvi75-rXLx)hlK9p+ipJ$`^Q>2l;lErL3MmT|b_Qq3X+vz~{A@Ov{&m#<D;+hF@Op z|9JiWf2%&&6?4imBqb*s=H4;^UHOtCt;YEIXU#U@&TZSuwtme+X}~^s^-Akg-Ro;> z6B7~`7L??yS-xETcU)PSS+qZ>Gwl!@Jh`^_{BvbpUEdV>1z)&WFP}=(+d5U>+T47) zZu`CM%Vq`L-j>VQ(5JL=@$>WZnHj3Sy@`Z4EU2*1kWb#OCvtNdBLisR{9_l9sHmtn zsU>p#?2Qf$Yu4y|<92s;X723loG@|X%EHj4prue3FM>{gEh{S%6{@%y(bLl-ARy4N zE%!EPuc4lvUPpg_`<gX6SFT)Pn4<O;(rN@v3C@}|OX;_P;q>r*Zv>UyHaxvBb>WI- zNABE8$=e&S_3)Xv<7d*s#Z4N!18?d_xVpN6j_TN5_V!Q%BeT|?^BTMN{g|p94x02W zi#)ck_BZ$-YO|b(rKKM#Y%(%44<0?rdV705=)k~LYnv<cA0BGGu{C?TN983WRlCcN z;`Z0sCM74|ysqvuBjDw?GpZ#{94t(X*Ve^yGko~?v9Y(8S4UU(=CoH`qS^*IHw+@8 zqORRw`u^?Pv37oW1re^BlRH*{PC=BDlY8*7BIEu(+iPngn=dYQ2OV$o*E%CRI~jCm z{GT6&-`?D0*45RWSPQx#bM>b1H4%*B;^JRkU0ofy^?<luOviHn`H$M=>jZY1K6w1N z`NoZiocsG^<7>Z$w*K9-cP}VSfNr*~1x>WFv9W<pYOMPDik0Eb@5IDJCHwI3u-I)+ zKUM^UhPE~~GJ<wXSX=L|s^y#16L~mFL7+gUvt;4)3#w;6K0YoeDG9o_2eh*6;>C-i z_tIy~n#H8yd+%^Nzx(TJYd01?c4KImKVQC$U%t<Kx?ZPB;j$jkb~M{+vE%*n$B*~R z7k+(pHS2W(XpOvf__{Tp_w0^YrB%p$;NoKU)j74(?@u#KKPPi$rm_1IQ+IcFoBDq; z@9*zlU+{C*L7ttQJUna6?rm}|{`KW$^M?-w6TdHBw8*7y+SI9Q4bH6nW0!h*Pw{iV zsj0@(pUe^#7Z(RL0v0Y@n8VcH+v}Q>qXX)Zfo?Xty)J5NS8d$B<O{1pSAY2OGI)-4 zIp1uv+(Ym8|BuVvdv$8)^xW`uF`ZAIq|C9Y6j~j&_Ry=Vt7qT6QMGKdvMhUCb&Z|; z$&)89T)2?%Ti^<-?}Oe4pU>MLpJAB1A^p5uSwmeUXy|>uar)ZV*VZ-%XdGF;|KF*& zK2sBuBP#+IZ>anGi;EL<m<>BakEAi%t5>f?_Z`t*-K?mu-=BMXTjJ|$Yk7a@&UP#9 zl-Ah$#-#9(%f>5Hr%r8!Y}%EJ-j*ZiJ#$J0kE9XH?(+A?-rnA>D8R8`&6=JI7XlcT zp4|Ip>hgWHzc-zqI%SH>slt+ymbr6f&&{<yuBQ+<_tmLYr?>g}`7wB<--_CrCCbFi zJUf;tJ&(Qi*O$)69!uPv-_<h*nf3TYEm^u$(ZWK4;l}CbsarEIx78YSK6-e#oxy8= zg2b8PXOpUaS_K6K6}-5h$gpAqTYhS(ftXH2L+$Txrl$&Y3pMrhj^*$F+xG76?&M!z zUWRU4Qd?VlblVKj4n`+u=Z~+hYVX*&vvcX0TSCvDn4X>3)y4JZ&6|LT2+*-LO#)4z zF*}FW$+r!Yk8SAR6uzk8lGyqC_5XPp-aP&MDkMCtcH7o%+t>oWPF2i2R<cG%Q}dyP z(944{oyO+o>#zUY!g`NmMyLL*?fLO9RjrmiWoUT2GG^v0u|5s!oo#JxZmphPt5!c= zy?)=Jb91dX*8cvcb^7_Gc7FK_d#k@k)t>a7V-c96Ti~^6=Z+l@etmrnS{*!Zo}69X zACBPQ%Ur_Nxwp6V*2dKxJ7$=Cj6vh=!vA;6?_Z5bFHOCg9-a9zJ4pV_j-s>_*3iwH z{?2{XtoFf8KuD;mnVtX9m6gE}JBw7An3!Dd=~q|IPRz{gglt(!JklY^@b9%s@J)Gh z6B7{|IsR9#UKyC0uHA6KCAHKbYI|O<W%09w@9*xG{=2Kur5zR)cH!bh$B+;a>wEW) z9$k8<>}suK-rZfI;(9Tl!@>(bJOEv*zUY?K>rY3cX6Me_$NhEY7UxSB#VYO^hR5mZ z>b~A;@B5%P;l_r<4VyQE4lnJKv25B|{JiUockDLzjVo7b`uO@jeEqun;o<hf$B(!F z4Y~<g((7V%++daWh0v>k*CwfYZzz9%uj+4I@7mbiWgOhxtH0edfBfU)<D7a1uRTgi zN(LDh6xJP1IC<j4ftxoa)&1sxmKZNwupl6lzu?&=tAJS=r`5c*wY5Qov;RDsgHyG` zA3S>&_WpN&>B{fFzP<+Sx9&f^%E~iH*S)UJ4zv+RRaN!NySuyNQZH0L=yi#VoEe+F z{ZFJ_@y+r_M>;KPf0;B~T2lY=lB$H1RMO8+Pb2o#Sn}}lYQJralb(7taN4?cdTHn8 zME2iblL<N$@Ya@0P@A7m-Y(|pTDE1M<*yn|$t}En^QNP#>(WDJudlC9mp@~&B~?>P zE9uphl?(^`Jhl0*UfrE|m<?1ow6(QGY|o3`{Q3afpX;C2y{@^Zd-d`0e$f2}#>U1c zPF`KF>l^(bDdgY3u%8RPOz-}eGRukRJ-KU{(W>hGf2wzvy-hl<=&hwT(SM%J&P!rH zyT$cEr%-~XTMlciTy|-xxA?bfL6xC<<8D@ijtl~wwNtZSFZF8b?PonZzn{Isy?oX6 z3%~C(<TeHeE!rja^U2A{nc8y}S-3?%C@uc}E|$Szf8F0#v24B%ri5tDKEW?zabREE z<s(`muBLivf6R^L=B&E6HhMb)18AbVT+*a5ILOn_kIy*$oJ(M!AgD55?B0JV%)+&> zBXZxiecy|tC$+S&fX+gjYgL+cp@U`C0nL@iww(C?=ks~C_4U4iA%6|C4~1XbI6+9Y z@0z)T^~S)nEVi$gYvdWOerA~bW#uZv#UgLszLgH?3)y<$Wl`x_Y2&Tg#Zj)_vkZ?% z=ZY;~uvYKnqE)M+9-H~BFD#VJKeK7inOzS;t{%C{G<_AzIiHy`rc60fs1lOw;pfNJ zP__1ybEkaqo~6r{70Ga3m6#!%Rw$eQ<;U8&Q>KW3jsV}aYuAf=d#jsIO<KjWZu#=| zZ*OlaTUtuKzrX*vm5kS!8LYNz)~vDUYhn6leb30qNTuqb^s2hJy;ZCZHOHkt&yBe} z=c8_{hX+T)spX98v{!mPu#w|m?AFVq$g<pT?jun9{?n&VpdBNQZf<Og-FhEc$#5+? ze!ExNd<S2<(Bh^hraSv;qt_gd_VVItxD+Y3a#ie(0!D@#sf(qZRtZ@!_{_JHW!R8; zS?$S_Cj~ORs(RMt?_9F7wA}h+Jl`+$6nIu)UG_%e)2B}seQiS1jnmI5Xlr|~IWE1o zC2sSgMM^O{i&#Mu5VMqa+pP3{@b}kO(CykmK|v25Kfb(X`txi}(3J?Kudjie_xjq} z$5t|{c%D_9K5+uH8U4k_YdoN(K<<4qg0DYLn>Vkosfp>uix(T_%CGEFQc^nb{BvS@ zIy*0KFWYqWQcf9-*z#~^XXeJnM$n+r3l_PcHy<A#m#{9=`Sj@%=$38JMBr<1NAK;i zUg;aV%k_O91?iZXiS66BPeVgP;Ppp0{rT7XEcE9y2hBRr+tX9<>4~R?hDO5kb8`!d zix<zmwS-5J1+;-YCpY)wzrWR>-t=+#`X^R8tAtYfw;QLQOL%%}>XzWyQxsbsoSLc) zT4{0V(xoGHdoG@SzE$}hi{94F@t_m%UR_-cny)G-FzD&&0Ub7KZf^eN#YN_-s;VzR zeJ!58zMvy44jnoKYHPap%P}&fotXi;+-4U?6N`5Bp1*&;-=ATUDHIbE1G<-^wzd{@ zJMe3Pl|`F2Z32y)y7$W|s;IE6kKfOB!Q%Ms+2;8S3~g;~N!putcJ}ohJ3U=LF(;=- z&bF#!d4ST>py1$>pr!LoO-zgj?9QAy<5IVbKTm$@Ut1qv-;=G};yeC{FM73L)#J6% z+w<o9@4x8&wZ8wD&Aom9eq}Q?{Q2>?zc;9^cthFSD5i!VzkYSC^^sFN`?xL4%ZuyW zJlpOC3lu<;aaLAVZ>m;{d_M!;fX!oTYYS>6ynFW!bbMBYjokHxfnOc^%}-vta{Ts+ zz{LVGGCd0xDD=o!ZVG%gq0F}G%YoJ5>p_dT*!&+H$}r>HV|nV#8JFwpVn2Sp9)I}y z_35t*G*(6KE_le~)+fUm9v%)lHD0za#L&#_*z4=-LHnrk?(Qm-?K{%h)z#G6%6jJP z*_+Yrj})fPy%E)QcD8x*`RB=BUtN9h`DaYKbKqI2&BvJDS_hjmH8O16xG^9s3^X`? z{h`N_<l}ve414zMITEGk`#?y`*jN~J>BsNS=jK{l_OvaUwSUbT9fpQw%hZlf^q9Wf zfBvE+OIVgITed|xOO->BgNKKu|2XJKq9ajez7K@5j`ztbt$p{&K3GIGE;BQeq2b!v z=wg}9lFqI!CWaZaXBW$KrgZi6xWvTB<mBdF+*zEyahk924wh4A&aAocXx$sru0==M z{oI1=&)CLtb9478PxJwuGQ#lV$B&M^IkOI^286E7y~VYB#WCmOM%VdcT{mRSoH^5? z@{`JzEn6PEe5v{EQzp}NgR5J&fQn`*e;*&7hD$S_uec@1!P3#y)wF4o(cYH0&V~kt zCr_UqynS1GZPZqw>YpZ!-ZN%J-P|JT7x-xU{Q3PaUSxpQqu;nO<8{H3V|%N=2gJni zNJ~qfIO+NJ$h_Vrfu_H|zc(L$ocQg{&E6n(-v>fV%ye^ZaV^*QSpDUNU{`l{Vq&7B zaG>m+eYMgI1_cis`jjWynCIO&06ISZ!2^YTD}zrj<cw*$vaNJ)+F2=(PQ$LA9u|fh zw{8`I!mFc$f#Jr@n}sr+PZHZ0&BI<xFW`(xN=ZxWT61>w;>FEBKR;*InA?>9;=;l= z)hz-)e*QGA>=C&d6T7cQlHtS6^!bG{onJIGG(hJYfer_$uC88pc%nxBy*&qSZcbmg zdNp@>`FFR~?P>*_8<UUoecL&IzC7ss5!Y@pMg}i0FVHnK9UUAiR<2}Z0PS-HyYRv1 zpB)_?4Q*{~xt`Y?Q&Ln|m>6?%a~G~zbEecnDE0NVwHkVQ$M#fyUa(-ng^aHkSo9c; zjExJwya@d9^QWS<wX}BFnub}kq^#wpO3u&9&hCEmCdb9aWkLS^eP7}%Tss{T5)`<& zxC{~xu~_wH$;Rxh5@m2%#}~9Tdoeo;i-WH(XhUz#m0cP6yqpszPi|hZLStL$*?{2S z=C(GrA2oJAYV1r*Oc<u9eY$WV0JJi_yFhbQ<jw8*@(c;DuB?=CSBiCVa$=aWPSpP| z=#p>HV$wsc+|spCal52uwn&>~2q-Bj3CPL$>Aw%0GNZMvEeX_U+pyul;dcI=eC}B) zDk=+#pPzeiW25q;M~_}?I`Dt`%$c0EwY4JR;>u=bVpUaDy;1UeTl5~DIdg`Ap<mwq znT1eSR$Pmd;xxTjE(TBw>G(yD>BY~_H41=+ooDSi4LUTvsHn&w_tq9S|9cF+4}|(( z-mU!n%(qW@;fiNZpU<y%3kebV_2nfqKR^Gv!xOdY|NT^F0G*~U<E~^m!_w->lP4eE zZohBlIrodut`={9|Mq$F<gQ%3I&sb%p32I~b<T@4R*DM?GlNb-V_^cV{B>^Qd1$4w za^kdUY_YMi8JU@is;aGeiofbXqmrN%(<djZKmLBdK7W!`CU?xCmoHu<ytuH?!{0x> zx;988w0`H#ouHbisJQs!QStZ-Ph#C08yi6xriD{D<I}(WJ9b#Sxw)CWtE($we_ie5 ztKPypL}r-fN--q7zqj`en^R!Wx(yoygw_3yOjh?#$ja)PU-zr?^@JtoKsQ4(Ojh@Q zW+8O)<KOT1mF?~2xy5uGrt8JdS`$~r8OtRiE`IpJ1p!V@&W@g*BMpqqJNP;mE%8fC zR8;ew)pB{c|6<?SW}w?9V=LG6#qF=-O-@cOd3}xd;>C+G?aG3nTfwrkvq2jc)zsK- z-MZx)W}e&V&A2R>MUf@G?x$*3clXhtb&ZXTGBPp=sj02W$NNlo>^U~)bNC(5eYd3? zA;PCloM`Co=JuO!$IHvh3t9uG_P#3N-CMtzMy-!MRE}R->a8fkwGnihn(sXZ1}D$f zMT?X`mqao(fYxLrX>QKHzpq8WiG_)A<Hn7G-ZM)BgMuzSDK+}__4V<{yCIi%mAn)J z-FL(2U{&(MVbP*RJNP`cL`6j>_Q_fcSz1~O$;+QFwGdLYu$aN1FxR?Vt+KMxH_kq{ z(VNrK((=!@+xZhFPd<FCSNh}i`1;PZZ}#l5QBhOdWFH+Fx$*qWX|J|sU%#+9-QQ=X zk?WJcn`T_!o_m`uJ3AZH065gjExOIv+`N7Ibn!iV_7wd8R|`6lB`hp#N9AX=Lx&G1 zCMGt5`n=wvQ4tZK(eP!<mhC8g9oAYqBX^nKTrOi{<3FEH>oWu-?%uG$;LDqv!jskg z#cqf4coo(D`og(6{rs^GLFEZkrm&=^r{CFIEnfTU%R?)Zl_mfFRH~?{C4G5u@x_&u z!q*=b=$V^~bBpOPF#P#&m_HyWDC?KPtUps4vnJ?9Zxdix61qC<$)ls)yjrWXudh3D z@7}yGFD^D)SXoV4vqs11M7?gY)4%MMR+g3%ckHm3G-HN`Rr$M^%*r!$u$6sI9RV6^ zHpDLXn|ormc|M0?%Z?p8K+9(*O`YoM)+6C4BO`O8YR;TFH{Q;?9upIz^~RY)5fs*) zuyup0y-v$nm1sow?b}z^Y-jCN^zmoSr^EdA6Rxd|7G`j9b#49e`*--S{T^5EO;B{^ zU?}?fDs-LmL=Nw1I*JUS1$XKHqf7KkG(W%HeqTvZkr6b)09xMsxZghM-=CjfXYqPQ zM@yUM-C<xja_m^rtu2`r<?rU4FnjX9R_14o-IuRlZ~k4iIrp~Nj~_o4ELgzs`Ptd# z)vH%eJ9G2}Y%Rcv-_Tj`hD)j6!BgLxHgCRJ1v>tcVb-i!Z?bFbK${noelsjR{MM@E z1p~vI3)4QOK7aOX)6*9(UWEL%4!HFEe*OQW8<UTJIIX{5!Pr<BG;9Cq)1hBqU*G(1 zzN!wiK~>s34>S$X*Vh-*et4&Qzg*(+KG}efkR$*8{<fUm+ox8bxuy8I--=bMk}fav zjo4A3xGrvQmvcLxsfK1|X6DA}7m*hPxHEt%7$IR{(9v@}Jv~{cr3?~4M+hqla3rLs zhbuOoKJlmg`LPoxI2aijLFY7ZadU&Nr1|lq;>4*_o4R*@_*tW(qT&!1Cid#ps|#1I zh}>-N+_~pdYQKbGlkW0m_ZuhGu(Go5D1R>py38ebx!=a_-zQF<1T_b=!`3)_e|Oii zZ&T%sEt$d`iZiUs^Sb9-ZC$d2WpmnDr@}(Ru(eS~U;dZyeGt@f{4wZMEoOGUBR!JF z1^@n3-q~Fa+MIQKP2}dRT75NTWoAA;K7|$s1%ZUOx3)4c$ji&$xN+marAw1+H6u1A zv9|F_vw3@;mWqCG@7}#1A09HdI4P!`ofZ0a+ibJkruKHw(f^>WG^W|tK%3(yOq_Ud zUF>d#DcgQb*NtvF-Y=hgexB`xOP7RhK0neayj83EXqPDHP>=O-do#FWPSyPS!U;O} z>GX7c&>3DXZf=kM{r!F7{Q30lFE20W2Q5Vd?QfB_E_-5d>zS&VnV7o&JeSwk)*9CS zDp_~<;hlN5)gK-lWS%i&2I%OAImeuiH+t{<{{DV4X!iaQldN^wk?{E1)=pvdu2Q2~ zCyojmIndmSzrTM=dwciVH?txlBOe}YX7>%7zva})lLx!S^*_A3YyEBFq)AO@&iH&g zcxT#)lP4Vm0|j@l@9E*$9it06o*J|@fdQ1HMMXtdtXk#d=*T#0)-33@hAUUDDCp~- z*PFd!<w{Pue)h`B$`z|tF)@UMhAQgo^UL+KySlngTypxzr1|sv-@M6r^5jXw`RAaH zsHUbSD2OLbnlxd`l#qwtLqkGZdV6{2%$Z|Q_ow2^o14LV<TY3sW>}Z&)&2XKz9x1z zs4o@Met6}M9TqcY%~CQq7dOwpcVvNMvqf*a+K049^XvZ|oMoCVAS1)G;EUac=4R$Q zckhCBhRm2Xt1D*Ly47dS_<*MBK7RZNTBvpB&YdHoRlONZ>tkwaY(S?wSAT!^@ZaCx zpxJ3JFRvYZs{=t-c2<9X_u}GWcF@pqbaZq?bae6M&)Zo&eSBIbP859d^r@h{Jio54 z?mFj3KAxVOGP1ITudnHznPVx;&L{K0N@do8*|Y2a{}tc=_nS26sE{X5Qofb)^77ue zd2?a-`ZxnKv$XW!tn2Gy7vH~p>il{4xH!44?(UB-FRL>wRcCQ{x%A?ywi3hdd!|mA z0vhYwmV4XD)pcoL@>I|%PKP%pA20a!Ceo(nhd?TSJm?hG88a4mPuF|X99hy-xnlL| z&9|q;O1Nu?fDR|H2NflMxw*KxC(fST4cbv8CZ?pV&CSZnD!{?=<I79ouCA^LQ>U^r zoH%ugNs-0X)%C>5lZ+qYv*!ymH8nMHd4`9Eih6l@1%!u#PMbF|F<G#DIeTnuEa((d zS*wx+YmFe^*WLR24lHzT2epEdPEXSXMcLQa*AHL6E<V?~9MpQMzS`++(r6y6s;UZ_ zjypHky8Xk40???n)4~mh$~JA<lyP^L>8&l9&DYjOJNx?bdU<&%O%FIN#K8jUOIPY@ zYjd}@wt_~n?mzzw+Fq5Uf3vH5(<Y;m(o)dXlX-V{9XxV`1$3<Be7o9NC47&Tef#jx zIp^jk*5&^5)1q(w`t_@zw6wLimv_zDwHFt=^Y7ZhqH1=2zP<Z=yIN2%gKpO;eSIya z{m4wvAwM4;9AxmCUbb!P)~6PWf=n8>3)I-j3knKWe0w9gXz^lD|L^+x_{WFa`7_?s zGpeepg3kRcDk{o3U-T?!&a7EdPo8MK_l^t-Y69hf=g*xL1Rgv--hblk*|nSGYHMpP zEG!P3Jjt1tm#6f-Wa-t{*Vk_>c<9v9(!#)SYg=x&q;XopogIZ6K>J^>3Nte^zj*yx zSzVnSv@T=Mo;^|`*WcXSys`fOzpA&|ebGvPe}6wd*ScIPge}yzyu2K=zcpfeo-C-S zEVY<(^3*9%4;8dO4pfkReRVaa{m3HDJ+0cBnvPLXQbEDN6Q@mU^Pg|0Xm20?L?|or z)TvVeAt54_zQMu5TwGiMp`oewuV1*(uxF1=^~tap7AD4^pr8qpCN+V=;ApovC<B4c z+uu|Dz3=Y2(A8m}<pX>6?tS>^(WM2y|Hmk_B%GgT3u=9{FfoD_ywv<G@|kb9H|~4w z%q26YPiJRmXTP(zdb{AFb<sM!j=~j>x%l~yKRDP7irX18W{B0kK6UxBaARYmgh__L zp+kpMUTcL1pObP9?A6rM>tkVInXoc=xezZeFH-}9f}5M$lN%e8gN%j4{rva}OG{N5 zIQow(7e70rc=P5>UaiS9RrPIc=Yn>79(vvK$NcrZtE<DoyCZBWH=X!Bb?Wxg*I`Mi zsjh8&vR+Ni&92)jKR@FwEGba|?YlU5uyM)q<=t<pUtiNr%FFZ9(be@#Nl9tl1iDNH zbh-)XMxeYqI~>==@AvcZ@j0=?bMmU5?yMc4R_Jnnd8URRzke6Y@-63+v+-aM(ACxb z^zN?py2C3Q)CyKb3URQ2R#&BbcyKUB>HYov_B(5Tn_XWRs%>sQokzxE0)s;C?QN>z z>tY1GcgFb4e*Nl|*S~+i^S`C1eUwVO|LO9xY5LuMt*3k6-rg?Eu*849-I5h6I$jr8 z6hA*FyJ*cCABG7B4mhkkyi&yXLC9ut5fPWFZ*M#q1S%^lH>IDKTj#uLN`QvSV)uSE z29N9OVo$!lzW!)f*-e+f&(2C4rJb3<wcc3!l40>l;h<RyR%^e%wKe<5-Me#pBn%fh zao;&}X3eeI)6;Tub7L3kC@U)`<>#Nb%Mup9Y5;1q#m3J4P+=n^D0r~cVveVWhXQD; z1jC6YR_+~q%e_n*gLRz(0|g^DCb2&JSi!<D(=eG$Q%~=im5!jad7cV`$859QBeV8! z3i@7=l$6Xd+Olbr($1YbRWvm_OI}`T6$rY;<nQ63;OXgUy6pff6QkmiFQ*)TE_wCp zmDjs_dr$v6v*m(zcB8eGRhY)>&FAfu<?U(|S_Fau0vzVdnd4DYQ?s=&kk>fz5X-k8 z87qs5i#vOJc^MsKWMx%<X|c@pnwljDx)J#KbI`pLppi__d266z`*!|*&m(uv85$ab z&R|bTO$A-UE+Hw|xwS@b+1a~Wv&Cy_Y63z+SXfzE=UA0`rEuK_$5Qrz2F4PtJ8B{l z5*-H)IJ|iABH{8f-<bBpoK75R=jL=)e}8xI#0ie&esfn9P3duY@QbHu(X3nd>;L<P zgoJP~e0tn(UnI+?_+<aI^Vj3+&z5TBcw1^}c7n$&c(01w+h6a$W$RW>hEK=k>kDN0 z((8UaWM^u~$jF%R{QUf4S-;*F21ct~L0z4g*jUhnoO{1qp;dpGj}H&%L_D+HTMAZI zQE!~zzv?=jS-f(YI|u0Ogu;)HTq`On9(;LuIi~$c=jZ3=L0kWfjEp$AxDI`Icz7q@ zO1Dd<7Sk3TN%`^NVZ^2sPA+cljTsk}{E|O@|K1*;ab%Hew}t;bhnFhW3l}Z~%}4m& z(>-wB{(n!mxV}?(xVZiQKgQP|7CbuEEB)cqCniOf+2;Avx}NY}=!{t*=A$66AbfpX z#rJozN=ix=Gvzk!*dZZnUFK3%WhEpmd~sduZngf#tetW;6%5hQ(ISwoo1nWiuPd7F z++F@2bTe>`oqX~0bFKUL+h13_DwW$9tUGPfCL?RtC*R)Qw(L|iG7^%vt7%xfR@e7l z$Yd{n|KmFfAA{!Wj&_T0Kk?-6las<bcI|39{~UBi3TWK-y5dz%-v=SxW|f~(Uc7jr zprOI>^5sk4IM6*Y3<qxB+<Ef#vM9ZU0UakNt1Ij2@s*X8fey3+xoE}=2_9)Po|i9Q zf(~SKaA<Jp@mR?{>%dAeUq?sAckkY5=;$2TS^Rv~o`2Qf-!U@e<mAlSleg+=)XpMR z(8c4RV^^P?oUG)1dK*h;XJ<iC5$Kdc(18XA4mg~g^?1*;45sB#dlC<~F*2-+*?CFh zsk(~FhSv+Ge}8gP7<@k-Wc9vVXM5JoZ*On6`_49VbaZ4?_n+tT``g={d@DUw)zuGQ zyeRnb<3|aL0)=z)?c-lwI(Z3HRvk^YTJP%SX6E&C)v8qn=H|zb^-8-6Ro2zn1qB5y zSh9pAHa7O#*Api^EUc}!-*{*f@_1*_Q!X*R7!HOXPp8Kx<maC+bn(?TGZQN-E35eX z%Tz~4r{LowR}F3LV%f02g_az17pb^{&jb7P@$qpt&HLA{Pmc{bdj5QWN_zU_>+9n; zuU;zX<l*AN5*Qqu9B!W^CbLkZ5VTTpx7YnoPfzdUTYmEI@Avy%!o#OCDE$5PRXH;= zGp7AY!WLG)Kn5OOUPgxedwVjcd=l4>J7f3%-R}3GE4Dx@`x!t7ET*TY-?({mqwbfP z#_3MZ&Wi(+7Dmkz*N;1J@?_`R+_%r4A20Rref90_ZP3-{?<?c?R&9;+IqofN;mY`? z_Q3b|_szY2Mny$^`1&=q-p}9v_&nQc28N3lFYc)Ns`Xp0|M=nZ`?c3K3IlZgOG-@U z%$YM`)~v4ccE5S{|NFK2%GYgq9jB-3AHI20a^}pLA3l6I(8?{oVAZNqr4dPvAS(ib zf|vrT;&*M-iQBUyZ0#%4>}waUnX8I{7MT?lITaNd&6ztFbpGkew;Mv`kN3;B&z>#K z!o;}m$0Kgg@vD)4|CuxfhX`N1bZJ%Lt!uY(oCCLh{Pfh@!pcg?&`^+%kMGCl^Y#~4 zg=()moMklIJRfxFCul`r`MVeyivkC&_O8%&wSulJC)2HmvTu7WU-1ewoKRL)=HcOS zV1Z*Z=pfXW?{Z^7J%kx1nL^X_<M}`(_uXBh|Ni|u`)M1a?*oymEvvE<FJCiP<(sY- z+cbHy@TJR_4YRIj#O$ltc~s?nOAE`5n>Qcc*q98u8+U&FzfM)}X$7)jix+avSu`sm zbZyS9U(2LkotUT$%0GE|dNnmQ1@G?c6q~%~@ZrOtbylFOCvM!3D1Ub+^V{d$ms$J* z89=k!48BHNmTa14mRlRl3p(;7f8S5Gd-v{vE|)kpRr}*<{rx7ptM`S1hA!vKne*Y} zWA`1qc0Ibcx7xta@S)WjH+N7JfR?o}ym<ZE+_Uy+^zAKQeXoW`MM=fP#DLbUgF030 zd@={xc%^4OwY~odG<SAXJU-#xo=VUlZI`GvXew>%jO5OB?0$iu;|5y)`~lse<lySM z)bmx$z8cHjTp?j$VckD3Ej;r4;o)}Bkl&+6k3h#I&atZnEsJ|@wMGqeiZW>ZBk0tI zt}ZUnR%xFZ292*b%n|_=ZTF7%%Y!cFmX)2W=6#O=bO1_5Mn=NhTU$*kgG-$_4t{%k z8+4lQjvW>^ZruXi4yUVB$=&J%YB@8r@f`U4{5)vLsrvi7tvjCZUJ$cTRRt}E`1U4} zg_ZT;)6>&0T)cSD{{NrDr4d*D&zw0^(b7_~s;UZfBK4iScMU5(JP<3C+`dv(O${`H zvZL&+RE3S4m~K>yZuGV-9jcCxA3ruMeHC(NPo=PtkrAlExVAq2{u;IPmBN1MNy}GA zfsRgN<rWiQWo0ch6ku2qy**FK{xbXa{!{<tmMvTM<WMVj%ztiEZFT>7Dp65UEDSGi zY*gmt<$Y?kM6LME4Z}q%S9*eXc?yY%9V_*ivskylE2*`;{qW(#%qv%}1odjWySYK5 z=<C;m4tQS(YA*?_{2v?|>I%6E40KjaOH0dxudlB&G(eW=%6D~j$+&Coef0S8#)^+g zpj9;t28oAQ-rU~Kf9uvQ8TV^HjEs#pCLCmvu`c6bFerTF^5ge!=iuPUk5BAy7q(EH z=;Y*NQ1vB4L`*E{Km#M_TvwO2ij^x?D43g1Kg_XmQ%Gp&#L1Hn|MTH+%*fCHU2wB! zj}2&q@X}Im-L#0wJ4D3AL3e+En)yXVMWAh6ptVqw)qEdWZE<twI5<(+9n>FFGBp*I zl9KxH{X1w#@%lnfo>>PpJB5XXnYFdGKm4qzsHjNz_vfeRyQP;{^de8G7r5o*=zxy5 z+p@((Cu$3ab=jK-3RW*mKt0^~_VWJo?OJ<!ctC{+Xh~O8R8&m+wHNbjtJ`)KKUcD` zkzoLxAvxE&d{OXnKN)wm$PE1wuSYtOn^<b><oWpcrmE$8RY^!lfbP}?jZnS2yZht& z{r`((CmpH&_D1qpk0f(-bv3ACC?+Nb8b<#1{{H<plgsn+^rq=XvvG5Cx3sq}&c415 zbmh*?&FPt+*0K0LnBuat`n%q_`S$#vdlqANO;LLfTNv9Kpdk_|JXc6mT)aK=^0I?x z&hR`xKfit6JUP$->F@8^etCVp|Mdr{yFWia2c7o{O7}K${MzB`j%-dp|KQcDQ>7U~ z-D(A1i)8F-Bp4n%eR_4#G`pO4Ha0d3R<7)P@F1b=R@ADHm>8LTe?ECjNJ}d#C@_F_ z5PtrA`1SSmpbLdhoIF`5o3yyAv-9AJz{Lh>XC#gsKMtx>L3`ZVc%@&IJMd;OEmvWK zEwwE`T}}(SDT|f0P`1ydqpR!ClarGZQ&L*)?k;!s^W*cLt_NE06}Beg;*!Z+g^Iem zyr4U+*T?Mz4T{9Z#>&`MiCkY7>-_!Q-JN{?S{GRSJbRuzN!e5XUk)_-zG(%=)h#ph zpR)7I707Uww>T;4#qZ-uPfrJ3RM2n#4>a*uQ(G%2F5Z52wz>K5-*=cA8SMXjVCLcF zefa)8e`I9jnwXtJ>*M$53GRJ;bY*4y?1f9bf`Wt?K$p?UxI3A$JzJt<X*u(;$E>)T z8XM5vU@}%E9kCY2Pn_TY_h$F*jXpAI{?DI3L1*lm<=$$UGDYOXi4zIOdL(abNM!!< z<;xB}f31rkhl7qlS#fpBgc6RKDJye0A}c`)UK_rA`ErcUU5SH*DP~6jBdE;%`ue(} z2p4Gla-nm3(!D*E1;xe9JwBiJb3{c%bTqT`A3A@Y-_z6c!N-b%^77-qzP<*X>A&vq z<SdiMU=dYO4n-k*Ek$eV*|OhCUS3k=U}0iddisjrY%|d2DBo=<y4Q<}iwi$Ia0Ja( zdw6&-F!V^7a%Epz1KK8Z{Gus8*qDp&?(Af)udfF!ZO_WeifIpa3<?s`i`~_-IsN>j zTU)a=baYr4G_<vo|NQs}Ivia_RyNutTbjYh$Y?|P`?xo^wsL1?W`fpUTNbI*)Yc~E z=AJFBILqbxK*ZH^$!zodq+efNf{yet%e$jtc+%R|RyHv)aYx->&~1TjFJ5GPvn?$x z?U6R;OFrIr^uxo$(MR^?9-D2RzoGhj-k)Eu*MkOtK)sr$Pg_$@Pdj+#Owa2Nvs7mt z&|Jj_nu}C+?^Dpy;+k()+q7(%+L^OwK~qA^pc5gP7(ff4O8&F+%Yk;TzL~yn<3>Z! z^n<pxcG+yu^wXW4!l1#G!a~C>TepHjcTL>hs3m=y_Ur{O)BI*D*Uugr8VV{3?(8Vs zuz9oa{q_qdK;zP&Ya=gbFdaD5%5B-{sv+{|>+9>FeYfxK@9+Qcp}@t})loxa({0dx zn8WS-$3dF}o;<noXxg?tb$_kO-rj0mut0&M)d>`?@9yjb)hIkXJUjT-M=s`^vnWf` z%1R0}&(z|ic&tyBo0*w;$<n2uRnA*){Xf{u9<i%L)5OHYp!k^&!-0#7-8YuJ49dB= zsnz$<>uYPBb8>V*W453TG9N#Fd~+%;b#2tvuG)KBv%@ET55rhTsalm|tH=V{mIFE$ z{`ooCiQo7A|My!>QaCmuqGQGk2~ar)x~ILFogcI_M#0)TI>lO6Ru;6Bp|7v6ps1*6 z<Ho|p$JH`_)Y$#|@t7ZU=3&LBC!7omf|vV&ZYWDTH|M5OnCD~`lg8i>U0I6)23A(q zh;2ENcE8^kfBV`gtbQ%)e?tR<fD@?Z2Tdh0fHo<Ej%=_fdcraLz|2IqzP`Q}*VaZ) zefst7?di4amMl^EG;i``VFu8sBIsaKCT3<;qefw;f_HZ;b8c*4?3c4$^}+7*&kpap zIy=xIlI8F3fv!clc<~}=90+ub)VsUZQ>IMm$kA6;Zhm)n_u*5gxUOBh1{%9LbM|cX znZIv7fnxLT@9&SFoSgjTL~|oEJLnt|3G1?)&GSwDE?w}Sy(sJD&CTfy4As@u6R&6A zHlCH~8XXa_VZGtr!qfNMWepM-K=<)vU(?x=e_w9ev}vF_FK%tm*AKck!!Y^A^E0Yn zKF#oR-nen&)~<~!K}9GV+oAL4`*RP5KHL3%-|8Z(vwQZ~q@<@mzP#N3!RMc#eZtHA z=TDeBxA)DP9MI*6hK7Rjb~T{uKqpO}yju3qvIPqoKz_M$MI<aNY{RBaPWSiK-h7y^ zd-eDC_l19c6tb|eY^c}f<>fsy+nj%M`uSzww_CahTew~gOy*Dh^!4je&=qllf{iOy zXt1!eKfby;+@jz?!-=xn+j5iVPxpVv;~As-<MHwS7dJPn$L*~OeY|aT*jk~Tp`e-e zMT-_yU0=IoNz1plw-<X)*E29PYXjW?_2mU)a&j_g0AyYGzxv9`N>HP{@XL$9mX?+c z;c9Evt~IRwmQztx<rEq^^|6K~C~r@z`ueK1{@+h_^Za`)-QC>3t8$O4m%qNo3%cwk zBt&HQu8@!r5r&W*{Z>U!JV09|<?U(?JfC0Rw>|%Un8x}ys$W(ae4l*!zVdS+#g@5S zmaEO2IWu(M^;MzTD^{-tjowO0Nr8@Znl(%6%GIk2*RA7=jg2jNb3^d$t*y?-`(zg` zU+%vA#ag$zIy)yPC(ybm7FO1c(@)&qp5NaotbXYBZE4WeG8SH|binQf4TpeMejk^w zKXQ9}equ&O$Coc9Ep2U}wy@IeX@76txFONZ#@n=gyZP<J-kG0&_S^qs=s$k=%F5uI zZ`FNfG%R#(KXl>*=m1DY2GF6{PBz!q$EVLPe|sxb#WQ|?ovf#)r$yl-7KQ_tF9-9? zZ>RtbZ(m;*dl)pTeVE^VL-32RXJ=*_EA4$38XB5y8Y~}bU0GSl!OMH}<>lpt|Nc~N zI~=z<Y%Qpv=QGbnQcq9s%c+)@MW7OAW%c)WAHIJ-K2h1d;OD1Q(45e#SFe=5ZvpM! zPo2Me$Bu*x3mid5rcTq177!3P5Xbla+FI$bH4%zNJ!fv+k`fdYv?zZk13C^hEv?P9 zTP$=%^50)y-xTNP=TBtWmw1>>Lt7g(DgXF*|M3Nm%||{-c62v2F+Dpsw>$IlvWEv6 znL$U?+SU9BNZkGQ_V(mAH#W+++^AU!S@#UO<iyFz>Bh}Rplep2J!A9t_wSK1?TS;H z&Saz1X?}8rn5L2vQ!^W{)BAgSH)dbgTX%TjkvAtNtN-|PT0b#8UES!Iw8q@B;`8%t zZ*0qzzI5r5%e~!&kKJ1PnnT_SIthr1wrYp3d+_LJcSlc8%KOaizv8RQKV14Ef4uO| zPM&LjqWtC*i@oA<Iy-A+>5Rn&8dDc)&-lw2%grBj;p8E2g+`9ji}nY+OI|Ef(dhgv z5T$#mbJ1q2Gr2o8*UXeGov<%sn$-UJb^CMQAAe~p`)Qt%{=VD4KmVKM13FRo*|W5D zaeHTdW3K)$wUbHQDZ?*N1T-3WcDDJ;SFaXr-aNU&hVQ`F*Vj4Q4@;H*$p87}r7$xy zGicA<_3Q2$B0>ApH%4US<Q#eYF(5vEe%S3tLA@+H1f0zI<n4T-qos9qb+>HY3cAur zX(Gqs#fvTG`mMcvd2NNwxep%<nwy(>czHiQJ1bopJ?CJ;f=!zy?b>B^C(m4Oy0_hB zKS7}fP8@d)XP*TfbNu`J`_CU9I$K#=SAKfZc`f&)n}$eINy(In69wb;R2=;A<Hs^p zlbt(vf>t}UwSo44Z@8HwRi^!|3*?;bI%3?iva&ilIvcian>KCszH8U6f#wWTQds7n zZ$JP1_NE!fbIgh#9%9vt-Q|*-t1Buhnz>t7Z|;)&_00m0=1-nKe|;(U??<<{=d&;| z9y@jnRE{SnC-15IJ1fO#=gUg7*}Tgycb<Ow=+V*ckkHVRw;yGCFvYxRyO_ap<LWY9 z*FX;yq3XMnZY*81MyK@S@%evjl66jpTsxX%_@~Z3|Ng$C@4r9({=4$~ySvlwKR(#Z zUT7h+BStSPD{IBdl@oW@a5^x>yg0Ej`8Y#|i;`5i(ziqBZJ)5RvPzY2+7G&E$f3bO z;lPzEB9kXi_VMxg@bGZE?)kGPPAu57XU?lvS?A{4`<IrQrk|hp_px2Y#Cs|STJuCi zL<+vV2>iNCxM=CLsJeG{_jhbj6IGe)`Rw^~PPXPV=g+VH`sR&JaB%Re!X5EXpFDX` zU|~`GjEAqCx&5$XW#vwt0KwgAjCv)96AUg~x#Ch@Ztm>tT(LK9ZM4w;$@=l2<CH;1 zO8ffyMs5EbF4W0#Fk!;ZotB_sR|5$Z37%D7-<zHAe*1MB0|OJQr;B4qZp!AH8oIhm zw``d*X_C;XQ>Q>zCA7A-{{F({vT728_^zVI$9Q+`-u?3J+oNyGPDi(EK6-h1`H{zk zHgf!7t3xlx33akOESOPX;bS7DD%2^^>lPUi5%9XVzkJqKgPA^{?%?*@ntFO+uZ7k9 zK<5YE%(=HbT<uctnjq0##cyw!&a<s{%gxpO{_gJYw{!QUboj<^lTMmFXU>wXTc@s% z-*04R=jZBrbeny4Wo6~%nQ0O6>{9*5fByMttgWq`HP=TiGAioU#=fITSqA^DF76d} z4cu`1t&Dx$oJEV2-jrFF?T%f0In^odML)}q3v*}AlmzX=xO7P<ZvFJ=?RmMJg`5So zKZ6_2pF3Cd{G4pkMhUmYfw8xD-pzITK5LOi#M-bmVcKHdt$X&^=!kLu{P{C$@5hac zG-iF(I#Q-`pjGed_wSECRz$?c9(`F-^!wXeU*}w*2fsdLH`M?CH~0DZ`IoO={dzro zk9(iY&7x&D6ATi}W}iHB=E;SH&RMxeGf$j5cW>jllP3e4BkiUMu5@CGd2#K-2ZOlv z(>+w0E@mv*w@+^RY1hC&!PeH+-B$W~-`vB(#N_SkQVI(vhOdvic>n(SFJDYH*j)!r z#($k-zs5g-Tk)SXXTiekiy2eCeJiV~s)~q>4c%Y&>4~SQLd&<h@82zIf0@Y2%I>(E h*SkwdY3pAG5#x`0ZmWkLWnf@n@O1TaS?83{1ORhUAP)cl literal 55019 zcmeAS@N?(olHy`uVBq!ia0y~yVEn+qz~s!q#K6E%U2*X{0|SF(iEBhjaDG}zd16s2 zgL_e8K}Ke>bADb~YEemQk!h^QI|hbpy`C<PAr*7p%<=b_oG5c#{bA-!p4mz4))fUN zHdiA2&TcF6QdDA-ZFS(-B*2z9Pb9VE#r>t;cNgD&5yl=^674(1DMxwJorSTdnwL3W zORfI(u$h1T``>xz%xZ3auCs5S9{>K{_wDJ2?SB7!uuqJQfx&@G$4#GsA%HC{JzZDq z^w#X_J#iccLL9OTk_{Ian=dd<VCIlD;E-joB$}()nzuDdU0uEM?u82<>V5zHb~|`? zce#G-u8<^QhAtK-b|0^Wx8Ig+zdhG)`OJk*_SN6kyz<eTuDwy6;b+4I#>qi1o;;ea zA8%LtYs%Z|pTEDqzkB!Y+_`geb93k0*Vp~|VHoT1Jpay)!vFtjwd8CnK74x{ojUo~ zuU{80UOYWrKYm9+VrpuuY>3Tz``TYF{bi-4tW1o%;wpDvf4z3yx@F4wrO(gF?s{`~ zclq1jH9tSK+Lye)XS@9J&qqhQCr%X9nrC0XuF7(YNB?nW?S;uILYlvCvp!*PV)qGK z`2X+k>raa=PMm%H`Da~S-N27;Z<`lcasGOCcJ@r4W!tw;xAA^{^7QT7w@;~stu~eF z4cfS2gTuenDyQXP^7eI0n)*uimPszU`stIA=#}<en$`1cDnA|Xm#_c#$FlH|i_y#_ zkM8U&US&6X_Ut`BetmuY^Yio5ANd$L8!s?U4t-Hl^XbXS)#2+aV#C9q-(9|StLgO9 zmNI?c-`{6%KDcn9;w8iDyC&Vb6%}{kX!^N1iR`WCo)^}|mF~@wJayVdv8roloXD-U z^8z$VzP<{LQq;YdwpsS;T?REqCw8Bth08BzZoi$o{r1g!E%Q87ek?ZGc6p-By^9we zlYhUyzJBG5dGo?d7jFD@xSc=5MM==k*WA=}X^^H?(ng8-$8F{O4TX1U9GTZy_UgLW zDZBl3e-|a?=DxkMGI;48V}~S#k^?GYR)&U#2W@BjsQv!+Yu7gk35f;9PYR`OZ@&5F z*fF=z(5sIgEn3BS-+B3K{kT0RzF&AbZQ3-kUpWHS&yx7(u6r_HX4h!})~}h_*~)7_ z=gQyB-r}@8Uin4jpSt~J%jFmtTli*7ak4instyq3Yme2Ne(^NpGBzi69w+@)AGOPu zFJHcQ?_G)2$M5O~A{0svD3maOB9zC8-GL7eSDc5B?~{@Y-{(bNYStAgHc1~<Vhmth z$ebp$P+s%dh6Cj_Jx<bhG#r|gA2_^d2%UCe>&J+L2@~AH*I%#x{Vg|iiBj+pnRV;e zf8NdYMCVi6swqc4ek}YY|ER#?-k!?EF`h~j7pT8_@nS*xlSrmrGdr#*3UK_WvAgJ4 z`uNqWRc7^prQJoIk7NV(ZAns+ZcO>}=Vx(xx_hPC{0omi{xDp}E#Z^OJ=g8}{r&a9 z6VIlFPVDj#EY{GNuz7{-nU~)pblhCErUtbtOq%%o*|QmsPA}Ruv*Q-uD(S61yLb7o z+HLmnQdegV%Opqp{Ih4z_RHA{MP28zmFoTV_utBun$6cZcoqb;o(uL(OG{&8XI~$` zUyiFaWMbEw1SzHE4(Aqy%{ui!<mxx>(y+IsFVd8<tXJgeOxV9-w@Pl4vbNqP!4t=i z9BE1AUst;Hg6C6HQ`0Z!FE97M%)aNMHtTVBRnFMi<vVuo_CCIL?b>6<+;W#JT6g`^ zQysB$Cxf=Wdh=$^{Q2o!x;b}!Tyoj3_OgBw=hk0&;&j823ls8gwlACc@L{4>jGnmf z(?@@9+?a9kG|O=>u!$a<e@@j7_vk)9&-SvL)~hPr_;ZVP{J6F@`tRSrYZhF1{L$j) zbUXeGg;Oa;I{s>lwl%*x#`LqB$BDgNv8^Qb#c}D!J8!N~S;)*V<-&x#%{M=B%I<!y z#^S`jpy{OflH~7q<~Y1y2r>BCR?_qQ8Ay23MZT93=Y6?b_#9Ff%U&{^H(QKDwxP@2 za!Im{xv_v1gJ^$|$MK51G=(pREicV4?cQ+ASu=TG@<)HJl&235x5vDYIDfW>$4TG& zQ9`4d`=>Yc9y`D2vpk&b(!dWg_?$fh1H=FSZ{}8eh{Q`Dzv@&U+aq6jvPb8j{S*^Z z{kuB5J3MEpwknlfHfY^$)YYXIvd_h}?6Q%5M8HfJL6?=Bx2Bp*j%vOBPs3E>4OgrK zk5bWn{px#upJ&gMO;11mwY18vo+tg>%*wKFXWpcrJM+%YIHg5z_KbijJ{NOTUn{b& ze)8nWnR&L>Ha2tq8c$|lxpuASvHD+MG9w}+9_8HG5%_Ta{6%j%51r}YvHooBb$@G# z^b&oq7pHfZzwheq78Vjx^PeXpE4%i?bDu*}KaNyZRkgLXJ$w4}?%wL@m+bfjoZVh* z>g04iDRMS!lU&h;Q-|C6Q=2;;J+3)0J*6`FOp(#lWw9c>)83wWuTgvbRQ)gYFHavI z@3&aId*{wV!`7A-o<(BqdW-4~=aiOyO?V&2Y?RWX=j)^4yDVedq^}b`f4^TJ&8^g> zKj&%Tl9zHzGsRu=wi@qW{3X_VyW_7#EqV`BUOj!v`nyNMkm>ijO`A6D+_`i2?%%wL z*79~W2UOE)YybZH`@6ZhdFC}^W8+9UTPOXto(ofjg^N-)%M}^0<mKeJFfMd)bopp_ zdioRPlFVK1H@9>z65py0vEyJ=xWKo7@bKraUU9uVa`dQe?XM}_oXOuDuROZodL!SW zft#DV@XMm=!l%C;AMZbS@Ak386CAOYhKlZHuNB!%rOk3WIy)bJzfdU<SX0xsk!RYO zlP4cSeNwr}t<UzS?9%s9yLdP0d);tOPgmD_wqW*~H#s+s&ziyU)#LZtg$o(k4Xi3Z zKResJ_i*pw34*)yE_h4}IDBcTx1!V><)!8k9xrZ9c)NYpEGctyb8&HTvk1jE?Ja%+ z{}(J>%4&A}!N$dlotMt&sM~lge|Op2r03@j-h0dT@Vt<f;}`F|ymgbG{-0*n*%@#w zYX8GEFCRW^bhN6rFi2EaDQWuQ8y`P^{rdHrH*Y?fvdPn@#fa<gw0ZOTj5Azak0!jY zQFd@r@3>!5Uhb@CXJ;pM#6@Glh5UAYdAIqG4`pm9-zTWBQ20px4c;#sHW=_GDTxHU z*k1hn+`{uWiyJtt6+v=&_xJJcJTuSs_QXxU5AQ5`%Jr+}U=wTe-p{=U1cZ0Jk-zWW zE44NMzFlCdr{~EtGmVpzlMT<FI+au(XHoj<%9ody11*z}^*nl%B<E#zXog{OQvJuj zzsoZ(&#^3C<~zIW@2}D@%c?Ig)<$pN^l6%Iw1IYS@z+<OamMxk{>+#$qp7KBzJ0yc zp46v4T~pEn<2_#VwYRKOb`#h&eR_CENQl2b|9Tx=U0;9y=l`|xGBO-~o|$R9a^=c3 zLQQTv_w2b7#j^QMzRXhJyLa!_)z$4Wva_2vH84P!efGqeGb=wlaGaWd^IF)UFu1W+ zTn0ZbE_Sa>EhzYKdwag?>qSEUo^IA?Z)u6>P6$)~a_!o+1q&47cIMvRwr!hPNZ$Q@ zvA!~!RsRMjBrMqQ^*|%@#fuju4y}*f9X7)=aF)lU?PVn;Ix#y0qz-*;Kbf-WUcHO` zgbT9#oU!gaN+mtJm6enXQm5M4*`0cA^dspKN7}))lXRoEbtr9Ewqb*Txw-kY)2&<0 zOikb3-k$&d-rjyW+ev#%KmYic{Bl~ywrkg~Pyeen{chJo?$c_MQr3Qcb~ZaR)A8ZY z&(8~X1@Q}YA#C#D=Hfba>eLkX7Zz1N)?~EkbtQzEgBpWxK0Q5MnHnE2f9xVBC#S{= znT3b%*7TfTv3|Y3r>EnD?Ca||#i#kIoQ$%yvH4-yykFCa`5VXFRDmgTQ=hI`qjOXB z<04N_&w2Ca9d76U{_R`bwj9a)RjXDVdU`8fEa1QzjeR*jfv=)^Jl5zwc=bw3N~-Gd zG2X<#Eu6w}d#hR_eFDQIZyr6$+Wz#+OyiFWH>|wx@xsdJNQ<1X@L{%{65NZ=XwAG* zRaLcU(V{(j_MDki{i6Kc9mk(vUS2*_{US3n^UX!!O@e1$wd8G6iK+SaMsoe1>8#n@ z-B~wmzc{z^aYk2HR~!EQ^z`(PkB?momvpN9<d~bwyr5>uH-iOE?Ne^wy5-`#J@2lQ z?U7ltXGcdw>?nSI?!W<uYb>>gCkfQ<V-+ztJ$IeJ<f-TXFy)`R#bog(;KTRt;@6rN zEmAs@R9)e_e`0rcclnzejmpBQJUv&wOLNA$x6QcVt0sKfuHz!t{>U>^x0k<<n-{ok z$&!?7Ya-u->%G3VHhF)MW#J>1u$F%UjO{x7+R~0oFX+eb+f($^>*c3S+hbhz7d2Y+ z$yh4=n#z6bS@H98N5$l<%g*SWSfVl8W75`rH9w6E4Ga5Nf7!0L<ympz?%lhIxq-rE zlBX<;es<aHS8fx}*j4b5X|`?sKby2dhVRmor~d!keeRs!P1b+|6CbBYF6Vx&tgKvk zwZl7NPE^1)O{2Ewe$$={uY7MVw5yNDaG~BQT|_qSwTJ~2`G_U+rPzAGFh!(%Ts zNYpM~xq5Z?*+cVkJnrTDEU!;`JB_<1CN8dziOu#<)i-~6p5}_k+LViKs~TI@DT9iq zvkhFbOszEw6INbGHMZ_*>1zskvB@y<=O_JHvu34iZ*TNIsqR0I<F%m~KL>{cWAHR? z$J&%Vf<nI(oSd#R{l0NoF~jDKpjEXRTlJoaCsUj%-`v>f#J_05<jIfUz0)&M*!{HV z(-TiQ_mb03A06$^5o1+9sVjbS#-iZvEt96MUbSk{q)7o08<ScyW-fN`U(~SjO&8b1 z)2B|&5h+&pP+a($gEN*}rDSnZ|AokF2Oc~~=$XFUZ*EtSn_HVl<=VAt|4h8RX63eR z)9N*&LPEBrpP#p2fx@*T`$WEe`}S`;tH_f0u2aWCG{2ZnvsQVt(a}8rUdaAMZ>BGr zad%&>we{91)26Kghv|e1TOFLtwZ3uuJ=!gveQiynd^@jn+sj*9vw!xAEEL|nX_L#n zBi(9hYDpITqPDiSlP6EE6#mj%X!ZN164#~qx~GnX=zlTaKS_4e?H5|%Pde(ham;?q zv}n<yL(A%v;hu1+*D115DUnrNnBCZt7XmHPR7!LwT<GQEy!&y&h0>Omb*w_W0u>ip z%L(o3gE~v4<hZlbbwQzBVjeHtT3g;#c)YLz1wQB970?32<3*IhLTS+|k1q_4{GDYy zP&2(_A3c7&*wLqjiR<sNe>bPho^5@@`aTEL*xK6Kef##EJ9kcP^2snmK`xCi(%v%z z0s{>ZY78W_lAb?%{`|I<niFI8-)mQ|9+kUuP;PgI_P>AsHg4P~C@45xFLqPu-LJ2& zXIHq&N_H%Fodga`gMNAYW9Pnp`!?-tpr6zAwykxy_g0%%SzB60-aglK%JA>Ex6vgf zTh_TB{4Zcz;}-An;=lfc3%zGAE%n}5KV2vC(%rjjgM3<yHvJ6?4u1UXS=+<P=;+zo zY>&45dwE$sK0ZFN_vdsyX(_3urlzoUF(+TUz7`V^adC4ycJydycsO^ov$Hd(t8?j6 zR8*7z7x(?$<?jzRvnM7dUS8&#os)CKNMrf3Wqvb_p8os$`_R#d%d0|HJ2^R>I(_== zH2vF^ujg8qZ}60ql)U7-Ngf>V$CfQ#+^lMT{@l4|H&2Qlarx4{<^F<Og^!Odoc#II zCzJP@Wv5jQ3<Ttlt&iV7OVufUN5R9@;p+>M=9y$p%81>TQc>~a`T6;0r>*yISu3pW z_vY0rr^JhkT;Jc{@BZOvxA^(l=KZeD5!-lX$EGyux2f%sc~$tbVRNenho4-IuD!ke z+59_F;ArLbkByzXdbRd9BfGjcGexf*aarMbBflUrG4bJwz{PWP&YM}){n_#C?vby& zKlP%w`9vJfJ7h3_mhPizvEuWePMIQ75oY4_{4_fY%ZGHP&!<+b(C{&2NZ)Lnc1A$2 zO{(Wnq_FjRj%ZP{lXc)!^`G;B)hydTjF%$!R+XlvrWO}({-VaSu#I2dZp-%V$szOR z&zF~xITN(Pxns?PH*a{JhK7dT+||EhpW&&rMMt)5-!8u1qViM9=G2yR>o%_Gy<pgJ zOk{P(ms85>Dk>ZFbN1K&Kj;49&E|f^Z?CVf7qqdni`y|HvS^_~&QZ0ETYsn}a_81Q zzV<^O+WM~z2)QbKys~uTlrRV5%|4z<N*k9YGMyEdFo`$jG4Lv^>6W=&qV!nxwu$e| zA~!=(pSdSy)OgmM6?Zzyb3{=1h(jXBnq_4*jtb>Bf|Ba*-+X?3?(4gEcb~pHeK+^> z&&SWbyIK6c_S>7C_dm}mK3~iyT%u{<_+IV6`jC|&PgZf8bX?SAdD_<hp<`iQQ_j76 z_Z~ic*xK3}_RrDeiBZ*;j2Ay9D!WgZG<mYHn3!4iHJwQzQqJ{{d(F>OzTo8KwD@yW zJpM@IvHMM@PI=W>XI)t#X`D94uD0sOhldtd`|ba&Fz1<~uB!U5=;+a-e{!mn9iP{G zs~tUloO@5j?gK2bTp#WR{0!iKV%G97A|obr@x`1wI|Tj2=Gc`ynY+9xmZKvfAwl6t z)yGFiC)np5uu@PskWwcvKmWvu6Wro@H=fG3So7F!{TOoW#?zH*cZ#=0<^HbZP<s)y zU}i4gEX|_{9uGb|JUmD0(C^*V-`Cv{i#)og^7D~sCV&6)H*Q2!*=aW3-k$&X!-NSF znA!PmTrb)?m*wt01IOu3p`laT7v9#`uE?Xf&1F_e*HZ84lP;%M*L1~J-KqZmPW7j< zY)^Oh;)5~b%a<-aD#d>P{Q2{OU3b1FH0iN^IcUqHU3Vgv!?|OzvaiLWMT>lvd2_gK zbi1HCuk7?R-4&A$9z3X0FV~hKyZyqKdwZ*AUoOng&;QdeDk@rZ`-Pc-<8-EXdh+t} z`ugjuzrQ<~%l+6+#eLR-V0mF-<Dw@gHYOi`RPb0psBR9272^cOB_Gb8Z(S7dZ)frI zw)XbtPoA8aZO+f0cXwB4er!YMgG+xdcWo$o>ZOt3<;AsXsnfz2mzVR~`OUNW`F{WZ zZEIa*{c39VY@Fim;$mWEb}Dz)?}IF{N-u6LzGZ4+aw3-lY_-GhQ>RY7u$9Vj<mgoJ zb2(qUdgtfjg&I|dTg+to{&+3@)NlXqfb^++--gb@FI}d}C$_Ng-s*pOdHG}BS(EqG z{(f|}g;Ti1Dt7tli=7K<eE8;;Uo{kK=euU;IQ_(xmBE2;`DCqBwk!7ho*<LSlt1f# zpny}7&EYc<7k;Wg`BbcIe~o<xhhA>#4^AnAkQ0;D{VxgsZfI!u^r>i;d;hV+N9Rxc z_U7i~$whwz^7He>ua`t$t0;VtAS+zbd0~;$>aewwZVMc%_2@HcZ0FNl@?BO|wn;#! zarSz1)fayz3K#!8%Iw2YJY6jPKm+572^P}#`XvmT_I!QyD(lnb$&)9uE_|zZ^vB1? zmX7ZHY-z=_>OMShEOt*#NtrTj+O_M~fB*cs(B|`}Py2p6>fW(q$3$iKNB;J8e|Fsa z6Qrw@y;dh`%ZocZi#>Go^!$8%MRhJE*)Tn`YA&r(dof8<N5`er*>wukbq8}hrG>Vq zmXv&18@-)HQRSOZ$wvm^LwA<CItaJkvM6}q@XKTNuGY3Try~!Se}8qATmJH;OKWtT zpBFzpB^vZu&bBIm%jE9q)7~+c`{itBO`ZDn>GXKNITjn2EMfUn{`FO;RQh3U-s~CC zt6Wpoii-T6r0P9k#-vG2mxNJVbunuzSL>sL?D8dl+x>X#_<BtyatD2AX<_+Q@&2Ce z3yvU#%BtqijtAGhzP^6?RUg9>s_xFGmquJES#kTy%HZec=kqVG`1<PVm-csecZ*Nz za<jFth{&&7DK>FySb(#Vvhw?Td%MFAhF1kEC#*A$Sf1XL$DJc_SGF)?NoPzz1z-K; z`RDC^^Jo^levw>PXO|-QYe(^OznM8(7<h&6?ksMf9}yaQG;^23M9vKJS%yE38X6kD zc>RL+6W97}D_3%It=OKlQta_UgFVZZElW#FtNU<}{aCzY`HYzK4SwfY?ur%UFIc6j zrgkcqV{tUI<?H+V?OXg8Uo7Z6d-m)LJEe)UJGPd+jgq=-QTV9EXIfWaRFss6NXi_& zbuYE1cD1=L^O-qm?%ZDUtgTXfIySXMrMh}olWauV`ky|1`ob_~U(L-Q+R2XPa}QeC z3YSD*cv;fe*tl=szKjV^x3ylZHT-Uoer}GXNBp)N$>~hTg*E^E`zNj+SF)}*tnlBT z%E>Rq{+6(@3zy7puzqmROeg&W*PP&xL$=l5I4*g6dA;z=tgg0RdSH6{YcI!h*Vn}s z?^=54VfL;Qd&Jp<OJ?sVe9UIG?Zw>KT_v7*(GvgNzn!iBI%!(2(ewFTpD+8{J3d}; zOD%oY;$%L-B{%I@HeHl){BkX`=4R}Q6)PT?)Lvf~TQvLeA_K?mqFg)sIywqI-r(JS zY+?0RD<;k+y~NISeSLj_i`^Ff%Du7SU<#X*d4G5JWA$xYw%B~V66`VGvN$b$y@vjW z%b7+zH}=);zVmE{lFx-)*X5U6TUvJfu!;YE^hw;_rT{+27wnxYJt{g*CJ2A@tz*5Y zBzC>sF|CVh;bBXbu#f(?cbC66Og_d@w{qtWiKN@xa#vJ1xA7Q?->Lum>#Lk?)sG)P z?(C_YJU=ct`0@Mq{mIwYMyo%KpV+@^m(?GcOC`l;Bg)%2cgbq#>wo|H)z!b?c%N+1 z?Mqh;c80H4nBpw(%W;*KkX(|{4VRk9@s3+Mj($z-Iqb>N82aaOk=!oVV9pMs+|!!> z<`mr8l6hkC?Ah8L_xIP^XXzaIcx7eqwEt}3kG9{hJN(vd*1V}xRkvHNV-+s>Jz?_X z=2uGtG<IEjlNNpe?#q>H(R^vRefNw5TK_V4&JpvyDlK<UL3-7lCRXkv+!NHUySckd z*MEK3F8^rtzS`fr?waVDRP4C!arvY66SL#32~BzCmo8rp-21@#$@Ax@bG@%0gjiF& zQ2yB=XCJoN9r>TMJH$5bu<QAllf<_#^v~s>;KbgQzP`Q&4fF0i(EiADC2Q-KJO9qx z{}-ugJ;!@?LgUtVUmHU5HCUp)$?p06Zg<h_$65xC+tno{CBKN+>FW0CPR$edd3RNt z<Eer8uS7kYBPkm?f2i$m$`I^+eYk_e>b};$%)s;u0lG0e0`7#EFuYi>VAetB_QhGg zl8<ao_!pWpMMXuu;1tjme;RjZXK_2*+#6RC`P5#NshOKkzjpS(+?ubiLU*1`v|wJo zmcRJVkHRRy?=P3nU)CzRHu3(xT8oq;9fE56*REW-(6*W7eEwag5}g+>_10==Znyk& znC0%jDO0EN%34i1v?f$bv~<2?tc3a+{^G~SdS@D^Pb%`AWwLVT&YQoIORZ!>_+{N6 z2Z}FRuz+EC>-OmA=xp`sxySAQ{}C1ta8PwVy|W~J#sX`W61I!Ybq^ZZ15Q?beYG@f z_3T-*o|tt#oR+cm)|)qP4jgc}qPjGwQ*S{_<WG}VhvN5oA82CbzGFUT(cZmtt@Idl zSKoPdf>XGJy~(f8%Ztl*cBqC(XJ_Z}KH0~QHc0XmN=Zo>85y1U+fv{AEBV~fZ72F< ztqX*19XhF!VU}Sqciy#K%Kf(ABr<m;tjgHl#JTJ6%GIlbSBAu_|1i;A&ePBD7;oBN z35~_S8@}yZv?%Flm*{!B-#Xi$AAWOl^XgTraxCAToo&8%@7{}%B9Z(4|M~fO-@bh( z%ATE(j9#azyyXg`gjLCkJKIh$3zw)jN@sq5cUM@==Rwl+gU07=jLYBM`TF|$e5=w| z*VaZC-M*oF;blpH`Icq9y}etvZngja$2jgG_y2#t-%Itf{ddaF&W?_reOXQOplMr# zxQNIB$^OpHh0iA+d2q0Kx^8sZ`nLIEGRu2!p4pgnRqILRqfYgV`|{-~Mn;po@((mH z-rZn+hUM<f1=s&v4Ua!N%e339@d@*DTP>}uV?C1I)AjCdNMz3Y^ytx}Q>RX4Utjl- z?e&`znzIBlE`NP}z5egl@QiCqy{A8Dnrm14>%>Im`*pu{b8hUZ{CsO`_Cua!OPB8b z`|Wl{R9y92(=VsgeP@~E-PvK7e9VFALba@2jfKp7_4zfQJ|35sPhiMjU|P`R<m^1Z z`rXcpi{1U_*;s07zC3Gw|IC>)cXkv$-dFqk++1t+&MDdQ-cv$-eb3Ibt=_b0)4i(K zYd=0d-rnBMFJmzwZD(awRn+HKPoF-0|Nj2|`uacL5)Zd6G)YQM4z&B?eZTU#?3CN? z^0h7AYofR7nVXyI>+|P+Yh-5cld||G&(1IBVztjzPNbr$>erv2pC3PZRN(aIafv10 zmhT_VUd=N7Q}TP-$yZlb7uL<toy5-N(S3NwT_gP(HNQC?tv8qZ%XewLurqL+&f9VB z>FMd)^Y8Dg`1t6>i;SvQs!U&&rk|hZwRBVb{<;gx6rI~zT3Q@Jo12?I%5hm|Tu|U( z(K6h0aaYMEX2+J}Ez6iDm4AB^$(fhmu6gF^5!DmtpDx=Z`S|&BaS@T0Ca1!MUk)8Q z6wsq#E26nY`ae^jD`OFNn}yUC!wlVJ{`2_`+E#vg5?}u}wfL+NZ&V5Y;TrdkIWKnD ze7WF!;^$fO`xYmJ)E!o{1b^I>pYP1%b0L=Xg`m~-rAwFYE_?gy%VqyiEz!K99VZJW zDBA8gZngR%S1Z#kmapy3yl0!br33{Vg%2_I_xJnz`Ni!hNX*L8n&bFm#{Bw!mb0eK zwJv{mf4{umpYQkU`Qzn|9a!luzHryBUF+8I$+p__Jn(gPW)4~xv$N>qqoeY5KOXLW zzwhwh{i&y?`P=<Wxwy!+z&^g>A*;ud1Akj=gO~X<?kK+fA|hBvEIv`CN}}KHmqxi_ zjQHNJmKGL^i<Xv_t*xySjK4^1iCTMf^TLHo)0p!YuuAo^?H6ec2nq@c32FIs^8ESZ z`e)Cbi`$%b_S4hTg`KM2)0Qk*0-9nmG%UQeB~zH!=STna_&Uj#Kg22n9#~|(zP9$o zkp&eOV~eBI*~Fbv9Zp8@xc~a~dVOFUBO_y;?PIYzp>pMt`OiarF5G2%;T;_vU0iIO zXPj|afB&DL=xFY>E7z|-UhSb$BF0qs`&({G@x-rb(b3VTPo3J9dz<ZKcURY=J8>p{ z8#ivuU_PTOoS_<!Rgz~R=$_A@d#Y1deb?0BG~0}a0Rh)^)ch>(8rDoXe_X!ar<7Tg zzr5?tGYe+57d+1yYwc@(7#ykn@Zey{@`Jo*&YYRDVE+rr1&1Bg9se``Gm^4&zj0^k zjV+mz+e-sKec+kmrFzTb`kjU=RT)=pJ}EBAReTg@;Fx}b!Aii@)z#C}bBmAD{<^<r z`S)_3a#(L#8?$o~9}hS8?Y-6I=5x*{^uBtPB@&g9vBGrb$Nqri%w&D9vJ1)&<w_QN zt8cgLYvr_Z_IvgEb$spD&`%2w9X_0$m38Fv;py_$Woz0K%{;2As>){{PEeMWmF2hp zW8me#_+rGF9=GYs7*<`)Qor#m;DK$ytasP=t91{t%vH2cKQ~9xEJxz3r@&379b314 z{rP<UcY~aons09+)1z*rRy>^=9?-zb%6ctj-I_IDK7I_;5Q$BgxszL5ui!G5S?(>B z?UsE_oK}ZbGqSU18>jQx?l;=Gpr*R|_m0BHHaw0EdD|76UvEe|D>X&Y$~^2@{rkP& zZFqhspAZd7aQ|`p`r3$%PI<*LOu{8?s~Jv4?5o+?u6W~a#Tw!A1?`G|)^FSx$oF~| zhpVfr+}y~6UaPP2Nttl8KY9Ap@`}Op1NUEfEDbuD+xIuI>0E(s#^dD+7AX9?^YGTK zs5|Wi>+h7$6ck^$bLY*=mxEV^M7=MRw<<Ytctdb(cJ^xL++sdmUEMp|B-Zc$x9iTc z8<J`-c&<OXU;lq;ZSPNS=3~c?D?k1F{r>ce8}yjhuDY>u>G{kjcWcFyL=MC|{arde zZqjX;>QAuw%Sw-syVA#V)!3(hnR;att2XbN9HXO3(Pzvy`)c3HVcvWt=l%*FqplMf z8&wQXPZIbmD5}-EcF|&yscA1mxK<`+bVaqK&c6C*-u35SOJ)Zar@gCqH`j8$ecNuk z?>p1a{hjw*@42PV1<9tx3l|<dd6HAlOlHEqHEVp7CVqK+{r%(P{aa#<*)~M)2~)nm zuj=cmJ9qA!I(2Hsu9!(FUb7Cfbcw6I;8C13Ws1up^*4uWzq|;%<tND*Fv;r9JJ4Xm zx2WA^Ya910YMMP;I_uYmhlewNAL949AnCMZ>C&TDuWohkm-AY>$$!3`ZS^-1zqpBt z&TT(_{`~ptSKf^c3nzbhG;6}d#ih$8@9T>-ulxI}bi#(6#m}=!Gc@X@rKMMf{Caeh zdu^GB#ghFW4>U4o{yxO)b3u}c_3~c5_<b^Ujt-f-KT9jk-MDe%#fulM-mDP4v&Ckv zjm(Q(AG^A^G=jv%#dB>BUeRc5Y`pbOqhOi;{JvT59z0O^7Iz$E%+fV$c-9%7(W-fI zLGjkRKW!e*zrVkKykDL_(D;Rp&Y81kTW9=zc({Fomb!ZS@jlr*p()4r?Add1v3qr8 z<=y@D@@a`xCnu@Cd-sm3)hV}{pTGaXg9o6I4rk{co61iq5t|YYHgO88Ra93`X4Jk= zQB+ivlJaD+dw<8=<l}t@(-uUU=iND=yRdb`rcIMPRL-6~8#VXGa{u|izP@I!Z~s`E z-E#5-gGOTD{#A)h=LGarl;6#@F3<S=Njgu*ChyLUna1hYu3oME@gecso0~s>{*2z9 z*ZTC~!-uS_tan0F+;`kwv1-+-b?fGt<<44Fs^T+e?oF=p>Il}0Cf_fpI2|uZ`(R!8 z$mLOJP0gQexwjK$WgowM`Sai3-&bvWa)84`Jz$mpJe!N(?g$GDC%Ri?E5Arz;^yMQ z5@yED-TmuV)vb3gID|{u0vc|F<qD*9IDeE1K5aW`;>3%4*ZpmbYOyPMap7cc!<oh# z2aA5R^6prDqHn>59lvK7CO-(*oBmkm&7y6#Hzzr;{C#zG^#y|iY3tUl+i_&AsEmAb zwz{>obeG_ixh^jboSLe=FeErAXp8OlY171HwhPN#D2so%x%_?Hn*3+ao+-WEe~e|W zqKKBZ_Cu#n-@mJG+LwJ@Z_ln1W}KXyd#k_CGfL%BmH*$$Q56$&r;(YRiHYe$t8N<C z?TyLqAt54lo7Qgg(si0|RjPHy%G!E=<>zI~ma+Nmx%+l!f;2;ql<BL_&(FWVx0m^? zTHMp8PtVRW<(^jj_JEF$iMe_4?DoIEzrVio*Vfin_M5D2)s~N}FAsctd_3^-(x8>| zn2UoOIjx)>e*F6N=xNKQzGSi6w{ES9S~^GN3^VJJ7b-tbsTvu5dVPKU`FXapEeank z@tpi2vE0#-F{3ePWyn^w?T^+uHJ&?r_Unfa43%fkpAX+^=giN?S5{tr{A04|_UD_b zzrV9AezqolznsX;+qbKac8SKt#qHoS-&gy)EFeJOhr=74xIGdvt&tiINzV_patBPx zzP9G#T9yx|C#+ecbGJ;~;^fJbDy>%go(l+qaspFR$!0T$9UJ`@Pn|0I@_Ks8U5AjG zn$s(ozrVZNJn2aL537Q=w@h!y-r}s=E5tW*=1i5U6X(t?d)p^w;F!+AEwrSZ<?e?$ z<tsR<Dl09gs8s%2r)yvTPsS`qB0?aR;dbc*x2_DU?_Zk_fKsxUz>?Lxx@TM8T`pey z@b>n6p-vaI$uDiby*b(~{_y<_^L)AeeVkp#`{k3lN>@w>Ul+6Rt>5&7rgH)^vaBz! z%%3MMJmaLx^E)~hRCr`81a^P=^m@hu4Nc97UP~kX>c#GIxjlFPVV1dy7FJxBA}h`* z&zm<dV2P`%t5tMIZ!asicKEs{7quCKqN2Rojy~8IA*Kc@tXzye(jWee=j7&o{p;Aj zfBynj{o<MR=jCPf>gs9%>xp%n?v_4aIeYf(MmahAx;fjd=N@F4tLS3VTp~8_Gq>7F zPha1w$2s~8Ql~ioUlAA_tUUST2GGL03EQk?LA7MS4#!;+Tc6+gqkHFy-km+#cQW(( zruS_NES;mBc6C)~(at}2b{5CT8)$x98NB?9<;3#$_adXCZ{ND*v}IktY+yiqynowz z;WrbOfFi3^dWm#o#ksTh5Ba`5bawZlx$iX0yQAh!D=R+ABW1#|%)b5~&!zKU8Le|) z+H(YEWN6&*^zyoNxlf~k?aZZ1La$SNe0XxpZ-G+ijvi@qK7F}luJfVw&+;EGD|`4X z_Mu<-l-aJj{@%NHCV7MhZRLyP<m3$4ASftUHIMs_ZG-Hj$p>CErd>UBh-vlHlatjm zcQ57>E@>+`sBrhhq2jCae@5?E8M~u0e8*+kr)hzwFJH=ACvmCJ)AvGfP|%NGZm$3N z(~htndHLj~cTJ5=Zu!3k&Rw3t(b3$dLSK?TJUEzqyf63r>-;t~g+x9+J~=tL=xsSC zPoBJJ<|}Gm&uzYy+x$IO`K;NGmoCl?k$uwj(&NI$-~SG^a(`X#TEqHVY0<uY^Y$qF z`uHq)doF**g4r4Y%I3MZT$p%8G_@XSxLrBrr8hnMs`VVN@_N&}dwV$NIY+PCzjE2K zWpR6}I%_jHa#yZit$g1|O<nzR*>n3D3uY^EwH~^7@!}fO_o6Ie1-bj{{zk2SXy_}$ zaZ*}JN}-^yw^#L%oRH9^qedc43!G&Q9_t^xwyX5@fmyfOP2Bu_eR*FNPnkB&?e^UI z#HPHWJG)A`--|szH#a&q*7vsT#m}FgpZA`w=h%^TZPwTAOP988bB_h}wPnJ7e{oIc z;^sa$OF(K>9-ETlqL(vg&fIc0u_-TU%Jk{CZ{Bo#dV5#t>T{hlC1#0;i$AWIZNW14 zL!j2w2X9YIRQ_qik;TX6c=M-`hM1O?mcf1RemPq?`#PWNl4>uOxdsFXT-l@QJx$_i zfpJOYmlqRTTU%X}D!;vv%#Htd?(_5W3)Ob)-u*e%Ku_=78I!8ste~Kvrdl<Jn=k8< zPP5!?IpE(mcg`H2h4J#DNl8g(TqcD~D|f8_{Y}>-tzdT2tn#|;`S;y?r=Ls_iRUwR zG*>K$DYmVyHnw7n@^W`~zhL?&C+5Tly%(#t<?wQ~Ho4DMVq*WsoRgDN_veS>QFgT# z%MPuN-~a3Tdw$23bDA3@V;yy3A6C}4@y)R;X3NRDv7ym@_9G=LD=AaicOfe*4zSz} zS+Q<iTa{VD0ft+B5|&9XQ<FIy*RNeW)oZDrpWl{8!HNPxLQS*I<=-q5RC}?kY30*9 z3tZjY*rpT*1PJ81|8puVH2h(ibw#7@?603c8*k2;BU5*_t6S1IZNW1C`F49}^Pgq8 z8*<{@xi+b`pSBWh&N@&3JUGbw;qvk0?eUvGe*BnVW@I!ee)A${z3GdWy}!A6xpn_( zmb)PW-4{A!H%|F{cXv6jpwqRhS3Q?r+E@E~)~8@`7VBi@$jHdMWdR@uMYOoR=~z0) z*x2~s`2z<W?&%)h*_^7ueowc%yI<ZuX_I)T3)9<}?=n+3cdb+qTPSFqr1^Zy7LyOg z78WzgPcQeM&vtsYdH%Dzn_g(>=p5<4T>bUcRa^IzraUc<;EWIRrj+O(iF{|GXk}IP z``g>JT*(#E($XJ;Dt~@bJrlRLN_1KH`Z(X$E*yt+(tRgQnsng&g$n`qbf-_9+L&r? zZhlX<TkwqocaMbOB5A(kEU|ay*w@=xTJGGl=g<0RuHcLf>!PEg9@(y3w&4GI-lah^ z=gs5uo~9eUEUP*x;o7u^{O%`2oVM8~PTQ=e?l*_QeqpakOJRC?x<OoMXe!6!MadTz zxkiLLJ2~;x>ZrYVv~1fpF@3o+7nmL%xV+r|cCEas&qBxZxw*OJ@9wP3^1mQ`D<dzj zE&h|{-*vIO6POms^_<$fXHP<CW~S!RV#k)qbF<#u+|2&RrszqBVo&$d^3d%MA3bXN zdh^1}%QF{rOZaRE4GCHDt>n@C`hT1p92PY{HaIQ(@#!gdo{rB#$M(gG7Oh#kR$5xx zy8a0hcRRm4-{q-OL2G?3G_<z2A6|Ot$`zHVUa~SW8S^})LBYkdYUgzQ_+uQ01&$p( zu|5BOK}n`_`PH<hJe~&yNpF=VpL|ked1Ui~_e>&ELT$|p-rwHtAAI5cw!pwZM()Fh z4kbLixjFseo(E+rrlz84`f+<W_J4kUetDJF|HdZ1wcKBQR?QWbkjO~eAad`5nYW5i zb#?V+pDS1O0vbQA?Vme$?!&%M^{{!+9Fe2a$NBpXB{GOEY53N=rEBTKoIru-C@+Jh z9@4?eNl#TDWIJSOvThM@;9N9KTw7mpqJ)d1=LGwXSxqKlS_$WcSSmShc)ex}(&BLC za*8^a|L&vt&HL}}ev2#nR<{20&&4};->rOk=3M!_nR6@MII3niRIO#&>1e)e!DHvb z!ou}&d#5z%?VjIfCTEf{;b^Va#>+2L;=|X)tSo<L>)7PCEg~-N-p9wso#!f_Pv~g& zk+Z3o5c~%;aQA5a%9RgA_De2|4Nv&<<Kvu30!?yicXk%DE60dBE>F#B6a503ugo!9 zy1+ZW>(TMHHnv}LEw^;{_AZT=;dAHsFUZDeRn%(Oe)O$E^{Xo@)6dP}EZz4+MMXuS zdh6D$a~{QSNML-_KKGzz-Q-ELW_k6$-j;j2;)p(rt;~+Hx3@N>o<6}A-gNNm{rdm8 zXLiP}Y!Vj{(O{kHSo}i4%Iel5yEnc2{N~x*d}JqcRUv)<#v(Uy)9h<HR&V+1KmJ_5 z{~uTByMN4g?Y(%CJElz&^YaV|3wtDg{>+&tBKs>HPcBZ`Rr0dv^)=nI%HmCVdADxe zGRwPj!c0=T^7C2qOu5T5n&j$EoZ7i>U)`-OnI$ff`|JMN{r^*}JV&(j<0IE6>Y$QE zC_r07yvnGqw#^f?3~8%x?%a#QP8WR7TwLsalS9weHrA~7-rDHxXJ?ylp540Ob@TBe zH|b@(9}~X3xTqK(x3d5B*)3a4mTap3U$<`M3_+_bwwxOq9B<EPT`*f{hP}bwmpeYL zSg}IZy6nO6pP!!_o3?)}eQ<y=Q$X>>uLo=AB+kgcxrx=y>g)lXm>nOE^-3$ARJ^gT z)_T*&H=EBF`7T|tf@9^HxV^KowbY*O`~7b7j=Os@eoJsTn#*t9x^+tn1M|;EkCMt7 z6oZR*-@SL?f&#ZHORW5r(?3s5)izE$<6wNu_T$HooBYDf!`4JJ@?1#MtNTzaF3e^z z*DvbminZQViZ9e2Z$5AL`sQZ!dCl!|RWB|qbbeF*<@1tfGiT0}JHJA-X&wK*DVq;J zT(EYnM6zz=CYS%$cWzEQ>+~x7`nspHykcWzzedLd8|vqXHnjaKZCx<C?b@|#=JzU^ z=QU(rUUo91`u)AVm%<l#wJdnu-2b%aR?YLd<r$ZBOie?dm-dz{Iahwa_PFU(>+*MB zUS4J|d$H7e`VO^}xQzF%-{0Nc+7-aD%d(;7`I9FL-sPG}_mn*4UAlBB$haedCBGhA z7c61tms8P~&$uDCda5wL%?Ab{+wylZ?^`x)-aIj&veNQ>i;q`nsp-s&$!flrRGbuF zs6FVn|L5W7=eG9y+uPS~&uY{TU$??tiLdh-dp&<=US1xkYqRy$pFcJIms4*wxgR}L z$!rBGMm@4$URr9kBsJ*L<;%M7YLCte*(*@8nAx=c$HVr(r$4;^`7kj*zW@9E{`uSU z6&w@%*6;iC$@`Xg+V<P8U%&pD^48vBuG*`K>-YbY%1kU+=^UlDbnDisag+FEtxSI0 zXjvdF)uC^x)z~Wc$3<mrovya_WtDs;Rr9<%9X&lRzxPypT(m#&^{ZEtCQZ`GJ04g4 z{oT`vwoUghig`&%OJ}-I<;$EYZncwjjzyu;i4`piq^B=irWW*h$`ldbIBiQAz9XRO zTlUyj*~$ENKMn{Tah!Yh?Ae_=cXlW$DLH-CRp*&Iz5Vi~>brbbO*Egxh$p{Lcr4hI z7m#;vkLPX&LxJ5jKR1P4wEO$zve@>;S;{#M{KgmJZ{?WHc<$aO!)Y;T+qP|!CJ99? zv`IeJb9;M!_6*Q;D)U58f&6)ftyA%l(9qCdD(OLH`S*O>swPAWw=9qrT=Diur*Poz z!otE^v&^<`-D(nUUHvWR;p!;oJ~>;i&s?n05fKtKIq@|gS!d=%Mn+y=AJ1>+<d&VC z-7jamCTw-yVw1wEiT!t~-|sbP;8PP)eBqYz@zK#Oe2wkqZ)10tP2@f>XO4`l*t%BR z7qy9Tj;fyZTW_g`1P5Q<UtfP@=Co<o-U+GQKPa5~@Uhq_X%k-4`hPWdgG@BHJTUc8 zj^)_(@W$qJ{<gP*f`X!=qH`u4D6lp%np9?z5ECC47Z)G@|GfSG0x!Kk4IS~jN;tzR zBO@cdytuX=etCI$c68hRf4{UVtNs1__#Wu4b~nqt<syCAr1Px!i;Vo{IqIneRo~yq zKJnQlP?CJ{#to0M$jnU5>n*cp&En$XIuW8i!+`UaYgm|b8_&;Yv-2xLCSQKJ#C3Hu z8}Fg#50vLv7ON#i@2{)<5cu=N$;s*ylai7a<!R2EKG(YZlCbCprc}ijY)obMZ){8s zoO|=;%{}o^L4U;cVj{NZ$xiC-?v}Qz*>P`IMwG&f+FxHb-hSKK+B$XW)EI5<ZI)l< z4Gj&K`_JbyGW+Y_w!8H8w5wUIFCEl<IIk%B`!cTg6mQB?c(LIzBQslu={_^-L;raS zzrMOUQQ1A}j&yDF&9at?1#8Ri*KR*|OG;k8|IGEPS6|Lt;i>38W3E*x*BcvU#TRZ1 zSFYrAlYceo@`JlQ9FFN*wruH<vz1ypal(X#!q9|?4=!%{V6*Us^y6c_n=@Vo8|+b> zo_pT@e+@%o>jLT4mBGuSe$2N_&}&)Xy|e7Cl<$liZ@(SrQ=e;HuGe&!?TStQs|nLD z^xOUNcwXXrs)bWn=Us3B6NmJ_rhC_}wLSmQsXouc*LSXY{=8@1>*Z^|1m4tNzwg(o z{S!mN!;>epZro6?Mah+8SC9SwKgAy&92DEGK8@kpa(-zup2YfJFV*ELgCFkwe$RPV z{@$<C&b^!^Qnt;JA$isZ@h_V;ZF21vyO>_XacSlLP4)p?RSZ3n#%?nVyjm7$Tb93z ziHVtWbnmmf>oc!CdzQBP>aEq``hVm7E}dTZ^78W6bJkTV{y)ZV_hZ3+#>4R!5@#4k zFI&1))z)_Jk|j?LG%}Z#mYU7x^?h{N-~R89$Nhz-mX?*Lrf531@hn_#kRn(Ar|^Yo zrB~IHiSD01e^&RK(;=wsw$I=0r;2Zx@)d9Wy+@pOstEOapSS%U6BIP*m)YyCF0PP! z2O61~t9gZvaX5bW$j#MVn|t)}tLha3>)8K)yPZGrOR&G~()vqkt=qU0uDr{CFa57c zZ}WnM7bQ;Y`Ty^?#-_r@$KKxGFJDyi>WXGeS8s3Y&*qPOU!>xX_sQPAaiikvtI#Te z#fukb7G`*Pah*-Llw=yIk=e!Z>G%8nkF^#BoqX6Ks2ouF>UeO8Ps@Vp$0sH#Z`qgo z^wd;4w#uhd!wc+<t-n0Eu+Z5fYVyXM<BW$jMQ+WpEdIkK3UbB;_dXfU-g9Tq*8Y4t zef6qU)AZx};$LV*|K_}S{C-PIOW^;*Pp=j3;+lH$^y%hPlUwz;pHAYiI#c$G;pDez zwmqT&xy|hSVyjE0ayW)3K0h~iu64QF=KEW-!*`n>{&7G<PAuMIj_n-VYO${pqM}Rd zFFiY&w>|n!`mG<LT7Ot;udWKs;j8`l=%|VR+?g{i6A!g)+h*3m8Xa+{WyTUqYwOw9 znlJls?B+_o^Yopx$D`DROZFc*a>QaTsPmVenp$~U&hp`<&p!->6<K2Erk<V_dB?8) z*4=`VA0HBL@h|m1ma>3#q5jKTTUUSh_|iJ(`il5vaX+}Nx)!fk(Gj*&L|puG^x3AS zrkk77A3OW`@l}gzPEPB|O5C%2`EuvtrQsKaQ&LhM2vx2L6a4bz$&){S{w!It<kTsz z{>tX3LV|)9_t)1ybU&)>bm3~F-6f&zM~=AkSckq-c^SW>U}0Y6WXCu!lM<G@f(s(W z_h;$;VYO}9Vx8Hs%BdAp^-q5@gJ1E*+oHd}O0DwE%+14({#*Lp#Qxup#q%mBH|eoU zf|eexFiLP+ap6zV3T>9T%CDOGHadlbggietH*xvvX{yDFEO*7Fq@;d*d%Jqmo2xHN z%3fX3w6d~lF_xP-bLNSK+ZV1npqzbe&BCpE``87W<cz+(z1@E6)QJ-urEWdl0wwaA z`ugshx8KY;-X|Lz7rVF0v}@yv6(0Y44ChrolYEkRyiZo~O!Lc(+}x#^U+(TM|1IId zQFY?N{fR4I3N*d5Zf$K9+pc_nwt4<3z1Et2tb0Bj;y!Ws+S+L68SKVR-NA<YK7Rbi zr}Coi?TP0b)28h;E#3M1-iZ?)tFLOwXs=RWxm&*AaX@kR?*hk{?|FH74eli;Cp+&x z^yH{`yvseipHGCJE^TCHciLbOQv3Jo^}kWF2l5klyT9jP-0_7&?$e2Di{1I<-@kWg zdMCbz_3p!h1@qeY<=0heJ!}yu+5h9|^!OYz=_k><jOO0icy6w>d5dK6%0BnV=-(d> z^Z$)fIN*O_sjumlH~03=PK&MCv!9vMDs+F&W4n*H^Y=TNUb=KCLG!{Xt($HC_Uy5V zado&Bl2XT{rKKe#EUfN7&u68_UACJ4f4}cA$-JcU^7HnZpG6@-o}Qh3tO<5|IIB2v ztwhg<x!vH53=4C6t#m`n%}VC+hlht3p1m>0vUoyo=;|;{{f$MtYk!wzWv$xsc0t|h z)vF6vZrZeI$Bu|+z0FKvp`i;6`DCr8^gWvL^Y(#o9=<nazuS1FSGeZi*>Q1c!5hWw zbGFsrWK6R})`m}edU<g}K`YDM<Jb9R{Vt?RfA9SG`1oc?x2P3*w=ejgZ9XTt;C706 zkEC&1+0V!2*Z=S4b+~(Z>5Lf?)0FC5RNvm*?B4(X&Xx+{lDWB7E8WdRZ=dC8>RWE5 zt<BxardiTjWj}EWE4P?}`ulyq*L|9_<&ImAgkr9>{htraXBGB-yOnKfYHE}(BO(xM zy;XmU<Mc!K*`#FmEt-3;_`L1&^Yf3huX2nG+4Stq#%ZA}E!uZ?mw&(8UE3~Pa`RX% zlkAQ+X*b*ct>5>H>pZX3+aEtF`ppg8^{!Mb$zx8L9`mlZc*T-+vAZuV3vM*OC0cSe z*D7D`X2hj4Wx;&6G(P#xHak1V^76xi4HYHZUY?s{S$sXVJaTQAMuMXwBUi!MS*BJ? zR-e1H)O(`vw)E((HD*h5*%xtk9)JJD#`#%qv!)KKyjji+?}z!#TZ7H^zPz}xeU0U6 zj$Q7I54kLT-d$fmU*Ejk!f|@;9rX*p7qVVTe^rtC+kW8>j*6e3Qf=5T-MGQKf$!Wr zTW;Y7osyNe8Df;!8A>?+{P}!d?0ew5n*WKPFRxp$d&{<$dn!|sH!NExvqkaK*VorC zzjDa5`E|R*WFh;+S9f=pZ_m5iv%!AzmMtQYv&{47eG*#jTVj*H|L?XlPuZ$cBff8m zzO>k!FKqUgIVb+)YM2+Tw*IzY^%e7qGs{5^ou?rZJ6$ifX6Mg%2FNbMN*|GMnd8%0 z^+h(yaje_8fK{KxbZghKWM!#9o_~$ow7zyotX+BS*s86D$FvvN+Gg2)a9Yc@G-|D3 zT<ehs6DwR7Z`-&n^uIywRx{U)(?qx3|Ij`8`pmgEZ{D?>HuL+><}>I1JliY({%zg! z?`ijb_r7I`-BK|BK)+Z#H%m<3_TLv5yT^I5>ql;4alCe<Q@B-o=ZS`Q3lBH!n&~U; z&|Xwr+*;h--F?w{vYM~aGx_!VSM*#k?RojcXcH&LE(O^wrRx@N+7uMB{-dF+OV=SQ zg<XO<Vq4tUl-XV?KJ4UhGdn-uUVQ1D1EG?Od1uAHH<o5U<{;s*aCw35cdt*mCpdS- zB=KAADtPF`Qu%(*XTI0Vn;Kr6TEG9_D!Y~4y)3ce8b6$36pmzbDZJp&__#9nqxOqg z$4iPDXEzA!{wcF%u4S>Bwl??gn?*hSFZYxhxod66zi)R~D>UKsG~I%<UteBUg^Td{ z8=1KOEe_OsajU_wG%YR7%j?wk`*p9cOFS+t>7TV`x!LjeI^t)Ot#%&pb?CVJge_Oy zZ_bI6CmZ>lERP*8d2nrQ^b)4Z%F4FTRR^A(o&B(fF?gr0<_lhFvyh*5!g?>%4hV~` zJTjy5#k465F+~?jd}o;yTFtfl%qY=wNLRcs{?@kK?rY9x9$ufsy^Hh6v15y>r+l7U zv?u05^V9YF|7G3UlIi1fW>f0v3k?#6Gu{U7Sd+hMc}hykg0Bmt>vVT6kUo2Px&KA; zAA4uM^{{PNFT&gBZ~u47p@*wht!imuxh%Z1K~y{JK=09R@!7B4Y+IMjUp4c^A=bMY z@9yku-Y2-stw7{KlN^g&zq+B}#g`?QvU|*OZZw#c?7sV~idC~+dP3>Tg+D((zZ}BU zYW>EJf2Cy9%9tbmPdA@#5alwj^Vpt#UT$h-3CI~+v#(z;zqHgxMl<F@bHep?u^A?_ z+~2RAopyO+vilp$%1=u=;~cj>JbYZfUdMLI#EF72Go`q8U9nih^0(jqUw~!tMDAS| zWA;=C$|~!~Kh;RsuweEiKmX{gtgIIkt=E>Qmc751Tcx(cviRAL8rI_v4mKwzC1w0$ z`~A+%Y;#wE$ChVdQwmPzGpTOKxVUI@`uU_OcXkve$Gj?gcgOSjB+1!_Tth6l`4&F8 zawWt|{Bf~o*Mw`H+8!5f=6%gwmN-?$bdGg7pR906NRoC%i=4*NrAsq5GBUGmuwM9S zO62wRGB1wzNE$ylu*`S%lJ+I~k400%J{oBsx?#Fq$#_5Klmi=+kB6;|+M0a4Z_S!D zU0qxr-}>$UX-qlq_9950#pPwvlI~+SxA;XpEU~)SaC*9axY^^TJQL9JQ;DdK6M=4i z7jC}M&Pft8Yf9dJ^M>!aW7_jyx{Bzw=}xfR(JR)R)5!;_GN1XC&ooNql4+Ra#qY@) zJ0;T9LM5tL+bGy?fs4aC_kOv#^XK=+>1k*rTsEutuMf4FWqT%%N_c69N!Aq(-XGVZ z^EGD|I-1Yo7S~&ld`SIak%hAQi=2)lYH5ke7G=?To4Yg~eV+N!RWXR$e8J->hg@fw zEZen9s<%z!{kONbm;LzmY<B*k?R%@ggWa$z?tZ$Q=){>tOsb4u-rv}mY?yWMyOz26 zblv&B50$<;I!w`Hi|5(V(%;$H8Rr?LzBc39nwhiOZ^vBdZJYL?^zE&yIqt6*i<-{0 zc|g7Y)M#~wlHL57aUx1vH#l*e_xAR#m0A<GH_Bsmw$0%--pSFjYvV4sX6L!4o#LFr zl6HQc@5|epHg9gN{uLrJ`;e>S1;dQfr%!wP`YtUoEMRMP<$3%<BoJit-Cd?q2DY}b zH+#5uT~xT^e0)px^>bLP|IzcqWoDd6-Hk+7PfyOX^O81i-<+V+q_IBp^0H+r@h!;( z?_XVAeJniJfN^PQ5dWiElZ2q4Nt-0aOBPptdcqkWu|%k~`i0XsQ8Pns>4O_@=e$u% ze?0Z%mmqzXyN^GrsH-ntJ4M*)(yu9p4mll`5$@>kcfUHp^6_f384Z`LR<_G!A3u5& z97j?y2Npi7dAVQe$`j}374ggVeUcWsx3Bj0%aUC&dNB+=g*^urC~9eGDJd=5wd>Z2 zs<kYK1WO7(KRY}1?2ZMq8Dewv<M-ukQ+~)NUSb*&8oD+6Iv=mAGgs<`8FkE+XBU<l zu8rDiv?-|Dkzeso-<zEaW*?Ygn0&#UolnN#_QZnr^UmRiFD>=H=ymhv&8(jCcXu-X zMC<3>*>O;vspZ6qz{MK1%RrtMULYQ`CTi=c9QQ-AdN1mBR)5bcDJcmFnQ}^I=hUfF zJ3cMocDwgcTU*=No=?)~$Ofsk?s<87w>AVWb~}|8bHO(Ow3cdir?C30w;nqVv)<KD zKHldly!ZFJ-LL#lo<4n8)791WSEXvw{e8773h(SFY`dCat010nxQ$m@Yqn)pc6RyO zTTjb&Pqvh5^kDH_^}#KHCHRH(!>g$>mOB<`J5S7ieQj-K<rFW!ITnqZ+4y8u%uiOj zwk}rsMQFRSlD)lr?u`YG%&Ergdp%ngTY^@{XMdSBYu2-~v)x@>Y-)Z4ysq0W5_3WH zLxs(klDp|mBCK(HDjpW?{P6Yn)9LXgpL$o+o?PVG{owhjsoJG$&)o_zlKI~>FUGv~ z>tTNTJ7+I;uyTtn@VvNz>#beMi-7irlX+js##|6xus!0-tE=8;Pd{+I5Im=;iOE)G zveWna+I7F5uW-q2nKxsGgt&P5yE{9J`rJU%9*T;MLe?i7jfFq#zO?1?S~l?#%esF* zpTBsKvHY^9<PoOUcUQl>zaL+GyvFIYi+=2`6ra**DX*@qT*WfiAewnC+tyW1yW{uO zNU~{aYR)R#b@f5hyUDk1-8yr|XA4iNEN9cJSFdi|xN+jd3HN@v%-6F;D!Q}z_x%0+ ze*f2Xrw;{`8UN>Z-MQd(W4z<>?RTCQ9c;TNeC#8qc**=XH#Rb#1<fr5s7zXR{LRhH z?#{<+ivItr4H1!-UtjKeP0iYRHutW~AEG7iPcN65U-PN6Y;N5CgZle7ZJKmfS^b51 z-W`Jr>py^&XlLKtq&n;AiHXV!r#OeVetdj9`{@js<^J>CT$|Z=FYQ*!Hm>-P&_1j3 z#hL}`Dk@8sFW>*|R`&ebZ!^7~9x81%3knLl@pn<bqEh&+W4+Q#=e00rvCQ4~qDFN0 zfyc-DtxI2p1OzCY*cEa?TT9Ex*ci0zbyEMc$&)8PzL2z1U603ax$yNig?TI4j)ce8 zvbKNz{JC`P(N87s@7-OPwp2s=#gf^-zrXkQ_T~;b)Fc2J)Of%p{^Hiw)u)7b+<F&W zzj8%IRn_v%#NZHB?`b*<mnlc4v&sg^2@5y(uix{jEBEs(QBl!_thcsgI^S$?UgAIB zj;~ZQ!71_Got-OEzrMP<>snH!hI~~?$(Bts`5oEkT9?P|F4J}T`sB$I{r!K6o}HO_ zqd8*Jh7A+$rujD-I;m@j_=$W|Zfbj$RDE`q>6&|r0@79`D{j9{<GnHI=B=AiExeP8 z{!~i@Es%LQ;e|^Mzr5X^<l}vxpPfDIKJoJ})~{JCvO4km?i>`4F;MUjSNpU*>nf<R zVbZZMz2Qg`EBBeQ%QAJpUaD8+o?YnNZld{Nalf5YruTHct4mBQH8?xN>~2p^KR?ga z#f3%l#nGcj_f~&@cXM;Pr{~E=X7&xdwKhdhJSt;-&gO0Ak`@<t|F+`|_wS9MwTO$| z`@g-tJ^iY+#QVFu!&44SJ9BNF!i$_1zjhb(ZMnC_ZXfTLZ|{4&_(bL30L>TQ-{0@= z={d4t`n@d&J{mdh^8c`PTYAO2j};%JFMhjswETW;JJU<w<G&oWWApCqS(&YSt?izU z{0Cj}UG4LxO=~+KdDp>ucgf37KcCO%m$4AIug<dVjoIoA9Zi{wqqpZBs+)d#>OY~d z_brDanYX2E`&Ja+<oA1Nlb%)J507a|&%Zh^UC><k_}IasySqxGzU&rtm>?%Dt*!oI z+umxw>y|wh^KB{@h0f%cw>!cL8ssX{x8$0;YSpS0D^{@aO8xo$e!o>{B74i%KfTiC zVcWjco?beKv$Xo_t5y#2>JQ?-PUKDZR{C=3(xvP1^|3epACt~cSkc-WyxebNmHM2c zQX5n^Z=L@Cf1ChMfOkzz%}?*EX{V=HPh^RGvZro^_?Ok;>mRvaUFgg{?{~a|p2zmL zcZ+#63@0@k&9kqMyFKYE-+XN?Et%5yYp<=WnQf4Gs3m~4_UtUvxmKl4^^YGJq?{0F zd23tsrQ-kJ?>FCm`hVY9-Yh2~DCm-Se2wCp`@2fDbrSuz?{s~nZIs}hmYx2#P{Yu$ z@W+RTThjmh`1tqN*V89Y3g$fVQ*jix%>QLulJw-nL<6_rmOJmo9Q8c5r&s)YaFDsG z{&ttBwu%0qx7+W#oxHs*_wt?;rsSk4_QlV9=APQlEMc!0v#k0>qi^(+3|EIHzrdc; zPpf`?$vm+)UvP=zF5AP!{l|?nE-3u@t?brw;qkE(ZM@O}Kfb)YY^p!g;l$F{tcUqP zZN}UVi>n94#b&xXH1TcPv?*bK#m7e%cHOh`XfCO4d;a<P`Q!iZEp%p|d+kO1&LY;Q z$!Au%KV)DopHlz#S1HIDCgOcz-#*3YJrh{5;Qxoi{4Z9i`Odntx7vKmz3qHC6Y|b~ z_;X>QvqXln#_ocLO@5&XEDfKOm6iYhd@g^M`?xE|KlAKsKJT}BUt3oH|6kv(&Obk- zMMan9oMDX>XA&*>aIgCP!zmXRySHEXI<1NKQm(|j_}yi_VnLcJ*RHqd#qL@lX1hsK z#=h>(LGi!s$L81n^E95#FK^d#?8vrFw&EqR98MP&#upYAT4ewJ_ExcmQRnEPR_>Lm zZ^h<;R`{>q_e<;F$CH!QU&o3+75edPcD{-J%y*(S9}cq5nw}%y)!luuZL*rLRoR;v zY)yW~mk+Lq+<YqDPfAlu>(q%82abKeUq64=tX=j0>#l)To*&w2Tm8+)+gsW=?aax^ z>b(~(ZcyZKWM}7>I}*v^{r>K5@i*cJf&wPwZU6A+=jZ1pr{oM07`A;~*Ozx$Tudx0 z&Zup+#?B>6Ts}{F+kE@2oAk7)Q!f@Ae_5h+`#(FlM;lw|6LMX=PN%CWz*K?L>2cG= zRTmnfT~{wUw&C%mrnT1=D7_P19UHVZ*Y);Fkye*g39%bix`@cKxEwXQW)|h^#qc_4 z`UNhIs8t)+-U?{FKfS!}PLJ`K*>7#rs_)0=zq?ayF{kqV?&tT)-&t01#D=$t{R!b} zRWda-wY1!Mc-|}B)6@0a7b}W|-(vAm{<7_xfzh9?xtrhKxN&2~+_|!Xf*04v@4vX% zz1WDy*~6n_`*!m?(?eH>J$x><LOz@6h1>ysC9gwbdl&pM`2765c<iS2>-AN<V_%%> zD|~%TS6zKMBQx6rwr2k`AJvz(w*UFhcGcBq7f0;M5Wa^8WAYiD^!4>YgA@@lnZgRI zXMGU1tN3u>{{8ur>lRkMzqfa)cKEKHJ6BE)Sw3lzuJhqAM@Pq`P~js*EKIhxw${2v zPu|?zJcs3K_qv#!OdA;)86S0(YOIOhKQG(9-r;1VW$l_z|E+_>4LA0RoLaZ^+^rqU zg@uK;R=c^n26k7apJIPtVQ}Qju7Y=WcCL%vom5d*w=YxZ%cI}#_kaKR@!^jcd+%vF zn%df{*RFlra&_-r2D!`f^?w3GL$~JMHgkJdP;_=nVqTtJjDfiL^hb}9Hilg7Ubak4 zqo1{XN76wFf!zrQnF^0u@ojKx&u^c-aNW9fYi*~RDC{Y_?)+kxO-ZYhpsXzKEIl2a zHyf6FeY@bRTB4w?&VJa|#zsq9+gEH6x4Pe)1)R!iYRmTRi!1rr*Oq>M-qWW~1Lcln zUS9V1`~CW5CoPMfaLkM2IJjPaU0aposq7GOL*XeYfmX|pybFwq;$n7lbGzj3_To@v zp^svTz!z`*y-Py0E?>U<@w?TVmG_#K)&>Plno*Pa)nM|4#wk-oJYHO0-oL~2Ro=Zl zH#evId-(bKPSsPL%)DsVE~)Miqcxm|&(E>Eyf)h0Z`S9(RgRTE3-dcv1(q~>9=dr` z^0maq6e}q;|9NLty2=|miJv=@#kEjBZjXeFukPbxz0J-Gg?frQ`}?Oaj_F~Q>+I;@ z=(AU?`28)n*kxsN(iI^gp(C~Z>dZR|9x{1I>V$=cre1OQvb>|(JN4M|?+=yI{w;EM zSa&SdNFzQkAwl7GLSl>FoV;NEg{KX8p9xn<&#x-^^W)<L<BAUttjpic(B$1w@lomc z^w(1-AM;>obvpRcLiXB)3l|<v@Sd)B@psRWBQD-+XJ%Bp9O<prn)~q}yL^Z0g^LcV z3(Mc$IvORh(7xh>L&5@|7n2-Bobn$tZ`^pQaRnnY+l>86ahp;&T~gE1X04ym!`C=d z=nap0to5UUYilBBEHstUkKgCBu{JO;Q0$DvyeU(TbXG0u?YbQr64If1VWETOR%Rxq zEBTymFY5pOTz(*8<^|Qph?aZD)Q>C(GX1coH}>@E#ap*tJ%66xyh|@UuuWsZrb?-k z6IQQYomkmBMF+G7bI%SzLBXIUL54D*IrSsjzdNnPf@ih2x67EPO09U|8x}ULN?Ez& z;dLRSh2BhpoU%WDzu&*ycQ#w2ZS^-DU0qXOkJ?(><LWO(y|pD}laBYv&Ix1t@Zdqh zyPs=xuCI$-JblHFRNd3h7*y+oUcWeeu$lepVdE4DR-Ic0vPpNBZJd|fQuqFzZR10b z@r9gwd+Xi3RxbUR3>vs?IU9D%;doSp%i5F-=anIc&VBs&am~|LS67$VySTdtd;9wG zzTM(8*XpX&sgp^z2Rq9nO788coD&mzF(g2vrA&>@?S-$eFVo?#0=vrW#J=tj54$wk zDTaxe+1SV^#40ISOH0ea^Kct)^A=8FwE$BK2Khqv3#La;?%2J1v(b`U2aU}bFLLhf zy>EPTQ!00>*70M<?(MI?zv5wuv(G%6$e6V$84kD4l}wSBuq;xsn`d9Yul)VJBhPN_ zekFF${C*8{?Xz=pv-hp2|NmF~wZ{(GPlD{i4w5_m{QbN2u$aU`?&Iz+6ieRL=*S9L znTm;sG|UaP;*b@3z!Y$Lo^7?4msbI(E%4z(!K(i&b;F{ktaadWQlDd2d+YXX=|g}2 z{OPgE(-W?G?r`{=dH%hU($b~B7e;T-Te@_qoSfW_d4|btUvmuQEeaU44&FD4zp^p; zxI)&SA0MA}7ny9?vZdiy!rs5Xzh~E<=7{|vJ7ZzXIlpQyfn8ntkJemrd~vv)KRwR! zaF?j|rAwF6&duTMx-Pa__f(jI>_X6V;FhKDo;+!>yma8oCZmPrd?s(^%$aj$<wEc2 zdRulThMLM}T(?$KJXjN0@cHRqvC9*tPG!B^D`~v!u(49l1x?`wJqfQDtG?CfFtyB^ zK3!Z&YSksj7e~HIHGEs{H}}@QTI<`TfwulHZfPdvFijGwlHUJ!(&Wj`tO7N)wZ+B7 zUxiwHUd&}KwFXtpQ&Jsey{GAH+!h=gq2atSa&y{D&F3d4tH;H~ojZ4Kk<9D@4HI+o z@9*wP>)qN}{M_oz0gl)oGZtQy`?bKa`Nnq86ejngyAK{bkhLybQ6gZ~mR<3polo}D z$B&Xn7ay*40tI@Ollqlw*Zk(&&HX3VQ~&2jVdFWFr?0%-Q}eUPkNe%bcPm$}4BL8i z&0nSKGM2*Xej?7A#}8dv>YcdD{C-VvIJ?`6L!nx{swLC<pH2;rySca8T<_c4+u~wk z%P#spSo}-w*S)>f-d<i8KAlvbAHbcbW^!q(&kMJOixxGh{*g9Ja&dHYY`?ebO3S~~ z`uivFZB9R*)(cvg7SGbUbJwn4zkhFb-Mg-gclX~fm;EDVetmOO_-<Uy$D@|T&o-=I zp`Pdcwo!`Z*T>`Xo82t>_f~yndMsmG6{2KqV13wo=@*?{2C1h+v^5o@V`9#HJbCNP z6lS}oId9(N1a2vk0nI^{r+t5Smvv9R+lxa#pF*<HhaVpv9)6g|&dLg^Jj{7-9bFM1 z7rfjrv{dA2lRDQuD-{t@(Tfv$rOh|RPUqVm^F%|OvEiWM>7a{7469eHS)<d-%n>AP zCAzP$u#mBPV{YxABN<1+e}8`uY8NUiDYe|b`u5x7e*3bQmsl^YnC-Ms!m32$ckvbB z^9-(qnZi|d)_SqKj!5y#SZv6=tmft4Hq)QW+Q52!+}@~$vz$NJ#dRVYrcM)?CDFHO zlTn}j{gl25$NS~0tEwKcW#r_DcpJJOSnS^a;lQDP@pV6!I+(k?*q(P+=*6=33#l{O z{M1UEyuG<Q_%G}J{kkr8_qiE{k8f;DE@_Aeays7AwDS7l!^vl7nf}n;xpU_gzxNFF z|9+<T{@Zoy>RYqSODgYvn*V#1sCeb_>C@ePhckqK$-iB2!Qm@k!FkJnZzo6m-)D8= z9B9g)p})Ginw^D3Cu$4F=d)Y0uj|bFwrRr#fhf@IOpW5hhYyo7pDI*5pIiPSPo$3b z7{}jZz0yo~Q=F!=h$)shWoKu5dUA$^xXhA?{|6dne`4U}^5V&(vvaM#UyrYU`Xgz^ z6}~<NSvEcyj(<rnGfK9uzJ2!Y-MQK4b=!A#32v$KulPR0b=K_JTRG=C)}C&)YItOM zZ};>=B3~YCyef3?{(XBrJ-%5QQ@ylxBzBj-kJFerWlBolgzItDyiR5B?r2U6>udP@ z{Cu+S<7dyxett@QIIriz`uP2N7kt%9JQEz9(sxvUe+Qb^batLQXO6^X50@94)6chk zxVyXj`n798I=VjvBV?XDdE(;g+GuOJuSojq^{eah%)73uIi;&T-Eya(Bzk+^+;8De z-!4#HRn=bq@27i~({YtqGiLnw`F#F-o64XcYqps-Fg?3h_d9p8s)?y-qHD+fLkAS1 zBy(#51Z;IcV;1+$^<3DvMEHf8@Gg}NY)<JbR<AyN_UuxhJwXCi^Ag`~uLrHbkoLcG z<@xseb&r3<D*RfpI`(d!NVb3Ex_9^Y^JiU4%Z*tRx%t@X)2k1!zq0UNL_k2p>x+xs zyYsrtZuh8pd3!gXdwqSqc_h;^J&%YT1q(Z(Zra|fes9~ypJK4&l&JC-?eKLRC6hU0 zg(5^33NKNXIwK}i|K+1b|DQiKYdC*>eSQ7btyiyK@2>j#YR?{<ThaADpH9#0SXWlM zJ2Wip+lz~fy{GG)o~{qtYyVd?_gY>~PRixZU*WR*M2@;o5cg$Z=a&<?E0Vj-^TijZ z>eJJ7m+{trdvmjaky+v4qoduAw9<}S6h3O%ym|BN+0mt?TNVFGF67QX$02AHcI4*G zn>!9f@x0?P{r3L;{zZ$JPM=J)*>LTc`<CkJYISw>V0o@!L60+=a&8)hR)0CYE_U~^ zKG|;W44axC1r`25n{(9<Eaa%Yv!ifAkMxwS0aiIT9<JSf?+`C@(7Stkf46W7-`Kl) zb?o81@bz)Ek9*Az{L|CZ)8F#}bmCx!bIfAUSRN?tDdz|lZHTZedeZTtOyPzSsC75P zIQjSQCnqOM$Vo|QtqUvbX=`h<tNnE#LsC+bjW4l9FJ^L3$A#<bV!5Alhzkk|CMG5- zyvyJJSIqx?m#B6`hoYXt_Z<gBYzrP7*tE&$>gU3CCda35l5=v_I4$(>^-T?KT6=gQ zM{Ju_&c$<6PJBMl$h?eqdH9{V@waceef;t=xa&bzXQ$zxGX}~f51q`NTK1)%pZDQI zL5$BF3qd_mu@kSat&QH2At+O<l*dpf>3xFLoiljvsS2lXt*OoxH+)|P&b%Niwk;!l zl{?Q_Uy17H=VaGxv9Y!N|Le8>MbXXPIX5;iUgP87$jHkxtC_-~?)q@j;rDu4T21VG zD?dN`e!pHm_~W+R+a?t=HKcnZDi3<HAAPM<vhC@lnKM^b&AadH<Rm04d^9zb+exjY zy;b+t%(4Tm{%c+^?G0#ESKk#@#(76hPfu^%x^?z{J~VG+?hHNSb<Q;DNXPdI8OtIS zJ-xn~VqSh*4GoX0=gyt3ka)dNTcqp7ix&%>+r`Ahy4+VyYw>x($31)V=gZ6eA0{=Y zMny&WNO%i=pE`AF(2KP6jEsy0Mxkv-G_x86cYSb-v2C#{e-~qM_xHEAhrfb`tfj>@ zqHFnUpPrh!s;rD{|Kj?D1ck{9re8RH`t(Kjl_ATPFL!ry>pHPY3}(;U+uJkQ543EI z*jGGh?#`{opbd6kUR;!kFS*dN`QW1|3l94{diTz+P)AtZucx;+^y5Q~_51%>x$aa^ zQMs_aXH9TW(4M_}XR_>V={qXr%Xwf&;p3vBA{V7lZ*T~my(yVpf9}d8k;KGAiRvF8 z5-)DuWV~hDwsSL$+aLG4NpCGZcYq^yN61V$r|F4ODNf}PH|EUsU1wkZ?2IJOkyUpe z?aWvsU-IG9>C@it1?yuITK;`_=-ilRw9uPLTcu>DN6B-CHFqA(ZS$RN=J>Gm^)*TB z38y6A-`woZwe}6CtE=m|bLaH*^xUrYTwzcyd1$o-qVdbGUsWrvY|oGP)=qkUV`DP= z@#(6YwkWkVWkr-n91micI(4d_pC2P5quL&?QjIHDt^}kSPUe3kB(act`l6|z0!4A* z_HEmK{rve*QAE#3`>>Br%#I1!{*KAQ3u;bJQ8-wjqN0)z5*9YiCF&--l(h8k@9+7Y z&(1bK?-ST_p>^|{Q!RR&YbIP^+|heM%h>qxrLG&ga`tt1mix=ES^xgt-t5d+9ww2p z($cs0_U=~vxlm$V{Qh^39zA;eSb5K%@&cQh9}~Pfdu6S|Zmcz9S?)jItR=LC<L-(W zy^@TK3kw`yUthm`p2(4)urM(hnVzS|o}Hcj(n3RYUGVwWNedkAI21oSvoQNi#Sf3` zVG&nPSaJS6)XIH<>)E0?TZ~+ei^tb6avwi>G%`xi*>QWz#!mIglP4Q$>FW9_t$o9g z@ZrOUf{4ry4-QIgJ?wLMW$<zZUhSNRc}^{PA$sCs?S1tP`<%QhD=puNYRPncdwjhA z@uL?P7q5EmEWs<nQN+*7yENOUc8$wc(QC3>{hZhzJ$}4U;@atJVHNlI7>eFpTPuC% z^Qu)^-mjB1d~SSPzk2oSTU%EzU%tHH&m85)H#et;yjz@qe_ztnURL3vnlekU#W{N7 zqW;%P3PO&4e!s+X^1a&cvA;S3qqpa&zK{ND!!4~Lplh6V=Eia6BS)0(q&k_)nCIPD z&^2r2%9TZ1W_GMtx9;2L&&`S9Yok&#V|yIDytvX+;@1BB{JglvHsa-$O{F@~+j!Jo zU0ogS>)RV)<n8Tkxi4*ffw`iSxz=><x78ID6&fO3S;zmregB@{_Qm7t@%6ms^1Ux# zzFhVE^DYSufx92BKmUB<#EFEKb1tr~uAMF?o*lB{{QL3o@gJ5+Nl7uWv6gl>qibvT zE}gomGGQ%q{BrkxIhlHn3oFiMbT<phO3ynk!{fTL$MvS$2Jf0*FPF>2^S^#`bF)&H zuAW|7gw4)FcfafrF*Tch`rKUW<vuf=;uoeKZsXmN>^I-;EQ_2~Nydu{3$+~iV;vrp z->)?<dU9gI1c4J%Y)hCMUGIm-*NV!@p53Z!Z$JN%;p1)5yGk^B;-jOp|5ZyLXY|;! zbEjmS<sHGQkE{pIZ_t&ttNL={?Afz-@7^ugs;sPRIXP&e1;@7h`+i$ihiDz0>SMYi zGFLzLhdg9yM{IRK$W{4x2O$xGN((!WjR`ueESEJH8$E-&jdYGWUHM?jskYd%?Q!-7 z9`_X|YXo|mEcdZp(pcouF6wgF@tD+{u1+E2r6S!%E|oj>pTCoT_x{&+@9wgH-+21o zd3o#d^MBv%yl?w`&iTLdiuXVNZR+@9+OZ-=C1vIA?(VH~=Kf8wkhiOmn7=__rH~$X zbco^`FRq`9gmy6`s2_4Tu!PIs{p{ZZEo@BJ*T=hCFRtJ4RL5|o0cTwF!im+J(p@w! zY<hELW$@W4>gO$eb{k%u9AapF^xfUvb0s_;ZmIh4z|myi?Afz7+}Lk>Ny0Ev@O0|i zTU(Eu%i;9-edS7s#4SZd#e)YAMn*>7`W<=W5*Oz$Z@pF1xz!F?m%sDz^7{1gqoJGI zmD?|tW)v42=X7OWUdGDC7W70x^ch3TyVtL!#l*HH9p$={XI*<ZC-9l&ANMoYO<!FL zP(E?~yt>){2hIFTR_tG}fT5S)Oib+e_GT^LhP}L3Rt4P&PhPQRO;1->QDLEAno<eJ z!w3O0*4^FRN%0cqc`~!MuUmIc<{>jXU&f4`9UqQ~9cSrLNl#DTu(QN^t=*pw&Rg~` zU%q_946hfH9O|4v1=scU@%lb5!j2>a31}_!Zl5+ytU%zI<TDFv(4kjlHgzA5iW|L1 zi*I<_GtK2O=)|5&v8lhmz1?x7fswi8Xo%BvmM#G+#>bl%ElRq#r}FRb@7LA8Ojh^T zS~RsZfHT%gL{xNPZhX~C)#4V%&{w?%9ksu|3C_;Hz0LO$_rf~f$6T5^%Y=5R1WdTV zxuCRb|Cys79v*&s`g@FO$xDYq1<;C#piMh>-n@PL_Q{hk|NQ)Hq><(hTDh%Tl$M_E zUAuPs{W@v!PoF;viv@GW3Tb%1`2OxLD20oB`0(My_4V@JFJ50;8|<a}dV$a`mjlJM zH#Q_1=$^gVVUT`K=1%LBDI$_0o0XqDd-h1NeOl%7x#cN4WR^|?ZNk|wgVQNp*84+B z#Fh*}*~!(O85tUBxgku;68`cXK6L0t^4f_yu2IKKRc&l!4(adt;8a<;)50dpIAGd^ z`1-%4yr2JVUbINb&~V}u$LGI49+#gQbkb@?i=N<_^Fd#pPLFrGbo}`7xI?`snX4jO z)gSfAT0hzOXqIWV$^V}++y`Qu>R&8um#h1cc<Y~Y%e-mRjxFnRKChvnalo;#u&}14 z#>J(jj(5-cH;k`l+Sl&`+dJXHN%6C1&%XWf@v+sjzt)<`v3-WA3qig<;d&T!aC5|( zwQG5q<tNG4ewk>~b<@sZr>DRFb%WjQ-`?NXzg_xr5hEkxp`>R*R(uyY4JKay=l;Ur z{P8~7?&eLKHa&QdAapp?JpZ0e@v}2~tG|EBy0Cr%pWhq{!?ZIJf+w$tEf85a`Qe8H z%=|U~em=KKdkY#vTGHeC(JF^UYoRw|z@-ZdofBhc_4NFIHamaO-{hpEH&-skm6Vi~ z1=$Hm_^7I?7RAka^oE^{jjKD-;l+j@2}|m~UJZZKH*dp+4gPjNQx3QBzLD}yNlB@! zv|Of`)9LBNt|8%&-=x&yxARDX#e-!9rwtQd-QK=lcIW)f0i3a1Az@*QLe+g|spy2o z$G?B|itF)#S0*#|^1OZfR%FeU%a=DVTIBR>_2t<-1{*faU~O5K`t1d?&cefT=TDsI z=<QXlmNDDCfB%0LHnz^_{Z4DM7IwGHnIpq1-1GLrLgzif2Dc|qp8Pb#O=m@m9_yt` zmoBV2)V+VhBXz$yD>iCf&sgu`?d@GsVj^|q`t|R3b{2oqb~ryNaIqU_ccj}3gYzFd zIJmeL9eVUAslc$@bdJ+}<{dU`SIt)W^7Qm{{fG??DoR^LPx!pp@>XK<i$jN;{%$rk zHLb`xwXCNjfHM{pXnb-u5|?*8dzQwyanBx`EjDhuq_(*p&$-DQKk@PVqut`77ZX1{ zIT?`f<;BHANz(+aHl&;svbVPnQ!p`^5*vH4(9@GsHa#^p@aF_Y=VOKqPEpQrdJF2V zo?fbMQT9fHr&z#>ZJ}dh9@{4kWxWt5aas3%IoHW*YHD03OiWD!FVyh(+!WayImfp8 z+Wq_TYZ--hm%W`8l;z^;>c}pz43u@k6J=ABzpPrNRbF21tACb#nb58mGmKKZ41&u` zOMPdVcqZouDycXH1`77BZ)ssk6*fQg=c+;ALr9VGNua8>_V0m4=E8-kr>A+=>bfov z+O;DiBjbP%-{us?^;31Dw=Fp9-Xrnx`TY7*D`)d6sjIhd`<h&%DK{zS%8I}XDTi7( z4<%_W^k$Oe0G)`<$jB(ACeuE5-HI74UN0UcJv}uw<NTdFG099@w{BgxZk?W<-qfj6 zi?q_RU%Ys+z@$i_WM%V~8Ju1PKb}nX=jvYBqQ|*J?aQ=j)7<52MW%OjcW+*=V=3mS zS|V8Z`&+KOynK22_u1z8QX)T|&#ynh13IWC(tP%zUTO13j~|=**sWi*NNMTSpW;&< zUs$qvrPm9k#ap(7Xd5ovzIE$E$KGGZ`($t5x}|k7G>1`ZVRy%$KQ$)LnpnAeI0Fv7 z`1ttvVY{iphO-Z~a*H!DGn<~7=kqyutyk~4bADaY$wfLd6iU3<L}X<4<lVK(<21LO zuz!DjQIV1C`Pt_D@h>A3_<FWYKUSovr`IOvvU-A$pjBS3lT%aMP2*(`tjjAG2<?h+ z*v`qtbxGnp``?$#=ReB%|L?D~lvK*Kvt<Q8J|uEk$%=}qzPYApye@vf-;_(iPU&~g z8;U=kR=~JR-aJo6*4@P=;8eic1R06k_q|UyWnW(>svYLx{$l0Il`ACuecdH0j&amJ zIWe)Yuy97*qR$aq9(}oy+~2wC!T-bw8i}91N-VuUempL}SoQJa$Gr1cD<`JUvpv=> zz<T%Y-I+6Irm*VA?fLQU?ryK_68U}q|5Y1u{=Km=dEvr^cZBBoBqb#&HcJ|(y$Ie` zCnK>o`HhI^-Se5RudPjS)7%v9TPLAhGHv?(>i2tlrOju>FDz-1la$m9JZtM79xkri zw>bUP{I@S&boBNfjpT{D8M>Ks%eHNHpU)U)FouVROQd+MPG-1z_39%5E8PtZj+-`b z-l@tktHI0RtVH;FqZ4P(ntHtWRhS^7IPLTl&0v>3D=XGm8Beg(n$Tq6`9fiFr?C1V zE4KNIK3rKDyy0ecR#pL5dE(Vop?8Ac@ULFA>d@iChHGt#pY`;8{4m$H+H4J1(c1&z zKFx;?9V&Z&Z*Rdvrx`{f*%QJ=j|2q;6`0xE%g5W=+B$Z7dV2n<%DcTS_s@@ylhyt8 zbakh0+uPG1bnN(%BN8^=6UF6gJ{*)b&pWYZhVFwyt=tC>9+XnMvg7QpZ#Ca;rYA+c zsI08?xBV)zy+ysbv0YDEP_XdR6VK+BbyvHYA9INP%HRLDP3_<B_xr2s+%LX;VY+>$ z<*jOVA0ev`M}+--=30sR`j%aLd3m|9kx@XOWMXcv?st*jhj;AQaeBJ`|6i}yzqtB? zOK<Udfn(Pn9&Ug9`t9xQd-v{LAGf!QdDFhi&|V2cCi{btUuxzGa?jOkFZ_61zW&9G z2h)SLOfuNDdv~J2LP_4X`U7jC4j<uji9Wf0_M-!bCH}`A{!#vTnfBVgKoJp<4$l`+ zYCTDXg&VJNEPQONsF?Wc%gZR|ZY{RQ2P`~v#Cg<b6h&{(dwVirU)ftJ4|dT*MO$_W zRkzF(v$6_(Q}1Bi{3x)`pQFJ4r3H_-{qkI?4VzwS|7DqGU0eI-<MEdbCuW6<YP+Sg za>)KyGBgzIXLQy1qU_$6(ep#U`AFxv1LB)rFEz-!yX)w)3>Ma#w-#CQPYDR|af;tv zrYk+W_4(67iz|{_*6p?D>v?>nXlK#WQ?IVBUVHC1v$VjOMTs#1xqEJR@=b2pSNr>$ z?`$*Q*=D_;UIzSL6SbA=?$kpppZq@Rl&q3e`>DVG4^#4=m&@lr3p-b2A}g_`%Qm}! zTmED~&FXF2%qIWd=6Zatb$Np8Lf+G-PE{=b5P!nU!{2{;r1sImkB?k$9eeonX{z<S zXG|53d(Dq1mWW<ExL~?>T-?2--qUq<P26BUdD0{kADI;Pm`5frpKi*zX;g5{{C<tF ztgNiCu(S6K1Dn{Gm{+e~7oM?p<*9ykMKeNW!S&0_{a??x`eAx}-OOu$OOA2gO$dE+ z(=_{<&F?px*YEu%74AQ2rfIfV$kF_>Cr{|;ZQ8t<cip_r`c4aHEUug@E+!VVDE3Zy zwdbi5erh33;cRT2vd>Z+92#7`UrC$ix!B&jckh1f_qj*+9{8u&FTbl~o&Kps;6tP? z-@LhV-MYT=u1)6-IhC*QS-3s#Zq?VT;h8ylk(-w6-5Z<Pdxo{G!Rv+BA%%snXIw3i zy}a?v&hB<T*`lJNSC^Obr?QtitZ2C>EKsQ%vtvT|zV!2QRf1X8){3bPzP`M<Yd?MX zU{Ua(;nJ%JwyL#jg?1$wxV>mu>OFngk|i9=`7G-H+3ejgNq6lIUZ=a7S*BUp*@?5O zD=R0i7VX}&$tXNLyuC{B*43+1r%q)(%<<pK$mmksw8$L`7Oc`*sLht>l%Jh_`osx= z8E?03*%IK;c~46Gy3dN1JlS`5cf0=-sF=ufey+89^le%7jd#x5|M&5I_~_B5y1&29 zo%362x=G^g+qY6`pLfrQ)6+S0=+F%j*C+2Tt&g|2x*+wb@nS#QV-5ke60zg`^4IU5 zzHs-hZSE}-Ug3a47vmy6E)d#PdSh$0_$}V%zSm+`FI;f={W~}~SoCAZba~Ktk_>Bo z<&zT=uU@_CwK`c<FLqbUeuIh+2_HH4?$}{rXJ@CR)D(T<m*%U}*_M7Ua!e%L8)mlD zJvzd9NBv&Vvo>Do7yn}SR&8~cJ@_xN=R)}UI9XZQwZc5pl0HnaJpD8+@6qyKJHPua zD6*XXGI4TMMTLc>W#Wa6t=HGZGOx^>amM;v#?q*++2;A@=Go3}Q{=g@|KBg~%-%J} zZ*ERE^)U<l$Z2b9Tl@LhS>yC`cXpTSM`!RYEM9!jg6WJ(3BwxRV$S5ACZDO(rde5A ze}8$o{o8bFiypyUCk_4|Q&3v?n)^1>!o~W5I{EK*2V9U;H8{Ly=i0Tta=s!*E-rRI zIZxK2;K4*?_bFk^mp4fI@-2HLY_%)Dvhru2to4mh@wb0l*2%wgwU_EqK2YPNo{-mZ zu+80Y@81(APri(lf1zsN@nYk~jq~Qs)6~?o;tTwwwE9KQk-$cY)^tU~yozaEU0k5O zSt)Wq)6&xBSr#wbxbfoIvv1$s-QC*S`XyTEaa+N|&~vPQ3!hDxAP|-K_~(Y;13f#7 zpMRV4-O$X`r>N?hTI)gwzx;liPafXh-u$n(gI0|upPOT8^2@<7d|ganl(OK2*|S$C z3Qg|xdEx5n`tRRAVTpp%XE$Ehc`-qTahi}7&+0X6bhv~}vaji|M?Ny)Oct}s7T?Ts zqI=CEV<Goe^<%u}nJz7VyEwu5-PTj5P9=1Uh=};ix7)jGm(-NMhxzR{d@a^3sg;fR zaOmg<4q4~sbBo&MnOyg`|LfANyJmiNc({13kF-@uMsRSjzt;BJh6QZAQZ8+l^LBf! zR+h@R><|?->qJYRlzHwgm*b$F>f+0ji#cLXcd|X^*f8Zn<Im5}AFDe$I(~Yuz9n*o z|BF2*w5*g1Ln@N)e9+P1{%rQ5`5owhOxJF)(9qD_o10p%y(?|wh>d3#+f!h;=9Y-w zu^UTunRd)JtJjO$GeZ}&r_kigu`T)g|6Y4FD_4I1|9{qJ6r@UaMDBg_^z!HP_Wl32 zR(?(s<fuI{LGiJ~fjY<KI+~gbi)KuIv#R@`s`y_IeQ^3-+QKK)Zu9K@hP7_}a(j!P zpPTo!F^=goXKelceFrVHYz*@%#Acinx#)V|r?0!4IUaP;knowBonMQccf5Fgph;Yh zjfZdQ2U7!sfa4J_!q>$ZR%CwOSogPTi)hw@qtniv^NXta@afYcje~nd+4<$ZeExjc z{_Dq&H}}`?zx1ku|AOW}*;Ij$zZa%9y0*lHhhN{GAAe?wrk?<t%32|dL%+2Xzs$K% z2@R$#6L|Nf@#c!1p02-q!X8de&iDKO+ikDQ;}B<b;^*g|Z(W|};n6XTQ=B>VSdZl7 zNt2xH7kaC!t4HT9oIZ8x#oZ-Qi{HO^q0n7=pn);I{_ob((pz>?($XgniXX5!vux6_ zP7a?9AJ`LpR=2E^IHO)-cJ<e(soFcAg7(GTm&q#LW+!umf9|#Ki3>NswiH{qa^=bE z*TX;GH&fd1vs-_khqmrs)6Jr3A)u|ayLVgvd$u9*@EfJ1MWvv<d+eKMCO@oafGnlT z4iOENw&QkjzS1*$VcN14F(Cm$&KELRGn9%rcfJVHJTb+)OQUI)(oENyt|YHcr=<#t z8dG&I#B^}zh+NW>@(w$~<mnm^Au&C4(f!YJ%T4dEDL%+NuQ=_T<>x;QGi{60zP;J| z{O0-H&+on$<A_xam~%n%0b5SN%L_YRO#c4<zWsr=1)>)Oo!T9rJ$q(W`RPehQ`5hH z+m<g+zqTe)CGeu*0@0s8eq3mG%#Gc=Xvvb6ru(m6zuy1-UbWQQ<bN&)I*v@fb@L`? z%Q;mMl`nJV$V{||3dqe}yQf%TN5Zq$hf)MGUvMn6=e@QjQd!8Kt91(V?91#X$;rtt zIl7}7rcIj$DgjPOO0C$nYu0O-l`<xmnzBSW=6Y*5z4-d|>xLx-QTO%2_~mRqeEAZy zEhlpS?WSkW3SagW{`inM<@|+(&h`I(K0kNPZ;SAoSu<wD>?~@1y+%`V@7}#HU%oWi zWRi5G<I0sQ?fmjZb2Up9R8?8~L45>QPT8b;hYmTF%Wz$7`17YGs()pFQTwB^q9P|= z-Pm1UI;VDB^YJ@kGCQPPL7+-rLq})Hj!prVvuDq4PCtKa+sc)iJtgZlFH4y+b*iO> z#RQM2O(~tzDpkMrUR@pjc;)3wmqb)cjBd`Wd^U3<(-ao2YVC~`y)4`E?sgTc`OH}G zgF}HQD?2;8m;31-69JA`xw=0ek3T%zzPRARgsklB%(<2(%cafp3g()oF50-!(86NI zv51`9+|+f&Yws>_;5&NsXqQk`baZq;fB<M+y2y*yui4qywr$^jTDxRL#T@3!(8$P} z>u>!9Ep5+Y^=Q11x@g}%Ikg2IGG(jw?3uG?gRHFV*36%v#a*)2Wf!6fj~zSq`}_Or zXU}^qcJFuNJfIOc<-*H&cX#)-45|y?yFQDGj$ZgE(0q5<Td4xm^puo4yUX(r*gscS zIIhy=7pJ_h?CmV6&qwta+&g*v@ZGz%=H}C5zVF$y=ijf_`s+3?GkLHxuI8hwjd)9% zi%ZM3_5~B!_wa4-OX#w#`m&<FMb9BOq3O++Z{PTSC~e%hF)S=B%4|v9|9^iwh1D0$ zPtJ(lB{+TR)SWwbI_@r<;@)@h=FOLn9w`a^-l(do`ts$=&Lhp$QJ-5kELxQG?#|AX zmy7NtPAZzKtQQy>sw(vRvrX8IC{d2swI|M<QxpF5(*Df_uc)YFFGaZLoe{rawOg?H zROXc*JD<;coowOV&B*Jgyz23>-sr7aqGk&B?f(5pUiW#a%#|xwe*F4%sbJ^QrJys* zcAgXb4jLlxYPPw<;`CfL@BTjDy71%u^5NG^nVFa#J$^jj?agN{ftP2Nb4&@%$j~s8 zk&#(&YGz4<dQAFcW}Au+4N3Wt5fKyGWQ|fdzA#?@8N{TJcftN*`kuhWZn72y4#&k` zB{_Vo6cQGe=WaRYTv1)U*y~=+XJ6I0%}bZ2K0P%xH#gU7kJ|PGmt8&%2VX9*VV^DB z+5G-kkEFBo(xppdp1;m)Ty<wprE%@gmY-86OlVMlY87n5q`S){yM&|VoW6{0mB`n` zw6tYP;Vqlf&&TbrixmwIGgi2ixo@h^iw7?%-QC%HXG=><J5Nmp)w#3Yb>F>ub!+wa zyieyPZ7K><QkIzQe4)X;ZQC{t`65OEj=Am!Ub}k>uGH%a2n!Rd>Yg=AN;Ecp?gaHq zr3GJP?n>)M+2`Ca&}vz+LZer1BE!_>OO{Nyt@>u|f&~li*Z-gU+UKL7#tO$~Hc2U| zN&A;Mys$a6$hA8_a!bI>R|Suc^}6@V+1C6BxZHl_X=h37<mdH&KC)M8OfoPxGP?94 zGc{qw-s<m0A@5$lUR^smYAVOJ?$gPQ7k)OMIpZVsB_}g8@atZO7ZvGZ`f+PsD!y3a zx@+CZ&)(DZ7M|@mvhT(ZYsd-8Q(yb=3f#R5nq^F0ap(B)=dZ4=j!Ex&@8R$7Uf9~& zdU2h@i#-R<&NkPy+k5NIhJ^mZTGzigyt<?myZnh|6nCwbio=<#jPz?aZ*poaf7$2q z^p?1Vk84LykIO<s#x1N)&soLvVl;wun5JK1Y@RE2=}N!`*Ij-mKigJ+yU?R3mE-B> zckPJl;ppgSVPWC3XU=q-+PilztJZt*7v4XPc8h0*E0nw|{PUx5;*G)?lQVx^y?QnI zc%SNgbzhd~CE1g0-X|+nmzSICRyb|gy!rBxm6LdRd9$ytGc__=^l{OH2MLL5_Uv~M zw@W(0QPOhe#!815GK<%)ef#tIe0SL=PoEY}ZI9lbH?ezH+b`FgTU$C;_+~$`<hXV7 zX5_Plw{AsgYin1<X?)qS!{VjunhHLfyPuw()?D%a!a`?dW#vS*qPd#AF0rw5J!I@A zdkS*QO>Sv#U(94<YrFH@iN~j>>-*0(^A(<Z*keg{uT49Hyk*goDVo7c_z%ulyyCRd z$20#veJc8zo`0ZWj!pTyJBM1iGav2i>^!+G_x8Jcdrz0{Gm-fD^QVTVy}iAft3ruh zU}PlcMAnHx@$u(N<Nmd8*|MdXo!@Ku{e88+4>U4!i|I(%*X>!nc=49y3m9h3FidV+ zxpL*)xp!}E%|1WhUO&GlT4}CY<*gexHV9W&RW&s=&CqUdYs(6_<B}rk+x={R$C22J z`)YriX#C&fnv<h*%2-pg6XYr5KcCOrfBW`L=<7lD11<kwtzO@es<2?uqD3bT&SZGH z!q4wYhQ}09o(1Z4^?lvlizoN?_Re&X@P9I!!(orOnAoaqtQ!0VKNc-se6pE)hI#(I zPGR*D<CL9R4in{WT$E*Tdd{=E{Qa`&bMlq1D}0RHoVGT8Kj>t_Cv^<Q^&cM{eNmC{ zDLf>kU}wR6H%6D3fPjJ@A0Bpeba+ly6I{9X>$T`lP4SO%mptTXxTfZEn}dTRL5P`| z*;Gk^|B6Fk;KfC*-6!~uU$|hPqvP}A*~*v&xeF3_d3bj1+BL(a@xo3=XXnEk5)WUv z^V5>&*4?{vCr&i1_>f@2r>?HPLaS}bs@1D4mw23Y3Jn$A92*lOBQNjI?ORb%;j#M4 zwQFHkUIhgOCr+PU9B@GCV~_DM)86wLSy{Js7OSr<W$%%<m$P#C9TxeJSwTGD(1o}+ zAp00wLqMk_?Kszwb0A2~_~!ll@;*n@G#f97vd_N2>E0)^@WzSP*VazfDE9XD{`P}M zc&clBeEs1zUYq{Q3|lKcJ@NGS_kR+m@=c?>xY)Y%)s$;GD-Sxqxw~83b#K|*sIo;4 zFJu_fEV%C8xie?`sn%c8;o;$&X7>65RrLzKFC3zxq<rKh(%&d{JUu=Av`p)KyV_r8 zXPaB*aQeIW`kp=3D?L;3pJDQ`oSU0mg=?3Z@HI9zYJ8Y8M+Ri@D>u-<Sxd#27lG?O zD@muEl9ZMf7ZdaPJkjArm$TYJ<}DK@OrI`ZTe(a$eMw?^`tj(*y65NSUbzyYuC6Y1 z-`v39!`H92wZFC~oV?lwy6)?Vw3O71PNs#cr8_%2Lmus!yJBzE*Q_T7Mn*wulAJB; zES?BjRh^os?C!M0+}!;7)vJLqx-%tgt4flSm9OhQ`k#@XfBwvwFCRW6e9B2p{d!V; ze#8Bp=Vs+CT)DFIjbdj><AtkSA<YvfPTaT8F8_Jf;@OOy4rNcDK0T?T+;~B>-NuPs zqw4%Z=k^=&PEQ?6KYkQtIpg)@;Q90YGq0IsU0JbW#fq*ju6wV9-X6OiU*8+W!ND=X zL!2XaZN$bT)-GwG8LxXzuzvlsY}v9;GdvVZj$UM6=<e>mc+T-Y+21Z^>II+v?peE5 zS6iEV%|VOXpkWe4MaA@Ua|CNn?quz~Rr~MfbD@_us$ZtZRh_(gwe;SeN<l%vzfl|S z9X$9@Gykr;%gyC`ek}E#zMv*C`*Y<kW8MXa`=%XtVOpr&XU9<s3fMv`OUtt}43nRo znORm=7QEbV>&A^UjZ(XoE>(?dEPQ-y=Iq(8U%qtYn>}-8?wuWhwz&%yE>tu%{rdHK z{PF^ArH#rv_wTQ-tE($7-(K}eVL`sn3<JimLE+)*6VC-ZrLQnnRRzuVG5<*1f8gI2 zlj?6dPvhn=oGv*x$5P|<-QDH<Ka{c<OgRF2q$>TzH>RJLbB(jv%DA3k*Zh_imJnOx ze$Ge9FE1_K@Xp%GYR9<+4ga03)Wn(h3IDoZ|DRW`C5Pp_66l(sS$j8a5^DbtcI3#B z4g7}oI=Z@Bw{LHMwJ_8AM%&Gd?Ck1?hgds5D|R<EH{V>n@8GVQuUEq-K6?H7^_w?; zKAqMV7Zu%DJay(wNjW*boo8dzEiEON@7%fbtKmj#YwKv0xPZ3j8$Yr*h4WW9y;#6D z<88qGW5<r2`M{^sykf<Q;^*f+=JIW3U|Pj<bxYP&t(VR<>Lm}RhR4mcum3mKy8PDd z+v0jL6(1kD&YJS^-R}2J!5}A=l$N&Mym93U%Vxpd`g=Ywy*(%1Tx-YYIYYO{X?et& zAFm%hI`rh#0q_N>H`3zSzm)&~_xE^E;53Pnva&~R8ZYwq{|(#8y0nC&Wu07s$BVUV z*Q)!?Iq=#!&Dzo5pMMd{wGUIZ!&~0Zu{l0T)jJ?{=gys%+JE@HSaLyES2zBzct-Am ziY1TVCx857^-SQi^9RAdbDkabn{C!x_EEU=^Gst&1JK&v_CChtzH=-l1}*Dwe5U@} zO2g$urNM5S)_uvx`KD~zy?b|&m-|!!j#%3O^@X78O!wE>+S>koyZ!#QZQIh^LQdqg zUtr$<xvXzC1Lp!WUmu?fjHhFmTHm+Kn>B0Jgb5oG4mLe|_U!m0hlU^0!or&?KR?rr z-j)#kXhMtAa`tA<n>TKNrbDVKDo)tU=T$R1^yTH{-Me;OxNz{U&pIz}@B0;xd6#Tn z?|iUO;qcPk?Z+Q|b?WWuVdIrrBDnhds#zB#wG0gm9NzzUxqQCY65+6QF`Y;B_x)h9 zlr&1|*tc)r%$bs_rtb7BDl+=@QZXrkdAHE^g!?70uB`O<`Qb4COc9~wnwpwM@4as; z?0a~){r1h9wI2?$d+D=>3jeyhyZrn-TW;0Hwo@$DDh+&p{{FT9{l@sEe-_h^{#C2A zLX^&E&UCNzdeJl8yP~4P-~YV7{of~#9vPLti;;SBO!*<NdfgNY7nazdpr-EvF%BPl z-n@O=+}xa-oBL7eq|N+Z-`QrBRaNUEH>cg+maDNf_4Kr}b1WzGT|Ak7ZqCPV-`wP8 zygtC>6t;2pv}tO8brcm9HIi&PUUjX`Kd?+wTRYgmYkn2S-@o7QxBDs!{eJ7YMA*p4 z=-hwr-HwiqA3uIv!Qt-iZYBA}_n*^5kjHtJdkb5MG<e9IY$)rOu~ZVO4iXm^KfOm^ zHSg{&QxlUZNvm@1?~C2}bU}>MaqFV5udagjV;*kf4bT-66U$+1pS5}8Mow<-!_A<x zp$>I)xjhDLm7II*=+Tolr-Gfr_2%81UU;BkW%oXIr~c^hqfJdrK}Q5Ov-8WXS+{Q5 z_r2b>Eq%OSx|dwO`I7bjq7^GRI!$ChURdZXB(8Y0cbf0+-DPiuI++E%?=&5Jd3iZ| z_s75A?<Y?W>x$Tz)Vk;Qru7V!eYx4$*-xh(Zs3${d$2Y8`o7=qtR>c8ym-;h&Q2lw z*!~HOJW}Q5<sFj_9dhdJ*rDy<=yBX3-C3dJ>Y?-J`@hJBOC~gYpa1uew3L*Uwe|Y= z{dVf=?R(=URdL8(nK@yCf{^>)wB^PN7V>B9R{F^E!?jy1H8u6($t@4qCh9lvzEPT3 ztJ(Q`QKzz@nVHzCJ9qBL+&<nXJGngmo2ZK3Ivs(9ppCkB@7|S_mHqziZgyT?URIV< z?3F85rc9q+|M{%Bfp|jMfs~dVY=zdAmIqfQ^fwqgd<&TLVo`xz)v4(1d4<<6u&fZs zP!Z_JIPfXy*$bA1#jU5O>p%W#Y-*Z%?a4C%gDrda>{+t2fniz0N<LFAw*cma!ahDe zMa9K8U;h6oe)Hx{k3SFF<&%<<K<5SU*kxW)v8rTfnKxyM%X!zw&o2C^y)(U*RU_uA z;4g-Tc@oc<c5Pp=LL=r0Xzq!L^}my>V^x*aEe5NKN_7p77ynryV=tf!AphT+u>Aoy zYp}1PLQm78r$WX?Q&No#Bww!B6EZ95q)AYx*JTS{15xI43pfoEPiSO$_bv=N;I_}i za7IwXqDR?|7Bkx-6OAWYyb(C@e&*jlJBrid^~%fN-`mao{Acsd-E*qnJ)dX$+;aZ; z%1S=<lIn&T(@!|%I{%YDeE6_QkuKA%CvS6{+_xLn|EuZ!xPtv#_2eT8CA%CX8vj>S zRb6tID!K{k${lHSD>=dH;OhRr@t^2j=6~IFPAZ1KRTpXZzPJ|oJHdQmcF*Rm71M8S zPPhO4X7kOPH)osWUV2$__UzgH|9-7Ly~?=g1k)r2tBMZ`wzAB*Fqd^!0XHvi>B_s8 zw&&lUXPn;05!oOmqVQ$0+xA&~RV&u4vB^peGSSd@vGe)7)2B~Y|NHs;<NcMv%Y)QR zG^J!@_MGF0nc?5HPR2DbP_R~CX49LuZ$SeNn>uy<x*jEmg-x43fBvz|$%{HWJOBUt zou8kd@9%&9>FMbYv*+8@?pnK+ck1$u8$T}Yx6{(r*4EId`1|$xbp7~!2?v{g{P>Z1 zdD%oyv4`*9%S%glo9pW6tXaGE?TZ%&^w*UweLR7Eg;s~i!=la=3k#gK^NN+HN4hvU zH6629_&lUKhiTULUteDzoFulBVcqNb_5W7hSn}dxV563lo4H}zu}zr=*<^~ZBwH-m zUH)F|6JzaR|K+LOI}GBtX)xG$+;5hDDIHRt-RV0`w@Lot5AN8eo`RIAr{`Li=iS>= z`R&ckWy_YWTBT)Rcg8L3;lqc|l;2EN^POc`{A^X|YAr3T3!xjH`xosH*YHc-zIAr9 z@UGwm*I%0+GmH-xSnB-PJ(<mYbMKucH<vG4Hc9)qxtJ!i`da7r@87rg?=OFUul!ym zyRQ7)rJdIApFUlBHA}E^LHVDj)8n7iTD1o|DylK*Pc(Tv?Ly>Vv9MdMS7Q^`NA`+m zXS%J)KAMu2c4(?{eN9D$#Pwvcy-W?l?Du<@378)9^r(2j%gd{lGjH~6?Vi0wPT_1_ zZ$)IKq;^$&T;#X>^vRQsS2C3L%Lxi@tor(@-~M03vF3M5%F6SrUTJO-`J%n;p0+KM z+{Wy$vpT-a>pq-dz{1A1NVj|a28r!0=U#2!a7k~?JFe<n-`Pi9mLFXdc4mrZa6xav zv~BqpJChPBx2CN~cm=v5SK2hn-~arSDN~r)`7T_D_Vwj`y{i7hLH0L$=UkZD7!{@0 z+}tcHD|_`Ss7yAJZPie)vXc61tJTn)sJd0qr2WT_ikWM~swems#5?6@WgW`jl5tV# zV+u-Otj*j!<HeSUD_w%yCN0{vzz{S`o2s>F&kLIcqHk|(R8~`Ko29Yq3+UL^*fhIC zbKH9p_H5jEQH9;_#i;|OSH#NS-rAaUwCm(#b?!5AGBSILo}SvZYghF4yqgo%w@w5N zrmLv5{7p-l;y-)#>_FF#9K~+S@^wy4KNKQz{m#zfhkg@3^;GW2(S4SenR!t7<1DQ_ z&q4vErWl=Lx(he|(p|HKd-d)^anYC43@>JGTp@b++I4@spDxL<nFlKy=BB2mZb@x( z%B<NUF_-i0wMT(+pn&NXu<AZ{?%bzOMOShk?g@yGkKfVq`}_OtnM=iZcb=JH$eiy! zX{lOE-;Ig0_?=iLSF^UCjM-Q6@KCF|-<$>6UA1Qqr)C?PYs|aUAofOErnGVTp?pCR z5tC>9hIyQGujVH%jg7b~`fb+LijC9Kj&z0bM8~I}o72g(cK!PBH@>`VhqvY4e!v^3 z+`^mDcx_Qy2#3D@`V}iyynC0|&1tbvn^|0?gwZ_z-kOywJ-xj@fB(MRtMvWe@9QEr zKf9g3f9fJ;WfS%vSG=d|rS4zoC~@$vq4?&-Q^cNnr=OpfYq)XikJ-IDUFW?JWB8e| zL^jqkk27}ajaQq`+g+9@SJX1Dva_%N-92d`d*zi}^_z|B_y3FfBi6EX#r-EoBUtR4 z{M>pfS?*3!^?tHWq=@P6{<!t+{>o=oH>-AcbqW0Fx}$1h8)BRk^vAWQd$)i^pM>p~ z`*pv0<=0le5PRzVa3N?DP)Tl~(`l7|X~}su6Cag+R^P>XVN2kT+}zycWlvi4qytVq zdh{q@R+-Pc+aK4|{{F_vF7hDN)vSM`LxgUfo3_15lv_`w#};jQ@pDX9c+>^AIK95J zckkZ#nvbrHalQ`DdL7vZABX4`>L)!tbH*oYs!7|vq@!Hfa=ToA2L1T`;N8yR=W1$d zlSFoa6U{R9w3HN%%dvSZTOy}`F1uf<BDcL|oeiI?m5W}F>0Ozf4YRtUyhHjdw(Q#% z=jIraA}S=*RMwqwSV_3hX*!>v({kH8yUX5Adfgt(rZD}_AJCx%^H;??IXUI#u3hV8 z6cYPTpF6#=u!Dhho#CpV-kxVTW6chfI|PP>hg-iFEbsx{+jdJ#L`teF;DBVZb%FH6 zdOyEDSG7kida~Cz{+^hq?C9tyCnsm3_Ml8cLgL2ebpM<jor}MooSeKp@9wSp_w_%P z{rC;KYvJO>XWeTod>Yu~<mCER6@7gbs`=7#;pyhZ$NoM_Oic8%V*a)N|G(SYa;4`! zdHwozbU=W@-oH1vS}sXF)>Anm^DN~EXROs4!K$({Gp~w|kB<8NVx7t;le@<|D@*Hz zTe8R-9bMh0mkd8OO>w#S-_z$jXRO?W4N0!9t;R<7wZFE6tyazFc<bIc`S3KI$VG;7 zA1`0Jl;q?#=fcv%N(;k7Lo2JRn_14!vwi*MexPK`jsitxW#<K7zu&K)uYK$UtJJK? z`?C6kckw7p7YmL2R+VEQ@u27Ot_L$_%rF$+c%t>)yF9B7A>OMkmn|21w_7fJe{b*a zeZSv1AI!V4!ExsNAVbhGFSfRG(|nzsoJy=@?O&gBEGaErIJ>8#V}hOTan4w_3HH%J zK}z}CUZ|&?owd}EOAB;yo}bj2jciA%3RE&pQ(|N1I(W{xu(VmV<V$yDWu?l}PhT$k z?{3PPZ4BD<-O4Q<WFjdqub;#EXalpQrKOZKf5?NDcN!1QEE4DC;8@^WxQSujzhk}9 znV&vibeDho;)TS-e8puYe-|eo@4I*{SYBSfBr1Aa&dRlGbF;I9Co0|LR`;KG<@MJO zr!E>TUbLv=S=jnG-F-zRG7mmHJZzkH=7NN3hq1A7byd}sZ72RR*!`R@XeP^fn)7bp zn&|C(sypibR_!!msSQqUXpV`A(OJV8oVxl-eEr{6ah3472DQIRc-u{8Ou4GuZ?mZD zP`{SLUR{0t<&D-mtV2UXYgmq{O_@4%;frhQVzV#D&bc7VR23K!R`KFm*`?cE{Puq? zT)!Tkd`G+F;UU&<@y~X-iY={mcM~;^C{+4b<ML*qTgBsJyb|Be7@v1>aZ%_CYnHw% z)UocxnjO5-W(N}IH}qV)eY?A(h3%TKu(0Ti^YZc%Qc_(#JuW*-%gSz*D65yWJM3Md z^ZL9%#L}fpGkXHF^77XG?AW<8Z=!4F{fU82=|?+{d@j6GQTp*-_4|c)nwpxfn6(@> z>XWf_ViNuL@1Lls=${9d4Fluj`yY9EdT#vc=J(<o^Ii>`Fp+p~@9yTvxfX>@o0^=L zUw^H;%<#JICXKh&Mp}(Wx`aEQKVI;0Rr2X+x^phX%GB1@W?x&Q7%p4VJi|Y?J4XD& z#tR;S0WUam_f8ky^;bbtZ*AD?1iPh6m&V1#op{x$K5s|a+gV#vp6zl~lX6oN@>pXr zvBHk;)_SY1?ru}JkL6o=A4)KvJ$rWH!i7?grQ%~&=k|3k+PHCI$I-qQGlh5kt@w0O zJ+Q3$+nbHn?9B%^WL?!tdGzq%#QF2}_f0t)v;Bn2;S(-QoucYO=a1+8j%5K&Vji<- zU$ae7CVBDp?dGbguE{pKukV)MFWvTG;%!D1zgb+oyu4+1&T-!Ln`2eV#rpjKGyjdf zEWCm0E0fq*SZY2V75_BLeBp$tQ(Y%dsJXv0I-#Os$C4#2+fJ*hs$Tr)EW^_E`|+bk zZ)V?l)RLzT>gqN%cPHL|n|^K%CpWh<-^7U%)mBGZ<hVLHF$w<q`T6<PZLQ8)QPI&a z@9bW&V#WOWf04PxF-$LBfz}L9@eB^0Tx(h2w4EJPcQe(<%gg_MR`%-Es~0*mDnCC{ zWSV++4=1aIQDbAH%L^|#k)sbSKx_Lp*B?B1P^~*#T`em++w_?1wzB63IPc1VmT+Hr zu;g~(`)g~XGuQo}8Xgx|Vg7%|k)__#17<9_5E~J(Vw<JRwuSrm+nbtBUFJ|?HTTxD z6`czgDq7w9`{Ci?vh+iocheMf7OA!!@0Z{H((T72liKGG9|p$7y;J$DCZ(mV9k^tP zeAE7{*@qL2FDx+2yW?SPaO%{lD`xJdSFT)HARt%&r_kN#VN0Izh5D?XTkU3NqZa&b z^<HPFm0SDk<??gJ{tYE78E$nvSr)OUV&k!jH}{u#P8QhtIaD~W>+S9BlNs_03pd`{ zwxVI*zJ2X-RUGTzKgja)dtui6t@zdxFA1KuFJDUTJbnJW{KW-D_j!7?)9<<{e5wEU z^Z4=O&*xRYbL6~yMPvH+;`kRORzgcopFSOYTWsmaXS4H92_+RdZRa)5yVKCkD>Tt= zX65T^Yo9zxxpnHt-SYc4|7NTW+g<bXlXzT3qiANLYGj|hy_~ePw79stzanVC*xT>- z>+O?lf;p$Q?FHRobM95B>o;#P(2-QEv!_mNeeFBj?BT8j3mkG6Tf8~`@9*!-$+E9j z-P)$n?mb;kaJ7XV=TXkPW>cn2S+HlCZnT=A?TtC-q+D&DK3KGC!v=#(W=XD55uVe2 zetsUmw`%M1<?5Q6nJH5)fUj~aE}S@b?%jL$&fV+IYq-?j-fo>VBg$ce(`1kIb8`+J z*A8EIr}TQPprGJmhq-A=&g-vF-u3*5WVK`S)YIY*Tk@C>h+JOg>s-0;%917fYk!-0 zh`n6yGxO1ob8|Mh&j<Upg{An}8A(aik{fd-Ofayp=-99J{m@qPlQ;J|O!oNv?5yxU zPamHn=6rlvg)92b+y9?)EN)x={dL=P{f;*>vwv7tuqx%I*m2IgY$oRBi#HtT45~TM z*vM#=VPazP<<ryCefF^u5{V%Hi5+xaK0nx_|Anc&{rq3`-{O9-USAixyY8>mFX`iF zgC#g>Gt$MXb>uUzY!o^FaM_A=>)iG{efV%={(ZZxxrIu<e*gAt-?VO>-!vY}g|{10 zPfuI8!7TrtO`6vQRox}k9}cqb-nA>Ga+kw}H6GmBCqJDvzn`%+%Ah(sTYL7ty?bT< z@x66Veee2TL|Az8#EF99;_BV4UXQMZ$Gd*ii`dZcx2U4R!pchOesu7fCk4tAI+peK zpWm2#{K~eYkqygR%YFR(rfEC-y$HH^`*!!Pr%#`LJuYA0v0O$*CT3TO=G(HJ6(1KF zJ@eHtF)=w%`}zBK^Z71K&hCLCHS(c3k0%Ij`NsVA#i^;<S+|w!AH;&{_n^8zAKiC; zdeWjN`t<2jjg?!rn0!nre|JZ5=JW>-68<Edx?#4kAwXF{fk8DUGBWdD{1p4MPPePd z#M`-<6t6FG?e_34oAdQT!EcXHLBCx+H;bI6a|z9rFrKztLd(El!`{8Il84nqcJ12b z<m41^NPq8_Nn1_k&YfFVS6A@x`@6fV7i7x#ImXA!uTAyx_m}s7J)Mi2`(x1Nw6l}G zA1UyAG3mo)fBT7-b=U0+ijDQHcHIB#mG;q`*%lV%?_@Ss1_fO@aG=5C)LiRwrJHxl z@7wmZ$E)-0+P(YYmk-U;rcGOw+ihb}`bs3?(B;dYpPZch>6y;N3;+2cqZ!p9Ay>c4 zyQTyLIiBzl?m9HVp-6M(6o(02&$Jy?4lMn+!KL$%fa#T<3jvQO&V0b^<5|Pvm875( zaoT*RQ_j*CUOIsn0yqzeH=TR`dG_8}?{nkM7?i);^X@tSwSxDS&*xRk&ENZd=kqtY zuRw>}b)?O*uirPx<ml0(Paaj?-j+Kj^h`-WM1)72s9{9t%?F~gvcCJCy%aX&Z)Q^q z|Nic7^|v>fEN%JO+1j<ct{-cRn0LXNoyXSQ-Tmpk9jjKa&P@D%+28)@ro3eg8jm+_ z-1uaXk%>u&tMJ#4kB=uNCZ13d;R1#3Tdz+S%pN^{e6sSF{r^9UU+>Cjsr>xxp{rY; z%u3$$)iw*u`+}GIU3{qE>RoYtU958W-v!diQO_=0UYJq+?TzC7X%C)$`BG9UyJ+G( zzjIx@b2)ru7TELi^FN*M|3!WaH}|Re&zApr+NA#F+{S{3PFn(<oSN?JmPi-zJa_zf z`}h2FN`CY0e1C^#G?ZDc3r<U0Hg&2fS7U;PzJB`lNj5u<JUu-<^XA(Fjm*2&d4~rC z2RoPj>65kI@`YpG1#8FZ>fe|B?R5iW?)8)$0F{X~t3F&1;Fq(xv9lPoNwf1*Vp6tU zb#`{P<|6Y4@88#ddg2+j>Qr;}lP6CW2qy}do14GhrT2=FO)2;KOyl&vZ}ScbSE*an z{4kI@arUh5yVwB!x62g%2iWZDxpwVZQ&ZE46CTmg(MfSzem*-p`=(Kqm6cV%ti5|} zMc=)CJ$v@-?3C!)zATTA_q+4Exw^jGrIhvH<YaY5M#dG}cJH>{`TBxTh0}W$MMcGo z1)w``zg^o|{JiSxtJd8&Z{D19{j|h|OP7KI11C<J^yvBX^u$ER5N#1IXJ=>AkH%|Q z1o$H(BMp|nhy-1yXj}blUF`04aeG(w9{+fO?ca~b{3S8l^X~Fw_`ed5uW{ttVp@J_ zxs1(1ZDtb-ZSB?X?(RPA_hbM6f3t1$weFujVLPv5;p?aq2iHb#*V5K5e}8Z8oH>8q z?S2nBk6Y=Az=d;{m;1BdE)p=6zV)l${-1=5jL*VdoP2zI8(M>dgF#mt1hl<sbctY> zTRY!&h5dr$+j@F>Z{NP%wa)wbjosz?NBU>Zlw_}SsB{Wv`;_zZm~{S$drJAba&mHS z<i1SmK6cD4AhE9Q-}U(Vxf3QZ+?#1tx@!CO?;V253L$Jf5*OCT+ZPB=iQ#m8#QyK- z(S5bQZ{4~DT1DT?&JQ}_QC3zqzV2u0joRd6J&x;t|Neb`j-~JyDM7)F1rHA$?G{&8 zQ*)XfvA?dis_NG=-`U&p?(RxH&bQ&izrVlv<!m@MX=`g+SABW0G5Pq1>5EbxctOtR z+xP$9@7&wl7EUtAn5GviB`Il{e2izyyv>`9Yq=*m&9|%lAU40|lV@h8Ci__p)(L7X zX0Lj#s~_+6Iq*%&EJtD%N4fpKACFD5uYs;&U3Oz%?Qa9!z{EWkar0*}ZRXHz7CX>z zb7!%-6r=C-Y17)uBDQ9Q*3{VCD!aF*($Uc|c$v?~uU|peSI(Y2d-7!ADwck?_g~)M zmtUKhnd#{+$?(TP_QK{D@f`Lkj_C*EVz%YnoTeKc0J@H5hR%CumE;fHJO}sdrRnVw z4SlNCW8nYdRKrP~?dlH2JNOn|nY5CRxA6D3xAJvA6xHmXZPpRhax^!*a_SK8g_sHT zo72y;U4Q=US=^qA!1gEuVVCX)?j7rH+_=Fhtajt}ZR54<eG9AjZ{4`jBX3{#^V8D_ zEBobaFO@nMadiZ35n>a~NsYbks+g6Xt+@7Luzbx2MsxosoUw|xZrxgNZ&B$Io4pGs zd)#k1b>`9I1&f@x`?|UoIs5qBxOuaYYvEg`i_NPz?lo?T2@L#rT7Unaf4|?G=ifUr zBQH1CmD6Qng2s$R{Bkx2T<`2EeI4fPe0Xd2^#hR}@xj5tp`oRpo_Kz#4Ga{N+m(G? zPowq%Xlr@c`Z(T0z1`j2ot+0Yc=-9-9T~*hl=wF%JUY@j!7yOgN%r;Ar%&(i=U>+l zw#;|7n2gLHP+w$Hz^=)YCvV=g>4M9Q3UR#{gEh7fmh72tUoYp&a&vRyVKxc3ix)2z zKR?II!O^hn&GYB&;>TYH2Pgbnka~fsv9WRC!i5<uCbCZqOFmE44tMf*zwPAo{OMCs zF|no^|G8GB@9yjbEs}A6_3BmLogJXKm^N+N@9*!uuL*p3d~a{HudnY8?uYF<8+aD{ zQ&&|zILC=~!Cm9Z`?qdM*|s(&3al1b!?3njy#4Qz*Ig&rt@@rBg|M8nYE>_3)zH%u z>)7vQtbgd*;<FbwEVx;9Vg3GpT_^b$M;lqn%E$!R<&^pS^V|FNlR@O2oyE(SEMXDh zpXs&Gf>8i;MoA=R{o>~h79w1&Vq#(fUAxwGn=J6)mA8|*YnXLKLvO3(ybGd9|Ni{U zn04OncTc5Ym-<=B7s0danKpmidOdD&Wk(^Wu7$Dj<f$LrY<zexd`#SRFhpsqY*?(D zTiZOHtW5q5tUF^a1PB_uPuRXN>D;+<GBr=qo778w9`KQ{C{UQiwrt~*q|ngN^Yd)a zo;fqcqBKy@;JLc*ESHdfr?l5QNFHywvcX5rreSmXdC<D<jJwB=AJ=ep_F&kxWz(ih z+N!cS@18zY6|m-hxG&6R;pyWiC#zr7>+9>Aq@A0atEZ>8V@JwKAz!a|FJ5@~_$)cg z)6B+u>g36nO;W8o-QxOkpl#k8lLO^X=Cy-X4-{<e3Oe1WZoKi%WZ4U#J1cj2Hv}&7 zW34P<1+Ak<nCfr)bxNW8*<(MBXM+liUF%N#U%YjzXmNl-pUN85eBDzAg?H6V&=eOJ zSKsO6&J4P*;pEMu)24}a$?!U{e=hsEM9HLzv+yzd(RVA?ujl9DY6@Bw7MOK0dwHi~ z@{QU>-wrGaNO4j+88R_9%C)%IIQO!Vxq13`=6!LFi<aEqQRuwg^xzvce&O@B-{<(< zh&dv>OKH!SOWqmNA0O|(ynpM~t<$DWySuyGzVubd^wURJ7H@DrZ})r6k|*mJWmE*& zzQ4P>c<!f!pP+?0GbAGI!`{7nmzbEiZr!@b$VjD+)AVB`4U>*^3ac+Tc+jauWr9lF z_Po0%CMy5^^M_B?$|U(1kH5eFpXivFp6D}2L|SIel-NFjfq&ASRyY1%$MSD&eD~&! zjF6C0XWZK84H_bxLDQybZSuX{FvZKmL!jgQeW{J?(x29>?v%JDQ~&p?cy2HI?AITR zCH!9$F*vy_=8-UPFmnC-_phnR>jl@VtE(3asH>}=oo>3+qVUU$i$AP0FD+^3mruI4 zE@GpT*518)|9*Xa{r&y@{GX2QUvcv4>hQv&*RO|%#n*kk8h-Mk#EXU)g@^i@v(Fp} zVNXj+W7=h%c&KHzdA^eME4E9^+xaAoTn=APXU*a~`r^fl%gg;AySuuwzA;<2;E?N$ z+=B-X`dBWH*=D#@fjxg$#ziHiS=Qz63O-o8YjkAQK637yU!{!p+lQy7YA<2hWVG9q z(f>u!ho8^qFAh{vR(=_8rO#D&{m6VJO~Gb1-lV5GlSCvN?F^Q&^UK*d@<fVC>|*|_ zaEO)r^8Uqcy^~Z+dN?(nEl9X<_TS&%2mfizw^KhMWM#b3qwNA{0Cau5<EECMC3l^4 z7goHvvGK-@h=~>NFV8eipV7o6esHRgyzHc;sVB@dHCN=8l$2aZx3Z1QxW<-I2->uE z$9~tURb6HQ2`%PkW<~LgY86h?nLp*nMMP)_t?v$$IUT#ZtaRsrQ>VPjm@^Egb354n zFgG<Vy}z%vB=uku>;Avrq>cBAoc1s&DY3DLT~+Xjjop&*USV<Z;r$ohIGk15$S^@` z^2`X8!%4#Gel40>Led%=*j~MQ_3HKOM7<4{IHa6(7jisfeQaO#rK4iL<_eepqJdo; zb7#7GaTPIasd;~I@7XhFva+&vR4N^BU~KVx_3G8BkHw!qe?F-!(6-%f&b-H*u~GqZ z4c<BKTf27cqWZI;U#6+0UW#0@HT(LekmLVrFG!o^M0j{`glqsE7rW`>$9DO;2|)%+ zBiO?Je|UJ<(K*0ox=y4~<)@Tqe)kR>H~`Ay2lDs-6?^LN{(!Q_@pQFiMl(BIjda3d zV|~-Tnwy$VojNsV?p$UjCY5JRc?;JC^mKPeZ_By)>FH_L|Dqv_{%ie)d4T!Xs`HN; zEozxlbmJy$_Gg{&@#M*qPn48wY-0SIZhvUe<MqkBbwFFlUE<}%#q1~kURvrMtM}o> z#l>58EbG<VU+|Er$G5gDec|?iaE(K|nwBizTDok3&`P%#XLN#sCP*K+_U8Kf`K_(3 z8`mvKPfaxp_u9&pQGM{>!3vqSBW=9W78Q%SEQ+3RWPQCBov-Pi=G4;1sCaQ%qWEL; zDJ8yKD#yRgT65#W1uY+UjYC_6B%0a}tz#5gUH<-F?XNEv%kE72{QSH#r-S#mx3{Nn zb~P3a3<+uJy0~0c)j-i{`2w@h(9q-k^5Pw_d$K+)T)cAS$vb!M+`1LzuVW;)tmo3D zAf8Nnd;8dMm*^SB>3t5f1+5$J+=+=YDK9U-el@LFRYOC=;qEg3`Ri<Et`w*OZHdYN z9R%OH)yK>0(h`Rr-NtE)IX*pDsPyjseti)xU0vPMt$Y1%2NbgI%+AQm<KyO5E|-1y z@L^Q1%Jo#xC8Aenn`Te@l(Nj}MP_DZM&E@C7ykUIv0_}Z@cORG&(9Xld3$^N=1^xj z8<WQNc6PRu)YPTxv=@n%l$6}Kd2{B>nH%@jZrHPDPK@S(l>hH`zrUe7$2DL|vcZf` zAQPV$XsfHIzqqjQ$HvstVpl(3yL$EHyXZw*w|#zo-dNu&cYcCk$*DOn3zu>qHxf;K zd1WFue{J)d8K6OE>kV7Y)hyZE)Zz?`jVG^VdVg=Pw6wJM?nuyr?LVLWw|QM-TVTCv z)AW-n9H0yAMQXmSUcb+2aYMJ_htTu)u3UNY;>C<Pb981poyg0}<EwQP@_qK><Kw!z zx*)yE$o4lM<+m=-=$`i@;UR;Sc;?)1v$|>(t<@$^nq;so^RsH>Y{Qe1A$OiFR02(H z$Y0gb(YdxZdino%9p?G>bOIDFZ1fbUij0)3eZ3%fPi1B0t7#jOj&emME!JfD+tC-( zedKc6BbmtP=*yK=z8gwjUJ_RKi`iEbsUfm$>(+xy6x4NHSbX}mE9QRqP|ztZ&N*ZG z`I+ltU3knU-fC2TeZp01@s#5dhg<nvr2^TaTl6MLPWIvLyKA^oz2Q?za`NTH?)<#v z>DR7bKR?T~d)B$zw|_r6+MRPXVD*U;CjwHF=XnZPRYuIQD%JYebopw~dCq_imj8?D z|Nr9_*IOd{;(_nUuRnfNoLyb@<HN(P+1Jz3(|`Z|ogCG)Df57!ph5cXDF_#JamI#y zoPKJ>i^yM`dako#7<HzGUsL4yRerFEb?Vfqvn(toOHE$5a3NFSo#Jc9m;7VMy<ytg z)4<4MeeBe!t|%U*3k^+$>*M#weTX;TSd=K#;&-rFgJ(h1>gPTlB1$`7Tw5!xy-I*< zrctVwiwlbf<1F#Yb3!MTOEmTMgbe)W8^`YMcye)OdwaV_W4d0No9p>Y{so$so^U0s z+!Mr?xbNq)*`O=tj<hu!=N((}kKt|4_gU8E>vl;R3YERT=bNpQmX;P67+A97dc%ga zvr-{;ii(bvMvv9M>@I(QscO5!n>qVV-#&IwP$Vi!FCu0oi!2Kp+aV{=DiLNTrWZ;Z zd)6Emoyc?22<#Gr%?(p0Fl<}i+}wO8Ni@}j!|8d@l9Qqbf+}a`F|>6#a^Ih2ZSgqA z=M|@vl$63!Ha?jZ)6#esc0XHc*4UBSre&<Kz&x-%vVL`tL7mfb){;$|gMx!iHN7S} z9eL;VbdhWKiU0R+=kK38Z=RocXKIS=x{ef$w#r{~Ufyb*$+|rzCg#wgLn5N9H5NMx zSRGgL4P($g<-OnWZ@}|F&oG%eg~n=M*+mxY+_fue>XD^Omp<wDS15b$8uyb&<n(lX z@f8JC$9`~v&Z4@qc-yvZQgX6kO9Uk6Yo%Ox5V7PWSAuJ$>V9u8uVuco%buN)JS#hA z=B*h$ot+17dy2^J1g+dWeR^`n(~O8etN;Iwn9@9lGc6@W!$0j$3*X)LU!_-9h0dC; zwpu`Pwbqft0SQ6LlaeGH(oXNaed*GqY17zNci%dA@?_@ob8};Fuq<p3xcIYiqVTW9 z?)_C?U#SYX$ET<oEnMT2vSyV4zjLE!@5#0{wmlCHG%_z;_y5o5^MZncTQ+f3R8>8D z{#<%j*g2NmOV$-17JN!^^Lw$}fBrJQFqKQY8J0Pv99bp6&)nqM>v?OP+e6#@`}_80 zURLY+sVUH&G2gOySs+{F(hDIXl7XB(b1no21+7?q`t<3WT9a1_NN&_Ra<~EH?50b) z5gQUdJvq5y&&###Jd&HLzP@^Wef{fQWw)Ak@3xNn{O0E7Q<Ehv7fwE|RQlbrv`f`{ z+64onywHwz#)BfqQj(LC{rvh?uU>sbMv$xZ{hrT$fq@eXb*5-D)=IoE3D{~VY~?YB zrDFMP^Q)|yE^h0&J{l-Uyq;0>=SN{^=+#?Wvu$l{Uz%_pJa$aY+WL0K(&-{6!mF46 z{_+npZZ@~lN94Km@$y`YD=T8+Zr@sPP1)6Di(yjs)fNUtg`^GFG*-IrQH{tnk;=`@ zo-C9b8@%Fb$FwNbF7|6%a+;fNR9sZcy0YS>W0O*E`l7%dm+#--+9Vq7pJ|(xo|c|g ze($_|%D21UXV&(&zu)uT+W38PkRxamOke-}sZ)naJKb*bST0$%Oie{)$&w`^;^O8e zCM_3cpMBQ;bBU4250y_bd#kptS;MpV{f{3N|3dEWDm{Jn?A=|ZtMBIZ_x5h>tG2KE zbK}@vpU39QU$V$<UbSe^q7^GN7CK8jXj|C1Vy%ItX|&4P0GC&jw{RLe^DWx;>DlCr zlqH}AV#db8i}M$rd~mQ?TrcLwWq<pR3)R_pBpSX<n<iE(d(hzDuh;rn?E5Xxs=ny$ z?cH1beOux5M@PHGuV1@nW^Qg@{q4+)qE;S>&3E=ze}8lo)a-b8wD#SdoojeS5C2Xn zDfu!*GuX@9d-bYS=jK>mJ}|*OI5^nX_w2d3*3)&P-EPmlwId*Yx&Qood#lSmJvr5E z*YEu{>xEGR=u(xG4?BD<a~;CM!<X;3mteZZ^;OosZqNNWYC<K`Pm4-Qb{0K<@}%YC z-K@Kyb*ZVTs<ty{Pn>x1;>E<0PAC3*>X$EFTD5w0<-}i)`|WwAoVf7l`~CXo{jXoY zzP={%^49F|mk#^f`{gF9`^W9A`ugy2``>@RFPAO9U-P-wE-%4CBwg3u{(ipSW)7=o zB8G;B8eh6ZwGX{4WjMUE<YmzRe}7jd_Ud_e9Q>W)=*T$5LnFxN!c%3Dl0}OaDVdo~ z3rjZ3yVLQ}dY09K|5YBAXB1x_d|ey7G55CFmGX~|j@A{=a=q~R)2Eymj*!=PUR>z? z{QSJTyL<V|ORmqRx$!jB6kS^4sbrd;&?LtZ<j5YN;ZrN}J0&+)cbA&Bw)ba0b9JNg zXGODJF3g@aE8tGu-(M^5*mOVa)!+X|NO#Wc+1VwIPHdk}?$}|G(H_!2W5Ma;ix)6= z39dS$UMSg+>*dw;>~Ef*M%BrAw$*>0nY1oQ)@poYHP>%3x6rl+UN?7_=ks(p<;B-8 zR+xWe$-TuAhK|$w%^i<VHBwV^o9TauW$)$X{__(`_HxcNNMw3d{pyP5e#>6*FVpqo ztz`Ii-@SM1R#r*mp_xBFKR>Kq_U=w*iK7$4J#~ILn-_sSAjiyJ(ER32PO9C{M@PFm zIyho@erUXX*!$<WNw4^q=<Rt6*R0?7Yt=<o&f+Kc!#|!l(8#RrH^(CF%#6L&-`TRd zPj1~Lf3?fuanS^SH5HYLU?sH|pFS$Skgxl(FlqjlbBkZ>$k_Yol=hB>lQ-`jsBm0< z)GP6Xgqy*Nl`9>spFe%7X}tUdkN<qTr89D8314xa%_Lg#>Ey%1?bR@Yq|Ng}-b@zJ z_;F`vF;|Xr_x}I?q)lZ_GA7J9bBy~}r?7fJ4A-@z9CBK>XR`eL_xCqnyYq}k@1}Tn z?KH0bmXmp>%IoHq%*)aFd#BEur&kqdpsJes?95E#v@;Dok3vq=e0p*+c)4G%lxfzN z7Z;cN&o3*EKD+n(y=qTS&)(kNLpfhU6B84QiazzpTHl!?_WAy`>(>{1Y)(5nN$jNg zm9Uj7S5|S&XZ`u>^?K3YpmmLj)lW_cvTj?*%6f50!{fTdraV!mtml1we1RspQAGzA zh^8-)o#@iU*S^?c)}<9QYHmDb=a<{DQ#9-0_8Hd6JWb7K&YY?L|5sf7{JC?_4i`<5 zSLUxh^W?$ihuVK+E*X|CusD4vzwo2NYEW0jG1}0P-z<xz7POdMS6@FoK{|@%%LQBE zlGO^E=PEwkUH10W*|VZ+8$W#F{dn|&#|)=#1G`7pg8f7k?Cs^Pw51k){&~ORac}3` z51m`Y+8HfsWz6&D7)S^GP?%E^D_Hk>vB$o|rgi*TEVYN*csKlgGTC3`Mw{5_X}Zq7 zr%#=Fl9JYxC;Dfb@sgU~-`;+aD+>*s`XV}RpW!LBg-7nI`_J35ZJU~!+OC~~zs}A! zw>`G@`StrB#nqH5pPrvHb*iiXhQy)+{TEgqkVx9TWy^ynl9G~#a`H~PIR4P>atXVn zbTU(0?ZrX2-UXLei>?k|AC@2;wV*a2_{WktXRe8s)CqU4SfP<2EWgcb%TX44mLFfQ z$KS7fK6jmr#R2!1E8mn=$Hd$@Gt=1c_4hI@D?KeOp<Ay4;^p7^EH3JL<LZ$gcxlq< z-S78xZ~OK0`TV<gl8rq*JzHB_RaS0kv&+7wldt^c<>lpvWqjG4UvAHPmn&EU>iJ6= zr_HgcG*VS%UH<Fs_WO74I9W!C+Ovxaq!oL!#Qx9~UAbUEgZxqUD`8d~zd8h!KRCzN zd}N((lyN~}325ia6C2RT=Dw%)ZZ0l7(q=r1%{DD^dAQNtdB5a?1GZIP98QC_&K_J> z-E8GpZZ&s<uAUyq+ZV3MZqL6zZSu`mO??YBa=#d-oDc}KD*X8=)qMH0*j*(rFE8(( z%*_7dM7CA_r^EdA7xqd;{rp;?<#i;~QRA1@mFvmY-b-cv{CM2Yb<SV=u>_y9|5nY7 z4G!<KR=Jov>T7ClEZog~;doaUSIwK-+w*H{ZNDD<<#)lCckZU{{+~a8n&o*r8BKY$ z739uqYopEU|JB^O!27sAAw0f!LH+l;<r`wRWK4XvH(yK6uBIdF*pVYA&g7Rm9(Sy+ z-rXy`ocr?ovQJM=3ajk<`|Y;J6Y=_fS?jj`Jw=?ZKQAtJx9IEX`BJ9k_2%a0=kD^g zPt5!-*m_x3d_HSF)z<OHgM-aqzI<8e+<xuKm5itl|2e`P+udD@5-v6Ozu*6VU+?Xx zZ3}}Fv#knu#_%%59!ofMtoQOuo1nel(lpeW+n!q-d!lyZYPj-?`}P0#_RfyWxcl?j zqc=A<uXwhj@Nvqs?YkB@r>|bUI&+GO&+~<)LbpClz8^1tDd(}<%|*dmw{E?dGIQIa z?-g2Bal6ZMzrVZt{_gJO`xjJCE^^vcmFM^+#(BBurO?%3i6MP6=l9N5H2o1H(a3dK z_h8^+w~L-js@`4<NMrNZ(<}XmW%s)*mfHXS{+i`k+n=qzA5!!C?e-PVCaHRZ9U;uu z{`lG1*@wRD@_W%~HF3dX2dx)2d#k=K+PLR<aG=r^`6j>FD_&~8kSMF1T-3%<%d&UN zmML}JZA{8;Jqt>-4nOnz_V)Jm5C5ZN<mKxh9AHdL+uvqnd?Bt)P5jGZ_x?j=r>1Dm z`oDZemqYoR4Z9X3zp|?RRU&PEUUXTv(d9|pcX?PWHh4~pQMh@$Up_x8>rv_b$18sv znKWtAJlpE3Gr~MG7O;2OHTBgsn%sU{R`pdd&hcdkTVR^koh_NdYE#Vg@;Xg6^E=O! zG?=>OXH8(3_7x5*U8{wxCjb2nMQ5}uoF%RoGhycaS55DpUGslo_vz;5^t*QXUEf|` z&(~(>TVn3I_ixMb*^Bb@UKEs+Y%z~Mo9M0g>Eh3gu2ELo3%AD^Y+vl+^|37f^3$Tg zFHb&w`o!ki^zLoh>phj9ca^?QGydxvsLfGTU0v<s!V=>2PcFsh!vAKob&FC<CLZ9F zk3M2CS1$TU<Cl%D`SyxdQw@p(11J7#@{>2+uPNpCLgxi&lixA-_a8bJ)lFPia`{}? zmY#JE7i{NA3b($yyIWmdz5d(HbjP(u2dBl<6#x5EdBt$S-N|dTUxX>&=+|u%esff* zHo@GrR``W%pt*3#>jj^VDtRAdiIu;?QI(py)VJWZw$4oBbiP*|oO5b~)n0@-K3)BP zS`+6kyA^^ZpF$6Bzs0Y`%+BW`3%c~?r<%`&wN0na?$luwE~!me|L^yLrAt{wWegG= z9Kyg-Z;N%oQnQPHCY+yVyW+u{o12+8B{k)VMp&P2hnQLwQFpkFch>iPo)H@o7_~eS zqn{-2S+H54<ktctmbpt46knLAcqqPLx}|C(B59T*p;hts*Vl$MJ>n%|DpB$wY@ORg zbUe1Sv1odH*^+rVq58!I#k1A-dG741mEQXL{{H#}ZO6EOot~~Q%h!H4FF!ZebeGOU zp9Qm>A|#=$icV0gqJ2Sndb;+vlUuf!-1wBpbBL$vdd|5ymW@(U`Y#x!XH2>GvP3F& z!iJ|WFE8KHZteOx@keV-(a%p$<)(IU?yA|tx$E@PuHN3zH<LR%J6|k#_AG5}^*xab zY{Be&G8|Vfh&1`-??|fq_~T>p;?qL&E=;R?_;=oxZ4>;D9Y6m6(`o%6!=xrX`TVAR z85fm~+I4D%l$4k(3wZnX?X2>>4{hrI?FnBWCnzW=(rc^WqxeEWU%x-@iD+v}`U>`2 zEbos8ym)l9+ikk)6ovV7OfrLNYxjD9TS|);<lo+=Yh)C((f{85dihvkaq;Dq%V#ro zg_~A>N@3lWCiunv{~u#DHMXmuT_jWEGcV5Zo~~yp)Ayl{RoUZ%U1UIj!le?m7oR3_ zRk^ylIyp5-&EHe>l<UmoNt3p`Eu8Go$O&4(d*GT*6JLy;xZbT5o_>Dk)<$pd(epde zywfi=RrP55nG+{oym(=-%Vi<^`^lM^nOCn~-J=3(6b4)<jE&ix#@pH*_;_+@X{m*C zRn@L-cXNf>_~rX<#qKWiZCu;QB5Pu179^rq@^g}^cUE@x?Af#D+g7KQ>~v!5__4S8 zyMb1@)!daUS8g#peP?HJq_kGs_meADtk|<>&!tP3R;^lPoPJJ1W8y;B;NZ&_7rPs3 z#qX;D9oT2`@ub1M6HkxzO0T$eVWIQXnX|nw9Gq)i-qqEW5#jRT(2)<_E7ne$Jo)E= zYdl9iYA410N;u(oC2ZD@C#R-r7p_{r@0Zu)f2N}I>wamj`u6d-ytc9V+y$3?FK*km zZPTVrYu2nea^%Ry<l|D0I~6%tZ0+poo}8F?^ypCunT^(GW*w*r;yw7`<eWJ&bAH~~ znEc8=)$Gce?G67K!D}$)RtJQn${&wpj8sT$2y$XJN^Q}-_Gpr@g!o2L{R-wzfm{P- zqh*B#9BF5iP8Rw|pLLlzLq=URU-@1`Pq%`&sHsk=kjjlsO>Bvelp<N)f4}?u?Vj`< zFW%iO{uVj?`RC*3;?7l`dvE#N^8WMR*3aL3mYBQ1UTDkq?YD2=UaY@VmZSNj{erx- zS-<_aFdMSS$;qvFvo?Br2D_3``1&~2*aZ)SW-Q=V)Ya|X!OzIwWh4<)@a09I$%&=j z(=YM46jfDKojH3pHz()UuU{F*m5f%dTxroU+dN+^hDo?&uHv^j99G6Jd6X5+&Bb|* z?Cj>1DNHJUc!>4Nm!snGOJqAveEI%;_pV*1QjE4n>Fy9vdtvqY-|zRu*V$!dWM+7# zOE9b1+gTiccXxN-<(3wfTa6uOetv!)xc<Nahgz=0rghRa)#rSy4p%5Bi|5_m)?219 z$+_+3$#dtH$#$IJnBiEW;d7z1Isg1j&vXg?lm$(H{?y!R^ypi^UOy`;I@;S>z_2lR z%eHN8Gw$pz_n%)hW5MeK0bm0?0yIQ2x~{K}UoP9R<;#~Z5m8aMZru3u^?Ll4WWmY) z_J6PV7=P%T_te1gdgH=xb7q#b88Sq(&ul(wY&cWeD>8EC%(NpWw;DS<>+An-$-JCm zH1omn^OiFfWS{l`sb(u(wR-hg6XtUl_*{xMZQ2xYxu=KcR%1t}-C=FMCeB^kdQ#4F zzKEUanSLSZ^fcX!me<$TE|%?hvLZz5%9a%?I?5E1gd`<9y`DaO`Z8WbxMXdE?ei_S zPoC`b3Fy|*)Y0krZD(pawQNRD;Hfo{n=deRcXwy9E9ut%`?<Wgw|DB)P=9~^w-GLn zzrDRJCMI_7+_~@X?_b|<qV^){;LXqd_WyQl-aOe}DJnJf>5jt3H>Q@b>0WrXpzzzb zZ)*0-mUT>5>tQ!41}$XKSZe54Z?WO|WOaYFAisSFrDd33SZwD>k<FVM>zOVwZ_XT< zEyu2|4!_LjQgrF^<<6ChWIHnc{Cd5<Xs3)9(?r3g4r(v>-PeW{2c2_#w&~@I7Z2() zKk@e(_6W$!%bU1HaNTP3;9L0;v_OVkN$T~rwa&eubF4RVr8MbHXlQ5%ED|&9nYn)d zKdH9@UhdWcCmYvKI+?O=-8wa64U-tlJ(e<7HM=5GjU2@}cIxjce(rax(ZEd~G?ew_ z<>jMQ4u?+M+?dRsHEYfsA8Ub&C(fL4=@k+dcGa28xyyl1-ma%vP*l{_THx4=r=QQ; zyDNuiO<iU_;Y|Q&5!cO2mx69Jb}+x$xp?v7)>hZ#<i#CFjU2^2qN8UoUAlDg<jE)h zoA)QqF)=Z@aqHHp6r;%(cd$2H=DpQ^`E1HFEA{a6j~_icqC1UqSHYpfhYLN<&9QX0 z7C5$I@#@v5Z{NOs#zoyrj_aiBy{gx`w;DT~i;FkM=xyJ$DJv^WXnTs<i$jXxv2G`q z#Pd96^i-S~61*_L;bvxgGDq5(8I8ZLUAc0B&qZdMeth4nB}<lc#2E>fJXH8yTwLsY zE;=?=H{t8@`E^zr8Yhk)Pyhe#@2+*;cc;(1S7X@E_5J<*_+2HMKaYO`oq*q-%<<~= z>%wWibFHqL%*zKI%QwR?Sw=?Y-MziqRS$hGd~Hf;s;jGG(tA76{p`EDyPv;*ukV=g zzm~<RD~Z$R!b%2C4n97$dha&93w*~N*2M3RJMup$sJ-X%hSbwynq28k>%=|kmix|b zJG?pZFk9?()uz7SD@TvE{y%$Qe^F#i%$t`lJKyBI2tM{idJAWK{QV6ZHe6or|G7R? zYpS84;l+y=r|ZQ!1xEb1v$I%KRP^$4|N4im;;UAz+Q4&9KYAOFWp!nxWxe62;Fy>@ z#pi9OPoCV||0mwt+gmUwC+AH@#fO_WG<0<4SQIKrNyoi@^(v!1Ss`Jnn(wTX#Kgkq z=VWhf>|pQ<m2oUD|9<aYoaU+Yrgi$JrluLWCl>a}S}(iY^<)zFujUIE0*pA$C^)+N zuM1m!vG4AkJ8Wycr-6?2J!#*@zH|}j+{j8Xucbj-w`^JPVQ2C4LpLX03ebscs|m?` zAa>aQhRi<qR}J@)0u*1^oQPVtZXMG%QD=#{bLVn$avII#iE408kh-)?)xBTNb?tPW zNGEFn!58n|wM|)U6<_;xs>|$zCOxK<4?)@4ubY~f-d=z7MEcS0jEhSD%%3RnT)fQK zTfo0N&(rhdqodsmH#f^zZT~YxGq~wr>+ehF&-1T0c<|(LkEHRB?uXJlDn1Fn4F9p; zPC=zj<j=?B@{y5|{r3MXq-LyL`}W*iYv0FKo4y@*H{*=MBu!1t72M~PU-BslmlS&V z`5jv*WnK0reSYn-rxzbRk=C2dp&D0RRaN)%sd&j_W~ugnpU>Mre(b?F*T=pil<lN; z_@_CR#Zl4G>?Y-xEZX~wS?(W5`v2v!zs8@b;c*Z3%?wlmAN=o{a3adtIjQ6H*6iz- zE?tt5k-4z$%-OTaNl9)ebp!0~*Z;TuB;@b!FZ|-zy12bvA@@$5^7^0IDaRmOQs~fJ z{eJIvkDxsT4-akIwyk}glitofe?FbQQ25E9x~y!Q)54DKZskc{>lPkAcC7Eog~f{& zZKz5}c(6e7f~D)a)vFJ$H%>p-)7NKL{%%gtN|(Ur=jY2`h|y?wODIlFP5pC}t&PL# zf4ERkN{Y(!N0LgHZr_d$3<O=TR#90w@!>2*M(waQJ4#=Ry}j_F;aLA%hRH700<|w+ zzg8}ee*C~|m!jH>q@q_>G$+YgTU+Pf-xquSx7?Ab2l$-*UAaE|->`cY^DJAPmzy2< zmu}v?dE2(K`}=AOm|x6(T4ZS+-?e@F_hr7bCoBr&>DTM+?R{~+z^Syn{Boab{0W&0 z2F^kKk>^=rQ{LU#xw+zFQqom*zd1WfUxyuZUb%Jq_V(7+%8H67&!2ZoKRKWw@MYb) zb>7qUWbJAyK0iC_>FMb`O^1_{(=qPRvuDqqJTb|;vtwiO@jgjowsy|-)22<^wr$(D zZ{PfFKDKmsckkZ)+xWZ<^X#6zEOSFwhD6BD40dulbZcw2v60cHO`Gg~J`uJ!Zd?8B z&E4JK4>U3#?~`>dulx2UGR5gc<Ehi9C;pl;WlGKGv*s2xzrVjfKI!(h-01yve_vf) zt*oT<=kH(8`j}gs>@2b~FSPMW=iS-iSpEN^`<<Ec8kg?e`Ew(=|6#=9P>;R3YA+@g z{QUH^^7FHao3GrtQ*&)iq{YwIuU@_Q<v7`WZP@!;TVH>@9v`kDa^o%k4CZOg8CJR% z)+-3Rhcg=YZH`^!epAkM!mJMK&&;~Ne*JpDS+EAQ!=5>(k8@Xu!|sI--tYN*ZnD4K z$+-vk`1p#SpY!$gJ$v@-+7&B)yxo5P$fO_t{?(-v%gV}X2=_f`m#^DV_V(7%ZgEB7 z4ZW<atm*%jZrC88C-m;?udlCteSOtF+%LS6^!QkBfZM)@t?HjXf9~$;I&`n?)M3Zz z)27w^e!KmKWo~Zn+_`ga#HKudEc$+<`~umvYu8Q?61j2V0>kW>=;&_Q4%@b?-{0Qe zUj039M@|m6nysqp)3@92*L^-~9=<L{QdpRo+rIwapPQT0*;!dx+1MV*@bU5S@$$O% zZ7q0s2y|VN_o2Io^PfF=GRLBjshv&QsIj_MXk*q@E#tuSx&=qu<?A}S6!c|GB>P+p z9H-9#4QN(=pJkdo#p`K+J%_So;-QxG`L$*$Dk%q>SWi#WZFW#mQ&Uq_b!57*=Arq+ z2MahZUc5MQ;>2z--C4%zd^@MUdiwO~yLWbVe=0hr+xcC-b`3P%qQCcxkQwjl8T04= zf81|>>0WMB;nP#1Z^X{^?B2C2X@Bj{r_*1oZj%kXmT*{?W5=SS|7uPbetzaF6Krk0 z8*~IznNC$;WMt;TMw`wAh8YXETRw+9={1x8SoQr~Y(+{(T1|~jjm(mmBU9#|5qb0G z4UhGMhYugVeaqWzRs787#<33{3R2h}N`+{NzT_9-V*SNj!ghEXTVcz-_jh++w<x~% z>sM7sOG}rYuC1+X-misi;jbQwvE_QG&sb1=VC#bobzd&JZ(+X39Z~ejTxsR}oQH>5 z<{Eu?udAzjzxI1<X6DP2lhyfUtyp-^o;!DMYxebdw$=N7JmUW0tMa>GN@ZoGd!LMD z-JgoY#Kg)<%P+5w^-BBt`mSBOHa0f)SIn-L@80F*<g8h>>d>}Jmo6zODLqKBOr3uE z>H2-YvH}AqPQ1g=koEq?M&`)YnQD`d_9>lzoZaklSU2H)Yg-!|3kwT7`((lCCl392 zDE32p(?t<EhO${RpIL5n|NBrZ<@O2=nW>7)<rACENyu%D>RrdGHuukVR-c(hPahm? zF46z}NJU-w_^FglM~=9}<}-Mh+&Q$T^7D>~v7X!A#h&qRKM+5$cbS3E2Xn8bLdV7b zn!JtpqGWD<-KY3G5Bv2Aw^N(WRdDRxyO*6$Mxp#w<Np2jYZF&4e3p{;?&IU*^KGlc z95{t|w?BCM*7gnDeQr%Q>wEwH^f>R+!gJ=<Eh$k)uiOW|#*XP3r&k6qKVdJStE<av zZ*4Y5|KqcF@80q9@*d)vn6ZP^;!C%<{-p0mcJdd!@ZbP@wT;#K;JI^rJHt~`Ro_Om zG)L{&v17r)b&;EoeTYtPI(MOQ-@biczLb0_NvNsWqnLYTneXfl^Y!c3i^p`h9M(PX z-g);#+m@D=34!v6;A>;u-LXacRwD=dU9(MwSD5~qOjT*-v~o_L;4vvZIc!}_<_zyw z8=e&HymRNyo+V3MF7bL=-C=sn_~hx+nVHKHt4icUT^@IKb}E+7UNWQCLwd#n<CcPl zhgcWAjNYDSdf-_{dGzkGwO6DkmF!?W=COdiw4}sja?yeU<_(39-9irDyZ7(e+1Xo? ze(*Cux{H+tQ}4?kU!N1G<lT8<QpjY(Og7)s6ZW-PFHxE*CE|4@VwS|pEkQNQeT3Ck znnZe=^qK}6U2Y2K^1S2`l_PrW+Oyxk&)8lzF3;J&+vfYc-zDc?^MAf`eDCw0bDqz6 zUTgQ<=6MaDU`bQMljqO<XBxRWIyzoybdTF#$16U|wz@1of4zsk%K;{fZ8>JrOD>!} z%e!5-Y4YsZ+*?JgCf4M3Ias?~;A|>>aDdSyM&r`zhGf3*&b~gem!TXx9Hc*IWoMU{ zmOk9(>L6!R(Xec5$MVBgoFEOx1_lQC_iR=iUo?B#htJRbKb(E~<jJkuw_Qs(ncP;b zS|uVXnwkQt)tYaMF|J&*CL}Phak+wm0>gG)mkXSS8pQ%S)@|n5$KSm<dwRzu^@Jt6 zcS~EcEL^y7N3P%mas9Xj7yrM#z1{mzP?pjQmW2{>a@Q_g2nYyxkUCk7(W2zVg?NE$ z%?4r<?A_hnHSSE+4*&P#BlC94rVCfDELppjH!@;>-QJcpElN#(0%G>|_A4%*Jb7}F z$DMok<b?D!H3eNCvGlmOxHz0VH_!I><Kz81as^wyzrVlu-BJ7hf0SR<c2u-;SUE=I z-Pyr-wd(RRU#Dfv{vPr1_g75TnDu8x?EF`+U$^cNW7NO!XR+$>)YQ}+xq>V!CUA@C zH0Z2}*yyyVsYB3ForAj~B4G2%AFWKEzrGGnPJaC2MTXZkc6N5fR8>{gSJwRUb}_rl z-fm1j-m*uGQQ6hiwWz2lU{m<In1i|93MS^}(vp&mf5pVaG>*)E;=nT3fjJ{P=i&0X zvX(_Gtqjha{(XBJZPC{L+`ezh;+-tU>F1_wS>AEL`usdw=cg4vJ|y1R#^DqjEBnec zDl)S3#ombq0*>kz8n$jV4JmxM*q~{$-_gYD7cOw{@U$=o2M2#RweoXfV&aw?J_7c< zyu6#!&N>x4&Dinx-eULu0F%rW6DI8}R~9T`;ssqkmQ|UTx9)>ypx>_@Cr+FY_&#T$ ziJ6(w{c8sgKK%Xt{f@H_XCFG`l$x4q;u&6auc@zz!>W;O&)&TY7sc<b3jML<fM<AU z=v<ErCtp}PSAKrhyKbG{r`-0owu0G*&1cS>$;HK$uz&sf^%ms{kHnQ;ut+Tkyzqba z4NvvO&v{sDife0YH5{X(Z#OnF-g)-HHzr2r)^Bqgo0voHT^$RAGY*_S&AqBRD@#jv zrSFp^!r$j~hJ=JHD1Wv(Z0)2Kl689wEG%9;e8_mLc|r4<$7av}JA*=Y-n@AMFW1NJ zb_;Jxo?G&0p7F#(hn%*|-M)FV@#C7$*RF+eb90NSE9nJ0odty=!>1(BW<r=^z84!$ zo<6<#$iAJTx>Kf4U(9K_Y}vB)aeEKt@~sCepA{An6XTOS>yDpQ;rW@YC(1K2G_-bu zj<x%-<8y?NkWfJIk+jYGYk#-hma$W4@>{^Tg=f~i-l!d5w{)yqx6U;Cn!`#>Ev+t% zL;Wu#WMsa4{OBm0qO7E(qS&AmF91qyKjJlZ*}q-C=g{H96Bh`7pQ8!dRyZMa*REZM z^i70~w{G3qEvC!#c)9QFX>;fH-j;DxXz~-7*4M`;mY%5oR#RDh?vCd@40CR7PCxHA z*J|p~&W_(dKd0Xj`^YF!|LlyU$>o}tmzFNN7aCY1;5a?&!AfrrkAi{%0|SE%Tei%} zu;fn^`EVvXD{I#5+3c*KHBN?kJu}K~-MaPW&6|ih6T2o%5J=Ny$<58(x^ZJ-;WM?i z)>gyQKLQ0Drw4(Kw|;wj`HB@Dol{n>)YPj@ky-q1>dcvub#->{l#aTEg^6_)ELy!f zIx4E`w#+}!Vy)m{=Eq;ZewCCuJzZMq#U+o*%AM1uiG?J+P*@+mozH6a%$YO$<?Z#9 zKe&a4UVVFedvH(?6Em}~kI#fP?{92$PI9j4;P{XmC?S8~?%ltqr|a*~eZ;&$%y&EM zw!FKi*4)$)c4UctrJ<+imJB+>W`E^pHPxW2SFcK_PKvat{WZmEU;Y0&7Z;W)-JJaV z^E)`NH+_73y#L0H8!s;}cV2hU(!<;PaIT<yPfyR1Wy_T2yM=~MjXdVhCs^`w(axQc zr3QEJ+;QmK;o8Mv^}c}H>d~jCr=_H%3X+?fn+wG^ooJN1H%ZkyVvghUySvMcPaCdZ zzdn9%m1)tLh1D0YU2D6oWTn`o7rSG}4hP$98#hWWeU|ES;b-ES1<anFo)^9{_E!J< zWBIN~Omsop3a*V7`EA--S_RQZ*#G|ho0yoGadg7Mg%9I@-fHI9B@!4K${HFO8@qSK zii|aKf{xGU7P88M&QtFe-p*1Uc-i0EyL<Zd>1)>Lq!gT+V|k&<vq<FT#wSmoF6`*P z@WRc_jgOD-(KZhi0mtb|fBybm==A>X?(!HzrKWS%!kkuHretMhJy=p+Qu07A_ZH|> zWHlGZcZ(J;o+)awapg+RSrJ!OM{G{xZD!ic!5~<YnV6E|;_mM5=BB2uo(?zVK-y+U z3()-#;ugGDu3f9Ds93-|cj}ZWhYlT@VH$Jq=1tCb+)~LGuU+%=_dlLH@q}WNo^H*L z4~(m}E?f4@#mj|dZn>J^mkARDcAUQ;c_{Wl)92sc-yb^UlqDaotGjl^3Jn4GJ7pgk zzbN|6wK7dU#<L+lGSbq>Xw&xX;@blsHE`_O(!h2>Trb9Aq7W#6JX!ueIXSster!xk zf%p!EJ=Ndey|}oTjg8IY)bsQ6=g*jNVvWT!XJ_Y+A3r|mZ~nV!(<bZkcP!y-+XEjp zbL`qu@cy2yiLv9HL+Y(_Y^%k3uRhW%uwyuR?$oJG+qb(*uRR!VaqjHd)N9%2A3l88 z(!#Q(cx6w|nPa`u@%w5zZ)+4fv&2RzH0jCx5H0B`OsJ}=x^($+Y;5esWljh7RDNEx zXi-#DRKZLYiNAmUKA8IY<x54)^0KmZD_0)O6_M*$;LYuF;VAR_rhiXP3j6z?-?z`s zaEhIIZf@>$z1XD9H!}_zNTuG}Q(5fk$@%zDef`f*Pk(%ToN+#ALXo=q@>8e0?zlZ{ z;n=msfhE@FgVKwqPoK86wSCw+V}``XDRt%L<$iwW=Gj*7INY^z)vBtBiUXBtzRoTt z=H~3ItSeWnaBzF_<cWfEX=&+>-b4I?C7F!V7sT%@I(qDwo3F2LSXh{|^Wk&n_~yFL zGWzzru&^*KEv-xD0fSx8e=lEO*540pRF*DX%6hU$-Sy$qr>=8Z*7MG*EH3^mtnSxg zvsy+?9JDww==Hfsr5i#mOf_$h9XqyVi%EbjH#fJ5Mc)kT@^$Oi=Q}zwIzK)Fx`6xW zQP!s%zr_Ci`<H)z-_hJDOB`5YqYfy&5Z8}m`8##`^me&g7nhd#^XE^TDERC8jwZfO zyh1#$_D^S)IpFSf`Qi2tlXauFIRxF_mb-b&mM4C%KFBZNT<9lfRdV9^arUDVy1KfA zoTnWZ{W5Xl#6N#(va_?_wXypw-B{D!-YzXAwQ2Kaei@5|?CkEeH-QepuU@^HHDd;c zmj7edqn`f${!UIzTRv*IS5;Ll_n)73ZBK<E)ODc#TX$P~dvN*+38TkcR$M<tgoT^! z+}zzaTU<PL(S6GyRZGjtE9(P-w*L=^iLueDEja(M;^HFLlIQs{Zk$#Xr?%(aWs<K9 zF?VuzcYkp8xwEtLgUN^H`gnP9@$sc?zIp7}v5Y`FR*MbGmMy#R=IHU`*RNbL$SasL z`_w6~jHxTlw`+&3IdSULq)98L{c(bXScdbaLx&D+{4W)L;o`5NB_|kUHds{iF796) zwsz5#3nx!%+S<;w*5rDpIKA+)pyreX|9^eeHZ~SE4NTry@bJ(LBc@K!=}}o(tJbY! z+k5Wx>D^^-Z~grI9JHe7?c3b^eEyXySFd(npPJJ&VfWE)@!h+3A3t{NQ2zg>Qj__1 zwN8)oHJVqgTE)o7n6jXz2$aSpSZnV@BrtJQWoEwo_xJbOHES+h_wn)BG5Obbeo0Bm z#h2KbkLbKuuy*o$2G(6`mMvShXc1GN`W@BE%F1_%?@l(pmzI>gdF$4%-@oTum#<r} zV8PCvGb4+SsV62RFi3&IZPoe2%*>gSCLKCrzWvejdT2vG-Xl0y=D2zH3!MvLHx_XR zyKr0)lQ^a4^>UHtBYTtF4^c)u&See<FI{yNP@5gc;ikFNXU_+IuLUk^yHDKZIm_+N z6|2%3XYzl^w$AL{P2YdNyO4P1<!-0*nb!NyUo9(1KYwm>?YZwZ=ZojHx9Eww<P>G* z<UHBla`{P;(aasoD-^ghiW)EMWZ&^<+Rx)=Z#Jwx&|Cig-qg1h)8FVF;*@<~`sv9@ z1J<*L4SKwm9_r*e&bv=fOKVrvSFO{VzQ4b}Jwiu6e&3vV^Wq{SJ5Q<l?63RVr7bkq z?|5m&i9f|w*REgRU;8`k%_3JJm6DYTT^Fpat$+GmyuCd?JUpDewCmsJ?&|OF_Wrx7 z+4beruZOe5fA|G14XXV4DRuG1h_JA>>uT!i?C-QvmTSy=^|h+iNl|!D@R!@$^ZVs& zALYf|Id$Q}g<H2~-G1x#q2+XqUA&8V@qa_P{`8WPEsGX4y+7)j8oRUTDQGUK_^hG| z$OYFn9DVoh-J3UWcI?<OW5$fb?fl9WMYo$-mS4@<`SyZ&k(GIlAU{*PZrq*<!IiuR zW$LYJf0=xfDGGNyEXFTu)zWi*t^td}ieQmVdD+>{@A$Ny>@0qM<gZ=F=}(`E{Qdn4 z3k~mIt^Dx7F=pbIuV2@$U*8?Oi=(YYPxQqxr9=+P96`f7IcCM#S3d6P`(yg7zWeN1 z-}b|aMl;XNw?DtV-<W6e{Q389-<D?GyQ7|2rDUaplX#nKo=(y3yE_6NTq~LSbGeb& zzib5?ZEbC4X6C6=r|#JG$Up7Jn;jFXetpp_Eq$j4)%1Vw*ZR`Zs|f}Lahq?yb*f`$ zd3<`h{^G@pOG``B&&_%0{{F<%qODPPFI-62d~-!@O~1lIZ&smQ1}&DB*FSywv^ILX zmzP(|%38*VhzN&A>(;Ngul|<vAlA>lPexN;e|v<^e7jnq-8~oiIb*dZTxfl`ecAa| z7Ul1K?o;kOEGQ`{2?+^NQCDX#<3Dor=+o!V9|!pO`g#_B>5G_fVJQ=5tb|fwW4FQ2 ze}8|UIpgE+&wqN8RBv1242RCuA*&uedUWmDwUZ}3vjPRVg?5E3P<>H0F(bA~ujA^~ zs~b0NWapQQ*<WX?t=%o3bYf%u|GKSFwU3YW-n)12=FP~B+}?lKIb*dhC|%s`5uzvb zw!|v1F7MF#J9lF87#BEz_K3`yRrU7P)^Fd+cHjMXd~&y7HAsC<Ufw*5LMOfH{QUgw zCW4%{HDv<7mU>Truy5Tuy^Y#6(F%{s-`|T|d+ppgzr`0<Tz)xW-_L_n8a1Y#dh;fy z`QV2iA0L1GSSXeB<GZudbb*fEA5$NFm%QYn^5w%#zZV-+R3wCjH}BY?QI`8ZCO&@t zym@us-rPLg&Yyp8Ph?oww3#zk2Ca1RyT;KcZ$EGH<iox{zCJqI{qtw#MtjDOw<las zJ#yqo%bESx98dhr@qF=c^V|!oSFbK?;pXD{wo6O#HNU*w0;h-B-A6B7y2O+k9v1fO z>C=O^JUu=Ch=fNcN<6!=GB|3j*wWm*ymzl(JO7G{j=ufcNSMjNX}VZzYwHhB<&KY= z<vvZga9DlG1#2rSJ{gOKigyJTO?<!m<?U<i=3jsPwZf)g<LReO4)*o`_H5bm<>TYy zGiOR_e7(9lTv=K9!t2TE{u3t7o;9n-P5Jbus=fR6?2%dKwl*~-MMXu0g;)P3pM|Zi zF0cNYl`9)Rva_=nGDSp0beuXV#mOhMYfHudf40}7qN1Xto|Fhx{m2omDlgw2wDL$} z>*d6tR;Po$#*$kmT*zzO?!e<N(Y{{rjNti&IWDCvWf9U3=PuhZNlm5XWa8E+MOhEW z#TR*ac|Uq7Eo}E+aG@~HWy(EEQ{`>W?*eT8@#^*U_8!gr`r_i^j~_pFc6P2@xiT^` zQd}=aLqp@j%aYL0(5+jymcP4`nU|NBpMQL1QbGd5vbwkH7w_C@DHZ3G!_FDobt7k6 z^6|ctf4YB&h>6WQ`|RJpy4`p6<|!)onCIW?>FIIU%GRu?s@l5QY|^I7FH3gDcpR6O zmX2G0{rTsMx@IjCCR|WGb?K7O=}j>q&u>(oG*OzcAbIM%d3`LpWmAQYoUaEj6<}tV Y`X(UjYf$BC1_lNOPgg&ebxsLQ01H^!8vp<R diff --git a/docs/images/bzLifecycle.xml b/docs/images/bzLifecycle.xml index d4c33c96c..1adc6b70c 100644 --- a/docs/images/bzLifecycle.xml +++ b/docs/images/bzLifecycle.xml @@ -1118,9 +1118,7 @@ possession#</dia:string> DUPLICATE WONTFIX WORKSFORME - INVALID - REMIND - LATER#</dia:string> + INVALID#</dia:string> </dia:attribute> <dia:attribute name="font"> <dia:font family="sans" style="0" name="Helvetica"/> diff --git a/docs/images/callouts/CVS/Entries b/docs/images/callouts/CVS/Entries index c25abfe27..cea3f9d28 100644 --- a/docs/images/callouts/CVS/Entries +++ b/docs/images/callouts/CVS/Entries @@ -1,4 +1,4 @@ -/1.gif/1.1/Sat May 17 01:27:53 2003/-kb/TBUGZILLA-2_22_3 -/2.gif/1.1/Sat May 17 01:27:54 2003/-kb/TBUGZILLA-2_22_3 -/3.gif/1.1/Thu Jul 3 20:23:39 2003/-kb/TBUGZILLA-2_22_3 +/1.gif/1.1/Sat May 17 01:27:53 2003/-kb/TBUGZILLA-3_0 +/2.gif/1.1/Sat May 17 01:27:54 2003/-kb/TBUGZILLA-3_0 +/3.gif/1.1/Thu Jul 3 20:23:39 2003/-kb/TBUGZILLA-3_0 D diff --git a/docs/images/callouts/CVS/Tag b/docs/images/callouts/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/docs/images/callouts/CVS/Tag +++ b/docs/images/callouts/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/docs/lib/CVS/Entries b/docs/lib/CVS/Entries new file mode 100644 index 000000000..6cf7d7949 --- /dev/null +++ b/docs/lib/CVS/Entries @@ -0,0 +1 @@ +D/Pod//// diff --git a/docs/lib/CVS/Repository b/docs/lib/CVS/Repository new file mode 100644 index 000000000..65bec1851 --- /dev/null +++ b/docs/lib/CVS/Repository @@ -0,0 +1 @@ +mozilla/webtools/bugzilla/docs/lib diff --git a/docs/lib/CVS/Root b/docs/lib/CVS/Root new file mode 100644 index 000000000..cdb6f4a07 --- /dev/null +++ b/docs/lib/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot diff --git a/docs/lib/CVS/Tag b/docs/lib/CVS/Tag new file mode 100644 index 000000000..941648ec7 --- /dev/null +++ b/docs/lib/CVS/Tag @@ -0,0 +1 @@ +TBUGZILLA-3_0 diff --git a/docs/lib/Pod/CVS/Entries b/docs/lib/Pod/CVS/Entries new file mode 100644 index 000000000..8cec978ce --- /dev/null +++ b/docs/lib/Pod/CVS/Entries @@ -0,0 +1 @@ +D/Simple//// diff --git a/docs/lib/Pod/CVS/Repository b/docs/lib/Pod/CVS/Repository new file mode 100644 index 000000000..80c820b6a --- /dev/null +++ b/docs/lib/Pod/CVS/Repository @@ -0,0 +1 @@ +mozilla/webtools/bugzilla/docs/lib/Pod diff --git a/docs/lib/Pod/CVS/Root b/docs/lib/Pod/CVS/Root new file mode 100644 index 000000000..cdb6f4a07 --- /dev/null +++ b/docs/lib/Pod/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot diff --git a/docs/lib/Pod/CVS/Tag b/docs/lib/Pod/CVS/Tag new file mode 100644 index 000000000..941648ec7 --- /dev/null +++ b/docs/lib/Pod/CVS/Tag @@ -0,0 +1 @@ +TBUGZILLA-3_0 diff --git a/docs/lib/Pod/Simple/CVS/Entries b/docs/lib/Pod/Simple/CVS/Entries new file mode 100644 index 000000000..a5c55af19 --- /dev/null +++ b/docs/lib/Pod/Simple/CVS/Entries @@ -0,0 +1,2 @@ +D/HTML//// +D/HTMLBatch//// diff --git a/docs/lib/Pod/Simple/CVS/Repository b/docs/lib/Pod/Simple/CVS/Repository new file mode 100644 index 000000000..667081e3e --- /dev/null +++ b/docs/lib/Pod/Simple/CVS/Repository @@ -0,0 +1 @@ +mozilla/webtools/bugzilla/docs/lib/Pod/Simple diff --git a/docs/lib/Pod/Simple/CVS/Root b/docs/lib/Pod/Simple/CVS/Root new file mode 100644 index 000000000..cdb6f4a07 --- /dev/null +++ b/docs/lib/Pod/Simple/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot diff --git a/docs/lib/Pod/Simple/CVS/Tag b/docs/lib/Pod/Simple/CVS/Tag new file mode 100644 index 000000000..941648ec7 --- /dev/null +++ b/docs/lib/Pod/Simple/CVS/Tag @@ -0,0 +1 @@ +TBUGZILLA-3_0 diff --git a/docs/lib/Pod/Simple/HTML/Bugzilla.pm b/docs/lib/Pod/Simple/HTML/Bugzilla.pm new file mode 100644 index 000000000..f82ab9266 --- /dev/null +++ b/docs/lib/Pod/Simple/HTML/Bugzilla.pm @@ -0,0 +1,78 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Everything Solved. +# Portions created by Everything Solved are Copyright (C) 2006 +# Everything Solved. All Rights Reserved. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + +package Pod::Simple::HTML::Bugzilla; + +use strict; +use base qw(Pod::Simple::HTML); + +# Without this constant, HTMLBatch will throw undef warnings. +use constant VERSION => $Pod::Simple::HTML::VERSION; +use constant CODE_CLASS => ' class="code"'; +use constant META_CT => '<meta http-equiv="Content-Type" content="text/html;' + . ' charset=UTF-8">'; +use constant DOCTYPE => '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01' + . ' Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'; + +sub new { + my $self = shift->SUPER::new(@_); + + my $doctype = $self->DOCTYPE; + my $content_type = $self->META_CT; + + my $html_pre_title = <<END_HTML; +$doctype +<html> + <head> + <title> +END_HTML + + my $html_post_title = <<END_HTML; +</title> + $content_type + </head> + <body id="pod"> +END_HTML + + $self->html_header_before_title($html_pre_title); + $self->html_header_after_title($html_post_title); + + # Fix some tags to have classes so that we can adjust them. + my $code = CODE_CLASS; + $self->{'Tagmap'}->{'Verbatim'} = "\n<pre $code>"; + $self->{'Tagmap'}->{'VerbatimFormatted'} = "\n<pre $code>"; + $self->{'Tagmap'}->{'F'} = "<em $code>"; + $self->{'Tagmap'}->{'C'} = "<code $code>"; + + # Don't put head4 tags into the Table of Contents. We have this + delete $Pod::Simple::HTML::ToIndex{'head4'}; + + return $self; +} + +# Override do_beginning to put the name of the module at the top +sub do_beginning { + my $self = shift; + $self->SUPER::do_beginning(@_); + print {$self->{'output_fh'}} "<h1>" . $self->get_short_title . "</h1>"; + return 1; +} + +1; diff --git a/docs/lib/Pod/Simple/HTML/CVS/Entries b/docs/lib/Pod/Simple/HTML/CVS/Entries new file mode 100644 index 000000000..bb31c6eb6 --- /dev/null +++ b/docs/lib/Pod/Simple/HTML/CVS/Entries @@ -0,0 +1,2 @@ +/Bugzilla.pm/1.1/Tue Sep 5 19:00:56 2006//TBUGZILLA-3_0 +D diff --git a/docs/lib/Pod/Simple/HTML/CVS/Repository b/docs/lib/Pod/Simple/HTML/CVS/Repository new file mode 100644 index 000000000..7c1727c55 --- /dev/null +++ b/docs/lib/Pod/Simple/HTML/CVS/Repository @@ -0,0 +1 @@ +mozilla/webtools/bugzilla/docs/lib/Pod/Simple/HTML diff --git a/docs/lib/Pod/Simple/HTML/CVS/Root b/docs/lib/Pod/Simple/HTML/CVS/Root new file mode 100644 index 000000000..cdb6f4a07 --- /dev/null +++ b/docs/lib/Pod/Simple/HTML/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot diff --git a/docs/lib/Pod/Simple/HTML/CVS/Tag b/docs/lib/Pod/Simple/HTML/CVS/Tag new file mode 100644 index 000000000..efdc1ff3e --- /dev/null +++ b/docs/lib/Pod/Simple/HTML/CVS/Tag @@ -0,0 +1 @@ +NBUGZILLA-3_0 diff --git a/docs/lib/Pod/Simple/HTMLBatch/Bugzilla.pm b/docs/lib/Pod/Simple/HTMLBatch/Bugzilla.pm new file mode 100644 index 000000000..06c76c678 --- /dev/null +++ b/docs/lib/Pod/Simple/HTMLBatch/Bugzilla.pm @@ -0,0 +1,107 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Everything Solved. +# Portions created by Everything Solved are Copyright (C) 2006 +# Everything Solved. All Rights Reserved. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + +package Pod::Simple::HTMLBatch::Bugzilla; + +use strict; +use base qw(Pod::Simple::HTMLBatch); + +# This is the same hack that HTMLBatch does to "import" this subroutine. +BEGIN { *esc = \&Pod::Simple::HTML::esc } + +# Describes how top-level modules should be sorted and named. This +# is a translation from HTMLBatch's names to our categories. +# Note that if you leave out a category here, it will not be indexed +# in the contents file, even though its HTML POD will still exist. +use constant FILE_TRANSLATION => { + Files => ['importxml', 'contrib', 'checksetup', 'email_in'], + Modules => ['bugzilla'], + Extensions => ['extensions'], +}; + +# This is basically copied from Pod::Simple::HTMLBatch, and overridden +# so that we can format things more nicely. +sub _write_contents_middle { + my ($self, $Contents, $outfile, $toplevel2submodules) = @_; + + my $file_trans = FILE_TRANSLATION; + + # For every top-level category... + foreach my $category (sort keys %$file_trans) { + # Get all of the HTMLBatch categories that should be in this + # category. + my @category_data; + foreach my $b_category (@{$file_trans->{$category}}) { + my $data = $toplevel2submodules->{$b_category}; + push(@category_data, @$data) if $data; + } + next unless @category_data; + + my @downlines = sort {$a->[-1] cmp $b->[-1]} @category_data; + + # And finally, actually print out the table for this category. + printf $Contents qq[<dt><a name="%s">%s</a></dt>\n<dd>\n], + esc($category), esc($category); + print $Contents '<table class="pod_desc_table">' . "\n"; + + # For every POD... + my $row_count = 0; + foreach my $e (@downlines) { + $row_count++; + my $even_or_odd = $row_count % 2 ? 'even' : 'odd'; + my $name = esc($e->[0]); + my $path = join( "/", '.', esc(@{$e->[3]}) ) + . $Pod::Simple::HTML::HTML_EXTENSION; + my $description = $self->{bugzilla_desc}->{$name} || ''; + my $html = <<END_HTML; +<tr class="$even_or_odd"> + <th><a href="$path">$name</a></th> + <td>$description</td> +</tr> +END_HTML + + print $Contents $html; + } + print $Contents "</table></dd>\n\n"; + } + + return 1; +} + +# This stores the name and description for each file, so that +# we can get that information out later. +sub note_for_contents_file { + my $self = shift; + my $retval = $self->SUPER::note_for_contents_file(@_); + + my ($namelets, $infile) = @_; + my $parser = $self->html_render_class->new; + $parser->set_source($infile); + my $full_title = $parser->get_title; + $full_title =~ /^\S+\s+-+\s+(.+)/; + my $description = $1; + + $self->{bugzilla_desc} ||= {}; + $self->{bugzilla_desc}->{join('::', @$namelets)} = $description; + + return $retval; +} + +1; diff --git a/docs/lib/Pod/Simple/HTMLBatch/CVS/Entries b/docs/lib/Pod/Simple/HTMLBatch/CVS/Entries new file mode 100644 index 000000000..59f6b80b4 --- /dev/null +++ b/docs/lib/Pod/Simple/HTMLBatch/CVS/Entries @@ -0,0 +1,2 @@ +/Bugzilla.pm/1.2/Tue Oct 17 06:45:44 2006//TBUGZILLA-3_0 +D diff --git a/docs/lib/Pod/Simple/HTMLBatch/CVS/Repository b/docs/lib/Pod/Simple/HTMLBatch/CVS/Repository new file mode 100644 index 000000000..7db220308 --- /dev/null +++ b/docs/lib/Pod/Simple/HTMLBatch/CVS/Repository @@ -0,0 +1 @@ +mozilla/webtools/bugzilla/docs/lib/Pod/Simple/HTMLBatch diff --git a/docs/lib/Pod/Simple/HTMLBatch/CVS/Root b/docs/lib/Pod/Simple/HTMLBatch/CVS/Root new file mode 100644 index 000000000..cdb6f4a07 --- /dev/null +++ b/docs/lib/Pod/Simple/HTMLBatch/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot diff --git a/docs/lib/Pod/Simple/HTMLBatch/CVS/Tag b/docs/lib/Pod/Simple/HTMLBatch/CVS/Tag new file mode 100644 index 000000000..efdc1ff3e --- /dev/null +++ b/docs/lib/Pod/Simple/HTMLBatch/CVS/Tag @@ -0,0 +1 @@ +NBUGZILLA-3_0 diff --git a/docs/makedocs.pl b/docs/makedocs.pl index 5a2244a17..b636a2f37 100644 --- a/docs/makedocs.pl +++ b/docs/makedocs.pl @@ -20,32 +20,99 @@ # # Contributor(s): Matthew Tuck <matty@chariot.net.au> # Jacob Steenhagen <jake@bugzilla.org> +# Colin Ogilvie <colin.ogilvie@gmail.com> +# Max Kanat-Alexander <mkanat@bugzilla.org> # This script compiles all the documentation. -use diagnostics; use strict; -use File::Basename; +# We need to be in this directory to use our libraries. +BEGIN { + require File::Basename; + import File::Basename qw(dirname); + chdir dirname($0); +} + +use lib qw(.. lib); + +# We only compile our POD if Pod::Simple is installed. We do the checks +# this way so that if there's a compile error in Pod::Simple::HTML::Bugzilla, +# makedocs doesn't just silently fail, but instead actually tells us there's +# a compile error. +my $pod_simple; +if (eval { require Pod::Simple }) { + require Pod::Simple::HTMLBatch::Bugzilla; + require Pod::Simple::HTML::Bugzilla; + $pod_simple = 1; +}; + +use Bugzilla::Install::Requirements + qw(REQUIRED_MODULES OPTIONAL_MODULES); +use Bugzilla::Constants qw(DB_MODULE BUGZILLA_VERSION); ############################################################################### -# Environment Variable Checking +# Generate minimum version list ############################################################################### -my ($JADE_PUB, $LDP_HOME); +my $modules = REQUIRED_MODULES; +my $opt_modules = OPTIONAL_MODULES; + +open(ENTITIES, '>', 'xml/bugzilla.ent') or die('Could not open xml/bugzilla.ent: ' . $!); +print ENTITIES '<?xml version="1.0"?>' ."\n\n"; +print ENTITIES '<!-- Module Versions -->' . "\n"; +foreach my $module (@$modules, @$opt_modules) +{ + my $name = $module->{'module'}; + $name =~ s/::/-/g; + $name = lc($name); + #This needs to be a string comparison, due to the modules having + #version numbers like 0.9.4 + my $version = $module->{'version'} eq 0 ? 'any' : $module->{'version'}; + print ENTITIES '<!ENTITY min-' . $name . '-ver "'.$version.'">' . "\n"; +} + +# CGI is a special case, because it has an optional version *and* a required +# version. +my ($cgi_opt) = grep($_->{package} eq 'CGI', @$opt_modules); +print ENTITIES '<!ENTITY min-mp-cgi-ver "' . $cgi_opt->{version} . '">' . "\n"; + +print ENTITIES "\n <!-- Database Versions --> \n"; + +my $db_modules = DB_MODULE; +foreach my $db (keys %$db_modules) { + my $dbd = $db_modules->{$db}->{dbd}; + my $name = $dbd->{package}; + $name = lc($name); + my $version = $dbd->{version} || 'any'; + my $db_version = $db_modules->{$db}->{'db_version'}; + print ENTITIES '<!ENTITY min-' . $name . '-ver "'.$version.'">' . "\n"; + print ENTITIES '<!ENTITY min-' . lc($db) . '-ver "'.$db_version.'">' . "\n"; +} +close(ENTITIES); +############################################################################### +# Environment Variable Checking +############################################################################### + +my ($JADE_PUB, $LDP_HOME, $build_docs); +$build_docs = 1; if (defined $ENV{JADE_PUB} && $ENV{JADE_PUB} ne '') { $JADE_PUB = $ENV{JADE_PUB}; } else { - die "You need to set the JADE_PUB environment variable first."; + print "To build 'The Bugzilla Guide', you need to set the "; + print "JADE_PUB environment variable first.\n"; + $build_docs = 0; } if (defined $ENV{LDP_HOME} && $ENV{LDP_HOME} ne '') { $LDP_HOME = $ENV{LDP_HOME}; } else { - die "You need to set the LDP_HOME environment variable first."; + print "To build 'The Bugzilla Guide', you need to set the "; + print "LDP_HOME environment variable first.\n"; + $build_docs = 0; } ############################################################################### @@ -63,16 +130,44 @@ sub MakeDocs { } +sub make_pod { + + print "Creating API documentation...\n"; + + my $converter = Pod::Simple::HTMLBatch::Bugzilla->new; + # Don't output progress information. + $converter->verbose(0); + $converter->html_render_class('Pod::Simple::HTML::Bugzilla'); + + my $doctype = Pod::Simple::HTML::Bugzilla->DOCTYPE; + my $content_type = Pod::Simple::HTML::Bugzilla->META_CT; + my $bz_version = BUGZILLA_VERSION; + + my $contents_start = <<END_HTML; +$doctype +<html> + <head> + $content_type + <title>Bugzilla $bz_version API Documentation</title> + </head> + <body class="contentspage"> + <h1>Bugzilla $bz_version API Documentation</h1> +END_HTML + + $converter->contents_page_start($contents_start); + $converter->contents_page_end("</body></html>"); + $converter->add_css('style.css'); + $converter->javascript_flurry(0); + $converter->css_flurry(0); + $converter->batch_convert(['../'], 'html/api/'); + + print "\n"; +} + ############################################################################### # Make the docs ... ############################################################################### -chdir dirname($0); - -if (!-d 'html') { - unlink 'html'; - mkdir 'html', 0755; -} if (!-d 'txt') { unlink 'txt'; mkdir 'txt', 0755; @@ -82,6 +177,9 @@ if (!-d 'pdf') { mkdir 'pdf', 0755; } +make_pod() if $pod_simple; +exit unless $build_docs; + chdir 'html'; MakeDocs('separate HTML', "jade -t sgml -i html -d $LDP_HOME/ldp.dsl\#html " . diff --git a/docs/pdf/Bugzilla-Guide.pdf b/docs/pdf/Bugzilla-Guide.pdf index 4a93292b1..8c5f7859f 100644 --- a/docs/pdf/Bugzilla-Guide.pdf +++ b/docs/pdf/Bugzilla-Guide.pdf @@ -3,7 +3,7 @@ << /S /GoTo /D (1.0) >> endobj 4 0 obj -(The Bugzilla Guide 2.22.3 Release) +(The Bugzilla Guide 3.0 Release) endobj 5 0 obj << /S /GoTo /D (2.0) >> @@ -123,7 +123,7 @@ endobj << /S /GoTo /D (6.6.5.4.3) >> endobj 84 0 obj -(2.1.5.2. Template Toolkit \(2.10\)) +(2.1.5.2. Template Toolkit \(2.12\)) endobj 85 0 obj << /S /GoTo /D (6.6.5.5.3) >> @@ -147,7 +147,7 @@ endobj << /S /GoTo /D (6.6.5.8.3) >> endobj 100 0 obj -(2.1.5.6. GD::Text::Align \(any\)) +(2.1.5.6. GD::Text \(any\)) endobj 101 0 obj << /S /GoTo /D (6.6.5.9.3) >> @@ -159,5882 +159,5893 @@ endobj << /S /GoTo /D (6.6.5.10.3) >> endobj 108 0 obj -(2.1.5.8. PatchReader \(0.9.4\)) +(2.1.5.8. SOAP::Lite \(any\)) endobj 109 0 obj -<< /S /GoTo /D (6.6.6.2) >> +<< /S /GoTo /D (6.6.5.11.3) >> endobj 112 0 obj -(2.1.6. Mail Transfer Agent \(MTA\)) +(2.1.5.9. PatchReader \(0.9.4\)) endobj 113 0 obj -<< /S /GoTo /D (6.7.1) >> +<< /S /GoTo /D (6.6.6.2) >> endobj 116 0 obj -(2.2. Configuration) +(2.1.6. Mail Transfer Agent \(MTA\)) endobj 117 0 obj -<< /S /GoTo /D (6.7.7.2) >> +<< /S /GoTo /D (6.6.7.2) >> endobj 120 0 obj -(2.2.1. localconfig) +(2.1.7. Installing Bugzilla on modperl) endobj 121 0 obj -<< /S /GoTo /D (6.7.8.2) >> +<< /S /GoTo /D (6.7.1) >> endobj 124 0 obj -(2.2.2. Database Server) +(2.2. Configuration) endobj 125 0 obj -<< /S /GoTo /D (6.7.8.11.3) >> +<< /S /GoTo /D (6.7.8.2) >> endobj 128 0 obj -(2.2.2.1. Bugzilla Database Schema) +(2.2.1. localconfig) endobj 129 0 obj -<< /S /GoTo /D (6.7.8.12.3) >> +<< /S /GoTo /D (6.7.9.2) >> endobj 132 0 obj -(2.2.2.2. MySQL) +(2.2.2. Database Server) endobj 133 0 obj -<< /S /GoTo /D (6.7.8.12.1.4) >> +<< /S /GoTo /D (6.7.9.12.3) >> endobj 136 0 obj -(2.2.2.2.1. Allow large attachments) +(2.2.2.1. Bugzilla Database Schema) endobj 137 0 obj -<< /S /GoTo /D (6.7.8.12.2.4) >> +<< /S /GoTo /D (6.7.9.13.3) >> endobj 140 0 obj -(2.2.2.2.2. Allow small words in fulltext indexes) +(2.2.2.2. MySQL) endobj 141 0 obj -<< /S /GoTo /D (6.7.8.12.3.4) >> +<< /S /GoTo /D (6.7.9.13.1.4) >> endobj 144 0 obj -(2.2.2.2.3. Add a user to MySQL) +(2.2.2.2.1. Allow large attachments) endobj 145 0 obj -<< /S /GoTo /D (6.7.8.12.4.4) >> +<< /S /GoTo /D (6.7.9.13.2.4) >> endobj 148 0 obj -(2.2.2.2.4. Permit attachments table to grow beyond 4GB) +(2.2.2.2.2. Allow small words in fulltext indexes) endobj 149 0 obj -<< /S /GoTo /D (6.7.8.13.3) >> +<< /S /GoTo /D (6.7.9.13.3.4) >> endobj 152 0 obj -(2.2.2.3. PostgreSQL) +(2.2.2.2.3. Add a user to MySQL) endobj 153 0 obj -<< /S /GoTo /D (6.7.8.13.5.4) >> +<< /S /GoTo /D (6.7.9.13.4.4) >> endobj 156 0 obj -(2.2.2.3.1. Add a User to PostgreSQL) +(2.2.2.2.4. Permit attachments table to grow beyond 4GB) endobj 157 0 obj -<< /S /GoTo /D (6.7.8.13.6.4) >> +<< /S /GoTo /D (6.7.9.14.3) >> endobj 160 0 obj -(2.2.2.3.2. Configure PostgreSQL) +(2.2.2.3. PostgreSQL) endobj 161 0 obj -<< /S /GoTo /D (6.7.9.2) >> +<< /S /GoTo /D (6.7.9.14.5.4) >> endobj 164 0 obj -(2.2.3. checksetup.pl) +(2.2.2.3.1. Add a User to PostgreSQL) endobj 165 0 obj -<< /S /GoTo /D (6.7.10.2) >> +<< /S /GoTo /D (6.7.9.14.6.4) >> endobj 168 0 obj -(2.2.4. Web server) +(2.2.2.3.2. Configure PostgreSQL) endobj 169 0 obj -<< /S /GoTo /D (6.7.10.14.3) >> +<< /S /GoTo /D (6.7.10.2) >> endobj 172 0 obj -(2.2.4.1. Apache httpd) +(2.2.3. checksetup.pl) endobj 173 0 obj -<< /S /GoTo /D (6.7.10.15.3) >> +<< /S /GoTo /D (6.7.11.2) >> endobj 176 0 obj -(2.2.4.2. Microsoft Internet Information Services) +(2.2.4. Web server) endobj 177 0 obj -<< /S /GoTo /D (6.7.11.2) >> +<< /S /GoTo /D (6.7.11.15.3) >> endobj 180 0 obj -(2.2.5. Bugzilla) +(2.2.4.1. Bugzilla using Apache) endobj 181 0 obj -<< /S /GoTo /D (6.8.1) >> +<< /S /GoTo /D (6.7.11.15.7.4) >> endobj 184 0 obj -(2.3. Optional Additional Configuration) +(2.2.4.1.1. Apache httpd with modcgi) endobj 185 0 obj -<< /S /GoTo /D (6.8.12.2) >> +<< /S /GoTo /D (6.7.11.15.8.4) >> endobj 188 0 obj -(2.3.1. Bug Graphs) +(2.2.4.1.2. Apache httpd with modperl) endobj 189 0 obj -<< /S /GoTo /D (6.8.13.2) >> +<< /S /GoTo /D (6.7.11.16.3) >> endobj 192 0 obj -(2.3.2. Dependency Charts) +(2.2.4.2. Microsoft Internet Information Services) endobj 193 0 obj -<< /S /GoTo /D (6.8.14.2) >> +<< /S /GoTo /D (6.7.12.2) >> endobj 196 0 obj -(2.3.3. The Whining Cron) +(2.2.5. Bugzilla) endobj 197 0 obj -<< /S /GoTo /D (6.8.15.2) >> +<< /S /GoTo /D (6.8.1) >> endobj 200 0 obj -(2.3.4. Whining) +(2.3. Optional Additional Configuration) endobj 201 0 obj -<< /S /GoTo /D (6.8.16.2) >> +<< /S /GoTo /D (6.8.13.2) >> endobj 204 0 obj -(2.3.5. Patch Viewer) +(2.3.1. Bug Graphs) endobj 205 0 obj -<< /S /GoTo /D (6.8.17.2) >> +<< /S /GoTo /D (6.8.14.2) >> endobj 208 0 obj -(2.3.6. LDAP Authentication) +(2.3.2. Dependency Charts) endobj 209 0 obj -<< /S /GoTo /D (6.8.18.2) >> +<< /S /GoTo /D (6.8.15.2) >> endobj 212 0 obj -(2.3.7. Serving Alternate Formats with the right MIME type) +(2.3.3. The Whining Cron) endobj 213 0 obj -<< /S /GoTo /D (6.9.1) >> +<< /S /GoTo /D (6.8.16.2) >> endobj 216 0 obj -(2.4. Multiple Bugzilla databases with a single installation) +(2.3.4. Whining) endobj 217 0 obj -<< /S /GoTo /D (6.10.1) >> +<< /S /GoTo /D (6.8.17.2) >> endobj 220 0 obj -(2.5. OSSpecific Installation Notes) +(2.3.5. Patch Viewer) endobj 221 0 obj -<< /S /GoTo /D (6.10.19.2) >> +<< /S /GoTo /D (6.8.18.2) >> endobj 224 0 obj -(2.5.1. Microsoft Windows) +(2.3.6. LDAP Authentication) endobj 225 0 obj -<< /S /GoTo /D (6.10.19.16.3) >> +<< /S /GoTo /D (6.8.19.2) >> endobj 228 0 obj -(2.5.1.1. Win32 Perl) +(2.3.7. Serving Alternate Formats with the right MIME type) endobj 229 0 obj -<< /S /GoTo /D (6.10.19.17.3) >> +<< /S /GoTo /D (6.9.1) >> endobj 232 0 obj -(2.5.1.2. Perl Modules on Win32) +(2.4. Multiple Bugzilla databases with a single installation) endobj 233 0 obj -<< /S /GoTo /D (6.10.19.18.3) >> +<< /S /GoTo /D (6.10.1) >> endobj 236 0 obj -(2.5.1.3. Code changes required to run on Win32) +(2.5. OSSpecific Installation Notes) endobj 237 0 obj -<< /S /GoTo /D (6.10.19.19.3) >> +<< /S /GoTo /D (6.10.20.2) >> endobj 240 0 obj -(2.5.1.4. Serving the web pages) +(2.5.1. Microsoft Windows) endobj 241 0 obj -<< /S /GoTo /D (6.10.19.20.3) >> +<< /S /GoTo /D (6.10.20.17.3) >> endobj 244 0 obj -(2.5.1.5. Sending Email) +(2.5.1.1. Win32 Perl) endobj 245 0 obj -<< /S /GoTo /D (6.10.20.2) >> +<< /S /GoTo /D (6.10.20.18.3) >> endobj 248 0 obj -(2.5.2. Mac OS X) +(2.5.1.2. Perl Modules on Win32) endobj 249 0 obj -<< /S /GoTo /D (6.10.20.21.3) >> +<< /S /GoTo /D (6.10.20.19.3) >> endobj 252 0 obj -(2.5.2.1. Sendmail) +(2.5.1.3. Code changes required to run on Win32) endobj 253 0 obj -<< /S /GoTo /D (6.10.20.22.3) >> +<< /S /GoTo /D (6.10.20.20.3) >> endobj 256 0 obj -(2.5.2.2. Libraries \046 Perl Modules on Mac OS X) +(2.5.1.4. Serving the web pages) endobj 257 0 obj -<< /S /GoTo /D (6.10.21.2) >> +<< /S /GoTo /D (6.10.20.21.3) >> endobj 260 0 obj -(2.5.3. LinuxMandrake 8.0) +(2.5.1.5. Sending Email) endobj 261 0 obj -<< /S /GoTo /D (6.11.1) >> +<< /S /GoTo /D (6.10.21.2) >> endobj 264 0 obj -(2.6. UNIX \(nonroot\) Installation Notes) +(2.5.2. Mac OS X) endobj 265 0 obj -<< /S /GoTo /D (6.11.22.2) >> +<< /S /GoTo /D (6.10.21.22.3) >> endobj 268 0 obj -(2.6.1. Introduction) +(2.5.2.1. Sendmail) endobj 269 0 obj -<< /S /GoTo /D (6.11.23.2) >> +<< /S /GoTo /D (6.10.21.23.3) >> endobj 272 0 obj -(2.6.2. MySQL) +(2.5.2.2. Libraries \046 Perl Modules on Mac OS X) endobj 273 0 obj -<< /S /GoTo /D (6.11.23.23.3) >> +<< /S /GoTo /D (6.10.22.2) >> endobj 276 0 obj -(2.6.2.1. Running MySQL as NonRoot) +(2.5.3. LinuxMandrake 8.0) endobj 277 0 obj -<< /S /GoTo /D (6.11.23.23.7.4) >> +<< /S /GoTo /D (6.11.1) >> endobj 280 0 obj -(2.6.2.1.1. The Custom Configuration Method) +(2.6. UNIX \(nonroot\) Installation Notes) endobj 281 0 obj -<< /S /GoTo /D (6.11.23.23.8.4) >> +<< /S /GoTo /D (6.11.23.2) >> endobj 284 0 obj -(2.6.2.1.2. The Custom Built Method) +(2.6.1. Introduction) endobj 285 0 obj -<< /S /GoTo /D (6.11.23.23.9.4) >> +<< /S /GoTo /D (6.11.24.2) >> endobj 288 0 obj -(2.6.2.1.3. Starting the Server) +(2.6.2. MySQL) endobj 289 0 obj -<< /S /GoTo /D (6.11.24.2) >> +<< /S /GoTo /D (6.11.24.24.3) >> endobj 292 0 obj -(2.6.3. Perl) +(2.6.2.1. Running MySQL as NonRoot) endobj 293 0 obj -<< /S /GoTo /D (6.11.25.2) >> +<< /S /GoTo /D (6.11.24.24.9.4) >> endobj 296 0 obj -(2.6.4. Perl Modules) +(2.6.2.1.1. The Custom Configuration Method) endobj 297 0 obj -<< /S /GoTo /D (6.11.25.24.3) >> +<< /S /GoTo /D (6.11.24.24.10.4) >> endobj 300 0 obj -(2.6.4.1. The Independant Method) +(2.6.2.1.2. The Custom Built Method) endobj 301 0 obj -<< /S /GoTo /D (6.11.25.25.3) >> +<< /S /GoTo /D (6.11.24.24.11.4) >> endobj 304 0 obj -(2.6.4.2. The Mixed Method) +(2.6.2.1.3. Starting the Server) endobj 305 0 obj -<< /S /GoTo /D (6.11.26.2) >> +<< /S /GoTo /D (6.11.25.2) >> endobj 308 0 obj -(2.6.5. HTTP Server) +(2.6.3. Perl) endobj 309 0 obj -<< /S /GoTo /D (6.11.26.26.3) >> +<< /S /GoTo /D (6.11.26.2) >> endobj 312 0 obj -(2.6.5.1. Running Apache as NonRoot) +(2.6.4. Perl Modules) endobj 313 0 obj -<< /S /GoTo /D (6.11.27.2) >> +<< /S /GoTo /D (6.11.26.25.3) >> endobj 316 0 obj -(2.6.6. Bugzilla) +(2.6.4.1. The Independant Method) endobj 317 0 obj -<< /S /GoTo /D (7.0) >> +<< /S /GoTo /D (6.11.26.26.3) >> endobj 320 0 obj -(Chapter 3. Administering Bugzilla) +(2.6.4.2. The Mixed Method) endobj 321 0 obj -<< /S /GoTo /D (7.12.1) >> +<< /S /GoTo /D (6.11.27.2) >> endobj 324 0 obj -(3.1. Bugzilla Configuration) +(2.6.5. HTTP Server) endobj 325 0 obj -<< /S /GoTo /D (7.13.1) >> +<< /S /GoTo /D (6.11.27.27.3) >> endobj 328 0 obj -(3.2. User Administration) +(2.6.5.1. Running Apache as NonRoot) endobj 329 0 obj -<< /S /GoTo /D (7.13.28.2) >> +<< /S /GoTo /D (6.11.28.2) >> endobj 332 0 obj -(3.2.1. Creating the Default User) +(2.6.6. Bugzilla) endobj 333 0 obj -<< /S /GoTo /D (7.13.29.2) >> +<< /S /GoTo /D (7.0) >> endobj 336 0 obj -(3.2.2. Managing Other Users) +(Chapter 3. Administering Bugzilla) endobj 337 0 obj -<< /S /GoTo /D (7.13.29.27.3) >> +<< /S /GoTo /D (7.12.1) >> endobj 340 0 obj -(3.2.2.1. Searching for existing users) +(3.1. Bugzilla Configuration) endobj 341 0 obj -<< /S /GoTo /D (7.13.29.28.3) >> +<< /S /GoTo /D (7.13.1) >> endobj 344 0 obj -(3.2.2.2. Creating new users) +(3.2. User Administration) endobj 345 0 obj -<< /S /GoTo /D (7.13.29.28.10.4) >> +<< /S /GoTo /D (7.13.29.2) >> endobj 348 0 obj -(3.2.2.2.1. Selfregistration) +(3.2.1. Creating the Default User) endobj 349 0 obj -<< /S /GoTo /D (7.13.29.28.11.4) >> +<< /S /GoTo /D (7.13.30.2) >> endobj 352 0 obj -(3.2.2.2.2. Accounts created by an administrator) +(3.2.2. Managing Other Users) endobj 353 0 obj -<< /S /GoTo /D (7.13.29.29.3) >> +<< /S /GoTo /D (7.13.30.28.3) >> endobj 356 0 obj -(3.2.2.3. Modifying Users) +(3.2.2.1. Searching for existing users) endobj 357 0 obj -<< /S /GoTo /D (7.13.29.30.3) >> +<< /S /GoTo /D (7.13.30.29.3) >> endobj 360 0 obj -(3.2.2.4. Deleting Users) +(3.2.2.2. Creating new users) endobj 361 0 obj -<< /S /GoTo /D (7.13.29.31.3) >> +<< /S /GoTo /D (7.13.30.29.12.4) >> endobj 364 0 obj -(3.2.2.5. Impersonating Users) +(3.2.2.2.1. Selfregistration) endobj 365 0 obj -<< /S /GoTo /D (7.14.1) >> +<< /S /GoTo /D (7.13.30.29.13.4) >> endobj 368 0 obj -(3.3. Classifications) +(3.2.2.2.2. Accounts created by an administrator) endobj 369 0 obj -<< /S /GoTo /D (7.15.1) >> +<< /S /GoTo /D (7.13.30.30.3) >> endobj 372 0 obj -(3.4. Products) +(3.2.2.3. Modifying Users) endobj 373 0 obj -<< /S /GoTo /D (7.16.1) >> +<< /S /GoTo /D (7.13.30.31.3) >> endobj 376 0 obj -(3.5. Components) +(3.2.2.4. Deleting Users) endobj 377 0 obj -<< /S /GoTo /D (7.17.1) >> +<< /S /GoTo /D (7.13.30.32.3) >> endobj 380 0 obj -(3.6. Versions) +(3.2.2.5. Impersonating Users) endobj 381 0 obj -<< /S /GoTo /D (7.18.1) >> +<< /S /GoTo /D (7.14.1) >> endobj 384 0 obj -(3.7. Milestones) +(3.3. Classifications) endobj 385 0 obj -<< /S /GoTo /D (7.19.1) >> +<< /S /GoTo /D (7.15.1) >> endobj 388 0 obj -(3.8. Flags) +(3.4. Products) endobj 389 0 obj -<< /S /GoTo /D (7.19.30.2) >> +<< /S /GoTo /D (7.16.1) >> endobj 392 0 obj -(3.8.1. A Simple Example) +(3.5. Components) endobj 393 0 obj -<< /S /GoTo /D (7.19.31.2) >> +<< /S /GoTo /D (7.17.1) >> endobj 396 0 obj -(3.8.2. About Flags) +(3.6. Versions) endobj 397 0 obj -<< /S /GoTo /D (7.19.31.32.3) >> +<< /S /GoTo /D (7.18.1) >> endobj 400 0 obj -(3.8.2.1. Values) +(3.7. Milestones) endobj 401 0 obj -<< /S /GoTo /D (7.19.32.2) >> +<< /S /GoTo /D (7.19.1) >> endobj 404 0 obj -(3.8.3. Using flag requests) +(3.8. Flags) endobj 405 0 obj -<< /S /GoTo /D (7.19.33.2) >> +<< /S /GoTo /D (7.19.31.2) >> endobj 408 0 obj -(3.8.4. Two Types of Flags) +(3.8.1. A Simple Example) endobj 409 0 obj -<< /S /GoTo /D (7.19.33.33.3) >> +<< /S /GoTo /D (7.19.32.2) >> endobj 412 0 obj -(3.8.4.1. Attachment Flags) +(3.8.2. About Flags) endobj 413 0 obj -<< /S /GoTo /D (7.19.33.34.3) >> +<< /S /GoTo /D (7.19.32.33.3) >> endobj 416 0 obj -(3.8.4.2. Bug Flags) +(3.8.2.1. Values) endobj 417 0 obj -<< /S /GoTo /D (7.19.34.2) >> +<< /S /GoTo /D (7.19.33.2) >> endobj 420 0 obj -(3.8.5. Administering Flags) +(3.8.3. Using flag requests) endobj 421 0 obj -<< /S /GoTo /D (7.19.34.35.3) >> +<< /S /GoTo /D (7.19.34.2) >> endobj 424 0 obj -(3.8.5.1. Creating a Flag) +(3.8.4. Two Types of Flags) endobj 425 0 obj -<< /S /GoTo /D (7.19.34.35.12.4) >> +<< /S /GoTo /D (7.19.34.34.3) >> endobj 428 0 obj -(3.8.5.1.1. Name) +(3.8.4.1. Attachment Flags) endobj 429 0 obj -<< /S /GoTo /D (7.19.34.35.13.4) >> +<< /S /GoTo /D (7.19.34.35.3) >> endobj 432 0 obj -(3.8.5.1.2. Description) +(3.8.4.2. Bug Flags) endobj 433 0 obj -<< /S /GoTo /D (7.19.34.35.14.4) >> +<< /S /GoTo /D (7.19.35.2) >> endobj 436 0 obj -(3.8.5.1.3. Category) +(3.8.5. Administering Flags) endobj 437 0 obj -<< /S /GoTo /D (7.19.34.35.15.4) >> +<< /S /GoTo /D (7.19.35.36.3) >> endobj 440 0 obj -(3.8.5.1.4. Sort Key) +(3.8.5.1. Creating a Flag) endobj 441 0 obj -<< /S /GoTo /D (7.19.34.35.16.4) >> +<< /S /GoTo /D (7.19.35.36.14.4) >> endobj 444 0 obj -(3.8.5.1.5. Active) +(3.8.5.1.1. Name) endobj 445 0 obj -<< /S /GoTo /D (7.19.34.35.17.4) >> +<< /S /GoTo /D (7.19.35.36.15.4) >> endobj 448 0 obj -(3.8.5.1.6. Requestable) +(3.8.5.1.2. Description) endobj 449 0 obj -<< /S /GoTo /D (7.19.34.35.18.4) >> +<< /S /GoTo /D (7.19.35.36.16.4) >> endobj 452 0 obj -(3.8.5.1.7. Specifically Requestable) +(3.8.5.1.3. Category) endobj 453 0 obj -<< /S /GoTo /D (7.19.34.35.19.4) >> +<< /S /GoTo /D (7.19.35.36.17.4) >> endobj 456 0 obj -(3.8.5.1.8. Multiplicable) +(3.8.5.1.4. Sort Key) endobj 457 0 obj -<< /S /GoTo /D (7.19.34.35.20.4) >> +<< /S /GoTo /D (7.19.35.36.18.4) >> endobj 460 0 obj -(3.8.5.1.9. CC List) +(3.8.5.1.5. Active) endobj 461 0 obj -<< /S /GoTo /D (7.19.34.35.21.4) >> +<< /S /GoTo /D (7.19.35.36.19.4) >> endobj 464 0 obj -(3.8.5.1.10. Grant Group) +(3.8.5.1.6. Requestable) endobj 465 0 obj -<< /S /GoTo /D (7.19.34.35.22.4) >> +<< /S /GoTo /D (7.19.35.36.20.4) >> endobj 468 0 obj -(3.8.5.1.11. Request Group) +(3.8.5.1.7. Specifically Requestable) endobj 469 0 obj -<< /S /GoTo /D (7.19.34.36.3) >> +<< /S /GoTo /D (7.19.35.36.21.4) >> endobj 472 0 obj -(3.8.5.2. Deleting a Flag) +(3.8.5.1.8. Multiplicable) endobj 473 0 obj -<< /S /GoTo /D (7.19.34.37.3) >> +<< /S /GoTo /D (7.19.35.36.22.4) >> endobj 476 0 obj -(3.8.5.3. Editing a Flag) +(3.8.5.1.9. CC List) endobj 477 0 obj -<< /S /GoTo /D (7.20.1) >> +<< /S /GoTo /D (7.19.35.36.23.4) >> endobj 480 0 obj -(3.9. Legal Values) +(3.8.5.1.10. Grant Group) endobj 481 0 obj -<< /S /GoTo /D (7.20.35.2) >> +<< /S /GoTo /D (7.19.35.36.24.4) >> endobj 484 0 obj -(3.9.1. Viewing/Editing legal values) +(3.8.5.1.11. Request Group) endobj 485 0 obj -<< /S /GoTo /D (7.20.36.2) >> +<< /S /GoTo /D (7.19.35.37.3) >> endobj 488 0 obj -(3.9.2. Deleting legal values) +(3.8.5.2. Deleting a Flag) endobj 489 0 obj -<< /S /GoTo /D (7.21.1) >> +<< /S /GoTo /D (7.19.35.38.3) >> endobj 492 0 obj -(3.10. Voting) +(3.8.5.3. Editing a Flag) endobj 493 0 obj -<< /S /GoTo /D (7.22.1) >> +<< /S /GoTo /D (7.20.1) >> endobj 496 0 obj -(3.11. Quips) +(3.9. Custom Fields) endobj 497 0 obj -<< /S /GoTo /D (7.23.1) >> +<< /S /GoTo /D (7.20.36.2) >> endobj 500 0 obj -(3.12. Groups and Group Security) +(3.9.1. Adding Custom Fields) endobj 501 0 obj -<< /S /GoTo /D (7.23.37.2) >> +<< /S /GoTo /D (7.20.37.2) >> endobj 504 0 obj -(3.12.1. Creating Groups) +(3.9.2. Editing Custom Fields) endobj 505 0 obj -<< /S /GoTo /D (7.23.38.2) >> +<< /S /GoTo /D (7.20.38.2) >> endobj 508 0 obj -(3.12.2. Assigning Users to Groups) +(3.9.3. Deleting Custom Fields) endobj 509 0 obj -<< /S /GoTo /D (7.23.39.2) >> +<< /S /GoTo /D (7.21.1) >> endobj 512 0 obj -(3.12.3. Assigning Group Controls to Products) +(3.10. Legal Values) endobj 513 0 obj -<< /S /GoTo /D (7.23.40.2) >> +<< /S /GoTo /D (7.21.39.2) >> endobj 516 0 obj -(3.12.4. Common Applications of Group Controls) +(3.10.1. Viewing/Editing legal values) endobj 517 0 obj -<< /S /GoTo /D (7.23.40.38.3) >> +<< /S /GoTo /D (7.21.40.2) >> endobj 520 0 obj -(3.12.4.1. General User Access With Security Group) +(3.10.2. Deleting legal values) endobj 521 0 obj -<< /S /GoTo /D (7.23.40.39.3) >> +<< /S /GoTo /D (7.22.1) >> endobj 524 0 obj -(3.12.4.2. General User Access With A Security Product) +(3.11. Voting) endobj 525 0 obj -<< /S /GoTo /D (7.23.40.40.3) >> +<< /S /GoTo /D (7.23.1) >> endobj 528 0 obj -(3.12.4.3. Product Isolation With Common Group) +(3.12. Quips) endobj 529 0 obj << /S /GoTo /D (7.24.1) >> endobj 532 0 obj -(3.13. Upgrading to New Releases) +(3.13. Groups and Group Security) endobj 533 0 obj << /S /GoTo /D (7.24.41.2) >> endobj 536 0 obj -(3.13.1. Version Definitions) +(3.13.1. Creating Groups) endobj 537 0 obj << /S /GoTo /D (7.24.42.2) >> endobj 540 0 obj -(3.13.2. Upgrading Methods and Procedure) +(3.13.2. Assigning Users to Groups) endobj 541 0 obj -<< /S /GoTo /D (7.24.42.41.3) >> +<< /S /GoTo /D (7.24.43.2) >> endobj 544 0 obj -(3.13.2.1. Upgrading using CVS) +(3.13.3. Assigning Group Controls to Products) endobj 545 0 obj -<< /S /GoTo /D (7.24.42.42.3) >> +<< /S /GoTo /D (7.24.44.2) >> endobj 548 0 obj -(3.13.2.2. Upgrading using the tarball) +(3.13.4. Common Applications of Group Controls) endobj 549 0 obj -<< /S /GoTo /D (7.24.42.43.3) >> +<< /S /GoTo /D (7.24.44.39.3) >> endobj 552 0 obj -(3.13.2.3. Upgrading using patches) +(3.13.4.1. General User Access With Security Group) endobj 553 0 obj -<< /S /GoTo /D (7.24.43.2) >> +<< /S /GoTo /D (7.24.44.40.3) >> endobj 556 0 obj -(3.13.3. Completing Your Upgrade) +(3.13.4.2. General User Access With A Security Product) endobj 557 0 obj -<< /S /GoTo /D (8.0) >> +<< /S /GoTo /D (7.24.44.41.3) >> endobj 560 0 obj -(Chapter 4. Bugzilla Security) +(3.13.4.3. Product Isolation With Common Group) endobj 561 0 obj -<< /S /GoTo /D (8.25.1) >> +<< /S /GoTo /D (7.25.1) >> endobj 564 0 obj -(4.1. Operating System) +(3.14. Upgrading to New Releases) endobj 565 0 obj -<< /S /GoTo /D (8.25.44.2) >> +<< /S /GoTo /D (7.25.45.2) >> endobj 568 0 obj -(4.1.1. TCP/IP Ports) +(3.14.1. Version Definitions) endobj 569 0 obj -<< /S /GoTo /D (8.25.45.2) >> +<< /S /GoTo /D (7.25.46.2) >> endobj 572 0 obj -(4.1.2. System User Accounts) +(3.14.2. Upgrading Notifications) endobj 573 0 obj -<< /S /GoTo /D (8.25.46.2) >> +<< /S /GoTo /D (7.25.47.2) >> endobj 576 0 obj -(4.1.3. The chroot Jail) +(3.14.3. Upgrading Methods and Procedure) endobj 577 0 obj -<< /S /GoTo /D (8.26.1) >> +<< /S /GoTo /D (7.25.47.42.3) >> endobj 580 0 obj -(4.2. MySQL) +(3.14.3.1. Upgrading using CVS) endobj 581 0 obj -<< /S /GoTo /D (8.26.47.2) >> +<< /S /GoTo /D (7.25.47.43.3) >> endobj 584 0 obj -(4.2.1. The MySQL System Account) +(3.14.3.2. Upgrading using the tarball) endobj 585 0 obj -<< /S /GoTo /D (8.26.48.2) >> +<< /S /GoTo /D (7.25.47.44.3) >> endobj 588 0 obj -(4.2.2. The MySQL root and anonymous Users) +(3.14.3.3. Upgrading using patches) endobj 589 0 obj -<< /S /GoTo /D (8.26.49.2) >> +<< /S /GoTo /D (7.25.48.2) >> endobj 592 0 obj -(4.2.3. Network Access) +(3.14.4. Completing Your Upgrade) endobj 593 0 obj -<< /S /GoTo /D (8.27.1) >> +<< /S /GoTo /D (8.0) >> endobj 596 0 obj -(4.3. Web server) +(Chapter 4. Bugzilla Security) endobj 597 0 obj -<< /S /GoTo /D (8.27.50.2) >> +<< /S /GoTo /D (8.26.1) >> endobj 600 0 obj -(4.3.1. Disabling Remote Access to Bugzilla Configuration Files) +(4.1. Operating System) endobj 601 0 obj -<< /S /GoTo /D (8.27.51.2) >> +<< /S /GoTo /D (8.26.49.2) >> endobj 604 0 obj -(4.3.2. Using modthrottle to Prevent a DOS) +(4.1.1. TCP/IP Ports) endobj 605 0 obj -<< /S /GoTo /D (8.28.1) >> +<< /S /GoTo /D (8.26.50.2) >> endobj 608 0 obj -(4.4. Bugzilla) +(4.1.2. System User Accounts) endobj 609 0 obj -<< /S /GoTo /D (8.28.52.2) >> +<< /S /GoTo /D (8.26.51.2) >> endobj 612 0 obj -(4.4.1. Prevent users injecting malicious Javascript) +(4.1.3. The chroot Jail) endobj 613 0 obj -<< /S /GoTo /D (9.0) >> +<< /S /GoTo /D (8.27.1) >> endobj 616 0 obj -(Chapter 5. Using Bugzilla) +(4.2. MySQL) endobj 617 0 obj -<< /S /GoTo /D (9.29.1) >> +<< /S /GoTo /D (8.27.52.2) >> endobj 620 0 obj -(5.1. Introduction) +(4.2.1. The MySQL System Account) endobj 621 0 obj -<< /S /GoTo /D (9.30.1) >> +<< /S /GoTo /D (8.27.53.2) >> endobj 624 0 obj -(5.2. Create a Bugzilla Account) +(4.2.2. The MySQL root and anonymous Users) endobj 625 0 obj -<< /S /GoTo /D (9.31.1) >> +<< /S /GoTo /D (8.27.54.2) >> endobj 628 0 obj -(5.3. Anatomy of a Bug) +(4.2.3. Network Access) endobj 629 0 obj -<< /S /GoTo /D (9.32.1) >> +<< /S /GoTo /D (8.28.1) >> endobj 632 0 obj -(5.4. Life Cycle of a Bug) +(4.3. Web server) endobj 633 0 obj -<< /S /GoTo /D (9.33.1) >> +<< /S /GoTo /D (8.28.55.2) >> endobj 636 0 obj -(5.5. Searching for Bugs) +(4.3.1. Disabling Remote Access to Bugzilla Configuration Files) endobj 637 0 obj -<< /S /GoTo /D (9.33.53.2) >> +<< /S /GoTo /D (8.28.56.2) >> endobj 640 0 obj -(5.5.1. Boolean Charts) +(4.3.2. Using modthrottle to Prevent a DOS) endobj 641 0 obj -<< /S /GoTo /D (9.33.53.44.3) >> +<< /S /GoTo /D (8.29.1) >> endobj 644 0 obj -(5.5.1.1. Pronoun Substitution) +(4.4. Bugzilla) endobj 645 0 obj -<< /S /GoTo /D (9.33.53.45.3) >> +<< /S /GoTo /D (8.29.57.2) >> endobj 648 0 obj -(5.5.1.2. Negation) +(4.4.1. Prevent users injecting malicious Javascript) endobj 649 0 obj -<< /S /GoTo /D (9.33.53.46.3) >> +<< /S /GoTo /D (9.0) >> endobj 652 0 obj -(5.5.1.3. Multiple Charts) +(Chapter 5. Using Bugzilla) endobj 653 0 obj -<< /S /GoTo /D (9.33.54.2) >> +<< /S /GoTo /D (9.30.1) >> endobj 656 0 obj -(5.5.2. Quicksearch) +(5.1. Introduction) endobj 657 0 obj -<< /S /GoTo /D (9.33.55.2) >> +<< /S /GoTo /D (9.31.1) >> endobj 660 0 obj -(5.5.3. Bug Lists) +(5.2. Create a Bugzilla Account) endobj 661 0 obj -<< /S /GoTo /D (9.33.56.2) >> +<< /S /GoTo /D (9.32.1) >> endobj 664 0 obj -(5.5.4. Adding individual bugs from bug lists) +(5.3. Anatomy of a Bug) endobj 665 0 obj -<< /S /GoTo /D (9.34.1) >> +<< /S /GoTo /D (9.33.1) >> endobj 668 0 obj -(5.6. Filing Bugs) +(5.4. Life Cycle of a Bug) endobj 669 0 obj -<< /S /GoTo /D (9.34.57.2) >> +<< /S /GoTo /D (9.34.1) >> endobj 672 0 obj -(5.6.1. Reporting a New Bug) +(5.5. Searching for Bugs) endobj 673 0 obj << /S /GoTo /D (9.34.58.2) >> endobj 676 0 obj -(5.6.2. Clone an Existing Bug) +(5.5.1. Boolean Charts) endobj 677 0 obj -<< /S /GoTo /D (9.35.1) >> +<< /S /GoTo /D (9.34.58.45.3) >> endobj 680 0 obj -(5.7. Attachments) +(5.5.1.1. Pronoun Substitution) endobj 681 0 obj -<< /S /GoTo /D (9.35.59.2) >> +<< /S /GoTo /D (9.34.58.46.3) >> endobj 684 0 obj -(5.7.1. Patch Viewer) +(5.5.1.2. Negation) endobj 685 0 obj -<< /S /GoTo /D (9.35.59.47.3) >> +<< /S /GoTo /D (9.34.58.47.3) >> endobj 688 0 obj -(5.7.1.1. Viewing Patches in Patch Viewer) +(5.5.1.3. Multiple Charts) endobj 689 0 obj -<< /S /GoTo /D (9.35.59.48.3) >> +<< /S /GoTo /D (9.34.59.2) >> endobj 692 0 obj -(5.7.1.2. Seeing the Difference Between Two Patches) +(5.5.2. Quicksearch) endobj 693 0 obj -<< /S /GoTo /D (9.35.59.49.3) >> +<< /S /GoTo /D (9.34.60.2) >> endobj 696 0 obj -(5.7.1.3. Getting More Context in a Patch) +(5.5.3. Bug Lists) endobj 697 0 obj -<< /S /GoTo /D (9.35.59.50.3) >> +<< /S /GoTo /D (9.34.61.2) >> endobj 700 0 obj -(5.7.1.4. Collapsing and Expanding Sections of a Patch) +(5.5.4. Adding/removing tags to/from bugs) endobj 701 0 obj -<< /S /GoTo /D (9.35.59.51.3) >> +<< /S /GoTo /D (9.35.1) >> endobj 704 0 obj -(5.7.1.5. Linking to a Section of a Patch) +(5.6. Filing Bugs) endobj 705 0 obj -<< /S /GoTo /D (9.35.59.52.3) >> +<< /S /GoTo /D (9.35.62.2) >> endobj 708 0 obj -(5.7.1.6. Going to Bonsai and LXR) +(5.6.1. Reporting a New Bug) endobj 709 0 obj -<< /S /GoTo /D (9.35.59.53.3) >> +<< /S /GoTo /D (9.35.63.2) >> endobj 712 0 obj -(5.7.1.7. Creating a Unified Diff) +(5.6.2. Clone an Existing Bug) endobj 713 0 obj << /S /GoTo /D (9.36.1) >> endobj 716 0 obj -(5.8. Hints and Tips) +(5.7. Attachments) endobj 717 0 obj -<< /S /GoTo /D (9.36.60.2) >> +<< /S /GoTo /D (9.36.64.2) >> endobj 720 0 obj -(5.8.1. Autolinkification) +(5.7.1. Patch Viewer) endobj 721 0 obj -<< /S /GoTo /D (9.36.61.2) >> +<< /S /GoTo /D (9.36.64.48.3) >> endobj 724 0 obj -(5.8.2. Comments) +(5.7.1.1. Viewing Patches in Patch Viewer) endobj 725 0 obj -<< /S /GoTo /D (9.36.62.2) >> +<< /S /GoTo /D (9.36.64.49.3) >> endobj 728 0 obj -(5.8.3. Dependency Tree) +(5.7.1.2. Seeing the Difference Between Two Patches) endobj 729 0 obj -<< /S /GoTo /D (9.37.1) >> +<< /S /GoTo /D (9.36.64.50.3) >> endobj 732 0 obj -(5.9. Time Tracking Information) +(5.7.1.3. Getting More Context in a Patch) endobj 733 0 obj -<< /S /GoTo /D (9.38.1) >> +<< /S /GoTo /D (9.36.64.51.3) >> endobj 736 0 obj -(5.10. User Preferences) +(5.7.1.4. Collapsing and Expanding Sections of a Patch) endobj 737 0 obj -<< /S /GoTo /D (9.38.63.2) >> +<< /S /GoTo /D (9.36.64.52.3) >> endobj 740 0 obj -(5.10.1. Account Preferences) +(5.7.1.5. Linking to a Section of a Patch) endobj 741 0 obj -<< /S /GoTo /D (9.38.64.2) >> +<< /S /GoTo /D (9.36.64.53.3) >> endobj 744 0 obj -(5.10.2. General Preferences) +(5.7.1.6. Going to Bonsai and LXR) endobj 745 0 obj -<< /S /GoTo /D (9.38.65.2) >> +<< /S /GoTo /D (9.36.64.54.3) >> endobj 748 0 obj -(5.10.3. Email Preferences) +(5.7.1.7. Creating a Unified Diff) endobj 749 0 obj -<< /S /GoTo /D (9.38.66.2) >> +<< /S /GoTo /D (9.37.1) >> endobj 752 0 obj -(5.10.4. Permissions) +(5.8. Hints and Tips) endobj 753 0 obj -<< /S /GoTo /D (9.39.1) >> +<< /S /GoTo /D (9.37.65.2) >> endobj 756 0 obj -(5.11. Reports and Charts) +(5.8.1. Autolinkification) endobj 757 0 obj -<< /S /GoTo /D (9.39.67.2) >> +<< /S /GoTo /D (9.37.66.2) >> endobj 760 0 obj -(5.11.1. Reports) +(5.8.2. Comments) endobj 761 0 obj -<< /S /GoTo /D (9.39.68.2) >> +<< /S /GoTo /D (9.37.67.2) >> endobj 764 0 obj -(5.11.2. Charts) +(5.8.3. Dependency Tree) endobj 765 0 obj -<< /S /GoTo /D (9.39.68.54.3) >> +<< /S /GoTo /D (9.38.1) >> endobj 768 0 obj -(5.11.2.1. Creating Charts) +(5.9. Time Tracking Information) endobj 769 0 obj -<< /S /GoTo /D (9.39.68.55.3) >> +<< /S /GoTo /D (9.39.1) >> endobj 772 0 obj -(5.11.2.2. Creating New Data Sets) +(5.10. User Preferences) endobj 773 0 obj -<< /S /GoTo /D (9.40.1) >> +<< /S /GoTo /D (9.39.68.2) >> endobj 776 0 obj -(5.12. Flags) +(5.10.1. Account Preferences) endobj 777 0 obj -<< /S /GoTo /D (9.41.1) >> +<< /S /GoTo /D (9.39.69.2) >> endobj 780 0 obj -(5.13. Whining) +(5.10.2. General Preferences) endobj 781 0 obj -<< /S /GoTo /D (9.41.69.2) >> +<< /S /GoTo /D (9.39.70.2) >> endobj 784 0 obj -(5.13.1. The Event) +(5.10.3. Email Preferences) endobj 785 0 obj -<< /S /GoTo /D (9.41.70.2) >> +<< /S /GoTo /D (9.39.71.2) >> endobj 788 0 obj -(5.13.2. Whining Schedule) +(5.10.4. Permissions) endobj 789 0 obj -<< /S /GoTo /D (9.41.71.2) >> +<< /S /GoTo /D (9.40.1) >> endobj 792 0 obj -(5.13.3. Whining Queries) +(5.11. Reports and Charts) endobj 793 0 obj -<< /S /GoTo /D (9.41.72.2) >> +<< /S /GoTo /D (9.40.72.2) >> endobj 796 0 obj -(5.13.4. Saving Your Changes) +(5.11.1. Reports) endobj 797 0 obj -<< /S /GoTo /D (10.0) >> +<< /S /GoTo /D (9.40.73.2) >> endobj 800 0 obj -(Chapter 6. Customizing Bugzilla) +(5.11.2. Charts) endobj 801 0 obj -<< /S /GoTo /D (10.42.1) >> +<< /S /GoTo /D (9.40.73.55.3) >> endobj 804 0 obj -(6.1. Template Customization) +(5.11.2.1. Creating Charts) endobj 805 0 obj -<< /S /GoTo /D (10.42.73.2) >> +<< /S /GoTo /D (9.40.73.56.3) >> endobj 808 0 obj -(6.1.1. Template Directory Structure) +(5.11.2.2. Creating New Data Sets) endobj 809 0 obj -<< /S /GoTo /D (10.42.74.2) >> +<< /S /GoTo /D (9.41.1) >> endobj 812 0 obj -(6.1.2. Choosing a Customization Method) +(5.12. Flags) endobj 813 0 obj -<< /S /GoTo /D (10.42.75.2) >> +<< /S /GoTo /D (9.42.1) >> endobj 816 0 obj -(6.1.3. How To Edit Templates) +(5.13. Whining) endobj 817 0 obj -<< /S /GoTo /D (10.42.76.2) >> +<< /S /GoTo /D (9.42.74.2) >> endobj 820 0 obj -(6.1.4. Template Formats and Types) +(5.13.1. The Event) endobj 821 0 obj -<< /S /GoTo /D (10.42.77.2) >> +<< /S /GoTo /D (9.42.75.2) >> endobj 824 0 obj -(6.1.5. Particular Templates) +(5.13.2. Whining Schedule) endobj 825 0 obj -<< /S /GoTo /D (10.42.78.2) >> +<< /S /GoTo /D (9.42.76.2) >> endobj 828 0 obj -(6.1.6. Configuring Bugzilla to Detect the User's Language) +(5.13.3. Whining Searches) endobj 829 0 obj -<< /S /GoTo /D (10.43.1) >> +<< /S /GoTo /D (9.42.77.2) >> endobj 832 0 obj -(6.2. Template Hooks) +(5.13.4. Saving Your Changes) endobj 833 0 obj -<< /S /GoTo /D (10.44.1) >> +<< /S /GoTo /D (10.0) >> endobj 836 0 obj -(6.3. Customizing Who Can Change What) +(Chapter 6. Customising Bugzilla) endobj 837 0 obj -<< /S /GoTo /D (10.44.79.2) >> +<< /S /GoTo /D (10.43.1) >> endobj 840 0 obj -(6.3.1. Modification in UserInGroup\(\)) +(6.1. Custom Skins) endobj 841 0 obj -<< /S /GoTo /D (10.45.1) >> +<< /S /GoTo /D (10.44.1) >> endobj 844 0 obj -(6.4. Modifying Your Running System) +(6.2. Template Customization) endobj 845 0 obj -<< /S /GoTo /D (10.46.1) >> +<< /S /GoTo /D (10.44.78.2) >> endobj 848 0 obj -(6.5. Integrating Bugzilla with ThirdParty Tools) +(6.2.1. Template Directory Structure) endobj 849 0 obj -<< /S /GoTo /D (10.46.80.2) >> +<< /S /GoTo /D (10.44.79.2) >> endobj 852 0 obj -(6.5.1. Bonsai) +(6.2.2. Choosing a Customization Method) endobj 853 0 obj -<< /S /GoTo /D (10.46.81.2) >> +<< /S /GoTo /D (10.44.80.2) >> endobj 856 0 obj -(6.5.2. CVS) +(6.2.3. How To Edit Templates) endobj 857 0 obj -<< /S /GoTo /D (10.46.82.2) >> +<< /S /GoTo /D (10.44.81.2) >> endobj 860 0 obj -(6.5.3. Perforce SCM) +(6.2.4. Template Formats and Types) endobj 861 0 obj -<< /S /GoTo /D (10.46.83.2) >> +<< /S /GoTo /D (10.44.82.2) >> endobj 864 0 obj -(6.5.4. Subversion) +(6.2.5. Particular Templates) endobj 865 0 obj -<< /S /GoTo /D (10.46.84.2) >> +<< /S /GoTo /D (10.44.83.2) >> endobj 868 0 obj -(6.5.5. Tinderbox/Tinderbox2) +(6.2.6. Configuring Bugzilla to Detect the User's Language) endobj 869 0 obj -<< /S /GoTo /D (11.0) >> +<< /S /GoTo /D (10.45.1) >> endobj 872 0 obj -(Appendix A. The Bugzilla FAQ) +(6.3. The Bugzilla Extension Mechanism) endobj 873 0 obj -<< /S /GoTo /D (12.0) >> +<< /S /GoTo /D (10.46.1) >> endobj 876 0 obj -(Appendix B. Troubleshooting) +(6.4. Customizing Who Can Change What) endobj 877 0 obj -<< /S /GoTo /D (12.47.1) >> +<< /S /GoTo /D (10.47.1) >> endobj 880 0 obj -(B.1. General Advice) +(6.5. Integrating Bugzilla with ThirdParty Tools) endobj 881 0 obj -<< /S /GoTo /D (12.48.1) >> +<< /S /GoTo /D (10.47.84.2) >> endobj 884 0 obj -(B.2. The Apache webserver is not serving Bugzilla pages) +(6.5.1. Bonsai) endobj 885 0 obj -<< /S /GoTo /D (12.49.1) >> +<< /S /GoTo /D (10.47.85.2) >> endobj 888 0 obj -(B.3. I installed a Perl module, but checksetup.pl claims it's not installed!) +(6.5.2. CVS) endobj 889 0 obj -<< /S /GoTo /D (12.50.1) >> +<< /S /GoTo /D (10.47.86.2) >> endobj 892 0 obj -(B.4. DBD::Sponge::db prepare failed) +(6.5.3. Perforce SCM) endobj 893 0 obj -<< /S /GoTo /D (12.51.1) >> +<< /S /GoTo /D (10.47.87.2) >> endobj 896 0 obj -(B.5. cannot chdir\(/var/spool/mqueue\)) +(6.5.4. Subversion) endobj 897 0 obj -<< /S /GoTo /D (12.52.1) >> +<< /S /GoTo /D (10.47.88.2) >> endobj 900 0 obj -(B.6. Your vendor has not defined Fcntl macro ONOINHERIT) +(6.5.5. Tinderbox/Tinderbox2) endobj 901 0 obj -<< /S /GoTo /D (12.53.1) >> +<< /S /GoTo /D (11.0) >> endobj 904 0 obj -(B.7. Everybody is constantly being forced to relogin) +(Appendix A. The Bugzilla FAQ) endobj 905 0 obj -<< /S /GoTo /D (12.54.1) >> +<< /S /GoTo /D (12.0) >> endobj 908 0 obj -(B.8. Some users are constantly being forced to relogin) +(Appendix B. Troubleshooting) endobj 909 0 obj -<< /S /GoTo /D (12.55.1) >> +<< /S /GoTo /D (12.48.1) >> endobj 912 0 obj -(B.9. index.cgi doesn't show up unless specified in the URL) +(B.1. General Advice) endobj 913 0 obj -<< /S /GoTo /D (12.56.1) >> +<< /S /GoTo /D (12.49.1) >> endobj 916 0 obj -(B.10. checksetup.pl reports "Client does not support authentication protocol requested by server...") +(B.2. The Apache webserver is not serving Bugzilla pages) endobj 917 0 obj -<< /S /GoTo /D (13.0) >> +<< /S /GoTo /D (12.50.1) >> endobj 920 0 obj -(Appendix C. Contrib) +(B.3. I installed a Perl module, but checksetup.pl claims it's not installed!) endobj 921 0 obj -<< /S /GoTo /D (13.57.1) >> +<< /S /GoTo /D (12.51.1) >> endobj 924 0 obj -(C.1. Commandline Search Interface) +(B.4. DBD::Sponge::db prepare failed) endobj 925 0 obj -<< /S /GoTo /D (13.58.1) >> +<< /S /GoTo /D (12.52.1) >> endobj 928 0 obj -(C.2. Commandline 'Send Unsent Bugmail' tool) +(B.5. cannot chdir\(/var/spool/mqueue\)) endobj 929 0 obj -<< /S /GoTo /D (14.0) >> +<< /S /GoTo /D (12.53.1) >> endobj 932 0 obj -(Appendix D. Manual Installation of Perl Modules) +(B.6. Everybody is constantly being forced to relogin) endobj 933 0 obj -<< /S /GoTo /D (14.59.1) >> +<< /S /GoTo /D (12.54.1) >> endobj 936 0 obj -(D.1. Instructions) +(B.7. Some users are constantly being forced to relogin) endobj 937 0 obj -<< /S /GoTo /D (14.60.1) >> +<< /S /GoTo /D (12.55.1) >> endobj 940 0 obj -(D.2. Download Locations) +(B.8. index.cgi doesn't show up unless specified in the URL) endobj 941 0 obj -<< /S /GoTo /D (14.61.1) >> +<< /S /GoTo /D (12.56.1) >> endobj 944 0 obj -(D.3. Optional Modules) +(B.9. checksetup.pl reports "Client does not support authentication protocol requested by server...") endobj 945 0 obj -<< /S /GoTo /D (15.0) >> +<< /S /GoTo /D (13.0) >> endobj 948 0 obj -(Appendix E. GNU Free Documentation License) +(Appendix C. Contrib) endobj 949 0 obj -<< /S /GoTo /D (15.62.1) >> +<< /S /GoTo /D (13.57.1) >> endobj 952 0 obj -(0. Preamble) +(C.1. Commandline Search Interface) endobj 953 0 obj -<< /S /GoTo /D (15.63.1) >> +<< /S /GoTo /D (13.58.1) >> endobj 956 0 obj -(1. Applicability and Definition) +(C.2. Commandline 'Send Unsent Bugmail' tool) endobj 957 0 obj -<< /S /GoTo /D (15.64.1) >> +<< /S /GoTo /D (14.0) >> endobj 960 0 obj -(2. Verbatim Copying) +(Appendix D. Manual Installation of Perl Modules) endobj 961 0 obj -<< /S /GoTo /D (15.65.1) >> +<< /S /GoTo /D (14.59.1) >> endobj 964 0 obj -(3. Copying in Quantity) +(D.1. Instructions) endobj 965 0 obj -<< /S /GoTo /D (15.66.1) >> +<< /S /GoTo /D (14.60.1) >> endobj 968 0 obj -(4. Modifications) +(D.2. Download Locations) endobj 969 0 obj -<< /S /GoTo /D (15.67.1) >> +<< /S /GoTo /D (14.61.1) >> endobj 972 0 obj -(5. Combining Documents) +(D.3. Optional Modules) endobj 973 0 obj -<< /S /GoTo /D (15.68.1) >> +<< /S /GoTo /D (15.0) >> endobj 976 0 obj -(6. Collections of Documents) +(Appendix E. GNU Free Documentation License) endobj 977 0 obj -<< /S /GoTo /D (15.69.1) >> +<< /S /GoTo /D (15.62.1) >> endobj 980 0 obj -(7. Aggregation with Independent Works) +(0. Preamble) endobj 981 0 obj -<< /S /GoTo /D (15.70.1) >> +<< /S /GoTo /D (15.63.1) >> endobj 984 0 obj -(8. Translation) +(1. Applicability and Definition) endobj 985 0 obj -<< /S /GoTo /D (15.71.1) >> +<< /S /GoTo /D (15.64.1) >> endobj 988 0 obj -(9. Termination) +(2. Verbatim Copying) endobj 989 0 obj -<< /S /GoTo /D (15.72.1) >> +<< /S /GoTo /D (15.65.1) >> endobj 992 0 obj -(10. Future Revisions of this License) +(3. Copying in Quantity) endobj 993 0 obj -<< /S /GoTo /D (15.73.1) >> +<< /S /GoTo /D (15.66.1) >> endobj 996 0 obj -(How to use this License for your documents) +(4. Modifications) endobj 997 0 obj -<< /S /GoTo /D (16.0) >> +<< /S /GoTo /D (15.67.1) >> endobj 1000 0 obj -(Glossary) +(5. Combining Documents) endobj 1001 0 obj -<< /S /GoTo /D (17.0) >> +<< /S /GoTo /D (15.68.1) >> endobj 1004 0 obj -(09, high ascii) +(6. Collections of Documents) endobj 1005 0 obj -<< /S /GoTo /D (17.73.85.2) >> +<< /S /GoTo /D (15.69.1) >> endobj 1008 0 obj -(.htaccess) +(7. Aggregation with Independent Works) endobj 1009 0 obj -<< /S /GoTo /D (18.0) >> +<< /S /GoTo /D (15.70.1) >> endobj 1012 0 obj -(A) +(8. Translation) endobj 1013 0 obj -<< /S /GoTo /D (18.73.86.2) >> +<< /S /GoTo /D (15.71.1) >> endobj 1016 0 obj -(Apache) +(9. Termination) endobj 1017 0 obj -<< /S /GoTo /D (18.73.86.56.3) >> +<< /S /GoTo /D (15.72.1) >> endobj 1020 0 obj -(Useful Directives when configuring Bugzilla) +(10. Future Revisions of this License) endobj 1021 0 obj -<< /S /GoTo /D (19.0) >> +<< /S /GoTo /D (15.73.1) >> endobj 1024 0 obj -(B) +(How to use this License for your documents) endobj 1025 0 obj -<< /S /GoTo /D (19.73.87.2) >> +<< /S /GoTo /D (16.0) >> endobj 1028 0 obj -(Bug) +(Glossary) endobj 1029 0 obj -<< /S /GoTo /D (19.73.88.2) >> +<< /S /GoTo /D (17.0) >> endobj 1032 0 obj -(Bug Number) +(09, high ascii) endobj 1033 0 obj -<< /S /GoTo /D (19.73.89.2) >> +<< /S /GoTo /D (17.73.89.2) >> endobj 1036 0 obj -(Bugzilla) +(.htaccess) endobj 1037 0 obj -<< /S /GoTo /D (20.0) >> +<< /S /GoTo /D (18.0) >> endobj 1040 0 obj -(C) +(A) endobj 1041 0 obj -<< /S /GoTo /D (20.73.90.2) >> +<< /S /GoTo /D (18.73.90.2) >> endobj 1044 0 obj -(Common Gateway Interface) +(Apache) endobj 1045 0 obj -<< /S /GoTo /D (20.73.91.2) >> +<< /S /GoTo /D (18.73.90.57.3) >> endobj 1048 0 obj -(Component) +(Useful Directives when configuring Bugzilla) endobj 1049 0 obj -<< /S /GoTo /D (20.73.92.2) >> +<< /S /GoTo /D (19.0) >> endobj 1052 0 obj -(Comprehensive Perl Archive Network) +(B) endobj 1053 0 obj -<< /S /GoTo /D (20.73.93.2) >> +<< /S /GoTo /D (19.73.91.2) >> endobj 1056 0 obj -(contrib) +(Bug) endobj 1057 0 obj -<< /S /GoTo /D (21.0) >> +<< /S /GoTo /D (19.73.92.2) >> endobj 1060 0 obj -(D) +(Bug Number) endobj 1061 0 obj -<< /S /GoTo /D (21.73.94.2) >> +<< /S /GoTo /D (19.73.93.2) >> endobj 1064 0 obj -(daemon) +(Bugzilla) endobj 1065 0 obj -<< /S /GoTo /D (21.73.95.2) >> +<< /S /GoTo /D (20.0) >> endobj 1068 0 obj -(DOS Attack) +(C) endobj 1069 0 obj -<< /S /GoTo /D (22.0) >> +<< /S /GoTo /D (20.73.94.2) >> endobj 1072 0 obj -(G) +(Common Gateway Interface) endobj 1073 0 obj -<< /S /GoTo /D (22.73.96.2) >> +<< /S /GoTo /D (20.73.95.2) >> endobj 1076 0 obj -(Groups) +(Component) endobj 1077 0 obj -<< /S /GoTo /D (23.0) >> +<< /S /GoTo /D (20.73.96.2) >> endobj 1080 0 obj -(J) +(Comprehensive Perl Archive Network) endobj 1081 0 obj -<< /S /GoTo /D (23.73.97.2) >> +<< /S /GoTo /D (20.73.97.2) >> endobj 1084 0 obj -(JavaScript) +(contrib) endobj 1085 0 obj -<< /S /GoTo /D (24.0) >> +<< /S /GoTo /D (21.0) >> endobj 1088 0 obj -(M) +(D) endobj 1089 0 obj -<< /S /GoTo /D (24.73.98.2) >> +<< /S /GoTo /D (21.73.98.2) >> endobj 1092 0 obj -(Message Transport Agent) +(daemon) endobj 1093 0 obj -<< /S /GoTo /D (24.73.99.2) >> +<< /S /GoTo /D (21.73.99.2) >> endobj 1096 0 obj -(MySQL) +(DOS Attack) endobj 1097 0 obj -<< /S /GoTo /D (25.0) >> +<< /S /GoTo /D (22.0) >> endobj 1100 0 obj -(P) +(G) endobj 1101 0 obj -<< /S /GoTo /D (25.73.100.2) >> +<< /S /GoTo /D (22.73.100.2) >> endobj 1104 0 obj -(Perl Package Manager) +(Groups) endobj 1105 0 obj -<< /S /GoTo /D (25.73.101.2) >> +<< /S /GoTo /D (23.0) >> endobj 1108 0 obj -(Product) +(J) endobj 1109 0 obj -<< /S /GoTo /D (25.73.102.2) >> +<< /S /GoTo /D (23.73.101.2) >> endobj 1112 0 obj -(Perl) +(JavaScript) endobj 1113 0 obj -<< /S /GoTo /D (26.0) >> +<< /S /GoTo /D (24.0) >> endobj 1116 0 obj -(Q) +(M) endobj 1117 0 obj -<< /S /GoTo /D (26.73.103.2) >> +<< /S /GoTo /D (24.73.102.2) >> endobj 1120 0 obj -(QA) +(Message Transport Agent) endobj 1121 0 obj -<< /S /GoTo /D (27.0) >> +<< /S /GoTo /D (24.73.103.2) >> endobj 1124 0 obj -(R) +(MySQL) endobj 1125 0 obj -<< /S /GoTo /D (27.73.104.2) >> +<< /S /GoTo /D (25.0) >> endobj 1128 0 obj -(Relational DataBase Management System) +(P) endobj 1129 0 obj -<< /S /GoTo /D (27.73.105.2) >> +<< /S /GoTo /D (25.73.104.2) >> endobj 1132 0 obj -(Regular Expression) +(Perl Package Manager) endobj 1133 0 obj -<< /S /GoTo /D (28.0) >> +<< /S /GoTo /D (25.73.105.2) >> endobj 1136 0 obj -(S) +(Product) endobj 1137 0 obj -<< /S /GoTo /D (28.73.106.2) >> +<< /S /GoTo /D (25.73.106.2) >> endobj 1140 0 obj -(Service) +(Perl) endobj 1141 0 obj -<< /S /GoTo /D (28.73.107.2) >> +<< /S /GoTo /D (26.0) >> endobj 1144 0 obj -(SGML ) +(Q) endobj 1145 0 obj -<< /S /GoTo /D (29.0) >> +<< /S /GoTo /D (26.73.107.2) >> endobj 1148 0 obj -(T) +(QA) endobj 1149 0 obj -<< /S /GoTo /D (29.73.108.2) >> +<< /S /GoTo /D (27.0) >> endobj 1152 0 obj -(Target Milestone) +(R) endobj 1153 0 obj -<< /S /GoTo /D (29.73.109.2) >> +<< /S /GoTo /D (27.73.108.2) >> endobj 1156 0 obj -(Tool Command Language) +(Relational DataBase Management System) endobj 1157 0 obj -<< /S /GoTo /D (30.0) >> +<< /S /GoTo /D (27.73.109.2) >> endobj 1160 0 obj -(Z) +(Regular Expression) endobj 1161 0 obj -<< /S /GoTo /D (30.73.110.2) >> +<< /S /GoTo /D (28.0) >> endobj 1164 0 obj -(Zarro Boogs Found) +(S) endobj 1165 0 obj -<< /S /GoTo /D [1166 0 R /Fit ] >> +<< /S /GoTo /D (28.73.110.2) >> +endobj +1168 0 obj +(Service) +endobj +1169 0 obj +<< /S /GoTo /D (28.73.111.2) >> +endobj +1172 0 obj +(SGML ) +endobj +1173 0 obj +<< /S /GoTo /D (29.0) >> +endobj +1176 0 obj +(T) +endobj +1177 0 obj +<< /S /GoTo /D (29.73.112.2) >> +endobj +1180 0 obj +(Target Milestone) +endobj +1181 0 obj +<< /S /GoTo /D (29.73.113.2) >> +endobj +1184 0 obj +(Tool Command Language) +endobj +1185 0 obj +<< /S /GoTo /D (30.0) >> endobj -1168 0 obj << -/Length 182 +1188 0 obj +(Z) +endobj +1189 0 obj +<< /S /GoTo /D (30.73.114.2) >> +endobj +1192 0 obj +(Zarro Boogs Found) +endobj +1193 0 obj +<< /S /GoTo /D [1194 0 R /Fit ] >> +endobj +1196 0 obj << +/Length 180 /Filter /FlateDecode >> stream -xڍP� -�@�����]һ�ւ�6q(z�B;I�ޫ-� "^�{y�ĀNe@ -' ��,��LC��&3��t�R꿐ʲ��ԇC�͎�D����f��� \�y��B�Ty=u�~�ej���jJ+�K�Cl�8��+���s���1��富P8��v�m�mx߲����2��'��?Hendstream +xڍ�?�@������%��ӵ�G�M�=k�������+� "�/�BB�R8B��p�l �g�`HI+h���E6���P����� b�c \��!\�(9���Bf���p��d�f��4u�k��_�E������by +��2��7���Z�5կ������Ĉmx_�>���������G�endstream endobj -1166 0 obj << +1194 0 obj << /Type /Page -/Contents 1168 0 R -/Resources 1167 0 R +/Contents 1196 0 R +/Resources 1195 0 R /MediaBox [0 0 609.714 789.041] -/Parent 1174 0 R +/Parent 1202 0 R >> endobj -1169 0 obj << -/D [1166 0 R /XYZ 71.731 729.265 null] +1197 0 obj << +/D [1194 0 R /XYZ 71.731 729.265 null] >> endobj -1170 0 obj << -/D [1166 0 R /XYZ 71.731 718.306 null] +1198 0 obj << +/D [1194 0 R /XYZ 71.731 718.306 null] >> endobj -1171 0 obj << -/D [1166 0 R /XYZ 71.731 718.306 null] +1199 0 obj << +/D [1194 0 R /XYZ 71.731 718.306 null] >> endobj 2 0 obj << -/D [1166 0 R /XYZ 512.21 700.222 null] +/D [1194 0 R /XYZ 494.981 700.222 null] >> endobj -1167 0 obj << -/Font << /F23 1173 0 R >> +1195 0 obj << +/Font << /F23 1201 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1177 0 obj << -/Length 526 +1205 0 obj << +/Length 521 /Filter /FlateDecode >> stream -xڍT���0��*% �yXW�E�R-uI -Z�%!:�����9�� E��s��y32�(�XT0RxxEx�Eʹ�Q���<'<� �Ùf� U)������pU��ET�nEhI�������U��_��}G���:�����I�bΉ@���4*�Y�Ž�R�I�:���3ʀ�Pƙ���JN�e�TT�̷�8�W-FrJ���)��U���Y�o[_�Ҭ�����2��h�m�|@�D�1�4^��j�����j����� ç�c�ee��?��Е�Q�~�>����� �����Qۀ�F�\NȂYN��0K����Ar��'� `0r0l�a�`�s`w0fU���Яs�U�B�3� {x��nhzY=� -���w��%���P��_^T@��(5��@(%�'ȂA���s6ׇ�~�N�V��N��+�l] &C�v��e����:�}z�gzs]��yOx�?hF{k�������I`��H��ewL0��4B2�,�>;|������ᅤ?j�$%endstream +xڍTɎ�0��+|��Z��x�q�v���om�-/��@�d���(g)z(rER�|�tx��ǃ��"�#�h�gA3X�C���}�1�i�%`�#eiA�2 ����IҠ�U�uw+�J��A�~'� �()J����4 ��nc�) 9ah��Z�?�P��`A�ZA��t���`<�`D���ؗIF+���o�i� [�L+"�E�����2�`Ԑ�gϜW��l�\�0�`�[��^>�_��&�l}d�h~�K�A}�F��c�u��yu@yIz���]��ЏTg5j5��>z_6r'�d��ڡ +z��%���4�0�j�g� `@�;v�O�{����ޤw�<`��*����y��ߝ�;�Z7x����tݮjj�li��7//*Q��M)�.%#�Cb������a�����{�+�5�dK�ZW��O�^��Zs]v<����>=�u�ٮD�<'\�,c�1�q|�\B5��?-I-k�C>w�>��ǒ���?R� endstream endobj -1176 0 obj << +1204 0 obj << /Type /Page -/Contents 1177 0 R -/Resources 1175 0 R +/Contents 1205 0 R +/Resources 1203 0 R /MediaBox [0 0 609.714 789.041] -/Parent 1174 0 R +/Parent 1202 0 R >> endobj -1178 0 obj << -/D [1176 0 R /XYZ 71.731 729.265 null] +1206 0 obj << +/D [1204 0 R /XYZ 71.731 729.265 null] >> endobj -1175 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R >> +1203 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1183 0 obj << -/Length 56511 +1211 0 obj << +/Length 56328 /Filter /FlateDecode >> stream -xڔ�M�lGb%���Xt����wC��6���ҴI2�����&Lh��q~�n�'�NT^Oo�?p�����+��{��n���7/�����/�o���o���u�͟������y�x|~>�?�o�����wO/��ׇo~�������������������yZ�N�������o����ݷ���w�o�����_^�����������O������������lP�_�NoOW���q�w�|����7�����29�~��i3?�}�����m����~��������e�����t��L��;�|����G�h}����E�ϧ���k�lgٺ����Wk��ް6���|zxy���� k�����i��ް6�u����IZ�Y�.���_�u?{�����ޤu?{������u?{�������1�;�~���;Pn��|���� i��3����� k����7����ް6���|�߾*�8��x`}8��X�~���������u?{�������7�q����W��w�cxt֜E� -<�n���YZ��7� <�n���EZ��7� <�n��l����^����p���,[�������&����X�O�Wk��ް6���zz�_�Go8w]y>m���,K��u{�ֺ��am��u{O�Һ��am��u{ -�Һ��am�u����u�e�<�n���QZ��7� <�n��,�ጳ7� <�n���Z��7� �n}<���u�e�<�>��^�7�q���������goXx`}==ٿ -��7� �n}�Ó��3βuX���h����X�� �"���,܁r{��8{C�������K�8��x`ݞ�Y~�goXx`ݞ��goXx`}==��os�� k�[_�No����q�����pz|���� k�O�y�mn��am��u{O���8{�������1<J�8��x`�Ã�67�ް6���=�{�mn��am��u{gk��ް6��m{w���8��x`��t���a�;�=��oY��7��;P��^�7�q����W�ww����&gѺ���gk��ް6���=��i��ް6���=��Gi��ް6���=�igٺ���c����� k��c8?K�~������1�Y�~�����w��7� .gٺ��������goXx`}:��X�~����������goXx���=�'�~���;Pn�@�Zݏ�P�@�=�dzt�goHx`���G�9{��������K�8��x`ݞ�Y~�goXx`���1D�ް6���z:�Y�~����Ow�g�ɓ�e�<�>���/�� k�O��gk��ް6���=�ɓ��am�u����'Or�����=�k��ް6���=�ɓ��am��u{�/�����]W�l�@~�ُ��q���Y�~����֧ӓ��I�ް6���z�{���� k�[_�NO�c'9��x`}8�ɏ��� k��cx���� k��c�;���^��m��AZ�Y�.�������q������1ȏ��� k��c����� k�Z��N�o�{\uX�Oo�gx9{��������Z��7� <��������]W��g ���,K��u{Oֺ��am��u{��Һ��am��u{ -�c'9{�������1�K�8��x`���QZ��7� <�n�A~�$goXx`}9��Y�~����w��W�m.gٺ����W�����am������l����X���$�͍�7� �n}����IβuX���`����X�� �Ҵ��,܁r{�c'9{C���֧��`"gٺ���3�;���X�N��c'9{��������Z��7� �n}�;�ˏ��,[�����"?v��7� <�n���Z��7� <�n�A~�$goXx���=����e�<�n���Z��7� <�n�A~�$goXx`����I�ް6����t��DβuX�O�V��� g��O����I�ސ6���rz~���� k�[߶g ?|��l]���)���� k��cx���� k��c�>���^�>�m�A��E� -<�n��l����X�� ?|��7� <�����ϙr�����ӝ&r����zz�>���X�Nw�ֺ��am��u{2����^��o�A��ُ��q��<J�ף7��;Pn@�9{C������Or�����#���7gٺ���S�{�%��\p4 �p����`s�6[>_d���}���s<��xx�u�����l�b��~���q�N�pY�y�\h�ɑ}C&+2������/?��_ƚ�����������?]���?�q�}��m��_�K� �������ߟ��7Z������Fk��6���ur������@5�7Z�����������8g�M�������Fk��V���hm ��ʚ�� ���Xg�M�������Fk��V���hm ��ʚ�� ���Xg�M�������Fk��V���hm ��ʚ�� ���Xg�M�������Fk��V����p�+g�o�6��oc��7Y ��ʚ�� ��[Y�����+k�o�6��oc��7Y ��ʚ�� ��[Y�����+k�o�6��oc��7Y ��ʚ�� ��[Y�����+k�o�6��oc��7Y ��ʹ��h���[ G����q����Q�@���ur������@5�7Z������Fk��6���ur������@5�7Z������Fk��6���ur������@5�7Z������Fk��6����l��J9�oT��o�L���r������@u��d]��+k�o�6��oeM���r������@u��d]��+k�o�6��oeM���r������@u��d]��+k�o�6��oeM���b�����Fg��6��ߤl��ʙ�� ��[Y�����+k�o�6��oc��7Y ��ʚ�� ��[Y�����+k�o�6��oc��7Y ��ʚ�� ��[Y�����+k�o�6��oa���`]��+k�o�6��oeM���b�����Fg��6���tr������@5�7Z������Fk��6���ur������@5�7Z������Fk��6���ur������@5�7Z������Fk��6���ur������@쿕t���,��ʙ�� ���Xg�M�������Fk��V���hm ��ʚ�� ���Xg�M�������Fk��V���hm ��ʚ�� ���Xg�M�������Fk��V���hm ��ʚ�� ���Xg�M�����������[9�����+k�o�6��oc��7Y ��ʚ�� ��[Y�����+k�o�6��oa���`]��+k�o�6��oeM���r������@u��d]��+k�o�6��oeM���r������@쿍4�79���R������[9�����+k�o�6��oc��7Y ���/��/2��a�}|����ϝo��O�!&�����ߏ��?���?~�ß����-�Oϧ���wE:ow���:?��~v��C���u�������,?_�u�e�<�>�^_�u?{���������6ʺ��am�������3Ke��ް6��e{O�:βuX����Qe��ް6���=���Y*�~������1�[�~������c�w��(;w�ܞ��,����X�gpg����X_��.ۯ�~����o����oX�:βuXN//ֺ��am����t��(����X���$�ጳ7� <�4�ã��,ZW��u��(kVc��@^�Q֬Ơ�����Y�Aky5�X�jY ��(kVc��@^�Q֬Ơ�����c5����㜫1$]����Y�Aky5FY����j��f5� ��c��1d]����Y�Aky5FY����j��f5� ��c��1d]����Y�Aky5FY����j��f5� ��c��1d]����Y�Akq5FI�j:ǫ1ʙ��6�Wc�u�Ɛu�j��f5� ��e�jZȫ1ʚ��6�Wc�u�Ɛu�j��f5� ��e�jZȫ1ʚ��6�Wc�u�Ɛu�j��f5� ��e�jZȫ1ʚ��6�Wc�u�Ɛu�j�r�1h���%�1h,��(gVcP�@^���jXW ��(kVc��@^�Q֬Ơ�����Y�Aky5�X�jY ��(kVc��@^�Q֬Ơ�����Y�Aky5�X�jY ��(kVc��@^�Q֬Ơ�����Y�Akq5�H�C���j�R��T�Wc�3�1(m ��(kVc��@^�1ֹC�ȫ1ʚ��6�Wc�5�1hm ��(kVc��@^�1ֹC�ȫ1ʚ��6�Wc�5�1hm ��(kVc��@^�1ֹC�ȫ1ʚ��6�Wc�5�1hm ��(�X�Ag�p5�(�C���j�rf5� ��e�jZȫ1ʚ��6�Wc�u�Ɛu�j��f5� ��e�jZȫ1ʚ��6�Wc�u�Ɛu�j��f5� ��e�jZȫ1ʚ��6�Wc����ȫ1ʚ��6�Wc�5�1hm ��(�X�Ag�x5�8�jI ��(kVc��@^�Q֬Ơ�����Y�Aky5�X�jY ��(kVc��@^�Q֬Ơ�����Y�Aky5�X�jY ��(kVc��@^�Q֬Ơ�����Y�Aky5�X�jY ��(kVc��@\�Qұ����j�rf5� ��c��1d]����Y�Aky5FY����j��f5� ��c��1d]����Y�Aky5FY����j��f5� ��c��1d]����Y�Aky5FY����j��f5� ��c��1d]����c5������jJȫ1ʚ��6�Wc�u�Ɛu�j��f5� ��e�jZȫ1ʚ��6�Wc����ȫ1ʚ��6�Wc�5�1hm ��(kVc��@^�1ֹC�ȫ1ʚ��6�Wc�5�1hm ��(kVc��@\�1ҬƐ�q���c5������jJȫ1ʚ��6�Wc�u�Ɛu�j���[�����+-��1�YVcμ��^�h�~bߌy�1����o��߾;���~���~���k�"����+_���� �95r|Ϲ4r����ȧ[��(�+#F��R�'F�2#�,�e�EHY8�l���`�,b�!c�xV�(�*B���QfR����A��{"�l��e�DHY8�1�,���p�#b��!e�xD��!r�\p� b�!e�x>�(�B���v�Qf:��������!�l��eFCHY8�1�,���p�b�c.��a<"�s+�����P)�3!F��R�7B�2!�,���e�x�(3B���4�Qf����]��,)ǣ B97A@�8^1����p<b�Y!e�x�(3B����P�P6�W@�2# �,N��X�!�G�a�?�X8�ʹ�����Qf���������)ǛF��R�?�r�}��q��a�� e�x��(��A���·Qf惔�����l/|e>HY8��0ʬ{��p��a��� e�x�C(�(G�F��z�� -'=�m,z��#��<�0sd,�y�V^�<����<�2C�,�xeV<HY8��0�Lx��p<�!�s�������x)��F��R�w;�2��,�v����e�x��(3�A���\�Qf�������T)�C�W:�o�t��#�':�0d,�se�9HY8�ʹ����2�Qf�����Y��*)ǛF�IR�9�r�q��q��a�� e�x��(��A����Qf��������l/pe8HY8��0ʬo��p��a�cz��a8�!|���_�xu�3�A����Qfq���� ���)�cB9�6@�8^�0�m��p<�a�Y� e�xc�(3�A�����P�} P6��5�2��,Oke�5HY8��0��j��p<�q[y��8V.8^�0�j��p<�a�Y� e�pK�ǔ ?�xHC��+F� R�'4�2�,�ge�3HY8�ʹ����r�Qf8�������j)ǛF��R�3�r�e��q��a�� e�x*�(��A���N�Qf&�������l/de2HY8��0Ʊ�A0��0�Lc��p<�!�s���U��()ǓF�ER��0�2s�,�a����e�x �(3�A����Qf���� ��)�B9�/@�8^�0ʌ_��p<}a�Y� e�x��(3{A����P��P6/�q^��#��.�0kd,o]e�.HY8�ʹs���ʅQf䂔�����)��F�yR��-n+/�����F�aR�g-�2��,oZe&-HY8�ʹg���Qf̂���)�̒)�;F�RG,�1 ,.X�� �G�Wa�+�X8ޮ0�LW��p<\!�s����� -�^�t��Y�a$�p����b��g��_14Y1���c��o~��O?��y����l��]���_��*N_�,��8��Z����������5�8��7� <�����u?{����֧���z�X�Y�.����ҭ����X��p���� k��cx����goXx��|>=����X�Y�.������Z��7� <�>�^��u?{����غQ�l砵���c�s>���t�5:hm o�(kFt��@��Q��蠵���c���!g�xLG9����fP� �IeͦZȫ:�:guȺ�yXGY����f\� �ye;Z�;�z��� -�e��Z�;;ʚ��6��v�5[;hm ����!���e��Zț;ʚ��6gw�t�p��c�sz����w�5�;hm ��(kx��@��Q�l𠵁��c�s�����x�5K<hm o�(k�x��@��Q����c�s����Gy�5�<hm ��(k�y��@��Q�l��c�s����z�5=hm n�(��Ag�x�G9�Ӄ��R��Ω�.@�Q֬�����ף��Aky�GY�ك��j�����.@�Q�,�����ݣ��Aky�GY�߃�� �.@�Q֬�����㣬�Aky�GY����9�.@�Q�}��a�飄c����Y�̮J��>�z��� -�qeͺZ��>ʚ��6�'~�5?hm ����!��e��Z�[?ʚ��6��~�5{?hm /���!���e��ZȻ?ʚ��6���5�?hm ��i���8�Rʱ������rf� � e�Z�K@�:��Ⱥ�yHY������f� �I e�&Zȫ@�:g�Ⱥ�yHY����6��f� �y e�>Z�A�:'�Ⱥ�y$HY����N��f(� ĩ %[A�,�e�H�8R�,������ Bky6HY����r���� �.@R֬������BkyBHY�!���!�.@R�, ����%��BkyNHY�'��^&���yTHY�*��fX� �i!%�B�,��"��!e��Z�Cʚ�!�6�g��5;Chm / �"��!e��Z�{Cʚ�!�6�'��5�Chm ��"���!e��Z��Cʚ�!�6�燔5�Chm /� "��"e� -Z�;DJ:���Y8�"R�l����Fd�s������5�Dhm o)kF���@�%R������Ld�s����lj�5�Dhm �)k���@�(R�l����Rd�s�������5KEhm o)kƊ��@�+R������Xd�s���G��t���p�[��.Biy�HY�]���z����"�.@0R�,����a��1Bky�HY�c��^����y�HY�f��f�� �I#eͦZȫF�:g�Ⱥ�y�HY�l��f�� �y#e;Z�GF��#r6G��r���p�s��:Biy�HY�u���ڑ�ι#�.@<:��q�Gx�1y��"���G�YF��y������=G�ѣ�1z�����������?}�x��������_���O�^K�_�?�r1��:�^����.n<��W>�?_�h�.@5]4Z�]����Fk��V��E��p�E��I����V�t�hm w�ʚ.� �.ZY�E����E��ɺ���V�t�hm w�ʚ.� �.ZY�E����E��ɺ���V�t�hm w�ʚ.� �.ZY�E����E��ɺ���V�t�hm v�J:�ht��h�L��rm���&��.ZY�E����E+k�h�6��heM��rm���&��.ZY�E����E+k�h�6��heM��rm���&��.ZY�E����E+k�h�6��heM��rm���&��.Z9�.�a�E+���X83]4J�]��^�h��@5]4Z�]����Fk��V�t�hm w��:�h�.@5]4Z�]����Fk��V�t�hm w��:�h�.@5]4Z�]����Fk��V�t�hm v�F�.����.Z)G���q���Q�@5]4Z�]���.����heM��r�����@5]4Z�]���.����heM��r�����@5]4Z�]���.����heM��r�����@좕tt��,v�F�.����.Z9�E����E+k�h�6��heM��rm���&��.ZY�E����E+k�h�6��heM��rm���&��.ZY�E����E+k�h�6��heM��r-��.�+��heM��r�����@좕tt��,w��9�h�.@5]4Z�]����Fk��V�t�hm w��:�h�.@5]4Z�]����Fk��V�t�hm w��:�h�.@5]4Z�]����Fk��V�t�hm w��:�h�.@5]4Z�]���.���.Z9�E����E��ɺ���V�t�hm w�ʚ.� �.ZY�E����E��ɺ���V�t�hm w�ʚ.� �.ZY�E����E��ɺ���V�t�hm w�ʚ.� �.ZY�E����E��ɺ���V��E��p�E+g�h�6��heM��rm���&��.ZY�E����E+k�h�6��heM��r-��.�+��heM��r�����@5]4Z�]���.����heM��r�����@5]4Z�]����&g㰋V��E��p�E+g�h�6��heM��rm���&��.�8�u]4^dt�.r�E_d�=������.��k}�������g��W�����y���˅ƙ�z�QE���~�����?������O�����ӛ���N������g�n������G�t��x�ϯ~8��>]���~��������˳��goXx`}=�>�H�~����۟.O�:βuX����*����X����&����X��po����^��n���I���l܁r{�t�goHx`ݞ����goXx`}=��ٯ�~����o����mDY�Y�.������Z��7� <�n���u?{�������7�q��������1<:kuX����,����X��p�"����X��g[.lm n�(k�\к�q��Yǖ[�[.�:�\��@�rq�}˅���-�̖J n�8��rakq��Yǖ[�[.�:�\��@�rQ�l��u▋��-�6�\�ul�������c˅� �-e͖Z n�8��rakq��Yǖ[�[.�:�\��@�rQ�l��u▋��-�6��\�t�rag�p��9ǖK�[.ʚ-�.@�rqֱ���▋��-�6�\�ul�����墬�rA��-g[.lm n�8��rakq��Yǖ[�[.ʚ-�.@�rqֱ���▋��-�6�\�ul�����墬�rA��-�����Ə0�rq�}˅���-�[.,m n���r!� -�-g[.lm n�8��rakq��Yǖ[�[.ʚ-�.@�rqֱ���▋��-�6�\�ul�����墬�rA��-g[.lm n�8��rakq��Yǖ[H[.J:�\��8�rq�}˅���-�[.,m n�8��rakq�EY����[.�:�\��@�rqֱ���▋��-�6�\�5[.h]����c˅� �-g[.lm n�8��rakq�EY����[.�:�\��@�rqֱ���Җ���[.�,m�(��rAe�p��9ǖK�[.�:�\��@�rqֱ���▋�f���\�ul�������c˅� �-g[.lm n�(k�\к�q��Yǖ[�[.�:�\��@�rqֱ���▋��-��@�rqֱ���▋��-�6��\�t�rag�p�E9����[.�:�\��@�rqֱ���▋��-�6�\�5[.h]����c˅� �-g[.lm n�8��rakq�EY����[.�:�\��@�rqֱ���▋��-�6�\�5[.h]����c˅� �-'ݷ\�Y8�rqα���▋�f���\�ul�������c˅� �-g[.lm n�(k�\к�q��Yǖ[�[.�:�\��@�rqֱ���▋�f���\�ul�������c˅� �-g[.lm n�(k�\к�i��I�-v�\�sl�������c˅� �-e͖Z n�8��rakq��Yǖ[�[.�:�\��@�r1ֹ�B��[.�:�\��@�rqֱ���▋��-�6�\�5[.h]����c˅� �-g[.lm n�8��raki�EIǖ:G[.N�o���p���c˅� �-g[.lm n�(k�\к�q�6IԖ_d?��"�G[.p��?y�pٷ\��پ�>����7n�����2�L��[.�^s���~����v��bs��j�mM>Xpyz���G�\}�ݕU�1���"�C�Ȼ1ʚ��6�wc�5�1hm ��(kvc��@ލ1ֹC�Ȼ1ʚ��6�wc�5�1hm ��(kvc��@܍1��Ɛ�q���ٍAiy7FY����n��f7� ��c��1d]����ٍAky7FY����n��f7� ��a��ƀu�n��f7� ��e�nZȻ1ʚ��6�wc�u�Ɛu�n��f7� ��e�nZ��1J:vc�Y8ލ1ιC�Ȼ1ʚ��6�wc�5�1hm ��(kvc��@ލ1ֹC�Ȼ1ʚ��6�wc�5�1hm ��(kvc��@ލ1ֹC�Ȼ1ʚ��6�wc�5�1hm ��(kvc��@ލ1ֹC�Ȼ1ʚ��6wc�t�Ơ�p���ٍAiy7�X�nY ��(kvc��@ލQ��Ơ�����ٍAky7�X�nY ��(kvc��@ލQ��Ơ�����ٍAky7�X�nY ��(kvc��@ލQ��Ơ�����ٍAky7�X�nY ��(��Ə0܍Q±����n�rf7� ��a��ƀu�n��f7� ��e�nZȻ1ʚ��6�wc�u�Ɛu�n��f7� ��e�nZȻ1ʚ��6�wc�u�Ɛu�n��f7� ��e�nZȻ1ʚ��6wc�4�1�l��(�؍Ae�x7F9����n��f7� ��c��1d]����ٍAky7FY����n��f7� ��c��1d]����ٍAky7FY����n��f7� ��c��1d]����ٍAky7FY����n����twc�2�1�l��(gvcP�@ލQ��Ơ�����ٍAky7�X�nY ��(kvc��@ލQ��Ơ�����ٍAky7�X�nY ��(kvc��@ލQ��Ơ�����ٍAky7FX/�1`]����ٍAky7FY����n����t�wc�s�Ɛt�n��f7� ��e�nZȻ1ʚ��6�wc�u�Ɛu�n��f7� ��e�nZȻ1ʚ��6�wc�u�Ɛu�n��f7� ��e�nZȻ1ʚ��6�wc�u�Ɛu�n��f7� ��%�1�,��(gvcP�@ލ1ֹC�Ȼ1ʚ��6�wc�5�1hm ��(kvc��@ލ1ֹC�Ȼ1ʚ��6�wc�5�1hm ��(kvc��@ލ1ֹC�Ȼ1ʚ��6�wc�5�1hm ��(kvc��@ލ1ֹC���1J:vc�Y8ލQ��Ơ�����ٍAky7�X�nY ��(kvc��@ލQ��Ơ�����ٍAky7FX/�1`]����ٍAky7FY����n��f7� ��c��1d]����ٍAky7FY����n��f7� ��#�n9��1J9vcPY8ލQ��Ơ�����ٍAky7�X�nY ����ٍ���ݘ9ލ9���ϯ���G<~�|u������y��<�}�?����P�d9&�1��?��m_��o>p?�^_7c�z�+�-�u����"�ނ��z��f�� ��e�zZ��-�:�[Ⱥ�y�EY�ނ��z��f�� ��e�zZ��-F��r6��[�3�-(m ��(k�[��@^oQ֬������b�s�����[�5�-hm ��(k�[��@^oQ֬������"�����@^oQ֬�����ޢ�YoAky�EY�ނ��z�����.@^oQ֬�����ޢ�YoAkq�EI�z:��-�9�[H��y�EY�ނ��z��f�� ��e�zZ��-�:�[Ⱥ�y�EY�ނ��z��f�� ��e�zZ��-�:�[Ⱥ�y�EY�ނ��z��f�� ��e�zZ��-�:�[Ⱥ�y�EY�ނ��z����t��[�3�-(m ���\o!���e�zZ��-ʚ��6��[�5�-hm ���\o!���e�zZ��-ʚ��6��[�5�-hm ���\o!���e�zZ��-ʚ��6��[�5�-hm ���\o!������[����-J8�[�X8^oQά������"�����@^oQ֬�����ޢ�YoAky�EY�ނ��z�����.@^oQ֬�����ޢ�YoAky�EY�ނ��z�����.@^oQ֬�����ޢ�YoAky�EY�ނ��z��f��������-�,��(g�[P�@^oQ֬������b�s�����[�5�-hm ��(k�[��@^oQ֬������b�s�����[�5�-hm ��(k�[��@^oQ֬������b�s�����[�5�-hm ��(k�[��@\oQұނ���z�Qf��������zJ��-ʚ��6��[�5�-hm ���\o!���e�zZ��-ʚ��6��[�5�-hm ���\o!���e�zZ��-ʚ��6��[�5�-hm ���e��+��[�5�-hm ��(k�[��@\oQұނ���z�q���.@^oQ֬�����ޢ�YoAky�EY�ނ��z�����.@^oQ֬�����ޢ�YoAky�EY�ނ��z�����.@^oQ֬�����ޢ�YoAky�EY�ނ��z�����.@^oQ֬�����ޢ�c�������zJ��-�:�[Ⱥ�y�EY�ނ��z��f�� ��e�zZ��-�:�[Ⱥ�y�EY�ނ��z��f�� ��e�zZ��-�:�[Ⱥ�y�EY�ނ��z��f�� ��e�zZ��-�:�[Ⱥ�q�EI�z:��-ʙ��6��[�5�-hm ���\o!���e�zZ��-ʚ��6��[�5�-hm ���e��+��[�5�-hm ��(k�[��@^oQ֬������b�s�����[�5�-hm ��(k�[��@^oQ֬������b�Yo!g�p�E)�z*��-ʙ��6��[�5�-hm ���\o!����$1�-x�����"��-�Y�[�o��<=og���-�L�[��z��������/���?�釟�\�����w߾�_�K"�����{'/�0Z�����D���D�8g"L�ȉ��&Fk9V�$�hm '�ʚD� �D�Xg"L�ȉ��&Fk9V�$�hm '�ʚD� �D�Xg"L�ȉ��&Fk9V�$�hm '�ʚD� �D�Xg"L�ȉ��&Fk1Vґ��p�+ga�6�ac��0Y '�ʚD� �DXY�����+ka�6�ac��0Y '�ʚD� �DXY�����+ka�6�ac��0Y '�ʚD� �DXY�����+ka�6�ac��0Y %�ʹ'�h��DX G"���q"��I�Q�@N�����ur"��I���@N��5�0Zȉ��&Fk96֙�ur"��I���@N��5�0Zȉ��&Fk96֙�ur"��I���@N��5�0Zȉ��&Fk16�$��l&�J9aT�a�L"��r"��I���@N��u&�d]��+ka�6�aeM"��r"��I���@N��u&�d]��+ka�6�aeM"��r"��I���@N��u&�d]��+ka�6�aeM"��b"��#Fg�06�$¤l'�ʙD� �DXY�����+ka�6�ac��0Y '�ʚD� �DXY�����+ka�6�ac��0Y '�ʚD� �DXY�����+ka�6�aa�$�`]��+ka�6�aeM"��b"��#Fg�86Ι�tr"��I���@N��5�0Zȉ��&Fk96֙�ur"��I���@N��5�0Zȉ��&Fk96֙�ur"��I���@N��5�0Zȉ��&Fk96֙�ur"��I���@L��t$��,'�ʙD� �D�Xg"L�ȉ��&Fk9V�$�hm '�ʚD� �D�Xg"L�ȉ��&Fk9V�$�hm '�ʚD� �D�Xg"L�ȉ��&Fk9V�$�hm '�ʚD� �D�Xg"L������D���DX9�����+ka�6�ac��0Y '�ʚD� �DXY�����+ka�6�aa�$�`]��+ka�6�aeM"��r"��I���@N��u&�d]��+ka�6�aeM"��r"��I���@L��4�09���R�D���DX9�����+ka�6�ac��0Y '�ǡ�K��"#�p���D��"�{x{ܾ�I��g�������x������j"<��%>�H������/�������������U�|I2\m�$��Վ_���"�d�.@~I����Fk��V��hm �J: +xڔ�M�lGb%���Xt���>{'�G�� e#�6If� 6aB�����n��:��zz���{t]��� +�'�_=l�w���|z�l���~z|y����7_�i����ߜlj���������o�?�|y=��]���'����o��������������?�˴<\N���������������o�����?|���_߾��_����~�������������?N٠����ޟo��w���>���6�ǯ������29�q��i3??|�?��O�u�������������n��������B�y8�=�|�>����'�h}��鋋��O���[��:βuX/��7k��ޱ6���r���H�~����ַ��˫��g�Xxۺ�mzy��q�����=��7i��ޱ6���=�˻��g�Xx`�ã��g�Xx���=�G'ݏ��q����ҹ��#m��u{ֺ��cm������n����;���O�۫����l]������Z��w� <�nxy����k��cx�/8��koZ����9��x`���EZ��w� <�n���UZ��w� <�n��l���;������^�r����z9���K�~����֗���Z��w� <���^����w����|<��?�8�8��x`ݞ����g�Xx`ݞ���g�Xx`ݞ��EZ��w� �m�l��"��,[��u{�OҺ��cm��u{g��3�ޱ6���=�k��ޱ6���|�-���q����z9=���q����֗�ë��g�Xx`};=�߅��;�>o��Y����l]���1<Y�~������1��$��w��;Pn��"_p��;��l��QZ�Y�.�����en��cm��u{ +ֺ��cm������._���;��>�������,[���rzz����k���y�27�ޱ6���=�g�27�ޱ6��m{O�:βuX��p�/s��k��cx�/s��k��c8[�~��������cx�/s�,[��u{��q��3���|�߲�G�w�|;]���8{G���������ս��,ZW���r��X�~������)<_�u?{��������u?{�������.�:βuX����,���;�X��p~����k��cx����ko[N���.gٺ������ ���;�X�O��ֺ��cm�������.���;�^�� �fڏ��q���_���;��(��t����i�����3g�Xx���=�Gigٺ���S8�q������1�C��k�o���g�Xx���pz��<�Y�.���t��A��w� <�>�^^�u?{������;Or������/�c��<�Y�.���.ֺ��cm��u{�'9{������o���;���V�n�@���GYٸ����s?{G�����Y��$g�Xx`};=�Y�~������o�g����e�<�^N�m'9{�������u?{�������Nr��������c�H�8��x`�ã|�g�Xx`��|�I�ޱ6���=�k��ޱ6��������^�r�+���xz�?���;�X�OO�ֺ��cm����$(0��q��=�Қ�,]���<[�~������<=J�~������)ȷ���ko[���(��,[��u{�'i��ޱ6���=�����cm������n���;�^N�7�2��l]���ӛ|�I�ޱ6���|��X�~������1<˗�q������O�c�o;�Y�.���.ֺ��cm��u{���g���3�o;��;�>o�@9��x`ݞ�|�I�ޱ6���|z�o;��;�X_O�oֺ��cm�m����Q��$gٺ����W�����cm��u{�ֺ��cm��u{�m'9{�������1ȷ��,[��u{�ֺ��cm��u{�m'9{�������Nr������o��&r�����xz��ߎ�q�@�|:�7���i����Wk��ޱ6��}{��'9��x`ݞ�|�I�ޱ6���=�'k��ޱ6���=�擜�cm�M�����?��Y������ֺ��cm��u{��'9{������Y��)g�Xx�z~8=�`"gٺ����g�擜�cm������b���;�X�� ����cm�m����/��(;w�ܞ��T�v�p���Z"g�Hx`��|�I�ޱ6���=�Oxs�����=��/�|�ィ�����?�͡�l��"� ��|����������ǿ�:��ľ��Ƨ����r]�y�^h�ɑ}C&+2�ӿ}��������_ǚ���_~�������O?ު��>ޓq�}���ܷ�|��n;��O�=���hm ��ʚ�� ���Xg�M�������Fk��V���hm ��J:�ot��o��7I ��ʚ�� ��[Y�����+k�o�6��oc��7Y ��ʚ�� ��[Y�����+k�o�6��oc��7Y ��ʚ�� ��[Y�����+k�o�6��oc��7Y ��ʚ�� ��[IG����q����Q�@u��d]��+k�o�6��oeM���r������@u��d]��+k�o�6��oeM���r������@u��d]��+k�o�6��oeM���r������@u��d]��+����3�o%�7���r��Fi���k� �������Fk��V���hm ��ʚ�� ���Xg�M�������Fk��V���hm ��ʚ�� ���Xg�M�������Fk��V���hm ��ʚ�� ���H���q�+��QY83�7J������Fk��6���ur������@5�7Z������Fk��6���ur������@5�7Z������Fk��6���ur������@5�7Z�����������(���q�+g�o�6��oeM���r������@u��d]��+k�o�6��oeM���r������@u��d]��+k�o�6��oeM���r������@���ur������@5�7Z�����������8g�M�������Fk��V���hm ��ʚ�� ���Xg�M�������Fk��V���hm ��ʚ�� ���Xg�M�������Fk��V���hm ��ʚ�� ���Xg�M�������Fk��V����p�+g�o�6��oc��7Y ��ʚ�� ��[Y�����+k�o�6��oc��7Y ��ʚ�� ��[Y�����+k�o�6��oc��7Y ��ʚ�� ��[Y�����+k�o�6��oc��7Y ��J:�ot��o�L���r������@u��d]��+k�o�6��oeM���r������@���ur������@5�7Z������Fk��6���ur������@5�7Z������Fk��6����l��J9�oT��o�L���r������@u��d]��S�l�o���?�և���E>��?w��?�1��G���q�������������_|�����������?����o���o���Wˡ�w����_Χ���,��ȗ�q����z9��Y�~����֗���6ʺ��cm�������3Ke��ޱ6��u{��:βuX����Ve��ޱ6���=���Y*�~������1<Z�~������o�cxt��(;w�ܞ��,���;�X�g�`���;�X߶ߗ��w?{�������5���X�Y�.�����j���;�X_N�/OҺ��cm��u{��g��cm�������5gѺ�c�EY����j��f5� ��e�jZȫ1�:WcȺ�y5FY����j��f5� ��%�1�,���\�!���e�jZȫ1ʚ��6�Wc�5�1hm ���\�!���e�jZȫ1ʚ��6�Wc�5�1hm ���\�!���e�jZȫ1ʚ��6�Wc�5�1hm ���\�!���e�jZ��1J:Vc�Y8^�QάƠ���c�s5���Wc�5�1hm ��(kVc��@^�Q֬Ơ���c�s5���Wc�5�1hm ��(kVc��@^�Q֬Ơ���c�s5���Wc�5�1hm ��(kVc��@^�Q֬Ơ���c�s5���Vc�s_�A�g��(�X�Ac�x5F9����j��^Wc��y5FY����j��f5� ��e�jZȫ1�:WcȺ�y5FY����j��f5� ��e�jZȫ1�:WcȺ�y5FY����j��f5� ��e�jZ��1F��r6Wc�r�Ơ�p���Y�Aiy5FY����j�����.@^�Q֬Ơ�����Y�Aky5FY����j�����.@^�Q֬Ơ�����Y�Aky5FY����j�����.@^�Q֬Ơ�����Y�Akq5FI�j:��1F��R6�Wc�3�1(m ��(kVc��@^�Q֬Ơ���c�s5���Wc�5�1hm ��(kVc��@^�Q֬Ơ���c�s5���Wc�5�1hm ��(kVc��@^�Q֬Ơ���#�����@^�Q֬Ơ�����Y�Akq5FI�j:ǫ1�9WcH��y5FY����j��f5� ��e�jZȫ1�:WcȺ�y5FY����j��f5� ��e�jZȫ1�:WcȺ�y5FY����j��f5� ��e�jZȫ1�:WcȺ�y5FY����j����t�Wc�3�1(m ���\�!���e�jZȫ1ʚ��6�Wc�5�1hm ���\�!���e�jZȫ1ʚ��6�Wc�5�1hm ���\�!���e�jZȫ1ʚ��6�Wc�5�1hm ���\�!���%�1�,��(gVcP�@^�Q֬Ơ���c�s5���Wc�5�1hm ��(kVc��@^�Q֬Ơ���#�����@^�Q֬Ơ�����Y�Aky5FY����j�����.@^�Q֬Ơ�����Y�Aky5FY����j��f5�������1�,��(gVcP�@^�Q֬Ơ���c�s5���Wc��P�j^d��|^i9\�9�Ȳs��GI��1��}3�26c���y|��������|>��Ͽ|�ӏ��y�x�����=�M�̩��{Υ��E��F��쌀�q�2b�!e�xb�(�0B���Qf^����qa̶��"F�a2�gE�2�"�,o�e&EHY8ʹ'���QfL����)�̒)�;"F�R�GD�+�"���"F�R��C�2�!�,o�e�CHY8ʹ���j�Qf4�������b)�{!�8�BH��c!B8�B��8^ +1����p<b�Y !e�x#�(3B���@�P�}P6��A�2� �,O�e�AHY8�1�̂��p< +"�s���E�� )�s F�5R��@�2S �,���e�x�(3B����1�~����f����������l/e�?HY8��0ʬ~��p��a��� e�x�C(��(�kF��R��>�2K�,�|ef>HY8�ʹ����Qf�����y�̺)��F�iR��=�r�z��q��a����>�p���Ƣ�>�x��3�A����}�u��X��x��(3�A���QfŃ��� �̄)�B9�;@�8^�0ʌw��p<�a�Y� e�x��(3�A���h�P��P6�;�2��,�ue�:HY8��0�Lu��p8�!����a�p����H�>�x����A���>�Qf�����q����l/se�9HY8��0ʬr��p��a��� e�x�C(�(�kF�1R��8�2K�,�pef8HY8�ʹ�����Qf������ ���)���8�7H���� ��W7�0�d,One7HY8��0��m��p<�!�sk��� ���)�3F�� R�76�2�,l����e�x]�(3�A���QfY����] �̬)ǣ���M�c��E �̠)�sF�5 R�4�qLi��3��4�p�h��q��a�� e�xB�(��A���~�Qf>���������l/ge�3HY8��0ʬf��p��a��� e�x0C(�^(�kF��R��2�2K�,�def2HY8�ʹ����B�Qf ����yc�$��m#�4��B9w1@�8^�0ʌb��p<�a�Y� e�x�(3�A����P�-P6��0�2C�,�`eV0HY8��0�L`��p<�!�s��������)��F��R�w/�2��,�^�ܼ�e�p���� ?�x���vA���օQfꂔ����;�l�\eF.HY8��0�,\��p�oa��� e�x���mq�\p�la�� e�x��(�jA���Qf҂���A��{�l�Ye�,HY8��0�,Y��p�ca��� e�p�B�aႅ��}��|�f������ +��t)��B9w+@�8^���1ZA���F"'+o��-V|�gk�C��ȾY�46+�������_��x:�?۹rW���;���B����[��g>_��f�����|�u����i�o��'k��ޱ6��y{*�2�q�����=���t+�~������1��u?{�����>�F����;���O��y�8��x`���ެu?{��������"���;�X�֍�f;� ��c��9d]�<���Y�AkyCGY3���fG� �%#͔9�c:ʙ5�6��t�5�:hm O�(k6u��@^�1�9�C���:ʚe�6��u�5�:hm ��(k�u��@^����XW ��(kVv��@��Q�����<�����Akym�X��Y �(kw��@��Q�8���cw������;$]�<���Y�AkyGY3������f�� �c�3<d]�<ģ�Y�Aky�GY3ƃ����f�� �Ec��<d]�<ʣ�Y�Aky�GY3̃��4��f�� �uc��<d]�<У�Y�Akq�GI�H:�3=ʙ��6��z�uN��u�X��f�� �e�`Zȓ=ʚ��6�W{�u���u�p��f�� ��e�xZ��=ʚ��6�|�uN��uf�� �e͐Z�S>ʚ-�6��|�u���uҠ�r�>h��M%�>h,��(gv}P�@^���XW ��(k�}��@��Q�����<���Aky��X��Y �(k�~��@��Q����<�����Aky��X��Y ��(kV��@��Q�����<�����Akq��H3�C�����R� T�7��3#@(m ��)kv���@^2�9D��c@ʚ5 �6����5�@hm O)k6���@^2�9D���@ʚe �6����5�@hm �)k����@^2�9D��#Aʚ� �6�w��5CAhm N)�� +Bg�p-�(3D���`�rf1� �� e�hZȳAʚ� �6����uN�u�x��f=� �� èZ�Bʚ !�6�W��u��ufI� �-!e͘Z�sBʚ=!�6����:)�ȣBʚU!�6�w��5�Bhm N)��Bg�x]�8�I )k���@�R���<3���Bkyi�X��Y � )kֆ��@�R����<9���Bkyu�X��Y )k����@�R���<?���Bky��X�Y �)kV���@�!R�1D�����rf�� �5"c�sDd]�<H��Y$Bky�HY3J���,��f�� �e"c��Dd]�<N��Y'Bky�HY3P���D��f�� �"c�3Ed]�<T��Y*Bky�HY3V���\��f�� ��"c��Ed]�8Z��c�����"��pJ��Eʚ�"�6��u��uf�� � #e͈Z�3Fʚ#�6�����:e��cFʚ5#�6����5�Fhm O)k6���@^52�9kD���Fʚe#�6����5�Fhm �)k����@\82�L��q8r��c����#���J�SGʚ�#�6��u��u����[<�ɣOy<�<:��2z�ȣG�o�_q�h�G�����~������H?���������������O?�r+�~�x��ո��|z{�| �]4�xvџ�|�Ey�ɺ���V�t�hm w�ʚ.� �.ZIG���qm���&��.ZY�E����E+k�h�6��heM��rm���&��.ZY�E����E+k�h�6��heM��rm���&��.ZY�E����E+k�h�6��heM��rm���&��.ZY�E����E+���Y83]4J�]���.����heM��r�����@5]4Z�]���.����heM��r�����@5]4Z�]���.����heM��r�����@5]4Z�]���.����h�ܻh4~�a����FcḋV�t�(m w��z������V�t�hm w�ʚ.� �.ZY�E����E��ɺ���V�t�hm w�ʚ.� �.ZY�E����E��ɺ���V�t�hm w�ʚ.� �.ZY�E����Ei�hr6�h�]4*�]�r��Fi��V�t�hm w��:�h�.@5]4Z�]����Fk��V�t�hm w��:�h�.@5]4Z�]����Fk��V�t�hm w��:�h�.@5]4Z�]����Fk��V��E��p�Ee�hR6��h�L��r�����@5]4Z�]���.����heM��r�����@5]4Z�]���.����heM��r�����@5]4Z�]��^�h��@5]4Z�]����Fk��V��E��p�E��I����V�t�hm w�ʚ.� �.ZY�E����E��ɺ���V�t�hm w�ʚ.� �.ZY�E����E��ɺ���V�t�hm w�ʚ.� �.ZY�E����E��ɺ���V�t�hm v�J:�ht��h�L��rm���&��.ZY�E����E+k�h�6��heM��rm���&��.ZY�E����E+k�h�6��heM��rm���&��.ZY�E����E+k�h�6��heM��rm���&��.ZIG���q���Q�@5]4Z�]���.����heM��r�����@5]4Z�]��^�h��@5]4Z�]����Fk��V�t�hm w��:�h�.@5]4Z�]����Fk��V�t�hm v�F�.����.Z)G���q���Q�@5]4Z�]���.�������u�x��E��q}|��{��훘�.���>�֙�������w���Mϼ���z�q&G~�Ϩ��㏿���?|�������������⓾��OOoW����g���n�����I�f}��9�r9��=ߺ� �~����֗���EZ��w� <����^^�u?{������o�˳���l]���1<�I�~������1\ޥu?{������u?{����ַ�1<:�~���;Pn��|����i��3x����k�o��w����ޱ6���|z�^F�u�e�<�^N��ֺ��cm��u{9|y����k��cx�/8��ko>�cxr֜E� +<�n���"���;�X����*���;�X��g[.lm n�(k�\к�q��Yǖ[�[.�:�\��@�rq�}˅���-�̖J n�8��rakq��Yǖ[�[.�:�\��@�rQ�l��u▋��-�6�\�ul�������c˅� �-e͖Z n�8��rakq��Yǖ[�[.�:�\��@�rQ�l��u▋��-�6��\�t�rag�p��9ǖK�[.ʚ-�.@�rqֱ���▋��-�6�\�ul�����墬�rA��-g[.lm n�8��rakq��Yǖ[�[.ʚ-�.@�rqֱ���▋��-�6�\�ul�����墬�rA��-��m˅��a������[.�9�\X�@�r1ֹ�B��[.�:�\��@�rqֱ���▋��-�6�\�5[.h]����c˅� �-g[.lm n�8��rakq�EY����[.�:�\��@�rqֱ���▋��-�6��\�tl���q�����+�[.�9�\X�@�rqֱ���▋�f���\�ul�������c˅� �-g[.lm n�(k�\к�q��Yǖ[�[.�:�\��@�rqֱ���▋�f���\�ul�������c˅� �-'ݷ\�Y8�rQʱ���ᖋs�-�6�\�ul�������c˅� �-e͖Z n�8��rakq��Yǖ[�[.�:�\��@�rQ�l��u▋��-�6�\�ul�������c˅� �-c�[.d]����c˅� �-g[.lm m�8�����ᖋrf���\�ul�������c˅� �-g[.lm n�(k�\к�q��Yǖ[�[.�:�\��@�rqֱ���▋�f���\�ul�������c˅� �-g[.lm n�(k�\к�q��Yǖ[H[.N�o���p���c˅� �-e͖Z n�8��rakq��Yǖ[�[.�:�\��@�rQ�l��u▋��-�6�\�ul�������c˅� �-e͖Z n�8��rakq��Yǖ[�[.�:�\��@�rQ�l��uҖ���[.�,n�8��raiq��Yǖ[�[.ʚ-�.@�rqֱ���▋��-�6�\�ul������b�s˅�+�\�ul�������c˅� �-g[.lm n�(k�\к�q��Yǖ[�[.�:�\��@�rqֱ���Җ���-t6��\�r�rae�p��9ǖK�[.�:�\��@�rQ�l��u�l��-��~��E���\�"��0�c�e�r��<��ľ��Ƨ�n��Ǜ�2�L��[.�^s������������ +������|�������O|��|��&c��ˋ�nY ��(kvc��@ލQ��Ơ�����ٍAky7�X�nY ��(kvc��@ލQ��Ơ�����ٍAkq7�H�C���n�rf7� ��e�nZȻ1ʚ��6�wc�u�Ɛu�n��f7� ��e�nZȻ1ʚ��6�wc����Ȼ1ʚ��6�wc�5�1hm ��(kvc��@ލ1ֹC�Ȼ1ʚ��6�wc�5�1hm ��(�؍Ag�x7�8�nI ��(kvc��@ލQ��Ơ�����ٍAky7�X�nY ��(kvc��@ލQ��Ơ�����ٍAky7�X�nY ��(kvc��@ލQ��Ơ�����ٍAky7�X�nY ��(kvc��@܍Qұ����n�rf7� ��c��1d]����ٍAky7FY����n��f7� ��c��1d]����ٍAky7FY����n��f7� ��c��1d]����ٍAky7FY����n��f7� ��c��1d]�����n?�p7F �nǻ1ʙ��6�wc����Ȼ1ʚ��6�wc�5�1hm ��(kvc��@ލ1ֹC�Ȼ1ʚ��6�wc�5�1hm ��(kvc��@ލ1ֹC�Ȼ1ʚ��6�wc�5�1hm ��(kvc��@܍1��Ɛ�q���c7������nJȻ1ʚ��6�wc�u�Ɛu�n��f7� ��e�nZȻ1ʚ��6�wc�u�Ɛu�n��f7� ��e�nZȻ1ʚ��6�wc�u�Ɛu�n��f7� ��e�nZ��1J:vc�Y8܍1��Ɛ�q���ٍAiy7FY����n��f7� ��c��1d]����ٍAky7FY����n��f7� ��c��1d]����ٍAky7FY����n��f7� ��a��ƀu�n��f7� ��e�nZ��1J:vc�Y8ލ1ιC�Ȼ1ʚ��6�wc�5�1hm ��(kvc��@ލ1ֹC�Ȼ1ʚ��6�wc�5�1hm ��(kvc��@ލ1ֹC�Ȼ1ʚ��6�wc�5�1hm ��(kvc��@ލ1ֹC�Ȼ1ʚ��6wc�t�Ơ�p���ٍAiy7�X�nY ��(kvc��@ލQ��Ơ�����ٍAky7�X�nY ��(kvc��@ލQ��Ơ�����ٍAky7�X�nY ��(kvc��@ލQ��Ơ�����ٍAky7�X�nY ��(�؍Ag�x7F9����n��f7� ��c��1d]����ٍAky7FY����n��f7� ��a��ƀu�n��f7� ��e�nZȻ1ʚ��6�wc�u�Ɛu�n��f7� ��e�nZȻ1ʚ��6wc�4�1�l��(�؍Ae�x7F9����n��f7� ��c��1d]��CK(f7/2vc>]�x7��"�{:���>�����m�������K���[�y3�r&�1َ�����×C"�W���O�/�Roo��1s�����O�:^o��"�ނ��z��f�� ��e�zZ��-�:�[Ⱥ�y�EY�ނ��z��f�� ��e�zZ��-F��r6��[�3�-(m ��(k�[��@^oQ֬������b�s�����[�5�-hm ��(k�[��@^oQ֬������"�����@^oQ֬�����ޢ�YoAky�EY�ނ��z�����.@^oQ֬�����ޢ�YoAkq�EI�z:��-�9�[H��y�EY�ނ��z��f�� ��e�zZ��-�:�[Ⱥ�y�EY�ނ��z��f�� ��e�zZ��-�:�[Ⱥ�y�EY�ނ��z��f�� ��e�zZ��-�:�[Ⱥ�y�EY�ނ��z����t��[�3�-(m ���\o!���e�zZ��-ʚ��6��[�5�-hm ���\o!���e�zZ��-ʚ��6��[�5�-hm ���\o!���e�zZ��-ʚ��6��[�5�-hm ���\o!������[����-J8�[�X8^oQά������"�����@^oQ֬�����ޢ�YoAky�EY�ނ��z�����.@^oQ֬�����ޢ�YoAky�EY�ނ��z�����.@^oQ֬�����ޢ�YoAky�EY�ނ��z��f��������-�,��(g�[P�@^oQ֬������b�s�����[�5�-hm ��(k�[��@^oQ֬������b�s�����[�5�-hm ��(k�[��@^oQ֬������b�s�����[�5�-hm ��(k�[��@\oQұނ���z�Qf��������zJ��-ʚ��6��[�5�-hm ���\o!���e�zZ��-ʚ��6��[�5�-hm ���\o!���e�zZ��-ʚ��6��[�5�-hm ���u��+��[�5�-hm ��(k�[��@\oQұނ���z�q���.@^oQ֬�����ޢ�YoAky�EY�ނ��z�����.@^oQ֬�����ޢ�YoAky�EY�ނ��z�����.@^oQ֬�����ޢ�YoAky�EY�ނ��z�����.@^oQ֬�����ޢ�c�������zJ��-�:�[Ⱥ�y�EY�ނ��z��f�� ��e�zZ��-�:�[Ⱥ�y�EY�ނ��z��f�� ��e�zZ��-�:�[Ⱥ�y�EY�ނ��z��f�� ��e�zZ��-�:�[Ⱥ�q�EI�z:��-ʙ��6��[�5�-hm ���\o!���e�zZ��-ʚ��6��[�5�-hm ���u��+��[�5�-hm ��(k�[��@^oQ֬������b�s�����[�5�-hm ��(k�[��@^oQ֬������b�Yo!g�p�E)�z*��-ʙ��6��[�5�-hm ���\o!����$1�-x�����"��-�Y�[<�l2~���q&�-�c������?~��w��?�����U!�|���Y/�}�/_�k"����{'�_^a�6a%�0:lj�q�D���aeM"��r"��I���@N��5�0Zȉ���D���aeM"��r"��I���@N��5�0Zȉ���D���aeM"��r"��I���@N��5�0Zȉ���D���aeM"��b"��#Fg�8V�$�(m '��:a�.@N��5�0Zȉ��&Fk9V�$�hm '��:a�.@N��5�0Zȉ��&Fk9V�$�hm '��:a�.@N��5�0Zȉ��&Fk9V�$�hm '��:a�.@J��sO�������D���DX9������5� +�DXY�����+ka�6�aeM"��r"l�3&��DXY�����+ka�6�aeM"��r"l�3&��DXY�����+ka�6�aeM"��b"l�I���8L��r$¨,'�ʙD� �DXY������L�ɺ�9V�$�hm '�ʚD� �DXY������L�ɺ�9V�$�hm '�ʚD� �DXY������L�ɺ�9V�$�hm '�ʚD� �DXIG"���a"l�I�I�8N��3�0Jȉ��&Fk9V�$�hm '��:a�.@N��5�0Zȉ��&Fk9V�$�hm '��:a�.@N��5�0Zȉ��&Fk9V�$�hm '��zM���9V�$�hm '�ʚD� �DXIG"���q"l�3&��DXY�����+ka�6�aeM"��r"l�3&��DXY�����+ka�6�aeM"��r"l�3&��DXY�����+ka�6�aeM"��r"l�3&��DXY�����+�H��Y8N��3�0Jȉ���D���aeM"��r"��I���@N��5�0Zȉ���D���aeM"��r"��I���@N��5�0Zȉ���D���aeM"��r"��I���@N��5�0Zȉ���D��a%�0:lj�r&Fi9V�$�hm '��:a�.@N��5�0Zȉ��&Fk9V�$�hm '��zM���9V�$�hm '�ʚD� �DXY������L�ɺ�9V�$�hm '�ʚD� �DXY�����iar6a��0*lj�r&Fi9V�$�hm '��:a�.@N��CW��EF"��"χ���E~wyھ�I�og������?t|��f��{3�r��G$���_���t���G'W��_���T��C��j�C�?]��C���|H2Y H����Fk��V��hm �J: ht�h�4I �ʚ� �ZYS@���\@+k h�6�hc�4Y �ʚ� �ZYS@���\@+k h�6�hc�4Y �ʚ� �ZYS@���\@+k h�6�hc�4Y �ʚ� �ZIG���q��)�Q�@.��u�d]�\@+k h�6�heM��r��)���@.��u�d]�\@+k h�6�heM��r��)���@.��u�d]�\@+k -h�6�heM��r��)���@.��u�d]�T@+�^@��#h%4��r��Fi���K ������Fk��V��hm �ʚ� ��XgM������Fk��V��hm �ʚ� ��XgM������Fk��V��hm �ʚ� ��HS@��qX@+�(�QY8.��34J�����Fk��6�Y@�ur��)���@.��54Z�����Fk��6�Y@�ur��)���@.��54Z�����Fk��6�Y@�ur��)���@.��54Z��������(S@��q\@+g +h�6�heM��r��)���@.��u�d]�T@+�^@��3h%4��r��Fi���k ������Fk��V��hm �ʚ� ��XgM������Fk��V��hm �ʚ� ��XgM������Fk��V��hm �ʚ� ��HS@��qX@+�(�QY8.��34J�����Fk��6�Y@�ur��)���@.��54Z�����Fk��6�Y@�ur��)���@.��54Z�����Fk��6�Y@�ur��)���@.��54Z��������(S@��q\@+g h�6�heM��r��)���@.��u�d]�\@+k h�6�heM��r��)���@.��u�d]�\@+k -h�6�heM��r��)���@.���R@�ur��)���@.��54Z��������8gM������Fk��V��hm �ʚ� ��XgM������Fk��V��hm �ʚ� ��XgM������Fk��V��hm �ʚ� ��XgM������Fk��V�Q@��p\@+g +h�6�heM��r��)���@.���Z@�ur��)���@.��54Z��������8gM������Fk��V��hm �ʚ� ��XgM������Fk��V��hm �ʚ� ��XgM������Fk��V��hm �ʚ� ��XgM������Fk��V�Q@��p\@+g h�6�hc�4Y �ʚ� �ZYS@���\@+k h�6�hc�4Y �ʚ� �ZYS@���\@+k h�6�hc�4Y �ʚ� �ZYS@���\@+k h�6�hc�4Y �J: ht�h�L��r��)���@.��u�d]�\@+k -h�6�heM��r��)���@.���R@�ur��)���@.��54Z�����Fk��6�Y@�ur��)���@.��54Z�����Fk��6���l�J9 +h�6�heM��r��)���@.���Z@�ur��)���@.��54Z�����Fk��6�Y@�ur��)���@.��54Z�����Fk��6���l�J9 hT�h�L��r��)���@.��u�d]�\@S�k -h��(�?\一>��R@��(���v~�z���yM�����o��˵�~����7��%�_�z��p��s~��q���"�s����s��9ɺ���T���hm ��ʚ�� �SY�s����s��9ɺ���T���hm ��ʚ�� �SY�s����s��9ɺ���T���hm ��J:zNt�{N�Lω�r�i���$��SY�s����s*kzN�6�{NeMω�r�i���$��SY�s����s*kzN�6�{NeMω�r�i���$��SY�s����s*kzN�6�{NeMω�r�i���$���S9���a�s*��9�X8�9�3='J�=��^zN��@�9�5='Z�=����Dk��T���hm ���:{N�.@�9�5='Z�=����Dk��T���hm ���:{N�.@�9�5='Z�=����Dk��T���hm ��F�����ÞS)Gω��qϩ��9Q�@�9�5='Z�=��Ξ���{NeMω�rϩ��9��@�9�5='Z�=��Ξ���{NeMω�rϩ��9��@�9�5='Z�=��Ξ���{NeMω�rϩ��9��@�9�t���,��F������S9�s����s*kzN�6�{NeMω�r�i���$��SY�s����s*kzN�6�{NeMω�r�i���$��SY�s����s*kzN�6�{NeMω�r�)����+�{NeMω�rϩ��9��@�9�t���,���9{N�.@�9�5='Z�=����Dk��T���hm ���:{N�.@�9�5='Z�=����Dk��T���hm ���:{N�.@�9�5='Z�=����Dk��T���hm ���:{N�.@�9�5='Z�=�������S9�s����s��9ɺ���T���hm ��ʚ�� �SY�s����s��9ɺ���T���hm ��ʚ�� �SY�s����s��9ɺ���T���hm ��ʚ�� �SY�s����s��9ɺ���T��s��p�s*gzN�6�{NeMω�r�i���$��SY�s����s*kzN�6�{NeMω�r�)����+�{NeMω�rϩ��9��@�9�5='Z�=��Ξ���{NeMω�rϩ��9��@�9�5='Z�=����$g��T��s��p�s*gzN�6�{NeMω�r�i���$���Nt='^d��.r�s_�w�����Í7ڞ߶_=�������YW{�q(g�s>��������/�������������/��w>o����sҋ����� ������o����ǫ�>_�����p�"W����X�O�ϏҺ��am�������;Ye��ް6�������9��x`��ó��goXx`����d�u?{����x������hm ��X绡ɺ����ʚwC����nheͻ���@|7���wC��p�nh��&��wC+k� ��5[hm o (k���@�0ֹ%@��[ʚ-�6���5[hm o (k���@�0ֹ%@��[ʚ-�6���5[hm o (k���@�0ֹ%@��[ʚ-�6��tl ��p�%���@iyK�X��Y o (k���@�P�l ����%���@kyK�X��Y o (k���@�P�l ����%���@kyK�X��Y o (k���@�P�l ����%���@kyK�X��Y m (�%�Ə0�P±%����rfK�� �-a�l �ufK�� �-e͖�Z�[ʚ-�6���un �ufK�� �-e͖�Z�[ʚ-�6���un �ufK�� �-e͖�Z�[ʚ-�6��4[�ln (��@e�xK@9�%��fK�� �-c�[d]��%���@kyK@Y�%��fK�� �-c�[d]��%���@kyK@Y�%��fK�� �-c�[d]��%���@kyK@Y�%��▀��-t��2[�lo (g�P�@�P�l ����%���@kyK�X��Y o (k���@�P�l ����%���@kyK�X��Y o (k���@�P�l ����%���@kyK@X/[`]��%���@kyK@Y�%��▀��-t���sn �tfK�� �-e͖�Z�[ʚ-�6���un �ufK�� �-e͖�Z�[ʚ-�6���un �ufK�� �-e͖�Z�[ʚ-�6���un �ufK�� �-%[�,o (g�P�@�0ֹ%@��[ʚ-�6���5[hm o (k���@�0ֹ%@��[ʚ-�6���5[hm o (k���@�0ֹ%@��[ʚ-�6���5[hm o (k���@�0ֹ%@��[J:��Y8�P�l ����%���@kyK�X��Y o (k���@�P�l ����%���@kyK@X/[`]��%���@kyK@Y�%��fK�� �-c�[d]��%���@kyK@Y�%��fK�� �-#͖�9�[J9�PY8�P�l ����%���@kyK�X��Y o `/��"cK��E���/�n �=�Ϗ�%0�dK�ql �����������_^O��?��?��Z����O��ơ�w�Կ�O����Y�eg�����Y:��7� <�>��u?{��������~}��7� <XI��:w(Ⱥ�y�BY�C�����f�� � -e�Z�;�z١�� -� +h��(�?]一>��R@?�)�?~�v~�z���������/�����neЏ�%�^���_/q�-�;Ƞg� ��=����_^zN�6�{Nc�='Y ��ʚ�� �SY�s����s*kzN�6�{Nc�='Y ��ʚ�� �SY�s����s*kzN�6�{Nc�='Y ��ʚ�� ĞSIGω��qϩ��9Q�@�9�u��d]��s*kzN�6�{NeMω�rϩ��9��@�9�u��d]��s*kzN�6�{NeMω�rϩ��9��@�9�u��d]��s*kzN�6�{NeMω�rϩ��9��@�9�u��d]��s*��s��3{N%='�=�r��Di���k� ��=����Dk��T���hm ��ʚ�� ��Xg�I��=����Dk��T���hm ��ʚ�� ��Xg�I��=����Dk��T���hm ��ʚ�� Ğ�H�s��q�s*��9QY8�9�3='J�=����Dk��4��s�urϩ��9��@�9�5='Z�=����Dk��4��s�urϩ��9��@�9�5='Z�=����Dk��4��s�urϩ��9��@�9�5='Z�=������Þ�(�s��q�s*gzN�6�{NeMω�rϩ��9��@�9�u��d]��s*kzN�6�{NeMω�rϩ��9��@�9�u��d]��s*kzN�6�{NeMω�rϩ��9��@�9���s�urϩ��9��@�9�5='Z�=��������8g�I��=����Dk��T���hm ��ʚ�� ��Xg�I��=����Dk��T���hm ��ʚ�� ��Xg�I��=����Dk��T���hm ��ʚ�� ��Xg�I��=����Dk��T��s��p�s*gzN�6�{Nc�='Y ��ʚ�� �SY�s����s*kzN�6�{Nc�='Y ��ʚ�� �SY�s����s*kzN�6�{Nc�='Y ��ʚ�� �SY�s����s*kzN�6�{Nc�='Y ��J:zNt�{N�Lω�rϩ��9��@�9�u��d]��s*kzN�6�{NeMω�rϩ��9��@�9���s�urϩ��9��@�9�5='Z�=����Dk��4��s�urϩ��9��@�9�5='Z�=����Dk��4����l��J9zNT�{N�Lω�rϩ��9��@�9�u��d]��s��ċ����E�{������vz���D������q��vپϺ�s�C9���2j�����������?���~��ߜ����������.o?'��n|�^�>���~>=���1]u�|�ӗ��^_/�.rú��cm�������$���;�X�N���*�~������`��=�'g�Y�����./Һ��cm��u{��*�~������Q�ʚφFk����u~64Y 6��泡��@�lhe�gC������J:>���φ6����$]����ʚφFk����5[hm o (k���@�0ֹ%@��[ʚ-�6���5[hm o (k���@�0ֹ%@��[ʚ-�6���5[hm o (k���@�0ֹ%@��[ʚ-�6��tl ��p�%���@iyK�X��Y o (k���@�P�l ����%���@kyK�X��Y o (k���@�P�l ����%���@kyK�X��Y o (k���@�P�l ����%���@kyK�X��Y m (�%���0�P±%����rfK�� �-a�n �ufK�� �-e͖�Z�[ʚ-�6���un �ufK�� �-e͖�Z�[ʚ-�6���un �ufK�� �-e͖�Z�[ʚ-�6��4[�ln (��@e�xK@9�%��fK�� �-c�[d]��%���@kyK@Y�%��fK�� �-c�[d]��%���@kyK@Y�%��fK�� �-c�[d]��%���@kyK@Y�%��▀��-t��2[�lo (g�P�@�P�l ����%���@kyK�X��Y o (k���@�P�l ����%���@kyK�X��Y o (k���@�P�l ����%���@kyK@X�[`]��%���@kyK@Y�%��▀��-t���sn �tfK�� �-e͖�Z�[ʚ-�6���un �ufK�� �-e͖�Z�[ʚ-�6���un �ufK�� �-e͖�Z�[ʚ-�6���un �ufK�� �-%[�,o (g�P�@�0ֹ%@��[ʚ-�6���5[hm o (k���@�0ֹ%@��[ʚ-�6���5[hm o (k���@�0ֹ%@��[ʚ-�6���5[hm o (k���@�0ֹ%@��[J:��Y8�P�l ����%���@kyK�X��Y o (k���@�P�l ����%���@kyK@X�[`]��%���@kyK@Y�%��fK�� �-c�[d]��%���@kyK@Y�%��fK�� �-#͖�9�[J9�PY8�P�l ����%���@kyK�X��Y o `/��"cK��E���/�Wn <<���O�%0�dK�il ��_��߿��o���_�N�?����j�<}�>���� @w�>��ˠ��|�<Ǘ��(;w�����g���ޑ6���r�<X�~����ַ�����g�Xx��0f#�u�P�u���f�� � e�Z�;ʚ -�6�w(�5;hm �P�ܡ �� +�6�w(���C��;ʚ +�6�w(�5;hm �P(kv(��@ޡ0ֹCA��;ʚ +�6�w(�5;hm �P(�ء@g�x��8�I �P(kv(��@ޡP��P����C��١@ky��X�Y �P(kv(��@ޡP��P����C��١@ky��X�Y �P(kv(��@ޡP��P����C��١@ky��X�Y �P(kv(��@ܡPұC�����rf�� � +c�;d]��C��١@ky�BY�C�����f�� � +c�;d]��C��١@ky�BY�C�����f�� � +c�;d]��C��١@ky�BY�C�����f�� � +c�;d]��C���?�p�B ��;ʙ +�6�w(���C��;ʚ +�6�w(�5;hm �P(kv(��@ޡ0ֹCA��;ʚ +�6�w(�5;hm �P(kv(��@ޡ0ֹCA��;ʚ +�6�w(�5;hm �P(kv(��@ܡ0��P��q�C��c���� +��J�;ʚ +�6�w(�u�P�u���f�� � e�Z�;ʚ -�6w(�t�P��p�Ca�s����w(�5;hm �P(kv(��@ޡP��P����Ca�s����w(�5;hm �P(kv(��@ޡP��P����Ca�s����w(�5;hm �P(kv(��@ޡP��P����Ca�s����w(�5;hm �P(�ء@g�x�B9�C������ -�.@ޡP��P����C��١@ky�BY�C������ -�.@ޡP��P����C��١@ky�BY�C������ -�.@ޡP��P����C��١@ky�BY�C������ -�.@ڡP�}��a�C��c���� -��J�;�z١�� -� +�6�w(�u�P�u���f�� � e�Z�;ʚ -�6�w(�5;hm �P�ܡ �� +�6�w(�u�P�u���f�� � +e�Z�;J:v(�Y8ܡ0��P��q�C��١@iy�BY�C�����f�� � +c�;d]��C��١@ky�BY�C�����f�� � +c�;d]��C��١@ky�BY�C�����f�� � +a��P�u���f�� � +e�Z�;J:v(�Y8ޡ0ιCA��;ʚ +�6�w(�5;hm �P(kv(��@ޡ0ֹCA��;ʚ +�6�w(�5;hm �P(kv(��@ޡ0ֹCA��;ʚ +�6�w(�5;hm �P(kv(��@ޡ0ֹCA��;ʚ +�6w(�t�P��p�C��١@iy��X�Y �P(kv(��@ޡP��P����C��١@ky��X�Y �P(kv(��@ޡP��P����C��١@ky��X�Y �P(kv(��@ޡP��P����C��١@ky��X�Y �P(�ء@g�x�B9�C�����f�� � +c�;d]��C��١@ky�BY�C�����f�� � +a��P�u���f�� � e�Z�;ʚ -�6�w(�5;hm �P�ܡ �� +�6�w(�u�P�u���f�� � e�Z�;ʚ -�6�w(�5;hm �Piv(��8ܡPʱC�����rf�� � -e�Z�;�:w(Ⱥ�y�BY�C�����f�� � -e�Z�;�:w(Ⱥ�y�BY�C�����f�� � -e�Z�;�:w(Ⱥ�y�BY�C�����f�� � -%;�,�Pev(H�8ޡP��P����C��١@ky�BY�C������ -�.@ޡP��P����C��١@ky�BY�C������ -�.@ޡP��P����C��١@ky�BY�C�����^v(��y�BY�C�����f�� � -%;�,�P�ܡ �� -e�Z�;ʚ -�6�w(�5;hm �P�ܡ �� -e�Z�;ʚ -�6�w(�5;hm �P�ܡ �� -e�Z�;ʚ -�6�w(�5;hm �P�ܡ �� -e�Z�;J:v(�Y8ޡP��P����Ca�s����w(�5;hm �P(kv(��@ޡP��P����Ca�s����w(�5;hm �P(kv(��@ޡP��P����Ca�s����w(�5;hm �P(kv(��@ޡP��P����Ca�s���w(�t�P��p�C��١@iy�BY�C������ -�.@ޡP��P����C��١@ky�BY�C�����^v(��y�BY�C�����f�� � -e�Z�;�:w(Ⱥ�y�BY�C�����f�� � -e�Z�;F� -r6w(�r�P��p�C��١@iy�BY�C������ -�.@ޡ�e�C�;.r�Cq|�e��w(�Χ��Z�C�3١x;����w?�ӿ�����A��������_����A�4�x�q��%�+9n�ɺ�qw�Ѹ���ظ;�h���@lܝu4�lm 6�ʚ��wg�;[�����Ɲ� ���I�Ɲ����]9Ӹ�tb�qgk�qw�Ѹ���ظ;�h���@lܕ5�;Z 6��:w�6wg�;[�����Ɲ� ��]YӸ�ub�qgk�qw�Ѹ���ظ;�h���@lܕ5�;Z 6��:w�6�w'�wvw��;K�����qG����YG���b�qgk�qw�Ѹ���ظ+kw�.@lܝu4�lm 6��:w�6wg�;[�����qG����YG���b�qgk�qw�Ѹ���ظ+kw�.@hܝ�k��Ə0jܝpo��X8lܝs4�,m 6��:w��@lܝu4�lm 6��:w�6wg�;[�����qG����YG���b�qgk�qw�Ѹ���ظ+kw�.@lܝu4�lm 6��:w�6wg�;[H����������)�Ɲ�����9G���b�qgk�qW�4�h]�ظ;�h���@lܝu4�lm 6��:w�6weM�������Ɲ� ���YG���b�qgk�qW�4�h]�ظ;�h���@lܝu4�lm 5�N�7��,5�J9wT6w��;K�����Ɲ� ���YG���b㮬i�Ѻ��qw�Ѹ���ظ;�h���@lܝu4�lm 6�ʚ��wg�;[�����Ɲ� ���YG���b�n��q'� -���YG���b�qgk�qwҽqgg�qW�4�(]�ظ;�h���@lܝu4�lm 6��:w�6weM�������Ɲ� ���YG���b�qgk�qW�4�h]�ظ;�h���@lܝu4�lm 6��:w�6weM�������Ɲ� ���I�Ɲ�����9G���b㮬i�Ѻ��qw�Ѹ���ظ;�h���@lܝu4�lm 6�ʚ��wg�;[�����Ɲ� ���YG���b㮬i�Ѻ��qw�Ѹ���ظ;�h���@lܝu4�lm 6�ʚ���w'�wvw��;K�����Ɲ� ��]YӸ�ub�qgk�qw�Ѹ���ظ;�h���@l܍u6�d]�ظ;�h���@lܝu4�lm 6��:w�6weM�������Ɲ� ���YG���b�qgk�qW�Ѹ��qԸ;���pظ;�h�Y�@lܝu4�lm 6�ʚ��w��E���}���Q�������uL�~���?>|�㷿�}==�����q(g.��yT���?�����_���ś/�Kxᯗ8�^��V^��]�J��,+?�︬�|(+ɺ���T֔�hm ��ʚ�� �RYSV���\V�,+ɺ���T֔�hm ��ʚ�� �RYSV���\V�,+ɺ���T֔�hm ��J:�Jt��J�LY��rYi���$��RYSV���\V*k�J�6��JeMY��rYi���$��RYSV���\V*k�J�6��JeMY��rYi���$��RYSV���\V*k�J�6��JeMY��rYi���$���R9���aXV*�(+�X8.+�3e%J�e��^�J��@.+�5e%Z�e����Dk��T֔�hm ���:�J�.@.+�5e%Z�e����Dk��T֔�hm ���:�J�.@.+�5e%Z�e����Dk��T֔�hm ��F�����òR)GY���qY��)+Q�@.+�5e%Z�e��β����JeMY��rY��)+��@.+�5e%Z�e��β����JeMY��rY��)+��@.+�5e%Z�e��β����JeMY��rY��)+��@,+�t���,��F������R9SV���\V*k�J�6��JeMY��rYi���$��RYSV���\V*k�J�6��JeMY��rYi���$��RYSV���\V*k�J�6��JeMY��rY)����+��JeMY��rY��)+��@,+�t���,���9�J�.@.+�5e%Z�e����Dk��T֔�hm ���:�J�.@.+�5e%Z�e����Dk��T֔�hm ���:�J�.@.+�5e%Z�e����Dk��T֔�hm ���:�J�.@.+�5e%Z�e�������R9SV���\V�,+ɺ���T֔�hm ��ʚ�� �RYSV���\V�,+ɺ���T֔�hm ��ʚ�� �RYSV���\V�,+ɺ���T֔�hm ��ʚ�� �RYSV���\V�,+ɺ���T�QV��p\V*g�J�6��JeMY��rYi���$��RYSV���\V*k�J�6��JeMY��rY)����+��JeMY��rY��)+��@.+�5e%Z�e��β����JeMY��rY��)+��@.+�5e%Z�e����$g㰬T�QV��p\V*g�J�6��JeMY��rYi���$���te%^d��.�rXV_d)+�o���O_aY9�\���QV�o���_���/�o^������~����������n���0���7y�K|��>�ߎ���j����j|�q�j|��hm �ʚV� �VCY�j����j�l5Ⱥ���Pִhm �ʚV� �VCY�j����j�l5Ⱥ���Pν�@�G�J8Z 4�[ �L���r�!��V�+�[ eM���r���i5��@n5�5�Zȭ���V���[ eM���r���i5��@n5�5�Zȭ���V���[ eM���r���i5��@n5�5�Z������ g��P��j��p�j(gZ �6�[ eM���r�a��� ��VCY�j����j(kZ �6�[ eM���r�a��� ��VCY�j����j(kZ �6�[ eM���r�a��� ��VCY�j����j(kZ �6[ %�:���Q�� e��Pδ(m �ʚV� �VCY�j����j�l5Ⱥ���Pִhm �ʚV� �VCY�j����j�l5Ⱥ���Pִhm �ʚV� �VCY�j����j���� -�VCY�j����j(kZ �6[ %�:ǭ�q�V���[ eM���r���i5��@n5�5�Zȭ���V���[ eM���r���i5��@n5�5�Zȭ���V���[ eM���r���i5��@n5�5�Zȭ���V���[ eM���b�����@g��Pδ(m ��:[ �.@n5�5�Zȭ����@k��Pִhm ��:[ �.@n5�5�Zȭ����@k��Pִhm ��:[ �.@n5�5�Zȭ����@k��Pִhm ��:[ �.@l5�t��,�ʙV� �VCY�j����j�l5Ⱥ���Pִhm �ʚV� �VCY�j����j���� -�VCY�j����j(kZ �6�[ eM���r�a��� ��VCY�j����j(kZ �6�[ eM���b�a�i5��8l5�r��,�ʙV� �VCY�j����j�l5Ⱥ��ՠ���x��j|���a�q|���-X��^��g.���h5��� �|��d���ߵ�|��t�}X�o�������_�����{~�����t~9_�ƕwp�gY�����gk��ް6���|:?�K�~������R2e�[���@~˙�η��u�[Δ5o9Ck�-gʚ�������3e�[���@~˙�η��u�[Δ5o9Ck�-gʚ�������3e�[���@~˙�η��u�[Δ5o9Ck�-gJ:�r����[Δ3o9Ci�-g�:�rF��o9Sּ�� ䷜)k�r���[Δ5o9Ck�-g�:�Y�.@.g�5�,Z�嬲��Ek��U֔�hm ���:�Y�.@.g�5�,Z�嬲��Ek��U֔�hm ���:�Y�.@*g�s/g�����r���rV9S��\� -륜� -�rVYS��\�*k�Y�6��YeM9��r9k���%��rVYS��\�*k�Y�6��YeM9��r9k���%��rVYS��\�*k�Y�6��YeM9��b9k�)g��8,g�r���,��ʙr� �rVYS��\��,gɺ���U֔�hm ��ʚr� �rVYS��\��,gɺ���U֔�hm ��ʚr� �rVYS��\��,gɺ���U֔�hm ��ʚr� �rVIG9���a9k�)gI�8.g�3�,J�嬲��Ek��U֔�hm ���:�Y�.@.g�5�,Z�嬲��Ek��U֔�hm ���:�Y�.@.g�5�,Z�嬲��Ek��U֔�hm ���z)g����U֔�hm ��ʚr� �rVIG9���q9k���%��rVYS��\�*k�Y�6��YeM9��r9k���%��rVYS��\�*k�Y�6��YeM9��r9k���%��rVYS��\�*k�Y�6��YeM9��r9k���%��rVYS��X�*�(g�Y8.g�3�,J�嬱�r����YeM9��r9��)g��@.g�5�,Z�嬱�r����YeM9��r9��)g��@.g�5�,Z�嬱�r����YeM9��r9��)g��@.g�5�,Z�嬱�r���Y%�,:��r��Ei��U֔�hm ���:�Y�.@.g�5�,Z�嬲��Ek��U֔�hm ���z)g����U֔�hm ��ʚr� �rVYS��\��,gɺ���U֔�hm ��ʚr� �rVYS��X�i�Yr6�Y��,*��r��Ei��U֔�hm ���:�Y�.@.g��OW��EF9��"����E�·�=�m�⟹�g.���(g��_�����������DŽ�zA��X����w���vcp�Y�}��q1��"P����\��,�Ⱥ��S�chm cJ:�1t��1�L1��r1f��#��bLYS����\�)k�1�6��1eM1��r1f��#��bLYS����\�)k�1�6��1eM1��r1f��#��bLYS����\�)k�1�6��1eM1��r1f��#��bL9�b�aX�)�(��X8.Ɣ3�J�Ř�^�1��@.Ɣ5�Z�Ř��Ck�S�chm c�:�1�.@.Ɣ5�Z�Ř��Ck�S�chm c�:�1�.@.Ɣ5�Z�Ř��Ck�S�chm cF�b����bL)G1���q1��)�P�@.Ɣ5�Z�Ř��b����1eM1��r1��)���@.Ɣ5�Z�Ř��b����1eM1��r1��)���@.Ɣ5�Z�Ř��b����1eM1��r1��)���@,Ɣtc�,cF�b����bL9S����\�)k�1�6��1eM1��r1f��#��bLYS����\�)k�1�6��1eM1��r1f��#��bLYS����\�)k�1�6��1eM1��r1&��b�+��1eM1��r1��)���@,Ɣtc�,c�9�1�.@.Ɣ5�Z�Ř��Ck�S�chm c�:�1�.@.Ɣ5�Z�Ř��Ck�S�chm c�:�1�.@.Ɣ5�Z�Ř��Ck�S�chm c�:�1�.@.Ɣ5�Z�Ř��b���bL9S����\��,�Ⱥ��S�chm cʚb� �bLYS����\��,�Ⱥ��S�chm cʚb� �bLYS����\��,�Ⱥ��S�chm cʚb� �bLYS����\��,�Ⱥ��S�Q���p\�)g�1�6��1eM1��r1f��#��bLYS����\�)k�1�6��1eM1��r1&��b�+��1eM1��r1��)���@.Ɣ5�Z�Ř��b����1eM1��r1��)���@.Ɣ5�Z�Ř��#g�S�Q���p\�)g�1�6��1eM1��r1f��#��b�vr�^dc.r\�_�/|�������O\��3�b�i�k�����_�����b�������?j����'wq���~}=�l��γ�p��f��E�Ck�3�ٌ�ur3��i���@lƔt4c�,7cʙf� �f�Xg3F��͘��Ck�S�4chm 7cʚf� �f�Xg3F��͘��Ck�S�4chm 7cʚf� �f�Xg3F��͘��Ck�S�4chm 7cʚf� �f�Xg3F�H͘r��?°S�ь��p܌)g�1�6��1a�4c`]�܌)k�1�6��1eM3��r3��i���@nƌu6cd]�܌)k�1�6��1eM3��r3��i���@nƌu6cd]�܌)k�1�6��1eM3��r3��i���@lƌ4�9�͘R�f���fL9ӌ���܌)k�1�6��1c��Y 7cʚf� �fLYӌ���܌)k�1�6��1c��Y 7cʚf� �fLYӌ���܌)k�1�6��1c��Y 7cʚf� �fLYӌ���،)�h��Y8lƌ2�)�͘r�Ci�S�4chm 7cʚf� �f�Xg3F��͘��Ck�S�4chm 7cʚf� �f�Xg3F��͘��Ck�S�4chm 7cʚf� �fLX/�XW 7cʚf� �fLYӌ���،)�h��Y8nƌs6c$]�܌)k�1�6��1eM3��r3��i���@nƌu6cd]�܌)k�1�6��1eM3��r3��i���@nƌu6cd]�܌)k�1�6��1eM3��r3��i���@nƌu6cd]�܌)k�1�6�1%�:�͘r�Ci�3�ٌ�ur3��i���@nƔ5�Z�͘��Ck�3�ٌ�ur3��i���@nƔ5�Z�͘��Ck�3�ٌ�ur3��i���@nƔ5�Z�͘��Ck�3�ٌ�ub3���Cg�S�4c(m 7cʚf� �f�Xg3F��͘��Ck�S�4chm 7cʚf� �fLX/�XW 7cʚf� �fLYӌ���܌)k�1�6��1c��Y 7cʚf� �fLYӌ���܌)k�1�6�1#M3F��a3���Ce�S�4c(m 7cʚf� �f�Xg3F����q��1��h�>\�;��_،�N/۟`،�3�f��C3���^���������������+ȞO/�����[�� -������|�_p�|�D)hm G)�:��.@�R�5Q -Z�Q��&JAk9JQ�D)hm G)�:��.@�R�5Q -Z�Q��&JAk9JQ�D)hm G)�:��.@�R�s�R���Q��(���(E9������%J� -�(EY�����(k��6��eM���r�b�3J!��(EY�����(k��6��eM���r�b�3J!��(EY�����(k��6��eM���b�b��R��8�R�rD)�,G)ʙ(� �(EY������RȺ�9JQ�D)hm G)ʚ(� �(EY������RȺ�9JQ�D)hm G)ʚ(� �(EY������RȺ�9JQ�D)hm G)ʚ(� �(EIG����a�b��RH�8�R�3Q -J�Q��&JAk9JQ�D)hm G)�:��.@�R�5Q -Z�Q��&JAk9JQ�D)hm G)�:��.@�R�5Q -Z�Q��&JAk9JQ�D)hm G)�z�R��9JQ�D)hm G)ʚ(� �(EIG����q�b�3J!��(EY�����(k��6��eM���r�b�3J!��(EY�����(k��6��eM���r�b�3J!��(EY�����(k��6��eM���r�b�3J!��(EY�����(�R�Y8�R�3Q -J�Q���(����eM���r����R��@�R�5Q -Z�Q���(����eM���r����R��@�R�5Q -Z�Q���(����eM���r����R��@�R�5Q -Z�Q���(���%Q -:�Q�r&JAi9JQ�D)hm G)�:��.@�R�5Q -Z�Q��&JAk9JQ�D)hm G)�z�R��9JQ�D)hm G)ʚ(� �(EY������RȺ�9JQ�D)hm G)ʚ(� �(EY�����i�r6��Q -*�Q�r&JAi9JQ�D)hm G)�:��.@�R� -��EF���"�Q��E�(��F���Yڻ{�RƙK��2�������{��z����O�eF/���g}.��)����×�Bp��Z��>~����k�Ⱥ���Bʚ� -����Z!%�Bg���Bʙ� -����Z!c��"��� -)k^+���k��5Z�����Bk��2�Yp�ur���)���@.��5Z�����Bk��2�Yp�ur���)���@.��5Z�����Bk��2�Yp�uR���{��Ə0,��p\h,\ʙ�� �KX/XW \ʚ�� �KYSp���\p)k -.�6�.c�Y \ʚ�� �KYSp���\p)k -.�6�.c�Y \ʚ�� �KYSp���\p)k -.�6.#M�E��a�����Be��R�\(m \ʚ�� ��Xg�E������Bk��R�\hm \ʚ�� ��Xg�E������Bk��R�\hm \ʚ�� ��Xg�E������Bk��R�\hm \J: -.t.�L�E��q���)�P�@.��5Z�����Bk��2�Yp�ur���)���@.��5Z�����Bk��2�Yp�ur���)���@.��5Z�����Bk���K�������Bk��R�\hm \J: -.t�.�I \ʚ�� �KYSp���\p)k -.�6�.c�Y \ʚ�� �KYSp���\p)k -.�6�.c�Y \ʚ�� �KYSp���\p)k -.�6�.c�Y \ʚ�� ĂKIG����q���)�P�@.��u\d]�\p)k +�6w(�4;�l�P(�ء@e�x�B9�C�����f�� � +c�;d]��CA� +f�/2v(>]�x���"��#�P<��O��Z�C�3١x;�������?�����_��_Oo/�_}�|�e{{;�H㎗�>_�q�q��Ɲ�+wg�;[�����Ɲ� ���YG���b㮬i�Ѻ��qw�Ѹ���ظ;�h���@jܝto��Y8lܕ3�;J 6��:w�6wg�;[�����Ɲ� ��]YӸ�ub�qgk�qw�Ѹ���ظ;�h���@lܕ5�;Z 6��:w�6wg�;[�����Ɲ� ��]YӸ�ub�qgk�qwҽqgg�qw�Ѹ���ظ+kw�.@lܝu4�lm 6��:w�6wg�;[�����qG����YG���b�qgk�qw�Ѹ���ظ+kw�.@lܝu4�lm 6��:w�6wg�;[�����qG����9k���F���;���s�Ɲ� ���Xg�N������Ɲ� ���YG���b�qgk�qW�4�h]�ظ;�h���@lܝu4�lm 6��:w�6weM�������Ɲ� ���YG���b�qgk�qW�Ѹ��qԸ;���pظ;�h�Y�@lܝu4�lm 6�ʚ��wg�;[�����Ɲ� ���YG���b㮬i�Ѻ��qw�Ѹ���ظ;�h���@lܝu4�lm 6�ʚ��wg�;[�����Ɲ� ���I�Ɲ����])G���a�qgi�qw�Ѹ���ظ;�h���@lܕ5�;Z 6��:w�6wg�;[�����Ɲ� ��]YӸ�ub�qgk�qw�Ѹ���ظ;�h���@l܍u6�d]�ظ;�h���@lܝu4�lm 5�N�7��,6�ʙ��wg�;[�����Ɲ� ���YG���b㮬i�Ѻ��qw�Ѹ���ظ;�h���@lܝu4�lm 6�ʚ��wg�;[�����Ɲ� ���YG���b㮬i�Ѻ��qw�Ѹ���Ը;���pظ;�h�Y�@lܕ5�;Z 6��:w�6wg�;[�����Ɲ� ��]YӸ�ub�qgk�qw�Ѹ���ظ;�h���@lܕ5�;Z 6��:w�6wg�;[�����Ɲ� ��]YӸ�uR��{����a�qgi�qw�Ѹ���ظ+kw�.@lܝu4�lm 6��:w�6wg�;[�����Ɲ�+wg�;[�����Ɲ� ���YG���b㮬i�Ѻ��qw�Ѹ���ظ;�h���@lܝu4�lm 5�J:wt6�w��wVw��;K�����Ɲ� ��]YӸ�ub㎱�h��"���y9j��"���?m_�4������巿~������|����C9sm�ϣr�������������p+�|��#ᕿ^�|z۾������p�YV~��qY��E��$��RYSV���\V*k�J�6��JeMY��rYi���$��RYSV���\V*k�J�6��JeMY��rYi���$��RYSV���XV*�(+�Y8.+�3e%J�e��β����JeMY��rY��)+��@.+�5e%Z�e��β����JeMY��rY��)+��@.+�5e%Z�e��β����JeMY��rY��)+��@.+�5e%Z�e��β����J���J4~�aY����DcḬTΔ�(m ���z-+����T֔�hm ��ʚ�� �RYSV���\V�,+ɺ���T֔�hm ��ʚ�� �RYSV���\V�,+ɺ���T֔�hm ��ʚ�� �RYSV���XVi�Jr6�J�e%*�e�r��Di��T֔�hm ���:�J�.@.+�5e%Z�e����Dk��T֔�hm ���:�J�.@.+�5e%Z�e����Dk��T֔�hm ���:�J�.@.+�5e%Z�e����Dk��T�QV��pXVe�JR6��J�LY��rY��)+��@.+�5e%Z�e��β����JeMY��rY��)+��@.+�5e%Z�e��β����JeMY��rY��)+��@.+�5e%Z�e��^�J��@.+�5e%Z�e����Dk��T�QV��p\V�,+I����T֔�hm ��ʚ�� �RYSV���\V�,+ɺ���T֔�hm ��ʚ�� �RYSV���\V�,+ɺ���T֔�hm ��ʚ�� �RYSV���\V�,+ɺ���T֔�hm ��J:�Jt��J�LY��rYi���$��RYSV���\V*k�J�6��JeMY��rYi���$��RYSV���\V*k�J�6��JeMY��rYi���$��RYSV���\V*k�J�6��JeMY��rYi���$�IJRIGY���qY��)+Q�@.+�5e%Z�e��β����JeMY��rY��)+��@.+�5e%Z�e��^�J��@.+�5e%Z�e����Dk��T֔�hm ���:�J�.@.+�5e%Z�e����Dk��T֔�hm ��F�����òR)GY���qY��)+Q�@.+�5e%Z�e��β������NЕ�x�QV~���aYy|���|�SV�<�����q�ZV>���>|�ݟ��o�.�����?���������=|�ڜ�=� +3.��]/�����~�_�V�G�V�����V�ˋ@���r���i5��@n5�5�Zȭ���V���[ eM���r���i5��@n5�5�Zȭ���V���Z ��[ 4~�a�����@c��Pδ(m ��zm5����Pִhm �ʚV� �VCY�j����j�l5Ⱥ���Pִhm �ʚV� �VCY�j����j�l5Ⱥ���Pִhm �ʚV� �VCY�j����jiZ r6[ ��*ǭ�r��@i��Pִhm ��:[ �.@n5�5�Zȭ����@k��Pִhm ��:[ �.@n5�5�Zȭ����@k��Pִhm ��:[ �.@n5�5�Zȭ����@k��P��j��p�jeZ R6�[ �L���r���i5��@n5�5�Zȭ���V���[ eM���r���i5��@n5�5�Zȭ���V���[ eM���r���i5��@n5�5�Zȭ��^[ ��@n5�5�Zȭ����@k��P��j��p�j�l5H����Pִhm �ʚV� �VCY�j����j�l5Ⱥ���Pִhm �ʚV� �VCY�j����j�l5Ⱥ���Pִhm �ʚV� �VCY�j����j�l5Ⱥ���Pִhm �J:Z t�[ �L���r�a��� ��VCY�j����j(kZ �6�[ eM���r�a��� ��VCY�j����j(kZ �6�[ eM���r�a��� ��VCY�j����j(kZ �6�[ eM���r�a��� ��VCIG����q���i5P�@n5�5�Zȭ���V���[ eM���r���i5��@n5�5�Zȭ��^[ ��@n5�5�Zȭ����@k��Pִhm ��:[ �.@n5�5�Zȭ����@k��Pִhm �F�V����VC)G����q���i5P�@n5�5�Zȭ���V���[ � +L���Ƨ����+?k�����[�q��j\F��������� ���}����'Ӎ��ھ�>2�o��~���3����{�ϧ����5n|�~����z9��X�~����֗���QZ��w� <��%S�|�Zȟrf��S�Ⱥ��SΔ5�r���)k>�� �O9S�|�Zȟrf��S�Ⱥ��SΔ5�r���)k>�� �O9S�|�Zȟrf��S�Ⱥ��SΔ5�r��⧜)���3t�?�L9�)g(m ʙ��O9#��O9S�|�Zȟr����3�6�?�LY�)ghm ʙ��r����YeM9��r9��)g��@.g�5�,Z�嬱�r����YeM9��r9��)g��@.g�5�,Z�嬱�r����Y���Y4~�a9����EcḜUΔ�(m ���z-g����U֔�hm ��ʚr� �rVYS��\��,gɺ���U֔�hm ��ʚr� �rVYS��\��,gɺ���U֔�hm ��ʚr� �rVYS��X�i�Yr6�Y��,*��r��Ei��U֔�hm ���:�Y�.@.g�5�,Z�嬲��Ek��U֔�hm ���:�Y�.@.g�5�,Z�嬲��Ek��U֔�hm ���:�Y�.@.g�5�,Z�嬲��Ek��U�Q�pX�e�YR6��Y�L9��r9��)g��@.g�5�,Z�嬱�r����YeM9��r9��)g��@.g�5�,Z�嬱�r����YeM9��r9��)g��@.g�5�,Z�嬰^�Y��@.g�5�,Z�嬲��Ek��U�Q�p\��,gI����U֔�hm ��ʚr� �rVYS��\��,gɺ���U֔�hm ��ʚr� �rVYS��\��,gɺ���U֔�hm ��ʚr� �rVYS��\��,gɺ���U֔�hm ��J:�Yt��Y�L9��r9k���%��rVYS��\�*k�Y�6��YeM9��r9k���%��rVYS��\�*k�Y�6��YeM9��r9k���%��rVYS��\�*k�Y�6��YeM9��r9k���%��rVIG9���q9��)gQ�@.g�5�,Z�嬱�r����YeM9��r9��)g��@.g�5�,Z�嬰^�Y��@.g�5�,Z�嬲��Ek��U֔�hm ���:�Y�.@.g�5�,Z�嬲��Ek��U֔�hm ��F�r����rV)G9���q9��)gQ�@.g�5�,Z�嬱�r�������ӕ�x�Q�~��q9{|���S�.��K����̵�}�����?��������|�9��]�>=�fA��tP��bn<��O7>.ƾ�chm c�:�1�.@.Ɣ5�Z�Ř��b���bL9S����\��,�Ⱥ��S�chm cʚb� �bLYS����\��,�Ⱥ��S�chm cʚb� �bLYS����\��,�Ⱥ��S�chm cʚb� �bLYS����\��,�Ⱥ��SνC�gcJ8�14��1�L1��r1&��b�+��1eM1��r1��)���@.Ɣ5�Z�Ř��b����1eM1��r1��)���@.Ɣ5�Z�Ř��b����1eM1��r1��)���@.Ɣ5�Z�Ř��#g�S�Q���p\�)g�1�6��1eM1��r1f��#��bLYS����\�)k�1�6��1eM1��r1f��#��bLYS����\�)k�1�6��1eM1��r1f��#��bLYS����\�)k�1�6�1%�:�ŘQ�#e�S�c(m cʚb� �bLYS����\��,�Ⱥ��S�chm cʚb� �bLYS����\��,�Ⱥ��S�chm cʚb� �bLYS����\� �� +�bLYS����\�)k�1�6�1%�:�Řq�b����1eM1��r1��)���@.Ɣ5�Z�Ř��b����1eM1��r1��)���@.Ɣ5�Z�Ř��b����1eM1��r1��)���@.Ɣ5�Z�Ř��b����1eM1��b1���Cg�S�c(m c�:�1�.@.Ɣ5�Z�Ř��Ck�S�chm c�:�1�.@.Ɣ5�Z�Ř��Ck�S�chm c�:�1�.@.Ɣ5�Z�Ř��Ck�S�chm c�:�1�.@,Ɣtc�,cʙb� �bLYS����\��,�Ⱥ��S�chm cʚb� �bLYS����\� �� +�bLYS����\�)k�1�6��1eM1��r1f��#��bLYS����\�)k�1�6��1eM1��b1f�)���8,Ɣrc�,cʙb� �bLYS����\��,�Ⱥ��;��\1��ا�c��+?k��e�3�3c�̵{�����������ۿ^{�o������5c�'wu�{�~}]�6cp�ٌ}��q3��E�Ck�3�ٌ�ur3��i���@lƔt4c�,7cʙf� �f�Xg3F��͘��Ck�S�4chm 7cʚf� �f�Xg3F��͘��Ck�S�4chm 7cʚf� �f�Xg3F��͘��Ck�S�4chm 7cʚf� �f�Xg3F�H͘r��?ðS�ь��p܌)g�1�6��1a�6c`]�܌)k�1�6��1eM3��r3��i���@nƌu6cd]�܌)k�1�6��1eM3��r3��i���@nƌu6cd]�܌)k�1�6��1eM3��r3��i���@lƌ4�9�͘R�f���fL9ӌ���܌)k�1�6��1c��Y 7cʚf� �fLYӌ���܌)k�1�6��1c��Y 7cʚf� �fLYӌ���܌)k�1�6��1c��Y 7cʚf� �fLYӌ���،)�h��Y8lƌ2�)�͘r�Ci�S�4chm 7cʚf� �f�Xg3F��͘��Ck�S�4chm 7cʚf� �f�Xg3F��͘��Ck�S�4chm 7cʚf� �fLX��XW 7cʚf� �fLYӌ���،)�h��Y8nƌs6c$]�܌)k�1�6��1eM3��r3��i���@nƌu6cd]�܌)k�1�6��1eM3��r3��i���@nƌu6cd]�܌)k�1�6��1eM3��r3��i���@nƌu6cd]�܌)k�1�6�1%�:�͘r�Ci�3�ٌ�ur3��i���@nƔ5�Z�͘��Ck�3�ٌ�ur3��i���@nƔ5�Z�͘��Ck�3�ٌ�ur3��i���@nƔ5�Z�͘��Ck�3�ٌ�ub3���Cg�S�4c(m 7cʚf� �f�Xg3F��͘��Ck�S�4chm 7cʚf� �fLX��XW 7cʚf� �fLYӌ���܌)k�1�6��1c��Y 7cʚf� �fLYӌ���܌)k�1�6�1#M3F��a3���Ce�S�4c(m 7cʚf� �f�Xg3F����q��1��h�>]�;��_ٌ�/���o0l�ƙk3����7�_�����t���-}���F:�yұ����_�p��|�������r�"7ұ�,[���rz�xiP���k���S��yhm �yʚ8� �8�Xg�G��q��&�Ck1�S�硳p�)g�<�6��<c�qY �yʚ8� �8OY硵��)k�<�6��<c�qY �yʚ8� �8OY硵��)k�<�6��<c�qY �yʚ8� �8OY硵��)k�<�6��<c�qY �yʹ�yh��8O G����q�����P�@����ur�������@��5qZ�q��&�Ck9�3��ur�������@��5qZ�q��&�Ck9�3��ur�������@��5qZ�q��&�Ck1�3��y�l�yJ9�<T��<�L���r�������@��u�yd]��)k�<�6��<eM���r�������@��u�yd]��)k�<�6��<eM���r�������@��u�yd]��)k�<�6��<eM���b���#�Cg�0�3��y�l�yʙ8� �8OY硵��)k�<�6��<c�qY �yʚ8� �8OY硵��)k�<�6��<c�qY �yʚ8� �8OY硵��)k�<�6��<a��y`]��)k�<�6��<eM���b���#�Cg�8�3��tr�������@��5qZ�q��&�Ck9�3��ur�������@��5qZ�q��&�Ck9�3��ur�������@��5qZ�q��&�Ck9�3��ur�������@��t�y�,�yʙ8� �8�Xg�G��q��&�Ck9�S��yhm �yʚ8� �8�Xg�G��q��&�Ck9�S��yhm �yʚ8� �8�Xg�G��q��&�Ck9�S��yhm �yʚ8� �8�Xg�G��q���8���8O9硴��)k�<�6��<c�qY �yʚ8� �8OY硵��)k�<�6��<a��y`]��)k�<�6��<eM���r�������@��u�yd]��)k�<�6��<eM���r�������@��4q9�q�R�8���8O9硴��)k�<�6��<c�qY �y�=����"#��t��8��"K��x'��x/��#�y��5�{q������{{���}�'��n����{}���r�����ᇺ���{ς�ӽ��//Y \ʚ�� ĂKIG����q���)�P�@.��u\d]�\p)k .�6�.eM���r���)���@.��u\d]�\p)k .�6�.eM���r���)���@.��u\d]�\p)k -.�6�.eM���r���)���@.��u\d]�Xp)�(��Y8.��3J�����Bk��2�Yp�ur���)���@.��5Z�����Bk���K�������Bk��R�\hm \ʚ�� ��Xg�E������Bk��R�\hm \ʚ�� Ă�HSp��qXp)�(�PY8.��3J�����Bk��2�Yp�ur�u���/2 -�9.��/�V����@g,�r�Rp������K�����_�|�O_~�4\w����Ղk�����;���_ɷǗ��kFt�q���+�8�X�@��5�Z F�:#�6#g�[��������K���ye鿢!0`X�%##����&�b��(�h�S@ZC�,�T���;"���߈o��L�r�lj�����W`�jb`��F��A���#V{#�������ȩ+0b�10Rj#T� FN]��=���SW`�jb`���ڃ)5��c#g~�X|9F��O��5���3W`�hb`d��:10r� -�X�A���#V{#�������H� �P�9uF�� FN]��=���SW`�jb`��F��A���#V{#�������ȩ+0b�)0R� -���9 -�y -���9���#F{#�������H� �P�9uF�� FN]��=���SW`�jb`��F��A���#V{#�������ȩ+0b�10Rj#T� FN]��=���SW`�jR`��S`�f�Q`��!�s9sF�� FN]��=���SW`�jb`��F��A���#V{#�������ȩ+0b�10Rj#T� FN]��=���SW`�jb`���ڃuF��A���#V{#�������ȡ���͚��H� ��9uF�� FN]��=���SW`�jb`��F��A���#V{#�������ȩ+0b�10Rj#T� FN]��=���SW`�jb`���ڃ)5��c#�������ȡ���͚��ș+0b�10Rj#T� FN]��=���SW`�jb`���ڃ)5��c#�������ȩ+0b�10r� -�X�A�����1���SW`�jb`���ڃ9uF�� FJM`����ȡ���͚��ș+0b�10r� -�X�A�����1���SW`�jb`���ڃ9uF�� FF݁�s#�������ȩ+0b�10r� -�X�A�����1���SW`�jb`���ڃ9uF�� F -]��=G��#O��5���3W`�hb`���ڃ)5��c#�bD`�_����_�00�/�뇫��?u����{���|��zx�W�oF�C�L�������O�ӿ|���/���S���O�|=G�_�������?�]�_�>?(8����ܧ�}T����3��z�w��z�E��"ur��@�� @JM�jr��@�� @F��c� ���B���Rj - T{� ���B���2�.�H�\�)5�=��RS��ڃ\�)5�=��QwD��H��ŗcX�)p@(�@�L�hr$�s��H�)�P�A.�����H�)�P�A.��� R� @JM�jr��@�� @JM�jrd�]��:��Rj - T{� ���B���Rj - T{ ���"���R�*���9.�����H�)�P�A.��� R� @JM�jr��@�� @JM�jrd�]��:��Rj - T{� ���B���Rj - T{� ����1��RS��ڃ\�)5�=��BW�f�ad�@D�@�L�hr��@�� @JM�jrd�]��:��Rj - T{� ���B���Rj - T{� ����1��RS��ڃ\�)5�=��RS��ڃ\� �\��:��Rj - T{� ���B���R�*�Ь9.��� B� @JM�jr��@�� @JM�jrd�]��:��Rj +.�6�.eM���r���)���@.��u\d]�Tp)�^p��3.%��r��Bi���k�������Bk��R�\hm \ʚ�� ��Xg�E������Bk��R�\hm \ʚ�� ��Xg�E������Bk��R�\hm \ʚ�� Ă�HSp��qXp)�(�PY8.��3J�����Bk��2�Yp�ur���)���@.��5Z�����Bk��2�Yp�ur���)���@.��5Z�����Bk��2�Yp�ur���)���@.��5Z�������Â�(Sp��q\p)g +.�6�.eM���r���)���@.��u\d]�\p)k +.�6�.eM���r���)���@.��u\d]�\p)k +.�6�.eM���r���)���@.���Zp�ur���)���@.��5Z���������8g�E������Bk��R�\hm \ʚ�� ��Xg�E������Bk��R�\hm \ʚ�� ��Xg�E������Bk��R�\hm \ʚ�� ��Xg�E������Bk��R�Qp��p\p)g +.�6�.c�Y \ʚ�� �KYSp���\p)k +.�6�.c�Y \ʚ�� �KYSp���\p)k +.�6�.c�Y \ʚ�� �KYSp���\p)k +.�6�.c�Y \J: +.t�.�L���r���)���@.��u\d]�\p)k +.�6�.eM���r���)���@.���Zp�ur���)���@.��5Z�����Bk��2�Yp�ur���)���@.��5Z�����Bk��2�\�l\J9 +.T�.�L���r���)���@.��u\d]�\pwG������E�������]odW~���R�҅���$��l��О��}�� [NK��S�T��O?���vp��x⩫.����(���~���>�v����Xp�s��� +���?����_��?~��I&\�o��}����/���łk}���;�|�_�z�=.wc�� vcJM7���n̩�c��s�c��s����A�Ɣ�n�1�ݘSW7�jb7��Ս�ڃ؍9uuc�� vcJM7���n̩�c��s���X�A�Ɯ��1V{�1��Cub7��Ս�ڃ؍9uuc�� vcN]��=�ݘRӍ�:�s��n�ŗcԍ9�ԍ�Xs؍9suc�� vcF���s�1��n���n̩�c��s���X�A�Ɣ�n�1�ݘSW7�jb7��Ս�ڃ؍9uuc�� vcJM7���n̩�c��s���X�A�Ɯ��1V{��1��n͞�n̑�n�ɚ�n̙�c��s���X�A�Ɣ�n�1�ݘSW7�jb7��Ս�ڃ؍9uuc�� vcJM7���n̩�c��s���X�A�Ɯ��1V{�1��Cub7��Ս�ڃ؍9uuc�� uc=ucl�uc�\��=�ݘ3W7�hb7��Ս�ڃ؍9uuc�� vcJM7���n̩�c��s���X�A�Ɯ��1V{�1��Cub7��Ս�ڃ؍9uuc�� vcN]��=�ݘQw7F��n̩�c��s���X�A��z��ج9�Ɣ�n�1�ݘSW7�jb7��Ս�ڃ؍9uuc�� vcJM7���n̩�c��s���X�A�Ɯ��1V{�1��Cub7��Ս�ڃ؍9uuc�� vcN]��=�ݘRӍ�:�s���X�A��z��ج9�Ɯ��1F{�1��Cub7��Ս�ڃ؍9uuc�� vcN]��=�ݘRӍ�:�s���X�A�Ɯ��1V{�1��n���nL���P�؍9uuc�� vcN]��=�ݘSW7�jb7��tc��A��z��ج9�Ɯ��1F{�1��n���nL���P�؍9uuc�� vcN]��=�ݘSW7�jb7f�ݍ�:�s���X�A�Ɯ��1V{�1��n���nL���P�؍9uuc�� vcN]��=�ݘSW7�jR7��Ս��sԍ9�ԍ1Ys؍9suc�� vcN]��=�ݘRӍ�:���Itc�"��^���n^����݇����_-b7��9wcO����<�㷟~�>}��O_��ػ�#�ofcǿs~��w�g�������n,��v�o}90z�!ڃuF��A�������H� �P�A�������Ȩ;0"ur`��F�� FJM`�jr`��F�� FF݁�c�#�&0B�90Rj#T{�#�&0B�902��H�)���r#��Ś��H� ��A��z�@��)5��=ȁ�R�ڃ)5��=ȁ�Qw`D���H� �P�A�������H� �P�A���#R� FJM`�jr`��F�� FJM`�jb`d�Fd�F�\��5ǁ�2!ڃ)5��=ȁ�Qw`D���H� �P�A�������H� �P�A���#R� FJM`�jr`��F�� FJM`�jr`d��:90Rj#T{�#�&0B�10R� +�Ь9����Ȟ��H� ��A�������H� �P�A���#R� FJM`�jr`��F�� FJM`�jr`d��:90Rj#T{�#�&0B�90Rj#T{�#��#P� FJM`�jr`��F�� F +]��5ǁ�1w`D���H� �P�A�������H� �P�A���#R� FJM`�jr`��F�� FJM`�jr`d��:90Rj#T{�#�&0B�90Rj#T{�#�����1ȁ�R�ڃ)tFh�F�L`�hr`d��:90Rj#T{�#�&0B�90Rj#T{�#�����1ȁ�R�ڃ)5��=ȁ�R�ڃuF��A�������H� �P�A�������Ȩ;0"ub`���Ys)3��=ȁ�R�ڃuF��A�������H� �P�A�������H����9ȁ�R�ڃ)5��=ȁ�R�ڃuF��A�������H� �P�A�������Ƞ ���9��#$k�#e&0B�90Rj#T{�#�����1ȁe1&0�Y�ы�]~���?<���]�0����=Ͽ4����Ƿ��P�I`���?}����?������~�����2��ϟ�|;G?~�ӿ��t��߮�n��_f���=�����(�����������@D��H�)�P�A.�����H�)�P�A.��� R� @JM�jr��@�� @JM�jrd�]��:��Rj T{� ���B���Rj - T{� ����1��RS��ڃ\�)5�=��RS��ڃ\�u@��A.�����H���B���Rf - D{� ����1��RS��ڃ\�)5�=��RS��ڃ\�u@��A.�����H�)�P�A.�����Ȩ��"ur��@�� @JM�jr��@�� @F��c ��͚�H�)��A.�����Ȩ��"ur��@�� @JM�jr��@�� @B=@��A.�����H�)�P�A.�����Ȩ��"ur��@�� @JM�jr��@�� @MDf�a��U�!Ys\�)3�=��RS��ڃ\�u@��A.��W��YЋ/�xX��o�a���<?1��O���>�__=�=����g�S�s�����}���ǿ~������y��e<�.?������/����÷���_>�������p}u���[_䵺>��<Po���z������Q���^P{�@}�c�����|[}x�c�q��l����gp}-��g/�=x�>������<P�><ڿ���^P{�m�������>��<Po�>|����<P�n��f(���j�O���RO�������ɻ�?�;�注������^���^P{�@}�c�� ��g/�=x�>�1\[���j��^?�1�s�4�ϲ:�۫��G��>{A����������^P{�@}�����}�Yso�7�W��?�䳌������ު��^P{�@}�3x#��g/�=x�>�)��J���j���>�1�Ju}��1x�>�1��I���j�O��p�g/�=x�>�1�����|[���z�(�in}��1x��^�����>{A��������>{A������G���j� -���{�O8볬�����Ϊ��^P{�@=�*�B�Ys�#��̉D{�O�u�!u�����=�'F��#�� �QjN��ڃ|bĨ���c�O�(5'FP�A>1�ԜA��ĈRsb��#F�'FH�|bD�91�j�����=�'F��#�� �1�>1B��#�<�A���Q�:1�b��e���=�'F�z>1��#J͉T{�O�(5'FP�A>1�ԜA��ĈQ��R� �QjN��ڃ|bD�91�j�����=�'F��O��:�ĈRsb��#J͉T{�O�(5'FP�A<1bМ!���Ĉ"$k�O�(3'F�A>1�ԜA��ĈQ��R� �QjN��ڃ|bD�91�j�����=�'F��O��:�ĈRsb��#J͉T{�O�(5'FP�A>1b�}b��1�'F��#�� �QjN��ڃxbD����5�'F�#D��QfN� ڃ|bD�91�j�����=�'F��O��:�ĈRsb��#J͉T{�O�(5'FP�A>1b�}b��1�'F��#�� �QjN��ڃ|bD�91�j���O��:�ĈRsb��#J͉T{O�(t�A���Ĉ1��B� �QjN��ڃ|bD�91�j�����=�'F��O��:�ĈRsb��#J͉T{�O�(5'FP�A>1b�}b��1�'F��#�� �QjN��ڃ|bD�91�j���#��A>1�ԜA��ĈB4k�O�(3'F�A>1b�}b��1�'F��#�� �QjN��ڃ|bD�91�j���#��A>1�ԜA��ĈRsb��#J͉T{�O�u�!u�����=�'F��#�� �QjN��ڃ|bĨ���cO�(t�A���Ĉ2sb��#J͉T{�O�u�!u�����=�'F��#�� �QjN��ڃ|bD��#��A>1�ԜA��ĈRsb��#J͉T{�O�u�!u�����=�'F��#�� �QjN��ڃxbĠ91Bf��E�#H��QfN� ڃ|bD�91�j���#��A>1�3ĉ�"��ȋ/r|b�����?2|�p��x�?2�>�##����Ͽ����֭�7�ܞ����K���7F���~9[����-x�=�l�c��(5gP�A>[�Ԝ-@��l�Rs����B=�-�u����l�=�g����� �-Pj��ڃ|����l�c��(5gP�A>[�Ԝ-@��l�B��4k��s�- t����l�=�g����� �-Pj��ڃ|����l�c��(5gP�A>[�Ԝ-@��l�Rs����F�gH�|�@�9[�j����l�=�g����� �-0�>[@��J��T{�(t�-@���l�2s����F�gH�|�@�9[�j����l�=�g����� �-0�>[@��J��T{��(5gP�A>[�Ԝ-@��l�Q��R� �-Pj��ڃ|�@�9[�j����l�=�g����:�l�2OgP|9�g���Xs|�@�9[�h������:�l�Rs����J��T{��(5gP�A>[`�}���1�g����� �-Pj��ڃ|�@�9[�j������A>[�Ԝ-@��l�Rs����J��T{�4g��9<[��u��ɚ����D{��(5gP�A>[`�}���1�g����� �-Pj��ڃ|�@�9[�j������A>[�Ԝ-@��l�Rs����J��T{��u�- u����l�=�g����� �-P�:[�f���C�l�=�g����� �-Pj��ڃ|�@�9[�j������A>[�Ԝ-@��l�Rs����J��T{��u�- u����l�=�g����� �-Pj��ڃ|�@����A>[�Ԝ-@��l�Rs���ij -]gЬ9>[`�}���1�g����� �-Pj��ڃ|�@�9[�j������A>[�Ԝ-@��l�Rs����J��T{��u�- u����l�=�g����� �-Pj��ڃ|����l�c��(5gP�A<[��u��͚����D{��u�- u����l�=�g����� �-Pj��ڃ|����l�c��(5gP�A>[�Ԝ-@��l�Rs����F�gH�|�@�9[�j����l�=�g����� �-0�>[@�ij -]gЬ9>[�̜-@��l�Rs����F�gH�|�@�9[�j����l�=�g����� �-��l�s��(5gP�A>[�Ԝ-@��l�Rs����F�gH�|�@�9[�j����l�=�g����� �-0h���sx�@��l�5�g����� �-Pj��ڃ|����l�c��P�o��Yg^|���_d�-��p�����k�g�gr��f�-�Ǐ_?����?��֟?}��������������?(=[�]_=<���;���]w����ɯ��ɨ� ��JM��jb���'�Ys's�Ʉ�A����8��8Y���Q�A����8��8٨;N&ur����ɨ� ��JM��jr����ɨ� ��F�q2�c��d�&NF�9NVj�dT{��d�&NF�9N6ꎓI�'+5q2�=�q�BW��f�q����Ɉ� ��F�q2�c��d�&NF�9NVj�dT{��d�&NF�9N6ꎓI�'+5q2�=�q�R'�ڃ'+5q2�=�q�Qw�L��8Y���Q�A����8��8Y���Q�A�����dR� ���<��(��8Y�+NF��8NVf�dD{��d���dP� ��JM��jr����ɨ� ��JM��jr�l�'�:9NVj�dT{��d�&NF�9NVj�dT{��d��8��1�q�R'�ڃ'+5q2�=�q�R'�ڃ'4q2�=�q�"W��d�q����Ɉ� ��JM��jr�l�'�:9NVj�dT{��d�&NF�9NVj�dT{��d��8��1�q�R'�ڃ'+5q2�=�q�R'�ڃ'u�ɤ�A����8��8Y���Q�A����d4k�dC&N&��8NVf�dD{��d�&NF�9NVj�dT{��d��8��1�q�R'�ڃ'+5q2�=�q�R'�ڃ'u�ɤ�A����8��8Y���Q�A����8��8Y��8�9�q�R'�ڃ'+5q2�=�q�BW��f�q�l�':9NVj�dT{��d�&NF�9NVj�dT{��d��8��1�q�R'�ڃ'+5q2�=�q�R'�ڃ'u�ɤ�A����8��8Y���Q�A����8��8٨;N&ur����ɨ� �� -]q2�5�q�2'#ڃ'u�ɤ�A����8��8Y���Q�A����8��8٨;N&ur����ɨ� ��JM��jr����ɨ� ��F�q2�c��d�&NF�9NVj�dT{��d�&NF�9N6ꎓI�'+t��h����L��hr����ɨ� ��F�q2�c��d�&NF�9NVj�dT{��d�&NF�9N�9Nur����ɨ� ��JM��jr����ɨ� ��F�q2�c��d�&NF�9NVj�dT{��d�&NF�1N6h�d2{�dE�8ɚ�8Y����A����Svo�.������_���a�{�=�p�x��]/��w�Ww��y�������۽��P>s�u�C�������?|�������~��_��~����h�L��k������9|�����W?~f����3sT{���+5��Q�A~fn��̜�1H�̕yzf���1|f����Ś�g���3sD{�������9��̕�g�� ?3Wj���ڃ��\�yf�j�3s��g椎A~f��<3G����R����g�J�3sT{���u?3'u�3s��9�=��̕�g�� ?3Wj���ڃ��ܠyfNf��3sE�g�H�?3Wf��#ڃ��\�yf�j�3s��g椎A~f��<3G����R����g�J�3sT{���u?3'u�3s��9�=��̕�g�� ?3Wj���ڃ��ܨ��9�c���+5��Q�A~f��<3G��B�3s4k��2�̉�9~f��<3G����R����g�J�3sT{���u?3'u�3s��9�=��̕�g�� ?3Wj���ڃ��ܨ��9�c���+5��Q�A~f��<3G����R����g�B=?3u�3s��9�=��̕�g�� >3W�zf�f��3sc�g愎A~f��<3G����R����g�J�3sT{���u?3'u�3s��9�=��̕�g�� ?3Wj���ڃ��ܨ��9�c���+5��Q�A~f��<3G����R����g�F���I���\�yf�j�3s��g�h�?3Wf��#ڃ��ܨ��9�c���+5��Q�A~f��<3G����R����g�F���I���\�yf�j�3s��9�=��̕�g�� ?37�~fN��g�J�3sT{���+5��Q�A~f��<3G����Q�3sR� >3W�zf�f��3se�9�=��̕�g�� ?37�~fN��g�J�3sT{���+5��Q�A~f��<3G����P���A����\�yf�j�3s��9�=��̕�g�� ?37�~fN��g�J�3sT{���+5��Q�A~f��<3G��A�̜̞�g�\�̑�9~f��<3G���9=����{���������{�g�7��?����~f�>s~f�������������&��_����~<zF������;_-z����e��SQ�����c�{J���)T{�{J���)T{{J�뷧Ь9��)c�ߞ"t�oO)5�=�j�oO)5�=�j�oO)5�=�j�oOu���c�{J���)T{�{J���)T{�{J���)T{�{ʨ���H���SJ�oO�ڃ��SJ�oO�ڃ��SJ�oO�ڃ��SFݿ=E��ߞRj~{ -��ߞR���)4k�{J���)D{�{ʨ���H���SJ�oO�ڃ��SJ�oO�ڃ��SJ�oO�ڃ��SFݿ=E��ߞRj~{ -��ߞRj~{ -��ߞRj~{ -��ߞ2���)R� ���R�ڃ+5Q0�=�Q�R�ڃuG���A���y��Q|9�Q�W�b�q��D��� G�B=G���A����(��(X���Q�A����(��(ب; -&ur��D��� G�JM�jr��D��� G�F�Q0�c��`�& -F�9 + T{� ����1H�2O�/ǰ�R�*�P�9.�����H���9��RS��ڃ\�)5�=��RS��ڃ\�u@��A.�����H�)�P�A.�����Ȩ��"ur��@�� @JM�jr��@�� @MDf�a��U�!Ys\�)3�=��RS��ڃ\�u@��A.�����H�)�P�A.�����Ȩ��"ur��@�� @JM�jr��@�� @F��c� ���B���Rj + T{ ��͚�Ȑ)���9.�����H�)�P�A.�����Ȩ��"ur��@�� @JM�jr��@�� @F��c� ���B���Rj + T{� ���B�����ur��@�� @JM�jb��U��Ys\�s@��A.�����H�)�P�A.�����Ȩ��"ur��@�� @JM�jr��@�� @F��c� ���B���Rj + T{� ���B���2�.�H�\�)5�=��BW�f�q��@�� @F��c� ���B���Rj + T{� ���B���2�.�H�\�)5�=��RS��ڃ\�)5�=��QwD��H�)�P�A.�����H�)�P�A.��� R� @ +]�5��2S�!ڃ\�)5�=��QwD��H�)�P�A.�����H�)�P�A.��z.�@��\�)5�=��RS��ڃ\�)5�=��QwD��H�)�P�A.�����H�)�P�A,���̞�H���B���Rf + D{� ���B���2�.�H�\�]NT\�/� +�/r����"����R��?�<==p��I�a@����o���O����������������������ϟ����8�<]8��|��������g�;��������/��=�ńRSL�ڃ\Lu��A.&��b��bB�)&P�A.&��b��b¨�� uR1��S1���1,&�� k�� e��@���깘�ur1���� JM1�jr1���� F���c�� ���@���Pj� T{�� ���@���0�.&H�\L(5��=�ńRSL�ڃ\L(5��=�ńASL��sXL(rH��L1�hr1���� F���c�� ���@���Pj� T{�� ���@���0�.&H�\L(5��=�ńRSL�ڃ\L(5��=�ńQw1A��bB�)&P�A.&��b��bB���@�氘0d� "{�� e��@���Pj� T{�� ���@���0�.&H�\L(5��=�ńRSL�ڃ\L(5��=�ńQw1A��bB�)&P�A.&��b��bB�)&P�A.&�z.&@��\L(5��=�ńRSL�ڃXL(th�����c�� ���@���Pj� T{�� ���@���0�.&H�\L(5��=�ńRSL�ڃ\L(5��=�ńQw1A��bB�)&P�A.&��b��bB�)&P�A.&��� R� JM1�jb1��UL�Ys\L(3��=�ńQw1A��bB�)&P�A.&��b��bB�)&P�A.&��� R� JM1�jr1���� JM1�jr1a�]L�:��Pj� T{�� ���@���Pj� T{�� ��b��1�ńBW1�f�q1���� JM1�jr1a�]L�:��Pj� T{�� ���@���Pj� T{�� ��� P� JM1�jr1���� JM1�jr1a�]L�:��Pj� T{�� ���@���Pj� T{� ��� �簘P�*&��9.&��b��bB�)&P�A.&��� R� ����b_d/^�r1q�E��Ð��<�L9�)�����������Z��S/q�j������x����|����o_�{��d�|�����/��Ӆ_���������/�|�W?�Ç����o��ku=������<�?J����/�ϟ�y����+j^P�?�[������������p��ӣl����38�yz� +ڃ�����UO�^Q{���x�������������������nF]ϲ:/�w7>X����/�7��G3�zz��ڃ����p)������N��Nͳ������p� �ӳW�����zz��ڃ���`�ӳW�|[=�ܟ��,�c��zw���$�ӳW���>��zz��ڃ�Ǜ����+fͽM�nܟp�,�c��z�<X����/�ǟ��[���������S������+j���wR]ϲ:/�����TO�^Q{��z�1�pֳW����zz��ڃo����wO�Os�YV���������z��ڃ������g��=xA}�yo�(�������������z��1xA=��zz��ڃ���R���b��r}CU��(+�=�e5��(+�c�?ʪ�|��䏲*5eE����J�GYQ�A�(�Q�GYI��QV��T{��Qj�A�����T{��1�b��1�W�(5W��ڃ|ňRs��=�W�(5W��ڃ|ňQ�#��A�bD��+FP|9�W�(p]1�b��#��#�� _1"��#��A�bD��b��+F��+FP�A�bD��b��+F���!u�#J�#�� _1��\1�j�#J�#�� _1b�}��c��Qj�A�����T{��Qj�A����2{�Q�bɚ�+F��+F�A�bD��b��+F���!u�#J�#�� _1��\1�j�#J�#�� _1b�}��c��Qj�A�����T{��Qj�A�����+FH�|ňRs��=�W�(5W��ڃxňB�#h�^1b�\1Bd��#��#�� _1��\1�j�#J�#�� _1b�}��c��Qj�A�����T{��Qj�A�����+FH�|ňRs��=�W�(5W��ڃ|ňRs��=�W��|��s��Qj�A�����T{�Q�b͚�+F���!t�#J�#�� _1��\1�j�#J�#�� _1b�}��c��Qj�A�����T{��Qj�A�����+FH�|ňRs��=�W�(5W��ڃ|ňRs��=�W�u_1B��+F��+FP�A�bD��4k��Qf�A�����+FH�|ňRs��=�W�(5W��ڃ|ňRs��=�W�u_1B��+F��+FP�A�bD��b��+F��+FP�A�bĨ��R� _1��\1�j�#J�#�� _1��\1�j�#F�W��:���+FЬ9�bD��b��+F��+FP�A�bĨ��R� _1��\1�j�#J�#�� _1��\1�j�#B=_1��+F��+FP�A�bD��b��+F��+FP�A�bĨ��R� _1��\1�j�#J�#�� _1��\1�j�#�#d�^1��u��5�W�(3W� ڃ|��"q�ڍ�Ǜks��y��woݸ��;��+�)���y�t��)]��ލúy���~���O���7������b�?@^�vc���~)�_�����{@�O��_�)�Q�A.������_�)�Q�A.��z.�A��\�+5%?�=�%�RS�ڃ\�+5%?�=�%�Qw�O��_�)�Q�A.�����Ē_���G���7�.� �\�+5%?�=�%�RS�ڃ\�+5%?�=�%�Qw�O��_�)�Q�A.������_�)�Q�A.���K~R� ��JMɏjrɯԔ��� ��JMɏjr�o�]�:��WjJ~T{K~���͚�_�)��A.���K~R� ��JMɏjrɯԔ��� ��JMɏjr�o�]�:��WjJ~T{�K~���G���WjJ~T{�K~��1�%�RS�ڃ\�+5%?�=�%�RS�ڃ\�u����A*��y*�Q|9�%�Wɏb�qɯ̔��� ��B=����A.������_�)�Q�A.������ߨ��'urɯԔ��� ��JMɏjrɯԔ��� ��F�%?�c�K~���G���WjJ~T{�K~���G���7hJ~2{K~E��ɚ�_�)��A.������ߨ��'urɯԔ��� ��JMɏjrɯԔ��� ��F�%?�c�K~���G���WjJ~T{�K~���G���7�.�I�\�+5%?�=�%�RS�ڃX�+t��h����L�Od�qɯ̔��� ��JMɏjrɯԔ��� ��F�%?�c�K~���G���WjJ~T{�K~���G���7�.�I�\�+5%?�=�%�RS�ڃ\�+5%?�=�%�P�%?�s�K~���G���WjJ~T{K~���͚�ߘ��'trɯԔ��� ��JMɏjrɯԔ��� ��F�%?�c�K~���G���WjJ~T{�K~���G���7�.�I�\�+5%?�=�%�RS�ڃ\�+5%?�=�%�Qw�O��_�)�Q�A,��J~4k�K~e��G���7�.�I�\�+5%?�=�%�RS�ڃ\�+5%?�=�%�Qw�O��_�)�Q�A.������_�)�Q�A.���K~R� ��JMɏjrɯԔ��� ��JMɏjr�o�]�:��W�*�Ѭ9.������_�)�Q�A.���K~R� ��JMɏjrɯԔ��� ��JMɏjr�/�s���_�)�Q�A.������_�)�Q�A.���K~R� ��JMɏjrɯԔ��� ��JMɏjb�oД�d����\%?�5�%�2S�#ڃ\�S�.J~|�S���5����俽R��o�p�%�z&%��*���㷏����N��ϟ��Ǐ��?|��: ~:����^X�7��ߛ��ν.���u_���^���@��jr������� �� +]�.�5ǽ�1w�K��^W��uQ�A�u��^��^W��uQ�A�u��{]R� ��JM��jr������� ��JM��jr�k���:��Ujz]T{�{]���E���Ujz]T{�{]��^��1Ƚ�R��ڃ��*t��h����L��hr�k���:��Ujz]T{�{]���E���Ujz]T{�{]��^��1Ƚ�R��ڃ��*5�.�=Ƚ�R��ڃ��u����A�u��^��^W��uQ�A�u��^��^ר��%uR���S����1�u�z]k�{]e��E�����ur������� ��JM��jr������� ��Fݽ.�c�{]���E���Ujz]T{�{]���E���5��uI���*5�.�=Ƚ�R��ڃ��*5�.�=���A���s��*r��H����L��hr������� ��Fݽ.�c�{]���E���Ujz]T{�{]���E���5��uI���*5�.�=Ƚ�R��ڃ��*5�.�=Ƚ�Qw�K��^W��uQ�A�u��^��^W���E���5dz]"{�{]e��E���Ujz]T{�{]���E���5��uI���*5�.�=Ƚ�R��ڃ��*5�.�=Ƚ�Qw�K��^W��uQ�A�u��^��^W��uQ�A�u�z�uA����*5�.�=Ƚ�R��ڃ��*t��h����ܽ.�c�{]���E���Ujz]T{�{]���E���5��uI���*5�.�=Ƚ�R��ڃ��*5�.�=Ƚ�Qw�K��^W��uQ�A�u��^��^W��uQ�A�u��{]R� ��JM��jb�����Ys��*3�.�=Ƚ�Qw�K��^W��uQ�A�u��^��^W��uQ�A�u��{]R� ��JM��jr������� ��JM��jr�k���:��Ujz]T{�{]���E���Ujz]T{�{]��^��1���BW��f�q������� ��JM��jr�k���:��Ujz]T{�{]���E���Ujz]T{�{]��{]P� ��JM��jr������� ��JM��jr�k���:��Ujz]T{�{]���E���Ujz]T{{]���%���U��u��9�u��^��^�rr�z]|�S���5��s�t|�+_������������۽�z(Ϝ{�|{�o���������w����/�����s��? �=��������_�}̜^=�|�����x����Y�A<f��u̜��c�J�1sT� 3w��c�,��c�<3g���3�1sF{��u3'u�1s��c�� 3w�:f�j�1s��c�� 3Wj���:�S�1sV{��;u3g��S�1sV{��+5��Q�x�ܩ�9�=��̝����ڃx�ܩ�9�=H�������st�ܑ�c�L�3w�:f�h�1s��c�� 3Wj���:�S�1sV{��;u3g��S�1sV{��+5��Q�x�ܩ�9�=��̝����ڃx�ܩ�9�=��̕�c樎A<f��u̜��c�N]��Y�A:f���1s6k���+r3G���3�1sF{��;u3g��S�1sV{��+5��Q�x�ܩ�9�=��̝����ڃx�ܩ�9�=��̕�c樎A<f��u̜��c�N]��Y�A<f��u̜��c�F���I��x�ܩ�9�=��̝����ڃt�ܡ�c�l�3Wf��#:�S�1sV{��;u3g��S�1sV{��+5��Q�x�ܩ�9�=��̝����ڃx�ܩ�9�=��̕�c樎A<f��u̜��c�N]��Y�A<f��u̜��c�J�1sT� 3w�:f�j�1s�����Ysx�ܙ�9�=��̕�c樎A<f��u̜��c�N]��Y�A<f��u̜��c�J�1sT� 3w�:f�j�1s��c�� 3w�:f�j�1s��9�c��;u3g��S�1sV{��;u3g��Rs��1H��z:f�f��1sg�c�� 3w�:f�j�1s��9�c��;u3g��S�1sV{��;u3g��Q�1sR� 3w�:f�j�1s��c�� 3w�:f�j�1s��9�c��;u3g��S�1sV{��;u3g�阹B�1s4{���;�t̜ɚ�c��\���A<f�G��3�������8.3����o�3�?���3_Ϝ����P�������W�O�6�<������t������;���^��_F:}*����)T� ~{ʩ��S�� ~{ʩ��S�� }{ʡ�oO�Ys��)e��S��A���S�X�A���S�X�A���S�X�A���R��)T� ~{ʩ��S�� ~{ʩ��S�� ~{ʩ��S�� ~{J����c�=����)V{�=����)V{�=����)V{�=��|{ +�1�ߞr����=Hߞr���Sl�~{ʙ��S�� ~{J����c�=����)V{�=����)V{�=����)V{�=��|{ +�1�ߞr����=�ߞr����=�ߞr����=�ߞRj�=���oO95Q0�=�Q�R�ڃ+5Q0�=�Q�QwL��(X��(ŗc+pE�(�G��L�hr,�s��(X���Q�A����(��(X���Q�A�����`R� G�JM�jr��D��� G�JM�jrl��:9 Vj�`T{��`�& -F�1 -6h�`2{�`E�(ɚ�(X����A����(��(ب; -&ur��D��� G�JM�jr��D��� G�F�Q0�c��`�& F�9 +Vj�`T{�`�& +&��0 +V䊂��9����(��(X���Q�A�����`R� G�JM�jr��D��� G�JM�jrl��:9 Vj�`T{��`�& F�9 -6ꎂI�+5Q0�=�Q�R�ڃ+tE�h�F��LLd�q��D��� G�JM�jr��D��� G�F�Q0�c��`�& -F�9 +Vj�`T{��`��(��1�Q�R�ڃ+5Q0�=�Q�BW�f�al�D�D�G��L�hr��D��� G�JM�jrl��:9 Vj�`T{��`�& F�9 -6ꎂI�+5Q0�=�Q�R�ڃ+5Q0�=�Q�P�Q0�s��`�& -F�9 -Vj�`T{�`��(͚�(ؘ; -&tr��D��� G�JM�jr��D��� G�F�Q0�c��`�& -F�9 +Vj�`T{��`��(��1�Q�R�ڃ+5Q0�=�Q�R�ڃ��:9 +Vj�`T{��`�& +F�1 +V节Ѭ9�����`B� G�JM�jr��D��� G�JM�jrl��:9 Vj�`T{��`�& F�9 -6ꎂI�+5Q0�=�Q�R�ڃ+5Q0�=�Q�QwL��(X���Q�A����`4k��`e& -F�9 -6ꎂI�+5Q0�=�Q�R�ڃ+5Q0�=�Q�QwL��(X���Q�A����(��(X���Q�A�����`R� G�JM�jr��D��� G�JM�jrl��:1 -V节Ѭ9����(��(X���Q�A�����`R� G�JM�jr��D��� G�JM�jr,�s��(X���Q�A����(��(X���Q�A�����`R� G�JM�jr��D��� G�JM�jbl�D�d�F��\Q0�5�Q�2#ڃS�*�`��(��׀(��{�m�=u�����3�(�vE�����_���2���K�}����K\+���$������0q|�'��� &�JM����ѩ+qd�1qt�JY�AL��GV{G�&qDub��ԕ8�ڃ�8:u%��� &�N]�#�=���R�8�:1qt�JY�AJzJ٬9L��GF{G�&qDub��ԕ8�ڃ�8:u%��� &�N]�#�=���R�8�:1qt�JY�AL��GV{G��đ���Q�IQ��8:u%��� &�N]�#�=���SW��jb��$���AH��-qd��%�<%�,�&��\�#�=���Qw�H���ѩ+qd�1qt�JY�AL��GV{G�&qDub��ԕ8�ڃ�8:u%��� &�N]�#�=���R�8�:1qt�JY�AL��GV{G��đ���Q�+qD��(qt�)qd��0qt�J�AL��GV{G�&qDub��ԕ8�ڃ�8:u%��� &�N]�#�=���R�8�:1qt�JY�AL��GV{G��đ���Q�IQ��8:u%��� &�N]�#�=H��CO�#�5G��"W�d�a��̕82ڃ�8:u%��� &�N]�#�=���R�8�:1qt�JY�AL��GV{G��đ���Q�IQ��8:u%��� &�N]�#�=���SW��jb�hԝ8�:1qt�JY�AL��GV{�G��G6kGe&qDtb��ԕ8�ڃ�8:u%��� &�N]�#�=���R�8�:1qt�JY�AL��GV{G��đ���Q�IQ��8:u%��� &�N]�#�=���SW��jb��$���AL��GV{�G��G6kGg�đ���Q�IQ��8:u%��� &�N]�#�=���SW��jb��$���AL��GV{G��đ���ѩ+qd�1qTjGT� &�N]�#�=���SW��jb��ԕ8�ڃ�8*5�#�c�G��G6kGg�đ���ѩ+qd�1qTjGT� &�N]�#�=���SW��jb��ԕ8�ڃ�8u'���AL��GV{G��đ���ѩ+qd�1qTjGT� &�N]�#�=���SW��jb��ԕ8�ڃ�8*t%�h�%��<%�L�&��\�#�=��#{&q����3/����Q���w�Ww�~������A=����a��v�>��$qL���O�~��~�����]������v^��[<m=������ͷ��`>���~�������[_� ���j��W7���_���^P{�@=��S��˲ڃ���J��ˢ:��e��~_���ߗu��}YV{�~_֡�ߗe����e��ߗEt���:u��,�=��/���ר� ��JM|�jr|m�_�:9�Vj�kT{��k�&�F�9�Vj�kT{��k�����1��R_�ڃ_+5�5�=��R_�ڃ_u�פ�A��������Z�+�F��8�Vf�kD{��k�����1��R_�ڃ_+5�5�=��R_�ڃ_u�פ�A��������Z���Q�A��������ڨ;�&ur|���ר� ��JM|�jr|���ר� ��F��5�c��ke��k_�a|��_�Xs_+3�5�=��P��5�s��k�&�F�9�Vj�kT{��k�&�F�9�6ꎯI�_+5�5�=��R_�ڃ_+5�5�=��Qw|M���Z���Q�A��������Z���Q�A�� ���̞��Z�+�F��8�Vf�kD{��k�&�F�9�6ꎯI�_+5�5�=��R_�ڃ_+5�5�=��Qw|M���Z���Q�A��������Z���Q�A�����kR� ��JM|�jr|���ר� �� -]�5�5��!_�s_+3�5�=��R_�ڃ_+5�5�=��Qw|M���Z���Q�A��������Z���Q�A�����kR� ��JM|�jr|���ר� ��JM|�jr|-�s| ���Z���Q�A��������Z�+�F��8�6掯 �_+5�5�=��R_�ڃ_+5�5�=��Qw|M���Z���Q�A��������Z���Q�A�����kR� ��JM|�jr|���ר� ��JM|�jr|m�_�:9�Vj�kT{�k���͚��Z����A�����kR� ��JM|�jr|���ר� ��JM|�jr|m�_�:9�Vj�kT{��k�&�F�9�Vj�kT{��k�����1��R_�ڃ_+5�5�=��R_�ڃ_u�פ�A����k4k��ke&�F�9�Vj�kT{��k�����1��R_�ڃ_+5�5�=��R_�ڃ_�_�:9�Vj�kT{��k�&�F�9�Vj�kT{��k�����1��R_�ڃ_+5�5�=��R_�ڃ_4�5�=��"W|�d�q|���� ���)����{���_���0�>�#���_���p������w+��_�?���ӿ�����������U���x����g�u��\����������7]z�M�^��W>ܾ�E�PO������zu���J*���j�W����<h�W/�s]��^���Q�A�땚���^���Q�A�덺�zR� ��JM]�jr]������ �� -]u=�5�u�1w]O��^���Q�A�땚���^���Q�A�덺�zR� ��JM]�jr]������ ��JM]�jr]o�]ד:��Wj�zT{��z���G���Wj�zT{��z��1�u�RSףڃX�+t��h����L]�hr]o�]ד:��Wj�zT{��z���G���Wj�zT{��z��1�u�RSףڃ\�+5u=�=�u�RSףڃ\�u����A�땚���^���Q�A�땚���ި��'uR]��S]���1����zk��ze��G���깮ur]������ ��JM]�jr]������ ��F�u=�c��z���G���Wj�zT{��z���G���7��I�\�+5u=�=�u�RSףڃ\�+5u=�=�u�ASד�sX�+r��H����L]�hr]������ ��F�u=�c��z���G���Wj�zT{��z���G���7��I�\�+5u=�=�u�RSףڃ\�+5u=�=�u�Qw]O��^���Q�A�땚��ĺ^���G�氮7d�z"{��ze��G���Wj�zT{��z���G���7��I�\�+5u=�=�u�RSףڃ\�+5u=�=�u�Qw]O��^���Q�A�땚���^���Q�A��z��A��\�+5u=�=�u�RSףڃX�+t��h�����u=�c��z���G���Wj�zT{��z���G���7��I�\�+5u=�=�u�RSףڃ\�+5u=�=�u�Qw]O��^���Q�A�땚���^���Q�A�덺�zR� ��JM]�jb]��UףYs\�+3u=�=�u�Qw]O��^���Q�A�땚���^���Q�A�덺�zR� ��JM]�jr]������ ��JM]�jr]o�]ד:��Wj�zT{��z���G���Wj�zT{��z��1�u�BW]�f�q]������ ��JM]�jr]o�]ד:��Wj�zT{��z���G���Wj�zT{��z���zP� ��JM]�jr]������ ��JM]�jr]o�]ד:��Wj�zT{��z���G���Wj�zT{�z���'�簮W�둬9�땙����8Wu=~�S]��k@]�=�p�x��]/������ݷ~�������.�ׇ�s]���?���>��矾~��/��ǫ�D�̯r}��xT֟�?��;�{�-���_�?T{��?�&�C�9�Sj�?T{��?�����1��R��ڃ�)5��=��R��ڃ�u���A��������O�+�C��8�Sf�?D{��?�����1��R��ڃ�)5��=��R��ڃ�u���A��������O���P�A��������Ϩ;�#ur������ �JM��jr������ �F���c��?e��?_�a�����Xs�)3��=��P���s��?�&�C�9�Sj�?T{��?�&�C�9�3��H��)5��=��R��ڃ�)5��=��Qw�G���O���P�A��������O���P�A�����̞��O�+�C��8�Sf�?D{��?�&�C�9�3��H��)5��=��R��ڃ�)5��=��Qw�G���O���P�A��������O���P�A�����?R� �JM��jr������ � -]��5��!��s�)3��=��R��ڃ�)5��=��Qw�G���O���P�A��������O���P�A�����?R� �JM��jr������ �JM��jr�'�s����O���P�A��������O�+�C��8�3����)5��=��R��ڃ�)5��=��Qw�G���O���P�A��������O���P�A�����?R� �JM��jr������ �JM��jr�g���:9�Sj�?T{�?���͚��O����A�����?R� �JM��jr������ �JM��jr�g���:9�Sj�?T{��?�&�C�9�Sj�?T{��?�����1��R��ڃ�)5��=��R��ڃ�u���A����?4k��?e&�C�9�Sj�?T{��?�����1��R��ڃ�)5��=��R��ڃ� ���:9�Sj�?T{��?�&�C�9�Sj�?T{��?�����1��R��ڃ�)5��=��R��ڃ�4��=��"W��d�q������ ������{��_���1�����gx�����9��Y�ߟ>�����������O�|���O�o��������?>~���/���?������'EwW��g�Ϳ�O�������M�wg�mz�w��m��/o�P�A~�d�����1�o����M�� �mRj�6�ڃ��I�yۄj��&��M��A~ۤԼmB��m�R� ��MJ��&T{��6u�m"u��&��m�=�o����M�� �mR�zۄf���&C�m�=�o����M�� �mRj�6�ڃ��I�yۄj��&��M��A~ۤԼmB��m�R� ��MJ��&T{��6u�m"u��&��m�=�o����M�� �mRj�6�ڃ��I��M��A~ۤԼmB��m�R� �ķM -]o�Ь9~�d�����1�o����M�� �mRj�6�ڃ��I�yۄj��&��M��A~ۤԼmB��m�R� ��MJ��&T{��6u�m"u��&��m�=�o����M�� �mRj�6�ڃ��ɨ�m�c��6)5o�P�A|ۤ��� ͚�M���&D{��6u�m"u��&��m�=�o����M�� �mRj�6�ڃ��ɨ�m�c��6)5o�P�A~ۤԼmB��m�R� ��MF�o�H���I�yۄj��&��m�=�o����M�� �m2�~�D�ķM -]o�Ь9~̼ۤmB��m�R� ��MF�o�H���I�yۄj��&��m�=�o����M�� �m��m�s��6)5o�P�A~ۤԼmB��m�R� ��MF�o�H���I�yۄj��&��m�=�o����M�� �m2h�6��s��I��m�5�o����M�� �m��7�m~��ۦ_����m����������텷MO�����<}����M�C�L�6�_/����?����8��������K~�~�����_�����o�9}������՟�ӿ`���y�{�FOe���۫��ki�>{�������UO�������p�����=}��ڃo���7�o��>��<Po�>|����<P�n��+m��>{A������?P���|�黧?�;�注������^���^P{�@}�cx��z���ԧ?�k��>{A�����?���W��,�c�@�}�7�R=}��ڃ��ӿK����<P���_�o�`���������O8�,�c�@}�3�����<P����H���j�O -w�R=}��ڃ?��~%ƨ�ggH���3J��Πڃ��3J��Πڃ��3J��Πڃ��3F�?;C�䟝Qj~v�䟝Qj~v�䟝Qj~v�䟝1���R� ��R�3�� ��B��ΠYs��3���� ڃ��3F�?;C�䟝Qj~v�䟝Qj~v�䟝Qj~v�䟝1���R� ��R�3�� ��R�3�� ��R�3�� ��Q��ΐ:�gg����A��gg����A��gg����A��gg��v��1H?;����Π�rvF��ggP�9��e�gg�A����v�9�?;�����=�?;�����=�?;�����=�?;c���3��A����ggP�A����ggP�A����ggP�A���!u���(5?;�j���(5?;�j���(5?;�j���4?;Cf����(r���5�?;�̜f@��4�Rs����FݧH�|�A�9̀j�i��4�=ȧ����� �f0�>�@���J�iT{�O3(5�P�A>͠Ԝf@��4�Q�iR� �fPjN3�ڃ|�A�9̀j�i���h��f0dN3�s|�A�9̀h�i��4�=ȧ����� �f0�>�@���J�iT{�O3(5�P�A>͠Ԝf@��4�Q�iR� �fPjN3�ڃ|�A�9̀j�i��4�=ȧ�z>�����J�iT{�O3(5�P�A<͠�u�͚���ܧ�|�A�9̀j�i��4�=ȧ����� �f0�>�@���J�iT{�O3(5�P�A>͠Ԝf@��4�Q�iR� �fPjN3�ڃ|�A�9̀j�i��4�=ȧ��O3�:�4�Rs���� -]�Ь9>̜͠f@��4�Q�iR� �fPjN3�ڃ|�A�9̀j�i��4�=ȧ��O3�:�4�Rs����J�iT{�O3(5�P�A>�`�}���1ȧ����� �fPjN3�ڃ|�A�9̀j�i�����A<͠�u�͚����iD{�O3(5�P�A>�`�}���1ȧ����� �fPjN3�ڃ|�A�9̀j�i��O3�:�4�Rs����J�iT{�O3(5�P�A>�`�}���1ȧ����� �fPjN3�ڃ|�A�9̀j�i��4�=���N3 Ys|�A�9̀h�i�6 N3��8�fx�5���f8����������{��g��Y���[��ǫ�=��Z��GN�n�Y�����o�|��������|~�����_��ݻ�����w_N�:�*zyw���_9���뿠���Aϙ�ؙы�Ǚ��/��=���BWf�f�qf��dF�� gFFݙ�c�3#�&3B�93Rj2#T{�3#�&3B�932�ΌH��)5��=ș�R��ڃ�)5��=ș�QwfD���H�ɌP�AΌ������H�ɌP�AΌ��3#R� eF�<eF(���H�+3B��83Rf2#D{�3#��3#P� gFJMf�jrf��dF�� gFJMf�jrfdԝ�:93Rj2#T{�3#�&3B�93Rj2#T{�3#��̈�1ș�R��ڃ�)5��=ș�R��ڃ�4��=���"Wf�d�qf��dF�� gFJMf�jrfdԝ�:93Rj2#T{�3#�&3B�93Rj2#T{�3#��̈�1ș�R��ڃ�)5��=ș�R��ڃ�ugF��AΌ������H�ɌP�Ǎ�2#4k3#C&3"��83Rf2#D{�3#�&3B�93Rj2#T{�3#��̈�1ș�R��ڃ�)5��=ș�R��ڃ�ugF��AΌ������H�ɌP�AΌ������H����9ș�R��ڃ�)5��=���BWf�f�qfd̝:93Rj2#T{�3#�&3B�93Rj2#T{�3#��̈�1ș�R��ڃ�)5��=ș�R��ڃ�ugF��AΌ������H�ɌP�AΌ������Ȩ;3"urf��dF�� fF -]��5Ǚ�2�!ڃ�ugF��AΌ������H�ɌP�AΌ������Ȩ;3"urf��dF�� gFJMf�jrf��dF�� gFFݙ�c�3#�&3B�93Rj2#T{�3#�&3B�932�ΌH��)teFh�gF�Lf�hrf��dF�� gFFݙ�c�3#�&3B�93Rj2#T{�3#�&3B�93�93urf��dF�� gFJMf�jrf��dF�� gFFݙ�c�3#�&3B�93Rj2#T{�3#�&3B�132h2#2{3#E��ɚ��H�Ɍ�AΌ���~�Sf��k@ft�=��_�}w���_�]�Iht}�����}���O���!ɧ??�>�{\_�ݽ?�!��;���;�/����h��"�;��� ���R�;��� ���PϿ� ����Tj~G����Tj~G����Tj~G����4��MR� ���R�;��� ���R�;��� ���B��h�Ys�;��ܿ�I����Tj~G����Tj~G����Tj~G����4��MR� ���R�;��� ���R�;��� ���R�;��� ���Q��h�:�w4����D��w4����D��w4����D��w4��wR� �JM��jb����Ys�+3�;�=ȁ�Qw�N���]� �Q�Aܕ�����]� �Q�A܍�wR� �JM��jr���� �JM��jr�n���:9pWjwT{�w�&pG�9pWjwT{�w�����1H��2O�;�/�0pW� -�Q�9ܕ�����]����9ȁ�R��ڃ�+5�;�=ȁ�R��ڃ�uAܕ�����]� �Q�Aܕ�����ݨ;p'ur���� �JM��jr���� �M�Nf�a���#Ys�+3�;�=ȁ�R��ڃ�uAܕ�����]� �Q�Aܕ�����ݨ;p'ur���� �JM��jr���� �F݁;�c�w�&pG�9pWjwT{w���͚��ݐ ܉�9ܕ�����]� �Q�Aܕ�����ݨ;p'ur���� �JM��jr���� �F݁;�c�w�&pG�9pWjwT{�w�&pG�9p�9pur���� �JM��jb����Ys�sAܕ�����]� �Q�Aܕ�����ݨ;p'ur���� �JM��jr���� �F݁;�c�w�&pG�9pWjwT{�w�&pG�9p7��I��+5�;�=���BW��f�q���� �F݁;�c�w�&pG�9pWjwT{�w�&pG�9p7��I��+5�;�=ȁ�R��ڃ�+5�;�=ȁ�Qw�N���]� �Q�Aܕ�����]� �Q�A܍�wR� � -]�;�5ǁ�2�#ڃ�+5�;�=ȁ�Qw�N���]� �Q�Aܕ�����]� �Q�A܅z�A���+5�;�=ȁ�R��ڃ�+5�;�=ȁ�Qw�N���]� �Q�Aܕ�����]� �Q�A� ���̞��]�+pG��8pWfwD{���X[��=N���������� �υ�����3 �oV����~���_>����������?}����ם�ͷ|���u����W3�Yҷ͇^~����/r�Y�ڃ�Y:ue��� f�JMf����ҩ+�d�1�t��,Y�A�,��2KV{3K�&�Dubf�ԕY�ڃ�Y:ue��� f�N]�%�=���R�Y�:1�t��,Y�A�,z�,٬9�,��2KF{3K�&�Dubf�ԕY�ڃ�Y:ue��� f�N]�%�=���R�Y�:1�t��,Y�A�,��2KV{3K��̒���R��,Q��Y:ue��� f�N]�%�=���SWf�jbf��d���A�,��-�d��e�<e�,�f��\�%�=���QwfI���ҩ+�d�1�t��,Y�A�,��2KV{3K�&�Dubf�ԕY�ڃ�Y:ue��� f�N]�%�=���R�Y�:1�t��,Y�A�,��2KV{3K��̒���R�+�D��(�t�)�d��0�t��,�A�,��2KV{3K�&�Dubf�ԕY�ڃ�Y:ue��� f�N]�%�=���R�Y�:1�t��,Y�A�,��2KV{3K��̒���R��,Q��Y:ue��� f�N]�%�=H��CO�%�5G��"Wf�d�af�̕Y2ڃ�Y:ue��� f�N]�%�=���R�Y�:1�t��,Y�A�,��2KV{3K��̒���R��,Q��Y:ue��� f�N]�%�=���SWf�jbfiԝY�:1�t��,Y�A�,��2KV{�2K��2K6k3Ke&�Dtbf�ԕY�ڃ�Y:ue��� f�N]�%�=���R�Y�:1�t��,Y�A�,��2KV{3K��̒���R��,Q��Y:ue��� f�N]�%�=���SWf�jbf��d���A�,��2KV{�2K��2K6k3Kg�̒���R��,Q��Y:ue��� f�N]�%�=���SWf�jbf��d���A�,��2KV{3K��̒���ҩ+�d�1�Tj2KT� f�N]�%�=���SWf�jbf�ԕY�ڃ�Y*5�%�c�2K��2K6k3Kg�̒���ҩ+�d�1�Tj2KT� f�N]�%�=���SWf�jbf�ԕY�ڃ�Yug���A�,��2KV{3K��̒���ҩ+�d�1�Tj2KT� f�N]�%�=���SWf�jbf�ԕY�ڃ�Y*te�h�e��<e�L�f��\�%�=��%t�&�����3/����Qf ��o���u�����L2�ەY��O�N������/�Y?*�_~���ot>>����{��-?)�C��m>������_�NT{��N�&�D�9�Tj�NT{��N��1�q�Rw�ڃw*5q'�=�q�Rw�ڃwuǝ��A�;�����S��;Q�A�;�����Ө;�$urܩ�ĝ�� Ɲ -]q'�5�q�2w"ڃwuǝ��A�;�����S��;Q�A�;�����Ө;�$urܩ�ĝ�� ǝJM܉jrܩ�ĝ�� ǝF�q'�c��N�&�D�9�Tj�NT{��N�&�D�9�4�;I�w*�w��r�N��Ś�S��;�A�;�z�;A��w*5q'�=�q�Rw�ڃw*5q'�=�q�Qw�I��S��;Q�A�;�����S��;Q�A�;���NR� ǝJM܉jrܩ�ĝ�� ǝJM܉jb�i�ĝd�Ɲ�\q'�5�q�2w"ڃw*5q'�=�q�Qw�I��S��;Q�A�;�����S��;Q�A�;���NR� ǝJM܉jrܩ�ĝ�� ǝJM܉jr�i�w�:9�Tj�NT{��N�&�D�1�T�;Ѭ9�; ���Ȟ�S��;�A�;�����S��;Q�A�;���NR� ǝJM܉jrܩ�ĝ�� ǝJM܉jr�i�w�:9�Tj�NT{��N�&�D�9�Tj�NT{��N���NP� ǝJM܉jrܩ�ĝ�� Ɲ -]q'�5�q�1w�I��S��;Q�A�;�����S��;Q�A�;���NR� ǝJM܉jrܩ�ĝ�� ǝJM܉jr�i�w�:9�Tj�NT{��N�&�D�9�Tj�NT{��N��1�q�Rw�ڃw*tŝh�ǝ�L܉hr�i�w�:9�Tj�NT{��N�&�D�9�Tj�NT{��N��1�q�Rw�ڃw*5q'�=�q�Rw�ڃwuǝ��A�;�����S��;Q�A�;�����Ө;�$ubܩ�w�Ysw*3q'�=�q�Rw�ڃwuǝ��A�;�����S��;Q�A�;�����S���9�q�Rw�ڃw*5q'�=�q�Rw�ڃwuǝ��A�;�����S��;Q�A�;����ĸӠ�;��9�;��N$k��Ne&�D�9�<�U܉��w��w���74��������ĝwW�t��x������_���_���O�����VO�*����7;}��{�Gv�p{���o�_�7��g/�=x��_ݾ����<P�><�H���j��>^_�<�?F��ϲ:�۫�z���������rY���^P{�@}�cx���J=}��ڃo�����p��|�9x�>�1��K���j�Oo������<P����z����V����=8u}��1x��>���G��>{A������/[���j�W��/�^0k� �_7 ���$:�H�Rs$��# J͑T{��$(5GP�A>�`�}$��1�G��# �� IPj�$�ڃ|$A�9��j���# ��A>���I@��H�Rs$��# J͑T{��$uI u���H�=�G��$�Ys|$A�9��h���# ��A>���I@��H�Rs$��# J͑T{��$uI u���H�=�G��# �� IPj�$�ڃ|$���H�c��$(5GP�A>���I@��H�Rs$��# F�GH�t$A��# (��# -\GP�9>���I@��H�P�G@��|$A�9��j���H�=�G��# �� I0�>�@��# J͑T{��$(5GP�A>���I@��H�Q��R� IPj�$�ڃ|$A�9��j���H�=�G�# d�IP�:��d��e�H�=�G��# �� I0�>�@��# J͑T{��$(5GP�A>���I@��H�Q��R� IPj�$�ڃ|$A�9��j���H�=�G���$�:�H�Rs$��# J͑T{�$(tI@���H�!s$�Ȟ�# �̑D{��$(5GP�A>���I@��H�Q��R� IPj�$�ڃ|$A�9��j���H�=�G���$�:�H�Rs$��# J͑T{��$(5GP�A>� ��P� IPj�$�ڃ|$A�9��j���# h�I0�>�@��# J͑T{��$(5GP�A>���I@��H�Q��R� IPj�$�ڃ|$A�9��j���H�=�G���$�:�H�Rs$��# J͑T{��$(5GP�A>�`�}$��1�G��# �� IP�:��f��e�H�=�G���$�:�H�Rs$��# J͑T{��$(5GP�A>�`�}$��1�G��# �� IPj�$�ڃ|$A�9��j���# ��A>���I@��H�Rs$��# J͑T{��$uI u���# h�IPf�$ ڃ|$A�9��j���# ��A>���I@��H�Rs$��# J͑T{��$�|$�9�G��# �� IPj�$�ڃ|$A�9��j���# ��A>���I@��H�Rs$��# J͑T{�$4G��9<���u$ɚ�# �̑D{��$���H~�ӑ�_�$������=�K��|$a}&Gޯ# ������>~����������O�������pu������� �O����t�N��'���_pP� '�JM�jr��$�� '�JM�jrnԝ��:9WjpT{�p�&G�1W�J�Ѭ9N���pB� '�JM�jr��$�� '�JM�jrnԝ��:9WjpT{�p�&G�9WjpT{�p����1� �R���ڃ��+5 8�=� �R���ڃ��u'ऎAN�����\�+G��8WfpD{�p����1� �R���ڃ��+5 8�=� �R���ڃ��u'ऎAN�����\�I�Q�AN�����ܨ;'ur��$�� '�JM�jr��$�� '�F� 8�c�pe�p_�a�����Xs��+3 8�=� �P� 8�s�p�&G�9WjpT{�p�&G�97�N�I���+5 8�=� �R���ڃ��+5 8�=� �QwN��\�I�Q�AN�����\�I�Q�AL� ��̞�\�+G��8WfpD{�p�&G�97�N�I���+5 8�=� �R���ڃ��+5 8�=� �QwN��\�I�Q�AN�����\�I�Q�AN���pR� '�JM�jr��$�� &� -] 8�5� �!���s��+3 8�=� �R���ڃ��+5 8�=� �QwN��\�I�Q�AN�����\�I�Q�AN���pR� '�JM�jr��$�� '�JM�jr.�s��\�I�Q�AN�����\�+G��87�N� ���+5 8�=� �R���ڃ��+5 8�=� �QwN��\�I�Q�AN�����\�I�Q�AN���pR� '�JM�jr��$�� '�JM�jrnԝ��:9WjpT{p��͚�\�I��AN���pR� '�JM�jr��$�� '�JM�jrnԝ��:9WjpT{�p�&G�9WjpT{�p����1� �R���ڃ��+5 8�=� �R���ڃ��u'ऎAL��p4k�pe&G�9WjpT{�p����1� �R���ڃ��+5 8�=� �R���ڃ������:9WjpT{�p�&G�9WjpT{�p����1� �R���ڃ��+5 8�=� �R���ڃ��4 8�=� �"W�d�q��$��� '���J��{��_���a~�=�������ӿ��|}& ��J���?~��?���o��_�����?|����_�j���?�{�?����;�x�uw�����x���x�� �xJM��jr�g���:��Sjz<T{�{<���C���Sjz<T{�{<����1�=�R��ڃ��)t�xh��x�L��hr�g���:��Sjz<T{�{<���C���Sjz<T{�{<����1�=�R��ڃ��)5=�=�=�R��ڃ��u�x��A����O���P�A����Ϩ��#uR���S����1���z<k�{<e��C�����ur����x�� �xJM��jr����x�� �xF�=�c�{<���C���Sjz<T{�{<���C���3���H���)5=�=�=�R��ڃ��)5=�=�=�A���s��)r�xH��x�L��hr����x�� �xF�=�c�{<���C���Sjz<T{�{<���C���3���H���)5=�=�=�R��ڃ��)5=�=�=�Qw�G��O���P�A����O���C���3dz<"{�{<e��C���Sjz<T{�{<���C���3���H���)5=�=�=�R��ڃ��)5=�=�=�Qw�G��O���P�A����O���P�A��z��@����)5=�=�=�R��ڃ��)t�xh��x��=�c�{<���C���Sjz<T{�{<���C���3���H���)5=�=�=�R��ڃ��)5=�=�=�Qw�G��O���P�A����O���P�A��{<R� �xJM��jb�����Ys��)3=�=�=�Qw�G��O���P�A����O���P�A��{<R� �xJM��jr����x�� �xJM��jr�g���:��Sjz<T{�{<���C���Sjz<T{�{<����1�=�BW��f�q����x�� �xJM��jr�g���:��Sjz<T{�{<���C���Sjz<T{�{<��{<P� �xJM��jr����x�� �xJM��jr�g���:��Sjz<T{�{<���C���Sjz<T{{<���#���S���9�����'S=~�S���k@�w�=F�ws��{Rnn��[�I��a�x���??�����~����/�~:������Z���_������������֯?��}���O_O����O�������>��r�����:���77������w?�x����1��/�)P�A~La�����1ȏ)����� ?�PjS�ڃ��B��1�5��)��D�?�PfS ڃ��B�yL�j�c -��1�=ȏ)��S�:�1�R����J�c -T{�S(5�)P�A~La�����1ȏ)����� ?�PjS�ڃ��B�yL�j�c -��S�:�1�R����J�c -T{S(t=�@���1�1�c -B� ?�PjS�ڃ��B�yL�j�c -��1�=ȏ)��S�:�1�R����J�c -T{�S(5�)P�A~La�����1ȏ)����� ?�PjS�ڃ��B�yL�j�c -�����A~L��<�@��1�B�c -4k�S(3�)�A~La�����1ȏ)����� ?�PjS�ڃ��B�yL�j�c -�����A~L��<�@��1�R����J�c -T{�Su?� u�c -��1�=ȏ)����� ?�PjS�ڃ��¨�1�cS(t=�@���1�2����J�c -T{�Su?� u�c -��1�=ȏ)����� ?�PjS�ڃ��B�����A~L��<�@��1�R����J�c -T{�Su?� u�c -��1�=ȏ)����� ?�PjS�ڃ�� yLAf��c -E��H�?�PfS ڃ�����|����1ŋ�q�x����{|��nO����q�ֹ�vX���ч�7���L>rzJq�R��?�����M����������O�/�~�����ݧW�(�G~��ˏ�_����_?>�/�u������߽���O"�|8��~>/�A�7���"p�ă@�A 2{)rB��� �2s��@J�A T{�u"u�A �� �=�����@�� Rj�ڃ|Ȩ� �c�)5�P�A>�ԼaC�� �R� ��7lF�o�H���M�yÆj�6�� �=�o��ް�Ys��͐y�Fd��6e� �=�oؔ�7l�� �aSjް�ڃ��ͨ� �c�߰)5o�P�A~æԼaC�� �R� ��7lF�o�H���M�yÆj�6�� �=�oؔ�7l�� �a�� �s�߰)5o�P�A~æԼaC�� �B�64k�߰s�a#t�6�� �=�oؔ�7l�� �aSjް�ڃ��ͨ� �c�߰)5o�P�A~æԼaC�� �R� ��7lF�o�H���M�yÆj�6�� �=�oؔ�7l�� �a3�~�F��7lJ�6T{߰)t�aC��� �2� ��7lF�o�H���M�yÆj�6�� �=�oؔ�7l�� �a3�~�F��7lJ�6T{�߰)5o�P�A~æԼaC�� �Q�6R� �aSjް�ڃ��M�yÆj�6�� �=�o،�߰�:� �B�64k�߰)3o��A~æԼaC�� �Q�6R� �aSjް�ڃ��M�yÆj�6�� �=�oz~���7lJ�6T{�߰)5o�P�A~æԼaC�� �Q�6R� �aSjް�ڃ��M�yÆj�6�� �=�o��7ld��aS�zÆd��6e� �=�o؎_S�7l�=No�^| x�v�=��~�����_?�������� ������ۧ>��w7?������[�o�'����������������Y���i���b���_]�G}�����o��7C�3�������<�U��3�F]�eu��g�z�����3�J=}��ڃ���{��>{A���v_?so��YV����~�^���^P{�@=�нB�}�Ys���{e�>{���_u_?so��YV����~�^���^P{�@]?s���g/�=x����W���<�U��3�F]�eu��g�z�����3�J=}��ڃ���{��>{A���_u_?so��YV����~�^���^P{�@]?s���g/�=x����W���<�y��3�F]�eu��~�^�ϟ� �;�N?t��o� ���~�^���^@{��W����5�Eu��g�z�����3�J=}��ڃ���{��>{A���_u_?so��YV����~�^���^P{�@]?s���g/�=x����W���<�����u}��1x����W���<PWզ�dr�� grJM&�jb&g�drd�fr�\��5Ǚ�2��!ڃ��)5��=ș�Qw&G��LN���P�A�䔚L��LN���P�A�䌺39R� grJM&�jr&��dr�� grJM&�jr&gԝɑ:9�Sj29T{�39�&�C�1�S���Ь9���L�Ȟ�LN����A�䔚L��LN���P�A�䌺39R� grJM&�jr&��dr�� grJM&�jr&gԝɑ:9�Sj29T{�39�&�C�9�Sj29T{�39��39P� grJM&�jr&��dr�� fr -]��5Ǚ�1w&G��LN���P�A�䔚L��LN���P�A�䌺39R� grJM&�jr&��dr�� grJM&�jr&gԝɑ:9�Sj29T{�39�&�C�9�Sj29T{�39��L��1ș�R�ɡڃ��)terh�gr�L&�hr&gԝɑ:9�Sj29T{�39�&�C�9�Sj29T{�39��L��1ș�R�ɡڃ��)5��=ș�R�ɡڃ��ugr��A�䔚L��LN���P�A�䔚L��LΨ;�#ub&�ЕɡYs��)3��=ș�R�ɡڃ��ugr��A�䔚L��LN���P�A�䔚L��LN��L�9ș�R�ɡڃ��)5��=ș�R�ɡڃ��ugr��A�䔚L��LN���P�A�䔚L��LΠ����9���29$k�39e&�C�9�;.�T&���ɽ���fr����_��?���'����?���}���p��_\=\����߽��>�O���w�#������G_�<��{ -J�endstream +Vj�`T{��`��(��1�Q�R�ڃ+5Q0�=�Q�R�ڃuG���A����(��(X�+ +F��8 +Vf�`D{��`��(��1�Q�R�ڃ+5Q0�=�Q�R�ڃuG���A����(��(X���Q�A����(��(ب; +&ur��D��� G�JM�jr��D��� G�F�Q0�c�`��(͚�(X����A����(��(ب; +&ur��D��� G�JM�jr��D��� G�B=G���A����(��(X���Q�A����(��(ب; +&ur��D��� G�JM�jr��D��� F�MLf�a��#Ys+3Q0�=�Q0��" +��8E�/^�����W~{�����1���3�(�nE������~���2������b���{Qv�މ#��N_�������@�jr�hԝ8�:9qTjGT{�G�&qD�9qTjGT{�G��đ�1ȉ�R�8�ڃ�8*5�#�=ȉ�R�8�ڃ�8u'���AN������Q�+qD��8qTfGD{�G��đ�1ȉ�R�8�ڃ�8*5�#�=ȉ�R�8�ڃ�8u'���AN������Q�IQ�AN������Ѩ;q$ur��$��� '�JM�jr��$��� '�F݉#�c�Ge�G_�a���8�Xs�8*3�#�=ȉ�Pω#�s�G�&qD�9qTjGT{�G�&qD�9q4�NI��8*5�#�=ȉ�R�8�ڃ�8*5�#�=ȉ�Qw�H���Q�IQ�AN������Q�IQ�AL �đ̞��Q�+qD��8qTfGD{�G�&qD�9q4�NI��8*5�#�=ȉ�R�8�ڃ�8*5�#�=ȉ�Qw�H���Q�IQ�AN������Q�IQ�AN��GR� '�JM�jr��$��� &� +]�#�5���!�8�s�8*3�#�=ȉ�R�8�ڃ�8*5�#�=ȉ�Qw�H���Q�IQ�AN������Q�IQ�AN��GR� '�JM�jr��$��� '�JM�jr�(�s����Q�IQ�AN������Q�+qD��8q4�N ��8*5�#�=ȉ�R�8�ڃ�8*5�#�=ȉ�Qw�H���Q�IQ�AN������Q�IQ�AN��GR� '�JM�jr��$��� '�JM�jr�hԝ8�:9qTjGT{G���͚��Q�I�AN��GR� '�JM�jr��$��� '�JM�jr�hԝ8�:9qTjGT{�G�&qD�9qTjGT{�G��đ�1ȉ�R�8�ڃ�8*5�#�=ȉ�R�8�ڃ�8u'���AL�G4k�Ge&qD�9qTjGT{�G��đ�1ȉ�R�8�ڃ�8*5�#�=ȉ�R�8�ڃ�8 +��8�:9qTjGT{�G�&qD�9qTjGT{�G��đ�1ȉ�R�8�ڃ�8*5�#�=ȉ�R�8�ڃ�84�#�=���"W�d�q��$��� '���=�8�{���q���8^~���?<���]��������nOA����ۉ�z(�$qL���/�~��~���/����MO��w^��-�[���~z���o�����|}���͇��Ƌ�������������/��zz��ڃ��9X������ _֨�����A���R�}YT{��/��|_����*t}_͚���s_��1�ߗUj�/�j��e������Z���Q�A�����kR� ��JM|�jr|���ר� ��JM|�jr|m�_�:9�Vj�kT{��k�&�F�9�Vj�kT{��k�����1��R_�ڃ_+t��h����L|�hr|m�_�:9�Vj�kT{��k�&�F�9�Vj�kT{��k�����1��R_�ڃ_+5�5�=��R_�ڃ_u�פ�A��������Z���Q�A��������ڨ;�&uR|��S|���1����kk��ke&�F�9��9�ur|���ר� ��JM|�jr|���ר� ��F��5�c��k�&�F�9�Vj�kT{��k�&�F�9�6ꎯI�_+5�5�=��R_�ڃ_+5�5�=��A_��s_+r��H����L|�hr|���ר� ��F��5�c��k�&�F�9�Vj�kT{��k�&�F�9�6ꎯI�_+5�5�=��R_�ڃ_+5�5�=��Qw|M���Z���Q�A��������Z�+�F��0�6d�k"{��ke&�F�9�Vj�kT{��k�&�F�9�6ꎯI�_+5�5�=��R_�ڃ_+5�5�=��Qw|M���Z���Q�A��������Z���Q�A���z��A��_+5�5�=��R_�ڃ_+t��h������5�c��k�&�F�9�Vj�kT{��k�&�F�9�6ꎯI�_+5�5�=��R_�ڃ_+5�5�=��Qw|M���Z���Q�A��������Z���Q�A�����kR� ��JM|�jb|��_�Ys_+3�5�=��Qw|M���Z���Q�A��������Z���Q�A�����kR� ��JM|�jr|���ר� ��JM|�jr|m�_�:9�Vj�kT{��k�&�F�9�Vj�kT{��k�����1��BW|�f�q|���� ��JM|�jr|m�_�:9�Vj�kT{��k�&�F�9�Vj�kT{��k���kP� ��JM|�jr|���ר� ��JM|�jr|m�_�:9�Vj�kT{��k�&�F�9�Vj�kT{�k�&�&��0�V䊯��9���������rJ��k|�S|��5w����1��Õ������s|��I|}�������>���o�����xx�ç��2�ǧ��?�����s���/���93���롗oz�:������yC=={E�������T���+j^Po>�/�ӳW���~�^���9�u�RSףڃ\�+5u=�=�u�RSףڃ\�u����A�땚���^���Q�A����z4k��zc�1�u�RSףڃ\�+5u=�=�u�RSףڃ\�u����A�땚���^���Q�A�땚���ި��'ur]������ ��JM]�jr]������ ��F�u=�c��z���G���W��Ѭ9�땙���ި��'ur]������ ��JM]�jr]������ ��F�u=�c��z���G���Wj�zT{��z���G���7��I�\�+5u=�=�u�RSףڃ\�+5u=�=�u�Qw]O���^���ŗcX�+p��(����L]�hr]/�s]��^���Q�A�땚���^���Q�A�덺�zR� ��JM]�jr]������ ��JM]�jr]o�]ד:��Wj�zT{��z���G���Wj�zT{�z���'�簮W�둬9�땙���^���Q�A�덺�zR� ��JM]�jr]������ ��JM]�jr]o�]ד:��Wj�zT{��z���G���Wj�zT{��z��1�u�RSףڃ\�+5u=�=�u�BW]�f�a]o���D����L]�hr]������ ��JM]�jr]o�]ד:��Wj�zT{��z���G���Wj�zT{��z��1�u�RSףڃ\�+5u=�=�u�RSףڃ\��\׃:��Wj�zT{��z���G���W��Ѭ9�덹�zB� ��JM]�jr]������ ��JM]�jr]o�]ד:��Wj�zT{��z���G���Wj�zT{��z��1�u�RSףڃ\�+5u=�=�u�RSףڃ\�u����A�땚��ĺ^���G�渮Wf�zD{��z��1�u�RSףڃ\�+5u=�=�u�RSףڃ\�u����A�땚���^���Q�A�땚���ި��'ur]������ ��JM]�jr]������ ��F�u=�c�z���͚�^����A�땚���ި��'ur]������ ��JM]�jr]������ ��B=����A�땚���^���Q�A�땚���ި��'ur]������ ��JM]�jr]������ ��M]Of�a]��U�#Ys\�+3u=�=�u��D\�������k@]�=�������W�����������?���͢z=�g�u�a��������_�x�������ϧ���?��Oou��j��7;�<>�_����$�w$��/G�_" R� GJM$�jr$��D�� GJM$�jr$a�I�:9�Pj" T{�# �&�@�9�Pj" T{�# ��H��1H��2O��/�0�P��$P�9�$��H��HB��H�9ȑ�RI�ڃI(5��=ȑ�RI�ڃIuG��A�$��H��HB��$P�A�$��H��H¨;� ur$��D�� GJM$�jr$��D�� FM$Af�a$��I YsI(3��=ȑ�RI�ڃIuG��A�$��H��HB��$P�A�$��H��H¨;� ur$��D�� GJM$�jr$��D�� GFݑ�c�# �&�@�9�Pj" T{# ��H͚�H�$��9�$��H��HB��$P�A�$��H��H¨;� ur$��D�� GJM$�jr$��D�� GFݑ�c�# �&�@�9�Pj" T{�# �&�@�9��9��ur$��D�� GJM$�jb$��I�YsIsG��A�$��H��HB��$P�A�$��H��H¨;� ur$��D�� GJM$�jr$��D�� GFݑ�c�# �&�@�9�Pj" T{�# �&�@�9�0�$H�I(5��=���BW$�f�q$��D�� GFݑ�c�# �&�@�9�Pj" T{�# �&�@�9�0�$H�I(5��=ȑ�RI�ڃI(5��=ȑ�Qw$A��HB��$P�A�$��H��HB��$P�A�$��# R� F +]��5Ǒ�2I ڃI(5��=ȑ�Qw$A��HB��$P�A�$��H��HB��$P�A�$�z�$@��I(5��=ȑ�RI�ڃI(5��=ȑ�Qw$A��HB��$P�A�$��H��HB��$P�A�$�H�̞�HB�+�@��8�Pf" D{�#����U$��q�$^�D��cD�W"�����/h8�XϜ#��I���O_����v�������/��o�ۏ�~����}�����ϟ����>���H����ݙz�������o����6���>���w��٦�/g�P�A>�d�}���1�g����M�� �mRj�6�ڃ|�I�9ۄj��&��M��A>ۤԜmB��l�Rs� ��MJ��&T{��6u�m"u��&��l�=�g����M�� �mR�:ۄf���&C�l�=�g����M�� �mRj�6�ڃ|�I�9ۄj��&��M��A>ۤԜmB��l�Rs� ��MJ��&T{��6u�m"u��&��l�=�g����M�� �mRj�6�ڃ|�I��M��A>ۤԜmB��l�Rs� �ijM +]g�Ь9>�d�}���1�g����M�� �mRj�6�ڃ|�I�9ۄj��&��M��A>ۤԜmB��l�Rs� ��MJ��&T{��6u�m"u��&��l�=�g����M�� �mRj�6�ڃ|�ɨ�l�c��6)5g�P�A<ۤ�u� ͚�M���&D{��6u�m"u��&��l�=�g����M�� �mRj�6�ڃ|�ɨ�l�c��6)5g�P�A>ۤԜmB��l�Rs� ��MF�g�H�|�I�9ۄj��&��l�=�g����M�� �m2�>�D�ijM +]g�Ь9>̜ۤmB��l�Rs� ��MF�g�H�|�I�9ۄj��&��l�=�g����M�� �m��l�s��6)5g�P�A>ۤԜmB��l�Rs� ��MF�g�H�|�I�9ۄj��&��l�=�g����M�� �m2h�6��sx�I��l�5�g����M�� �m��7�l���lӋ�8��x���{������������������������g��Cy&g����_�K><��>�-�y��/�ûK�X�����9��z�廽����������x��e��.�w7���4O�^A{���ps�Ϊ�g��=xA}���d}O�^Q{�m��ps��F]ϲ:/�w7>X����/�7���J[��g��=xA=�����RO�^Q{���H��Nͳ������p� �ӳW�����`@��g��=xA=�V=={E�������p���R׳������oҟ�zz��ڃԇ�ߥ[����/��7����W̚{��=�>�?��YF����3x����+j^P�?���R=={E����p'�ӳW�|[�;��eu^P�?��{���������c8�?�g��=xA=��Y�����V�7���ֳ�������G�'����/�7�>X����/��7���׳W�|[}�1���Yϲ:/��ýUO�^Q{��z�1�?H��b�������ӳW�|[}8�n���eu^P�?�����z��ڃ��O�UO�^Q{������|v����uv��1ȟ�Qj>;�j�gg���Πڃ����3�� vƨ��3��A��R��T{�?;��|v����(5��A���3Fݟ�!u�gg�y���/��3 +\��A����3��gg�A��Pϟ�u�gg���Πڃ����3�� vF����=ȟ�1����c�?;��|v����(5��A���3J�ggP�A��Q�ggH�����3�� vF����=ȟ�Qj>;�j�gg��ΐ�s��E��� Ys��e�jD{��fPj�f@��j��H�|5�Rs5�=�W3(5W3�ڃ|5�Rs5�=�W3u_�@�����P�A��A��������P�A�����jR� _͠�\̀j��J���� ^͠�u5�5�W32W3�s|5�2s5�=�W3(5W3�ڃ|5�Rs5�=�W3u_�@�����P�A��A��������P�A�����jR� _͠�\̀j��J���� _͠�\̀j��B=_�������P�A��A����ī��f@���jc��|5�Rs5�=�W3(5W3�ڃ|5�Rs5�=�W3u_�@�����P�A��A��������P�A�����jR� _͠�\̀j��J���� _͠�\̀j��F�W3�:�j��jT{�fP躚͚�����A�����jR� _͠�\̀j��J���� _͠�\̀j��F�W3�:�j��jT{��fPj�f@��j��jT{��f0꾚��1�W3(5W3�ڃ|5�Rs5�=�W3(5W3�ڃ|5�Q����A��A��j4k��fPf�f@��j��jT{��f0꾚��1�W3(5W3�ڃ|5�Rs5�=�W3(5W3�ڃ|5�P�W3�:�j��jT{��fPj�f@��j��jT{��f0꾚��1�W3(5W3�ڃ|5�Rs5�=�W3(5W3�ڃx5�As5�=�W3(r]̀d�������� _�@� ���=NW3�x���ū.���>p��OL�3�?�<ܯ�����7_h=�GN3ܭk�럟�%����o��_�������߾��w�n�ˏ����:�*zyw�x��z��A���;3�߁<����bf�Ƌ\ΌX�Aʌzʌج9̌��2#F{3#�&3Bubf�ԕ�ڃ�9ueF�� fFN]��=���R��:13r�ʌX�Ǎ��2#V{3#��̈���H�ɌP��9ueF�� fFN]��=���SWf�jbf��dF��AȌ��=3b��eF<eF,�fF�\��=���QwfD���ȩ+3b�13r�ʌX�Ǎ��2#V{3#�&3Bubf�ԕ�ڃ�9ueF�� fFN]��=���R��:13r�ʌX�Ǎ��2#V{3#��̈���H�+3B��(3r�)3b��03r�ʌ�Ǎ��2#V{3#�&3Bubf�ԕ�ڃ�9ueF�� fFN]��=���R��:13r�ʌX�Ǎ��2#V{3#��̈���H�ɌP��9ueF�� fFN]��=H��CO��5G��"Wf�d�af�̕1ڃ�9ueF�� fFN]��=���R��:13r�ʌX�Ǎ��2#V{3#��̈���H�ɌP��9ueF�� fFN]��=���SWf�jbfdԝ�:13r�ʌX�Ǎ��2#V{�2#��2#6k3#e&3Btbf�ԕ�ڃ�9ueF�� fFN]��=���R��:13r�ʌX�Ǎ��2#V{3#��̈���H�ɌP��9ueF�� fFN]��=���SWf�jbf��dF��Ǎ��2#V{�2#��2#6k3#g�̈���H�ɌP��9ueF�� fFN]��=���SWf�jbf��dF��Ǎ��2#V{3#��̈���ȩ+3b�13Rj2#T� fFN]��=���SWf�jbf�ԕ�ڃ�)5��c�2#��2#6k3#g�̈���ȩ+3b�13Rj2#T� fFN]��=���SWf�jbf�ԕ�ڃ�ugF��Ǎ��2#V{3#��̈���ȩ+3b�13Rj2#T� fFN]��=���SWf�jbf�ԕ�ڃ�)teFh�eF�<eFL�fF�\��=��V1�3#~��ϼ|�ÇK���_����/�n��y&���������~��/��������C�gb����������;���롗�x�;�o����h�ڃ�M���h�ڃ�M���h�:�;�N]��d��;�N]��d��;�N]��d��;�J�w4Q��M���h�ڃ�M���h�ڃ�M�����f��w4���h":�;�N]��d��;�N]��d��;�N]��d��;�J�w4Q��M���h�ڃ�M���h�ڃ�M���h�ڃ�M��;���A���S�w4Y�A���S�w4Y�A���S�w4Y�A���Rw�N���]� �Q�A��w4k�we&pG�9p7��I��+5�;�=ȁ�R��ڃ�+5�;�=ȁ�Qw�N���]� �Q�Aܕ�����]� �Q�A܍�wR� �JM��jr���� �JM��jr�n���:)pW�)pG��� +\�;�5ǁ�2�#ڃ����:9pWjwT{�w�&pG�9pWjwT{�w�����1ȁ�R��ڃ�+5�;�=ȁ�R��ڃ�uAܕ�����]� �Q�Aܕ�����ݠ ���9��w$k�we&pG�9pWjwT{�w�����1ȁ�R��ڃ�+5�;�=ȁ�R��ڃ�uAܕ�����]� �Q�Aܕ�����ݨ;p'ur���� �JM��jb����Ys�2�;�=ǁ�2�#ڃ�+5�;�=ȁ�R��ڃ�uAܕ�����]� �Q�Aܕ�����ݨ;p'ur���� �JM��jr���� �B=��Aܕ�����]� �Q�A��w4k�wc����1ȁ�R��ڃ�+5�;�=ȁ�R��ڃ�uAܕ�����]� �Q�Aܕ�����ݨ;p'ur���� �JM��jr���� �F݁;�c�w�&pG�1pW� +�Ѭ9ܕ�����ݨ;p'ur���� �JM��jr���� �F݁;�c�w�&pG�9pWjwT{�w�&pG�9p7��I��+5�;�=ȁ�R��ڃ�+5�;�=ȁ�Qw�N���]�+pG��8pWfwD{�w�&pG�9p7��I��+5�;�=ȁ�R��ڃ�+5�;�=ȁ�Pρ;�s�w�&pG�9pWjwT{�w�&pG�9p7��I��+5�;�=ȁ�R��ڃ�+5�;�=���A���s�+r�H���L��hr�~9�V�;��)p��_~���^ �������z&��� +���ӟ?}��O_~������\_�����o���oO��Y{ݺ�{�p髙;���ݙ勷��Y�~�,Q�A�,������Ҩ;�$urf��d��� g�JMf�jrf��d��� g�Fݙ%�c�3K�&�D�9�Tj2KT{�3K�&�D�9�4��,I��Y*5�%�=���BWf�f�qf��d��� g�Fݙ%�c�3K�&�D�9�Tj2KT{�3K�&�D�9�4��,I��Y*5�%�=ș�R�Y�ڃ�Y*5�%�=ș�QwfI���R��,Q�A�,������R��,Q�A�,��3KR� e��<e�(���R�+�D��8�Tf2KD{�3K��3KP� g�JMf�jrf��d��� g�JMf�jrfiԝY�:9�Tj2KT{�3K�&�D�9�Tj2KT{�3K��̒�1ș�R�Y�ڃ�Y*5�%�=ș�R�Y�ڃ�Y4�%�=���"Wf�d�qf��d��� g�JMf�jrfiԝY�:9�Tj2KT{�3K�&�D�9�Tj2KT{�3K��̒�1ș�R�Y�ڃ�Y*5�%�=ș�R�Y�ڃ�Yug���A�,������R��,Q�A�,�2K4k3KC&�$��8�Tf2KD{�3K�&�D�9�Tj2KT{�3K��̒�1ș�R�Y�ڃ�Y*5�%�=ș�R�Y�ڃ�Yug���A�,������R��,Q�A�,������R����9ș�R�Y�ڃ�Y*5�%�=���BWf�f�qfi̝Y:9�Tj2KT{�3K�&�D�9�Tj2KT{�3K��̒�1ș�R�Y�ڃ�Y*5�%�=ș�R�Y�ڃ�Yug���A�,������R��,Q�A�,������Ҩ;�$urf��d��� f� +]�%�5Ǚ�2�Y"ڃ�Yug���A�,������R��,Q�A�,������Ҩ;�$urf��d��� g�JMf�jrf��d��� g�Fݙ%�c�3K�&�D�9�Tj2KT{�3K�&�D�9�4��,I��Y*te�h�g��Lf�hrf��d��� g�Fݙ%�c�3K�&�D�9�Tj2KT{�3K�&�D�9��9�urf��d��� g�JMf�jrf��d��� g�Fݙ%�c�3K�&�D�9�Tj2KT{�3K�&�D�1�4h2K2{3KE��ɚ��R��,�A�,/w�*���8e�/^2����W~G����/Q�sf��Ify�2�����?��_>��e}T������7:��x��5�>C�vC���^��������S��;Q�A�;�����Ө;�$urܩ�ĝ�� ǝJM܉jrܩ�ĝ�� ǝF�q'�c��N�&�D�9�Tj�NT{��N�&�D�9�4�;I�w*5q'�=�q�BW܉f�qܩ�ĝ�� ǝF�q'�c��N�&�D�9�Tj�NT{��N�&�D�9�4�;I�w*5q'�=�q�Rw�ڃw*5q'�=�q�Qw�I��S��;Q�A�;�����S��;Q�A�;���NR� ŝ�<ŝ(�øS�+�D��8�Tf�ND{��N���NP� ǝJM܉jrܩ�ĝ�� ǝJM܉jr�i�w�:9�Tj�NT{��N�&�D�9�Tj�NT{��N��1�q�Rw�ڃw*5q'�=�q�Rw�ڃw4q'�=�q�"W܉d�qܩ�ĝ�� ǝJM܉jr�i�w�:9�Tj�NT{��N�&�D�9�Tj�NT{��N��1�q�Rw�ڃw*5q'�=�q�Rw�ڃwuǝ��A�;�����S��;Q�A�;��N4k�NC&�$��8�Tf�ND{��N�&�D�9�Tj�NT{��N��1�q�Rw�ڃw*5q'�=�q�Rw�ڃwuǝ��A�;�����S��;Q�A�;�����S���9�q�Rw�ڃw*5q'�=�q�BW܉f�q�i�w:9�Tj�NT{��N�&�D�9�Tj�NT{��N��1�q�Rw�ڃw*5q'�=�q�Rw�ڃwuǝ��A�;�����S��;Q�A�;�����Ө;�$urܩ�ĝ�� Ɲ +]q'�5�q�2w"ڃwuǝ��A�;�����S��;Q�A�;�����Ө;�$urܩ�ĝ�� ǝJM܉jrܩ�ĝ�� ǝF�q'�c��N�&�D�9�Tj�NT{��N�&�D�9�4�;I�w*tŝh�ǝ�L܉hrܩ�ĝ�� ǝF�q'�c��N�&�D�9�Tj�NT{��N�&�D�9��9�urܩ�ĝ�� ǝJM܉jrܩ�ĝ�� ǝF�q'�c��N�&�D�9�Tj�NT{��N�&�D�1�4h�N2{�NE��ɚ�S��;�A�;/*���8ŝ/^��x1��e�y��p��;�3�;�o���x��ts��W����%���o(���:�U��ݵ7;=���^���w7�����5�0O�^A{���ps�Ϊ�g��=xA}���t+�ӳW�|[}:��>�F��gY�Ի�i�ӳW���>��>��e���������cx�[t��������'���Nͳ������p� �ӳW���o��� ����/������g��=��z8��=:u=������v�I��g��=xA}8���UO�^Q{���x�`��?zŬ� �������B� _���\��j�% J�% �� _���\��j�% Fݗ$�:����T{�/IPj.I@�����T{�/I0�$��1ȗ$(5�$�ڃ|I�RsI�=ȗ$(5�$�ڃ|I�Q�% ��A�$A��$��K�.I@����e�D{�/I0�$��1ȗ$(5�$�ڃ|I�RsI�=ȗ$(5�$�ڃ|I�Q�% ��A�$A��$��K��KP�A�$A��$��K��/I u�% J�% �� _���\��j�% J�% �� _�`�}I�c�.IP��_��% +\�$�Xs|I�2sI�=ȗ$�|I�s�/IPj.I@�����T{�/IPj.I@�����KH�|I�RsI�=ȗ$(5�$�ڃ|I�RsI�=ȗ$u_�@��K��KP�A�$A��$��K��KP�A�$���$�̞�K�.I@����e�D{�/IPj.I@�����KH�|I�RsI�=ȗ$(5�$�ڃ|I�RsI�=ȗ$u_�@��K��KP�A�$A��$��K��KP�A�$����R� _���\��j�% J�% �� ^���uI�5��$2�$�s|I�2sI�=ȗ$(5�$�ڃ|I�RsI�=ȗ$u_�@��K��KP�A�$A��$��K��KP�A�$����R� _���\��j�% J�% �� _���\��j�% B=_����K��KP�A�$A��$��K�.I@����c�K�|I�RsI�=ȗ$(5�$�ڃ|I�RsI�=ȗ$u_�@��K��KP�A�$A��$��K��KP�A�$����R� _���\��j�% J�% �� _���\��j�% Fݗ$�:����T{/IP�$͚�K��K�A�$����R� _���\��j�% J�% �� _���\��j�% Fݗ$�:����T{�/IPj.I@�����T{�/I0�$��1ȗ$(5�$�ڃ|I�RsI�=ȗ$(5�$�ڃ|I�Q�% ��A�$A��4k�/IPf.I@�����T{�/I0�$��1ȗ$(5�$�ڃ|I�RsI�=ȗ$(5�$�ڃ|I�Pϗ$�:����T{�/IPj.I@�����T{�/I0�$��1ȗ$(5�$�ڃ|I�RsI�=ȗ$(5�$�ڃxI�AsI�=��$(r]��d��% ��% �� _�p9�W�$�{�.Ix�pI����$�^�$�>���% �\��~]��O?�����O��~�����ϟ~�}������u�����������cp�ꄝ��'���/ 8�s�p�&G�9WjpT{�p�&G�97�N�I���+5 8�=� �R���ڃ��+t%�h�'��� 8�c�p�&G�9WjpT{�p�&G�97�N�I���+5 8�=� �R���ڃ��+5 8�=� �QwN��\�I�Q�AN�����\�I�Q�AN���pR� '�JM�jb�Е��Ys��+3 8�=� �QwN��\�I�Q�AN�����\�I�Q�AN���pR� '�JM�jr��$�� '�JM�jrnԝ��:9WjpT{�p�&G�9WjpT{�p����1H �2O 8�/�0W�J�Q�9N�����\���9� �R���ڃ��+5 8�=� �R���ڃ��u'ऎAN�����\�I�Q�AN�����ܨ;'ur��$�� '�JM�jr��$�� &�MNf�a�ȕ�#Ys��+3 8�=� �R���ڃ��u'ऎAN�����\�I�Q�AN�����ܨ;'ur��$�� '�JM�jr��$�� '�F� 8�c�p�&G�9WjpT{p��͚�ܐI���9N�����\�I�Q�AN�����ܨ;'ur��$�� '�JM�jr��$�� '�F� 8�c�p�&G�9WjpT{�p�&G�9�9ur��$�� '�JM�jb�Е��Ys��s'���AN�����\�I�Q�AN�����ܨ;'ur��$�� '�JM�jr��$�� '�F� 8�c�p�&G�9WjpT{�p�&G�97�N�I���+5 8�=� �BW�f�q��$��� '�F� 8�c�p�&G�9WjpT{�p�&G�97�N�I���+5 8�=� �R���ڃ��+5 8�=� �QwN��\�I�Q�AN�����\�I�Q�AN���pR� &� +] 8�5� �2��#ڃ��+5 8�=� �QwN��\�I�Q�AN�����\�I�Q�AN��zN�A����+5 8�=� �R���ڃ��+5 8�=� �QwN��\�I�Q�AN�����\�I�Q�AL� ��̞�\�+G��8WfpD{����J��=N ��׀��{��p%>���� �z& ��J����������[�˷_>}������>�������X��������¯߹ǃ��=ދ��~��P�A����Ϩ��#ur����x�� �xJM��jr����x�� �xF�=�c�{<���C���S���Ь9����Ϩ��#ur����x�� �xJM��jr����x�� �xF�=�c�{<���C���Sjz<T{�{<���C���3���H���)5=�=�=�R��ڃ��)5=�=�=�Qw�G��O��ŗc��)p�x(��x�L��hr�'�s���O���P�A����O���P�A��{<R� �xJM��jr����x�� �xJM��jr�g���:��Sjz<T{�{<���C���Sjz<T{{<���#���S���9����O���P�A��{<R� �xJM��jr����x�� �xJM��jr�g���:��Sjz<T{�{<���C���Sjz<T{�{<����1�=�R��ڃ��)5=�=�=�BW��f�a�g��xD��x�L��hr����x�� �xJM��jr�g���:��Sjz<T{�{<���C���Sjz<T{�{<����1�=�R��ڃ��)5=�=�=�R��ڃ�� ���:��Sjz<T{�{<���C���S���Ь9��{<B� �xJM��jr����x�� �xJM��jr�g���:��Sjz<T{�{<���C���Sjz<T{�{<����1�=�R��ڃ��)5=�=�=�R��ڃ��u�x��A����O���C���Sfz<D{�{<����1�=�R��ڃ��)5=�=�=�R��ڃ��u�x��A����O���P�A����Ϩ��#ur����x�� �xJM��jr����x�� �xF�=�c{<��͚�O����A����Ϩ��#ur����x�� �xJM��jr����x�� �xB=�x��A����O���P�A����Ϩ��#ur����x�� �xJM��jr����x�� �xM�Gf�a�����!Ys��)3=�=�=��L�x����k�.�x����$��?�?<q���I��a�x����|�����~���뗏�>�~��|�\�o_������~��������[�������_������O���o��ϟ�:9q��/�����p{{��8����}��������_S�ڃ|�¨�0�c�S(5�)P�A>L���@��0�B�a +4kS2�)��9>L���@��0�Rs����J�a +T{�Su� u�a +��0�=ȇ)����� �PjS�ڃ|�¨�0�c�S(5�)P�A>L���@��0�Rs����B=��u�a +��0�=ȇ)����� �P�:L�f��a +c����A>L���@��0�Rs����J�a +T{�Su� u�a +��0�=ȇ)����� �PjS�ڃ|�¨�0�c�S(5�)P�A>L���@��0�Rs����F݇)H�|�B�9L�j�a +���h��PfS ڃ|�¨�0�c�S(5�)P�A>L���@��0�Rs����F݇)H�|�B�9L�j�a +��0�=ȇ)����� �0�>LA���J�a +T{�S(5�)P�A>L���@��0�Q�a +R� �P�:L�f��a +e�0�=ȇ)����� �0�>LA���J�a +T{�S(5�)P�A>L���@��0�Pχ)@��|�B�9L�j�a +��0�=ȇ)����� �0�>LA���J�a +T{�S(5�)P�A>L���@��0�As��̞���\�)��9>L���@��0��|q���t���ɅwS\~��_�?������?�!���7��U�����~��߽�x�������y~�ϟ?_z��P��nScendstream endobj -1182 0 obj << +1210 0 obj << /Type /Page -/Contents 1183 0 R -/Resources 1181 0 R +/Contents 1211 0 R +/Resources 1209 0 R /MediaBox [0 0 609.714 789.041] -/Parent 1174 0 R -/Annots [ 1185 0 R 1188 0 R 1189 0 R 1190 0 R 1191 0 R 1192 0 R 1193 0 R 1194 0 R 1195 0 R 1196 0 R 1197 0 R 1198 0 R 1199 0 R 1200 0 R 1201 0 R 1202 0 R 1203 0 R 1204 0 R 1205 0 R 1206 0 R 1207 0 R 1208 0 R 1209 0 R 1210 0 R 1211 0 R 1212 0 R 1213 0 R 1214 0 R 1215 0 R 1216 0 R 1217 0 R 1218 0 R 1219 0 R 1220 0 R 1221 0 R 1222 0 R 1223 0 R 1224 0 R 1225 0 R 1226 0 R 1227 0 R 1228 0 R 1229 0 R 1230 0 R 1231 0 R 1232 0 R 1233 0 R 1234 0 R 1235 0 R 1236 0 R 1237 0 R 1238 0 R 1239 0 R 1240 0 R 1241 0 R 1242 0 R 1243 0 R 1244 0 R 1245 0 R 1246 0 R 1247 0 R 1248 0 R 1249 0 R 1250 0 R 1251 0 R 1252 0 R 1253 0 R 1254 0 R 1255 0 R 1256 0 R 1257 0 R 1258 0 R 1259 0 R 1260 0 R 1261 0 R 1262 0 R 1263 0 R 1264 0 R 1265 0 R 1266 0 R 1267 0 R 1268 0 R 1269 0 R 1270 0 R 1271 0 R 1272 0 R 1273 0 R 1274 0 R 1275 0 R 1276 0 R ] +/Parent 1202 0 R +/Annots [ 1213 0 R 1216 0 R 1217 0 R 1218 0 R 1219 0 R 1220 0 R 1221 0 R 1222 0 R 1223 0 R 1224 0 R 1225 0 R 1226 0 R 1227 0 R 1228 0 R 1229 0 R 1230 0 R 1231 0 R 1232 0 R 1233 0 R 1234 0 R 1235 0 R 1236 0 R 1237 0 R 1238 0 R 1239 0 R 1240 0 R 1241 0 R 1242 0 R 1243 0 R 1244 0 R 1245 0 R 1246 0 R 1247 0 R 1248 0 R 1249 0 R 1250 0 R 1251 0 R 1252 0 R 1253 0 R 1254 0 R 1255 0 R 1256 0 R 1257 0 R 1258 0 R 1259 0 R 1260 0 R 1261 0 R 1262 0 R 1263 0 R 1264 0 R 1265 0 R 1266 0 R 1267 0 R 1268 0 R 1269 0 R 1270 0 R 1271 0 R 1272 0 R 1273 0 R 1274 0 R 1275 0 R 1276 0 R 1277 0 R 1278 0 R 1279 0 R 1280 0 R 1281 0 R 1282 0 R 1283 0 R 1284 0 R 1285 0 R 1286 0 R 1287 0 R 1288 0 R 1289 0 R 1290 0 R 1291 0 R 1292 0 R 1293 0 R 1294 0 R 1295 0 R 1296 0 R 1297 0 R 1298 0 R 1299 0 R 1300 0 R 1301 0 R 1302 0 R 1303 0 R 1304 0 R ] >> endobj -1185 0 obj << +1213 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [71.731 679.836 158.096 686.82] /Subtype /Link /A << /S /GoTo /D (about) >> >> endobj -1188 0 obj << +1216 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 679.836 537.983 686.82] /Subtype /Link /A << /S /GoTo /D (about) >> >> endobj -1189 0 obj << +1217 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [95.641 662.456 203.466 671.367] /Subtype /Link /A << /S /GoTo /D (copyright) >> >> endobj -1190 0 obj << +1218 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 662.456 537.983 671.367] /Subtype /Link /A << /S /GoTo /D (copyright) >> >> endobj -1191 0 obj << +1219 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [95.641 651.562 156.791 658.416] /Subtype /Link /A << /S /GoTo /D (disclaimer) >> >> endobj -1192 0 obj << +1220 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 651.562 537.983 658.416] /Subtype /Link /A << /S /GoTo /D (disclaimer) >> >> endobj -1193 0 obj << +1221 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [95.641 638.61 168.438 645.465] /Subtype /Link /A << /S /GoTo /D (newversions) >> >> endobj -1194 0 obj << +1222 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 638.61 537.983 645.465] /Subtype /Link /A << /S /GoTo /D (newversions) >> >> endobj -1195 0 obj << +1223 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [95.641 625.659 141.858 632.513] /Subtype /Link /A << /S /GoTo /D (credits) >> >> endobj -1196 0 obj << +1224 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 625.659 537.983 632.513] /Subtype /Link /A << /S /GoTo /D (credits) >> >> endobj -1197 0 obj << +1225 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [95.641 612.708 206.894 619.562] /Subtype /Link /A << /S /GoTo /D (conventions) >> >> endobj -1198 0 obj << +1226 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 612.708 537.983 619.562] /Subtype /Link /A << /S /GoTo /D (conventions) >> >> endobj -1199 0 obj << +1227 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [71.731 595.442 159.481 604.329] /Subtype /Link /A << /S /GoTo /D (installing-bugzilla) >> >> endobj -1200 0 obj << +1228 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 595.442 537.983 604.329] /Subtype /Link /A << /S /GoTo /D (installing-bugzilla) >> >> endobj -1201 0 obj << +1229 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [95.641 582.023 157.907 588.877] /Subtype /Link /A << /S /GoTo /D (installation) >> >> endobj -1202 0 obj << +1230 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 582.023 537.983 588.877] /Subtype /Link /A << /S /GoTo /D (installation) >> >> endobj -1203 0 obj << +1231 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [119.552 569.071 160.508 575.925] /Subtype /Link /A << /S /GoTo /D (install-perl) >> >> endobj -1204 0 obj << +1232 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 569.071 537.983 575.925] /Subtype /Link /A << /S /GoTo /D (install-perl) >> >> endobj -1205 0 obj << +1233 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [119.552 554.062 211.686 562.974] /Subtype /Link /A << /S /GoTo /D (install-database) >> >> endobj -1206 0 obj << +1234 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 554.062 537.983 562.974] /Subtype /Link /A << /S /GoTo /D (install-database) >> >> endobj -1207 0 obj << +1235 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [143.462 541.111 208.498 550.022] /Subtype /Link /A << /S /GoTo /D (install-mysql) >> >> endobj -1208 0 obj << +1236 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 541.111 537.983 550.022] /Subtype /Link /A << /S /GoTo /D (install-mysql) >> >> endobj -1209 0 obj << +1237 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [143.462 528.16 224.547 537.071] /Subtype /Link /A << /S /GoTo /D (install-pg) >> >> endobj -1210 0 obj << +1238 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 528.16 537.983 537.071] /Subtype /Link /A << /S /GoTo /D (install-pg) >> >> endobj -1211 0 obj << +1239 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [119.552 517.265 190.814 524.12] /Subtype /Link /A << /S /GoTo /D (install-webserver) >> >> endobj -1212 0 obj << +1240 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 517.265 537.983 524.12] /Subtype /Link /A << /S /GoTo /D (install-webserver) >> >> endobj -1213 0 obj << +1241 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [119.552 502.257 178.221 511.168] /Subtype /Link /A << /S /GoTo /D (install-bzfiles) >> >> endobj -1214 0 obj << +1242 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 502.257 537.983 511.168] /Subtype /Link /A << /S /GoTo /D (install-bzfiles) >> >> endobj -1215 0 obj << +1243 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [119.552 491.363 197.867 498.217] /Subtype /Link /A << /S /GoTo /D (install-perlmodules) >> >> endobj -1216 0 obj << +1244 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 491.363 537.983 498.217] /Subtype /Link /A << /S /GoTo /D (install-perlmodules) >> >> endobj -1217 0 obj << +1245 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [143.462 476.354 226.769 485.265] /Subtype /Link /A << /S /GoTo /D (install-modules-dbd-mysql) >> >> endobj -1218 0 obj << +1246 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 476.354 537.983 485.265] /Subtype /Link /A << /S /GoTo /D (install-modules-dbd-mysql) >> >> endobj -1219 0 obj << +1247 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [143.462 463.402 270.365 472.314] /Subtype /Link /A << /S /GoTo /D (install-modules-template) >> >> endobj -1220 0 obj << +1248 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 463.402 537.983 472.314] /Subtype /Link /A << /S /GoTo /D (install-modules-template) >> >> endobj -1221 0 obj << +1249 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [143.462 450.825 216.787 459.362] /Subtype /Link /A << /S /GoTo /D (install-modules-gd) >> >> endobj -1222 0 obj << +1250 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 450.825 537.983 459.362] /Subtype /Link /A << /S /GoTo /D (install-modules-gd) >> >> endobj -1223 0 obj << +1251 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [143.462 437.873 244.462 446.411] /Subtype /Link /A << /S /GoTo /D (install-modules-chart-base) >> >> endobj -1224 0 obj << +1252 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 437.873 537.983 446.411] /Subtype /Link /A << /S /GoTo /D (install-modules-chart-base) >> >> endobj -1225 0 obj << +1253 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [143.462 424.548 244.024 433.46] /Subtype /Link /A << /S /GoTo /D (install-modules-gd-graph) >> >> endobj -1226 0 obj << +1254 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 424.548 537.983 433.46] /Subtype /Link /A << /S /GoTo /D (install-modules-gd-graph) >> >> endobj -1227 0 obj << +1255 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 411.597 264.776 420.508] +/Rect [143.462 411.597 236.543 420.508] /Subtype /Link -/A << /S /GoTo /D (install-modules-gd-text-align) >> +/A << /S /GoTo /D (install-modules-gd-text) >> >> endobj -1228 0 obj << +1256 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 411.597 537.983 420.508] /Subtype /Link -/A << /S /GoTo /D (install-modules-gd-text-align) >> +/A << /S /GoTo /D (install-modules-gd-text) >> >> endobj -1229 0 obj << +1257 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [143.462 398.645 247.113 407.557] /Subtype /Link /A << /S /GoTo /D (install-modules-xml-twig) >> >> endobj -1230 0 obj << +1258 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [533.001 398.645 537.983 407.557] /Subtype /Link /A << /S /GoTo /D (install-modules-xml-twig) >> >> endobj -1231 0 obj << +1259 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 386.067 255.093 394.605] +/Rect [143.462 385.694 245.907 394.605] +/Subtype /Link +/A << /S /GoTo /D (install-modules-soap-lite) >> +>> endobj +1260 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [533.001 385.694 537.983 394.605] +/Subtype /Link +/A << /S /GoTo /D (install-modules-soap-lite) >> +>> endobj +1261 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [143.462 373.116 255.093 381.654] /Subtype /Link /A << /S /GoTo /D (install-modules-patchreader) >> >> endobj -1232 0 obj << +1262 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [533.001 386.067 537.983 394.605] +/Rect [533.001 373.116 537.983 381.654] /Subtype /Link /A << /S /GoTo /D (install-modules-patchreader) >> >> endobj -1233 0 obj << +1263 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 372.742 256.338 381.654] +/Rect [119.552 359.791 256.338 368.702] /Subtype /Link /A << /S /GoTo /D (install-MTA) >> >> endobj -1234 0 obj << +1264 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [533.001 372.742 537.983 381.654] +/Rect [533.001 359.791 537.983 368.702] /Subtype /Link /A << /S /GoTo /D (install-MTA) >> >> endobj -1235 0 obj << +1265 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [119.552 346.84 271.48 355.751] +/Subtype /Link +/A << /S /GoTo /D (using-mod_perl-with-bugzilla) >> +>> endobj +1266 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 359.791 168.428 368.702] +/Rect [533.001 346.84 537.983 355.751] +/Subtype /Link +/A << /S /GoTo /D (using-mod_perl-with-bugzilla) >> +>> endobj +1267 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [95.641 333.888 168.428 342.8] /Subtype /Link /A << /S /GoTo /D (configuration) >> >> endobj -1236 0 obj << +1268 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [533.001 359.791 537.983 368.702] +/Rect [528.02 333.888 537.983 342.8] /Subtype /Link /A << /S /GoTo /D (configuration) >> >> endobj -1237 0 obj << +1269 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 346.84 188.732 355.751] +/Rect [119.552 320.937 188.732 329.848] /Subtype /Link /A << /S /GoTo /D (localconfig) >> >> endobj -1238 0 obj << +1270 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [533.001 346.84 537.983 355.751] +/Rect [528.02 320.937 537.983 329.848] /Subtype /Link /A << /S /GoTo /D (localconfig) >> >> endobj -1239 0 obj << +1271 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 335.945 209.314 342.8] +/Rect [119.552 310.043 209.314 316.897] /Subtype /Link /A << /S /GoTo /D (database-engine) >> >> endobj -1240 0 obj << +1272 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 335.945 537.983 342.8] +/Rect [528.02 310.043 537.983 316.897] /Subtype /Link /A << /S /GoTo /D (database-engine) >> >> endobj -1241 0 obj << +1273 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 320.937 282.639 329.848] +/Rect [143.462 295.034 282.639 303.945] /Subtype /Link /A << /S /GoTo /D (database-schema) >> >> endobj -1242 0 obj << +1274 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 320.937 537.983 329.848] +/Rect [528.02 295.034 537.983 303.945] /Subtype /Link /A << /S /GoTo /D (database-schema) >> >> endobj -1243 0 obj << +1275 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 307.985 208.498 316.897] +/Rect [143.462 282.082 208.498 290.994] /Subtype /Link /A << /S /GoTo /D (mysql) >> >> endobj -1244 0 obj << +1276 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 307.985 537.983 316.897] +/Rect [528.02 282.082 537.983 290.994] /Subtype /Link /A << /S /GoTo /D (mysql) >> >> endobj -1245 0 obj << +1277 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 295.034 224.547 303.945] +/Rect [143.462 269.131 224.547 278.042] /Subtype /Link /A << /S /GoTo /D (postgresql) >> >> endobj -1246 0 obj << +1278 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 295.034 537.983 303.945] +/Rect [528.02 269.131 537.983 278.042] /Subtype /Link /A << /S /GoTo /D (postgresql) >> >> endobj -1247 0 obj << +1279 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 282.082 198.963 290.994] +/Rect [119.552 256.18 198.963 265.091] /Subtype /Link -/A << /S /GoTo /D (528) >> +/A << /S /GoTo /D (545) >> >> endobj -1248 0 obj << +1280 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 282.082 537.983 290.994] +/Rect [528.02 256.18 537.983 265.091] /Subtype /Link -/A << /S /GoTo /D (528) >> +/A << /S /GoTo /D (545) >> >> endobj -1249 0 obj << +1281 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 271.188 189.15 278.042] +/Rect [119.552 245.285 189.15 252.14] /Subtype /Link /A << /S /GoTo /D (http) >> >> endobj -1250 0 obj << +1282 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 271.188 537.983 278.042] +/Rect [528.02 245.285 537.983 252.14] /Subtype /Link /A << /S /GoTo /D (http) >> >> endobj -1251 0 obj << +1283 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 256.18 229.24 265.091] +/Rect [143.462 230.277 266.599 239.188] /Subtype /Link /A << /S /GoTo /D (http-apache) >> >> endobj -1252 0 obj << +1284 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 256.18 537.983 265.091] +/Rect [528.02 230.277 537.983 239.188] /Subtype /Link /A << /S /GoTo /D (http-apache) >> >> endobj -1253 0 obj << +1285 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 245.285 334.932 252.14] +/Rect [143.462 219.383 334.932 226.237] /Subtype /Link /A << /S /GoTo /D (http-iis) >> >> endobj -1254 0 obj << +1286 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 245.285 537.983 252.14] +/Rect [528.02 219.383 537.983 226.237] /Subtype /Link /A << /S /GoTo /D (http-iis) >> >> endobj -1255 0 obj << +1287 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 230.277 178.221 239.188] +/Rect [119.552 204.374 178.221 213.285] /Subtype /Link /A << /S /GoTo /D (install-config-bugzilla) >> >> endobj -1256 0 obj << +1288 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 230.277 537.983 239.188] +/Rect [528.02 204.374 537.983 213.285] /Subtype /Link /A << /S /GoTo /D (install-config-bugzilla) >> >> endobj -1257 0 obj << +1289 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 217.325 250.898 226.237] +/Rect [95.641 191.422 250.898 200.334] /Subtype /Link /A << /S /GoTo /D (extraconfig) >> >> endobj -1258 0 obj << +1290 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 217.325 537.983 226.237] +/Rect [528.02 191.422 537.983 200.334] /Subtype /Link /A << /S /GoTo /D (extraconfig) >> >> endobj -1259 0 obj << +1291 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 204.374 192.328 213.285] +/Rect [119.552 178.471 192.328 187.382] /Subtype /Link -/A << /S /GoTo /D (629) >> +/A << /S /GoTo /D (695) >> >> endobj -1260 0 obj << +1292 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 204.374 537.983 213.285] +/Rect [528.02 178.471 537.983 187.382] /Subtype /Link -/A << /S /GoTo /D (629) >> +/A << /S /GoTo /D (695) >> >> endobj -1261 0 obj << +1293 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 191.422 222.605 200.334] +/Rect [119.552 165.52 222.605 174.431] /Subtype /Link -/A << /S /GoTo /D (648) >> +/A << /S /GoTo /D (714) >> >> endobj -1262 0 obj << +1294 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 191.422 537.983 200.334] +/Rect [528.02 165.52 537.983 174.431] /Subtype /Link -/A << /S /GoTo /D (648) >> +/A << /S /GoTo /D (714) >> >> endobj -1263 0 obj << +1295 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 178.471 219.726 187.382] +/Rect [119.552 152.568 219.726 161.48] /Subtype /Link /A << /S /GoTo /D (installation-whining-cron) >> >> endobj -1264 0 obj << +1296 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 178.471 537.983 187.382] +/Rect [528.02 152.568 537.983 161.48] /Subtype /Link /A << /S /GoTo /D (installation-whining-cron) >> >> endobj -1265 0 obj << +1297 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 165.52 179.327 174.431] +/Rect [119.552 139.617 179.327 148.528] /Subtype /Link /A << /S /GoTo /D (installation-whining) >> >> endobj -1266 0 obj << +1298 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 165.52 537.983 174.431] +/Rect [528.02 139.617 537.983 148.528] /Subtype /Link /A << /S /GoTo /D (installation-whining) >> >> endobj -1267 0 obj << +1299 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 154.625 197.409 161.48] +/Rect [119.552 128.723 197.409 135.577] /Subtype /Link /A << /S /GoTo /D (patch-viewer) >> >> endobj -1268 0 obj << +1300 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 154.625 537.983 161.48] +/Rect [528.02 128.723 537.983 135.577] /Subtype /Link /A << /S /GoTo /D (patch-viewer) >> >> endobj -1269 0 obj << +1301 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 141.674 231.78 148.528] +/Rect [119.552 115.651 231.78 122.625] /Subtype /Link /A << /S /GoTo /D (bzldap) >> >> endobj -1270 0 obj << +1302 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 141.674 537.983 148.528] +/Rect [528.02 115.651 537.983 122.625] /Subtype /Link /A << /S /GoTo /D (bzldap) >> >> endobj -1271 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 126.665 355.445 135.577] -/Subtype /Link -/A << /S /GoTo /D (apache-addtype) >> ->> endobj -1272 0 obj << +1303 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 126.665 537.983 135.577] +/Rect [119.552 100.762 355.445 109.674] /Subtype /Link /A << /S /GoTo /D (apache-addtype) >> >> endobj -1273 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 113.714 324.5 122.625] -/Subtype /Link -/A << /S /GoTo /D (762) >> ->> endobj -1274 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 113.714 537.983 122.625] -/Subtype /Link -/A << /S /GoTo /D (762) >> ->> endobj -1275 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 100.762 234.28 109.674] -/Subtype /Link -/A << /S /GoTo /D (os-specific) >> ->> endobj -1276 0 obj << +1304 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 100.762 537.983 109.674] /Subtype /Link -/A << /S /GoTo /D (os-specific) >> +/A << /S /GoTo /D (apache-addtype) >> >> endobj -1184 0 obj << -/D [1182 0 R /XYZ 71.731 729.265 null] +1212 0 obj << +/D [1210 0 R /XYZ 71.731 729.265 null] >> endobj 6 0 obj << -/D [1182 0 R /XYZ 244.332 703.236 null] +/D [1210 0 R /XYZ 244.332 703.236 null] >> endobj -1181 0 obj << -/Font << /F23 1173 0 R /F32 1187 0 R /F27 1180 0 R /F33 1278 0 R >> +1209 0 obj << +/Font << /F23 1201 0 R /F32 1215 0 R /F27 1208 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1326 0 obj << -/Length 57151 +1354 0 obj << +/Length 57019 /Filter /FlateDecode >> stream -xڔ�]�dי^w?�W�����Ki,��G�*���C"���C����g?;�ٕg�b肤xf�D'�B��z����;~�r<�<�����p���͟��o������_��8�x|~>�?ݟ���������������v�����vx:��{=<<>�?�o��7���|��������?��7y(�����������x������o��ӟ~����m����w�w�����/��?}��~�������7���y�pxy��B�~�����������x���|��9^Ϗ�>���� k�[��ヴ�gٺ�w����Giݞ�am����5��u{����;���pg�۳7� �n}<�ޞ�u<���c}8<��H��� kw�χ�kݞ�am�������*�۳7� �n}:} Oo�:�e�ܱ���Gkݞ�am����5�?Il��pnGy���)��� i�[�O�����gٺ�w����x/�۳7� ܱ���;kݞ�am�����o���x����/���y�� ϲu�X�/ֺ={������y�cn<{�����kx�?�Ƴ7� �n}=} ��:�e�ܱ����cn<{�����k��?�Ƴ7� ܱ�����n�ް6����5��s�Y�.���k���'o/a;��ë����� c�v���U���ސ6��������~��Y��������Z�goX�c=}OҺ={�����o:��� k�[����AZdzl]�;���p�$�۳7� ܱ���㳴n�ް6p�z�7�u{�����w��7�.ϲu�X��Һ={��������Z�goX�c}=�?�I��� k�[N_����(;��<}�ۣ7���Q���ǣtn�ސ6p�z��O��� k�[O_����gٺ�w��o�(ƍgoX�c=} �oC����X_�7kݞ�am�u�����U��f<���c}8� Ƴ7� ܱ>���u{����;����$ƍgoXx��|��O��,[����5<X��� kw����^���ް6p�z���Go8w]�r��ϛ�QV6nGy��s{����;֧�ӛ���ް6p��z�{�����^����^�ϸ�,[����p�,ڌgoX�c=} Oֺ={�����kx�?�Ƴ7� �n};} �:�e�ܱ���{�3n<{�����k8ʟq����XO_Ý�n�ް6��������~��Y������M�=�<{��������Z�goX�c}9ȿ)0��,�u�����y��p�z���u{����;��w�x/�۳7� ܱ��yv�goXx�z��u<���c=} �Giݞ�am����5ȳ�<{��������Z�goXx��pwxxu?��,[�����*�N�� kw�O��gkݞ�am����5<�s���^�>��yv�gٺ�w�����Z�goX�c=} �OMۣ7���Q��yv�goHx��t���:�e�ܱ��yv�goX�c}:�˳�<{��������Z�goXx��|w��g'y��p�zx�g'y����;����d�۳7� ܱ��yv�goXx��r���I�e�ܱ���{kݞ�am����5ȳ�<{�����k�g'y�����w�㛴�gٺ�w���g+��� g�v�O��<>ɳ7� ܱ��_�u{����o��@��Y�.���[��'y����;����h�۳7� ܱ��y|�goXx��tw�����gѺw����h�۳7� ܱ��y|�goX�c}9<ɿϔgoXx�z�;��`"ϲu�X�O��$�ް6p��t�{������XO_�&�� k�[�O_��/��(;��<}�R������(O_��%�� iw��/���I����b����p�7w� -�>|�������f]� ����6������������������������q<�g��c�Ǒ9>�o��>��������m�}���{�MO����B�3]~�õ������bݞ�am��u�0�ud�lm f��:�N�6�NeM։��Y������ Ĭ�YG���b��#�dk1�T�d�h]��u:��:��@�:�ud�lm f��:�N�6�NeM։��Y������ ���I�����ì�9G���b֩��:Ѻ�1�t֑u����u:��:��@�:�ud�lm f�ʚ���NgY'[�Y������ Ĭ�YG���b֩��:Ѻ�1�t֑u����u:��:��@�:�ud�lm f�ʚ���N���u��FY�nY'�Y�s���� Ĭ�Xg�I��Y������ Ĭ�YG���b��#�dk1�T�d�h]��u:��:��@�:�ud�lm f��:�N�6�NeM։��Y������ Ĭ�YG���b��#�dk)�Tґu��q�u:�u��p�u:��:Y�@�:�ud�lm f�ʚ���NgY'[�Y������ Ĭ�YG���b֩��:Ѻ�1�t֑u����u:��:��@�:�ud�lm f�ʚ���NgY'[�Y������ ���I�������S)G։��a��#�di1�t֑u����u:��:��@�:�5Y'Z f��:�N�6�NgY'[�Y������ ĬSY�u�ub��#�dk1�t֑u����u:��:��@�:�uf�d]��u:��:��@�:�ud�lm e�N�e��,f�ʙ���NgY'[�Y������ Ĭ�YG���b֩��:Ѻ�1�t֑u����u:��:��@�:�ud�lm f�ʚ���NgY'[�Y������ Ĭ�YG���b֩��:Ѻ�1�t֑u����u:�u��p�u:��:Y�@�:�5Y'Z f��:�N�6�NgY'[�Y������ ĬSY�u�ub��#�dk1�t֑u����u:��:��@�:�5Y'Z f��:�N�6�NgY'[�Y������ ĬSY�u�uR��[����a��#�di1�t֑u����u*k�N�.@�:�ud�lm f��:�N�6�NgY'[�Y��ά��+�NgY'[�Y������ Ĭ�YG���b֩��:Ѻ�1�t֑u����u:��:��@�:�ud�lm e�J:�Nt6��N�ܲNV�N�Y'K�Y'Ɖ��N�_���r7�ϱd��Y��/f��u�g�Y�����^k��������/�|^��k�����~��<�Ş�[�O?���O��-|� �-����-(k��6��eM���r�`��[ ��nAY�-����-(k��6��eM���r�`��[ ��nA9�n��0��pth,wʙn� �nAX��XW wʚn� �nAY�-����-(k��6��c��Y wʚn� �nAY�-����-(k��6��c��Y wʚn� �nAY�-����-(k��6�#M�@��a����[@e�[P�t(m wʚn� �n�Xg�@��݂��[@k�[P�thm wʚn� �n�Xg�@��݂��[@k�[P�thm wʚn� �n�Xg�@��݂��[@k�[P�thm vJ:�t��L�@��q����P�@��5�Z�݂��[@k�[0��-�ur������@��5�Z�݂��[@k�[0��-�ur������@��5�Z�݂��[@k�[�s����݂��[@k�[P�thm vJ:�t����I wʚn� �nAY�-����-(k��6��c��Y wʚn� �nAY�-����-(k��6��c��Y wʚn� �nAY�-����-(k��6��c��Y wʚn� �nAIG����q����P�@��uvd]��-(k��6��eM���r������@��uvd]��-(k��6��eM���r������@��uvd]��-(k��6��eM���r������@��uvd]��-(���Y8��3�J�݂��[@k�[0��-�ur������@��5�Z�݂��[@k�[�s����݂��[@k�[P�thm wʚn� �n�Xg�@��݂��[@k�[P�thm wʚn� �n�H�-��q�-(��PY8��3�J��ڋn?��-\F������+_G��vx|}�na<s�F��_~����?���N��˧����~�����~�����o��Y� ����3������~�}��|�|����o�����c'�6����u;�u�� � �c'eͱZ��Nʚc'�6����u;�u�� � �c'eͱZ��Nʚc'�6����u;�u�� � �c'eͱZ��NJ:���Y8<v2�;��q|줜9vBi��IYs���� � �c'c��Nd]�|줬9vBk��IYs���� � �c'c��Nd]�|줬9vBk��IYs���� � �c'a=;�u�� � �c'eͱZ��NJ:���Y8>v2�y�D���Nʚc'�6����5�Nhm ;)k����@>v2�y�D���Nʚc'�6����5�Nhm ;)k����@>v2�y�D���Nʚc'�6����5�Nhm ;)k����@>v2�y�D���Nʚc'�6���t;��p|줜9vBi���X�Y ;)k����@>vR�;���|줬9vBk���X�Y ;)k����@>vR�;���|줬9vBk���X�Y ;)k����@>vR�;���|줬9vBk���X�Y ;)�8vBg���I9s���� � �c'c��Nd]�|줬9vBk��IYs���� � �c'a=;�u�� � �c'eͱZ��Nʚc'�6����u;�u�� � �c'eͱZ��Nʚc'�6���4�N�l;)�8vBe���I9s����ވc'�۱��e�q��i�s��#�Oχ��W>vϜ��DZ�?}��������/���}�/�?�������o;^N���_��ǽ}�������<t��?�!>�������u{����;K�c:�X�-Y o�*k�h��@ޢU�lѢ���E��٢Eky��X�-Y o�*k�h��@ޢU�lѢ���E��٢Eky��X�-Y m�*�E��Kn�*�آEc�x�V9�E�������h��y�VY�E�����f�� �-Ze�-Z�[��:�hɺ�y�VY�E�����f�� �-Ze�-Z�[��:�hɺ�y�VY�E�����f�� �-Ze�-Z�[�F�-Zr6�h�rlѢ�p�E���3P�@�3�5yZ�y���<����eM���r����3��@�3�5yZ�y���<����eM���r����3��@�3�5yZ�y���<����eM���r����3��@�3�t��,�F�<����<C9�g����g(k��6��eM���r�a�3� ��<CY�g����g(k��6��eM���r�a�3� ��<CY�g����g(k��6��eM���r�!��<�+��eM���r����3��@�3�t��,��9��.@�3�5yZ�y��&�@k9�P��hm ��:��.@�3�5yZ�y��&�@k9�P��hm ��:��.@�3�5yZ�y��&�@k9�P��hm ��:��.@�3�5yZ�y���<���<C9�g����g��3Ⱥ�9�P��hm �ʚ<� �<CY�g����g��3Ⱥ�9�P��hm �ʚ<� �<CY�g����g��3Ⱥ�9�P��hm �ʚ<� �<CY�g����g��3Ⱥ�1�Pґg��p�g(g��6��eM���r�a�3� ��<CY�g����g(k��6��eM���r�!��<�+��eM���r����3��@�3�5yZ�y���<����eM���r����3��@�3�5yZ�y��&� g�0�Pʑg��p�g(g��6��j -D���c�3.[��<c�s��y��<����y�x�g<�<��3��w���O?��}x<�6����a��������p��gx��y��s~<~x=<�=]� W�۳7� �n}<�ޞ�u<���c��Mgݞ�am����p�b�۳7� ܱ�������۳7� �n}:} Oo�:�e�ܱ���Gkݞ�am����5<J��Go8��<}�NV�����[���^Zdzl]�;�ӿy�������X�6kݞ�am 'qʚ$� �$�XgG��I��&�Ck9�S�$qhm 'qʚ$� �$�XgG��I��&�Ck9�S�$qhm 'qʚ$� �$�XgG�HI�rnI/a��)�H��X8N�3IJ�I����8��@N�5IZ�I��&�Ck9�S�$qhm 'q�:�8�.@N�5IZ�I��&�Ck9�S�$qhm 'q�:�8�.@N�5IZ�I��&�Ck9�S�$qhm &qF�$����$N)G���q��I�P�@N�5IZ�I���$����8eM��r��I���@N�5IZ�I���$����8eM��r��I���@N�5IZ�I���$����8eM��r��I���@L�t$q�,&qF�$����$N9�ġ����)k�8�6��8eM��rg�3�#��$NY�ġ����)k�8�6��8eM��rg�3�#��$NY�ġ����)k�8�6��8eM��r'��$�+��8eM��r��I���@L�t$q�,'q�9�8�.@N�5IZ�I��&�Ck9�S�$qhm 'q�:�8�.@N�5IZ�I��&�Ck9�S�$qhm 'q�:�8�.@N�5IZ�I��&�Ck9�S�$qhm 'q�:�8�.@N�5IZ�I���$���$N9�ġ�����L�Ⱥ�9�S�$qhm 'qʚ$� �$NY�ġ�����L�Ⱥ�9�S�$qhm 'qʚ$� �$NY�ġ�����L�Ⱥ�9�S�$qhm 'qʚ$� �$NY�ġ�����L�Ⱥ�1�Sґġ�p��)g�8�6��8eM��rg�3�#��$NY�ġ����)k�8�6��8eM��r'��$�+��8eM��r��I���@N�5IZ�I���$����8eM��r��I���@N�5IZ�I��&�#g�0�Sʑġ�p��)g�8�6�����K%q�9�$�?�O��?�������C����I������O�pw�I�t=��$q�#������������q���~��ߖ��c���z�������֧]~�����x��u��A>Zdzl]�;և�ˋ�n�ް6p��|���A�u{����;������Ieݞ�am��#�����y�+p�z���u{����;������Ieݞ�am����5�u{�������p���Y�.����wvoҺ={������vֺ={��������}�pו�����w��9�e�ܱ���gkݞ�am����\��d��� kw��o��AZ�goX�S����iϲu�XO_����n�ް6p�:�{eMϏ�rϯ�����@���u��d]���+kz~�6�{~eMϏ�rϯ�����@���u��d]���+kz~�6{~%=?:�=�r��Gi��7���urϯ�����@���5=?Z�=����Gk��7���urϯ�����@���5=?Z�=����Gk��7���urϯ�����@���5=?Z�=����Gk��7���uRϯ�[Ϗ�K��J8z~4�{~�LϏ�r�/���+�{~eMϏ�rϯ�����@���5=?Z�=��Ξ���{~eMϏ�rϯ�����@���5=?Z�=��Ξ���{~eMϏ�rϯ�����@���5=?Z�=����'g��W���p��+gz~�6�{~eMϏ�r�o���'��_Y���+kz~�6�{~eMϏ�r�o���'��_Y���+kz~�6�{~eMϏ�r�o���'��_Y���+kz~�6{~%=?:�=�Q��'e��W���(m ��ʚ�� �_Y������ɺ���W���hm ��ʚ�� �_Y������ɺ���W���hm ��ʚ�� �_Y������ -�_Y���+kz~�6{~%=?:�=�qΞ���{~eMϏ�rϯ�����@���5=?Z�=��Ξ���{~eMϏ�rϯ�����@���5=?Z�=��Ξ���{~eMϏ�rϯ�����@���5=?Z�=��Ξ���{~eMϏ�bϯ���Gg��W���(m ���:{~�.@���5=?Z�=����Gk��W���hm ���:{~�.@���5=?Z�=����Gk��W���hm ���:{~�.@���5=?Z�=����Gk��W���hm ���:{~�.@���t���,��ʙ�� �_Y������ɺ���W���hm ��ʚ�� �_Y������ -�_Y���+kz~�6�{~eMϏ�r�o���'��_Y���+kz~�6�{~eMϏ�b�o�����8���r���,��ʙ�� �?LW=?~��翌��{����W��������G~��x���/^q{�ŶLJ�o����N��;ﵝ�,|���^|��T���T� �TVIG*���q*k�3�%��TVY�ʢ����*kRY�6�SYeM*��r*k�3�%��TVY�ʢ����*kRY�6�SYeM*��r*k�3�%��TVY�ʢ����*kRY�6�SYeM*��r*k�3�%��TVY�ʢ����*�He�Y8Ne�3�,Jȩ���T���SYeM*��r*��Ie��@Ne�5�,Zȩ���T���SYeM*��r*��Ie��@Ne�5�,Zȩ���T���SYeM*��r*��Ie��@Ne�5�,Zȩ���T���RY��RY4^�0�Uʢ�p��*gRY�6�SYa=��`]���*kRY�6�SYeM*��r*��Ie��@Ne�u��d]���*kRY�6�SYeM*��r*��Ie��@Ne�u��d]���*kRY�6�SYeM*��r*��Ie��@Le�4�,9���R�T���TV9�ʢ����*kRY�6�SYc��,Y ��ʚT� �TVY�ʢ����*kRY�6�SYc��,Y ��ʚT� �TVY�ʢ����*kRY�6�SYc��,Y ��ʚT� �TVY�ʢ����*�He�Y8Le�2�,)ǩ�r&�Ei9�U֤�hm ��ʚT� �T�Xg*K�ȩ��&�Ek9�U֤�hm ��ʚT� �T�Xg*K�ȩ��&�Ek9�U֤�hm ��ʚT� �TVXϩ,XW ��ʚT� �TVY�ʢ����*�He�Y8Ne�s��$]���*kRY�6�SYeM*��r*��Ie��@Ne�u��d]���*kRY�6�SYeM*��r*��Ie��@Ne�u��d]���*kRY�6�SYeM*��r*��Ie��@Ne�u��d]���*kRY�6SY%�,:ǩ�r&�Ei9�5֙ʒur*��Ie��@Ne�5�,Zȩ��&�Ek9�5֙ʒur*��Ie��@Ne�5�,Zȩ��&�Ek9�5֙ʒur*��Ie��@Ne�5�,Zȩ��&�Ek9�5֙ʒub*��#�Eg�8�UΤ�(m ��ʚT� �T�Xg*K�ȩ��&�Ek9�U֤�hm ��ʚT� �TVXϩ,XW ��ʚT� �TVY�ʢ����*kRY�6�SYc��,Y ��ʚT� �TVY�ʢ����*kRY�6SY#M*K��a*��#�Ee�8�UΤ�(m ���~�T?ǖ�^v������XR���������S���9��˯��O��~��ӯۿ����O��<^����߿;~�s��پ4���雋Ow%�}<��r�O���n�:]���:}� p���S'�.@>uR֜:���|꤬9uBk��IYs���S'�.@>uR֜:���|꤬9uBk��IYs���S'�.@>uR֜:���|꤬9uBk��IIǩ:��NF�S'R6�O��3�N(m �:)kN���@>uR֜:���|�d��ԉ��O��5�Nhm �:)kN���@>uR֜:���|�d��ԉ��O��5�Nhm �:)kN���@>uR֜:���|�$��S'��@>uR֜:���|꤬9uBk��IIǩ:ǧN�9O�H����IYs���� � �S'eͩZȧN�:O�Ⱥ���IYs���� � �S'eͩZȧN�:O�Ⱥ���IYs���� � �S'eͩZȧN�:O�Ⱥ���IYs��⩓��S't�O��3�N(m �:�<u"��S'eͩZȧNʚS'�6�O��5�Nhm �:�<u"��S'eͩZȧNʚS'�6�O��5�Nhm �:�<u"��S'eͩZȧNʚS'�6�O��5�Nhm �:�<u"��S'%�N�,�:)gN�P�@>uR֜:���|�d��ԉ��O��5�Nhm �:)kN���@>uR֜:���|�$��S'��@>uR֜:���|꤬9uBk��IYs���S'�.@>uR֜:���|꤬9uBk��IYs��⩓��ԉ���S'��N�,�:)gN�P�@>u��qꄟc;u��+�?u���?_�7� -p|;���ގ��f��:���LN�������������w�������㸶��z�������_��v���u��y����ά_� �3�h]�8��cf�� ęug3�lm ά;�Ygkqf]Y3����3��:f���@�Yw�1����̺���u�6g֕53�h]�8��cf�� ��u'�f��Y8�Yw�1����̺�ff�g֝u̬���8��cf�� ęug3�lm ά+kf�Ѻ�qf�Y��:[�3��:f���@�Yw�1����̺�ff�g֝u̬���8��cf�� ęug3�lm ά+kf�Ѻ�af�9�ά��F3�N�ͬ��p8��cf�� ęuc�3�d]�8��cf�� ęug3�lm ά;�Ygkqf]Y3����3��:f���@�Yw�1����̺���u�6g֕53�h]�8��cf�� ęug3�lm ά;�Ygkif]I��::G3�N�ͬ��p8�=di�=t������*k�C�.@l�u��lm ���:�C�6�Cg�![�����=D����YG{��b{謣=dk�=t������*k�C�.@l�u��lm ���:�C�6��C'��Cv��C��!*���s���� ���YG{��b{謣=dk�=Tִ�h]��:�h��@l�u��lm ���:�C�6�CeM{���������� ���YG{��b{謣=dk�=4���ub{謣=dk�=t������:����p�*g�C�.@l�u��lm ���:�C�6�Cg�![�����=D����YG{��b{謣=dk�=t������*k�C�.@l�u��lm ���:�C�6�Cg�![�����=D����YG{��R{�[{���a{蜣=di�=Tִ�h]��:�h��@l�u��lm ���:�C�6�CeM{���������� ���YG{��b{謣=dk�=Tִ�h]��:�h��@l�u��lm ���:�C�6�CeM{��H���n�!;���s���� ���YG{��b{��iѺ��=t������:�h��@l�u��lm ���:�C��@l�u��lm ���:�C�6�Cg�![�����=D����YG{��b{謣=dk�=t������*�h��8j�rkYY8l�s��,m ���Ι��?��g*���k�s|����f�O?u������~��v��g��V>���?�������继��_>�˗/����q����Ͽ����?���O_�;~;�����o�~���<��g��G��%>�<�e��p��$���~���c@���r�c���!�� -GYSᠵ�\�(k*�6�+eM���r�c���!�� -GYSᠵ�\�(k*�6�+eM���r�c���!�� -GYSᠵ�\�(k*�6�+eM���r�c���!�� -G9� -��0�p�pT8h,W8ʙ -� � -GX�XW W8ʚ -� � -GYSᠵ�\�(k*�6�+c�Y W8ʚ +xڔ�͒dWze7�S`$p�����֒(k�)V��f�`!��I���O/��g�}���U�A��˵�(Deշ�=~sw���7������������o��/u�͟�������㉇�����������x�?�������z�����������w/�gޞ��?������?�zx}:}�����x&����������������������������?���~�������o?���~w��ӯ����~�ퟷ?�����?����Ͽ���������|�������W����������p����q�<<����g����i>~���w�z�\�n�ް6��twx~r��Qv6nGy:��%�_��,����댝۳7� ܱ���ӽ�n�ް6�����K�x��p�z��'iݞ�am����5�=H��� kw�/�㫵n�ް6������"�u3�e�ܱ�G�7��� kw��Oֺ={�����kx|�����^�>����gϲu�X�_��Z�goX�c= ��g�x����;��� ���=z�Y�����w �l���q;��pg�۳7� ܱ>_�/�x����;֗��n�ް6������,ƍgٺ�w���ݓ�i3��am����5<Z��� kw���A���ް6����5��u<���c= ��g�x����;���p�?�Ƴ7� ܱ���;kݞ�am�U���������˳h]�;����˫�n�ް6p��xxx������X���R�����]W�߁�њgY��w�����Z�goX�c=�Һ={�����[8��u{�������^Zdzl]�;���p|������X�_�ݣ�n�ް6p��|xy�����^�����c.ϲu�X�/���L����X�'kݞ�am����5<�s���^�>����g<���c= 'kݞ�am����5ȿ5m��pnGy������ i�[���QZdzl]�;��wp'̍goX�c}<ܿ�ou<{��������Z�goXx��tw��?�Ƴl]�;������3��am����5<Z��� kw���A���ް6����5����,[����5�[��� kw���(̍goX�c= w��x����/w�㫴�gٺ�w���'+��� g�v������3��!m������l�۳7� �n}=O���x��p�z����� kw����Z�goX�c= '�cn<{�����ǻ�� ��<���c= Gkݞ�am����5�=I��� kw�χG��3���^��w/�:�e�ܱ��_�u{����;���ݓ�n�ް6p�z�_�u{������A�g{����Q������� e�v��/�t������X�_���<��G�ׯ��_�~s7��������|x��۬�7l_���{�a{:�����n���v��8n�����ÿ~��O�xww����7�oѾ�o���_~����gqz8ܿ|�N��4�����yz:���O>�����t�x�\�n�ް6���x�{}r��,[���tx<�M�Y�goX�c}:�=[��� kw�/�ǧiݞ�am�u���k8�MZYdzl]�;����`�۳7� ܱ���)��� g�v����t�����^�>���{iϲu�X����^Z�goX�c=wֺ={������'�IZ�goXx��|w�A*� +ϲu�XO��gkݞ�am�������17��am����5<�s���^�����iϲu�X�_�I���ް6p�z��叹�� kw���h�۳7� �n}= w���x��p�z�������������I~}�p;���$^���� i�N��^�ݏ�<���c=NOֺ={�����[x<I��� kw����u{�������p���,[����5�?J��� kw����$�۳7� ܱ���;kݞ�am�N�uwx~u?��,[���t8�t������X���YG&��b&�#�ck)�Sґɡ�q��9�ɱ�p��9���X�@��udrlm frʚL�39g�[�����L�� �L�YG&��b&����к�1�s֑ɱ����9�����@��udrlm frʚL�39g�[�����L�� �L�I�L����LN)G&���a&�#�ci1�s֑ɱ����9�����@��5�Z fr�:29�639g�[�����L�� �LNY�ɡub&�#�ck1�s֑ɱ����9�����@��ufrd]���9�����@��udrlm erN�er�,frʙL�39g�[�����L�� �L�YG&��b&����к�1�s֑ɱ����9�����@��udrlm frʚL�39g�[�����L�� �L�YG&��b&����к�1�s֑ɱ����9�ɱ�p��9���X�@��5�Z fr�:29�639g�[�����L�� �LNY�ɡub&�#�ck1�s֑ɱ����9�����@��5�Z fr�:29�639g�[�����L�� �LNY�ɡuR&�[&���a&�#�ci1�s֑ɱ����)k29�.@��udrlm fr�:29�639g�[�����L��+39g�[�����L�� �L�YG&��b&����к�1�s֑ɱ����9�����@��udrlm erJ:29t6�29��29V39��K���]&�������Ҏ{�|���/���?���^{�x|=������f���x��<�P����˗_���߶�}�����������m�����/p�T�����~�����x�����]������'��rź={����"�x8��u<���c=���u{����;֑(*k�G�6��GeM��r�h��y$���QY�<����<*k�G�6��GeM��r�h��y$���QY�<����<*�h�Y8n�3�#J�ͣ��摬��GeM��r�i��@n�5�#Z�ͣ��摬��GeM��r�i��@n�5�#Z�ͣ��摬��GeM��r�i��@n�5�#Z�ͣ��摬��G�ܚG4��ayDc�yT�4�(m 7��zi���yT�4�hm 7�ʚ�� ��QY�<����<�lɺ��yT�4�hm 7�ʚ�� ��QY�<����<�lɺ��yT�4�hm 7�ʚ�� ��QY�<����<i�Gr6�G��#*�ͣr�yDi�yT�4�hm 7��:�G�.@n�5�#Z�ͣ��yDk�yT�4�hm 7��:�G�.@n�5�#Z�ͣ��yDk�yT�4�hm 7��:�G�.@n�5�#Z�ͣ��yDk�yT��<��p�<e�GR6��G�L��r�i��@n�5�#Z�ͣ��摬��GeM��r�i��@n�5�#Z�ͣ��摬��GeM��r�i��@n�5�#Z�ͣ�^�G��@n�5�#Z�ͣ��yDk�yT��<��p�<�lI���yT�4�hm 7�ʚ�� ��QY�<����<�lɺ��yT�4�hm 7�ʚ�� ��QY�<����<�lɺ��yT�4�hm 7�ʚ�� ��QY�<����<�lɺ��yT�4�hm 6�J:�Gt��G�L��r�h��y$���QY�<����<*k�G�6��GeM��r�h��y$���QY�<����<*k�G�6��GeM��r�h��y$���QY�<����<*k�G�6��GeM��r�h��y$���QIG���q�iQ�@n�5�#Z�ͣ��摬��GeM��r�i��@n�5�#Z�ͣ�^�G��@n�5�#Z�ͣ��yDk�yT�4�hm 7��:�G�.@n�5�#Z�ͣ��yDk�yT�4�hm 6�F�摜���Q)G���q�iQ�@n��=�<��ؚ����~��9�?�>�?�_ x��sx��s������z�y�K��qd�������_~������"��+w���:��������y���<\K.���~�+�����XG����:��@�:�5Y'Z�Y��ά����NeM։�r֩��:��@�:�5Y'Z�Y��ά����NeM։�r֩��:��@�:�5Y'Z�Y��ά����NeM։�b֩�#�Dg�8�T�d�(m g��:�N�.@�:�5Y'Z�Y��&�Dk9�T�d�hm g��:�N�.@�:�5Y'Z�Y��&�Dk9�T�d�hm g��:�N�.@�:�5Y'Z�Y��&�Dk9�T�d�hm g��:�N�.@�:�s�:���Y������S9�u����u +�%�� +�SY�u����u*k�N�6��NeM։�r�i�3�$��SY�u����u*k�N�6��NeM։�r�i�3�$��SY�u����u*k�N�6��NeM։�b�i��:��8�:�rd��,g�ʙ�� �SY�u����u��:ɺ�9�T�d�hm g�ʚ�� �SY�u����u��:ɺ�9�T�d�hm g�ʚ�� �SY�u����u��:ɺ�9�T�d�hm g�ʚ�� ĬSIG։��a�i��:I�8�:�3Y'J�Y��&�Dk9�T�d�hm g��:�N�.@�:�5Y'Z�Y��&�Dk9�T�d�hm g��:�N�.@�:�5Y'Z�Y��&�Dk9�T�d�hm g��z�:��9�T�d�hm g�ʚ�� ĬSIG։��q�i�3�$��SY�u����u*k�N�6��NeM։�r�i�3�$��SY�u����u*k�N�6��NeM։�r�i�3�$��SY�u����u*k�N�6��NeM։�r�i�3�$��SY�u����u*��:�Y8�:�3Y'J�Y��ά����NeM։�r֩��:��@�:�5Y'Z�Y��ά����NeM։�r֩��:��@�:�5Y'Z�Y��ά����NeM։�r֩��:��@�:�5Y'Z�Y��ά���N%Y':�Y�r&�Di9�T�d�hm g��:�N�.@�:�5Y'Z�Y��&�Dk9�T�d�hm g��z�:��9�T�d�hm g�ʚ�� �SY�u����u��:ɺ�9�T�d�hm g�ʚ�� �SY�u����ui�Nr6�N�Y'*�Y�r&�Di9�8Qd��9���}C��u��%�<��:����:�3�������^k��������O�|^��k�����~��<�Ş�[�O?��w�~�[��A�[@k�[P�thm wʚn� �n�Xg�@��݂��[@k�[P�thm wʚn� �n�Xg�@�H݂rn��ð[P��-��p�-(g��6��a�t`]��-(k��6��eM���r������@��uvd]��-(k��6��eM���r������@��uvd]��-(k��6��eM���r������@��4�9�݂R�n���nA9�-����-(k��6��c��Y wʚn� �nAY�-����-(k��6��c��Y wʚn� �nAY�-����-(k��6��c��Y wʚn� �nAY�-����-(���Y8��2�)�݂r�[@i�[P�thm wʚn� �n�Xg�@��݂��[@k�[P�thm wʚn� �n�Xg�@��݂��[@k�[P�thm wʚn� �nAX/�XW wʚn� �nAY�-����-(���Y8��sv$]��-(k��6��eM���r������@��uvd]��-(k��6��eM���r������@��uvd]��-(k��6��eM���r������@��uvd]��-(k��6�%�:�݂r�[@i�[0��-�ur������@��5�Z�݂��[@k�[0��-�ur������@��5�Z�݂��[@k�[0��-�ur������@��5�Z�݂��[@k�[0��-�ub����[@g�[P�t(m wʚn� �n�Xg�@��݂��[@k�[P�thm wʚn� �nAX/�XW wʚn� �nAY�-����-(k��6��c��Y wʚn� �nAY�-����-(k��6�#M�@��a����[@e�[P�t(m wth/��[��>���?�_�-���`�0��t��-��/?~���O����?�[������O�|�q�g�}w����?��Y� ������L���>����t_��;���<vz�������Z��N�:��Ⱥ���IYs���� � �c'eͱZ��N�:��Ⱥ���IYs���� � �c'eͱZ��N�:��Ⱥ���IYs���� � �c'%�N�,;e��H�8>vR�;���|줬9vBk��IYs���c'�.@>vR�;���|줬9vBk��IYs���c'�.@>vR�;���|줬9vBk��IYs��^������IYs���� � �c'%�N�,;�<v"��c'eͱZ��Nʚc'�6����5�Nhm ;�<v"��c'eͱZ��Nʚc'�6����5�Nhm ;�<v"��c'eͱZ��Nʚc'�6����5�Nhm ;�<v"��c'eͱZ��NJ:���Y8>vR�;���|�d��؉�����5�Nhm ;)k����@>vR�;���|�d��؉�����5�Nhm ;)k����@>vR�;���|�d��؉�����5�Nhm ;)k����@>vR�;���|�d��؉����t;��p|줜9vBi��IYs���c'�.@>vR�;���|줬9vBk��IYs��^������IYs���� � �c'eͱZ��N�:��Ⱥ���IYs���� � �c'eͱZ��NF�c'r6���r;��p|줜9vBi�؉noı~�����e������X���o;���? ��i<s9vz�N�������Q�?�ç��O���o�O�����g�;��_����}֧���݉?xz��?�!>�������u{����;K�c:�X�-Y o�*k�h��@ޢU�lѢ���E��٢Eky��X�-Y o�*k�h��@ޢU�lѢ���E��٢Eky��X�-Y m�*�E���0ܢU±E�����rf�� �-Za�lтu���f�� �-Ze�-Z�[�ʚ-Z�6��h�unђu���f�� �-Ze�-Z�[�ʚ-Z�6��h�unђu���f�� �-Ze�-Z�[�ʚ-Z�6�h�4[��ln�*�آEe�x�V9�g����g(k��6��c�yY �ʚ<� �<CY�g����g(k��6��c�yY �ʚ<� �<CY�g����g(k��6��c�yY �ʚ<� �<CY�g����g(��3�Y8�3�2y)�y�r&�@i9�P��hm �ʚ<� �<�Xg�A��y��&�@k9�P��hm �ʚ<� �<�Xg�A��y��&�@k9�P��hm �ʚ<� �<CX/yXW �ʚ<� �<CY�g����g(��3�Y8�3�s�$]��g(k��6��eM���r����3��@�3�u�d]��g(k��6��eM���r����3��@�3�u�d]��g(k��6��eM���r����3��@�3�u�d]��g(k��6�%y:�y�r&�@i9�0֙g�ur����3��@�3�5yZ�y��&�@k9�0֙g�ur����3��@�3�5yZ�y��&�@k9�0֙g�ur����3��@�3�5yZ�y��&�@k9�0֙g�ub���#�@g�8�P��(m �ʚ<� �<�Xg�A��y��&�@k9�P��hm �ʚ<� �<CX/yXW �ʚ<� �<CY�g����g(k��6��c�yY �ʚ<� �<CY�g����g(k��6�#M�A��a���#�@e�8�P��(m ���<?ǖg�o!�����nў��zzy�<c<s�3g���Ǚg���᧟?\�ο�{��g�0����i��8=�_��3���ρO/����k�u{�������듳�gٺ�w�[��۳7� ܱ>u{����;֗���ߐ�u{���������Ydzl]�;����`�۳7� ܱ���)��� g�v�������ʹ={C���`���K�x��p�z���Һ={����[�f�۳7� �$NY�ġ�����L�Ⱥ�9�S�$qhm 'qʚ$� �$NY�ġ�����L�Ⱥ�9�S�$qhm 'qʚ$� �$NY�ġ�����L�Ⱥ�)�S�-�C�{&qJ8�84��8�L��r'��$�+��8eM��r��I���@N�5IZ�I���$����8eM��r��I���@N�5IZ�I���$����8eM��r��I���@N�5IZ�I��&�#g�0�Sʑġ�p��)g�8�6��8eM��rg�3�#��$NY�ġ����)k�8�6��8eM��rg�3�#��$NY�ġ����)k�8�6��8eM��rg�3�#��$NY�ġ����)k�8�6�8%I:�I�Q&�#e�8�S�$q(m 'qʚ$� �$NY�ġ�����L�Ⱥ�9�S�$qhm 'qʚ$� �$NY�ġ�����L�Ⱥ�9�S�$qhm 'qʚ$� �$NY�ġ���� �%�� +�$NY�ġ����)k�8�6�8%I:�I�q�$����8eM��r��I���@N�5IZ�I���$����8eM��r��I���@N�5IZ�I���$����8eM��r��I���@N�5IZ�I���$����8eM��b��#�Cg�8�S�$q(m 'q�:�8�.@N�5IZ�I��&�Ck9�S�$qhm 'q�:�8�.@N�5IZ�I��&�Ck9�S�$qhm 'q�:�8�.@N�5IZ�I��&�Ck9�S�$qhm 'q�:�8�.@L�t$q�,'qʙ$� �$NY�ġ�����L�Ⱥ�9�S�$qhm 'qʚ$� �$NY�ġ���� �%�� +�$NY�ġ����)k�8�6��8eM��rg�3�#��$NY�ġ����)k�8�6��8eM��bg�I���8L�r$q�,'qʙ$� �$n��RI~�-�{ߟ�'q���������t�E���_Po�����|���č��L���������?�a����~����?|�W���1�{�}=������z�S��������x��u��A>Zdzl]�;�����Z�goX�c}:ܿ���ʺ={�����kx�ݤ�n�ް6������kxp�<���c= �'iݞ�am����5��nRY�goX�c= Gkݞ�am�u���5ܽ8�x��p�z:���UZ�goX�c}:���Z�goX�c}9<�_�p���x8��n�8dz,]�;��w�d�۳7� ܱ���w?;ٺ={�����[x8I��� kwj���p���,[����5�?H��� kw�#�W���hm ��ʚ�� ��Xg�O��=����Gk��W���hm ��ʚ�� ��Xg�O��=����Gk��W���p��+gz~�6�{~c�=?Y ��ʚ�� �_Y���+kz~�6�{~c�=?Y ��ʚ�� �_Y���+kz~�6�{~c�=?Y ��ʚ�� �_Y���+kz~�6�{~c�=?Y ��ʹ��h|Þ_ GϏ��qϯ���Q�@������urϯ�����@���5=?Z�=����Gk��7���urϯ�����@���5=?Z�=����Gk��7���urϯ�����@���5=?Z�=����Gk��7����l��J9z~T�{~�LϏ�rϯ�����@���u��d]���+kz~�6�{~eMϏ�rϯ�����@���u��d]���+kz~�6�{~eMϏ�rϯ�����@���u��d]���+kz~�6�{~eMϏ�bϯ���Gg��7����l��ʙ�� �_Y���+kz~�6�{~c�=?Y ��ʚ�� �_Y���+kz~�6�{~c�=?Y ��ʚ�� �_Y���+kz~�6�{~a���`]���+kz~�6�{~eMϏ�bϯ���Gg��7���trϯ�����@���5=?Z�=����Gk��7���urϯ�����@���5=?Z�=����Gk��7���urϯ�����@���5=?Z�=����Gk��7���urϯ�����@���t���,��ʙ�� ��Xg�O��=����Gk��W���hm ��ʚ�� ��Xg�O��=����Gk��W���hm ��ʚ�� ��Xg�O��=����Gk��W���hm ��ʚ�� ��Xg�O��=�������_9���+kz~�6�{~c�=?Y ��ʚ�� �_Y���+kz~�6�{~a���`]���+kz~�6�{~eMϏ�rϯ�����@���u��d]���+kz~�6�{~eMϏ�rϯ�����@���4=?9�=�R�����_9�������ϱ��������s�e��}|=��u�W��K�|��۫/�=��������ο�;�M*K.��p���ϱ�ʲ����:�ʲ�p��*gRY�.@Le�u��lm ���:RY�6SYg�,[����&�E��T�YG*��b*�#�ek1�u֑ʲ����*kRY�.@Le�u��lm ���:RY�6SYg�,[����&�E��T�YG*��R*�[*���a*�#�ei1�U֤�h]���:�He��@Le�u��lm ���:RY�6SYeM*�������T�� �T�YG*��b*�#�ek1�U֤�h]���:�He��@Le�u��lm ���:RY�6SYeM*����s~Me��F��n�,���s�T�� �T�Xg*K������T�� �T�YG*��b*�#�ek1�U֤�h]���:�He��@Le�u��lm ���:RY�6SYeM*�������T�� �T�YG*��b*�#�ek)�Uґʢ�q��:�ʲ�p��:�HeY�@Le�u��lm ��ʚT�SYg�,[�����T�� �T�YG*��b*��IeѺ�1�u֑ʲ����:�He��@Le�u��lm ��ʚT�SYg�,[�����T�� �T�I�T����TV)G*���a*�#�ei1�u֑ʲ����:�He��@Le�5�,Z ���:RY�6SYg�,[�����T�� �TVY�ʢub*�#�ek1�u֑ʲ����:�He��@Le�u��d]���:�He��@Le�u��lm ��N����,��ʙT�SYg�,[�����T�� �T�YG*��b*��IeѺ�1�u֑ʲ����:�He��@Le�u��lm ��ʚT�SYg�,[�����T�� �T�YG*��b*��IeѺ�1�u֑ʲ����:�ʲ�p��:�HeY�@Le�5�,Z ���:RY�6SYg�,[�����T�� �TVY�ʢub*�#�ek1�u֑ʲ����:�He��@Le�5�,Z ���:RY�6SYg�,[�����T�� �TVY�ʢuR*�[*���a*�#�ei1�u֑ʲ����*kRY�.@Le�u��lm ���:RY�6SYg�,[�����T��+SYg�,[�����T�� �T�YG*��b*��IeѺ�1�u֑ʲ����:�He��@Le�u��lm ��J:RYt6�RY��RYVSY��,K��,���SY�_��.������XR��������ϯ�ʎg.�l^~���_~��O�n������?���x9�������y��g���C��o�}�+���q��r�v���ݟ������Nhm �:�<u"��S'eͩZȧNʚS'�6�O��5�Nhm �:�<u"��S'eͩZȧNʚS'�6�O��5�Nhm �:�<u"��S'eͩZȧNʚS'�6O��t�:��px�d�9u"e���I9s���� � �S'eͩZȧN�:O�Ⱥ���IYs���� � �S'eͩZȧN�:O�Ⱥ���IYs���� � �S'eͩZȧN�z9u� +�S'eͩZȧNʚS'�6O��t�:��p|�d��ԉ��O��5�Nhm �:)kN���@>uR֜:���|�d��ԉ��O��5�Nhm �:)kN���@>uR֜:���|�d��ԉ��O��5�Nhm �:)kN���@>uR֜:���|�d��ԉ��O��5�Nhm �:)�8uBg���I9s���S'�.@>uR֜:���|꤬9uBk��IYs���S'�.@>uR֜:���|꤬9uBk��IYs���S'�.@>uR֜:���|꤬9uBk��IYs���S'�.@<uR�q����r�� � �S'eͩZȧN�:O�Ⱥ���IYs���� � �S'eͩZȧN�z9u� +�S'eͩZȧNʚS'�6�O��5�Nhm �:�<u"��S'eͩZȧNʚS'�6�O��5�Nhm �:iN���8<uR�q����r�� � �S'���N�9�S��wE��N���������t�����_Po�������:���LN�N���������������~w������?�y\[ry�w�����_��v�0g���Ι�wwf����u�.@�YW�̬���<����YGkyf]Y3����̺�Ιu�.@�YW�̬���<����YGkyf]Y3����̺�Ιu�.@�YW�̬���8���cf���u���:J�3��:g�ɺ�yf]Y3����̺�ff� �ue��:Z�3��:g�ɺ�yf]Y3����̺�ff� �ue��:Z�3��:g�ɺ�yf]Y3����̺�ff� �ue��:Z�3��:g�ɺ�if]9��u4���̺��u4�g֕33�(m Ϭ�ef�+�g֕53�hm Ϭ+kf���@�YW�̬���<�n�sf���g֕53�hm Ϭ+kf���@�YW�̬���<�n�sf���g֕53�hm Ϭ+kf���@�YW�̬���8�n��Y'g�pf])��:*�3�ʙ�� ��PY������lɺ��=Tִ�hm ��ʚ�� ��PY������lɺ��=Tִ�hm ��ʚ�� ��PY������lɺ��=Tִ�hm ��ʚ�� ��PIG{���a{h�iI�8n�3�!J�����=Dk�=Tִ�hm ���:�C�.@n�5�!Z�����=Dk�=Tִ�hm ���:�C�.@n�5�!Z�����=Dk�=Tִ�hm ���zi���=Tִ�hm ��ʚ�� ��PIG{���q{h��=$���PY�����*k�C�6��CeM{��r{h��=$���PY�����*k�C�6��CeM{��r{h��=$���PY�����*k�C�6��CeM{��r{h��=$���PY�����*�h�Y8n�3�!J����������CeM{��r{��i��@n�5�!Z����������CeM{��r{��i��@n�5�!Z����������CeM{��r{��i��@n�5�!Z���������C%�!:���r�=Di�=Tִ�hm ���:�C�.@n�5�!Z�����=Dk�=Tִ�hm ���zi���=Tִ�hm ��ʚ�� ��PY������lɺ��=Tִ�hm ��ʚ�� ��PY�����i�Cr6�C��!*���r�=Di�=�o�T{��ck߇~�����������Sh�?u����G�z��>�x&�l�����Ͽ������?�=�}����_�|�������7��퇟�ᷟ�|w�v���ݗ�>��1y8<���v���1K||~��S���I*�w&��ǏJ���� +���+eM���r����p��@�p�5Z���� +���+eM���r����p��@�p�5Z���� +���+eM���r����p��@�p�5Z���� +���*��*4��a�����Ac��Q�T8(m W8�z�p����Q�T8hm W8ʚ � � -GYSᠵ�\�(k*�6�+c�Y W8ʚ +GYSᠵ�\��pȺ���Q�T8hm W8ʚ � � -GYSᠵ�\�(k*�6+#M�C��a�����Ae��Q�T8(m W8ʚ +GYSᠵ�\��pȺ���Q�T8hm W8ʚ � � -�Xg�C������Ak��Q�T8hm W8ʚ +GYSᠵ�X�i*r6+�*��r��Ai��Q�T8hm W8�:+�.@�p�5Z�����Ak��Q�T8hm W8�:+�.@�p�5Z�����Ak��Q�T8hm W8�:+�.@�p�5Z�����Ak��Q�QᠳpX�e*R6�+�L���r����p��@�p�5Z���� +���+eM���r����p��@�p�5Z���� +���+eM���r����p��@�p�5Z���^*��@�p�5Z�����Ak��Q�Qᠳp\��pH����Q�T8hm W8ʚ � � -�Xg�C������Ak��Q�T8hm W8ʚ +GYSᠵ�\��pȺ���Q�T8hm W8ʚ � � -�Xg�C������Ak��Q�T8hm V8J:*t+�L�C��q����pP�@�p�5Z�����Ak��1�Y�ur����p��@�p�5Z�����Ak��1�Y�ur����p��@�p�5Z�����Ak���s�������Ak��Q�T8hm V8J:*t�+�I W8ʚ +GYSᠵ�\��pȺ���Q�T8hm W8ʚ � � -GYSᠵ�\�(k*�6�+c�Y W8ʚ -� � -GYSᠵ�\�(k*�6�+c�Y W8ʚ -� � -GYSᠵ�\�(k*�6�+c�Y W8ʚ -� � -GIG����q����pP�@�p�uV8d]�\�(k*�6�+eM���r����p��@�p�uV8d]�\�(k*�6�+eM���r����p��@�p�uV8d]�\�(k*�6�+eM���r����p��@�p�uV8d]�X�(�p�Y8�p�3J�����Ak��1�Y�ur����p��@�p�5Z�����Ak���s�������Ak��Q�T8hm W8ʚ -� � -�Xg�C������Ak��Q�T8hm W8ʚ -� � -�HSᐳqX�(�pPY8�p�3J��~*�*�[�s��W8���|��7������3�p���6���������O_>����pxy?s9�?�����5_���������C����s<���G����u{����;�����o��u{�����/��Ggͳh]�;�����,�۳7� ܱ�����Z)��� kw����h�۳7� �n=����Wgϲu�XN��y������XO~y������X_����7�����?�2��,K����<[��� kw����� [�goX�co�Tּb� �WL�|�$Y �bRY�I�6�_1��y�$Zȯ�Tּb� �WL�|�$Y �bRY�I�6�_1��y�$Zȯ�Tּb� �WL�|�$Y �bRY�I�6_1��#nGg�8nW���(m ���:�v�.@�ە5q;Z�q��&nGk9nW���hm ���:�v�.@�ە5q;Z�q��&nGk9nW���hm ���:�v�.@�ە5q;Z�q��&nGk9nW���hm ���:�v�.@�ەs���x ø] G��qܮ���Q�@�ۅ���urܮ�����@�ە5q;Z�q��&nGk9n7���urܮ�����@�ە5q;Z�q��&nGk9n7���urܮ�����@�ە5q;Z�q��&nGk1n7����l��J9�vT��v�L�rܮ�����@�ۍu��d]��+k�v�6��veM�rܮ�����@�ۍu��d]��+k�v�6��veM�rܮ�����@�ۍu��d]��+k�v�6��veM�bܮ�#nGg�0n7����l��ʙ�� �]Y�����+k�v�6��vc�q;Y ��ʚ�� �]Y�����+k�v�6��vc�q;Y ��ʚ�� �]Y�����+k�v�6��va=��`]��+k�v�6��veM�bܮ�#nGg�8n7���trܮ�����@�ە5q;Z�q��&nGk9n7���urܮ�����@�ە5q;Z�q��&nGk9n7���urܮ�����@�ە5q;Z�q��&nGk9n7���urܮ�����@�ەt���,��ʙ�� ��Xg�N��q��&nGk9nW���hm ��ʚ�� ��Xg�N��q��&nGk9nW���hm ��ʚ�� ��Xg�N��q��&nGk9nW���hm ��ʚ�� ��Xg�N��q�������]9�����+k�v�6��vc�q;Y ��ʚ�� �]Y�����+k�v�6��va=��`]��+k�v�6��veM�rܮ�����@�ۍu��d]��+k�v�6��veM�rܮ�����@�ۍ4q;9�q�R�����]9�����S�-�v�[�~Y�?�����㯌�O��|;}���3���G�����������>�u�����������}'k�>���������>�G��(;��|8���]�ܞ�!m�����pg�۳7� ܱ�^����� kwV�������x��p�:f�5�hm �2(kv��@�eP��2����� ��]��@�eP��2����ˠ��e@ky�AY�ˀ��.���]�.@�eP��2����ˠ��e@kq�AI�.:ǻ�9wH��y�AY�ˀ��.��f�� �]e�.ZȻ�:wȺ�y�AY�ˀ��.��f�� �]e�.ZȻ�:wȺ�y�AY�ˀ��.��f�� �]e�.ZȻ�:wȺ�y�AY�ˀ��.���]t�w�3�(m �2��e ��]e�.ZȻʚ]�6�w�5�hm �2��e ��]e�.ZȻʚ]�6�w�5�hm �2��e ��]e�.ZȻʚ]�6�w�5�hm �2��e ��]��v�x �]%�h,�2(gvP�@�e��.XW �2(kv��@�eP��2����ˠ��e@ky��X�.Y �2(kv��@�eP��2����ˠ��e@ky��X�.Y �2(kv��@�eP��2����ˠ��e@kq��H��@���.�R�]T�w�3�(m �2(kv��@�e0ֹ�@�Ȼʚ]�6�w�5�hm �2(kv��@�e0ֹ�@�Ȼʚ]�6�w�5�hm �2(kv��@�e0ֹ�@�Ȼʚ]�6�w�5�hm �2(��e@g�p��(��@���.�rf�� �]e�.ZȻʚ]�6�w�u�2�u�.��f�� �]e�.ZȻʚ]�6�w�u�2�u�.��f�� �]e�.ZȻʚ]�6�w������Ȼʚ]�6�w�5�hm �2(��e@g�x��8�.I �2(kv��@�eP��2����ˠ��e@ky��X�.Y �2(kv��@�eP��2����ˠ��e@ky��X�.Y �2(kv��@�eP��2����ˠ��e@ky��X�.Y �2(kv��@�ePұˀ���.�rf�� �]c��d]��ˠ��e@ky�AY�ˀ��.��f�� �]c��d]��ˠ��e@ky�AY�ˀ��.��f�� �]c��d]��ˠ��e@ky�AY�ˀ��.��f�� �]c��d]��ˠ�c����]��.JȻʚ]�6�w�u�2�u�.��f�� �]e�.ZȻʚ]�6�w������Ȼʚ]�6�w�5�hm �2(kv��@�e0ֹ�@�Ȼʚ]�6�w�5�hm �2(kv��@�e0��2��q�ˠ�c����]��.JȻ�kj�?Ƕ�p9���˰�9�x{<}��2�_�?x|8<~�9�p��/O��P�9�2�2�?����O��|9�����������������/_~�v��~ty������p��z>���?Og/>�������hm ��*kNg��@>�U֜��|:k��t���Og�5��hm ��*kNg��@>�U֜��|:k��t���Og�5��hm ��*kNg��@>�U֜��x:k�9�%g��tV)��,*ǧ�ʙ�Y�6�Og�5��hm ���<�%���Ye��,Zȧ�ʚ�Y�6�Og�5��hm ���<�%���Ye��,Zȧ�ʚ�Y�6�Og�5��hm ���<�%���Ye��,Zȧ�ʚ�Y�6Og�t��px:k�9�%e��tV9s:���鬲�t� ��Ye��,Zȧ��:Ogɺ��tVYs:���鬲�t� ��Ye��,Zȧ��:Ogɺ��tVYs:���鬲�t� ��Ye��,Zȧ��z>�� -��Ye��,Zȧ�ʚ�Y�6Og�t��p|:k��t���Og�5��hm ��*kNg��@>�U֜��|:k��t���Og�5��hm ��*kNg��@>�U֜��|:k��t���Og�5��hm ��*kNg��@>�U֜��|:k��t���Og�5��hm ��*�8�Eg��tV9s:���鬱��Y�.@>�U֜��|:��9�Ek�tVYs:���鬱��Y�.@>�U֜��|:��9�Ek�tVYs:���鬱��Y�.@>�U֜��|:��9�Ek�tVYs:���鬱��Y�.@<�U�q:�����r�t� ��Ye��,Zȧ��:Ogɺ��tVYs:���鬲�t� ��Ye��,Zȧ��z>�� -��Ye��,Zȧ�ʚ�Y�6�Og�5��hm ���<�%���Ye��,Zȧ�ʚ�Y�6�Og�5��hm ��iNg��8<�U�q:�����r�t� ����KOu:��c;���S�?����+�N`w���J��LNg���?|���oD:�����3g��_��ӟ,v�h�|<<|��s���C���㫙�N��k�u{����;��/����n�ް6p��zx}��iʺ={����֗���$��Y�.���kx|������XO_���NS�����Xǫ��5�Dk�]�F�w��q�.@�̻�Q�@~���]�hm �PY�.@�6��h��]�d]��.@eͻ���@~���]�hm �PY�.@�6��(��w�u���5�Dk�]�ʚw����.@eͻ���@~���w�u���5�Dk�]�ʚw����.@%�Dg��]��9�H���Tּ� �w*k������5�Dk�]��:�H���Tּ� �w*k������5�Dk�]��:�H���Tּ� �w*k������5�Dk�]��:�H���Tּ� �w*�x :��Tμ� �w�| Y �PY�.@�6����y Z��Tּ� �w�| Y �PY�.@�6����y Z��Tּ� �w�| Y �PY�.@�6����y Z��Tּ� �w�| Y �P9�w����T��.@4����y J���� XW �(kM��@4Q�����<h��4Aky��X� Y �(kM��@4Q�����<h��4Aky��X� Y �(kM��@4Q�����<h��4Akq��H3hB��᠉R�AT�M�3�&(m �(kM��@41�9hB�ȃ&ʚA�6�M�5�&hm �(kM��@41�9hB�ȃ&ʚA�6�M�5�&hm �(kM��@41�9hB�ȃ&ʚA�6�M�5�&hm �(�4Ag�p��(3hB���rf�� �Ae͠ Zȃ&ʚA�6�M�u��uf�� �Ae͠ Zȃ&ʚA�6�M�u��uf�� �Ae͠ Zȃ&ʚA�6�M��<h�ȃ&ʚA�6�M�5�&hm �(�4Ag�x��8� I �(kM��@4Q�����<h��4Aky��X� Y �(kM��@4Q�����<h��4Aky��X� Y �(kM��@4Q�����<h��4Aky��X� Y �(kM��@4Q�1h����rf�� �Ac��&d]�<h��4Aky�DY3h��f�� �Ac��&d]�<h��4Aky�DY3h��f�� �Ac��&d]�<h��4Aky�DY3h��f�� �Ac��&d]�8h��c����A�̠ Jȃ&ʚA�6�M�u��uf�� �Ae͠ Zȃ&ʚA�6�M��<h�ȃ&ʚA�6�M�5�&hm �(kM��@41�9hB�ȃ&ʚA�6�M�5�&hm �(kM��@41����q8h��c����A�̠ Jȃ&��!M�sl�&��!���&��c4��1hr|<ܽ���x&�&���&�k�����ϟ~��x�l�gɵu��_�s�M2��Ň�Ͼ?~Ⱦ��9�V�d�hm g�ʚ�� ��[Y�}����}�̾ɺ�9�V�d�hm g�ʚ�� ��[IG����q�m�3�&���[Y�}����}+k�o�6��oeM���r�m�3�&���[Y�}����}+k�o�6��oeM���r�m�3�&���[Y�}����}+k�o�6��oeM���r�m�3�&���[Y�}����}+�Ⱦ�Y8ξ�3�7J�ٷ��웬��oeM���r���ɾ��@ξ�5�7Z�ٷ��웬��oeM���r���ɾ��@ξ�5�7Z�ٷ��웬��oeM���r���ɾ��@ξ�5�7Z�ٷ��웬��o�ܲo4^�0�V}��p�}+g�o�6��oa=g�`]��}+k�o�6��oeM���r���ɾ��@ξ�uf�d]��}+k�o�6��oeM���r���ɾ��@ξ�uf�d]��}+k�o�6��oeM���r���ɾ��@̾�4�79�ٷR������[9�}����}+k�o�6��oc��7Y g�ʚ�� ��[Y�}����}+k�o�6��oc��7Y g�ʚ�� ��[Y�}����}+k�o�6��oc��7Y g�ʚ�� ��[Y�}����}+�Ⱦ�Y8̾�2�7)�ٷr&�Fi9�V�d�hm g�ʚ�� ���Xg�M��ٷ�&�Fk9�V�d�hm g�ʚ�� ���Xg�M��ٷ�&�Fk9�V�d�hm g�ʚ�� ��[X��7XW g�ʚ�� ��[Y�}����}+�Ⱦ�Y8ξ�sf�$]��}+k�o�6��oeM���r���ɾ��@ξ�uf�d]��}+k�o�6��oeM���r���ɾ��@ξ�uf�d]��}+k�o�6��oeM���r���ɾ��@ξ�uf�d]��}+k�o�6�o%�7:�ٷr&�Fi9�6֙}�ur���ɾ��@ξ�5�7Z�ٷ�&�Fk9�6֙}�ur���ɾ��@ξ�5�7Z�ٷ�&�Fk9�6֙}�ur���ɾ��@ξ�5�7Z�ٷ�&�Fk9�6֙}�ub���#�Fg�8�V�d�(m g�ʚ�� ���Xg�M��ٷ�&�Fk9�V�d�hm g�ʚ�� ��[X��7XW g�ʚ�� ��[Y�}����}+k�o�6��oc��7Y g�ʚ�� ��[Y�}����}+k�o�6�o#M�M��a���#�Fe�8�V�d�(m g�0��?ǖ}_6�O�����������Y�}�Տ�ǯ?�?'���<sξ�#���_>m���>���_?}��Ͽ���o�������-$?[v<��=��2����S�k��O�M���5=Y _�+k����@��W�\ӣ��|M����Gk���X�5=Y ]�+�vM��K^�+ḦGc���^9sM���5���������^YsM���5���� �kze�5=Z����:��ɺ���^YsM���5���� �kze�5=Z����:��ɺ���^YsM���5���� �kze�5=Z���F�kzr6��r\ӣ�p|M����Gi��^YsM���5���kz�.@��W�\ӣ��|M����Gk��^YsM���5���kz�.@��W�\ӣ��|M����Gk��^YsM���5���kz�.@��W�\ӣ��|M����Gk�^I�5=:���F�kzR6���3��(m _�+k����@��W�\ӣ��|Mo����5��hm _�+k����@��W�\ӣ��|Mo����5��hm _�+k����@��W�\ӣ��|M/��kz��@��W�\ӣ��|M����Gk�^I�5=:����9��I����^YsM���5���� �kze�5=Z����:��ɺ���^YsM���5���� �kze�5=Z����:��ɺ���^YsM���5���� �kze�5=Z����:��ɺ���^YsM���5���kzt���3��(m _�뼦'��kze�5=Z���ʚkz�6���5��hm _�뼦'��kze�5=Z���ʚkz�6���5��hm _�뼦'��kze�5=Z���ʚkz�6���5��hm _�뼦'��kz%���,_�+g��Q�@��W�\ӣ��|Mo����5��hm _�+k����@��W�\ӣ��|M/��kz��@��W�\ӣ��|M����Gk��^YsM���5���kz�.@��W�\ӣ��|M����Gk��^YsM���5��暞���kz����,_�+g��Q�@���?W���9�k�����k��ϱ\���5�����g�^���5��zM�����wǧo?����_O$��P~�5|xy�;��3�#�ˏ��ƌ+�c���,�1�9�3X�@|c���h]���go�`k��:ޘ���3�u�1�� �7f(kޘ���o�p����6ߘ��lm �1�YG���b㣬i|к���q��������8�h|��@l|�u4>lm 6>ʚ��������F��n����s�Ƈ� ���Xg�C������Ƈ� ���YG���b�㬣�ak��Q�4>h]���8�h|��@l|�u4>lm 6>�:�6eM�������Ƈ� ���YG���b�㬣�ak��Q�����q��8�����p��8�h|X�@l|�u4>lm 6>ʚ��g�[�����Ƈ� ���YG���b㣬i|к���q��������8�h|��@l|�u4>lm 6>ʚ��g�[�����Ƈ� ���I�Ƈ����G)G���a�㜣�ai��q��������8�h|��@l|�5�Z 6>�:�6g�[�����Ƈ� ��GY���ub�㬣�ak��q��������8�h|��@l|�u6>d]���8�h|��@l|�u4>lm 5>N�5>�,6>ʙ��g�[�����Ƈ� ���YG���b㣬i|к���q��������8�h|��@l|�u4>lm 6>ʚ��g�[�����Ƈ� ���YG���b㣬i|к���q��������8�����p��8�h|X�@l|�5�Z 6>�:�6g�[�����Ƈ� ��GY���ub�㬣�ak��q��������8�h|��@l|�5�Z 6>�:�6g�[�����Ƈ� ��GY���uR��[����a�㜣�ai��q��������(k�.@l|�u4>lm 6>�:�6g�[�����Ƈ�+g�[�����Ƈ� ���YG���b㣬i|к���q��������8�h|��@l|�u4>lm 5>J:t6���V��K���)��_���f����������p�Ƿ����Ey���4>O���_������?}��~m|~Y?����/_���||G�����/�������72�9�C����9���p��t�|<Ϣu�X/�Һ={���������ʺ={�����k8Z��� k�[������>Zdzl]�;և��ޤu{����;���o�u{����;��ó���� g�+���9dz,]�;��w�l�۳7� ܱ����?˲u{����;�ӷ���eݞ�am�u���kx���,[����5�?J��� kw����(��goX�c=} wֺ={��������7�cn<���c}8<��8����X�w/ֺ={��������Yx<{����4��5<�8�Y�.����5�7Z�巒������[9S~���\~�,�ɺ���V֔�hm ��ʚ�� ��[YS~���\~�,�ɺ���V֔�hm ��ʚ�� ��[YS~���\~�,�ɺ���V֔�hm ��ʚ�� ��[YS~���\~�,�ɺ���Vέ�F�%�o%�7��r��Fi���s� ��已��Fk��V֔�hm ��ʚ�� ���Xg�M��已��Fk��V֔�hm ��ʚ�� ���Xg�M��已��Fk��V֔�hm ��ʚ�� ���HS~��qX~+�(�QY8.��3�7J�已��Fk��6�Y~�ur���)���@.��5�7Z�已��Fk��6�Y~�ur���)���@.��5�7Z�已��Fk��6�Y~�ur���)���@.��5�7Z�巒�������(S~��q\~+g�o�6��oeM���r���)���@.��u��d]�\~+k�o�6��oeM���r���)���@.��u��d]�\~+k�o�6��oeM���r���)���@.���\~�ur���)���@.��5�7Z�巒�������8g�M��已��Fk��V֔�hm ��ʚ�� ���Xg�M��已��Fk��V֔�hm ��ʚ�� ���Xg�M��已��Fk��V֔�hm ��ʚ�� ���Xg�M��已��Fk��V�Q~��p\~+g�o�6��oc��7Y ��ʚ�� ��[YS~���\~+k�o�6��oc��7Y ��ʚ�� ��[YS~���\~+k�o�6��oc��7Y ��ʚ�� ��[YS~���\~+k�o�6��oc��7Y ��J:�ot��o�L���r���)���@.��u��d]�\~+k�o�6��oeM���r���)���@.���\~�ur���)���@.��5�7Z�已��Fk��6�Y~�ur���)���@.��5�7Z�已��Fk��6Ҕ��l��J9�oT��o�L���r��0��?�V~_f�/�����X��x��v��o=�_���s�}��?����O������?�)o{���������;~��_����>�y+lϟ`�����������.�̓?���ݏNv���dWYs����ɮ��d� �]e��.Z�'��:Ovɺ��dWYs����ɮ��d� �]e��.Z�'��:Ovɺ��dWYs����ɮ��d� �]e��.Z�'�F��]r6Ov�r�좲p|���9�Ei�dWYs����ɮ�Γ]�.@>�U֜좵�|���9�Ek�dWYs����ɮ�Γ]�.@>�U֜좵�|���9�Ek�dWYs����ɮ�Γ]�.@>�U֜좵�|���9�Ek�dWI��.:�'�F��]R6�Ov�3'�(m ��*kNv��@>�U֜좵�|�k��d���Ov�5'�hm ��*kNv��@>�U֜좵�|�k��d���Ov�5'�hm ��*kNv��@>�U֜좵�|�+��]��@>�U֜좵�|���9�Ek�dWI��.:�'��9OvI���dWYs����ɮ��d� �]e��.Z�'��:Ovɺ��dWYs����ɮ��d� �]e��.Z�'��:Ovɺ��dWYs����ɮ��d� �]e��.Z�'��:Ovɺ��dWYs����ɮ���]t�Ov�3'�(m ���<�%��]e��.Z�'�ʚ�]�6�Ov�5'�hm ���<�%��]e��.Z�'�ʚ�]�6�Ov�5'�hm ���<�%��]e��.Z�'�ʚ�]�6�Ov�5'�hm ���<�%�ē]%'��,��*gNvQ�@>�U֜좵�|�k��d���Ov�5'�hm ��*kNv��@>�U֜좵�|�+��]��@>�U֜좵�|���9�Ek�dWYs����ɮ�Γ]�.@>�U֜좵�|���9�Ek�dWYs����ɮ��d���Ó]�'��,��*gNvQ�@>�ݿ/U'��9����������ϱ�����˚�N��}�5�gr��<v�����~���>�����p��[�3��/����/���������>�x��}��N�tx���9>J�G�ٸ����x������X�wֺ={����������n�ް6���x������gٺ�w���kݞ�am�����_�Giݞ�am��u��LY�65�6�ߦ&�緩�u��Ԕ5oSCk�mjʚ������65e�����@~���η��u��Ԕ5oSCk�mjʚ������65%oSCg��mj�9ߦF��oSSּM � ䷩)kަ����Ԕ5oSCk�mj�:ߦF��oSSּM � ䷩)kަ����Ԕ5oSCk�mj�:ߦF��oSSּM � ䷩)kަ����Ԕ5oSCk�mj�:ߦF��oSSּM � ķ�)�x�:�oSSμM � ䷩�|�Y �MMY�65�6�ߦ��y�Z�oSSּM � ䷩�|�Y �MMY�65�6�ߦ��y�Z�oSSּM � ䷩�|�Y �MMY�65�6�ߦ��y�Z�oSSּM � ䷩�|�Y �MM9������oSS��654�ߦ���f@iy�AX��`]�<͠��f@ky�AY3̀��4��f�� �ic��d]�<͠��f@ky�AY3̀��4��f�� �ic��d]�<͠��f@ky�AY3̀��4��f�� �i#�49��J9�PY8�fP�L3���<͠��f@ky��X�4Y O3(k���@�fP�L3���<͠��f@ky��X�4Y O3(k���@�fP�L3���<͠��f@ky��X�4Y O3(k���@�fP�L3���8͠�c����i��4)��ʙi�6���5�hm O3(k���@�f0�9�@���ʚi�6���5�hm O3(k���@�f0�9�@���ʚi�6���5�hm O3(k���@�f��4XW O3(k���@�fP�L3���8͠�c����i��$]�<͠��f@ky�AY3̀��4��f�� �ic��d]�<͠��f@ky�AY3̀��4��f�� �ic��d]�<͠��f@ky�AY3̀��4��f�� �ic��d]�<͠��f@kq�AI�4:��ʙi�6���uN3�u�4��f�� �ie�4Z��ʚi�6���uN3�u�4��f�� �ie�4Z��ʚi�6���uN3�u�4��f�� �ie�4Z��ʚi�6���uN3�u�4���it���3�(m O3(k���@�f0�9�@���ʚi�6���5�hm O3(k���@�f��4XW O3(k���@�fP�L3���<͠��f@ky��X�4Y O3(k���@�fP�L3���<͠��f@kq��H3�@���4�R�iT���3�(m O3�ڀ�f�ϱM3\� �O3���_�?����d;�G����4������������0?�����g���z�������O�����.�ݝ���-����l��+�z��i�d|�L&\|��Ʉ�&P�@�LP�L&���<����L@ky2�X�dY O&(k&��@�LP�L&���<����L@ky2AXϓ `]�<����L@ky2AY3����d��f2� ��c�� d]�<����L@ky2AY3����d����t�'�sN&�t�d��f2� ��e�dZȓ ʚ��6�'�uN&�u�d��f2� ��e�dZȓ ʚ��6�'�uN&�u�d��f2� ��e�dZȓ ʚ��6�'�uN&�u�d��f2� ��%� �,O&(g&P�@�L0�9�@�ȓ ʚ��6�'�5� hm O&(k&��@�L0�9�@�ȓ ʚ��6�'�5� hm O&(k&��@�L0�9�@�ȓ ʚ��6�'�5� hm O&(k&��@�L0�9�@�H� ʹM&���� J8&�X8�LP�L&���<� �����@�LP�L&���<����L@ky2AY3����d�����.@�LP�L&���<����L@ky2AY3����d�����.@�LP�L&���<����L@ky2AY3����d��f2������� �,O&(g&P�@�LP�L&���<�`�s2���'�5� hm O&(k&��@�LP�L&���<�`�s2���'�5� hm O&(k&��@�LP�L&���<�`�s2���'�5� hm O&(k&��@�LP�1�����d�Qf2�������dJȓ ʚ��6�'�5� hm O&�L ���e�dZȓ ʚ��6�'�5� hm O&�L ���e�dZȓ ʚ��6�'�5� hm O&�y2�+�'�5� hm O&(k&��@�LP�1�����d�q���.@�LP�L&���<����L@ky2AY3����d�����.@�LP�L&���<����L@ky2AY3����d�����.@�LP�L&���<����L@ky2AY3����d�����.@�LP�L&���8���c2������dJȓ �:'Ⱥ�y2AY3����d��f2� ��e�dZȓ �:'Ⱥ�y2AY3����d��f2� ��e�dZȓ �:'Ⱥ�y2AY3����d��f2� ��e�dZȓ �:'Ⱥ�q2AI�d:Ǔ ʙ��6�'�5� hm O&�L ���e�dZȓ ʚ��6�'�5� hm O&�y2�+�'�5� hm O&(k&��@�LP�L&���<�`�s2���'�5� hm O&(k&��@�LP�L&���8�`��L g�p2A)�d*Ǔ ʙ��6�'(�� �9�Ʉ��q��;���9�������m2��3��:�_o��3̇����6�p<,�_���~���������/?��ӗ�������$]�8�ӷ���Kw.��?��ϟu�K��) K&e�8J��$��q\$e�dR�sd�L�L��a�l�#E&�%�Cd!�2��Q&B&e�8A6�Ȥ,��F�������X(g{��qyl� �IY8Ύ�2�1)�ͱQ&9&e�88����q\ebcR�Sc�LiL��qgl�ɌIY8���r6Ơl�F�����ü�G]L�K��F������X(gW��qUl���IY8N��2E1)�=�Q&'&e�8&����q\eBbR�3b�LEL��qCl�I�IY8��r�àl��F�x����t�(S��p� e�aR��a���0(GŰn�0�.P�ۨ�Iw �V�� -��p -�V�;�}��J�( ��p�e -aR��`�LL��q,�� e�6ʄ��,g�F�*����&�(���p��A�8���210)�)�Q�&e�6�d��,F�����F�L�K�F��������(����p� -��~A�8�~�2�/)�ɯQ��%e��5�侤,ǾB9[_P6�K_�L�K��q�k��|IY8n|�2�/)ǁ�Pξ����(���p��e�^R�^cY/ /a� -_�^���^#L�K��q�k��yIY8ny�2)/)�!�PΎ����(�p��e -^R��]�L�K��q�+���e��5ʄ��,g�F�j����f�(�쒲p��V�{�}��Z�(뒲p��eJ]R;]c�. /a� -�lt��8.t�2�.)�y�Q��%e��5ʤ��,��B9�\P6��\�L�K��q�k�)rIY8�q�29.)�1�P�����(⒲p��e*\R�\�L�K��q�+���e㸾5�ķ�,���8�[^¸�5�d�d,G�B9�[P6��[�LpK��qnk��mIY8nm�2�-)ǡ�P�������(ْ�p��e -[R��Z�L^K��q\+���e㸬5ʄ��,g�F�������(�Ԓ�p� -��iA�8�i�qĴ$��qJk�)i�X8�h�2-)��PΆ����(В�p��e�YR��Y�L:K��q8{[y�f����Y�L4K��q2k�)fIY8�e�2�,)DZ�P�V���R�(ʒ�p��e*YR�Y�L"K��a +��cAX0�c�oı仄qk�)c�X8�bw�N��҇ت��g�(v�C\4�����&��g��7�b�#[{?�����_���׃�����vgѕ"�������w0���`�����`��A��hm ��YX��`� -�w0+k�����;��5�3Zȭ��&vFk9w6��;�ur�I���@���5�3Z�ݳ��������8g�L�����&Fk9�V��hm 7�ʚ� ��XgM��%��&�Fk9�V���hm ��ʚ � �$�XgM��U��&�Fk9�V֔�hm ��ʚ8� �<�XgM�ȅ��&�Fk1�V�QI��p�I+gBi�6�Sic��4Y ��ʚ\� �`ZYSL����L+k�i�6��ic��4Y ��ʚt� �xZYSO����O+kj�6�jc� 5Y W�ʚ�� �ZYSR����R+kbj�6�sjc�=5Y �ʹ%�h��aT����FcḫV΄�(m ���zn�����V���hm �ʚ�� ��ZYY����Y��ɺ���V֤�hm ��ʚ�� ��ZY\����\�l�ɺ���V�d�hm ��ʚ�� ��ZY_����_i�kr6l� 6*��r��Fi��Vք�hm ���:[l�.@���596Z�A����Fk��V�D�hm g��:�l�.@.��5i6Z�q����Fk��V��hm '��:m�.@���5�6Zȡ����Fk��V�k��p�kezmR6��m�L���r�������@5�6Z�鶱�v����meM���r���)���@n��57Z���Ύ���KneMʍ�r̭�����@5A7Z�I����n��@���5Y7Z�a����Fk��V�w��p�w��I����V�$�hm G�ʚ�� ��[Yz����z�l�ɺ���V���hm �ʚ�� ��[Y}����}��ɺ���V֤�hm ��ʚ�� ��[Y�������l�ɺ��W�d�hm ��J:Jpt�[p�L��rn��'��"\Y������+k�p�6��peM��rn�� '��:\Y������+k -q�6�qeM$��r&n��'��R\Y������+kjq�6�{qeM0��r2n��'��j\IG6���q8��)�Q�@nǕ5�8Z�����~���reMB��rD������@�ȕ5!9Z�)���[r��@�ɕ599Z�A���(Gk�)W�D�hm g��:�r�.@.˕5i9Z�q���.Gk�/W��hm &�F�Ɯ����\)Gf���qh��)�Q�@n���i����j�˼�������E����{��>���u���Jl�z����y������~����_���O�?��>��wǻo����F������<�C���5���WR��ݗ3�o�?�<t����7]� �}Z �M�:�&�6��&'��&v�&�}K�}���oB�ľ�YG���b�䬣obk�or��7����7)k�&�.@웜u�Mlm �M�:�&�6�&g}[�}���oB�ľ�YG���b�䬣obk�or��7����7)k�&�.@蛜�k���K�MN��Ml,�M�9�&�6�&c�}YW �M�:�&�6�&g}[�}������ ľIY�7�ub�䬣obk�or��7����79����@월5}Z �M�:�&�6�&g}[�}������ ��IIG߄��Q��[����a�䜣obi�or��7����7)k�&�.@웜u�Mlm �M�:�&�6�&g}[�}���oB�ľ�YG���b�䬣obk�or��7����7)k�&�.@웜u�Mlm �M�:�&�6��&'��&v��&�}*�}�s���� ľ�YG���b�䬣obk�oR��Mh]��79��������;h��<�+�W8�B�pq��#�U��*�e���2�(�����i���_�,,ed'���1i�}�{�or��X�A웜��&V{�&��oBub����7�ڃ�79u�M�� �MN]}�=�}�Qw�D�ľɩ�ob��or��X�A�z�ج9월�� �1�}�SW��jb����7�ڃ�79u�M�� �MJM߄�ľɩ�ob��or��X�A웜��&V{�&��oBub����7�ڃ�79u�M�� �MN]}�=�}�R�7�:�or��X�A�z�ج9웜��&F{�&��oBub����7�ڃ�79u�M�� �MN]}�=�}�R�7�:�or��X�A웜��&V{�&�����ľI��P��79u�M�� �MN]}�=�}�SW��jbߤ��M��A�z�ج9웜��&F{�&�����ľI��P��79u�M�� �MN]}�=�}�SW��jb�d��7�:�or��X�A웜��&V{�&�����ľI��P��79u�M�� �MN]}�=�}�SW��jRߤ��7��s�79��71Ys�79s�M�� �M�☾����o*&:��9F�t��o��r����M�7��MͿ������������������7��[��ڸ�o��|:�C�?�EO��>��ǿ�y���ڃ��/���_��A���S�ǿX�A���S�ǿX�A���Sǡڃ�u�q��A�㔚8��8N�+�C��8�Sf�8D{��8��8��1�q�Rǡڃ�)5q�=�q�Rǡڃ�u�q��A�㔚8��8N���P�A�㔚8��8Ψ;�#ur���q�� �qJM�jr���q�� �qF�q�c��8e^�8o�0�S���P�9�㔙8��8N��8�9�q�Rǡڃ�)5q�=�q�Rǡڃ�u�q��A�㔚8��8N���P�A�㔚8��8Ψ;�#ur���q�� �qJM�jr���q�� �qMGf�a���!Ys�)3q�=�q�Rǡڃ�u�q��A�㔚8��8N���P�A�㔚8��8Ψ;�#ur���q�� �qJM�jr���q�� �qF�q�c��8�&�C�9�Sj�8T{�8��8͚�8ΐ���9�㔙8��8N���P�A�㔚8��8Ψ;�#ur���q�� �qJM�jr���q�� �qF�q�c��8�&�C�9�Sj�8T{��8�&�C�9��5�ur���q�� �qJM�jb��ǡYs�s�q��A�㔚8��8N���P�A�㔚8��8Ψ;�#ur���q�� �qJM�jr���q�� �qF�q�c��8�&�C�9�Sj�8T{��8�&�C�9�3��H��)5q�=�q�BW�f�q���q�� �qF�q�c��8�&�C�9�Sj�8T{��8�&�C�9�3��H��)5q�=�q�Rǡڃ�)5q�=�q�QwG��8N���P�A�㔚8��8N���P�A�㌺�8R� �q -]q�5�q�2�!ڃ�)5q�=�q�QwG��8N���P�A�㔚8��8N���P�A��z��@���)5q�=�q�Rǡڃ�)5q�=�q�QwG��8N���P�A�㔚8��8N���P�A���8�̞�8N�+�C��8�Sf�8D{��8*�D��q��nK���8��9~���x~�>���p�����OO����~�~��\�|���~��?�������U�}����o��_�����`o��移�ח/����`_���� ���a��=��>���~� �6�c���V��=lo��=l���Q�9~[�y�����z}�9��a+5�a�ڃ��R�6�=��a+5�a�ڃ��Q�{ؤ�A~[�y��������Q�A~[�y��������&u�{�J�{ب� ���Լ��j�{�J�{ب� ��mм�Mf��{؊\�a#Ys��2�6�=��a+5�a�ڃ��Q�{ؤ�A~[�y��������Q�A~[�y��������&u�{�J�{ب� ���Լ��j�{�J�{ب� ��m��6�c���Vj��F��=l��=lT{��V�z͚��� �����9~[�y��������Q�A~[�y��������&u�{�J�{ب� ���Լ��j�{�J�{ب� ��m��6�c���Vj��F��=l��=lT{���Vj��F��=l�^��u�{�J�{ب� ���Լ��j�{� -]�a�Ys��1�{�A~[�y��������Q�A~[�y��������&u�{�J�{ب� ���Լ��j�{�J�{ب� ��m��6�c���Vj��F��=l��=lT{���Vj��F��=l����I���R�6�=��a+t���f��{���{؈� ��m��6�c���Vj��F��=l��=lT{���Vj��F��=l����I���R�6�=��a+5�a�ڃ��R�6�=��au��M��������Q�A~[�y��������Q�A~ۨ�=lR� �����6�5��a+3�a#ڃ��R�6�=��au��M��������Q�A~[�y��������Q�A~[����A����R�6�=��a+5�a�ڃ��R�6�=��au��M��������Q�A~[�y��������Q�A|۠y�̞������F���=le�=lD{���>~]X����qy���������c��}��=��w�_�=����{��L��������?}�������z��ݷ�?�Ώ��ݍ�����/��ޟ[��ޟ[�y���-�}���-�Ys��e�s�� n���s��A�܂R�T{�?���|n���-(5�[@��sFݟ[ u�����-�ڃ����s�� nA����=ȟ[0����c�?���|n���-(5�[@��sJM�jr�cԝ��:)�Q�%�A�v3��Ś��G��|�A�|�z�|@����(5��=ș�R���ڃ��(5��=ș�Qw�C���G��|P�A�|������G��|P�A�|��3R� g>JM�jr��d>�� g>JM�jb�c�d>d�f>�\��5Ǚ�2�� ڃ��(5��=ș�Qw�C���G��|P�A�|������G��|P�A�|��3R� g>JM�jr��d>�� g>JM�jr�cԝ��:9�Qj2T{�3�&�A�1�Q��|Ь9�|�̇Ȟ��G��|�A�|������G��|P�A�|��3R� g>JM�jr��d>�� g>JM�jr�cԝ��:9�Qj2T{�3�&�A�9�Qj2T{�3�^3P� g>JM�jr��d>�� f> -]��5Ǚ�1w�C���G��|P�A�|������G��|P�A�|��3R� g>JM�jr��d>�� g>JM�jr�cԝ��:9�Qj2T{�3�&�A�9�Qj2T{�3��̇�1ș�R���ڃ��(te>h�g>�L�hr�cԝ��:9�Qj2T{�3�&�A�9�Qj2T{�3��̇�1ș�R���ڃ��(5��=ș�R���ڃ��ug>��A�|������G��|P�A�|������Ǩ;�!ub�Е��Ys��(3��=ș�R���ڃ��ug>��A�|������G��|P�A�|������G����9ș�R���ڃ��(5��=ș�R���ڃ��ug>��A�|������G��|P�A�|������Ǡ�|��9�|�2$k�3e&�A�9�9�ST��q�|n������9���������=g>�7���ae>��?��/��;�|7�9�<=<}w#�ǹ�{|<�=�Ow���S,x����I߾��|���u�>�;���=xP����k����[V����Z'�&�B�1�R芧Ь9����x -��xʨ;�"ur<���S�� �SJM<�jr<���S�� �SF���c��)�&�B�9�Rj�)T{��)�&�B�9�2ꎧH�O)5��=��RO�ڃO)5��=��Qw<E��xJ��x -��1����)k��)e&�B�9��5�ur<���S�� �SJM<�jr<���S�� �SF���c��)�&�B�9�Rj�)T{��)�&�B�9�2ꎧH�O)5��=��RO�ڃO)5��=��AO��sO)r�SH��S�L<�hr<���S�� �SF���c��)�&�B�9�Rj�)T{��)�&�B�9�2ꎧH�O)5��=��RO�ڃO)5��=��Qw<E��xJ���P�A����x -��xJ�+�B��0�2d�)"{��)e&�B�9�Rj�)T{��)�&�B�9�2ꎧH�O)5��=��RO�ڃO)5��=��Qw<E��xJ���P�A����x -��xJ���P�A���z��@��O)5��=��RO�ڃO)t�Sh��S����c��)�&�B�9�Rj�)T{��)�&�B�9�2ꎧH�O)5��=��RO�ڃO)5��=��Qw<E��xJ���P�A����x -��xJ���P�A�����)R� �SJM<�jb<��O�YsO)3��=��Qw<E��xJ���P�A����x -��xJ���P�A�����)R� �SJM<�jr<���S�� �SJM<�jr<e�O�:9�Rj�)T{��)�&�B�9�Rj�)T{��)��x��1��BW<�f�q<���S�� �SJM<�jr<e�O�:9�Rj�)T{��)�&�B�9�Rj�)T{��)�^�)P� �SJM<�jr<���S�� �SJM<�jr<e�O�:9�Rj�)T{��)�&�B�9�Rj�)T{�)�&�"��0�R䊧��9����x -��x��R�>�%��-�����������4����'�t�q�S��ǯ�~PN�������?l_�����?<ݝ�����S�77O��U��继O��y�w��O����R�t���I��H���p����#/?e����2�5� �!S�Ysܿ r�o@��o�L�Fd�a�f��x;�ٛS��Xsܼ r'o@�o�L�Fd�q�f��nD��n�L�Fd�q�&ȝ��s�2��5Dž�!�Ys��2u�5�m� w�d�q�f�tmD�Wm�L�Fd�q�f�mD��l��9�=G1�/-q7SX�m�l�ݎq�f�Tl$�7l�ׄ�s�2��5���!�Ys��2��5�ݚ w�d�q�f�4kD�k�L�Fd�q�f��jD��j�ܩ�=ǡ�!өYs\�2��5lj�!S�Ysا 1y�5�q��V�F���iL�Fb�q�f�TiD�7i��I�=�A�!ӣYs\�21�5�)�!S�Ysܡ rgh@�Gh�L�Fd�q�f�hD��g�L}Fd�q{&ȝ��s�2��5�ՙ!�Ys��qgގao&��f���fLkFb�qifȄfD�gf�LeFd�qc&ȝ��s�2}�5�u�!�Ys��2e�5�]� wVd�qTf�4eD�e�LPFd�qNf��dD��d�ה�s�2�5��!�Ys��qdގq?&�����s�2��5��!�Ys��2��5�͘ w2d�q0f��bD��b�L,Fd�q*fȔbD�wb�ܙ�=Ǒ�!ӈYs\�2��5�y�!S�Ys܆ r�a@��a�LFd�af��x;�I�S��Xs܃ r�`@��`�LFd�q fȄ`D�g`�LFd�q&ȝ��s�2��5���!Ys�~2��5�ݗ w�d�q�e�4_D�_�L�Ed�q�e��^D��^�ܩ�=���W�E��W^L�Eb�q�e�^D��]��y�=�q�!�vYs\v2a�5�Y�!SuYs�t}L^��cr�q�e��\D��\�L�Ed�q�eȔ\D�w\���=��!�pYs\p2�5���!SoYs�n 1��5���V�E��W[L�Eb�q��(��!.��M�x�k>�_������=�p��~s �>�`���߾�������j뵥x�{������>�e[����������o� T{� -���@���Pj" -T{�3 -��1�%�R�R�ڃS(55�=�=�RT�ڃ�Tu7��A�*�����B�)+P�An+�����¨�� uRa��Kb���F -\��5ǝ�2Z ڃ�Z��Z�:��PjrT{�����@���Pj�T{������1��R�^�ڃ_(5��=���R`�ڃ�`u7��A�0����C�)1P�An1����à�1��9,2��$k��e��@���Pj�T{����6��1�u�R�g�ڃh(5��=ȍ�Ri�ڃ�iuw��A.5��T��XC��5P�A�5��`��dè�� ur���d�� �JM��jb���o�Ys�o2��=��2�p ڃq(5�=��Rr�ڃ�ru���A�9�����C�):P�An:�����è�� ur١Ԥ�� �JM݁jrߡ��� 'B�6��A�<������C�)=P�Al=�b4k�sc�ރ�1�ŇR�|�ڃ}(5��=�݇R~�ڃ�~u���A�?������D�)@P�An@����Ĩ�!ur �Ԥ �� � JM �jr��!�� '!F�M�c���&A�1Q�*CЬ9nC��8��<Ĩ�!ur!��$"�� G"JM%�jr'�Ԅ"�� �"Fݭ�c�k�&A�9Qj�T{���&A�91��FH�\�(5��=��RS��ڃ(5 �=� �QwCB�ĊD�+#A��8$QfJD{�[�&&A�9'1��IH�\�(5I �=�Q�RS��ڃܕ(5a �=�i�P�m �s���&/A�90Qj -T{��&2A�931��LH�\�(5� �=ȱ�RS��ڃܛ(5� �=�ɉAӜ��sX�(re'H��'�Ly�hr{rP����R�������s|�����>t���ӷw��������f�&?��'�<���������ӧ�?|��?��&99}9�����w7��?b���?`����^C�̏n����s<�=��5��9�Q/��@��������(����<P���z��j��>��4�;��S6{�<�98��y��h��?��z��j��w_^���o?P{�}��tw��/4F]�eu�w_�X����<P���__P���=x���4����^~��ڃ�W����ߢ:�'�^~��ڃ��O���^~��ڃ��O�ɪ��~�����������\~��<P�^^�z��j�Ow�g�^~��ڃ��ݓ�����5�>y�{�/�/8�-�c�@=�9x����=x���|�����=x���,<>H����<�|��OÃT�oY���O���T/��@��u}�S��<(�=�Uj��j�7B��?J��τ*5� E��K�JͧBQ�A�X�R�PT{��j���PR� 2T��f(�=�_ U��l(�5�Uf��h�C��`�:���Rs���J�T{�`(50P�A>�a�}���1�0���� �Pj`�ڃ|�C�9��j�����A>����@����Rs���J�T{�`u� u�e^`�x;�0�`�Xs|�C�9��h��^`�:���Rs���J�T{�`(50P�A>�a�}���1�0���� �Pj`�ڃ|�C�9��j�����A>����@����Rs���J�T{`40��9<���u�ɚ���D{�`(50P�A>�a�}���1�0���� �Pj`�ڃ|�C�9��j�����A>����@����Rs���J�T{�`u� u�����=�0���� �P�:��f��C���=�0���� �Pj`�ڃ|�C�9��j�����A>����@����Rs���J�T{�`u� u�����=�0���� �Pj`�ڃ|�C����A>����@����Rs��� -]0Ь9>�a�}���1�0���� �Pj`�ڃ|�C�9��j�����A>����@����Rs���J�T{�`u� u�����=�0���� �Pj`�ڃ|�è���c�`(50P�A<���u�͚���D{�`u� u�����=�0���� �Pj`�ڃ|�è���c�`(50P�A>����@����Rs���F�0H�|�C�9��j�����=�0���� �0�>�A�� -]0Ь9>����@����Rs���F�0H�|�C�9��j�����=�0���� �����s�`(50P�A>����@����Rs���F�0H�|�C�9��j�����=�0���� �0h`��sx�C����5�0���� ��s��>����������1`����������D0����u�������~}{���o�_?w3�������������>�۾��������y��߲:ԇ����^~��ڃ����ɪ��~����z����Q���~����������S�oY�����U/��@������˓T/��@��������-N������\��(5�qP�xǩ�<�=��q����ڃxǩ�<�=H�q����sxǙ�<�=��q����ڃxǩ�<�=��q���8��A<���u����8N]�qX�A<���u����8F��qH��xǩ�<�=��q����ڃxǩ�<�=��q���8��A<���u����8N]�qX�A:����y6k��(3�q�xǩ�<�=��q����ڃxǩ�<�=��q���8��A<���u����8N]�qX�A<���u����8J�yT� ��q�:��j�y���8�� ��q�:��j�y��<�c��8u��a��<�C/�qج9<���u����8J�yT� ��q�:��j�y���8�� ��q�:��j�y��<�c��8u��a��<�S�yV{��8u��a��<�Rs�1��q����ڃxǩ�<�=��q����ڃxG�9�����8��v���1:����yk��8s��a��<�Q�yR� ��q�:��j�y���8�� ��q�:��j�y��<�c��8u��a��<�S�yV{��8u��a��<�Rs�1��q����ڃxǩ�<�=��q����ڃtG��<�=G�qy9��d��yg��8�� ��q�:��j�y��<�c��8u��a��<�S�yV{��8u��a��<�Rs�1��q����ڃxǩ�<�=��q����ڃxG�9�����8N]�qX�A<���u����8���a���<�"�y${��8s��a��<�S�yV{��8u��a��<�Rs�1��q����ڃxǩ�<�=��q����ڃxG�9�����8N]�qX�A<���u����8N]�qX�A<�c�}��9��q����ڃxǩ�<�=H�qz9��f��ye�<�c��8u��a��<�S�yV{��8u��a��<�Rs�1��q����ڃxǩ�<�=��q����ڃxG�9�����8N]�qX�A<���u����8N]�qX�A<��Ԝ�Au�y���8�� ��q��<�5��q����0ڃxG�9�����8N]�qX�A<���u����8N]�qX�A<��Ԝ�Au�y���8�� ��q�:��j�y���8�� ��Qj��:�<�S�yV{��8u��a��<�S�yV{��(5�qP�tǡ��8l���q�:��h�y���8�� ��Qj��:�<�S�yV{��8u��a��<�S�yV{��u��!u�y���8�� ��q�:��j�y���8�� ��Qj��:�<�S�yV{��8u��a��<�S�yV{���(t��A���<�#/�q��9<���u����8x����8��~S�h>�ǁ��q��<Η��_j�<����<��u��?���~���O��yz�;����n���C�p��z\m�y���"o���ڃ|\D�9.�j�q���"��A>.��A����Rs\���"J�qT{��4�E��9>.��A����Rs\���"J�qT{���u!u�q���=��E���"�� Qj���ڃ|\D���"��A>.��A����Rs\���"J�qT{���u!u�q���=��E���"�� Q�:.�f��qc��"��A>.��A����Rs\���"J�qT{���u!u�q���=��E���"�� Qj���ڃ|\Ĩ���c���(5�EP�A>.��A����Rs\���"F��EH�|\D�9.�j�q���"h�Qf�� ڃ|\Ĩ���c���(5�EP�A>.��A����Rs\���"F��EH�|\D�9.�j�q���=��E���"�� 1�>.B���"J�qT{���(5�EP�A>.��A����Q�qR� Q����cx\D���5��E���"�� ����s���(5�EP�A>.��A����Rs\���"F��EH�|\D�9.�j�q���=��E���"�� 1�>.B���"J�qT{���(5�EP�A>.��A��As\�̞��"�\�E��9>.��A����Rs\���"F��EH�|\D�9.�j�q���=��E���"�� 1�>.B���"J�qT{���(5�EP�A>.��A����Q�qR� Qj���ڃ|\D�9.�j�q���"h�1d���s|\D�9.�h�q���=��E���"�� 1�>.B���"J�qT{���(5�EP�A>.��A����Q�qR� Qj���ڃ|\D�9.�j�q���=��E�z=.���"J�qT{���(5�EP�A<.��u\͚��"���E�|\D�9.�j�q���=��E���"�� 1�>.B���"J�qT{���(5�EP�A>.��A����Q�qR� Qj���ڃ|\D�9.�j�q���=��E�����:���Rs\���" -]�EЬ9>.��A����Q�qR� Qj���ڃ|\D�9.�j�q���=��E�����:���Rs\���"J�qT{���(5�EP�A>.b�}\��1��E���"�� Qj���ڃ|\D�9.�j�q���"��A<.��u\͚��"��qD{���(5�EP�A>.b�}\��1��E���"�� Qj���ڃ|\D�9.�j�q�^���:���Rs\���"J�qT{���(5�EP�A>.b�}\��1��E���"�� Qj���ڃ|\D�9.�j�q���=��E��� Ys|\D�9.�h�q����q|��q��[��E��c9�q����(t\d��r\�i��ߞN��|��/?�����"�O���/����o�G���"��w/=]~t�xo#�ϧ�����>�[u���1x�>ܽ��Z�^~��ڃ����ɪ��~����z����b�R/��@���.����Bk��[V����N�(57rP�A������A��F�Rs#��9F�7rH�|#G����j���F�=�7r��9�� ��1hn��s|#G����h���F�=�7r��9�� ��1꾑C��9J͍T{�o�(57rP�A������A��F�P�7r@��|#G����j���F�=�7r��9�� ��1꾑C��9J͍T{�o�(57rP�A����u#͚�9��7r�|#G����j���F�=�7r��9�� ��1꾑C��9J͍T{�o�(57rP�A������A��F�Q��R� ��Qjn�ڃ|#G����j���F�=�7r��o�:�F�Rs#��9 -]7rЬ9������A��F�Q��R� ��Qjn�ڃ|#G����j���F�=�7r��o�:�F�Rs#��9J͍T{�o�(57rP�A��c�}#��1�7r��9�� ��Qjn�ڃ|#G����j���9��A����ˍo��F�k�o�(37r�A��#��P� ��Qjn�ڃ|#G����j���F�=�7r��o�:�F�Rs#��9J͍T{�o�(57rP�A��c�}#��1�7r��9�� ��Qjn�ڃ|#G����j���F�=�7r�n� Ys|#G����h���F�=�7r��o�:�F�Rs#��9J͍T{�o�(57rP�A��c�}#��1�7r��9�� ��Qjn�ڃ|#G����j���9��A������A��F�Rs#��9 -]7rЬ9��c���!���F�2s#��9J͍T{�o�(57rP�A��c�}#��1�7r��9�� ��Qjn�ڃ|#G����j���9��A������A��F�Rs#��9J͍T{�o��z#�9�7r��9�� ��Qjn�ڃx#G��F�5�7r��o�:�F�Rs#��9J͍T{�o�(57rP�A��c�}#��1�7r��9�� ��Qjn�ڃ|#G����j���9��A������A��F�Rs#��9J͍T{�o�u��!u���F�=�7r�n�Ys|#G����h���9��A������A��F�Rs#��9J͍T{�o�u��!u���F�=�7r��9�� ��Qjn�ڃ|#Ǩ�F�c�o�(57rP�A������A��F�Rs#��9F�7rH�x#G��F�5�7r��9�� ��Qjn�ڃ|#Ǩ�F�c�o�(57rP�A������A��F�Rs#��9B���u���F�=�7r��9�� ��Qjn�ڃ|#Ǩ�F�c�o�(57rP�A������A��F�Rs#��9͍2{o�(r��A���F�2s#��9�W_ԍ|�ˍ�ۓ4�7r��㯻�s������ҍ���ˍ�/�F������_~������w����������/�Gr�!x�}H��َ��}8�B��C*J�!T{��(5�TP�A>���RA����Q�!R� RQj��ڃ|HE�9��j�!�� -�=��T�C*d�RQf� ڃ|HE�9��j�!�� -�=ȇT����:���RsH��C*J�!T{��(5�TP�A>�"��!P� RQj��ڃ|HE�9��j�!�� -�=ȇT����:���RsH��C*J�!T{�(tRA�����1�!B� RQj��ڃ|HE�9��j�!�� -�=ȇT����:���RsH��C*J�!T{��(5�TP�A>�b�}H��1ȇT��C*�� RQj��ڃ|HE�9��j�!��C*��A>���RA��B�!4k��(3�T�A>�b�}H��1ȇT��C*�� RQj��ڃ|HE�9��j�!��C*��A>���RA����RsH��C*J�!T{��uR!u�!�� -�=ȇT��C*�� RQj��ڃ|HŨ�� -�c��(�rH��1<���uHŚ�C*��!D{���zH�9ȇT��C*�� RQj��ڃ|HE�9��j�!��C*��A>���RA����RsH��C*J�!T{��uR!u�!�� -�=ȇT��C*�� RQj��ڃxHŠ9�Bf��!E�C*H�RQf� ڃ|HE�9��j�!��C*��A>���RA����RsH��C*J�!T{��uR!u�!�� -�=ȇT��C*�� RQj��ڃ|HŨ�� -�c��(5�TP�A>���RA��B�!4k�2�T��9>���RA����RsH��C*J�!T{��uR!u�!�� -�=ȇT��C*�� RQj��ڃ|HŨ�� -�c��(5�TP�A>���RA����RsH��C*B�Ru�!�� -�=ȇT��C*�� RQ�:��f��!c�C*��A>���RA����RsH��C*J�!T{��uR!u�!�� -�=ȇT��C*�� RQj��ڃ|HŨ�� -�c��(5�TP�A>���RA����RsH��C*F݇TH�|HE�9��j�!��C*h�RQf� ڃ|HŨ�� -�c��(5�TP�A>���RA����RsH��C*F݇TH�|HE�9��j�!�� -�=ȇT��C*�� R1�>�B��C*J�!T{��(5�TP�A>���RA����Q�!R� RQ�:��f��!e� -�=ȇT��C*�� R1�>�B��C*J�!T{��(5�TP�A>���RA����P��T@��|HE�9��j�!�� -�=ȇT��C*�� R1�>�B��C*J�!T{��(5�TP�A>���RA��AsH�̞�C*�\�T��9>���RA�����uuH��rH��n���!����T����y��wT.���Qy^gT�������������뿋ٛ�=����������o��?R~s�Lo��绗����)�!/?e���'Ow�O�\?E��ȇ��0Έ�~���w�#�����OY����G�Q���2Ys��_�C��)�=w@��ؿ��|C^~�d���?�'I^~�d����!sH�Ț�3J��W���9��dȜP"�����!s?�Ț��I���$"k�O' r_N���n�!s6�Ț�I���$"k�/&2���9<�$�\K���V�s*�Ě�CI�̝$"k��$2G���9>�$�}! Ȟ��H��y$"k��#2����9��d�F"���,����*�19��&�!s�Ț�H��=$"k��!2ǐ��9>�$�} Ȟ�;H��$"k�� 27���9��d�u����1>$�}�Ğ��G���#"k�2w���9�zd�="���� ��# {��2玈�9>vd��:"���ґ!s�Ț�3G��W���9�qdȜ8"�����!s߈Ț��F��q#"k�O r_6�����!sֈȚãFF\7���F�A#k�� r_3�����!sʈȚ�CF��#"k��2G���9>a$�}�Ȟ��E���""k��2����9�\d�."���l� ��" {�o2'���9>Xd��+"���Z�!s��Ț�SE�ܗ���9�Sd�˙"�n��H��֍"�n��B�s��Ě��D���D����D��i""k�2w���9�Jd�%"���$� �E" {��2爈�9>Fd��""����!s��Ț�3D��W���9�AdȜ "�����!s�Ț��C���!"kO 1����1�;d�uv���1>:d��"����!sp�Ț�sC��׆��9�5dȜ"���А!sg�Ț�+C�̑!"k�O r_�����!s^�Ț��B��m!"k�/2����9>+$�}UȞ�B��I!"k� -2����9�&d�uL���1<%$�\�����sF�Ě�#B�� !"k�/2���9>$�}=Ȟ��A��� "k�2w���9�d� "���d� �� {��2炈�9>d�� -"���R�!s(�Ț�3A��+A���A�̉ "k�2����9�d�u���1> $�}Ğ�@��Y "k��27���9�d�"���� �5 {�o2����9>d��"��� -�!s�Ț�@�����9��cȜ�!�����!s��Ț��?���"k���r_�����!s�ȚÃ?F\�~��k?̱k�O�r_����Ώ!s�Ț�#?�̍"k�/�2~��9>�#�}�Ȟ��>��i"k��2w}��9��c��!����� �E {���2�|��9>�c���!�����!sȇȚ�3>��W|��9��c�u��1>�c���!���z�!s��Ț��=�ܗ{��9��cȜ�!���h�!s��Ț�=���"k���|L^���c�o�2�z��9>�c���!���J�!s��Ț�=��z��9��cȜ�!���8�!s��Ț��<��a"k��1Wy��1��c�u����1>�c���!�����u���r������)�Ç������������?߽{sz9������?�=��g�݆w�(��5�Ӻ��7���?���~�z����|����}�tɬ���?v��G쮡!<�. o��85|� ��ڃ\*5�!�=���RS�ڃ�uG���A�������P�IQ�A�������Ш;@$ur���4��� W�JM��jr��Ԕ��� ��F�1"�c�sD��GD��HT�JѬ9���*��.Ѩ;L$ur��Դ��� JM��jr������ 7�Fݑ"�c�3E��SD��TTjRET{�cE��VD��W4�I��,*5�"�=�բR�-�ڃ.*5�"�=���Qw�H��|Q��~��1,�Fk�#Fe�bD��c�5durʨԴ��� JMΈjrШ���� 7�F�Q#�c��F��kD��lTj�FT{��F��nD��o4�I��8*5�#�=ȕ�R�9�ڃ:*5�#�=���A;��s�;*r��H���L�hr���T��� w�F��#�c��G��}D��~Tj�GT{�H���D���4� I��A*5$�=�%�R�B�ڃC*55$�=�=�QwI��$R�i"Q�A�"��,��0R���D�氍4d�H"{��He��D���TjIT{�#I���D���4�%I��J*5�$�=ȵ�R�K�ڃL*5�$�=�ͤQw4I��lR��&Q�A.'��t��xR��'Q�A�'�z (A���P*5 %�=��R�Q�ڃR*t��h�����1%�c�sJ���D���Tj�JT{��J���D���4�+I��V*5m%�=�u�R�W�ڃX*5�%�=ȍ�QwdI���R��,Q�A.-������R��-Q�A�-���KR� '�JMs�jbu�Е]�Ys^*3�%�=���Qw|I���R��/Q�A.0����S��0Q�A�0��CLR� ��JM��jr���䘨� �JM��jr�i�e�:9�Tj�LT{��L�&�D�9�Tj�LT{��L��@��1���BW��f�q���d��� ��JM��jr�i�k�:9�TjzMT{��M�&�D�9�Tj�MT{��M�^�MP� ��JM��jr���䛨� �JM��jr�i�q�:9�Tj:NT{�KN�&�D�9�TjjNT{{N�&�$��0�T�j:��9�:����䰓�DQv�s\��ے��<~�w�w�Nw���pܹ~���>q����/�^�ӿ���?���Wq__��o��=ܿ�A�~)��1�ʽy��o�}�X.�=ȟ�Uj���j�s�z�d.�s�?���|5����*5�E��ӹJͷsQ�A�z�Q��sI��]����� CW���.�=���U���.�5�_�5�.� �\�+5�;�=ȅ�RS��ڃ\�+5�;�=ȅ�Qw�N���]�)�Q�A.ܕ�����]�)�Q�A.܍�wR� �JM�jr���� �JM�jr�n�]��:�pWj -wT{w���͚��]�)��A.܍�wR� �JM�jr���� �JM�jr�n�]��:�pWj -wT{�w��pG��pWj -wT{�w���1ȅ�RS��ڃ\�+5�;�=ȅ�RS��ڃ\�uA*ܕy)�Q���]��pG��pWf -wD{�w�^wP� �JM�jr���� �JM�jr�n�]��:�pWj +GYSᠵ�\��pȺ���Q�T8hm V8J:*t�+�L���r�c���!�� +GYSᠵ�\�(k*�6�+eM���r�c���!�� +GYSᠵ�\�(k*�6�+eM���r�c���!�� +GYSᠵ�\�(k*�6�+eM���r�c���!�� +GIG����q����pP�@�p�5Z���� +���+eM���r����p��@�p�5Z���^*��@�p�5Z�����Ak��Q�T8hm W8�:+�.@�p�5Z�����Ak��Q�T8hm V8F� +���� +G)G����q����pP�@�p�SU����*�����n���9�7���x����� `�t8�CJ��~�������/��z|=���\.���`w{i�����-#}�����w��9��o�����qź={���������Vʺ={�����w������Y�����k8=I��� kw�����Vʺ={�����k8Z��� k�[�����Ydzl]�;����9�Һ={������//ֺ={��������}�pו������V�9�e�ܱ���'kݞ�am������A������X�!�5��Dk���:_1I�ȯ�Tּb� �WL*k^1���+&�5��Dk���:_1I�ȯ�Tּb� �WL*k^1���+&�5��Dk���:_1I�ȯ�Tּb� �WL*���Y8�ە3q;J�q��θ����veM�rܮ�����@�ە5q;Z�q��θ����veM�rܮ�����@�ە5q;Z�q��θ����veM�rܮ�����@�ە5q;Z�q��θ����v���v4��aܮ�#nGc�8nW���(m ���z����9nW���hm ��ʚ�� �]Y�������ɺ�9nW���hm ��ʚ�� �]Y�������ɺ�9nW���hm ��ʚ�� �]Y�����i�vr6�v�q;*�q�r&nGi9nW���hm ���:�v�.@�ە5q;Z�q��&nGk9nW���hm ���:�v�.@�ە5q;Z�q��&nGk9nW���hm ���:�v�.@�ە5q;Z�q��&nGk1nW����p�e�vR6��v�L�rܮ�����@�ە5q;Z�q��θ����veM�rܮ�����@�ە5q;Z�q��θ����veM�rܮ�����@�ە5q;Z�q��^�v��@�ە5q;Z�q��&nGk1nW����p���I��9nW���hm ��ʚ�� �]Y�������ɺ�9nW���hm ��ʚ�� �]Y�������ɺ�9nW���hm ��ʚ�� �]Y�������ɺ�9nW���hm ��J:�vt��v�L�r�n�3n'��]Y�����+k�v�6��veM�r�n�3n'��]Y�����+k�v�6��veM�r�n�3n'��]Y�����+k�v�6��veM�r�n�3n'�ĸ]IG��qܮ���Q�@�ە5q;Z�q��θ����veM�rܮ�����@�ە5q;Z�q��^�v��@�ە5q;Z�q��&nGk9nW���hm ���:�v�.@�ە5q;Z�q��&nGk9nW���hm ��F�����ø])G��qܮ���Q�@�۩�q;~�-n_������c�ۏ7������������#n�������?~���>��v�w|c�[����?��;�zネ��������p���9>J�G�ٸ���r<J��� iw�O�ӝ�n�ް6p��rx~���۳7� �Y 8����7��,[��u�((kv��@�eP��2����ˠ��e@ky�AX/�`]��ˠ��e@ky�AY�ˀ��.��f�� �]c��d]��ˠ��e@ky�AY�ˀ��.���]t�w�s�2�t�.��f�� �]e�.ZȻʚ]�6�w�u�2�u�.��f�� �]e�.ZȻʚ]�6�w�u�2�u�.��f�� �]e�.ZȻʚ]�6�w�u�2�u�.��f�� �]%��,�2(gvP�@�e0ֹ�@�Ȼʚ]�6�w�5�hm �2(kv��@�e0ֹ�@�Ȼʚ]�6�w�5�hm �2(kv��@�e0ֹ�@�Ȼʚ]�6�w�5�hm �2(kv��@�e0ֹ�@�H�ʹ�2��=w�p�2��p�ˠ��e@iy�AX/�`]��ˠ��e@ky�AY�ˀ��.��f�� �]c��d]��ˠ��e@ky�AY�ˀ��.��f�� �]c��d]��ˠ��e@ky�AY�ˀ��.��f�� �]#�.9��J9vPY8�eP��2����ˠ��e@ky��X�.Y �2(kv��@�eP��2����ˠ��e@ky��X�.Y �2(kv��@�eP��2����ˠ��e@ky��X�.Y �2(kv��@�eP��2����ˠ�c����]��.)ǻʙ]�6�w�5�hm �2(kv��@�e0ֹ�@�Ȼʚ]�6�w�5�hm �2(kv��@�e0ֹ�@�Ȼʚ]�6�w�5�hm �2(kv��@�e��.XW �2(kv��@�eP��2����ˠ�c����]㜻$]��ˠ��e@ky�AY�ˀ��.��f�� �]c��d]��ˠ��e@ky�AY�ˀ��.��f�� �]c��d]��ˠ��e@ky�AY�ˀ��.��f�� �]c��d]��ˠ��e@kq�AI�.:ǻʙ]�6�w�u�2�u�.��f�� �]e�.ZȻʚ]�6�w�u�2�u�.��f�� �]e�.ZȻʚ]�6�w�u�2�u�.��f�� �]e�.ZȻʚ]�6�w�u�2�u�.���]t�w�3�(m �2(kv��@�e0ֹ�@�Ȼʚ]�6�w�5�hm �2(kv��@�e��.XW �2(kv��@�eP��2����ˠ��e@ky��X�.Y �2(kv��@�eP��2����ˠ��e@kq��H��@���.�R�]T�w�3�(m �2� �]��.����]���������Y��p}���tx��s��p�{��^T����e��8����ϟ����3 _���_���/������?|��۵�ܷ�ˋ��������/��t>�<�}���Og?~8�Ek�tVYs:���鬲�t� ��Yc���d]�|:��9�Ek�tVYs:���鬲�t� ��Yc���d]�|:��9�Ek�tVYs:���鬲�t� ��Y#��,9���J9NgQY8>�UΜ��|:��9�Ek�t�X��,Y ��*kNg��@>�U֜��|:��9�Ek�t�X��,Y ��*kNg��@>�U֜��|:��9�Ek�t�X��,Y ��*kNg��@>�U֜��x:���t����Y���,)ǧ�ʙ�Y�6�Og�5��hm ��*kNg��@>�5�y:K�ȧ�ʚ�Y�6�Og�5��hm ��*kNg��@>�5�y:K�ȧ�ʚ�Y�6�Og�5��hm ��*kNg��@>����,XW ��*kNg��@>�U֜��x:���t����Y㜧�$]�|:��9�Ek�tVYs:���鬲�t� ��Yc���d]�|:��9�Ek�tVYs:���鬲�t� ��Yc���d]�|:��9�Ek�tVYs:���鬲�t� ��Yc���d]�|:��9�Ek�tVI��,:ǧ�ʙ�Y�6�Og�u�Βu�鬲�t� ��Ye��,Zȧ�ʚ�Y�6�Og�u�Βu�鬲�t� ��Ye��,Zȧ�ʚ�Y�6�Og�u�Βu�鬲�t� ��Ye��,Zȧ�ʚ�Y�6�Og�u�Βu�鬒��Yt�Og�3��(m ��*kNg��@>�5�y:K�ȧ�ʚ�Y�6�Og�5��hm ��*kNg��@>����,XW ��*kNg��@>�U֜��|:��9�Ek�t�X��,Y ��*kNg��@>�U֜��|:��9�Ek�t�Hs:K����R��YT�Og�3��(m ���_z��Y�����;�����������x�{�_i6����i����_~��F��o��^9s�~��z9��b�fO����>G�k<��s}|5����y��A�X�goX�c=��]�(��� kw�/����8MY�goXx��|��u<���c= /Һ={�����kx��Ӕu{����;���>eͻ���@|���]��l�P9�.@�6����y Z��Tּ� �w�| Y �PY�.@�6����y Z��Tּ� �w +��]�`]��.@eͻ���@~���]�hm �PY�.@�6��h��]�d]��.@eͻ���@~���]�hm �PIǻ��Y8~�q�w�t���5�Dk�]�ʚw����.@eͻ���@~���w�u���5�Dk�]�ʚw����.@eͻ���@~���w�u���5�Dk�]�ʚw����.@eͻ���@~���w�u���5�Dk�]�J:�������3�Di�]��:�H���Tּ� �w*k������5�Dk�]��:�H���Tּ� �w*k������5�Dk�]��:�H���Tּ� �w*k������5�Dk�]��:�H�H�T��]�h|�w*�x ��Tμ� �w +�e��+�M�5�&hm �(kM��@4Q�����<hb�sЄ��M�5�&hm �(kM��@4Q�����<hb�sЄ��M�5�&hm �(kM��@4Q�����8hb�4!g�p�D)Ǡ *ǃ&ʙA�6�M�5�&hm ��4!��Ae͠ Zȃ&ʚA�6�M�5�&hm ��4!��Ae͠ Zȃ&ʚA�6�M�5�&hm ��4!��Ae͠ Zȃ&ʚA�6M�t���p8hb�4!e�x�D93h��f�� �Ae͠ Zȃ&�:MȺ�y�DY3h��f�� �Ae͠ Zȃ&�:MȺ�y�DY3h��f�� �Ae͠ Zȃ&�z4� +�Ae͠ Zȃ&ʚA�6M�t���p<hb�sЄ��M�5�&hm �(kM��@4Q�����<hb�sЄ��M�5�&hm �(kM��@4Q�����<hb�sЄ��M�5�&hm �(kM��@4Q�����<hb�sЄ��M�5�&hm �(�4Ag�x�D93h���A�.@4Q�����<h��4Aky�DY3h���A�.@4Q�����<h��4Aky�DY3h���A�.@4Q�����<h��4Aky�DY3h���A�.@4Q�1h����rf�� �Ae͠ Zȃ&�:MȺ�y�DY3h��f�� �Ae͠ Zȃ&�z4� +�Ae͠ Zȃ&ʚA�6�M�5�&hm ��4!��Ae͠ Zȃ&ʚA�6�M�5�&hm �iM��84Q�1h����rf�� �A���&�9�A���!O��&��c4��A�������W4�34yx?h���ˏ��������]�w�k�&{�j3��9z�!w��+d?�&� +���YG���b���#�fk1�v֑}����}+k�o�.@̾�ud�lm f��:�o�6��o'ݲov�o�L����ٷ��웭 ���YG���b���#�fk1�V�d�h]��};�Ⱦ��@̾�ud�lm f��:�o�6�oeM����ٷ��웭 ���YG���b���#�fk1�V�d�h]��};�Ⱦ��@ʾ�t˾�Y8̾�sd�,m f�ʚ���og�7[�ٷ��웭 ���YG���b���ɾѺ�1�v֑}����};�Ⱦ��@̾�ud�lm f�ʚ���og�7[�ٷ��웭 ���YG���b���ɾѺ�!�vί�7��(�v�-�fc�0�vΑ}����}�̾ɺ1�v֑}����};�Ⱦ��@̾�ud�lm f�ʚ���og�7[�ٷ��웭 ���YG���b���ɾѺ�1�v֑}����};�Ⱦ��@̾�ud�lm e�J:�ot6��o�ܲoV�o��7K�ٷ��웭 ��[Y�}�ub���#�fk1�v֑}����};�Ⱦ��@̾�5�7Z f��:�o�6�og�7[�ٷ��웭 ��[Y�}�ub���#�fk1�v֑}����};�}��p�}+�ȾQ�8̾�sd�,m f��:�o�6�og�7[�ٷ�&�F����YG���b���#�fk1�v֑}����}+k�o�.@̾�ud�lm f��:�o�6�og�7[�ٷ��웬+�og�7[�ٷ��웭 ���I�웝���[9�}�tb���#�fk1�v֑}����};�Ⱦ��@̾�5�7Z f��:�o�6�og�7[�ٷ��웭 ��[Y�}�ub���#�fk1�v֑}����};�Ⱦ��@̾�5�7Z f��:�o�6��o'ݲov�o��7K�ٷ�&�F����YG���b���#�fk1�v֑}����}+k�o�.@̾�ud�lm f��:�o�6�og�7[�ٷ�&�F����YG���b���#�fk1�v֑}����}+k�o�.@ʾ�t˾�Y8̾�sd�,m f��:�o�6�oeM����ٷ��웭 ���YG���b���#�fk1�6֙}�ub���#�fk1�v֑}����};�Ⱦ��@̾�5�7Z f��:�o�6�og�7[�ٷ��웭 ��[IG����Q��[����a��#�fi1�ƀ�v�͟��3�X�f��9�?�>�?k���i��G�������o���<sɾ�#���?���o>���_?}��Ͽ���o���Ǐ��O[H~���xx�{��e�\�ç����>��5����d]�|M����Gk��^YsM���5���� �kzc���d]�tM���5=���^ �5=���ʙkz�6����rM����ʚkz�6���5��hm _�+k����@��7�yMO����ʚkz�6���5��hm _�+k����@��7�yMO����ʚkz�6���5��hm _�+k����@��7�\ӓ�qxM������kz��5=J���ʚkz�6���u^ӓu�5���� �kze�5=Z���ʚkz�6���u^ӓu�5���� �kze�5=Z���ʚkz�6���u^ӓu�5���� �kze�5=Z���J:���Y8��7�\ӓ�q|M����Gi��^YsM���5���� �kzc���d]�|M����Gk��^YsM���5���� �kzc���d]�|M����Gk��^YsM���5���� �kza�\Ӄu�5���� �kze�5=Z���J:���Y8��7�yMO����ʚkz�6���5��hm _�+k����@��7�yMO����ʚkz�6���5��hm _�+k����@��7�yMO����ʚkz�6���5��hm _�+k����@��7�yMO����ʚkz�6��t\ӣ�p|M����Gi���X�5=Y _�+k����@��W�\ӣ��|M����Gk���X�5=Y _�+k����@��W�\ӣ��|M����Gk���X�5=Y _�+k����@��W�\ӣ��|M����Gk���X�5=Y ^�+鸦Gg���^9sM���5���� �kzc���d]�|M����Gk��^YsM���5���� �kza�\Ӄu�5���� �kze�5=Z���ʚkz�6���u^ӓu�5���� �kze�5=Z���ʚkz�6��4���l^�+带Ge���^9sM���5������ϱ]ӿ?]߿����5����O�|M?��\�߯��������������7� Oϯ{�����3�}��7f|��o�@g���ʙ7f�����c�o� ��7f(kޘ���3�5o�@k��ʚ7f�����c�o� ��7f(kޘ���3�5o�@k��ʚ�� ���Xg�C�ȍ����Ak��Q�4>hm 7>ʚ�� ���Xg�C�H��rn��ð�Q�����p��(g�6�a�4>`]���(k�6�eM��r㣬i|��@n|�u6>d]���(k�6�eM��r㣬i|��@n|�u6>d]���(k�6�eM��r㣬i|��@l|�4�9���R������G9�������(k�6�c��Y 7>ʚ�� ��GY�������(k�6�c��Y 7>ʚ�� ��GY�������(k�6�c��Y 7>ʚ�� ��GY�������(�h|�Y8l|�2�)Ǎ�r��Ai��Q�4>hm 7>ʚ�� ���Xg�C�ȍ����Ak��Q�4>hm 7>ʚ�� ���Xg�C�ȍ����Ak��Q�4>hm 7>ʚ�� ��GX/�XW 7>ʚ�� ��GY�������(�h|�Y8n|�s6>$]���(k�6�eM��r㣬i|��@n|�u6>d]���(k�6�eM��r㣬i|��@n|�u6>d]���(k�6�eM��r㣬i|��@n|�u6>d]���(k�6%�:Ǎ�r��Ai��1����ur㣬i|��@n|�5�Zȍ����Ak��1����ur㣬i|��@n|�5�Zȍ����Ak��1����ur㣬i|��@n|�5�Zȍ����Ak��1����ub㣤��Ag��Q�4>(m 7>ʚ�� ���Xg�C�ȍ����Ak��Q�4>hm 7>ʚ�� ��GX/�XW 7>ʚ�� ��GY�������(k�6�c��Y 7>ʚ�� ��GY�������(k�6#M�C��a㣔��Ae��Q�4>(m 7>ԧ��?����j�w���������pJ�s��9�~}u���د���>^o|�Cy&���(|��?���?�ç_������_��m��7�<ߑq���w|}9<��}���������x�x��A>��gѺw�����IZ�goX�c}:ܿ��CY�goX�c= Gkݞ�am�u���5\��u<���c=��*�۳7� ܱ>�`�۳7� ܱ���/��Go8w]y<�~�a��Y�.���;x������X�����˲u{����;�����eݞ�am�u���5��u<���c= �Һ={�����k8�8����X�_Ý�n�ް6����C�U��ϲu�XO���g<{��������Z�goX�c}9<ڿ�goX��&���G�g<���c�����Fk��V�Q~��p\~+g�o�6��oc��7Y ��ʚ�� ��[YS~���\~+k�o�6��oc��7Y ��ʚ�� ��[YS~���\~+k�o�6��oc��7Y ��ʚ�� ��[YS~���\~+k�o�6��oc��7Y ��ʹ��h|��[ G����q���)�Q�@.���R~�ur���)���@.��5�7Z�已��Fk��6�Y~�ur���)���@.��5�7Z�已��Fk��6�Y~�ur���)���@.��5�7Z�已��Fk��6Ҕ��l��J9�oT��o�L���r���)���@.��u��d]�\~+k�o�6��oeM���r���)���@.��u��d]�\~+k�o�6��oeM���r���)���@.��u��d]�\~+k�o�6��oeM���b�����Fg��6ʔߤl��ʙ�� ��[YS~���\~+k�o�6��oc��7Y ��ʚ�� ��[YS~���\~+k�o�6��oc��7Y ��ʚ�� ��[YS~���\~+k�o�6��oa���`]�\~+k�o�6��oeM���b�����Fg��6�Y~�tr���)���@.��5�7Z�已��Fk��6�Y~�ur���)���@.��5�7Z�已��Fk��6�Y~�ur���)���@.��5�7Z�已��Fk��6�Y~�ur���)���@,��t���,��ʙ�� ���Xg�M��已��Fk��V֔�hm ��ʚ�� ���Xg�M��已��Fk��V֔�hm ��ʚ�� ���Xg�M��已��Fk��V֔�hm ��ʚ�� ���Xg�M��巒������[9S~���\~+k�o�6��oc��7Y ��ʚ�� ��[YS~���\~+k�o�6��oa���`]�\~+k�o�6��oeM���r���)���@.��u��d]�\~+k�o�6��oeM���r���)���@,��4�79��R������[9S~���\~�̪��ϱ���3���{�s��ow<=NO�v��̥�>���~�������ɿ�����=�������������/_~�x�����O�~���������y��d�ݟ�����'�`]�|���9�Ek�dWYs����ɮ��d� �]c�'�d]�|���9�Ek�dWYs����ɮ��d� �]c�'�d]�|���9�Ek�dWYs����ɮ��d� ē]#��.9�'�J9NvQY8>�UΜ좴�|���9�Ek�d�X��.Y ��*kNv��@>�U֜좵�|���9�Ek�d�X��.Y ��*kNv��@>�U֜좵�|���9�Ek�d�X��.Y ��*kNv��@>�U֜좵�x����d��Ó]���.)�'�ʙ�]�6�Ov�5'�hm ��*kNv��@>�5�y�K��'�ʚ�]�6�Ov�5'�hm ��*kNv��@>�5�y�K��'�ʚ�]�6�Ov�5'�hm ��*kNv��@>����.XW ��*kNv��@>�U֜좵�x����d���]�'�$]�|���9�Ek�dWYs����ɮ��d� �]c�'�d]�|���9�Ek�dWYs����ɮ��d� �]c�'�d]�|���9�Ek�dWYs����ɮ��d� �]c�'�d]�|���9�Ek�dWI��.:�'�ʙ�]�6�Ov�u��u�ɮ��d� �]e��.Z�'�ʚ�]�6�Ov�u��u�ɮ��d� �]e��.Z�'�ʚ�]�6�Ov�u��u�ɮ��d� �]e��.Z�'�ʚ�]�6�Ov�u��u�ɮ���]t�Ov�3'�(m ��*kNv��@>�5�y�K��'�ʚ�]�6�Ov�5'�hm ��*kNv��@>����.XW ��*kNv��@>�U֜좵�|���9�Ek�d�X��.Y ��*kNv��@>�U֜좵�|���9�Ek�d�Hs�K���ɮR��]T�Ov�3'�(m ���ߗ��]�����������������tx8��˚�39�}������O?��Ç4=���~K~a��z����z���_��g��l���a:��}����Qv6nGy:��ҹ={C����/�;kݞ�am������j}�goXx��z<ܿ�K�Xdzl]�;�����Z�goX�c}:ܿ�W�ʺ={����x����mjhm �MMX/oS� +䷩)kަ����Ԕ5oSCk�mjʚ������65c�oS#�䷩)kަ����Ԕ5oSCk�mjJ:ަ�����Ԍs�M���ߦ��y�Z�oSSּM � ䷩)kަ����Ԍu�M���ߦ��y�Z�oSSּM � ䷩)kަ����Ԍu�M���ߦ��y�Z�oSSּM � ䷩)kަ����Ԍu�M���ߦ��y�Z�oSS��65t�ߦ��y�J�oS3��65�.@~����mjhm �MMY�65�6�ߦ��y�Z�oS3��65�.@~����mjhm �MMY�65�6�ߦ��y�Z�oS3��65�.@~����mjhm �MMY�65�6�ߦ��y�Z�oS3��65�.@z��rnoSC�{�MM ����X8~��rf�� �ia�L3�u�4��f�� �ie�4Z��ʚi�6���uN3�u�4��f�� �ie�4Z��ʚi�6���uN3�u�4��f�� �ie�4Z��ʚi�6��4��lN3(�f@e�x�A93̀��4��f�� �ic��d]�<͠��f@ky�AY3̀��4��f�� �ic��d]�<͠��f@ky�AY3̀��4��f�� �ic��d]�<͠��f@ky�AY3̀��4���it��2��lO3(g�P�@�fP�L3���<͠��f@ky��X�4Y O3(k���@�fP�L3���<͠��f@ky��X�4Y O3(k���@�fP�L3���<͠��f@ky�AX/�`]�<͠��f@ky�AY3̀��4���it���sN3�t�4��f�� �ie�4Z��ʚi�6���uN3�u�4��f�� �ie�4Z��ʚi�6���uN3�u�4��f�� �ie�4Z��ʚi�6���uN3�u�4��f�� �i%��,O3(g�P�@�f0�9�@���ʚi�6���5�hm O3(k���@�f0�9�@���ʚi�6���5�hm O3(k���@�f0�9�@���ʚi�6���5�hm O3(k���@�f0�9�@���J:��Y8�fP�L3���<͠��f@ky��X�4Y O3(k���@�fP�L3���<͠��f@ky�AX/�`]�<͠��f@ky�AY3̀��4��f�� �ic��d]�<͠��f@ky�AY3̀��4��f�� �i#�49��J9�PY8�fP�L3���<�@kb�?�6��~�uw�a�s��m����ןm�TOןy>����ܝ�����/�g<2�x�8�1���~���>���o�~�oR�]ix�o������/��qw�!{ ��2s �O�����3�X�S F��R�w�23 �,�$��H�e�x!�(3�@���<�Qf����m��4)�����]�}��U��()ǓF�ER���2s�,�!��B�e�x �(3�@����Qf���� c$|�!��`l�e�HY8�>0�,��p�{`��= e�x�@(��(NjF��R���2k�,oe�HY8:ʹs����ʁQf䀔�����)��F�yR�� �rn��q�l`�6 e�p��Ǫ ��x��3i@���P�=P6���2c�,Oe�HY8�10����p<b �s������̀)��F��R���2��,��-�e�x��(3Z@���d�Qf�������\)�cB9� +@�8Z*0�m��t�P8S`lc��t�a�Q`��( c�x���O��\p�N`�' e�x��(�L@���.�Qf�����Q����l/e HY8�#0ʬ��p�E`��" e�x�@(�(�+F�R�'�2�,�e�HY8�l��`�<`|cx�|�a<;`�Y c�xs�(39@�����PνP6���2c�,O e�HY8�0����p<2 �sc��������)��F�uR���2��,���e�xU�(3*@���QfQ����=cs$|�1�˖�� +�KF�!2�g�2+�,oe&HY8ʹ����z�Qf<��������r�)ǻF���R�G�rn��q�`� e�x.�(�@���V�Qf*���㡀���N��r��J�Qf$�������B�)����8�H����B8���8^0���p<`�Y e�x�(3 @��� �P�=�P6����2c��,Oe��HY8�0�����p< �s���������)���Q��'e��7ʤ��,��B9�P6���L�O��a�o���'�{��F�ܟ����_(g���q�o� �IY8���2�?)Ǎ�Q&�'e�8������q\�e�~R��~�L�O��q�o���IY8���r6��l�F�������(S�p��eR~R�C~��?(��1�����a��a +~2��}�L�O��q�/���e��7ʄ��,g�F�j����f�(�쓲p��V^z�}��Z�(듲p��eJ}R�;}�L�O��q�/���e��7���,��F�:����6�(�擲p�c�|�|�Q>���8�7��d,��Е��>�V㿫��vc������o ��⟮>s�a����?�����q��L�j��a�������?������_~���/�?�������':���_���ҧ�C�?�n{�엱lm ��ʚ8��Xg},[�����D�� �H�I�J����NV9ʢtb*묣�ek��u֑˲���:�(f��@lf�5�,Z f��:�Y�6�Yg�,[�z�� �~VYТubB묣�ek��u֑Ѳ���:�(i��@li�51-Z ��:zZ�6��Z'ݒZv�Z�U-K�]��&�E�Ĵ�YG[��b]�#�ek1�u�Qز����*k"[�.@�l�ut�lm ���:R[�6c[g�-[����&�E����YGs��bu�#�ek1�u�Q����*k�[�.@�o��k���0*p�pKp�X8�p�sT�,m v��:C\��@Lq�u��lm ָ�:r\�6�\gE.[�M��&�E��,�YG���b��#�ek1�u�Q粵���*k]�.@Lt�u4�lm V��:2]�6C]g�.[H����X���\�)�^����b�9G���b�묣�ek��Uք�h]���:�hw��@�w�u�lm ��: +^�6^eMċ�������� Ē�YG���b�묣�ek��U��h]���:�hz��@�z�ud�lm ��N����,��J9�^T6�^�}/K�����ė� ���YG���b竬 }Ѻ�1�u������X�:��}��@~�u�lm 6�ʚ���_g�/[�寳���� ���YG���b�k�3�&� +��YG��b�#fk)vҭfg�V���(]��;����@,��u$�lm F��:�`�6�`eM���i���6�� �:�YG��b 쬣fk�V�D�h]�� ;����@,��u��lm ���:ja�6{aeM0���ɰ��f�� �j�I�l����p�9G9��b;����Ѻ�1v�������n��:�+ߊ��@���n��Gw��y�� ��&��}�������ߪ�jid�J�' H$���Ăة+!f�1"vꪈY�A숕���1�)�SWK�jbM�ԕ�ڃ;uŬ� 6�JMT��Ĭة�+f��,v�J�Y�A�����bV{�b�&0FuRb��sc�f�ae�̕3ڃ;u�Ƭ� ��JMl����ة�7f��8v�J�Y�A�����cV{�c����9��SW{�jb}�ԕ�ڃ ;uȬ� 6�JM����٩�Cf��Dv�J�Y�A����jdV{�zd�� ͞�$ّ�&�ɚ�*ٙ+Kf�1L��֔��=�}�Z��6��U�|��X��?=�|��q���9N�[q�~��K�6��.��������F�|����W�����E��oz���7���ۗY�A|��Q��I��� +f��w0�ڃ�f��7G��7WjzsT{�{s��ޜ�1Ƚ�Rӛ�ڃܛ+5�9�=���BWo�f�qon�ݛ:�7WjzsT{�{s��7G��7WjzsT{�{s��ޜ�1Ƚ�Rӛ�ڃܛ+5�9�=Ƚ�Rӛ�ڃܛu�椎A�͕�����\���Q�A�͕�����ܨ�7'uro����� �� +]�9�5ǽ�2ӛ#ڃܛu�椎A�͕�����\���Q�A�͕�����ܨ�7'uro����� ��JMo�jro����� ��Fݽ9�c�{s��7G��7WjzsT{�{s��7G��77���I�ԛ+�ܛ�x=���Wo�b�qo����� ��B����A�͕�����\���Q�A�͕�����ܨ�7'uro����� ��JMo�jro����� ��Fݽ9�c�{s��7G��7WjzsT{�{s��7G��77hzs2{{sE��ɚ��\����A�͕�����ܨ�7'uro����� ��JMo�jro����� ��Fݽ9�c�{s��7G��7WjzsT{�{s��7G��77���I�ܛ+5�9�=Ƚ�Rӛ�ڃ؛+t��h���LoNd�qo����� ��JMo�jro����� ��Fݽ9�c�{s��7G��7WjzsT{�{s��7G��77���I�ܛ+5�9�=Ƚ�Rӛ�ڃܛ+5�9�=Ƚ�P/�9�s�{s��7G��7WjzsT{{s���͚��ܘ�7'tro����� ��JMo�jro����� ��Fݽ9�c�{s��7G��7WjzsT{�{s��7G��77���I�ܛ+5�9�=Ƚ�Rӛ�ڃܛ+5�9�=Ƚ�QwoN���\���Q�A���zs4k�{se�7G��77���I�ܛ+5�9�=Ƚ�Rӛ�ڃܛ+5�9�=Ƚ�QwoN���\���Q�A�͕�����\���Q�A�͍�{sR� ��JMo�jro����� ��JMo�jron�ݛ�:�7W���Ѭ9�͕�����\���Q�A�͍�{sR� ��JMo�jro����� ��JMo�jro.�Ko���\���Q�A�͕�����\���Q�A�͍�{sR� ��JMo�jro����� ��JMo�jbon���d���\�9�5ǽ�2ӛ#ڃܛgӪ7��q�ͯ������{����������o��q�>����O���vQ�>�Ϥ8���˗Ͽ��ӟ����?9������o?|��o?�����o�{��_�L����+���?�"{�M������?��������1�}�R�7�ڃ�7)t�Mh��M�L߄hr�d��7�:�oRj�&T{��&��oB��oRj�&T{��&��1�}�R�7�ڃ�7)5}�=�}�R�7�ڃ�7u�M��A�� ��I��P�A�� ��ɨ�o"uRߤ�s߄���M +\}�5�}�2�7!ڃ�7 ��7�:�oRj�&T{��&��oB��oRj�&T{��&��1�}�R�7�ڃ�7)5}�=�}�R�7�ڃ�7u�M��A�� ��I��P�A�� �ľɠ���9���&$k��&e�oB��oRj�&T{��&��1�}�R�7�ڃ�7)5}�=�}�R�7�ڃ�7u�M��A�� ��I��P�A�� ��ɨ�o"urߤ��M�� �MJM߄jbߤ��7�Ys�72}�=�}�2�7!ڃ�7)5}�=�}�R�7�ڃ�7u�M��A�� ��I��P�A�� ��ɨ�o"urߤ��M�� �MJM߄jrߤ��M�� �MB��M��A�� ��I��P�A���&4k��&c�1�}�R�7�ڃ�7)5}�=�}�R�7�ڃ�7u�M��A�� ��I��P�A�� ��ɨ�o"urߤ��M�� �MJM߄jrߤ��M�� �MF�}�c��&��oB��oR��Ь9�� ��ɨ�o"urߤ��M�� �MJM߄jrߤ��M�� �MF�}�c��&��oB��oRj�&T{��&��oB��o2��H��7)5}�=�}�R�7�ڃ�7)5}�=�}�Qw�D�ľI��oB��oRf�&D{��&��oB��o2��H��7)5}�=�}�R�7�ڃ�7)5}�=�}�P/}�s��&��oB��oRj�&T{��&��oB��o2��H��7)5}�=�}�R�7�ڃ�7)5}�=�}�A�7��s�7)r�MH��M�L߄hr�t�⨾ �ǹo��������1���w����7O��oZ�Iߔwj���>�i�M���?��//�����[�_���O������˿��]}����"��/T{�_�e���/R� ��K�y��=�/�Rj^��j�˿��8��8Ψ;�#ur���q�� �q +]q�5�q�2�!ڃ�u�q��A�㔚8��8N���P�A�㔚8��8Ψ;�#ur���q�� �qJM�jr���q�� �qF�q�c��8�&�C�9�Sj�8T{��8�&�C�9�3��H��)�ǡx=�q�W�b�q���q�� �qB��q��A�㔚8��8N���P�A�㔚8��8Ψ;�#ur���q�� �qJM�jr���q�� �qF�q�c��8�&�C�9�Sj�8T{��8�&�C�1�3h�82{�8E�8ɚ�8N����A�㔚8��8Ψ;�#ur���q�� �qJM�jr���q�� �qF�q�c��8�&�C�9�Sj�8T{��8�&�C�9�3��H��)5q�=�q�Rǡڃ�)t�qh��q�LGd�q���q�� �qJM�jr���q�� �qF�q�c��8�&�C�9�Sj�8T{��8�&�C�9�3��H��)5q�=�q�Rǡڃ�)5q�=�q�P/q�s��8�&�C�9�Sj�8T{�8��8͚�8Θ;�#tr���q�� �qJM�jr���q�� �qF�q�c��8�&�C�9�Sj�8T{��8�&�C�9�3��H��)5q�=�q�Rǡڃ�)5q�=�q�QwG��8N���P�A����84k��8e&�C�9�3��H��)5q�=�q�Rǡڃ�)5q�=�q�QwG��8N���P�A�㔚8��8N���P�A�㌺�8R� �qJM�jr���q�� �qJM�jrg�Ǒ:1�S��Ь9�㔙8��8N���P�A�㌺�8R� �qJM�jr���q�� �qJM�jr'�K��8N���P�A�㔚8��8N���P�A�㌺�8R� �qJM�jr���q�� �qJM�jbg��qd��q�\q�5�q�2�!ڃ�Q�%�8��8�D�?�㎿�o�N���8������_�>�<�ݽǭ�3�8.����/����w�ǟW���ۏ���_/����`����ǛǗ�//����>���� ���a��~����9��_��&u�s��<?����>����6�5��a+3�a#ڃ��P/�a�:�9l��9lT{���Vj��F��9l��9lT{���6�~��1��a+5�a�ڃ��R�6�=��a+5�a�ڃ��Q�sؤ�A~[�y��簕��Q�A~[�y��� ����9|[��9l$k���Vf��F��9l��9lT{���6�~��1��a+5�a�ڃ��R�6�=��a+5�a�ڃ��Q�sؤ�A~[�y��簕��Q�A~[�y��簍���&u�s�J�sب� ?���<��j�s� +]�a�Ys��!�6�=��a+3�a#ڃ��R�6�=��a+5�a�ڃ��Q�sؤ�A~[�y��簕��Q�A~[�y��簍���&u�s�J�sب� ?���<��j�s�J�sب� ?�-��sؠ�A~[�y��簕��Q�A|[��9l4k���6�~��1��a+5�a�ڃ��R�6�=��a+5�a�ڃ��Q�sؤ�A~[�y��簕��Q�A~[�y��簍���&u�s�J�sب� ?���<��j�s�J�sب� ?�m��6�c���Vj��F��9l���Ѭ9~[�y��簍���&u�s�J�sب� ?���<��j�s�J�sب� ?�m��6�c���Vj��F��9l��9lT{���Vj��F��9l���I���R�6�=��a+5�a�ڃ��R�6�=��au?�M������F���9le�9lD{���Vj��F��9l���I���R�6�=��a+5�a�ڃ��R�6�=��a��6�s���Vj��F��9l��9lT{���Vj��F��9l���I���R�6�=��a+5�a�ڃ��R�6�=��a4�a��s��"�s�H�?���<��h�s�Ǐ���{��þ~���9���1�þ{�9�o�5��a�?ry +;/)��/_>_������w��������\�=}���\�\|�x���~���WޯZ�|��7-���/Z �z�_�`��e�Ě�w,r�bȞ�,2�W ���� +�����9~��!�f"k�߫ ��Z {�_�`ȼS�Ț�7*2/T ���u +�����9~�� ����9~��!�"k�ߢ`ȼD�Ț�W(2��5�ݎ w�d�Q�c�s�C��;F[�q�c��0��5ǭ���%�9&��:�L�Cd�q�c�D:D�':�L�Cd�q�#ȝ���s�2m�5�e�!�Ys��2U�5�M� w�d�q�c��8D��8�L�Cd�q�cȔ8D�v8BL�`�a�c����w=����Xs��2� �5�� wzd�qxc�t7D�W7�LtCd�qrc�7D��6�ܹ �=DZ�!��Ys\�2� �5Ǚ�!S�Ys��r'6@�6�L_Cd�q]c��5D��5F\e ��c��/Y x5�Q��ԐXs\�2A �5�9�!S�Ys��r�4@��4�LGCd�qEc�D4D�'4�LACd�q?#ȝ���s�2��5��!�Ys��2��5�����%�9&�3�L/Cd�q-c��2D��2F\���c��pg2 �G2�L#Cd�q!c�2D��1�LCd�q#ȝ���s�2]�5�U�!�Ys��2E�5�=� wd�qcȴ0D��0�LCd�qc�T0D�70�� �=��!ӿYsX�q�/^�q�b��/$�w/����=�ы!ӼYs\�2��5ǹ�!S�Ysܺr�.@��.�L�Bd�q�b�D.D�'.�L�Bd�q�"ȝ���s�2m�5�e�!�Ys��2U�5�M� w�d�a�b�ճx=�5���Xs��2%�5�� w�d�q�b�4,D�,�L�Bd�q�b��+D��+t�s�2� +�5�Պ!�Ys��2� +�5ǽ� w�d�q�bȴ*D��*�L�Bd�q�b�T*D�6*BL�`�a�b�է�w=�u���Xs��V�L�/qS�2��.��K���x����3w)�3�0�~�)���~���2�_ߌQN+��������yx�=�Qo>|� %�����7}������Ǘ����"o��Ͼ���A�r{��γS�gY���s������G�+�A��8�Qf�D{�������1��R���ڃ\�(5��=��RS��ڃ��uG@��A����H�I�P�A������Ȩ;"ur��4A�� WAJM�jr�ԔA�� �AF�q�c�� e�� �ǰR�J�P�9����J��NH��P�9ȩ�R� +�ڃ\)5��=���RS�ڃ�uGC��AΆ��n��rH�I�P�A����z��~Ȩ; "urB��4D�� WDJMF�jrH�ԔD�� �DMLDf�aN���!Ys\)3I�=�Q�RS�ڃ�u�E��AN������H�ɋP�A�������Ȩ;2"urf��tF�� �FJMj�jrl���F�� �FF���c��#��9B��:Rj�#T{�#���͚��Ȑ����9Ώ�����I�I�P�A���� + ��ɨ;D"ur��ԴH�� �HJM��jr���I�� 7IF�Q�c��$��KB��LRj�$T{��$��NB��O�%Pur���4J�� WJJM��jb���U*�Ys�*s�J��AΕ��^ ��bI�I�P�A����j ��nɨ;\"ur��ԴK�� �KJM��jr���L�� 7LF��c�3&��cB��dRjR&T{�c&��fB��g2��H��4)5M�=�U�BWքf�qؤ̔M�� �MF�q�c��&��oB��pRj'T{�#'��rB��s2��H��:)5��=ȵ�R�;�ڃ<)5��=�͓Qw�D���I��P�A.���� ���I���P�A�(R� &P +] �5��2�A!ڃB)5%�=�-�QwE��J��P�A.���$ +��(J���P�Az �@���F)5m�=�u�R�G�ڃH)5��=ȍ�Qw$E��LJ��P�A.���T +��XJ���P�A��`�̞�dJ���B�渚Rf�)D{�é�H�S�=���u�t�N���>�?;~x|�>�3�x�a�S����/���N��V�˯�/���OOG?rw��7���_4�������y���/�z��;j[�7���>��<P�o>>}�����=x���M�i�P�An┚&��&Ψ��#ur��4q�� 6q +]M�5�M�2��!ڃ��u7q��An┚&��&N�i�P�An┚&��&Ψ��#ur��4q�� 7qJM�jr��4q�� 7qF�M�c��8���C���Sj�8T{��8���C���3�n�H���)��ġx=�M�W�b�q��4q�� 7qB�4q��An┚&��&N�i�P�An┚&��&Ψ��#ur��4q�� 7qJM�jr��4q�� 7qF�M�c��8���C���Sj�8T{��8���C���3h�82{�8E�&ɚ�&N�i��An┚&��&Ψ��#ur��4q�� 7qJM�jr��4q�� 7qF�M�c��8���C���Sj�8T{��8���C���3�n�H���)5M�=�M�R�ġڃ��)t5qh�6q�LGd�q��4q�� 7qJM�jr��4q�� 7qF�M�c��8���C���Sj�8T{��8���C���3�n�H���)5M�=�M�R�ġڃ��)5M�=�M�P/M�s��8���C���Sj�8T{�8��&͚�&Θ��#tr��4q�� 7qJM�jr��4q�� 7qF�M�c��8���C���Sj�8T{��8���C���3�n�H���)5M�=�M�R�ġڃ��)5M�=�M�QwG��&N�i�P�Al���84k��8e��C���3�n�H���)5M�=�M�R�ġڃ��)5M�=�M�QwG��&N�i�P�An┚&��&N�i�P�An⌺�8R� 7qJM�jr��4q�� 7qJM�jrg��đ:��S�j�Ь9n┙&��&N�i�P�An⌺�8R� 7qJM�jr��4q�� 7qJM�jr'�K��&N�i�P�An┚&��&N�i�P�An⌺�8R� 7qJM�jr��4q�� 7qJM�jbg�4qd�6q�\M�5�M�2��!ڃ��Q�%�8��&�:@�x�����bwO�7������3�&��j���_��嗯?����0�H9���J{�b�¸�'�m��o{؟��E��V{��������ĩ�?a��?Qj�T� �'N]� �=���SW�jb��՟�ڃ؟(5� �c��������ĩ�?a��?q��OX�A�O����1��3��',^�Q��s�b�a��՟0ڃ؟u�'��A�O���V{��������ĩ�?a��?Qj�T� �'N]� �=���SW�jb��՟�ڃ؟(5� �c��������ĩ�?a��?q��OX�A�O��4{��G��&k�g������ĩ�?a��?Qj�T� �'N]� �=���SW�jb��՟�ڃ؟(5� �c��������ĩ�?a��?q��OX�A�O����1���SW�jb��՟�ڃԟ8�ܟ�Ysԟ(r�'H��'�\� �=���SW�jb��՟�ڃ؟(5� �c��������ĩ�?a��?q��OX�A�O����1���SW�jb��՟�ڃ؟8u�'�� �'F�� �s��������ĩ�?a��?q�?a��?Qf�D� �'N]� �=���SW�jb��՟�ڃ؟(5� �c��������ĩ�?a��?q��OX�A�O����1���SW�jb��՟�ڃ؟8u�'�� �'JM����ĩ�?a��?q�?a��?q��O�A�O����1���SW�jb��՟�ڃ؟8u�'�� �'JM����ĩ�?a��?q��OX�A�O���V{���?Aub��՟�ڃ؟8u�'�� �'N]� �=���Rӟ�:�?q�?a��?q��O�A�O���V{���?Aub��՟�ڃ؟8u�'�� �'N]� �=���QwB���ĩ�?a��?q��OX�A�O���V{���?Aub��՟�ڃ؟8u�'�� �'N]� �=H��BW�f�Q��s�d�a��՟0ڃ؟@@a���>S��a����ܿ��)����W��o�}z<�����/�>�����U�����_����>����?��ӫ������Wf�~s%��;��������|�|����7O/O ��o��Ͼ�����xs���/J=��ԧ��;��?��ڃo�O���;��?�f������[i�?�ڃ�����Uϟ}G�����ӳ��=���V�oo�^�Dc��YV���z��Uϟ}G����������?��ڃ����_�z��;j�]E|8�4<85�Eu�����G��?��ڃ����Tϟ}G�����pk��g�Q{�m�������e.�eu��7���R=���ӿ�d��g�Q{�@}�y�?��>��Yso�w�_C}r��g�����Ѫ�Ͼ����z�?�I���w�<PO?�R=��^z�i����,�c�@=�4�=H���w�<P��Ku�z+�=�/`u�z+�=�/`Uj^�����:u������:u������:u������*5/`Eu�X��^��j�Xz~+�5�/`u�z+�=�/`U�>�A��J�T{�`(50P�A>����@����Q�R� �Pj`�ڃ|�C�9��j�����=�0��`�:���Rs���J�T{�`(50P�A>�a�}���1H0�y>�����P�:��b��e���=�0�z9���J�T{�`(50P�A>����@����Q�R� �Pj`�ڃ|�C�9��j�����=�0��`�:���Rs���J�T{�`(50P�A<�a�� �����"�$k�`(30�A>����@����Q�R� �Pj`�ڃ|�C�9��j�����=�0��`�:���Rs���J�T{�`(50P�A>�a�}���1�0���� �Pj`�ڃx�C����5�0�D��Pf` ڃ|�C�9��j�����=�0��`�:���Rs���J�T{�`(50P�A>�a�}���1�0���� �Pj`�ڃ|�C�9��j��^`�:���Rs���J�T{`(t�@�����1�B� �Pj`�ڃ|�C�9��j�����=�0��`�:���Rs���J�T{�`(50P�A>�a�}���1�0���� �Pj`�ڃ|�C�9��j�����A>����@����B�4k�`(30�A>�a�}���1�0���� �Pj`�ڃ|�C�9��j�����A>����@����Rs���J�T{�`u� u�����=�0���� �Pj`�ڃ|�è���c`(t�@�����2s���J�T{�`u� u�����=�0���� �Pj`�ڃ|�C����A>����@����Rs���J�T{�`u� u�����=�0���� �Pj`�ڃx�à9�Af��E�H��Pf` ڃ|���9��=�0��M�8����-�x<?�B0�G�0���������}}������/���e�������ӿ��/�]��}��ۛ��g�^����,�c�@��y~��Y��?��ڃ���íUϟ}G�������L�Rϟ}G�����ۛ��N]�eu��7OOV=���Ǜ��g��z��;j�O7O/�9���g�Q{��x˺fc�}��1��q���8�� ��Qj��ڃ|G�9��j�y��<�=��q���8�� ��Qj��ڃ|G�9��j�y���8��A>��Ԝ�A��<�Rs���8J�yT{����r�9��q���8�� ��Qj��ڃ|G�9��j�y���8��A>��Ԝ�A��<�Rs���8 +]�qЬ9>�c�}��1��q���8�� ��Qj��ڃ|G�9��j�y���8��A>��Ԝ�A��<�Rs���8J�yT{���u��!u�y��<�=��q���8�� ��Qj��ڃ|Ǩ�<�c���(5�qP�A<���u͚��8��yD{���u��!u�y��<�=��q���8�� ��Qj��ڃ|Ǩ�<�c���(5�qP�A>��Ԝ�A��<�Rs���8F��qH�|G�9��j�y��<�=��q���8�� ��1�>�C���8�<��A�z��(p��A���<�2s���8B���u�y��<�=��q���8�� ��Qj��ڃ|Ǩ�<�c���(5�qP�A>��Ԝ�A��<�Rs���8F��qH�|G�9��j�y��<�=��q���8�� ��1h���sxG��<�5��q���8�� ��Qj��ڃ|Ǩ�<�c���(5�qP�A>��Ԝ�A��<�Rs���8F��qH�|G�9��j�y��<�=��q���8�� ��1�>�C���8J�yT{���(5�qP�A<���u͚��8��y"{���(3�q�A>��Ԝ�A��<�Rs���8F��qH�|G�9��j�y��<�=��q���8�� ��1�>�C���8J�yT{���(5�qP�A>��Ԝ�A��<�P/�q@��|G�9��j�y��<�=��q���Ys|ǘ�<�c���(5�qP�A>��Ԝ�A��<�Rs���8F��qH�|G�9��j�y��<�=��q���8�� ��1�>�C���8J�yT{���(5�qP�A>��Ԝ�A��<�Q�yR� ��Qj��ڃxG��<�5��q���8�� ��1�>�C���8J�yT{���(5�qP�A>��Ԝ�A��<�Q�yR� ��Qj��ڃ|G�9��j�y��<�=��q����:�<�Rs���8J�yT{���(5�qP�A>�c�}��1��q���Ys|G�9��h�y��<�=��q����:�<�Rs���8J�yT{���(5�qP�A>�#��yP� ��Qj��ڃ|G�9��j�y��<�=��q����:�<�Rs���8J�yT{���(5�qP�A<�cМ�!���<�"�y$k���(3�q�A>�CW_�y���8��h������<���c�N���8�#��8�y��������ӗ��8�s�j��)����?T�G?T��"���q���v|\����"�� Qj���ڃ|\Ĩ���c���(5�EP�A>.��A����Rs\���"�q2{���(3�E�A>.��A����Rs\���"F��EH�|\D�9.�j�q���=��E���"�� ���s���(5�EP�A>.��A����Rs\���"F��EH�|\D�9.�j�q���=��E����Ys|\Ę���c���(5�EP�A>.��A����Rs\���"F��EH�|\D�9.�j�q���=��E���"�� 1�>.B���"J�qT{���(5�EP�A>.��A����Q�qR� Qj���ڃx\D���5��E���"�� 1�>.B���"J�qT{���(5�EP�A>.��A����Q�qR� Qj���ڃ|\D�9.�j�q���=��E�����:���Rs\���"J�qT{���(5�EP�A>.b�}\��1H�E�y>.���Q�:.�b��qe��=��E�z9.���"J�qT{���(5�EP�A>.��A����Q�qR� Qj���ڃ|\D�9.�j�q���=��E�����:���Rs\���"J�qT{���(5�EP�A<.b�!���"�q$k���(3�E�A>.��A����Q�qR� Qj���ڃ|\D�9.�j�q���=��E�����:���Rs\���"J�qT{���(5�EP�A>.b�}\��1��E���"�� Qj���ڃx\D���5��E��"D�Qf�� ڃ|\D�9.�j�q���=��E�����:���Rs\���"J�qT{���(5�EP�A>.b�}\��1��E���"�� Qj���ڃ|\D�9.�j�q�^���:���Rs\���"J�qT{��(tA�����1�qB� Qj���ڃ|\D�9.�j�q���=��E�����:���Rs\���"J�qT{���(5�EP�A>.b�}\��1��E���"�� Qj���ڃ|\D�9.�j�q���"��A>.��A��B�q4k���(3�E�A>.b�}\��1��E���"�� Qj���ڃ|\D�9.�j�q���"��A>.��A����Rs\���"J�qT{���u!u�q���=��E���"�� Qj���ڃ|\Ĩ���c��(tA�����2s\���"J�qT{���u!u�q���=��E���"�� Qj���ڃ|\D���"��A>.��A����Rs\���"J�qT{���u!u�q���=��E���"�� Qj���ڃx\Ġ9.Bf��qE��"H�Qf�� ڃ|\/f�\������-����"��c���"���[�-r������:-�o����~�嗯?�����"��#����ޞ������������;_-���n���7/������Q${�y~��YC�?�d���7��<�ɚ; O?�/���Q&k��`�����o� +r}ɞ; ��C��5��p�[8D�_�1d�Ys|G�� +�=�7p�8D��1d��Ys|�Ɛ9~Cd���!�� �5�wo��7$��1dn�Ys|�Ɛ9xCd��A�k7@�ߺ1dN�Ys|�Ɛ�sCd��C�� �5�'n�'/n��1��m��6D��1dn�Ys|�Ɛ9lCd��YA�6@�ߴ1dN�Ys|�Ɛ�gCd��5#�c6^��)�K6 �߱1d��Ys|�Ɛ�aCd��C� �5��k�����s|�Ɛ9]Cd���C�n �5�Wk��5D����Xd��C�\ �5��j�[5D�_�1d�Ys|�F��J �=�7j�5D��1�OC��_�1`�ӐXs|�F��2 �=�wi��4D��1dn�Ys|�Ɛ9HCd��9A�k4@�ߢ1dN�Ys|�Ɛ�CCd��C� �5�'h�/���s|Ɛ9?Cd���C���5Ǘg��3D����:d����O�w5�g����w=��f�c3$���y��\�9&�ߙ1d��Ys|dƐ�1Cd��C���5��e�����s|[Ɛ9-Cd��aC��5�We��2D����(d��=C��5��d�[2D�_�1d�YsxFF��"`�� �2�]���~�5��c��1D����d���C�l�5�Gc��1D�_�1d�Ys|.F��Z�=Ƿb�S1D��1d��Ys|%Ɛ9Cd��A�1@�߇1d��Ys|Ɛ� Cd��e#��0^��Y��*x5�7a��0$��1d��Ys| Ɛ9Cd��)A�K0@�߁1d��Ys|Ɛ�Cd��C���5��_�����s|�Ő9�Bd���C���5�W_��/D��|y��\|9&��{1dνYs|�Ő��Bd��#�C/^���+/ ��x1dN�Ys|�Ő��Bd��uC��5ǧ]�/���s|�Ő9�Bd��QC��5�]��.D��s��d��-C��5LJ\�;.D�_q1d��Ys|�E����=��[��-D�o1��B��_n1`��Xs|�E��j�=�7[��-D�l1d�Ys|�Ő9�Bd��A�K-@��i1dδYs|�Ő��Bd��C�@�5��Y�����s|�Ő9�Bd��aC�.�5�WY��,D��d��d��=#�s,^��1��5ǗX�C,D��a��d�� C��5�X��+D�__1d��Ys|z�}�ry�s|wŐ9�Bd���C�� +�5�W��+D��[侶d��C�� +�5LJV�;+D�_Y1d��YsxbE���`��}��*�]��q� +�5ǗU����*�%�wU���U9���-_U�{��?�G�Ϊ����|ZwU����|��矾|}���Ӈ˿� ���g����*�|�}�����x�E��c��q(5�8P�A�ȡԜ�@��(�Rs���F݇9H�|�C��́j�u��<�=�:���� ��0h�t��s|�C��Ӂh���T�=��:��k�� ��0�>�A��J��T{��v(5g;P�A>ܡ�\�@��v�P/�;@��|�C��߁j����=�G<��+�� ��0�>�A��SJ�-T{��y(5�<P�A<��u�͚���G=�|�C���j�e���=��=����� ��0�>�A��J͍T{��|(5g>P�A>���\�@��ևQ��R� ��Pj�}�ڃ|�C�9��j������=�w?���:��Rs���� +]�?Ь9>���\�A���Q�R� �Qjڃ| D�9�j�1���=��@����:�$�Rs�� J�YT{��(5�AP�A� b�}��1��A��� �� _QjN��ڃ|$D���j���C!��A:������Z�k��(3C�A�"���P� � Qjڃ|9D�9�j����z�=��C����:���RsC��+"J�T{��(5�DP�A�%b�}L��1��D��{"�� _QjN��ڃ|TD��*�j�]���=��E�n� Ys|]D�9/�h�����=�7F�����:�̈Rsg��K#JͩT{���(5�FP�A�7b�}p��1�'G���#�� _QjΎ�ڃ|xD��<�j�����#��A>?���A���Rs���#$ +]WHЬ9�Cb�"!����2s���k$J�9T{��(5IP�A�Ib�}���1�gI���$�� _&QjN��ڃ|�D��N�j�}��%��A>Q���(A��J�Rs���C%JͥT{�o��r��9��J��{%�� _,QjN��ڃx�D��j �5�wK���:�t�Rs����%J��T{��(5LP�A�ab�}Ą�1�gL��;&�� _2QjN��ڃ|�D��f�j�=��&��A>i���4A����Rs����&J�eT{�o�u7!u�y�� �=�N�N��Ys|�D��r�h���C'��A>u���:A��ډRs���'J��T{�o�u=!u����� �=ȗO���'�� ?Qj���ڃ|�Ĩ�� +�c�O�(57PP�A���ԜAA���Rs ��[(F��PH�xE�� +�5�Q���(�� EQj���ڃ|Ũ�0 +�c�O�(5�QP�A���ԜGA��@�Rs!��)B�Iu���N +�=ȗR��S)�� KQj���ڃ|/Ũ�` +�c�O�(57SP�A���ԜMA��p�Rs9���)��2{ϧ(r�OA�����2sB��#*��A���3*�wK>�Q9���R���y�� �����<�C*����?���r�p����1��)ߞ�f�������÷'��[�C�_�u\~�t�����������=���p���>��<P�o^9�~��;f��������<�������Uϟ}G���Տ����4��ϲ:�����o�+���w�<PO? �V=���uI�9��j�%��3K��A>��ԜYB��̒Rsf ��3KJ͙%T{��,u�Y"u�%����=�g���3K�� �YRj�,�ڃxfɠ9�Df��%e���=�g���3K�� �YRj�,�ڃ|fɨ���c��,)5g�P�A>��ԜYB��̒Rsf ��3KB��Yu�%����=�g���3K�� �YRj�,�ڃ|fɨ���c��,)5g�P�A>��ԜYB��̒Bי%4k��,s�Y"t�%����=�g���3K�� �YRj�,�ڃ|fɨ���c��,)5g�P�A>��ԜYB��̒Rsf ��3KF�g�H�|fI�9��j�%����=�g���3K�� �Y2�>�D��3KJ͙%T{�,)t�YB���̒2sf ��3KF�g�H�|fI�9��j�%����=�g���3K�� �Y2�>�D��3KJ͙%T{��,)5g�P�A>��ԜYB��̒Q��%R� �YRj�,�ڃ|fI�9��j�%����=�g����,�:�̒2�g�P��3K +\g�P�9>��̜YB��̒P/g�@��|fI�9��j�%����=�g���3K�� �Y2�>�D��3KJ͙%T{��,)5g�P�A>��ԜYB��̒Q��%R� �YRj�,�ڃ|fI�9��j�%����=�g��3Kd��YR�:��d��%e���=�g���3K�� �Y2�>�D��3KJ͙%T{��,)5g�P�A>��ԜYB��̒Q��%R� �YRj�,�ڃ|fI�9��j�%����=�g����,�:�̒Rsf ��3KJ͙%T{�,)t�YB���̒!sf�Ȟ�3K�̙%D{��,)5g�P�A>��ԜYB��̒Q��%R� �YRj�,�ڃ|fI�9��j�%����=�g����,�:�̒Rsf ��3KJ͙%T{��,)5g�P�A>�$�˙%P� �YRj�,�ڃ|fI�9��j�%��3Kh��Y2�>�D��3KJ͙%T{��,)5g�P�A>��ԜYB��̒Q��%R� �YRj�,�ڃ|fI�9��j�%����=�g����,�:�̒Rsf ��3KJ͙%T{��,)5g�P�A>�d�}f��1�g���3K�� �YR�:��f��%e���=�g����,�:�̒Rsf ��3KJ͙%T{��,)5g�P�A>�d�}f��1�g���3K�� �YRj�,�ڃ|fI�9��j�%��3K��A>��ԜYB��̒Rsf ��3KJ͙%T{��,u�Y"u�%��3Kh��YRf�,!ڃ|fI�9��j�%��3K��A>��ԜYB��̒Rsf ��3KJ͙%T{��, �rf �9�g���3K�� �YRj�,�ڃ|fI�9��j�%��3K��A>��ԜYB��̒Rsf ��3KJ͙%T{�,4g���9<���uf ɚ�3K�̙%D{��,Rg��{��,]_5:>�t�=~�p�t���G�~+�͋F�ϧ�@ݝ��g��,�ׇ�Z�]������凿���/�������3��~��^��==������m>t�m��7��q��jb���w�ڃw:uŝ�� ƝJM܉�ĸө+�d�1�t�;Y�A�;���NV{�N�&�Dub���w�ڃw:uŝ�� ƝN]q'�=�q�Rw�:1�t�;Y�A�;z�;٬9�;���NF{�N�&�Dub���w�ڃw:uŝ�� ƝN]q'�=�q�Rw�:1�t�;Y�A�;���NV{�N�����ĸS��;Q�w:uŝ�� ƝN]q'�=�q�SW��jbܩ�ĝ��A�;��-�d�z��N��Nk�Ng����ĸӨ;�$ub���w�ڃw:uŝ�� ƝN]q'�=�q�Rw�:1�t�;Y�A�;���NV{�N�����ĸS��;Q�w:uŝ�� ƝN]q'�=�q�SW��jRܩ�w��sw:�w2Ysw:sŝ�� ƝN]q'�=�q�Rw�:1�t�;Y�A�;���NV{�N�����ĸS��;Q�w:uŝ�� ƝN]q'�=�q�SW��jbܩ�ĝ��A�;���NV{�N�������ӡ縓͚��S�+�D��0�t�;�A�;���NV{�N�����ĸS��;Q�w:uŝ�� ƝN]q'�=�q�SW��jbܩ�ĝ��A�;���NV{�N�����ĸө+�d�1�4�;I��w:uŝ�� ƝN]q'�=Hq�C�q'�5�q�2w":1�t�;Y�A�;���NV{�N�����ĸS��;Q�w:uŝ�� ƝN]q'�=�q�SW��jbܩ�ĝ��A�;���NV{�N�����ĸө+�d�1�Tj�NT� ƝN]q'�=Hq�C�q'�5�q�3W��hbܩ�ĝ��A�;���NV{�N�����ĸө+�d�1�Tj�NT� ƝN]q'�=�q�SW��jb���w�ڃw*5q'�c�N�����ĸө+�d�1�t�;Y�A�;����1Hq�C�q'�5�q�3W��hb���w�ڃw*5q'�c�N�����ĸө+�d�1�t�;Y�A�;���NR� ƝN]q'�=�q�SW��jb���w�ڃw*5q'�c�N�����ĸө+�d�1�t�;Y�A�;��N4{��NG��N&k�Ng����ĸ����N��>S%�a� �cĝw�ĝ/��Շ�;�gw�%��??����?��?���[�*~xy��b��A��{>�Aۯ/��>t�__��9~}1�=��/v�z}1�=��/6�~}1�s__����bV{__����bV{__����bV{__�Լ��1��/v�z}1�=��/v�z}1�=H�/v����l���X��p'tr���� �JM�jr���� �F݅;�c�w��pG��pWj +wT{�w��pG��p7�.�I�\�+5�;�=ȅ�RS��ڃ\�+5�;�=ȅ�Qw�N���]�)�Q�A,�� +w4k�we�pG��p7�.�I�\�+5�;�=ȅ�RS��ڃ\�+5�;�=ȅ�Qw�N���]�)�Q�A.ܕ�����]�)�Q�A.܍�wR� �JM�jr���� �JM�jr�n�]��:�pW�pG�zw��Ś��]�)��A.܅z)�A��\�+5�;�=ȅ�RS��ڃ\�+5�;�=ȅ�Qw�N���]�)�Q�A.ܕ�����]�)�Q�A.܍�wR� �JM�jr���� �JM�jb�n��d��\�;�5Dž�2S�#ڃ\�+5�;�=ȅ�Qw�N���]�)�Q�A.ܕ�����]�)�Q�A.܍�wR� �JM�jr���� �JM�jr�n�]��:�pWj +wT{�w��pG��pW�*�Ѭ9,� �Ȟ��]�)��A.ܕ�����]�)�Q�A.܍�wR� �JM�jr���� �JM�jr�n�]��:�pWj wT{�w��pG��pWj -wT{�w���1ȅ�RS��ڃ\�+5�;�=ȅ�RS��ڃX�4�;�=���"W�d�q���� �JM�jr�n�]��:�pWj +wT{�w�^ +wP� �JM�jr���� � +]�;�5Dž�1w�N���]�)�Q�A.ܕ�����]�)�Q�A.܍�wR� �JM�jr���� �JM�jr�n�]��:�pWj wT{�w��pG��pWj -wT{�w���1ȅ�RS��ڃ\�+5�;�=ȅ�RS��ڃ\�uA.ܕ�����]�)�Q�A,�� -w4kwC�p'��pWf -wD{�w��pG��pWj -wT{�w���1ȅ�RS��ڃ\�+5�;�=ȅ�RS��ڃ\�uA.ܕ�����]�)�Q�A.ܕ�����]����9ȅ�RS��ڃ\�+5�;�=���BW�f�q�n�]�:�pWj +wT{�w���1ȅ�RS��ڃX�+t�h���L�hr�n�]��:�pWj wT{�w��pG��pWj -wT{�w���1ȅ�RS��ڃ\�+5�;�=ȅ�RS��ڃ\�uA.ܕ�����]�)�Q�A.ܕ�����ݨ�p'ur���� � -]�;�5Dž�2S�#ڃ\�uA.ܕ�����]�)�Q�A.ܕ�����ݨ�p'ur���� �JM�jr���� �F݅;�c�w��pG��pWj -wT{�w��pG��p7�.�I�X�+t�h���L�hr���� �F݅;�c�w��pG��pWj -wT{�w��pG��p�pur���� �JM�jr���� �F݅;�c�w��pG��pWj -wT{�w��pG��p7h -w2{wE��ɚ��]�)��A.�)��;>ǥp��ɿ�����~���LJ���Vӯ[T��7��=0��ߞN��|��_����??��`>���������A��G�x�A�� �4�=��SW�jb��dШ�A̠��2hV{3h�����ڡ��͚�Z�ɠ��A;ueЬ� f�N]4�=��SW�jb��dШ�A̠��2hV{3h�����ک+�f�1�Vj2hT� f�N]4�=��SW�jb�ԕA�ڃ�A+54�c3h�����ڡ��͚�ڙ+�f�1�Vj2hT� f�N]4�=��SW�jb�ԕA�ڃ�A+54�c3h�����ک+�f�1�v�ʠY�A̠���1��SW�jb�ԕA�ڃ�A;ueЬ� f�JM���ڙ�2ho�(�v�%�f��0�v�ʠ�A̠��3hR� f�N]4�=��SW�jb�ԕA�ڃ�A+54�c3h�����ک+�f�1�v�ʠY�A̠���1��SW�jb�ԕA�ڃ�A;ueЬ� e� -]4�=G�#/4�5��3W�hb�ԕA�ڃ�A+54�c3h�����ک+�f�1�v�ʠY�A̠���1��SW�jb�ԕA�ڃ�A;ueЬ� f�JM���ک+�f�1�v�ʠY�Aʠzɠ٬9ʠ�2h${3hg����ک+�f�1�v�ʠY�A̠���1��SW�jb�ԕA�ڃ�A;ueЬ� f�JM���ک+�f�1�v�ʠY�A̠��2hV{3h����9��SW�jb�ԕA�ڃ�A;��A�Ys�A+34�c3h�����ک+�f�1�v�ʠY�A̠���1��SW�jb�ԕA�ڃ�A;ueЬ� f�JM���ک+�f�1�v�ʠY�A̠��2hV{3h�&�Fub�ԕA�ڃ�A;��A�Ys�A;seЌ� f�JM���ک+�f�1�v�ʠY�A̠��2hV{3h�&�Fub�ԕA�ڃ�A;ueЬ� f�N]4�=��R�A�:1�v�ʠY�A̠��2hV{3h�����Z�ɠQ��A;��A�Ys�A;seЌ� f�N]4�=��R�A�:1�v�ʠY�A̠��2hV{3h�����ڨ;�&ub�ԕA�ڃ�A;ueЬ� f�N]4�=��R�A�:1�v�ʠY�A̠��2hV{3h�����Z�+�F��(�v�%�f��0�v�ʠ�A̠!�54?Ƿ�Ts|�A�s�u�>����>=⇾�d�+���_~�鏗��}�������������/�� ��_�x<}wC����ǣ.z���;�y�����s@��jr����� �JM��jr�i�x�:9�TjOT{�O�&�D�9�TjOT{�O�����1ȁ�Rx�ڃx*5�'�=ȁ�Rx�ڃxu���A<������S�+�D��8�TfOD{�O�����1ȁ�Rx�ڃx*5�'�=ȁ�Rx�ڃxu���A<������S� <Q�A<������Ө;�$ur����� �JM��jr����� �F݁'�c�Oe^Oo�0�T� -<Q�9<������S����9ȁ�Rx�ڃx*5�'�=ȁ�Rx�ڃxu���A<������S� <Q�A<������Ө;�$ur����� �JM��jr����� �M�If�a��x"Ysx*3�'�=ȁ�Rx�ڃxu���A<������S� <Q�A<������Ө;�$ur����� �JM��jr����� �F݁'�c�O�&�D�9�TjOT{O���͚��Ӑ <��9<������S� <Q�A<������Ө;�$ur����� �JM��jr����� �F݁'�c�O�&�D�9�TjOT{�O�&�D�9��5�ur����� �JM��jb��x�Ysxs���A<������S� <Q�A<������Ө;�$ur����� �JM��jr����� �F݁'�c�O�&�D�9�TjOT{�O�&�D�9�4�<I�x*5�'�=���BW��f�q����� �F݁'�c�O�&�D�9�TjOT{�O�&�D�9�4�<I�x*5�'�=ȁ�Rx�ڃx*5�'�=ȁ�Qw�I���S� <Q�A<������S� <Q�A<��OR� � -]�'�5ǁ�2x"ڃx*5�'�=ȁ�Qw�I���S� <Q�A<������S� <Q�A<�z <A��x*5�'�=ȁ�Rx�ڃx*5�'�=ȁ�Qw�I���S� <Q�A<������S� <Q�A< ���̞��S�+�D��8�TfOD{�O�E���q <ok�����9F�y� �<�-���_�0�\�I��������O���ߞ>����������\��?���?�ݏ�������Ư �>��?�/��9�=S^�����o|� P^�ڃ\^*5�%�=��QwyI���R�)/Q�A./������R�)/Q�A./���KR� ��JMy�jry�Ԕ��� ��JMy�jryi�]^�:��Tj�KT{�K���͚��R�)/�A./���KR� ��JMy�jry�Ԕ��� ��JMy�jryi�]^�:��Tj�KT{��K���D���Tj�KT{��K����1��RS^�ڃ\^*5�%�=��RS^�ڃ\^u����A*/�y)/Q���R���D�渼Tf�KD{��K�^�KP� ��JMy�jry�Ԕ��� ��JMy�jryi�]^�:��Tj�KT{��K���D���Tj�KT{��K����1��RS^�ڃ\^*5�%�=��RS^�ڃX^4�%�=��"Wy�d�qy�̔��� ��JMy�jryi�]^�:��Tj�KT{��K���D���Tj�KT{��K����1��RS^�ڃ\^*5�%�=��RS^�ڃ\^u����A./������R�)/Q�A,/��K4k�KC��$�縼Tf�KD{��K���D���Tj�KT{��K����1��RS^�ڃ\^*5�%�=��RS^�ڃ\^u����A./������R�)/Q�A./������R����9��RS^�ڃ\^*5�%�=��BWy�f�qyi�]^:��Tj�KT{��K���D���Tj�KT{��K����1��RS^�ڃ\^*5�%�=��RS^�ڃ\^u����A./������R�)/Q�A./������Ҩ��$ury�Ԕ��� �� -]�%�5��2S^"ڃ\^u����A./������R�)/Q�A./������Ҩ��$ury�Ԕ��� ��JMy�jry�Ԕ��� ��F��%�c��K���D���Tj�KT{��K���D���4�./I�X^*t��h����Ly�hry�Ԕ��� ��F��%�c��K���D���Tj�KT{��K���D���굼ury�Ԕ��� ��JMy�jry�Ԕ��� ��F��%�c��K���D���Tj�KT{��K���D���4h�K2{�KE��ɚ��R�)/�A./��%>ǥ��������������Y?(/���u����ӧ��������Z^�V{�7������O_���ǧ�?ĻR�y���8j,w���;��G=��>tL��A�� �ĎI��cB��cRf:&D{�;&��1��R�1�ڃ�1)5�=��R�1�ڃ�1uwL��A�� ��I��P�A�� ��ɨ�c"urǤ�tL�� wLJMDŽjrǤ�tL�� wLF��c�:&e^:&oǰcR��P�9�� ��I� �9��R�1�ڃ�1)5�=��R�1�ڃ�1uwL��A�� ��I��P�A�� ��ɨ�c"urǤ�tL�� wLJMDŽjrǤ�tL�� vLM�Df�aǤ��1!Ys�1)3�=��R�1�ڃ�1uwL��A�� ��I��P�A�� ��ɨ�c"urǤ�tL�� wLJMDŽjrǤ�tL�� wLF��c�;&��cB��cRj:&T{;&��� ͚Îɐ阈�9�� ��I��P�A�� ��ɨ�c"urǤ�tL�� wLJMDŽjrǤ�tL�� wLF��c�;&��cB��cRj:&T{�;&��cB��c�curǤ�tL�� wLJMDŽjbǤ��1�Ys�1swL��A�� ��I��P�A�� ��ɨ�c"urǤ�tL�� wLJMDŽjrǤ�tL�� wLF��c�;&��cB��cRj:&T{�;&��cB��c2��H��1)5�=��BWDŽf�qǤ�tL�� wLF��c�;&��cB��cRj:&T{�;&��cB��c2��H��1)5�=��R�1�ڃ�1)5�=��Qw�D��I��P�A�� ��I��P�A�;&R� vL -]�5��2�1!ڃ�1)5�=��Qw�D��I��P�A�� ��I��P�Az�@���1)5�=��R�1�ڃ�1)5�=��Qw�D��I��P�A�� ��I��P�A����̞ÎI��cB��cRf:&D{�;��GuL����6:�ctL�tL�O��q�t�ɵb�_���)_:=������N�t~��z��|����o������N������/o��ϴ]~�b���u��W���9��!� <"k�?�g�|��Ț�� r�Ȟ�O�2_�#����w��g9��!��;"k��x'���; {�?wg�|�Ț�o�2��#���Cw�LJd�q*���s��2e(�5�]�WJ��G�LJb�q*���s��25(�5�-�!��Ys�2(�5�� w -d�qj��D����L�Id�q�iȴ�D������'�=�٧!S}Ys�|2�'�5���!�{Ys\{ -rǞ@��������La�i��yw;Ƒ��x�Xs\x~L^�cr�q�i�ԝD����L�Id�q�i�t�D�W���Q'�=�I�!StYs�s29'�5�1�!�rYs\r -r��@�g��L�Id�q�i�$�D���L�Id�a�)�ě�����[�&y�c�m0�&�5�Ѧ!�lYs\l -r�@�皆L�Id�q�iȤ�D����L�Id�q�)�i�s�h2�&�5�}�!�gYsg2m&�5�e� w� d�q�i�T�D�7��L�Id�a�i��cx;�5��c�Wc�b0%&�5��!�aYsa2 &�5�� w� d�q~i�ԗD����LzId�qxi�t�D�W����%�=�ɥ!S\Ys�[2�%�5DZ�!�ZYs\Z~L^C�cr�qfi�T�D�7��LbId�a`i��Wx;�u��w\ b�qZiȔ�D�w��LVId�qTi�4�D����A%�=�9�!SSYs�R2)%�5�!�!�QYs\Q -rG�@�'��LAId�q?i��D�Ǔ�L;Id�q9)�N�s�M2�$�5�ͤW2I���L/Ib�q-)�K�s�J2�$�5ǝ�!�IYsI2�$�5Dž� w d�qi�ԑD����LId�qi�t�D�W���Q$�=�I�!SDYs�C29$�5�1�!�BYs\B -r��@�f�F\$��c�@0 $�5��!�?Ys\? -rǏ@����L�Hd�q�h�d�D�G��L�Hd�q��1y ��1ǹ�!S;Ys�:2�#�5ǡ�!�9Ys\9 -rG�@�'��L�Hd�q�h��D�Ǎ�L�Hd�a�(Ą���f��[U#y�c�40I#�5�A�a��zFz�K�x��������e;���G��q^����[3��7�?�l���~��_�����0k|��^���W���O�OG]���Yw�w�� ����� -Ϩ;�#ur��Ԕx�� �xJM��jr����x�� yF�I�c��<���C���Sj�<T{��<���C���3���H��)5��=���BW��f�q���tz�� �zFݩ�c�c=���C���Sj�=T{��=���C���3���H��)5��=��R�ڃ��)5��=��Qw�G��O���P�A�������O�i�P�A����s>R� }ʼ}(ގaӧ���Xs��)3]�=�e�P�i�s��>���C���Sj?T{�?���C���3���H��)5��=ȭ�R��ڃ��)5��=�şQw�G���O���P�A��������O�i�P�A�����̞��P���D��Tf"@D{�3@��D��4�NI�*55 �=�=�R�ڃ�*5M �=�U�QwH��0P�)Q�An��8��<P��Q�A.��AR� G�JM%�jr'�Ԅ��� �� -]� �5���!��s*3� �=�͠R �ڃ� *5� �=��Qw:H��xP��Q�A������P�iQ�A���3BR� ��JMI�jrK��Ą�� �JMO�jrQ(�kR��P�� -Q�A� -����ĴP��-D��.4�� �*5�!�=ȍ�R�ڃ�*5�!�=ȥ�QwjH���P�� Q�A� ������P�iQ�A����CR� ��JMy�jr{��ć�� �JM�jr�hԝ �:9BTj*DT{;D��͚�Q�i�A���sDR� �JM��jr���D��� g�JM��jr�hԝ&�:9NTj�DT{��D�&PD�9QTjET{�+E��L��1ȡ�RS*�ڃ�**5�"�=ȹ�R�+�ڃ\,u'���A���E4k��Ee&\D�9]Tj�ET{��E��|��1��RS0�ڃ�0*5#�=��R�1�ڃ\2 -��2�:9fTjjFT{�{F�&hD�9iTj�FT{��F��1�a�RS6�ڃ�6*5q#�=�y�R�7�ڃX84�#�=���"W�d�q�̄��� ��T����;�ǵ��s���n|}]���q��;�V���?����:~M�i_.�l]��L�������q7j�Q�y��F��@�F��FM�i�P�AnԔ�F ��FM�i�P�AnԌ�5R� 7jJM��jb���ը�Ysܨ)3��=ȍ�Qw�F��FM�i�P�AnԔ�F ��FM�i�P�AnԌ�5R� 7jJM��jr���4j�� 7jJM��jr�f�ݨ�:�QSj5T{�5��QC��QSj5T{�5��F��1H��2/���cب)p5j(�7j�L��hr�&�k���FM�i�P�AnԔ�F ��FM�i�P�AnԌ�5R� 7jJM��jr���4j�� 7jJM��jr�f�ݨ�:�QSj5T{�5��QC��QSj5T{5��Q#��QS�jԐ�9nԔ�F ��FM�i�P�AnԌ�5R� 7jJM��jr���4j�� 7jJM��jr�f�ݨ�:�QSj5T{�5��QC��QSj5T{�5��F��1ȍ�RӨ�ڃܨ)5��=���BW��f�a�f�4jD�7j�L��hr���4j�� 7jJM��jr�f�ݨ�:�QSj5T{�5��QC��QSj5T{�5��F��1ȍ�RӨ�ڃܨ)5��=ȍ�RӨ�ڃܨ �ڨ�:�QSj5T{�5��QC��QS�j�Ь9nԌ�5B� 7jJM��jr���4j�� 7jJM��jr�f�ݨ�:�QSj5T{�5��QC��QSj5T{�5��F��1ȍ�RӨ�ڃܨ)5��=ȍ�RӨ�ڃܨu7j��AnԔ�F ��FM��QC��QSf5D{�5��F��1ȍ�RӨ�ڃܨ)5��=ȍ�RӨ�ڃܨu7j��AnԔ�F ��FM�i�P�AnԔ�F ��Fͨ�Q#ur���4j�� 7jJM��jr���4j�� 7jFݍ�c5��F ͚�FM�i��AnԔ�F ��Fͨ�Q#ur���4j�� 7jJM��jr���4j�� 7jB�6j��AnԔ�F ��FM�i�P�AnԔ�F ��Fͨ�Q#ur���4j�� 7jJM��jr���4j�� 6jM�Ff�a���ը!Ysܨ)3��=ȍ�qc�5|�K�v��6j��1�����_1��<q��~sm��W���_���5jW���Q��ݍ���7jo5R� 7jJM��jr���4j�� 7jJM��jr�f�ݨ�:�QSj5T{5��F ͚�FM�i��AnԌ�5R� 7jJM��jr���4j�� 7jJM��jr�f�ݨ�:�QSj5T{�5��QC��QSj5T{�5��F��1ȍ�RӨ�ڃܨ)5��=ȍ�RӨ�ڃܨu7j��AjԔyi�P��FM��QC��QSf5D{�5�^5P� 7jJM��jr���4j�� 7jJM��jr�f�ݨ�:�QSj5T{�5��QC��QSj5T{�5��F��1ȍ�RӨ�ڃܨ)5��=ȍ�RӨ�ڃب4��=���"W��d�q���4j�� 7jJM��jr�f�ݨ�:�QSj5T{�5��QC��QSj5T{�5��F��1ȍ�RӨ�ڃܨ)5��=ȍ�RӨ�ڃܨu7j��AnԔ�F ��FM�i�P�Al��54k5C�Q#��QSf5D{�5��QC��QSj5T{�5��F��1ȍ�RӨ�ڃܨ)5��=ȍ�RӨ�ڃܨu7j��AnԔ�F ��FM�i�P�AnԔ�F ��FM��F �9ȍ�RӨ�ڃܨ)5��=���BW��f�q�f�ݨ:�QSj5T{�5��QC��QSj5T{�5��F��1ȍ�RӨ�ڃܨ)5��=ȍ�RӨ�ڃܨu7j��AnԔ�F ��FM�i�P�AnԔ�F ��Fͨ�Q#ur���4j�� 6j -]��5Ǎ�2Ө!ڃܨu7j��AnԔ�F ��FM�i�P�AnԔ�F ��Fͨ�Q#ur���4j�� 7jJM��jr���4j�� 7jFݍ�c�5��QC��QSj5T{�5��QC��Q3�n�H�ب)t5jh�7j�L��hr���4j�� 7jFݍ�c�5��QC��QSj5T{�5��QC��Q�Qur���4j�� 7jJM��jr���4j�� 7jFݍ�c�5��QC��QSj5T{�5��QC��Q3h52{5E�F ɚ�FM�i��AnԎ+ը�s\���x<6j��q�����ן���w/_���ڗ�ݗ�op�|�6s��~}��W�^�[�x}�����\g"�?9���endstream +wT{�w���1ȅ�RS��ڃ\�+5�;�=ȅ�RS��ڃ\�uA.ܕ�����]�)�Q�A.ܕ�����ݨ�p'ub��U��Ys\�+3�;�=ȅ�RS��ڃ\�uA.ܕ�����]�)�Q�A.ܕ�����]����9ȅ�RS��ڃ\�+5�;�=ȅ�RS��ڃ\�uA.ܕ�����]�)�Q�A.ܕ�����ݠ)���9,�� +w$k�we�pG��p�X[��=΅�uN�tX����??���;�/~��y�����/Q?����fQ�>��\ +����߾���������u|w���^��-no��?��xg��w}��3��_2hT{�3h�&�F�9�6�ΠI��A+54�=��R�A�ڃ�A+te�h�g���4�c�3h�&�F�9�Vj2hT{�3h�&�F�9�6�ΠI��A+54�=��R�A�ڃ�A+54�=��QwM��Z�ɠQ�AΠ����Z�ɠQ�AΠ��3hR� g�JM�jb�ЕA�Ys�A+34�=��QwM��Z�ɠQ�AΠ����Z�ɠQ�AΠ��3hR� g�JM�jr��dШ� g�JM�jrmԝA�:9�Vj2hT{�3h�&�F�9�Vj2hT{�3h����1H�2�4��c�A+pe�(�g��L�hr-�K ��Z�ɠQ�AΠ����Z�ɠQ�AΠ��3hR� g�JM�jr��dШ� g�JM�jrmԝA�:9�Vj2hT{�3h�&�F�9�Vj2hT{3h�&�&��0�V�ʠ��9Π����Z�ɠQ�AΠ��3hR� g�JM�jr��dШ� g�JM�jrmԝA�:9�Vj2hT{�3h�&�F�9�Vj2hT{�3h����1��R�A�ڃ�A+54�=��BW�f�am�d�D�g��L�hr��dШ� g�JM�jrmԝA�:9�Vj2hT{�3h�&�F�9�Vj2hT{�3h����1��R�A�ڃ�A+54�=��R�A�ڃ�A��A�:9�Vj2hT{�3h�&�F�1�V�ʠѬ9Π��3hB� g�JM�jr��dШ� g�JM�jrmԝA�:9�Vj2hT{�3h�&�F�9�Vj2hT{�3h����1��R�A�ڃ�A+54�=��R�A�ڃ�AugФ�AΠ����Z�+�F��8�Vf2hD{�3h����1��R�A�ڃ�A+54�=��R�A�ڃ�AugФ�AΠ����Z�ɠQ�AΠ����ڨ;�&ur��dШ� g�JM�jr��dШ� g�F�4�c3h��͚�Z�ɠ�AΠ����ڨ;�&ur��dШ� g�JM�jr��dШ� g�B�dР�AΠ����Z�ɠQ�AΠ����ڨ;�&ur��dШ� g�JM�jr��dШ� f�MMf�a�ȕA#Ys�A+34�=��qԫ2h����9>Π���x���;/���|���_��>��~E�������t���������������믯�軗'osE���.z���w�y������OT{�O�&�D�9�TjOT{�O�����1ȁ�Rx�ڃx*5�'�=ȁ�Rx�ڃxu���A<������S� <Q�A<������Ө;�$ur����� � +]�'�5ǁ�2x"ڃxu���A<������S� <Q�A<������Ө;�$ur����� �JM��jr����� �F݁'�c�O�&�D�9�TjOT{�O�&�D�9�4�<I�x*�x�x=���W��b�q����� �B����A<������S� <Q�A<������Ө;�$ur����� �JM��jr����� �F݁'�c�O�&�D�9�TjOT{�O�&�D�1�4hO2{OE��ɚ��S� <�A<������Ө;�$ur����� �JM��jr����� �F݁'�c�O�&�D�9�TjOT{�O�&�D�9�4�<I�x*5�'�=ȁ�Rx�ڃx*t�h���L�Id�q����� �JM��jr����� �F݁'�c�O�&�D�9�TjOT{�O�&�D�9�4�<I�x*5�'�=ȁ�Rx�ڃx*5�'�=ȁ�P/�'�s�O�&�D�9�TjOT{O���͚��Ә;�$tr����� �JM��jr����� �F݁'�c�O�&�D�9�TjOT{�O�&�D�9�4�<I�x*5�'�=ȁ�Rx�ڃx*5�'�=ȁ�Qw�I���S� <Q�A<�O4k�Oe&�D�9�4�<I�x*5�'�=ȁ�Rx�ڃx*5�'�=ȁ�Qw�I���S� <Q�A<������S� <Q�A<��OR� �JM��jr����� �JM��jr�i�x�:1�T� +<Ѭ9<������S� <Q�A<��OR� �JM��jr����� �JM��jr�)�K� ���S� <Q�A<������S� <Q�A<��OR� �JM��jr����� �JM��jb�i��d���\�'�5ǁ�2x"ڃxR�(O����<<���<�� <O������+����?}��?������W����뗯�������~���7b�ӯ�_����?�ϧ/s{&�<�����|����շ��Ț��Ґ .��9�-�kK {�[KC&�$��8�4d:K"k�+KC&�$��8��.,��9�+ ���Ț�Ґi+��9.+ ���Ț�R����縩4d�J"k�J#�����1�) ���Ě�R����縣4d2J"k�#JC��$�渠4dJ"k��IA�zȞ�vҐI'��9' �n�Ț�jҐ�&��9N&��I {�{IC&�$��8�4dZI"k�KIC&�$��8��$��9j$ xN$����@�h��$�z��H&�$��8�|�������.Ґ�"��9�" �&�Ț�"Ґ "��9�!�kH {�[HC&�$��8�4d:H"k�+HC&�$��8��. ��9� ���Ț��ѐi��9. ��Ț��Q���1l���G��8x4`zGk�kGC&v$��8u�.��9� �̑Ț��ѐi��9. ���Ț�Q��n��m4d�F"k��FC�k$��j4d�F"k��FA�Ȟ�ѐ���9� ���ȚÒш+d$�z3F�b�Ƹa4`Fk�FC�_$��^4d�E"k��EA�rȞ�nѐ���9� �f�Ț�bѐ ��9��kE {�[EC&U$��8T4d:E"k�+EC&R$��8Q|������>ѐ���9� �6�Ț�2ш+L$�z��D�*Ğ�&ѐI��9 ��Ț�ѐ���9N�KD {�;DC&C$��8B4dD"k�DC&@$��8?���9n ���Ț��А���9� ��Ț��P��8��74drC"kcC#���1. �АĚ��P��2��14dC"k�CC�/$��.4d�B"k��BA�Ȟ�А� +��9� + ���Ț�А +��9� �kB {�[BC&%$��8$4d:B"k�+BC&"$��8!�.��9����A��84`�Ak��AC&$��8���9n �d�Ț�`А���9� �X�Ț�T�}�R +�c�;AC&$��84dA"k�AC&$��8���9n �4�Ț�0А���9� �(�Ț�$P�)�1���r@��84`Z@k�K@(�DH_��^Uw���������{��LJ���o]} �N� +z3\�g.��*���_?�����ӯT�����G�P��ܝ�~������n���qv���@wC���F�IoP�A�o��4k��e&�A�9�1�npH�\�(5�=�!�RS�ڃ��(51�=�9�Qw�C��"G�IrP�A�r��*��.G� sP�ANs���R� �9JM��jr���:�� 7:JM��jr�c���:��Q�9�A�zc�ZŚ�^G� v�ANv�ziv@��\�(5��=��RS�ڃ��(5��=���Qw�C��G�IxP�A�x�����G� yP�ANy��[R� �<JMjrУ�=�� 7=JMԃjb�c�t=d��=�\i�5�q�2S� ڃ��(5��=ȉ�Qw�C���G��|P�A}������G��}P�A�}��{R� ?JM�jr���T?�� w?JM��jr�c����:��Qj�T{� ���B��R芀Ь9̀��Ȟ�H�I��A������H� �P�AN���� R� WAJM�jr�ԔA�� �AJM�jrd���:�Rj!T{�#!��B��RjB!T{�S!�^Z!P� �BJM.�jr0��C�� 6C +]��5�ِ1w7D��rH�I�P�A����z��~H� �P�AN���"R� WDJMF�jrH�ԔD�� �DJML�jrNd���:�(Rj�"T{��"��*B��+Rj�"T{��"��1�u�R��ڃ)tFh�7F�Ld�hrfd���:�4RjR#T{�c#��6B��7Rj�#T{��#����1�ՑR��ڃ)5��=��R�ڃ�u�G��A.��� ��I���P�A� ��ɨ�E"ub��Е#�Ys$)3E�=�M�R%�ڃ�%uwI��A.���4 ��8I���P�A�@ ��DI��F �9ȕ�R�)�ڃ*)5��=ȭ�R+�ڃ�+u�J��A.���d ��hI���P�A�p ��tɠi���9����%$k�&e�`B��a:nqTĄ��\1]GCχ�����;���j��cZ��tLw�c�o�L���/���+㍀�� �ۧ�o�u���>s� �x������/b^�7� v�,�c�@]oSSj�Άj��ٔ���ڃ��6��m�� ��ͨ�5m��A~Q�R�6T{��զԼ� ��)5�kC���mFݯl#u�K۔����ڃ��6���m�� ��M��HQ�A�H��3RR� g�JMF�jbF�Е��Ys��*3)�=��QwFJ��T��HQ�A�H�����T��HQ�A�H��3RR� g�JMF�jrF��d��� g�JMF�jrFjԝ��:9#Uj2RT{�3R�&#E�9#Uj2RT{�3R��1H�2�)��c��*pe�(�g��LF�hrF*�KF +��T��HQ�A�H�����T��HQ�A�H��3RR� g�JMF�jrF��d��� g�JMF�jrFjԝ��:9#Uj2RT{�3R�&#E�9#Uj2RT{3R�&#%��0#U��H��9�H�����T��HQ�A�H��3RR� g�JMF�jrF��d��� g�JMF�jrFjԝ��:9#Uj2RT{�3R�&#E�9#Uj2RT{�3R��1��R���ڃ��*5)�=��BWF�f�aFj�d�D�g��LF�hrF��d��� g�JMF�jrFjԝ��:9#Uj2RT{�3R�&#E�9#Uj2RT{�3R��1��R���ڃ��*5)�=��R���ڃ�� +����:9#Uj2RT{�3R�&#E�1#U��HѬ9�H��3RB� g�JMF�jrF��d��� g�JMF�jrFjԝ��:9#Uj2RT{�3R�&#E�9#Uj2RT{�3R��1��R���ڃ��*5)�=��R���ڃ��ug���A�H����ČT�+#E��8#Uf2RD{�3R��1��R���ڃ��*5)�=��R���ڃ��ug���A�H�����T��HQ�A�H�����Ԩ;#%urF��d��� g�JMF�jrF��d��� g�F�)�c3R���͚�T��H�A�H�����Ԩ;#%urF��d��� g�JMF�jrF��d��� g�B�d���A�H�����T��HQ�A�H�����Ԩ;#%urF��d��� g�JMF�jrF��d��� f�MFJf�aF�ȕ�"Ys��*3)�=��q�2R�����<�H���on�n��y����?P/���g�OϏog��C�L2ҏy����O?|���/?��9�K���?�^��?x>��;w��sǫ�z�;��"�;�ڃ�;u玤�A�������Q��Q�A�������Ѩ;w$ur��䎨� �JM�jr��䎨� �Fݹ#�c�sG�&wD�1wT��Ѭ9�������Ѩ;w$ur��䎨� �JM�jr��䎨� �Fݹ#�c�sG�&wD�9wTjrGT{�sG�&wD�9w4��I��;*5�#�=ȹ�R�;�ڃ�;*5�#�=ȹ�Qw�H���Q�����1��rGk�sGe&wD�9w�%wur��䎨� �JM�jr��䎨� �Fݹ#�c�sG�&wD�9wTjrGT{�sG�&wD�9w4��I��;*5�#�=ȹ�R�;�ڃ�;*5�#�=���A�;��s�;*r�H���L�hr��䎨� �Fݹ#�c�sG�&wD�9wTjrGT{�sG�&wD�9w4��I��;*5�#�=ȹ�R�;�ڃ�;*5�#�=ȹ�Qw�H���Q��Q�A�������Q�+wD��0w4drG"{�sGe&wD�9wTjrGT{�sG�&wD�9w4��I��;*5�#�=ȹ�R�;�ڃ�;*5�#�=ȹ�Qw�H���Q��Q�A�������Q��Q�A��z�A���;*5�#�=ȹ�R�;�ڃ�;*t�h���ܹ#�c�sG�&wD�9wTjrGT{�sG�&wD�9w4��I��;*5�#�=ȹ�R�;�ڃ�;*5�#�=ȹ�Qw�H���Q��Q�A�������Q��Q�A���sGR� �JM�jb�Е;�Ys�;*3�#�=ȹ�Qw�H���Q��Q�A�������Q��Q�A���sGR� �JM�jr��䎨� �JM�jr�hԝ;�:9wTjrGT{�sG�&wD�9wTjrGT{�sG��ܑ�1���BW�f�q��䎈� �JM�jr�hԝ;�:9wTjrGT{�sG�&wD�9wTjrGT{�sG�^rGP� �JM�jr��䎨� �JM�jr�hԝ;�:9wTjrGT{�sG�&wD�9wTjrGT{sG�&w$��0wT����9������ܑ�=�;��8��m�q�x�=N�<����}|�y����5?��|��������K~y�����yy���7�/_��w�u.3��?ڪ�_endstream endobj -1325 0 obj << +1353 0 obj << /Type /Page -/Contents 1326 0 R -/Resources 1324 0 R +/Contents 1354 0 R +/Resources 1352 0 R /MediaBox [0 0 609.714 789.041] -/Parent 1174 0 R -/Annots [ 1328 0 R 1329 0 R 1330 0 R 1331 0 R 1332 0 R 1333 0 R 1334 0 R 1335 0 R 1336 0 R 1337 0 R 1338 0 R 1339 0 R 1340 0 R 1341 0 R 1342 0 R 1343 0 R 1344 0 R 1345 0 R 1346 0 R 1347 0 R 1348 0 R 1349 0 R 1350 0 R 1351 0 R 1352 0 R 1353 0 R 1354 0 R 1355 0 R 1356 0 R 1357 0 R 1358 0 R 1359 0 R 1360 0 R 1361 0 R 1362 0 R 1363 0 R 1364 0 R 1365 0 R 1366 0 R 1367 0 R 1368 0 R 1369 0 R 1370 0 R 1371 0 R 1372 0 R 1373 0 R 1374 0 R 1375 0 R 1376 0 R 1377 0 R 1378 0 R 1379 0 R 1380 0 R 1381 0 R 1382 0 R 1383 0 R 1384 0 R 1385 0 R 1386 0 R 1387 0 R 1388 0 R 1389 0 R 1390 0 R 1391 0 R 1392 0 R 1393 0 R 1394 0 R 1395 0 R 1396 0 R 1397 0 R 1398 0 R 1399 0 R 1400 0 R 1401 0 R 1402 0 R 1403 0 R 1404 0 R 1405 0 R 1406 0 R 1407 0 R 1408 0 R 1409 0 R 1410 0 R 1411 0 R 1412 0 R 1413 0 R 1414 0 R 1415 0 R 1416 0 R 1417 0 R 1418 0 R 1419 0 R 1420 0 R 1421 0 R ] +/Parent 1202 0 R +/Annots [ 1356 0 R 1357 0 R 1358 0 R 1359 0 R 1360 0 R 1361 0 R 1362 0 R 1363 0 R 1364 0 R 1365 0 R 1366 0 R 1367 0 R 1368 0 R 1369 0 R 1370 0 R 1371 0 R 1372 0 R 1373 0 R 1374 0 R 1375 0 R 1376 0 R 1377 0 R 1378 0 R 1379 0 R 1380 0 R 1381 0 R 1382 0 R 1383 0 R 1384 0 R 1385 0 R 1386 0 R 1387 0 R 1388 0 R 1389 0 R 1390 0 R 1391 0 R 1392 0 R 1393 0 R 1394 0 R 1395 0 R 1396 0 R 1397 0 R 1398 0 R 1399 0 R 1400 0 R 1401 0 R 1402 0 R 1403 0 R 1404 0 R 1405 0 R 1406 0 R 1407 0 R 1408 0 R 1409 0 R 1410 0 R 1411 0 R 1412 0 R 1413 0 R 1414 0 R 1415 0 R 1416 0 R 1417 0 R 1418 0 R 1419 0 R 1420 0 R 1421 0 R 1422 0 R 1423 0 R 1424 0 R 1425 0 R 1426 0 R 1427 0 R 1428 0 R 1429 0 R 1430 0 R 1431 0 R 1432 0 R 1433 0 R 1434 0 R 1435 0 R 1436 0 R 1437 0 R 1438 0 R 1439 0 R 1440 0 R 1441 0 R 1442 0 R 1443 0 R 1444 0 R 1445 0 R 1446 0 R 1447 0 R 1448 0 R 1449 0 R ] >> endobj -1328 0 obj << +1356 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 708.244 223.78 715.098] +/Rect [95.641 706.187 324.5 715.098] /Subtype /Link -/A << /S /GoTo /D (os-win32) >> +/A << /S /GoTo /D (833) >> >> endobj -1329 0 obj << +1357 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 708.244 537.983 715.098] +/Rect [528.02 706.187 537.983 715.098] /Subtype /Link -/A << /S /GoTo /D (os-win32) >> +/A << /S /GoTo /D (833) >> >> endobj -1330 0 obj << +1358 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 695.293 221.101 702.147] +/Rect [95.641 693.235 234.28 702.147] /Subtype /Link -/A << /S /GoTo /D (win32-perl) >> +/A << /S /GoTo /D (os-specific) >> >> endobj -1331 0 obj << +1359 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 695.293 537.983 702.147] +/Rect [528.02 693.235 537.983 702.147] /Subtype /Link -/A << /S /GoTo /D (win32-perl) >> +/A << /S /GoTo /D (os-specific) >> >> endobj -1332 0 obj << +1360 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 682.341 270.913 689.195] +/Rect [119.552 682.341 223.78 689.195] /Subtype /Link -/A << /S /GoTo /D (win32-perl-modules) >> +/A << /S /GoTo /D (os-win32) >> >> endobj -1333 0 obj << +1361 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 682.341 537.983 689.195] /Subtype /Link -/A << /S /GoTo /D (win32-perl-modules) >> +/A << /S /GoTo /D (os-win32) >> >> endobj -1334 0 obj << +1362 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 667.333 334.813 676.244] +/Rect [143.462 669.39 221.101 676.244] /Subtype /Link -/A << /S /GoTo /D (win32-code-changes) >> +/A << /S /GoTo /D (win32-perl) >> >> endobj -1335 0 obj << +1363 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 667.333 537.983 676.244] +/Rect [528.02 669.39 537.983 676.244] /Subtype /Link -/A << /S /GoTo /D (win32-code-changes) >> +/A << /S /GoTo /D (win32-perl) >> >> endobj -1336 0 obj << +1364 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 654.381 265.763 663.293] +/Rect [143.462 656.438 270.913 663.293] /Subtype /Link -/A << /S /GoTo /D (win32-http) >> +/A << /S /GoTo /D (win32-perl-modules) >> >> endobj -1337 0 obj << +1365 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 654.381 537.983 663.293] +/Rect [528.02 656.438 537.983 663.293] /Subtype /Link -/A << /S /GoTo /D (win32-http) >> +/A << /S /GoTo /D (win32-perl-modules) >> >> endobj -1338 0 obj << +1366 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 641.43 234.789 650.341] +/Rect [143.462 641.43 334.813 650.341] /Subtype /Link -/A << /S /GoTo /D (win32-email) >> +/A << /S /GoTo /D (win32-code-changes) >> >> endobj -1339 0 obj << +1367 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 641.43 537.983 650.341] /Subtype /Link +/A << /S /GoTo /D (win32-code-changes) >> +>> endobj +1368 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [143.462 628.478 265.763 637.39] +/Subtype /Link +/A << /S /GoTo /D (win32-http) >> +>> endobj +1369 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [528.02 628.478 537.983 637.39] +/Subtype /Link +/A << /S /GoTo /D (win32-http) >> +>> endobj +1370 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [143.462 615.527 234.789 624.438] +/Subtype /Link /A << /S /GoTo /D (win32-email) >> >> endobj -1340 0 obj << +1371 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [528.02 615.527 537.983 624.438] +/Subtype /Link +/A << /S /GoTo /D (win32-email) >> +>> endobj +1372 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 630.536 187.068 637.39] +/Rect [119.552 604.633 187.068 611.487] /Subtype /Link /A << /S /GoTo /D (os-macosx) >> >> endobj -1341 0 obj << +1373 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 630.536 537.983 637.39] +/Rect [528.02 604.633 537.983 611.487] /Subtype /Link /A << /S /GoTo /D (os-macosx) >> >> endobj -1342 0 obj << +1374 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 617.584 213.479 624.438] +/Rect [143.462 591.681 213.479 598.535] /Subtype /Link /A << /S /GoTo /D (macosx-sendmail) >> >> endobj -1343 0 obj << +1375 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 617.584 537.983 624.438] +/Rect [528.02 591.681 537.983 598.535] /Subtype /Link /A << /S /GoTo /D (macosx-sendmail) >> >> endobj -1344 0 obj << +1376 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 604.633 335.5 611.487] +/Rect [143.462 578.73 335.5 585.584] /Subtype /Link /A << /S /GoTo /D (macosx-libraries) >> >> endobj -1345 0 obj << +1377 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 604.633 537.983 611.487] +/Rect [528.02 578.73 537.983 585.584] /Subtype /Link /A << /S /GoTo /D (macosx-libraries) >> >> endobj -1346 0 obj << +1378 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 591.681 226.809 598.535] +/Rect [119.552 565.778 226.809 572.633] /Subtype /Link /A << /S /GoTo /D (os-mandrake) >> >> endobj -1347 0 obj << +1379 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 591.681 537.983 598.535] +/Rect [528.02 565.778 537.983 572.633] /Subtype /Link /A << /S /GoTo /D (os-mandrake) >> >> endobj -1348 0 obj << +1380 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 577.046 254.464 585.584] +/Rect [95.641 551.143 254.464 559.681] /Subtype /Link /A << /S /GoTo /D (nonroot) >> >> endobj -1349 0 obj << +1381 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 577.046 537.983 585.584] +/Rect [528.02 551.143 537.983 559.681] /Subtype /Link /A << /S /GoTo /D (nonroot) >> >> endobj -1350 0 obj << +1382 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 565.778 193.713 572.633] +/Rect [119.552 539.876 193.713 546.73] /Subtype /Link -/A << /S /GoTo /D (884) >> +/A << /S /GoTo /D (955) >> >> endobj -1351 0 obj << +1383 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 565.778 537.983 572.633] +/Rect [528.02 539.876 537.983 546.73] /Subtype /Link -/A << /S /GoTo /D (884) >> +/A << /S /GoTo /D (955) >> >> endobj -1352 0 obj << +1384 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 550.77 177.116 559.681] +/Rect [119.552 524.867 177.116 533.778] /Subtype /Link -/A << /S /GoTo /D (888) >> +/A << /S /GoTo /D (959) >> >> endobj -1353 0 obj << +1385 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 550.77 537.983 559.681] +/Rect [528.02 524.867 537.983 533.778] /Subtype /Link -/A << /S /GoTo /D (888) >> +/A << /S /GoTo /D (959) >> >> endobj -1354 0 obj << +1386 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 537.818 298.44 546.73] +/Rect [143.462 511.915 298.44 520.827] /Subtype /Link -/A << /S /GoTo /D (896) >> +/A << /S /GoTo /D (967) >> >> endobj -1355 0 obj << +1387 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 537.818 537.983 546.73] +/Rect [528.02 511.915 537.983 520.827] /Subtype /Link -/A << /S /GoTo /D (896) >> +/A << /S /GoTo /D (967) >> >> endobj -1356 0 obj << +1388 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 526.924 160.508 533.778] +/Rect [119.552 501.021 160.508 507.875] /Subtype /Link -/A << /S /GoTo /D (923) >> +/A << /S /GoTo /D (994) >> >> endobj -1357 0 obj << +1389 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 526.924 537.983 533.778] +/Rect [528.02 501.021 537.983 507.875] /Subtype /Link -/A << /S /GoTo /D (923) >> +/A << /S /GoTo /D (994) >> >> endobj -1358 0 obj << +1390 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 513.973 197.867 520.827] +/Rect [119.552 488.07 197.867 494.924] /Subtype /Link /A << /S /GoTo /D (install-perlmodules-nonroot) >> >> endobj -1359 0 obj << +1391 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 513.973 537.983 520.827] +/Rect [528.02 488.07 537.983 494.924] /Subtype /Link /A << /S /GoTo /D (install-perlmodules-nonroot) >> >> endobj -1360 0 obj << +1392 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 498.964 276.552 507.875] +/Rect [143.462 473.061 276.552 481.973] /Subtype /Link -/A << /S /GoTo /D (942) >> +/A << /S /GoTo /D (1013) >> >> endobj -1361 0 obj << +1393 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 498.964 537.983 507.875] +/Rect [528.02 473.061 537.983 481.973] /Subtype /Link -/A << /S /GoTo /D (942) >> +/A << /S /GoTo /D (1013) >> >> endobj -1362 0 obj << +1394 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 488.07 253.17 494.924] +/Rect [143.462 462.167 253.17 469.021] /Subtype /Link -/A << /S /GoTo /D (955) >> +/A << /S /GoTo /D (1026) >> >> endobj -1363 0 obj << +1395 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 488.07 537.983 494.924] +/Rect [528.02 462.167 537.983 469.021] /Subtype /Link -/A << /S /GoTo /D (955) >> +/A << /S /GoTo /D (1026) >> >> endobj -1364 0 obj << +1396 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 475.118 197.708 481.973] +/Rect [119.552 449.216 197.708 456.07] /Subtype /Link -/A << /S /GoTo /D (988) >> +/A << /S /GoTo /D (1059) >> >> endobj -1365 0 obj << +1397 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 475.118 537.983 481.973] +/Rect [528.02 449.216 537.983 456.07] /Subtype /Link -/A << /S /GoTo /D (988) >> +/A << /S /GoTo /D (1059) >> >> endobj -1366 0 obj << +1398 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 460.11 296.208 469.021] +/Rect [143.462 434.207 296.208 443.118] /Subtype /Link -/A << /S /GoTo /D (991) >> +/A << /S /GoTo /D (1062) >> >> endobj -1367 0 obj << +1399 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 460.11 537.983 469.021] +/Rect [528.02 434.207 537.983 443.118] /Subtype /Link -/A << /S /GoTo /D (991) >> +/A << /S /GoTo /D (1062) >> >> endobj -1368 0 obj << +1400 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 447.158 178.221 456.07] +/Rect [119.552 421.255 178.221 430.167] /Subtype /Link -/A << /S /GoTo /D (1000) >> +/A << /S /GoTo /D (1071) >> >> endobj -1369 0 obj << +1401 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 447.158 537.983 456.07] +/Rect [528.02 421.255 537.983 430.167] /Subtype /Link -/A << /S /GoTo /D (1000) >> +/A << /S /GoTo /D (1071) >> >> endobj -1370 0 obj << +1402 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.731 431.95 180.502 440.837] +/Rect [71.731 406.047 180.502 414.934] /Subtype /Link /A << /S /GoTo /D (administration) >> >> endobj -1371 0 obj << +1403 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 431.95 537.983 440.837] +/Rect [528.02 406.047 537.983 414.934] /Subtype /Link /A << /S /GoTo /D (administration) >> >> endobj -1372 0 obj << +1404 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 416.473 204.681 425.385] +/Rect [95.641 390.57 204.681 399.482] /Subtype /Link /A << /S /GoTo /D (parameters) >> >> endobj -1373 0 obj << +1405 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 416.473 537.983 425.385] +/Rect [528.02 390.57 537.983 399.482] /Subtype /Link /A << /S /GoTo /D (parameters) >> >> endobj -1374 0 obj << +1406 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 405.579 194.709 412.433] +/Rect [95.641 379.676 194.709 386.53] /Subtype /Link /A << /S /GoTo /D (useradmin) >> >> endobj -1375 0 obj << +1407 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 405.579 537.983 412.433] +/Rect [528.02 379.676 537.983 386.53] /Subtype /Link /A << /S /GoTo /D (useradmin) >> >> endobj -1376 0 obj << +1408 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 390.57 247.002 399.482] +/Rect [119.552 364.668 247.002 373.579] /Subtype /Link /A << /S /GoTo /D (defaultuser) >> >> endobj -1377 0 obj << +1409 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 390.57 537.983 399.482] +/Rect [528.02 364.668 537.983 373.579] /Subtype /Link /A << /S /GoTo /D (defaultuser) >> >> endobj -1378 0 obj << +1410 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 377.619 235.207 386.53] +/Rect [119.552 351.716 235.207 360.628] /Subtype /Link /A << /S /GoTo /D (manageusers) >> >> endobj -1379 0 obj << +1411 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 377.619 537.983 386.53] +/Rect [528.02 351.716 537.983 360.628] /Subtype /Link /A << /S /GoTo /D (manageusers) >> >> endobj -1380 0 obj << +1412 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 364.668 286.644 373.579] +/Rect [143.462 338.765 286.644 347.676] /Subtype /Link /A << /S /GoTo /D (user-account-search) >> >> endobj -1381 0 obj << +1413 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 364.668 537.983 373.579] +/Rect [528.02 338.765 537.983 347.676] /Subtype /Link /A << /S /GoTo /D (user-account-search) >> >> endobj -1382 0 obj << +1414 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 351.716 251.954 360.628] +/Rect [143.462 325.813 251.954 334.725] /Subtype /Link /A << /S /GoTo /D (createnewusers) >> >> endobj -1383 0 obj << +1415 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 351.716 537.983 360.628] +/Rect [528.02 325.813 537.983 334.725] /Subtype /Link /A << /S /GoTo /D (createnewusers) >> >> endobj -1384 0 obj << +1416 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 338.765 243.636 347.676] +/Rect [143.462 312.862 243.636 321.773] /Subtype /Link /A << /S /GoTo /D (modifyusers) >> >> endobj -1385 0 obj << +1417 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 338.765 537.983 347.676] +/Rect [528.02 312.862 537.983 321.773] /Subtype /Link /A << /S /GoTo /D (modifyusers) >> >> endobj -1386 0 obj << +1418 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 325.813 235.327 334.725] +/Rect [143.462 299.91 235.327 308.822] /Subtype /Link /A << /S /GoTo /D (user-account-deletion) >> >> endobj -1387 0 obj << +1419 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 325.813 537.983 334.725] +/Rect [528.02 299.91 537.983 308.822] /Subtype /Link /A << /S /GoTo /D (user-account-deletion) >> >> endobj -1388 0 obj << +1420 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 312.862 258.569 321.773] +/Rect [143.462 286.959 258.569 295.87] /Subtype /Link /A << /S /GoTo /D (impersonatingusers) >> >> endobj -1389 0 obj << +1421 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 312.862 537.983 321.773] +/Rect [528.02 286.959 537.983 295.87] /Subtype /Link /A << /S /GoTo /D (impersonatingusers) >> >> endobj -1390 0 obj << +1422 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 301.968 171.197 308.822] +/Rect [95.641 276.065 171.197 282.919] /Subtype /Link /A << /S /GoTo /D (classifications) >> >> endobj -1391 0 obj << +1423 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 301.968 537.983 308.822] +/Rect [528.02 276.065 537.983 282.919] /Subtype /Link /A << /S /GoTo /D (classifications) >> >> endobj -1392 0 obj << +1424 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 289.016 147.945 295.87] +/Rect [95.641 263.113 147.945 269.968] /Subtype /Link /A << /S /GoTo /D (products) >> >> endobj -1393 0 obj << +1425 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 289.016 537.983 295.87] +/Rect [528.02 263.113 537.983 269.968] /Subtype /Link /A << /S /GoTo /D (products) >> >> endobj -1394 0 obj << +1426 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 274.008 163.447 282.919] +/Rect [95.641 248.105 163.447 257.016] /Subtype /Link /A << /S /GoTo /D (components) >> >> endobj -1395 0 obj << +1427 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 274.008 537.983 282.919] +/Rect [528.02 248.105 537.983 257.016] /Subtype /Link /A << /S /GoTo /D (components) >> >> endobj -1396 0 obj << +1428 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 263.113 147.387 269.968] +/Rect [95.641 237.211 147.387 244.065] /Subtype /Link /A << /S /GoTo /D (versions) >> >> endobj -1397 0 obj << +1429 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 263.113 537.983 269.968] +/Rect [528.02 237.211 537.983 244.065] /Subtype /Link /A << /S /GoTo /D (versions) >> >> endobj -1398 0 obj << +1430 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 250.162 156.801 257.016] +/Rect [95.641 224.259 156.801 231.113] /Subtype /Link /A << /S /GoTo /D (milestones) >> >> endobj -1399 0 obj << +1431 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 250.162 537.983 257.016] +/Rect [528.02 224.259 537.983 231.113] /Subtype /Link /A << /S /GoTo /D (milestones) >> >> endobj -1400 0 obj << +1432 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 235.153 134.665 244.065] +/Rect [95.641 209.25 134.665 218.162] /Subtype /Link /A << /S /GoTo /D (flags-overview) >> >> endobj -1401 0 obj << +1433 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 235.153 537.983 244.065] +/Rect [528.02 209.25 537.983 218.162] /Subtype /Link /A << /S /GoTo /D (flags-overview) >> >> endobj -1402 0 obj << +1434 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 222.202 220.283 231.113] +/Rect [119.552 196.299 220.283 205.21] /Subtype /Link /A << /S /GoTo /D (flags-simpleexample) >> >> endobj -1403 0 obj << +1435 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 222.202 537.983 231.113] +/Rect [528.02 196.299 537.983 205.21] /Subtype /Link /A << /S /GoTo /D (flags-simpleexample) >> >> endobj -1404 0 obj << +1436 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 209.25 193.444 218.162] +/Rect [119.552 183.348 193.444 192.259] /Subtype /Link /A << /S /GoTo /D (flags-about) >> >> endobj -1405 0 obj << +1437 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 209.25 537.983 218.162] +/Rect [528.02 183.348 537.983 192.259] /Subtype /Link /A << /S /GoTo /D (flags-about) >> >> endobj -1406 0 obj << +1438 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 198.356 202.401 205.21] +/Rect [143.462 172.453 202.401 179.308] /Subtype /Link /A << /S /GoTo /D (flag-values) >> >> endobj -1407 0 obj << +1439 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 198.356 537.983 205.21] +/Rect [528.02 172.453 537.983 179.308] /Subtype /Link /A << /S /GoTo /D (flag-values) >> >> endobj -1408 0 obj << +1440 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 183.348 220.831 192.259] +/Rect [119.552 157.445 220.831 166.356] /Subtype /Link /A << /S /GoTo /D (flag-askto) >> >> endobj -1409 0 obj << +1441 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 183.348 537.983 192.259] +/Rect [528.02 157.445 537.983 166.356] /Subtype /Link /A << /S /GoTo /D (flag-askto) >> >> endobj -1410 0 obj << +1442 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 170.396 222.734 179.308] +/Rect [119.552 144.493 222.734 153.405] /Subtype /Link /A << /S /GoTo /D (flag-types) >> >> endobj -1411 0 obj << +1443 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 170.396 537.983 179.308] +/Rect [528.02 144.493 537.983 153.405] /Subtype /Link /A << /S /GoTo /D (flag-types) >> >> endobj -1412 0 obj << +1444 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 157.445 246.405 166.356] +/Rect [143.462 131.542 246.405 140.453] /Subtype /Link /A << /S /GoTo /D (flag-type-attachment) >> >> endobj -1413 0 obj << +1445 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 157.445 537.983 166.356] +/Rect [528.02 131.542 537.983 140.453] /Subtype /Link /A << /S /GoTo /D (flag-type-attachment) >> >> endobj -1414 0 obj << +1446 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 144.493 216.528 153.405] +/Rect [143.462 118.59 216.528 127.502] /Subtype /Link /A << /S /GoTo /D (flag-type-bug) >> >> endobj -1415 0 obj << +1447 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 144.493 537.983 153.405] +/Rect [528.02 118.59 537.983 127.502] /Subtype /Link /A << /S /GoTo /D (flag-type-bug) >> >> endobj -1416 0 obj << +1448 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 131.542 226.101 140.453] +/Rect [119.552 105.639 226.101 114.55] /Subtype /Link /A << /S /GoTo /D (flags-admin) >> >> endobj -1417 0 obj << +1449 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 131.542 537.983 140.453] +/Rect [528.02 105.639 537.983 114.55] /Subtype /Link /A << /S /GoTo /D (flags-admin) >> >> endobj -1418 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 118.59 237.269 127.502] -/Subtype /Link -/A << /S /GoTo /D (flags-create) >> ->> endobj -1419 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 118.59 537.983 127.502] -/Subtype /Link -/A << /S /GoTo /D (flags-create) >> +1355 0 obj << +/D [1353 0 R /XYZ 71.731 729.265 null] >> endobj -1420 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 105.639 237.269 114.55] -/Subtype /Link -/A << /S /GoTo /D (flags-delete) >> ->> endobj -1421 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 105.639 537.983 114.55] -/Subtype /Link -/A << /S /GoTo /D (flags-delete) >> ->> endobj -1327 0 obj << -/D [1325 0 R /XYZ 71.731 729.265 null] ->> endobj -1324 0 obj << -/Font << /F27 1180 0 R /F32 1187 0 R /F33 1278 0 R >> +1352 0 obj << +/Font << /F27 1208 0 R /F32 1215 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1471 0 obj << -/Length 56693 +1499 0 obj << +/Length 56144 /Filter /FlateDecode >> stream -xڜ�M�l�}���>������z�խ����lQr8l`�6��`��;�O�S�쵫֮<O>rx �y�~yo�,��Z�<s���o�ϧ����_O�O����s�����?��y<���t��������w�ׇ����/��N��������rzx���w�w/�����C�����p������������7y(����Ƿ�����t9}���ǻo��~���?�q�7����~�����_����~?�����������Χ�������r9=�?��C_���y:�Ϗ�^�u��ځ����Ϊ��7���>�Ow�ONϲ�����˳T�go�x�>��?{C��u�/�ӋT�go�x]}�ކ�W��gY]��mx���� ���mx���Go�w@n�����*s�ځ�է�=���x��%�@�ރ�T�go�x�n�U�go�x���^/Rݟ��v�u�y�!�"� -ϲ���O�g����P;�@}ܞ�?�Ƴ7�<P���Q����P;���� Rϲ����p�?�Ƴ7�<P���^����P;�@�ކ�U�go�x]}�ކ;�cn<��x�no�4ߞ�!~;�O/����b����"��go�xU��ݝ^�ݏ�<��x�^N�'����P;�@�ޅNjT�go�x����S�gn�x]=oo�E��YV��u{���?{C��u{�ORݟ��v�����wVݟ��v�u������~��YV���r�~:Hu��ځ����٪��7�<P_N�O�Rݟ��v�u��� �/��Q6;��������d����p���� ��� �ȟ6��j^W���^��YV��u{��g�x��ځ��6�?�ȳ7�<P_N�W����P;��xwzz���ϲ�������x��ځ����ɪ��7�<P���Q����P;���� ��x��%�@�ކ�U�go�x�noý�7���v���� ��Go�w�|����f�Ɏ; �7�Κ��7�<PO���7w<{C����t�b���j^W_�N���g�x��%�@����O��� ���mx���� ���mx�?�Ƴ7����no�E��YV��u{��ϸ�� ���m8˟q��j���pg���j^U��N��g\�Eu <P�O������ ����óU�go�x�>�� -�Go�w�<o��њg]��=x���� ���=x����� ���]�\��?{C������6�Ku<��x�no��A���7�<P��A�N�� ����˫U�go�x]�ܝ./��\�eu <P�O/�v�go�x�>�.OVݟ��v���� ����x��ځ�Շ�m���<��x�no�Ū��7�<P��A�O��� ����=���<{��������:�eu <P��@�N�� ���ӽ����j�ϧ�����P;��tw����<��x�ޟ�e�$��P;�@�ކG����P;�@��Y;ɳ7���>oo����YV��u{?{C��u{d�$��P;�@��Y;ɳ7����ܝίRϲ����'�~}�Yq���,�'y�ځ����٪��7����n�,��YV��u{d�$��P;�@�ކ����P;�@��Y>ɳ7���>�mo��@;Ϣ����p���� ���m��<{C�����(��)��P;�z�;���D�eu <P�O��|�go�x�>��?{C��u{�`"��P;�z�� �8��lv������� ���� �k�<{��u{��O���G���d��/�[�p7���2Ο^����z����.ob���b�>���yz�=m���z��g��>�{C����w��o�����������w��y�w������O����A���{~z8��;?=�.o�z�y���=}~!/����k/䊺?{C������ty��x��%�@��^^��?{C��u{.�Rݟ��v���� �Vݟ��v�u��mC���Q6;��ރ�Y���7�<P���Ϊ��7�<P_Nϯ��w��ځ�����~�_X��gY]����٪��7�<P�N����:u��ځ��6<>Ju��ځ�� w�����<��x�no��I���7�<P����Y���7�<P���l���j^W���p�~��YV���rzz}���� �ԧ��Ū��7�<P_NO�7��7̊�NޟO���8s<��x�n���U�go�x�n���T�go�x�n���E���7�<�K�� ��gY]��P�S��V;/8u\�`���S��V;/(5�?P]��S��V;/8u\�`���S��V;/(5�?P]��S��V;�.8t���f���g���v ^�Pj.��������v ^�p���j������v ^�Pj.��������v ^�p���j������v ^�Pj.��������v ^�p���j������v ^�Pj.����g~�����0���������?�9.0ځx�è���k ^�p���j������v ^�p���j������K ^�p���j������v ^�p���j������K ^�p���j������v ^�p���j�����hv]�p�~��Ɋ����?�@����q�����J��T�@����q�����N�?X�@����q�����J��T�@����q�����N�?X�@����q�����J��T�@����q�����N�?X�@�������G�?9. �qx�Ù�����?�:.�ځx�é�����?����.�x�é�����?�:.�ځx�é�����?����.�x�é�����?�:.�ځx�é�����?�:/��������v ^�p���j����?ج8����\�@t ��N�?X�@����q�����N�?X�@����\�@u ��N�?X�@����q�����N�?X�@����\�@u ��N�?X�@����q�����N�?X�@����\�@u ��N�?X�@���������?�9.0ځx�C�������?�:.�ځx�é�����?�:.�ځx�C�������?�:.�ځx�é�����?�:.�ځx�C�������?�:.�ځx�é�����?�:.�ځx�C�����H�?�_�`����3��F;/8u\�`���Rs��%/8u\�`���S��V;/8u\�`���Q��R�@����q�����N�?X�@����q�����J��T�@����q�����N�?X�@����q����� -�?��8���������?�9.0ځx�nW���:�>��e_���������W=�(��1������+��f���|}Q=�3��q>����ݷ?~��������������?�i���o����^�|������|��ty<���9O�_̜�|���S>����ځ<OQj�)�v �S��y -�����y -�K �S��y -����f��j�<E����ځ<O1ꜧ���<E����ځ<OQj�)�v �S��y -�����y -�K �S���SP����y -���ef��h�<E���P�@��(5�T;��)J�<��y�R3OA�y�b�9O!u �y�R3OA�y����SP�@��(5�T;��)F��R�@��(5�T;��)J�<��y�R3OA�q�b��S��8��(r�S��8��(3�D;��)J�<��y�Q�<��%��)J�<��y�R3OA�y����SP�@��u�SH]y����SP�@��(5�T;��)J�<��y�Q�<��%��)J�<��y�R3OA�q���1OA��p�b��S��8��(3�D;��)J�<��y�R3OA�y�b�9O!u �y�R3OA�y����SP�@��(5�T;��)F��R�@��(5�T;��)J�<��y�R3OA�y�"��y -�k �S��y -����f��j�<E�c��f��<Řs�B����f��j�<E����ځ<OQj�)�v �S�:�)�.�<OQj�)�v �S��y -����f��j�<Ũs�B����f��j�<E����ځ<OQj�)�v �S�:�)�.�<OQj�)�v �S:�)hV�S��y -�����y -�K �S��y -����f��j�<E����ځ<O1ꜧ���<E����ځ<OQj�)�v �S��y -�����y -�K �S��y -����f��j�<E����ځ<O1ꜧ���<E�c��f��<E��� ځ<OQj�)�v �S�:�)�.�<OQj�)�v �S��y -����f��j�<E���P�@��(5�T;��)J�<��y�R3OA�y�b�9O!u �y�R3OA�y����SP�@��(5�T;�)�<�̎�y�"�<Ɋ�y�23OA�y�r<�P�|�<��ˀy���X�)�7�)O����W���g2O�����/�{����(�o5?|�A����x~=ڣ�oʂW?�)�ë?����/�)��%��)K���,T;��)K���,T;��)K���,T;��)˨�H]�����o�B������o�B������o�B�����:�)��%��)K���,T;�)K�㛲Ь8��,e曲�@��,��)"�K O��)"��SD�f��j�Q��"�ځ<E4�"���Q��"�ځ<ETj���v O��)"��SD��)"�K O��)"��SD�f��j�Q��"�ځ<E4�"���Q��ŏa8ET��"�Xq<ETf���v O��>Eu �)�R3ED�y���LQ�@�"*5SDT;���F�SDR�@�"*5SDT;���J���)�R3ED�y�h�9E$u �)�R3ED�y���LQ�@�"*5SDT;����̎�)�"�Ɋ�)�23ED�y���LQ�@�"uNI]y���LQ�@�"*5SDT;���J���)�Q���%���J���)�R3ED�y���LQ�@�"uNI]y���LQ�@�"*5SDT;�� -SD4+�����Ȏ�)�23ED�y���LQ�@�"*5SDT;���F�SDR�@�"*5SDT;���J���)�R3ED�y�h�9E$u �)�R3ED�y���LQ�@�"*5SDT;���B}�"���Q��"�ځ<ETj���v N:��hVO�9���.�<ETj���v O��)"��SD�f��j�Ѩs�H��SD�f��j�Q��"�ځ<ETj���v O�:���.�<ETj���v O��)"��SD�f��j�Ѩs�H��SD�f��j�Q�c��f��Q��""ځ<E4�"���Q��"�ځ<ETj���v O��)"��SD��)"�K O��)"��SD�f��j�Q��"�ځ<E4�"���Q��"�ځ<ETj���v O��)"��SD��)"�K N:��hVO��)"��SD�f��j�Ѩs�H��SD�f��j�Q��"�ځ<ETj���v O��>Eu �)�R3ED�y���LQ�@�"*5SDT;���F�SDR�@�"*5SDT;���J���)�R3ED�q�h�L��8�"*rL��8�"*3SDD;�����SD|���ˀ)��������?1�o��~�<}�=>�//W_�x&��C����������?�"./���pzx���=|}������o������x��塏�������^?�试<{C���������f2�x��%�@��^��XX���7�<P���l���j�����fR��� ���O���폅�:�eu <P/������P;�@}:]��LJݟ��v���rzy�ca����P;���� �Rϲ����p�$����7�<P���폅��?{C��u{?{C������6���e����=8�8��h��{pg���j�/��W���?{C������t�"��gY]����٪��7�<P�N�O���x��ځ��6<�8��j^_k�moÃS�,�k���� �'����P;�@�ކ�g����P;�@�ކ�U�go�x]=ooÝ�1�gY]�����U���7�<P�N�����P;�@}9=���0+�:y>����<��x�n���U�go�x�n���T�go�x��;:J�aT;��u�!u ��<J�aT;��(5�yP�@>̣��A��0�Q�aR�@>̣��A��0�Rs����<J�aT;��u�!u ��<J�aT;�(t�A���0�2s����<F��yH]�0�Rs����<J�aT;��(5�yP�@>�c�y���%��(5�yP�@>̣��A��0�Rs����<F��yH]�0�Rs����<J�aT;��(5�yP�@>�c�y���%��(s?̃��0<̣�q�Ŋ��<��aD;����0�k �Qj�ځ|�G�9̃j�a��0�ȇy�:��a��0�ȇy���<�v �Qj�ځ|�Ǩ�0�K �Qj�ځ|�G�9̃j�a��0���y��<dv�Q�8̃d��ae�0�ȇy���<�v �1�<�C�ȇy���<�v �Qj�ځ|�G�9̃j�a���<�.�|�G�9̃j�a��0�ȇy���<�v �1�<�C�ȇy���<�v �Qj�ځx�G��0���y��<Dv�Qf� ځ|�G�9̃j�a��0�ȇy�:��a��0�ȇy���<�v �Qj�ځ|�Ǩ�0�K �Qj�ځ|�G�9̃j�a��0�ȇy��~��5��(5�yP�@>̣��A��0�B�a4+��s�!t ��<J�aT;��(5�yP�@>̣��A��0�Q�aR�@>̣��A��0�Rs����<J�aT;��u�!u ��<J�aT;��(5�yP�@>̣��A��0�Q�aR�@>̣��A��0�B�a4+��(3�y�@>�c�y���%��(5�yP�@>̣��A��0�Rs����<F��yH]�0�Rs����<J�aT;��(5�yP�@>�c�y���%��(5�yP�@>̣��A��0�Rs����<F��yH]�0�B�a4+��(3�y�@>̣��A��0�Q�aR�@>̣��A��0�Rs����<J�aT;����0�k �Qj�ځ|�G�9̃j�a��0�ȇy�:��a��0�ȇy���<�v �Qj�ځx�Ǡ9�Cf��aE��<HV�Qf� ځ|���:̃�c?���e<��9~���<c�D�y�#�0�y��_���_~�| �� �{��<��Wyt��r�� �W5������W{>�8�h� ����g��:����� ����g���3@�v �Rj���ځ|Ȩ��K �Rj���ځ|H�9�j� ����g��:����� ����g���3@�v �Rj���ځxȠ9Df�� e���g���3@�v �Rj���ځ|Ȩ��K �Rj���ځ|H�9�j� ����g���~�5���)5g�P�@>�ԜB���Rs��3@F�g�H]��Rs��3@J� T;��)t�B����1� B�@>�ԜB���Rs��3@J� T;���u�"u �3@J� T;���)5g�P�@>�ԜB���Q� R�@>�ԜB���Rs��3@J� T;���u�"u �3@J� T;��)t�B����2s��3@F�g�H]��Rs��3@J� T;���)5g�P�@>d�y��%���)5g�P�@>�ԜB���Rs��3@F�g�H]��Rs��3@J� T;���)5g�P�@>d�y��%���)s?���0<��qŊ�3@�� D;��� ���k �Rj���ځ|H�9�j� ����g��:����� ����g���3@�v �Rj���ځ|Ȩ��K �Rj���ځ|H�9�j� ����g��3@dv�R�8�d�� e���g���3@�v �2�<D��g���3@�v �Rj���ځ|H�9�j� ��3@�.�|H�9�j� ����g���3@�v �2�<D��g���3@�v �Rj���ځxH����g��3@Dv�Rf��!ځ|H�9�j� ����g��:����� ����g���3@�v �Rj���ځ|Ȩ��K �Rj���ځ|H�9�j� ����g���~�5���)5g�P�@>�ԜB���B� 4+���s�"t �3@J� T;���)5g�P�@>�ԜB���Q� R�@>�ԜB���Rs��3@J� T;���u�"u �3@J� T;���)5g�P�@>�ԜB���Q� R�@>�ԜB���B� 4+���)3g��@>d�y��%���)5g�P�@>�ԜB���Rs��3@F�g�H]��Rs��3@J� T;���)5g�P�@>d�y��%���)5g�P�@>�ԜB���Rs��3@F�g�H]��B� 4+���)3g��@>�ԜB���Q� R�@>�ԜB���Rs��3@J� T;��� ���k �Rj���ځ|H�9�j� ����g��:����� ����g���3@�v �Rj���ځxȠ9Df�� E�3@HV�Rf��!ځ|����:��c?��e���ױ���3@����#���3@����������_��?|����?}�᯿��ۿ}�n�������Ͽ�ϗ����"��B��ҏW��_�I]y��ԬQ�@^!*5+DT;�W�J� -���Q� -��%�W�J� -���R�BD�y��ԬQ�@^!u�I]y��ԬQ�@\!*t�Ѭ8^!*3+DD;�W�F�+DR�@^!*5+DT;�W�J� -���R�BD�y�hԹB$u ��R�BD�y��ԬQ�@^!*5+DT;�W�F�+DR�@^!*5+DT;�W�J� -���R�BD�y�hԹB$u ��2�"��p����BD��x��̬�@^! -�}���+D�f��j� -Q�Y!�ځ�BTjV��v ��:W��.��BTjV��v ���"��+D�f��j� -Ѩs�H��+D�f��j� -Q�Y!�ځ�BTjV��v � �"��+DE�"��+Def��h� -Q�Y!�ځ�B4�\!��� -Q�Y!�ځ�BTjV��v ���"��+D��"�K ���"��+D�f��j� -Q�Y!�ځ�B4�\!��� -Q�Y!�ځ�BTjV��v �:V�hV� �"��+Def��h� -Q�Y!�ځ�BTjV��v ��:W��.��BTjV��v ���"��+D�f��j� -Ѩs�H��+D�f��j� -Q�Y!�ځ�BTjV��v ����Bu ��R�BD�y��ԬQ�@\!*t�Ѭ8^!s� ]y��ԬQ�@^!*5+DT;�W�J� -���Q� -��%�W�J� -���R�BD�y��ԬQ�@^!u�I]y��ԬQ�@^!*5+DT;�W�J� -���Q� -��%�W�J� -���B� -͊��2�BD�y�hԹB$u ��R�BD�y��ԬQ�@^!*5+DT;�W�F�+DR�@^!*5+DT;�W�J� -���R�BD�y�hԹB$u ��R�BD�y��ԬQ�@^!*5+DT;�W�F�+DR�@\!*t�Ѭ8^!*3+DD;�W�J� -���Q� -��%�W�J� -���R�BD�y��ԬQ�@^! -�}���+D�f��j� -Q�Y!�ځ�BTjV��v ��:W��.��BTjV��v ���"��+D�f��j� -ѠY!��q�BT�X!"Yq�BTfV��v �i;'V��:�⇗+���������W=�(��3������+���zzy�����<3w��D��_�|�ۏ�c�?}{���_��7�ϿsO�����Mx��k4?��ï���:��F͊��4��MB�@�M��k4Q�@�M��k4Q�@�M�f��j�ըs�J��V�f��j�U���ځ<`Uj��v X�:��.�<`Uj��v X��+��V�f��j�ըs�J��V�f��j�U�c��f��U��"ځ<`5�����U���ځ<`Uj��v X��+��V��+�K X��+��V�f��j�U���ځ<`5�����U���ځ<`Uj��v X��+��V��+�K X��XQ��V�+��Vef��h�U��VP�@�*5VT;��J̀���R3`E�y�j�9`%u ��R3`E�y���XQ�@�*5VT;��F�VR�@�*5VT;��J̀���R3`E�q�j�X��8�*rX��8�*3VD;��J̀���Q瀕�%��J̀���R3`E�y���XQ�@�uXI]y���XQ�@�*5VT;��J̀���Q瀕�%��J̀���R3`E�q���1`E��p�j�X��8�*3VD;��J̀���R3`E�y�j�9`%u ��R3`E�y���XQ�@�*5VT;��F�VR�@�*5VT;��J̀���R3`E�y�*��+�k X��+��V�f��j�U�c��f��s�J��V�f��j�U���ځ<`Uj��v X�:��.�<`Uj��v X��+��V�f��j�ըs�J��V�f��j�U���ځ<`Uj��v X�:��.�<`Uj��v X:�hVX��+��V��+�K X��+��V�f��j�U���ځ<`5�����U���ځ<`Uj��v X��+��V��+�K X��+��V�f��j�U���ځ<`5�����U�c��f��U��"ځ<`Uj��v X�:��.�<`Uj��v X��+��V�f��j�U��VP�@�*5VT;��J̀���R3`E�y�j�9`%u ��R3`E�y���XQ�@�*5VT;�̀�̎��"ǀɊ��23`E�y�J3L1`�ױX?�������u,��ֻ������9`�Wi�ݯ����?��?����Ś��<F�ߝ���k������/�|z��9�`�:w0������?��|~!��!u ��R��A�y���`P�@��(5;T;�w0F�;R�@��(5;T;�w0J����R��A�ycԹ�!u ��R��A�y���`P�@��(5;T;�w0F�;R�@��(s����1w0 -;+�w0�����P�w0�����Qjv0�v �`����;�f�j�ƨsC��;�f�j�F����ځ��Qjv0�v �`�:w0�.���Qjv0�v �`����;�f�j�Ơ����q��Q��� Yq��Qfv0�v �`����;���K �`����;�f�j�F����ځ��1������F����ځ��Qjv0�v �`����;���K �`����;�f�j�F�c�f��Ɛ���q��Qfv0�v �`����;�f�j�ƨsC��;�f�j�F����ځ��Qjv0�v �`�:w0�.���Qjv0�v �`����;�f�j�F��;P�@��(5;T;�w0J����B�͊��1���%�w0J����R��A�y���`P�@��u�`H]y���`P�@��(5;T;�w0J����Q���%�w0J����R��A�y���`P�@��u�`H]y���`P�@��(t�`Ь8��(3;D;�w0F�;R�@��(5;T;�w0J����R��A�ycԹ�!u ��R��A�y���`P�@��(5;T;�w0F�;R�@��(5;T;�w0J����R��A�ycԹ�!u ��B�͊��2��A�y���`P�@��u�`H]y���`P�@��(5;T;�w0J����P�w0�����Qjv0�v �`����;�f�j�ƨsC��;�f�j�F����ځ��Qjv0�v �`���;E���;ef�h��x��v0�:�̇���p��9~��/r{|=o��u�L��;�����or_����:��i���/?��?����V���~��������y�\� ��V��䡏���R�r\je�����Qje��ԪԔZQ]����Qje�����Qje�����Qje��ԪԔZQ]����Qje�����Qje�����Qje��Ԫ�QjE����Ƚ��d�a�ՙ���hb�թ���jb�U�)���b�թ���jb�թ���jb�թ���jb�U�)���b�թ���jb�թ���jb�թ���jb�U�)���b�թ���jb�թ���jR�ա{��͊�R�"G�Ɏ�R�3G����R�SG����R�SG����R�RSjEu �R�SG����R�SG����R�SG����R�RSjEu �R�SG����R�SG����R�SG����R�Qg���5K�N�VV;K�N�VV;�J��K�lV�Z��R+�K �Z�:J��v �Z�:J��v �Z�:J��v �Z��R+�K �Z�:J��v �Z�:J��v �Z�:J��v �Z��R+�K �Z�:J��v �Z�:J��v �Z�:J��v �Z��R+�K �Z�:J��v �Z��Z٬8,�:s�Z�@,�*5�VT�@,�:u�ZY�@,�:u�ZY�@,�:u�ZY�@,�*5�VT�@,�:u�ZY�@,�:u�ZY�@,�:u�ZY�@,�*5�VT�@,�:u�ZY�@,�:u�ZY�@,�:u�ZY�@,�*5�VT�@*�:t/��YqXju�(�2ځXju�(��ځXjUjJ��.�Xju�(��ځXju�(��ځXju�(��ځXj5�,���b�թ���jb�թ���jb�թ���jb�U�)���b�թ���jb�թ���jb�թ���jR�U��Ԋf�Q�Ց{��Ɋ�R�3G����R+t.M��_��g>���R+���q���A�?>�r�u<3K��TW��_��(���/?��������?��U֟��պ�����[k��}��\�G���C�_��!~��?��!�ځ�C4��!��rQ��!�ځ�CTjz��v ���"��=D���Hf�aQ����d�qQ��!"ځ�CTjz��v ��:{��.��CTjz��v ���"��=D����jrѨ��H��=D����jrQ��!�ځ�CTjz��v ��:{��.��CTjz��v ���"��=D��"��=DC��Hd�qQ��!"ځ�CTjz��v ���"��=D��"�K ���"��=D����jrQ��!�ځ�C4��!��rQ��!�ځ�CTjz��v ���"��=D���A]�����Q�@�!*5=DT;{� -=D4+�{�Ɯ=DB�@�!*5=DT;�{�JM���R�CD���h��C$u ��R�CD������Q�@�!*5=DT;�{�F�=DR�@�!*5=DT;�{�JM���R�CD���h��C$u ��R�CD������CD�⸇����@�!u�I]�����Q�@�!*5=DT;�{�JM���Qg��%�{�JM���R�CD������Q�@�!u�I]�����Q�@�!*5=DT;�{�JM���Qg��%{� -=D4+�{��L���R�CD���h��C$u ��R�CD������Q�@�!*5=DT;�{�B}�!��rQ��!�ځ�CTjz��v ���"��=D��"�K ���"��=D����jrQ��!�ځ�C4hz�dv�9z�HV���"��=Djɉ"������e@��u��������5.���?��x��[t��8�3z���D��_�������?���QJ��/��u^��߾{��������'��凿���o����x�r��|i�����;h$Ύ��fG��/��#���@G�䎈R�A��#��tDP�@�uvDH]�#��tDP�@�(5T;;" -4+;"�LG�Ȏ㎈2�A��#��tDP�@�(5T;�;"F�R�@�(5T;�;"JMG�䎈R�A��#b��!u 䎈R�A��#��tDP�@�(5T;�;"B}�rGD�鈠ځ�Qj:"�v vD::"hVwD�9;"�.��Qj:"�v wD�������#�jrGĨ�#B����#�jrGD�鈠ځ�Qj:"�v wD�:;"�.��Qj:"�v wD�������#�jrGĨ�#B����#�jbGD��#�f�qGD�� ځ�1�숐�rGD�鈠ځ�Qj:"�v wD������Ύ�K wD�������#�jrGD�鈠ځ�1�숐�rGD�鈠ځ�Qj:"�v wD������Ύ�K vD::"hVwD�������#�jrGĨ�#B����#�jrGD�鈠ځ�Qj:"�v wD���u 䎈R�A��#��tDP�@�(5T;�;"F�R�@�(5T;�;"JMG�䎈R�A��#b�tD��8�(rtD��8�(3D;�;"�[|{G���xx<���gGd�G���e`Gd<�#r���#�wת"�[Y�}�~�����k�r����|���~�������?����Ѭ8��ݐ���Ȏ�ڕ���@��]�����ڕ��Q�@��ݨ�vR�@��]�����ڕ��Q�@��]�����ڍ:?h'u �ڕ��Q�@��]�����ڕ��Q�@��]�������J���v Ю�|Ўj�� -��Yq�A�1��.��A�R�A;���+5��ځ�A�R�A;���u~�N���+5��ځ�A�R�A;���+5��ځ�A�Q���.��A�R�A;���+5��ځ�A�R�A;���u~�N���+5��ځ�A�B��hVЮ�|Ўh��F������J���v Ю�|Ўj��J���v �n��A;�K Ю�|Ўj��J���v Ю�|Ўj��F������J���v Ю�|Ўj��J���v �n��A;�K ~Ю��A;���+3�#ځ�A�R�A;���u~�N���+5��ځ�A�R�A;���+5��ځ�A�P�?hu �ڕ��Q�@��]�����ڕ��Q�@��ݨ�vR�@��]�����ڕ��Q�@��]������ ����8��]��v$+�?hWf>hG���v��W|Ў�c����ˀڏ_��A����/�x~���3>h���#������O��B}����������wH]?�py9=������Z_���������,���_���u�,�_|��_���|��_���|��_�b�y^��%��k(5�5P�@>��Ԝ�@����Rs^���F��5H]���Rs^���JM���֏BG�͊�֏!��!����̴~�@n�(5�T;�[?JM���֏Qg��%�[?JM���֏R��A����Դ~P�@n�u�~H]���Դ~P�@n�(5�T;�[?JM���֏P�[?�����QjZ?�v �~����������ǭc���K �~����ȭ����jr�G�i��ځ��1�l���r�G�i��ځ��QjZ?�v �~����ȭ����K �~����ȭ����jr�G�i��ځ��1�l���r�G�i��ځ��Q�h��Yq��QfZ?�v �~�:[?�.���QjZ?�v �~����ȭ����jr�Ǩ��C�ȭ����jr�G�i��ځ��QjZ?�v �~�:[?�.���QjZ?�v �~����ȭ����jr�Ǩ��C�������ǭe���hr�G�i��ځ��1�l���r�G�i��ځ��QjZ?�v �~����ȭ���~@]���Դ~P�@n�(5�T;�[?JM���֏Qg��%�[?JM���֏R��A����Դ~P�@l�4�2;[?��$+�[?�L�����qE�~�u쭟/Z?ǯ��\����kl?u����� }����3ydt~���������������~��������o���o��/?}���/ߝ��u���߿�.o����y������s9o/�¿�<��W�靽�\NO�x�\Q�go�x�>��o?���?{C�����tg���j^WΧ��'��gY]����퇒R�go�x�>��?{C�������CI���7���>no��Sdz�.���6<Xu��ځ��6�����aV�����4�go�x]}�ރ{��gY]��=x�)u��ځ��.�Yu��ځ���w -����P;��|�����+x<��x�^N�Vݟ��v����=/̍go�x�noã�17���v�u�e{�:�eu <P���"̍go�x�noý�17���v���� g����P;���� w���x��%�@��i�=yC�v�=�^�/��7Ċ; _N��n<{���E����˳�Q�gQ]����d���j�ۻ�x���� ���mxx���� �����m�Hu<��x�no���T�go�x�no��I���7�<P���Ϊ��7����ߝ�_��<��x�^N�O����P;�@}<=?[u��ځ�����U���7���^��A�Ŵ?�f���{ ���?z���r{��ܟ��v������f<{C�����X�u�I]y���Q�@�*5�@T;�g�J�,��Y�Q�,��%�g�J�,��Y�R3D�y���Q�@�u�I]y���Q�@�*5�@T;g� -�@4+g���,�Ȏ�Y�23D�y���Q�@�*5�@T;�g�F��@R�@�*5�@T;�g�J�,��Y�R3D�yh�9$u �Y�R3D�y���Q�@�*5�@T;�g�B}����,P���ځ<Tjf��v �:f�hV��9g��.�<Tjf��v ���Y �ȳ@�f�j�,ШsH�ȳ@�f�j�,P���ځ<Tjf��v ��:g��.�<Tjf��v ���Y �ȳ@�f�j�,ШsH�ȳ@�f�j�,P�c�f��,P��"ځ<4����,P���ځ<Tjf��v ���Y �ȳ@��Y �K ���Y �ȳ@�f�j�,P���ځ<4����,P���ځ<Tjf��v ���Y �ȳ@��Y �K �:f�hV���Y �ȳ@�f�j�,ШsH�ȳ@�f�j�,P���ځ<Tjf��v ���>u �Y�R3D�y���Q�@�*5�@T;�g�F��@R�@�*5�@T;�g�J�,��Y�R3D�qh����8�*r���8�*3�@D;�g��+65�ױ�?�����Y���������p�q����������������Cyf�c�/ߝ��o����<�����ww����$��)�����OB���S����)������)��<��5_�Ǎ���DR�@ *5DT;��J�����R3@D�y�h�9@$u ��R3@D�y���Q�@ *5DT;��F�DR�@ *5DT;� -D4+��������Q����%��J�����R3@D�y���Q�@ uI]y���Q�@ *5DT;��J�����Q����%��J�����R3@D�y���Q�@ uI]i���}����0 *pQ�8 *3DD;��B} ����Q� �ځ<@Tj��v ��"��D��"�K ��"��D�f��j��Q� �ځ<@4� ����Q� �ځ<@Tj��v ��"��D�f�Hf���Q�c��d���Q� "ځ<@Tj��v �:��.�<@Tj��v ��"��D�f��j��Ѩs�H��D�f��j��Q� �ځ<@Tj��v �:��.�<@Tj��v ��"��D��"��DCf�Hd���Q� "ځ<@Tj��v ��"��D��"�K ��"��D�f��j��Q� �ځ<@4� ����Q� �ځ<@Tj��v ��"��D��A]y���Q�@ *5DT;� -D4+��ƜDB�@ *5DT;��J�����R3@D�y�h�9@$u ��R3@D�y���Q�@ *5DT;��F�DR�@ *5DT;��J�����R3@D�y�h�9@$u ��R3@D�q���1@D��x����@ uI]y���Q�@ *5DT;��J�����Q����%��J�����R3@D�y���Q�@ uI]y���Q�@ *5DT;��J�����Q����%� -D4+��������R3@D�y�h�9@$u ��R3@D�y���Q�@ *5DT;��B} ����Q� �ځ<@Tj��v ��"��D��"�K ��"��D�f��j��Q� �ځ8@4h�dv9�HV��"����� ����^�_�2@<� ޝ��M>��q<3����w������������o��������������᯿|�\�}8��}^��b>�����iï%���������aD;��B}o��rcX�i�ځ�Vjèv 7����0�ȍa���0�K 7����0�ȍa��1�jrcX�i�ځ�6�l��rcX�i�ځ�Vjèv 7����0���a��1Lf�acX��1�d�qcX�i#ځ�Vjèv 7��:ä.��Vjèv 7����0�ȍa��1�jrcب�1L�ȍa��1�jrcX�i�ځ�Vjèv 7��:ä.��Vjèv 7����0���a���0���aC�1Ld�qcX�i#ځ�Vjèv 7����0�ȍa���0�K 7����0�ȍa��1�jrcX�i�ځ�6�l��rcX�i�ځ�Vjèv 7����0�ȍa��7�A]�1��4�Q�@n+5�aT;� -�a4+��Ɯ�aB�@n+5�aT;��JMc��ưR�F��1l��&u �ưR�F��1��4�Q�@n+5�aT;��F��aR�@n+5�aT;��JMc��ưR�F��1l��&u �ưR�F��1���F��1��4��@nu6�I]�1��4�Q�@n+5�aT;��JMc��ưQgc��%��JMc��ưR�F��1��4�Q�@nu6�I]�1��4�Q�@n+5�aT;��JMc��ưQgc��%� -�a4+���Lc��ưR�F��1l��&u �ưR�F��1��4�Q�@n+5�aT;��B}o��rcX�i�ځ�Vjèv 7����0�ȍa���0�K 7����0�ȍa��1�jrcX�i�ځ�6h�dv6�9�HV7����0�ȍa괊�0���1��e@c��u�������_Y�p9=��~xy�~־^o���̇���zg��������O�O���.ϯ�|0?e���R�sߜ^s����_y!���Y�@�o��qߜ����N��Y�@�o���7Gu ���N��Y�@�o��qߜ����N��Y�@�o���7Gu �����zߜŏat�܁�Z�Ŋõ�3�Z��ĵ�Q�Z��5� -NkV;� -NkV;� -NkV;� -J�Z�%� -NkV;� -NkV;� -NkV;� -J�Z�%� -NkV;� -NkV;� -NkV;�� - -k4;�� -��� -LV��9� -�v ��:� -�v �����K ��:� -�v ��:� -�v ��:� -�v �����K ��:� -�v ��:� -�v ��:� -�v �����K ��:� -�v ��:� -�v ���ج8Z+(r���8\+8s��@\+8u�X�@\+8u�X�@\+(5kT�@\+8u�X�@\+8u�X�@\+8u�X�@\+(5kT�@\+8u�X�@\+8u�X�@\+8u�X�@\+u�H]q��ԱV`�q��ԱV`�i���}��f��ZA�Y+ ��Z��c��j�Z��c��j�Z��c��j�ZA�Y+���Z��c��j�Z��c��j�Z��c��j�ZA�Y+���Z��c��j�Z��c��j�Z��c��j�ZA�Y+���Z��c��j�Z���Z�͊õ�3�Z��ĵ�R�V@u ĵ�S�Z��ĵ�S�Z��ĵ�S�Z��ĵ�R�V@u ĵ�S�Z��ĵ�S�Z��ĵ�S�Z��ĵ�R�V@u ĵ�S�Z��ĵ�S�Z��ĵ�S�Z��ĵ�R�V@u ���C����kg����k�����k�f����k�����k�����k�����k�ε�k ��:� -�v ��:� -�v ��:� -�v �����K ��:� -�v ��:� -�v ��:� -�v �:� -hv�����8\+8s��@\+@�ެ�u|}���xx>Z+��X� -�k��7��V�|X+��\+���/�_��8��������U��&^����痗ó�iCïa��?���П_�aŏa؆V�hC�Xq܆Vf�Јv ����ކu �6�RӆF�� �Դ�Q�@nC+5mhT;���F�mhR�@nC+5mhT;���JM��6�RӆF�� m�ن&u �6�RӆF�� �Դ�Q�@nC+5mhT;��M�̎�6�"GɊ�6�2ӆF�� �Դ�Q�@nCu��I]� �Դ�Q�@nC+5mhT;���JM��6�Qg��%���JM��6�RӆF�� �Դ�Q�@nCu��I]� �Դ�Q�@nC+5mhT;�� -mh4+�ІL�Ȏ�6�2ӆF�� �Դ�Q�@nC+5mhT;���F�mhR�@nC+5mhT;���JM��6�RӆF�� m�ن&u �6�RӆF�� �Դ�Q�@nC+5mhT;���B}oC��rZ�iC�ځ܆Vj�Шv ��:��hV���9�Є.�܆Vj�Шv ����64��mh�� �jrڨ� M��mh�� �jrZ�iC�ځ܆Vj�Шv ���:�Ф.�܆Vj�Шv ����64��mh�� �jrڨ� M��mh�� �jbZ�� �f�qZ�iC#ځ܆6�lC��rZ�iC�ځ܆Vj�Шv ����64��mh��64�K ����64��mh�� �jrZ�iC�ځ܆6�lC��rZ�iC�ځ܆Vj�Шv ����64��mh��64�K ��:��hV����64��mh�� �jrڨ� M��mh�� �jrZ�iC�ځ܆Vj�Шv ����ކu �6�RӆF�� �Դ�Q�@nC+5mhT;���F�mhR�@nC+5mhT;���JM��6�RӆF�� mд���8lC+r����8nC+3mhD;���T�mh|{���xx9lC��gz�G���gnC�g>��/7���������~�&�zz���˟/��==u��ox�����W~|����Kߨv _�Vj.}�ځ|�[���j�o��n;�K uە�w�Q���v�n;���ve�ێhr�]���vP�@�+5�vT;���JM���n�R�mG���n��m'u �n�R�mG��ۮ�t�Q�@�+5�vT;���F��vR�@�+5�vT;���JM���n�R�mG���n�t���8�+rtۑ�8�+3�vD;���JM���n�Qg���%���JM���n�R�mG��ۮ�t�Q�@�uv�I]�ۮ�t�Q�@�+5�vT;���JM���n�Qg���%���JM���n�R�mG��ۮ��mG���n�tۉ�8�+3�vD;���JM���n�R�mG���n��m'u �n�R�mG��ۮ�t�Q�@�+5�vT;���F��vR�@�+5�vT;���JM���n�R�mG���.��n;�k wە�n;���v��ێjb�]��ێf�q�ݘ��N���v��ێjr�]�鶣ځ�mWj���v wۍ:���.��mWj���v wە�n;���v��ێjr�ݨ��N���v��ێjr�]�鶣ځ�mWj���v wۍ:���.��mWj���v v�:��hVwە�n;���v��n;�K wە�n;���v��ێjr�]�鶣ځ�m7�춓�r�]�鶣ځ�mWj���v wە�n;���v��n;�K wە�n;���v��ێjr�]�鶣ځ�m7�춓�b�]��ێf�q�]��#ځ�mWj���v wۍ:���.��mWj���v wە�n;���v��ێjr�]���vP�@�+5�vT;���JM���n�R�mG���n��m'u �n�R�mG��ۮ�t�Q�@�+5�vT;��M��̎�n�"G�Ɋ�n�2�mG���~\�V�v|{����xx=����=�_N�t��w�ϯ�_Po���u�������P����4������O_~�}�������۟���{�������˧n������W;_�o|?>��6^�ŏg>����Ǘ���[��e\1�go�x]}:oo�Tdz�.����x����� ���]����� ����ob����j^W��|}yp�x��%�@�����?{C���q{�Q���7�<P����I���7�<���Q���%��7J�����R��A�yy��,oP�@^�u.oH]iy��}y���0\�(p,oP�8^�(3�D;��7B}_ހ���F�Yޠځ��Qj�7�v /o��� ������ �K /o��� ����fy�j��F�Yޠځ��1�\ސ���F�Yޠځ��Qj�7�v /o��� ����fyCf���F�cy�d���F�Y� ځ��Qj�7�v /o�:�7�.���Qj�7�v /o��� ����fy�j��ƨsyC����fy�j��F�Yޠځ��Qj�7�v /o�:�7�.���Qj�7�v /o��� ������ ���CfyCd���F�Y� ځ��Qj�7�v /o��� ������ �K /o��� ����fy�j��F�Yޠځ��1�\ސ���F�Yޠځ��Qj�7�v /o��� �����/o@]yy��,oP�@^�(5�T;�7 -�4+��7Ɯ�B�@^�(5�T;��7J�����R��A�yycԹ�!u ��R��A�yy��,oP�@^�(5�T;��7F��R�@^�(5�T;��7J�����R��A�yycԹ�!u ��R��A�qy�б�A��xy��,o�@^�u.oH]yy��,oP�@^�(5�T;��7J�����Q���%��7J�����R��A�yy��,oP�@^�u.oH]yy��,oP�@^�(5�T;��7J�����Q���%�7 -�4+��7������R��A�yycԹ�!u ��R��A�yy��,oP�@^�(5�T;��7B}_ހ���F�Yޠځ��Qj�7�v /o��� ������ �K /o��� ����fy�j��F�Yޠځ��1h�7dv.o9�7HV/o��� ������� ��}y��e����ul���}��m�^�/o�ϧ篿1�����2_�����g���4&7��������O_~��/?��o�=?>��>�7>}�۟�^�=;?>���i�5桏/���u��^��/�_�u��ځ�է������Fϲ����ˋU�go�x�>�.o�����P;�@}9���)�R�go�x]��{qy��x��%�@�ކ��e�����P;�@�ކ�?ET��� ���m����� ���/��p���Q6;��ރ�Y���7�<P���Ϊ��7�<P_Nϯ��w��ځ����������,�K��z9=?[u��ځ��s�I����P;�@�ކG�g<{C���㞻�mxpj�Eu <P����$���j���p�,���j���p���� �����m�s?��,�K��z9=��Ju��ځ����b���j�/�'����f�]'�ϧ����g]��=x���� �ԧ���R�go�x�n���E���7���^���"��,�K���� �Rݟ��v���� g�g<{C��u{?{C������t�*̍gY]����E����P;�@}:�=[u��ځ�������x��ځ�F���Q��ϲ�����`���j�����;.hV�qQf� ځ|�Ũ��K �qQjځ|�E���j�����w\�:︐������w\��;.�v �qQjځ|�Ũ��K �qQjځ|�E���j�����w\�:︐��e�w\P��w\8Xq|�E���h����qu �;.J�T;��(5w\P�@����qA����Q�R�@����qA����Rs���;.J�T;��u�q!u �;.J�T;��(5w\P�@����qA��AsDž̎�;.�w\��8����qA����Rs���;.F�w\H]���Rs���;.J�T;��(5w\P�@��b�yDž�%��(5w\P�@����qA����Rs���;.F�w\H]���Rs���;.J�T;�(t�qA�����!sDžȎ�;.��D;��(5w\P�@����qA����Q�R�@����qA����Rs���;.J�T;��u�q!u �;.J�T;��(5w\P�@����qA����P�︀������w\��;.�v �qQ��f��c�;.�.�|�E���j�����w\��;.�v �q1��B��w\��;.�v �qQjځ|�E���j���;.�.�|�E���j�����w\��;.�v �q1��B��w\��;.�v �qQ��f��e���w\�:︐������w\��;.�v �qQjځ|�Ũ��K �qQjځ|�E���j�����w\�:︐������w\��;.�v �qQjځ|�Ũ��K �qQ��f��e���w\��;.�v �q1��B��w\��;.�v �qQjځ|�E���j����qu �;.J�T;��(5w\P�@����qA����Q�R�@����qA����Rs���;.J�T;�4w\��8���q�Ɋ�;.��D;���$Qw\�u�w\>��ǻ�;.ǯ����o��\f����0�m��r���xd<�_q9�;.��_�����7'�ӿ��ۗ�����N�ϸ<n��qp�e^8~����k<���U���"+��r�����r�!s8�Ȋ�����"+�o2'��8>p�|�pL.q|-��9@d���C�R���w�3DV ��d���C�@�������DV�0�8 @��0> �y�Ď����Q�"+�O2��8�`Ȝ ���� �-� ;�/2����8>`�\ ����!s�Ȋ����� ;�������Ȋ��!��'��x�o�����8�rn���8^�2�"+��Fk?���߀���Xq<�����q��7dF�DVO� ��?���~Cf�Od��_�s�d��ߐ�Yq<�7dV�DVo� �I?�ǃ~A�=?��k~Cf�Od��ߐY�Yq��7df�DV��97�@v-� ������}���>q�x�o�L�I�8��&�w���ǫ}Cf�Od��dߐY�Yq��7d��DV��9��@v/� ��>��3}Cf�Od��Fߐ��Yq<�����q��7d��DVO� �e>�ǻ|Cf�Od��(_���Xa��7���1�����Ċ�-�!3�'��x�/ȹ���x�oȌ���8��2|"+�������Ȋ�� ��Ȏ��!3�'��xvoȬ8��2�{"+����{{ ;�����؞Ȋ㩽!��'��pgo�1�'�c�셗�=x�{f`Ob��ސY�Yq��7d��DV�9w�@v�� �Q=�ǓzCfQOd��ސ��Yq<�����q��7d��DV�� �=��zCfBOd���6���?&�8^�2�y"+����r�Ȋ�ݼ�l���a<���̃�q��7d�DV�� ��<��[yCf*Od��P^�s'd��Jސ�Yq<�7d�DV�� �y<���xA�m<���xCfOd��,ސY�Yq��7d&�DV�9��@v�� �1<��Sx#�%<��xo���I�8�rn���8^�2x"+������Ȋ���!3}'��x�.ȹ{��x�nȌމ�8��2�w"+����ܝȊ㱻 ��Ȏ㥻!3t'��x�nȬ܉�82w"+��v ;��F�v?��݀Y��Xq�k7df�DV��97�@v/� �A;��svCf�Nd��ݐ��Yq<d�M��؏�%�W�̈�Ȋ� �!�`'��x�n���8�rnׁ�8^�2�u"+�g��j�Ȋ�ͺ!3Y'��p�.����0\�o�����Suf�Nb��N�ps�f��"����k�����*<��z�^]��_�����?�~z~�����ԳT�����������?���o�~�?�.o��#�g��OG3��3����y�4��B`j��cc�fm�j��X��ځ<9Vj6Ǩv ���:gǤ.�<<Vj�Ǩv o����1���c���1��dc� 2�K ����2��;d�f��j�Y��"�ځ�F6�#��� Y�Y$�ځ�IVjFɨv ϒ��]2���d��i2�K ����u2���d�f��j�DY��(�ځ�R6�)���PY�Y*�ځ�UV�+�Yq<WVf�ʈv /��:'ˤ.�<ZVjV˨v ��2���e�f��j�z٨s�L��f�f��j�Y�1�ځ<cVjv̨v /��:�̤.�<fVj�̨v �A3�ȓf�fӌj�٨s�L�H�fe��f?��Y�c܌b��Y��7#ځ�p����5�G�J���䝳R3tF�y��l�Q�@^;uΝI]y��,�Q�@�<+5�gT;�g�J�����Q����%���J������R3�F�y��l�Q�@\A43h2;�ЊKh$+�������9�R��F�ym�9�&u �Q�R��F�y���Q�@�F+5�hT;���F��hR�@H+5iT;�7�J�H�䙴R��F�y)m�9�&u 䱴R��F�y/���Q�@�L+tl�Ѭ8\M2�i";�����r����R3�F�y>���Q�@^PuN�I]yD�Ԭ�Q�@�Q+5CjT;���J͖��5�Q眚�%��J͢��M�R3�F�yV���Q�@^V�}Z ���j�f]�j�Z�X�ځ8�V��X�Yq��6�Y���Z�YZ�ځ��Vj�֨v ϭ���5�ȋk���5�K �����5�Ȼk�fx�j��Z��^�ځ��6�_����[�Y`�ځ��VjFبv ϰ��6��Kl��)6�K ����56��{l��A6�Ǔlef��h�*ۨs�M���l�f��j�6[�g�ځ<�Vj�٨v /��:'ڤ.�<�VjVڨv ﴕ��6��Sm�f��j�Zۨs�M�ȃm�f��j�f[�m�ځ<�Vjvۨv /��:�ۤ.�8�V�Xo�Yq��Vf܈v O��� 7��+n��7�K ���%7��[n�f̍j�[��s�ځ������5�G�Jͪ��]�R3�F�yڭ�l�Q�@^wuλI]y��,�Q�@�x+5#oT;�g�J���ĥ�A3�&��p�ȱ�F��x����@�|���_�>���2`�}�:���=Ͼ/��ߢ��;�d�}�o$������/�����~��������������|?����q��<���㮼��q���8�f����8��q���8��q���8��q���8�f����8��q�H�8���86+�q��8F;�qJ�8�%�qN�8V;�qN�8V;�qN�8V;�qJ�8�%�qN�8V;�qN�8V;�qN�8V;�qJ�8�%�qN�8V;�qN�8V;�qN�8V;�qJ�8�%�q��:�c�c�����X�8�9s���@�u��H]q��1�c�q��1�c�q��1�c�q�Ԍ�P]q��1�c�q��1�c�q��1�c�q�Ԍ�P]q��1�c�q��1�c�q��1�c�i��1�C��h��}�d��8Ιc�h�8Ωc�j�8N�ǡ��8Ωc�j�8Ωc�j�8Ωc�j�8N�ǡ��8Ωc�j�8Ωc�j�8Ωc�j�8N�ǡ��8Ωc�j�8Ωc�j�8Ρ�8�͊�q�"�8Ɏ�q�3�8���q�S�8���q�S�8���q�R3�Cu �q�S�8���q�S�8���q�S�8���q�R3�Cu �q�S�8���q�S�8���q�S�8���q�Q�8��5�qN�8V;�qN�8V;��q��qlV�㔙q�K ��:�q�v ��:�q�v ��:�q�v �㔚q�K ��:�q�v ��:�q�v ��:�q�v �㔚q�K ��:�q�v ��:�q�v ��:�q�v �㔚q�K ��:�q�v �����ج8�9s���@�)5�8T�@�9u��X�@�9u��X�@�9u��X�@�)5�8T�@�9u��X�@�9u��X�@�9u��X�@�)5�8T�@�9u��X�@�9u��X�@�9u��X�@�)5�8T�@�9tDZYq8�s��1ځ8�s�DZځ8�Sj�q�.�8�s�DZځ8�s�DZځ8�s�DZځ8�3�Ǒ��8Ωc�j�8Ωc�j�8Ωc�j�8N�ǡ��8Ωc�j�8Ωc�j�8Ωc�j�8N�c�f��8Α�8�Ɋ�q�3�8���q.�n���u|}���8�����}'����������L�q�|'ꟾ��������7/��OO���^^^7�������?��?�Ő�w����ǟ�}����g��/�������T��_ү.}��~���q����v ~��S��_�ځ���ݿ��͊ï�Tf���%��ҩ��/Y�@��K����d���/�:����į�Tj���%��ҩ��/Y�@��K�f�j��W�Y��ځ��5�\�����W�Y��ځ��Uj��v /|�����W��5�u$���|���|ϣ$�#�?� -�8�Q6p���_��:�}j�f�>�ܽ�ٜ�8 n�)�6�_c��/Y �ʚ�� ��WIG���q)|Q�@.|�u�d]�\�*k -_�6�_eM��r)|��@.|�u�d]�\�*k -_�6�_eM��r)|��@.|�u�d]�\�*k -_�6�_eM��r)|��@.|�u�d]�T�*�V������������W9S����\� -��� -��WYS����\�*k -_�6�_eM��r�k���%���WYS����\�*k -_�6�_eM��r�k���%���WYS����\�*k -_�6�_eM��b�k�)|��8,|�r��,�ʙ�� ��WYS����\��,|ɺ���U��hm �ʚ�� ��WYS����\��,|ɺ���U��hm �ʚ�� ��WYS����\��,|ɺ���U��hm �ʚ�� ��WIG���a�k�)|I�8.|�3�/Jȅ����Ek��U��hm ��:_�.@.|�5�/Zȅ����Ek��U��hm ��:_�.@.|�5�/Zȅ����Ek��U��hm ��z.|����U��hm �ʚ�� ��WIG���q�k���%���WYS����\�*k -_�6�_eM��r�k���%���WYS����\�*k -_�6�_eM��r�k���%���WYS����\�*k -_�6�_eM��r�k���%���WYS����X�*�(|�Y8.|�3�/Jȅ�����_eM��r)|��@.|�5�/Zȅ�����_eM��r)|��@.|�5�/Zȅ�����_eM��r)|��@.|�5�/Zȅ����_%�/:Dž�r��Ei��U��hm ��:_�.@.|�5�/Zȅ����Ek��U��hm ��z.|����U��hm �ʚ�� ��WYS����\��,|ɺ���U��hm �ʚ�� ��WYS����X�i -_r6_��/*Dž�r��Ei���T��9����c@��9~�����������:�?�=>������4��#[ߛ�/��_����a�t��S&��p���*=��J�����ÕO��.?���y>�\|v��$�^�6�}���p�z��Xdzl]�;ֻ��흴n�^�6p�z�6�u{����;�ӷ����n�^�6�}���p�����:�e�ܱ����u{����;�����1&eݞ�bm���������ʺ={�����O�oÃ��gٺ�w��o��1&eݞ�bm����mx��`eݞ�bm����m�����+��o}>}�?��G�ٸ��{p�?pƳW� ܱ��7ֺ={��������~}�g�X����x�}�?pƳl]�;ֻӯ��u{����;������17��bm����mx�?pƳW� |?Ӻ9}�5Ϣu�XO߆�Giݞ�bm����m�}����+��XO߆��n�^�6pg/f��\�!��Ee�"Zȋ<ʚE�6y�t,�p��c�s����y�5�<hm /�(ky��@^�Q�,��c�s����y�5�<hm /�(ky��@^�Q�,��c�s����y�5�<hm /�(ky��@^�Q�,��c�s����y�5�<hm .�(�X�Ag�x�G9�ȃ��"���E�.@^�Q�,�ȣ�Y�Aky�GY�ȃ��"���E�.@^�Q�,�ȣ�Y�Aky�GY�ȃ��"���E�.@^�Q�,�ȣ�Y�Aky�GY�ȃ��"���E�.@Z�Q�m���0\�Q±ȃ���"�rf�� �Ea=/�u�"��f�� �Ee�"Zȋ<ʚE�6�y�u.�u�"��f�� �Ee�"Zȋ<ʚE�6�y�u.�u�"��f�� �Ee�"Zȋ<ʚE�6y�4�<�l.�(�X�Ae�x�G9�ȃ��"��f�� �Ec��<d]��ȣ�Y�Aky�GY�ȃ��"��f�� �Ec��<d]��ȣ�Y�Aky�GY�ȃ��"��f�� �Ec��<d]��ȣ�Y�Aky�GY�ȃ��"���Ety�2�<�l/�(gyP�@^�Q�,�ȣ�Y�Aky��X�"Y /�(ky��@^�Q�,�ȣ�Y�Aky��X�"Y /�(ky��@^�Q�,�ȣ�Y�Aky�GXϋ<`]��ȣ�Y�Aky�GY�ȃ��"���Et�y�s.�t�"��f�� �Ee�"Zȋ<ʚE�6�y�u.�u�"��f�� �Ee�"Zȋ<ʚE�6�y�u.�u�"��f�� �Ee�"Zȋ<ʚE�6�y�u.�u�"��f�� �E%�<�,/�(gyP�@^�1ֹ�C�ȋ<ʚE�6�y�5�<hm /�(ky��@^�1ֹ�C�ȋ<ʚE�6�y�5�<hm /�(ky��@^�1ֹ�C�ȋ<ʚE�6�y�5�<hm /�(ky��@^�1ֹ�C���<J:y�Y8^�Q�,�ȣ�Y�Aky��X�"Y /�(ky��@^�Q�,�ȣ�Y�Aky�GXϋ<`]��ȣ�Y�Aky�GY�ȃ��"��f�� �Ec��<d]��ȣ�Y�Aky�GY�ȃ��"��f�� �E#�"9��<J9yPY8^�Q�,��C[3b�?Ƕ�s�1`�g�s����|�����������7��v�������z<�g��s�<��O/�y~�������?o����|��/���^r|:���r�~>���<�!��gr���Ð����6��eM��rb�3!��0DY�����(k��6��eM��rb�3!��0DY�����(k��6��eM��rb�3!��0D9�0��0C�p�!h,�!ʙ0� �0DX�aXW �!ʚ0� �0DY�����(k��6��c�aY �!ʚ0� �0DY�����(k��6��c�aY �!ʚ0� �0DY�����(k��6�#MB��a��#Ae�8Q΄!(m �!ʚ0� �0�XgB��a��&Ak9Qք!hm �!ʚ0� �0�XgB��a��&Ak9Qք!hm �!ʚ0� �0�XgB��a��&Ak9Qք!hm �!J:�t��LB��q�� CP�@C�5aZ�a��&Ak91���ur�� C��@C�5aZ�a��&Ak91���ur�� C��@C�5aZ�a��&Ak9�s��a��&Ak9Qք!hm �!J:�t���aI �!ʚ0� �0DY�����(k��6��c�aY �!ʚ0� �0DY�����(k��6��c�aY �!ʚ0� �0DY�����(k��6��c�aY �!ʚ0� �0DIG���q�� CP�@C�u�!d]��(k��6��eM��r�� C��@C�u�!d]��(k��6��eM��r�� C��@C�u�!d]��(k��6��eM��r�� C��@C�u�!d]��(�C�Y8C�3aJ�a��&Ak91���ur�� C��@C�5aZ�a��&Ak9�s��a��&Ak9Qք!hm �!ʚ0� �0�XgB��a��&Ak9Qք!hm �!ʚ0� �0�H���q�(�CPY8C�3aJ�a�"�ϱ�!������2��9���r2�Ira��������������������/?����|�����_����o�g���ǯ��;O���#��N?O�������_�<7w�n���sshm ��S֜�Ck�ܜ���9���r��Ce��ܜr��J���5����@>7g���Y ��S֜�Ck�ܜ���Z���5����@>7g���Y ��S֜�Ck�ܜ���Z���5����@>7g���Y ��S֜�Ck�ܜ���Z���t��Cg��ܜQ��)���3��P�@>7��97���9e9�6����<7G����5����@>7��97���9e9�6����<7G����5����@>7��97���9e9�6��� ���XW ��S֜�Ck�ܜ���Z���t��Cg��ܜq�ss$]�|nNYsn� �ssʚsshm ��S֜�Ck�ܜ��ssd]�|nNYsn� �ssʚsshm ��S֜�Ck�ܜ��ssd]�|nNYsn� �ssʚsshm ��S֜�Ck�ܜ��ssd]�|nNYsn� �ssJ:�͡�p|nN9sn� �ss�:�͑u�9e9�6���)k�͡��|nNYsn� �ss�:�͑u�9e9�6���)k�͡��|nNYsn� �ss�:�͑u�9e9�6���)k�͡��|nNYsn� �ss�:�͑u�9%���Y8>7��97���9e9�6����<7G����5����@>7��97���9e9�6��� ���XW ��S֜�Ck�ܜ���Z���5����@>7g���Y ��S֜�Ck�ܜ���Z���5����@<7g�97G���9���PY8>7��97����3\��~�����ǀss��c97w{����ߚ�cs�#95w7N��������Ǜ��|�_�O���7��no^~|ҳ�����ǽ���鿽y�ϙg.>�������l/�|�w�ۣ�,���+6��ee�v�χ�gg��$/a��n����/�p<����(O_�G��ee�v����íSn���p;�����W�F�=��½��;}��r<����(O_��{��ee�v��/��/�r{����Q���7R�=��½��?n^�r<����(���4��QVnG�x�y���QVnG�|x������p�+N_��cd<����(O_�{��ee�v��/��'��$/a;��W������p;�(���N9Ee�v��R ��%�,_Qa��������)�2�S��p|9�Pλ)@�8���(s1)��Ren� e��N -�̕�,_H!��> -P6�o�0�\FA���UF��(HY8���(s )ǗP弃���(�p���t(�~���������F��'�X8�x��|�ľr��F�K'HY8�r�(s�)��Me�� e��� ��wM��q|ӄQ� R���0��2A���F�+&HY8�`B(���l�.a��dIY8Nd�2�,)�}�Q&�%e�0�ƴ� ,���7�X�]�8�5�T�d,7�F�$���� V(g��q k��aIY8Na�2%,)��Q&�%e�8������q\�eXR��W�L�J��q�j�I_IY8_�rv��lW�F�蕔����(S���pػ��]Ix ��U�Һ��`\�aBW2�3W�L�J��q�j�I\IY8\�r���lF�������(S���pܵe�VR��V��M+(�E�Q&h%e�8g5�Ԭ�,��F���������ܱ�+W�F�������(S���pد��WIx �xUg� -��q�j� WIY8�V�2�*)�ͪQ&Y%e�8X�٫��q\�ebUR�SU�L�J��q�j��TIY8�T�r6��l�F�@����<�(S���pܦe�TR��T��]*(�U�Q&J%e�0I5�Q����=�&G%c�8F�٢��q\�eBTR�3T�L�J��q�j�IPIY8P�r���lקF��������(S���pܝe�SR��S���)(�ũQ&8%e�875�Ԧ�,��F�Ԕ����T(gg -��aej�#2%�%�S#LaJ��q_j��KIY8�K�r���l��F�������(S���pܔe�RR�����sO��\p\�ebRR�SR�LIJ��qGj��HIY8�H�r6��l�F������|�(S���pe�QR�QaL7 -a5j|#%�%��Q#L1J��q/�[=�\�>�V��?Ģ��ǿ�߽�>%ܱp�a�x?��_��8�<���)E����7?}���O�}��^oN��u�����z�����m*z��KE�χ��?�s����w|<�^g��ykϲu�X���ֺ={��������؆�n�^�6p��|x~�-6eݞ�bm��֧ӷ�AZdzl]�;�ӷ��YZ�g�X�c=}^�MY�g�X�c=}n�u{�����[�O߆['�eg�v�����(�۳W� ܱ��7ֺ={��������~}�g�X����u��Ydzl]�;ֻ�ӓ�n�^�6p��x�}�����+��XO߆�g<{�������ӷ��Y�,ZW����m�{����+��XO߆�'iݞ�bm����m8Z���kw�'� -���U�.@��P�{���<�����@kq�CIǼ:��9>H��y�CY3���̇�f�� �e��Z�c�:�>Ⱥ�y�CY3����䇲f�� ��e��Z���:�?Ⱥ�y�CY3�������f�� �e�Z�# �:W@Ⱥ�yDY3������-t��@�3s (m ��\!��Me�(Zȳ ʚ]�6��A�5� hm ���\!��}e�@Z�!ʚ��6�WB�53!hm ��\ -!��e�XZ�s!ʚ��6�C�5�!hm ���\ !����܆C�x ��%�!h,��(g�CP�@��XW o�(kFD��@�Q�술���$���AkyL�X�Y �(kE��@�Q�l�����*���AkyX�X�Y o�(k�E��@�Q�신���0���Akqd�H�2B���ΈR��T��F�3[#(m ��(k�F��@1ֹ8B�ț#ʚ��6�gG�5�#hm /�(k�G��@1ֹ>B���#ʚ�6�'H�5$hm ��(kfH��@"1ֹDB��[$ʚ1�6��H�5{$hm .�(�$Ag�p��(�JB���.�rf�� �ie�6 Z��$ʚy�6�J�u.��u�F��f�� �e�N Z�K%ʚ��6��J�u���u�^��f�� ��e�f Zȫ%ʚ��6��K���\���%ʚ��6��K�5�%hm .�(�0Ag�x��8� I �(k�L��@�2Q�l�����f���3Aky��X� Y o�(kFM��@�5Q�욠���l���6Aky��X� Y �(kN��@�8Q�l�����r���9Aky��X�� Y o�(k�N��@�;Qұw�����rf�� ��c��'d]��{��>Aky�DY�}������f�� �c�(d]�����AAkyEY�������f -� �1c�k(d]�����DAkyEY�����*��f� �ac��(d]�����c���y��> -J�)ʚ��6�GR�u���u�N��f(� �e�V -Z�k)ʚ��6�S�����ț)ʚ��6�gS�5�)hm /�(k�S��@O1ֹ�B���)ʚ�6�'T�5*hm ��(kfT��@R1�,���q����cL���9�̞ -Jȋ*�� jR?Ƕ�r�1nwGU�?��χ���{��\����7��':��������<�g��r�*��ӷ��ۧϿn�_>��������/?���o۟~���߿�������>l��_>�����_�����/�����|�����?��`�O�v���eo�����j�ڋ����o?��Ek�����d]���VY�� ��ʚ�hm ��Uּ�Ek�����d]���VY�� ��ʚ�hm ��Uּ�Ek����_Ђu�Ze�Z�6�_�*k^Т����VI�Zt�_��|AK��/h�5/h��@~A��yA���Ze�Z�6�_��|AK��/h�5/h��@~A��yA���Ze�Z�6�_��|AK��/h�5/h��@~A��yA���Ze�Z�6�_��|AK��/h�5/h��@|A���-:�/h�3/hQ�@~Ak��-Y ��Uּ�Ek����-Z�/h�5/h��@~Ak��-Y ��Uּ�Ek����-Z�/h�5/h��@~Ak��-Y ��Uּ�Ek����-Z�/h�5/h��@~Ak��-Y ��U������ʙ�(m ��Uּ�Ek�����d]���VY�� ��ʚ�hm ��Uּ�Ek����_Ђu�Ze�Z�6�_�*k^Т����VY�� ���:_Вu�Ze�Z�6�_�*k^Т����VY�� ��F���l��U������ʙ�(m ���C�^����^�^|xA��9��G~A{��r8�m����������=}��o�����?{��f=�����y}��_��|���/߿��q{��p�w�����h������}�i�H����?�t����������韴%o�5/w{ߚ��C_�<t�����y��o��u�� �67|�ul�������cÇ� � e͆Z n�8���akq��Ydž[�>�:6|��@��Qұ���ц�Sn>�,n�8���aiq��Ydž[�>ʚ �.@��qֱ����� �67|�ul�����ᣬ��A�� g>lm n�8���akq��Ydž[�>ʚ �.@��qֱ����� �6�6|�t��ag�h�G)dž*�>�96|X�@��q�qD�� �#��:�����xDTYsD���:�8"���QgGD��@<"��([�GD�5GDѺ��#�lm u�qD�� �#��:�����xD�X�Q��@<"��([�GD�uek鈨�nGD�Y8<"��9"���GD�uek�#�lm u�qD�� �#�ʚ#�h]�xD�Y�Q�6��:�8"���QgGD��@<"��9"���GD�uek�#�lm u�qD�� �#�ʚ#�h]�xD�Y�Q�6���:�vD����#��9�����xDTYsD���:�8"���QgGD��@<"��([�GD�5GDѺ��#�lm u�qD�� �#��:�����xDTYsD���:�8"���QgGD��@<"��([�GD�5GDѺ�鈨�nGD�Y8<"��(K�GD�uek�(Z u�qD�� �#��:�����xD�Y�Q�6���<"J��GD�uek�#�lm u�qD�� �#�ʚ#�h]�xD�Y�Q�6��:�8"���QgGD��@:"���(:GGD�r;"����Q�GDY�@<"�������ˏ�p�wD>Ǐ��{�S��9��y�q��������4��#���òƳ|������g�*�=���v�u�>�\�`y��������3Eo?�[�x��p�zwxy��Yeݞ�bm����p����+��XO߆�3Eʺ={����������o��x��p�zwx~����+��Xw�g��u{����;�����o�*���k߷>�� �:�e�ܱ�� �g��u{����;�ӷ��H�cݞ�bm����m�����+��o}>}�?��G�ٸ��{p<J���iw������n�^�6p��|xz�_���+��o}9n����,[������d�۳W� ܱ>n叹��kw��oÃ��3��bm����ߜ� �ΚgѺw��o�ݣ�n�^�6p�z�6�>I���kw��o��Z�g�X���x�6ܸsy��p�zwx|y����+��XO�峵n�^�6p��|x�_��^q�}���p|r?p�,K����=x����+��XO��í�n�^�6p�z�.��I���k߷ޝ� w�:�e�ܱ�� ��Һ={�����<�8��+��XO߆kݞ�bm�������E��ϲu�X����x����;���͓�n�^�6p��|x���^�6�}����� ��gٺ�w��oý�n�^�6p�z�6�Hl�^qnGy���8��+��o}<}n�u<���c=}����x����;��w��Z�g�X�c}>ܿ�s��+��o}�9�<˿�dzl]�;ֻ����n�^�6p��pz^���^�6p�z�6<�s��+��o}>}�u<���c=}�䏹��kw��oí�17��bm����m8Z���k߷��� 7���x��p�z�6H��W�������+���c�v�χ�g�n<{E����������Q�gѺw�w��Gkݞ�bm����]x�����+��Xǚ��f� �yc��8d]�<�����AkyGY3����<��f� �yc��8d]�<�����AkyGY3����<��f� �y#�<9��8J9�qPY8��Q��㠴�<�����Aky�X�<Y ��(k�q��@��Q��㠵�<�����Aky�X�<Y ��(k�q��@��Q��㠵�<�����Aky�X�<Y ��(k�q��@��Q��㠵�8���c���y��<)��8ʙy�6��q�5�8hm ��(k�q��@��1�9�C���8ʚy�6��q�5�8hm ��(k�q��@��1�9�C���8ʚy�6��q�5�8hm ��(k�q��@����<XW ��(k�q��@��Q��㠵�8���c���y��8$]�<�����AkyGY3����<��f� �yc��8d]�<�����AkyGY3����<��f� �yc��8d]�<�����AkyGY3����<��f� �yc��8d]�<�����AkqGI�<:��8ʙy�6��q�u��u�<��f� �ye�<Z��8ʚy�6��q�u��u�<��f� �ye�<Z��8ʚy�6��q�u��u�<��f� �ye�<Z��8ʚy�6��q�u��u�<���yt��q�3�8(m ��(k�q��@��1�9�C���8ʚy�6��q�5�8hm ��(k�q��@����<XW ��(k�q��@��Q��㠵�<�����Aky�X�<Y ��(k�q��@��Q��㠵�<�����Akq�H3�C���<�R�yT��q�3�8(m ��쯾�y��<��ǀy����Wޠ��G��3�9��߿}��m��O����_�����_����~��˧/���݇�ooN���÷_�~���� -|�-և����o��wOǽ��9A�˜�/�2�� �� pN���� *k� ���|NPYsN� �s�ʚs�hm �4Ҝ$g��R�s��,�TΜDi����� Z���u�$��s�ʚs�hm �T֜Dk����� Z���u�$��s�ʚs�hm �T֜Dk����� Z���u�$��s�ʚs�hm �T֜Dk�s��,�4ʜ$e����r� J���5���@>'��9'���9Ac��ɺ������ Z���5���@>'��9'���9Ac��ɺ������ Z���5���@>'��9'���9Aa=�� -�s�ʚs�hm �T֜Dk�s��,�4�yN���� *k� ���|NPYsN� �s�ʚs�hm �4�yN���� *k� ���|NPYsN� �s�ʚs�hm �4�yN���� *k� ���|NPYsN� �s�ʚs�hm �4�yN���� *k� ���xNPI�9At�� *g� ���|N�X�9A�.@>'��9'���9Ae�9A�6�� *k� ���|N�X�9A�.@>'��9'���9Ae�9A�6�� *k� ���|N�X�9A�.@>'��9'���9Ae�9A�6�� *k� ���|N�X�9A�.@<'��� :���3�Q�@>'��9'���9Ac��ɺ������ Z���5���@>'��9'���9Aa=�� -�s�ʚs�hm �T֜Dk����� Z���u�$��s�ʚs�hm �T֜Dk����� Z���4���8<'��� *���3�Q�@>'H���9A��9�����?��Ꮷ_^����:���y:�~|a^����8?�����g�ȏ4N��O��v�������?�+�p��{����nj<|����<�w���û����iw��?e�́hm �h���@�.@�9PYss Z�7*knDk��@e�́hm �h���@�.@�9PYss Z�7*knDk��@e�́hm �h���@�.@�9PYss Z�7*knDk��@e�́hm �h��9�����37���|s����@�6�oT�����́�:o$���57���|s����@�6�oT�����́�z�9�+�oT�����́ʚ���@�9PYss Z�7�9���oT�����́ʚ���@�9PI�́�,�h���@�.@�9PYss Z�7*knDk��@e�́hm �h���@�.@�9PYss Z�7*knDk��@e�́hm �h���@�.@�9PYss Z�7*knDk��@e�́hm �h���@�.@�9PYss Z�7*�9����37���|s��Λɺ���@e�́hm ����9� ��57���|s��Λɺ���@e�́hm ����9� ��57���|s��Λɺ���@e�́hm ����9� ��57���|s��Λɺ���@��nD�%oT�qs �7*gnDi��@a=���7*knDk��@e�́hm ����9� ��u�H��7*knDk��@e�́hm ���YBky�X�"Y /)k���@^R�,������YBkq�H�D���"�R�E T���3�@(m /)k���@^2ֹD�ȋ@ʚE �6���5�@hm /)k���@^2ֹD�ȋ@ʚE �6���5�@hm /)k���@^2ֹD�ȋ@ʚE �6���5�@hm .)�XBg�p�(�D���"�rf� �E e�"Zȋ@ʚE �6���u.�u�"��f� �E e�"Zȋ@ʚE �6���u.�u�"��f� �E e�"Zȋ@ʚE �6������ȋ@ʚE �6���5�@hm .)�XBg�x�8�"I /)k���@^R�,������YBky�X�"Y /)k���@^R�,������YBky�X�"Y /)k���@^R�,������YBky�X�"Y /)k���@\Rұ����"�rf� �E c��@d]����YBkyHY����"��f� �E c��@d]����YBkyHY����"��f� �E c��@d]����YBkyHY����"��f� �E c��@d]����c���E ��"Jȋ@ʚE �6���u.�u�"��f� �E e�"Zȋ@ʚE �6������ȋ@ʚE �6���5�@hm /)k���@^2ֹD�ȋ@ʚE �6���5�@hm /)k���@\2�,��q���c���E ��"Jȋ@�o#��sl�@�<���@������.m�@��~�<�8tw���>�;Q4��#�"Pn ������Ͽ���ӗ�o�5N����|��3���"����ŧ۟y�A`^� �yeͼZ��"�:�EȺ�y^DY3/��f^� �yeͼZ��"F�yr6��E�3�"(m ϋ(k�E��@�Q�̋���</b�s^����E�5�"hm ϋ(k�E��@�Q�̋���</"��y��@�Q�̋���</���Aky^DY3/���y�.@�Q�̋���</���Akq^DIǼ:��"�9�EH��y^DY3/��f^� �yeͼZ��"�:�EȺ�y^DY3/��f^� �yeͼZ��"�:�EȺ�y^DY3/��f^� �yeͼZ��"�:�EȺ�y^DY3/��⼈��yt��E�3�"(m ϋ�!��yeͼZ��"ʚy�6��E�5�"hm ϋ�!��yeͼZ��"ʚy�6��E�5�"hm ϋ�!��yeͼZ��"ʚy�6��E�5�"hm ϋ�!��y���E�x �y%�"h,ϋ(g�EP�@���XW ϋ(k�E��@�Q�̋���</���Aky^�X�Y ϋ(k�E��@�Q�̋���</���Aky^�X�Y ϋ(k�E��@�Q�̋���</���Akq^�H3/B��ἈR�yT��E�3�"(m ϋ(k�E��@�1�9/B���"ʚy�6��E�5�"hm ϋ(k�E��@�1�9/B���"ʚy�6��E�5�"hm ϋ(k�E��@�1�9/B���"ʚy�6��E�5�"hm (�Ag�p^�(3/B���rf^� �yeͼZ��"ʚy�6��E�u�uf^� �yeͼZ��"ʚy�6��E�u�uf^� �yeͼZ��"ʚy�6��E��</���"ʚy�6��E�5�"hm (�Ag�x^�8�I ϋ(k�E��@�Q�̋���</���Aky^�X�Y ϋ(k�E��@�Q�̋���</���Aky^�X�Y ϋ(k�E��@�Q�̋���</���Aky^�X�Y ϋ(k�E��@�Q�1/����rf^� �yc��"d]�</���Aky^DY3/��f^� �yc��"d]�</���Aky^DY3/��f^� �yc��"d]�</���Aky^DY3/��f^� �yc��"d]�8/��c^���y�̼J��"ʚy�6��E�u�uf^� �yeͼZ��"ʚy�6��E��</���"ʚy�6��E�5�"hm ϋ(k�E��@�1�9/B���"ʚy�6��E�5�"hm ϋ(k�E��@�1�̋��q8/��c^���y�̼J��"��j^?�6/r��?/��9.�E�ߊ�y�������p^d<�͋y��������������������o�����_�����{���o���o��Ǘ��r��^|�����ǀ�����ReMZ��rZ��IK��@NK�5i)Z�i��δ����ReMZ��rZ��IK��@NK�5i)Z�i��δ����ReMZ��rZ��IK��@NK�5i)Z�i��δ����ReMZ��bZ��#-Eg�8-UΤ�(m ���:�R�.@NK�5i)Z�i��&-Ek9-U֤�hm ���:�R�.@NK�5i)Z�i��&-Ek9-U֤�hm ���:�R�.@NK�5i)Z�i��&-Ek9-U֤�hm ���:�R�.@JK�sKK�x ôT GZ���qZ��IKQ�@NK�����urZ��IK��@NK�5i)Z�i��&-Ek9-5֙��urZ��IK��@NK�5i)Z�i��&-Ek9-5֙��urZ��IK��@NK�5i)Z�i��&-Ek1-5Ҥ��l��J9�RT��R�LZ��rZ��IK��@NK�u��d]���*k�R�6��ReMZ��rZ��IK��@NK�u��d]���*k�R�6��ReMZ��rZ��IK��@NK�u��d]���*k�R�6��ReMZ��bZ��#-Eg�0-5ʤ��l��ʙ�� �TY�������*k�R�6��Rc�i)Y ��ʚ�� �TY�������*k�R�6��Rc�i)Y ��ʚ�� �TY�������*k�R�6��Ra=��`]���*k�R�6��ReMZ��bZ��#-Eg�8-5Ι��trZ��IK��@NK�5i)Z�i��&-Ek9-5֙��urZ��IK��@NK�5i)Z�i��&-Ek9-5֙��urZ��IK��@NK�5i)Z�i��&-Ek9-5֙��urZ��IK��@LK�t���,��ʙ�� ��XgZJ��i��&-Ek9-U֤�hm ��ʚ�� ��XgZJ��i��&-Ek9-U֤�hm ��ʚ�� ��XgZJ��i��&-Ek9-U֤�hm ��ʚ�� ��XgZJ��i�������T9�������*k�R�6��Rc�i)Y ��ʚ�� �TY�������*k�R�6��Ra=��`]���*k�R�6��ReMZ��rZ��IK��@NK�u��d]���*k�R�6��ReMZ��rZ��IK��@LK�4i)9�i�R�����T9�������R)�R�[ZzYr��cIKo9-�y<<���Li�xdKK�FZ���?|���l��_����k�_^���{{���qȝ�����y��x����&��;��5wF���|g����h�6��V�������z�3�+��V������ʚ;���@�3ZYsg4Z�wF�3����V������ʚ;���@�3ZIG؏��q�o�3�'��_Y�����+k�~�6��~eM؏�r�o�3�'��_Y�����+k�~�6��~eM؏�r�o�3�'��_Y�����+k�~�6��~eM؏�r�o�3�'��_Y�����+���Y8��3a?J�a��ΰ����~eM؏�rد� ���@��5a?Z�a��ΰ����~eM؏�rد� ���@��5a?Z�a��ΰ����~eM؏�rد� ���@��5a?Z�a��ΰ����~���~4^�0�W����p�+g�~�6��~a=��`]��+k�~�6��~eM؏�rد� ���@��u��d]��+k�~�6��~eM؏�rد� ���@��u��d]��+k�~�6��~eM؏�rد� ���@��4a?9�a�R�����_9�����+k�~�6��~c�a?Y ��ʚ�� �_Y�����+k�~�6��~c�a?Y ��ʚ�� �_Y�����+k�~�6��~c�a?Y ��ʚ�� �_Y�����+���Y8��2a?)�a�r&�Gi9�Wք�hm ��ʚ�� ��Xg�O��a��&�Gk9�Wք�hm ��ʚ�� ��Xg�O��a��&�Gk9�Wք�hm ��ʚ�� �_X�a?XW ��ʚ�� �_Y�����+���Y8��s��$]��+k�~�6��~eM؏�rد� ���@��u��d]��+k�~�6��~eM؏�rد� ���@��u��d]��+k�~�6��~eM؏�rد� ���@��u��d]��+k�~�6�~%a?:�a�r&�Gi9�7���urد� ���@��5a?Z�a��&�Gk9�7���urد� ���@��5a?Z�a��&�Gk9�7���urد� ���@��5a?Z�a��&�Gk9�7���ubد�#�Gg�8�W΄�(m ��ʚ�� ��Xg�O��a��&�Gk9�Wք�hm ��ʚ�� �_X�a?XW ��ʚ�� �_Y�����+k�~�6��~c�a?Y ��ʚ�� �_Y�����+k�~�6�~#M�O��aد�#�Ge�8�W΄�(m ���a� -��sla�eG���������@����;��-�a�?|��qc�����>����C����������q7�O�N�;]~�����������;����@�ލuF�d]��;����@�ޝuD�lm F��:�w�6�weM���ѻ��蝭 ���YG���R��[����a�����Q��1zw������;����@�ޝuD�lm F�ʚ���wg�;[�ѻ��蝭 ���YG���b�����Ѻ�1zw������;����@�ޝuD�lm F�ʚ���wg�;[Hѻ�n�;;�ѻs�蝥 ��]Y��ub��#zgk1zw������;����@�ޕ5�;Z F��:�w�6�wg�;[�ѻ��蝭 ��]Y��ub��#zgk1zw������;����@�ޕ5�;Z D���#zg�%��w'ܢw6�w��;K�ѻ��蝬+�wg�;[�ѻ��蝭 ���YG���b�����Ѻ�1zw������;����@�ޝuD�lm F�ʚ���wg�;[�ѻ��蝭 ���YG���R���#zGg�(zw�-zge�0zw������;����@�ޕ5�;Z F��:�w�6�wg�;[�ѻ��蝭 ��]Y��ub��#zgk1zw������;����@�ޕ5�;Z F��:�w�6�wg�;[Hѻ�n�;;GѻR�������9G���b��#zgk1zw������+k�w�.@�ޝuD�lm F��:�w�6�wg�;[�ѻ�&zG����YG���b��#zgk1zw��������ɺ1zw������;����@�ޝt���Y8�ޕ3�;J F��:�w�6�wg�;[�ѻ��蝭 ��]Y��ub��#zgk1zw������;����@�ޕ5�;Z F��:�w�6�wg�;[�ѻ��蝭 ��]Y��ub��#zgk)zw�-zgg�0zw������+k�w�.@�ޝuD�lm F��:�w�6�wg�;[�ѻ�&zG����YG���b��#zgk1zw������+k�w�.@�ޝuD�lm F��:�w�6�wg�;[�ѻ�&zG����I�蝝����9G���b��#zgk1zW�D�h]��;����@�ޝuD�lm F��:�w�6�wc��;YW F��:�w�6�wg�;[�ѻ��蝭 ��]Y��ub��#zgk1zw������;����@�ޕtD��lE�N�E�,F��9�w�6�w��M�Ο��3?�E��9���������#[��0��?~����?}���������ݿ�����|���Y��t�}~�-�ǥ��a���ݽT��}=Z�}����Gk��W���hm ���z������W���hm ��ʚ�� �^Y�ף�������ɺ���W���hm ��ʚ�� ľ^IG_���q_o���'��^Y�ף����+k�z�6��zeM_��r_o���'��^Y�ף����+k�z�6��zeM_��r_o���'��^Y�ף����+k�z�6��zeM_��r_o���'��^Y�ף����+����Y8��3}=J�}��ξ����zeM_��r_������@��5}=Z�}��ξ����zeM_��r_������@��5}=Z�}��ξ����zeM_��r_������@��5}=Z�}��ξ����z���z4^°�W��ף�p��+g�z�6��za=��`]���+k�z�6��zeM_��r_������@��u��d]���+k�z�6��zeM_��r_������@��u��d]���+k�z�6��zeM_��r_������@��4}=9�}�R�����^9�ף����+k�z�6��zc�}=Y ��ʚ�� �^Y�ף����+k�z�6��zc�}=Y ��ʚ�� �^Y�ף����+k�z�6��zc�}=Y ��ʚ�� �^Y�ף����+����Y8��2}=)�}�r��Gi��W���hm ��ʚ�� ��Xg_O��}����Gk��W���hm ��ʚ�� ��Xg_O��}����Gk��W���hm ��ʚ�� �^X�}=XW ��ʚ�� �^Y�ף����+����Y8��s��$]���+k�z�6��zeM_��r_������@��u��d]���+k�z�6��zeM_��r_������@��u��d]���+k�z�6��zeM_��r_������@��u��d]���+k�z�6�z%}=:�}�r��Gi��7��דur_������@��5}=Z�}����Gk��7��דur_������@��5}=Z�}����Gk��7��דur_������@��5}=Z�}����Gk��7��דub_����GgḯW���(m ��ʚ�� ��Xg_O��}����Gk��W���hm ��ʚ�� �^X�}=XW ��ʚ�� �^Y�ף����+k�z�6��zc�}=Y ��ʚ�� �^Y�ף����+k�z�6�z#M_O��a_����GeḯW���(m ��������sl}�eξ����?���?���/�?_NC�~��_�?�/��Cy&��q4����o?|w��������k����Κ�_�������%�ǜY����ϒ�~Ȓ��@Β�uf�d]��%+k�d�6��deM���b���#KFg�8K6Ι%�tr���ɒ��@Β�5Y2Z�Y��&KFk9K6֙%�ur���ɒ��@Β�5Y2Z�Y��&KFk9K6֙%�ur���ɒ��@Β�5Y2Z�Y��&KFk9K6֙%�ur���ɒ��@̒�td��,g�ʙ,� �,�Xg�L��Y��&KFk9KV�d�hm g�ʚ,� �,�Xg�L��Y��&KFk9KV�d�hm g�ʚ,� �,�Xg�L��Y��&KFk9KV�d�hm g�ʚ,� �,�Xg�L�HY�rnY2/a�%+�Ȓ�X8Β�3Y2J�Y����d��@Β�5Y2Z�Y��&KFk9KV�d�hm g��:�d�.@Β�5Y2Z�Y��&KFk9KV�d�hm g��:�d�.@Β�5Y2Z�Y��&KFk9KV�d�hm f�F�,����,Y)G����q���ɒQ�@Β�5Y2Z�Y���,����deM���r���ɒ��@Β�5Y2Z�Y���,����deM���r���ɒ��@Β�5Y2Z�Y���,����deM���r���ɒ��@̒�td��,f�F�,����,Y9�%����%+k�d�6��deM���r�l�3K&��,YY�%����%+k�d�6��deM���r�l�3K&��,YY�%����%+k�d�6��deM���r�,��,�+��deM���r���ɒ��@̒�td��,g��9�d�.@Β�5Y2Z�Y��&KFk9KV�d�hm g��:�d�.@Β�5Y2Z�Y��&KFk9KV�d�hm g��:�d�.@Β�5Y2Z�Y��&KFk9KV�d�hm g��:�d�.@Β�5Y2Z�Y���,���,Y9�%����%�̒ɺ�9KV�d�hm g�ʚ,� �,YY�%����%�̒ɺ�9KV�d�hm g�ʚ,� �,YY�%����%�̒ɺ�9KV�d�hm g�ʚ,� �,YY�%����%�̒ɺ�1KVґ%��p�%+g�d�6��deM���r�l�3K&��,YY�%����%+k�d�6��deM���r�,��,�+��deM���r���ɒ��@Β�5Y2Z�Y���,����deM���r���ɒ��@Β�5Y2Z�Y��&K&g�0KVʑ%��p�%+g�d�6��d�kE���c˒/��,y�s������Y�x���G������������,y<�g�Yr�������/��0����ӷ���ӗ�o[�ӯ�O��ۯ��������ǝ����P�~P��@P�5 -Z���&@Ak9@1���ur��� P��@P�5 -Z���&@Ak9@1���ur��� P��@P�5 -Z���&@Ak9@1���uR���[���K(J84��L���r�"����+�eM���r��� P��@P�5 -Z��������eM���r��� P��@P�5 -Z��������eM���r��� P��@P�5 -Z���&@!g�0@Q����p�(g�6�eM���r�b�3@!���EY�����(k�6�eM���r�b�3@!���EY�����(k�6�eM���r�b�3@!���EY�����(k�6% -:��Q&@!e�8@Q�((m (ʚ�� ��EY������PȺ�9@Q�(hm (ʚ�� ��EY������PȺ�9@Q�(hm (ʚ�� ��EY������9@� -��EY�����(k�6% -:��q�����eM���r��� P��@P�5 -Z��������eM���r��� P��@P�5 -Z��������eM���r��� P��@P�5 -Z��������eM���b���#@Ag�8@Q�((m (�:�.@P�5 -Z���&@Ak9@Q�(hm (�:�.@P�5 -Z���&@Ak9@Q�(hm (�:�.@P�5 -Z���&@Ak9@Q�(hm (�:�.@P�t(�,(ʙ�� ��EY������PȺ�9@Q�(hm (ʚ�� ��EY������9@� -��EY�����(k�6�eM���r�b�3@!���EY�����(k�6�eM���b�b� P��8P�r(�,(ʙ�� ��� -�������c?@��K�r���ϧ��1@Ϝ������?~��營>����>�����Y�~��J;�ɼ� >伳��C��������mhm �٦���6t��l3�ygI �٦��� � �;۔5w����|g����6�6��l3�ygY �٦��� � �;۔5w����|g����6�6��l3�ygY �٦��� � �;۔5w����|g����6�6��l3�ygY �٦��� � �;۔t�ن���mʙ;�P�@���Xg2K��ɬ�&�Ek9�U�$�hm '�ʚd� �d�Xg2K��ɬ�&�Ek9�U�$�hm '�ʚd� �d�Xg2K��ɬ�&�Ek9�U�$�hm '�ʚd� �d�Xg2K�Hɬrn�,/a��*�Hf�X8Nf�3�,J�ɬ���Y��@Nf�5�,Z�ɬ�&�Ek9�U�$�hm '��:�Y�.@Nf�5�,Z�ɬ�&�Ek9�U�$�hm '��:�Y�.@Nf�5�,Z�ɬ�&�Ek9�U�$�hm &�F�d����dV)G2���q2��IfQ�@Nf�5�,Z�ɬ��d����YeM2��r2��If��@Nf�5�,Z�ɬ��d����YeM2��r2��If��@Nf�5�,Z�ɬ��d����YeM2��r2��If��@Lf�t$��,&�F�d����dV9�̢����*k�Y�6��YeM2��r2k�3�%��dVY�̢����*k�Y�6��YeM2��r2k�3�%��dVY�̢����*k�Y�6��YeM2��r2+��d�+��YeM2��r2��If��@Lf�t$��,'��9�Y�.@Nf�5�,Z�ɬ�&�Ek9�U�$�hm '��:�Y�.@Nf�5�,Z�ɬ�&�Ek9�U�$�hm '��:�Y�.@Nf�5�,Z�ɬ�&�Ek9�U�$�hm '��:�Y�.@Nf�5�,Z�ɬ��d���dV9�̢�����Lfɺ�9�U�$�hm '�ʚd� �dVY�̢�����Lfɺ�9�U�$�hm '�ʚd� �dVY�̢�����Lfɺ�9�U�$�hm '�ʚd� �dVY�̢�����Lfɺ�1�Uґ̢�p��*g�Y�6��YeM2��r2k�3�%��dVY�̢����*k�Y�6��YeM2��r2+��d�+��YeM2��r2��If��@Nf�5�,Z�ɬ��d����YeM2��r2��If��@Nf�5�,Z�ɬ�&�%g�0�Uʑ̢�p��*g�Y�6�����S%��9�d��O�Of�?�_�̞�/�'Nf�3�d�n$����߾�߿}���������o�h���Φ�����n�����'����'���~���@Ŕ5�Zȡ��&Ck93���ur(�� ���@Ŕt�b�,�bʙP� �P�Xg(F�ȡ��&Ck9Sքbhm �bʚP� �P�Xg(F�ȡ��&Ck9Sքbhm �bʚP� �P�Xg(F�ȡ��&Ck9Sքbhm �bʚP� �P�Xg(F�H��rn�/a�)���X8Ŕ3�Jȡ���C1��@Ŕ5�Zȡ��&Ck9Sքbhm �b�:C1�.@Ŕ5�Zȡ��&Ck9Sքbhm �b�:C1�.@Ŕ5�Zȡ��&Ck9Sքbhm �bF�P����PL)G(���q(�� �P�@Ŕ5�Zȡ���P���C1eM(��r(�� ���@Ŕ5�Zȡ���P���C1eM(��r(�� ���@Ŕ5�Zȡ���P���C1eM(��r(�� ���@Ŕt�b�,�bF�P����PL9�����)kB1�6�C1eM(��r(f�3#��PLY�����)kB1�6�C1eM(��r(f�3#��PLY�����)kB1�6�C1eM(��r(&��P�+�C1eM(��r(�� ���@Ŕt�b�,�b�9C1�.@Ŕ5�Zȡ��&Ck9Sքbhm �b�:C1�.@Ŕ5�Zȡ��&Ck9Sքbhm �b�:C1�.@Ŕ5�Zȡ��&Ck9Sքbhm �b�:C1�.@Ŕ5�Z�����P���PL9�������Ⱥ�9Sքbhm �bʚP� �PLY�������Ⱥ�9Sքbhm �bʚP� �PLY�������Ⱥ�9Sքbhm �bʚP� �PLY�������Ⱥ�1S����p�)gB1�6�C1eM(��r(f�3#��PLY�����)kB1�6�C1eM(��r(&��P�+�C1eM(��r(�� ���@Ŕ5�Zȡ���P���C1eM(��r(�� ���@Ŕ5�Z����&#g�0S����p�)gB1�6�C���I�b�9�P��z� ��?��χ���b��bǗ��P��踝x7噄b�Y�?��������i��Ǘ�ӿ[�����9��|��/������㍇.?���y><��K���u{�����=�9n�5Ϣu�X�Ow�Һ={��������/9ʺ={������p����+��ܖy�6�<;�x��p�:�U��G���}�ʚ�H��@��TI�}��,�Gj��>R�.@��TYs)Z���*k�#Ek�>Re�}�hm �Gj��>R�.@��TYs)Z���*k�#Ek�>Re�}�hm �Gj�33'���\Y�������+k2s�6�3seMf��rfn�33'���\Y�������+����Y8�̕3�9Jș���̜��3seMf��rf������@�̕5�9Zș���̜��3seMf��rf������@�̕5�9Zș���̜��3seMf��rf������@�̕5�9Zș���̜��2s��2s4^�03W���p��+g2s�6�3sa=g�`]���+k2s�6�3seMf��rf������@�̍uf�d]���+k2s�6�3seMf��rf������@�̍uf�d]���+k2s�6�3seMf��rf������@�̍4�99���R������\9�������+k2s�6�3sc��9Y g�ʚ�� ��\Y�������+k2s�6�3sc��9Y g�ʚ�� ��\Y�������+k2s�6�3sc��9Y g�ʚ�� ��\Y�������+����Y8�̍2�9)Ǚ�r&3Gi93W�d�hm g�ʚ�� ���XgfN�ș��&3Gk93W�d�hm g�ʚ�� ���XgfN�ș��&3Gk93W�d�hm g�ʚ�� ��\Xϙ9XW g�ʚ�� ��\Y�������+����Y8�̍sf�$]���+k2s�6�3seMf��rf������@�̍uf�d]���+k2s�6�3seMf��rf������@�̍uf�d]���+k2s�6�3seMf��rf������@�̍uf�d]���+k2s�63s%�9:Ǚ�r&3Gi937֙��urf������@�̕5�9Zș��&3Gk937֙��urf������@�̕5�9Zș��&3Gk937֙��urf������@�̕5�9Zș��&3Gk937֙��ubf��#3Gg�83W�d�(m g�ʚ�� ���XgfN�ș��&3Gk93W�d�hm g�ʚ�� ��\Xϙ9XW g�ʚ�� ��\Y�������+k2s�6�3sc��9Y g�ʚ�� ��\Y�������+k2s�63s#MfN��af��#3Ge�83W�d�(m g��ٴ���sl��eӽ����%3?^��o�7�{���3��s�����������{H��_&���ѳ����i�Kv|�;<���p����O��4~<���� �X�g�X�c}><��J���kw�������Ydzl]�;ֻ�ӓ�n�^�6p�:f�5�hm �(kv��@�-��nXW �(kv��@�-P������[���-@ky��X�nY �(kv��@�-P������[��c������㜻$]��[���-@ky�@Y�[���n��f��� ��c��d]��[���-@ky�@Y�[���n��f��� ��c��d]��[���-@ky�@Y�[���n��f��� ��c��d]��[���-@kq�@I�n:ǻʙ��6�w�u��u�n��f��� ��e�nZȻʚ��6�w�u��u�n��f��� ��e�nZȻʚ��6�w�u��u�n��f��� ��e�nZȻʚ��6�w�u��u�n�rn�h���n���4�w�3�(m ��y���+�w�5�hm �(kv��@�-P������[`�s����w�5�hm �(kv��@�-P������[`�s����w�5�hm �(kv��@�-P������[`��- g�p�@)�n*ǻʙ��6�w�5�hm ���- ���e�nZȻʚ��6�w�5�hm ���- ���e�nZȻʚ��6�w�5�hm ���- ���e�nZȻʚ��6w�t���p�[`��- e�x�@9�[���n��f��� ��e�nZȻ�:wȺ�y�@Y�[���n��f��� ��e�nZȻ�:wȺ�y�@Y�[���n��f��� ��e�nZȻ�z�-�� -��e�nZȻʚ��6w�t���p�[`�s����w�5�hm �(kv��@�-P������[`�s����w�5�hm �(kv��@�-P������[`�s����w�5�hm �(kv��@�-P������[`�s����w�5�hm �(��-@g�x�@9�[���n�����.@�-P������[���-@ky�@Y�[���n�����.@�-P������[���-@ky�@Y�[���n�����.@�-P������[���-@ky�@Y�[���n�����.@�-Pұ[����n�rf��� ��e�nZȻ�:wȺ�y�@Y�[���n��f��� ��e�nZȻ�z�-�� -��e�nZȻʚ��6�w�5�hm ���- ���e�nZȻʚ��6�w�5�hm �iv��8�-Pʱ[����n�rf��� �����n~�m��r$`�`�s�~�x�u���p���ӻ�<Ow?~px>>��s����繻����x�������s�����{�endstream +xڜ�O�l�}e7ק�0����ՒZa��h�(y���&^S��������o�{��ڧ�\��@d�z�|/A��v�������7����e�?������o��os�͟�����<�xxz:�?�o����������~��w����^{��p9=<��绗��������ǿ�����������?��o�P�����������t>}���ǻo���/������������O?}�����?����������y��n}M����t�K��������桏/���<�Ow�O�^�g�x����z9=�<K��� k�O��gkݟ�am��u�+��EZ�goXx���� ���:�e�<�noÃ���ް6���� R�����(����oJʹ?{C���֧�=����,[��u{��Һ?{�����.�Y��� k�/�����ް6��y���"� +ϲuX�g�ֺ?{�����������ް6���� ����x����/��� ��Y�.���6\䏹�� k���p/̍goXx`�ކ����ް6��u{�䏹�,[��u{����Ə������"�>z�X�����p���^�^��N/��GM�E� +<�^N�'kݟ�am��u{/Һ?{�����:��� k�[���p���,[��u{��u������m8?I��� k��xg���7� �n��A�����˳l]���i�� ���7� <�>����u����֗�?��bݟ�am�u�e{�_L���l܁r{�W�Go(w��ހ��t��ސ6������f<{����և�-����,[��u{��g�x������m��goXx`}9�_�u�����w���ߛ�,[���r:ۿA�goXx`}<==Y��� k����(ƍgoXx���� ��x������ kݟ�am��u{��ϸ�� k��� ���?z�Y�����=�?o�GYٸ���Y��� i����W��;��am����t�b���7� �n}�;=>˟q�Y�.���t�$ڌgoXx`�ކGkݟ�am��u{�ϸ�� k�[_���"��Y�.���6�˟q���X���,ƍgoXx`�ކ;kݟ�am�U���������˳h]���ӫ�3�<{��������Z�goXx`}>�?��p���Gk�e�<�n������ް6�����Һ?{�����.\.Һ?{�������m����,[��u{�Һ?{�����6�=J��� k�ϧ�Wkݟ�am�u���tyq?��,[�����"�N�� k���˓���ް6���� ����x������ �N�,[��u{.ֺ?{�����6ȿ5��p�@����$�ސ6��q{��:�e�<�n�<;ɳ7� <�>����I��am������b���7� �n}�;�˳�<��x`�?=˳�<{�����6<Z��� k��� �N�� k�[���A���Y�.���6�[��� k��� �N�� k��� �N�� k�[_�N�WiϲuX�OOV�����(Ogy|�goHx`}>==[��� k�[_��@��Y�.���.��<{�����6<X��� k��� �O�� k�ZﶷA~��gѺ���p�����X��A����X�O��ϙ�� k�[�w�;L�Y�.����Q����XOwOֺ?{�����6�`"�ް6��~{�q�G�ٸ��<H��Go(w����YK���X�7���I���zc�x�r��w� +�^?�������?f}nԾ�Q�=7jO�ϟ��=6jy�Q�������_ը}��O5j�r��Ǘ{ب]y!ǍZ 6j�:5�65g�[�����F�� �FMYӨ�ub�欣Qck�QsҽQcg�Qs�Ѩ���ب)k5�.@lԜu4jlm 6j�:5�65g�[�����QC��F�YG���b�欣Qck�Qs�Ѩ���ب)k5�.@lԜu4jlm 6j�:5�65g�[�����QC��F�9�6jl��F� �F����F�9G���b�f��Q#� +�F�YG���b�欣Qck�Qs�Ѩ���ب)k5�.@lԜu4jlm 6j�:5�65g�[�����QC��F�YG���b�欣Qck�Qs�Ѩ���Ԩ)�h���8jԜro�XY8lԜs4j,m 6j�:5�65eM��������F�� �F�YG���b�欣Qck�QS�4jh]�ب9�h���@lԜu4jlm 6j�:5�65eM��������F�� �F�YG���R��{����Q����QCe�Qs�Ѩ���ب9�h���@lԜu4jlm 6jʚF �5g�[�����F�� �F�YG���b���i�к��Qs�Ѩ���ب9�h���@lԜu4jlm 6j�:5��@lԜu4jlm 6j�:5�6�5'�5v5�L��������F�� �F�YG���b�欣Qck�QS�4jh]�ب9�h���@lԜu4jlm 6j�:5�65eM��������F�� �F�YG���b�欣Qck�QS�4jh]�ب9�h���@jԜto��Y8lԜs4j,m 6jʚF �5g�[�����F�� �F�YG���b���i�к��Qs�Ѩ���ب9�h���@lԜu4jlm 6jʚF �5g�[�����F�� �F�YG���b���i�к��QsҽQcg�Qs�Ѩ���ب9�h���@lԔ5�Z 6j�:5�65g�[�����F�� �F�Xg�F������F�� �F�YG���b�欣Qck�QS�4jh]�ب9�h���@lԜu4jlm 6j�:5�6�5%�:G��S�+���s�F�� �F +Ө�����Ǘ�p>j��u,�ڍ�Q{�����Ù���{�v��?��L���|���J�v��]NO��j���W��(��t:��0��B�X�goXx`���&�Ck9�3֙�ur�������@��59Z�9��&�Ck9�3֙�ur�������@��t�x�,�xʙ� ��Xg�G��9��&�Ck9�S��xhm �xʚ� ��Xg�G��9��&�Ck9�S��xhm �xʚ� ��Xg�G��9��&�Ck9�S��xhm �xʚ� ��Xg�G�H9�r�9?�0�S㡱p��)gr<�6�s<a}����9�S��xhm �xʚ� �OY�㡵������Ⱥ�9�S��xhm �xʚ� �OY�㡵������Ⱥ�9�S��xhm �xʚ� �OY�㡵���ir<r6s<�9*�9�r&�Ci9�S��xhm �x�:s<�.@��59Z�9��&�Ck9�S��xhm �x�:s<�.@��59Z�9��&�Ck9�S��xhm �x�:s<�.@��59Z�9��&�Ck1�Sґ㡳p��er<R6�s<�L���r�������@��59Z�9������s<eM���r�������@��59Z�9������s<eM���r�������@��59Z�9����x`]���)kr<�6�s<eM���b���#�Cg�8�3Ι�tr�������@��59Z�9��&�Ck9�3֙�ur�������@��59Z�9��&�Ck9�3֙�ur�������@��59Z�9��&�Ck9�3֙�ur�������@��t�x�,�xʙ� ��Xg�G��9��&�Ck9�S��xhm �xʚ� ��Xg�G��9��&�Ck9�S��xhm �xʚ� ��Xg�G��9��&�Ck9�S��xhm �xʚ� ��Xg�G��9������O9�㡴���)kr<�6�s<c�9Y �xʚ� �OY�㡵���)kr<�6�s<a}����9�S��xhm �xʚ� �OY�㡵������Ⱥ�9�S��xhm �xʚ� �OY�㡵���ir<r6s<�9*�9�r&�Ci9�;��T���c��>�������u|���۟��W�m?u���=��^^����L�c�����_~���ޏ_~�����ߺ����wŕ߲�׃߲���t�z��/1}|���/�rzy��B�X�goXx`}:]���FY�goXx`}9��[��� k�[_�bJ'�eg���{p>K��� i��{pg���7� <����_����� k�[_ϧ�����x����z9=?[��� k�O����eݟ�am��u{���FY�goXx����ކgͳh]���m�<I��� k���p�,���7� <�no��Z�goXx�z�ކ;�c.ϲuX/���Wiݟ�am����t~�����X_NO�7��7�����?����N�e�<�n������ް6������Һ?{�����.<\�u���� ��p���,[��u,V(k&0��@��P�L`���<�����@ky�X�Y O`(k&0��@��P�L`���<�����@ky�X�Y O`(k&0��@��P�1������rf� � c�d]�<�����@kyCY3������f� � c�d]�<�����@kyCY3������f� � c�d]�<�����@kyCY3������f� � c�d]�4����?�pC ��ʙ �6�'0��}�+�'0�5hm O`(k&0��@��P�L`���<�a�s���'0�5hm O`(k&0��@��P�L`���<�a�s���'0�5hm O`(k&0��@��P�L`���8�a��� g�pC)�*�ʙ �6�'0�5hm O`�� �� e�Z�ʚ �6�'0�5hm O`�� �� e�Z�ʚ �6�'0�5hm O`�� �� e�Z�ʚ �6'0�tL`��p8�a��� e�xC93������f� � e�Z��:'0Ⱥ�yCY3������f� � e�Z��:'0Ⱥ�yCY3������f� � e�Z���>���ʚ �6�'0�5hm N`(��@g�x�8�I O`(k&0��@��P�L`���<�����@ky�X�Y O`(k&0��@��P�L`���<�����@ky�X�Y O`(k&0��@��P�L`���<�����@ky�X�Y O`(k&0��@��P�1������rf� � c�d]�<�����@kyCY3������f� � c�d]�<�����@kyCY3������f� � c�d]�<�����@kyCY3������f� � c�d]�8���c��� ��J�ʚ �6�'0�uN`�u���f� � e�Z�ʚ �6�'0��}�+�'0�5hm O`(k&0��@��P�L`���<�a�s���'0�5hm O`(k&0��@��P�L`���8�a��� g�pC)�*�ʙ �6�'0p�����}��ˀ ��������r��ϯ�_Po�����xy�^T���LF0�c�o�a~��I��������ߍ������:q���}x��q��qZ�q���8����8eM��r������@��5qZ�q���8����8eM��b��#�Cg�8�S��q(m �q�:�8�.@��5qZ�q��&�Ck9�S��qhm �q�:�8�.@��5qZ�q��&�Ck9�S��qhm �q�:�8�.@��5qZ�q��&�Ck9�S��qhm �q�:�8�.@��s�����q��8���8N9ǡ��� �{��q��&�Ck9�S��qhm �qʚ8� �8�XgG��q��&�Ck9�S��qhm �qʚ8� �8�XgG��q��&�Ck9�S��qhm �qʚ8� �8�HǑ�q�)��PY8��3qJ�q��&�Ck9�3�Ǒur������@��5qZ�q��&�Ck9�3�Ǒur������@��5qZ�q��&�Ck9�3�Ǒur������@��5qZ�q���8���8�(Ǒ�q�)g�8�6��8eM��r������@��u�qd]��)k�8�6��8eM��r������@��u�qd]��)k�8�6��8eM��r������@���=�� +�8NYǡ���)k�8�6�8%q:�q�q�8����8eM��r������@��5qZ�q���8����8eM��r������@��5qZ�q���8����8eM��r������@��5qZ�q���8����8eM��b��#�Cg�8�S��q(m �q�:�8�.@��5qZ�q��&�Ck9�S��qhm �q�:�8�.@��5qZ�q��&�Ck9�S��qhm �q�:�8�.@��5qZ�q��&�Ck9�S��qhm �q�:�8�.@��t�q�,�qʙ8� �8NYǡ�����Ⱥ�9�S��qhm �qʚ8� �8NYǡ��� �{��q��&�Ck9�S��qhm �qʚ8� �8�XgG��q��&�Ck9�S��qhm �qʚ8� �8�HǑ�q�)��PY8��3qJ�q�q٥�8|{��e@w�:��8n�NǍg�ݏ8�~����:��W���yѻ�s ����@^��>���@���@� �@�Xg G�ȁ��&�Ck9�S�rhm rʚ@� �@�Xg G�ȁ��&�Ck1�S�ȡ�p�)g9�6�9c��Y rʚ@� �@NYȡ���)k9�6�9c��Y rʚ@� �@NYȡ���)k9�6�9c��Y rʚ@� �@NYȡ���)k9�6�9c��Y rʹrh��@N G ���q �� �P�@��=�� +�@NYȡ���)k9�6�9eM ��r g�3�#��@NYȡ���)k9�6�9eM ��r g�3�#��@NYȡ���)k9�6�9eM ��b g� ���8�rr�,rʙ@� �@NYȡ�����Ⱥ�9�S�rhm rʚ@� �@NYȡ�����Ⱥ�9�S�rhm rʚ@� �@NYȡ�����Ⱥ�9�S�rhm rʚ@� �@NIG ���a g� �H�8�3�Jȁ��&�Ck9�S�rhm r�:9�.@�5�Zȁ��&�Ck9�S�rhm r�:9�.@�5�Zȁ��&�Ck9�S�rhm r��ȁur �� ���@�5�Z�����@���@�8g G�ȁ��&�Ck9�S�rhm rʚ@� �@�Xg G�ȁ��&�Ck9�S�rhm rʚ@� �@�Xg G�ȁ��&�Ck9�S�rhm rʚ@� �@�Xg G�ȁ��&�Ck1�S�ȡ�p�)g9�6�9c��Y rʚ@� �@NYȡ���)k9�6�9c��Y rʚ@� �@NYȡ���)k9�6�9c��Y rʚ@� �@NYȡ���)k9�6�9c��Y rJ:9t�9�L ��r �� ���@�urd]��)k9�6�9eM ��r �� ���@��=�� +�@NYȡ���)k9�6�9eM ��r g�3�#��@NYȡ���)k9�6�9eM ��b g� ���8�rr�,rʙ@� �@��R���=���2.�����X�����n�I�ȁ�x&��er��/Dž�w�o�}����|~G^/�^�Y��˞�؇�}\�}~!P����\�)k�1�6��1eM5��r5f��#��jLYS����X�)���Y8�Ɣ3�J���j����1eM5��r5������@�Ɣ5�Z���j����1eM5��r5������@�Ɣ5�Z���j����1eM5��r5������@�Ɣ5�Z���j����1�ܫ14~�a5���Cc�S�Tc(m Wc��^��ur5������@�Ɣ5�Z���Ck�3�Y��ur5������@�Ɣ5�Z���Ck�3�Y��ur5������@�Ɣ5�Z���Ck�3�Tc�lVcJ9�1T��1�L5��r5������@�ƌuVcd]�\�)k�1�6��1eM5��r5������@�ƌuVcd]�\�)k�1�6��1eM5��r5������@�ƌuVcd]�\�)k�1�6��1eM5��b5���Cg�3�Tc�lWcʙj� �jLYS����\�)k�1�6��1c��Y Wcʚj� �jLYS����\�)k�1�6��1c��Y Wcʚj� �jLYS����\�)k�1�6��1a}�����S�Tchm Wcʚj� �jLIG5���q5f��#��jLYS����\�)k�1�6��1eM5��r5f��#��jLYS����\�)k�1�6��1eM5��r5f��#��jLYS����\�)k�1�6��1eM5��r5f��#��jLYS����X�)���Y8�Ɣ3�J���j����1eM5��r5������@�Ɣ5�Z���j����1eM5��r5������@�Ɣ5�Z���j����1eM5��r5������@�Ɣ5�Z���j���1%�:�r�Ci�S�Tchm Wc�:�1�.@�Ɣ5�Z���Ck�S�Tchm Wc��^��ur5������@�Ɣ5�Z���Ck�3�Y��ur5������@�Ɣ5�Z���Ck�3�Tc�lVcJ9�1T��1�L5��r5v\;�j_�^�}xP����>py�S�Z������[��/�����/h<�G�fl�����o_�;?~����������_�;��ۿ�˗O����u����7t�c��M{����|>]�%���C_����|9���|~!W���7� <�>�.o����7� <���^�u����/��p����l܁r{�g�ܟ�!m��u{�u����֗����ݟ�am�u���t���cϲuX/��gkݟ�am����t�� ���7� <�no���(��� k�7w����y�+���� �'iݟ�am��u{u������m8[��� k�[���p�~��Y�.������*���7� <�>��/ֺ?{��������}�pו�������ɳ,]���=x�����X����^Z�goXx`�ޅ�����ް6��+~���"��Y�.���6�?H��� k��;��5_����(+k�D� �/Q6�9�A��sʚ9�6��0�5shm �a(k�0��@��0�9�A��sʚ9�6�0�t�a��p<�����@iy�X�Y �a(k�0��@��P��a���<�����@ky�X�Y �a(k�0��@��P��a���<�����@ky�X�Y �a(k�0��@��P��a���<�����@ky�X�Y �a(�>��Ə0��P�1������rf� �9a}���� +�9e�Z�sʚ9�6��0�5shm �a�� ��9e�Z�sʚ9�6��0�5shm �a�� ��9e�Z�sʚ9�6��0�5shm �ai�0��8��P�1������rf� �9e�Z�s�:�0Ⱥ�yCY3������f� �9e�Z�s�:�0Ⱥ�yCY3������f� �9e�Z�s�:�0Ⱥ�yCY3������f� �9%s�,�ae�0H�8��P��a���<�����@kyCY3�������9�.@��P��a���<�����@kyCY3�������9�.@��P��a���<�����@kyCY3��������a�u���f� �9e�Z�sJ:�0�Y8��0�9�A��sʚ9�6��0�5shm �a(k�0��@��0�9�A��sʚ9�6��0�5shm �a(k�0��@��0�9�A��sʚ9�6��0�5shm �a(k�0��@��0�9�A��sʚ9�6�0�t�a��p<�����@iy�X�Y �a(k�0��@��P��a���<�����@ky�X�Y �a(k�0��@��P��a���<�����@ky�X�Y �a(k�0��@��P��a���<�����@ky�X�Y �a(��@g�xC93������f� �9c�sd]�<�����@kyCY3������f� �9a}���� +�9e�Z�sʚ9�6��0�5shm �a�� ��9e�Z�sʚ9�6��0�5shm �ai�0��8��P�1������rf� �9��=5���c����2`��u��_�|�pz���(�g� ������o�������ǟ����߿T����xx���{{��\������A���\�����w+�f~5����9n6>�h6��@n6�u6d]��l(k� �6�� eM���r���i6��@n6�u6d]��l(k� �6�� eM���r���i6��@n6�u6d]��l(��l��#� %��͆r��@i����f�+�� eM���r���i6��@n6�5�Z�͆��f���� eM���r���i6��@n6�5�Z�͆��f���� eM���r���i6��@n6�5�Z�͆��� g��P��l��p�l(g� �6�� eM���r�a��� ��fCY�l����l(k� �6�� eM���r�a��� ��fCY�l����l(k� �6�� eM���r�a��� ��fCY�l����l(k� �6� %�:�͆Q�� e��P�4(m 7ʚf� �fCY�l����l�l6Ⱥ���P�4hm 7ʚf� �fCY�l����l�l6Ⱥ���P�4hm 7ʚf� �fCY�l����l�{���͆���@k��P�4hm 6J:� t�� ��I 7ʚf� �fCY�l����l(k� �6�� c��Y 7ʚf� �fCY�l����l(k� �6�� c��Y 7ʚf� �fCY�l����l(k� �6�� c��Y 7ʚf� �fCIG����q���i6P�@n6�u6d]��l(k� �6�� eM���r���i6��@n6�u6d]��l(k� �6�� eM���r���i6��@n6�u6d]��l(k� �6�� eM���r���i6��@n6�u6d]��l(�h6�Y8n6�3�J�͆���@k��0��l�ur���i6��@n6�5�Z�͆���@k����f�+�� eM���r���i6��@n6�5�Z�͆��f���� eM���r���i6��@n6�5�Z�͆��� g��P��l��p�l(g� �6����@5�:�f��ˀf��u,�ƙ�������Ygl6��l6�G���_~�ril�/i\�@��|���|<�E�N%z�y���?�N�+/��;���@�N%gߩ���w*)k�S ��S�Y�w*�����J�:�S�� ��Tr��Jlm ~����;�к��;��u|�[Hߩ��w*��p��J�9�S�� ��TR�|�Z ~�����Tbk�;��u�ylm �y�:�<�6�<eM����}���>�� �>�YG���b�笣�ck��S��yh]���9�����@��u�ylm �y�:�<�6�<eM���}�s~����F}��}�}�s�>�� �>�Xg�G��}���>�� �>�YG���b�笣�ck��S��yh]���9�����@��u�ylm �y�:�<�6�<eM����}���>�� �>�YG���b�笣�ck��S��硳q��9��籲p��9���X�@��u�ylm �yʚ>��<g}[�}���>�� �>�YG���b�����к���s��籵���9�����@��u�ylm �yʚ>��<g}[�}���>�� �>�I�>����>O)G����a�眣�ci��s��籵���9�����@��5}Z �y�:�<�6�<g}[�}���>�� �>OY��ub�笣�ck��s��籵���9�����@��u�yd]���9�����@��u�ylm �yN��y�,�yʙ>��<g}[�}���>�� �>�YG���b�����к���s��籵���9�����@��u�ylm �yʚ>��<g}[�}���>�� �>�YG���b�����к���s��籵���9��米p��9���X�@��5}Z �y�:�<�6�<g}[�}���>�� �>OY��ub�笣�ck��s��籵���9�����@��5}Z �y�:�<�6�<g}[�}���>�� �>OY��uR��{����a�眣�ci��s��籵���)k�<�.@��u�ylm �y�:�<�6�<g}[�}���>��+�<g}[�}���>�� �>�YG���b�����к���s��籵���9�����@��u�ylm �yJ:�<t6��<���<V�<�}K�}�d��<~_���2��<x_�|���'��J�O����@�/�?=�^}A�<2���S:߿~���<oy�燇�������ܟ��.�Y燧�����>�����rz��K��V�� k�[ϧ��k&cϲuX/�?V����X���l���7� <�no��5����ް6���|�������gٺ����ˋ���ް6���t��]3)��� k������ʺ?{�������mx���,[��u{��M�u������mx�caeݟ�am��u��u憵�/�� �6�?���(���,��goHx`�ރ;kݟ�am������j�goXxݺ����g<��x`�����u����֧����17��am��u{���� k��Zw����y�+���� �'iݟ�am��u{u������m8[��� k�[�`�t��,[���rzz}�����X�N�kݟ�am�����d��>z�Y��������~��Y�.���<Y��� k��{�x/���7� <�n���EZ�goXx0�� iϲuXǎ��f�� �ae�0Z��<ʚa�6��y�u�u�0��f�� �ae�0Z��<ʚa�6��y�u�u�0��f�� �a%�<�,�(g�yP�@�1�9�C���<ʚa�6��y�5�<hm �(k�y��@�1�9�C���<ʚa�6��y�5�<hm �(k�y��@�1�9�C���<ʚa�6��y�5�<hm �(k�y��@�1�9�C�H�<ʹ��#�y�p�p<̣��Aiy�GX߇y��y�GY3̃��0��f�� �ae�0Z��<�:�yȺ�y�GY3̃��0��f�� �ae�0Z��<�:�yȺ�y�GY3̃��0��f�� �ae�0Z��<F�ar6�y�r�p<̣��Aiy�GY3̃��0���a�.@�Q�<̣��Aky�GY3̃��0���a�.@�Q�<̣��Aky�GY3̃��0���a�.@�Q�<̣��Akq�GI�0:��<F�aR6��y�3�<(m �(k�y��@�Q�<�c�s�����y�5�<hm �(k�y��@�Q�<�c�s�����y�5�<hm �(k�y��@�Q�<�#���<`]�<̣��Aky�GY3̃��0���at��y�s�t�0��f�� �ae�0Z��<ʚa�6��y�u�u�0��f�� �ae�0Z��<ʚa�6��y�u�u�0��f�� �ae�0Z��<ʚa�6��y�u�u�0��f�� �a%�<�,�(g�yP�@�1�9�C���<ʚa�6��y�5�<hm �(k�y��@�1�9�C���<ʚa�6��y�5�<hm �(k�y��@�1�9�C���<ʚa�6��y�5�<hm �(k�y��@�1�9�C���<J:�y�Y8�Q�<̣��Aky��X�0Y �(k�y��@�Q�<̣��Aky�GX߇y��y�GY3̃��0��f�� �ae�0Z��<�:�yȺ�y�GY3̃��0��f�� �ae�0Z��<F�ar6�y�r�p<̣��Aiy��xkF ���؇y>�����a��ױ�y�g�g����D4�3�<�c����ˏ����%���',��ϓ<��Wy4�s9}m��U�g>��+�<c���ˀ �6�g��53@hm ���"�� e�Z�3@ʚ �6�g��53@hm ���"�� e�Z�3@ʚ �6�g��53@hm ���"�� e�Z�3@ʚ �6�g��53@hm ��if���8�R������<���BkyHY3������ �.@�R������<���BkyHY3���������u���f� � e�Z�3@ʚ �6�g��u���u���f� � e�Z�3@J:f��Y8�2�9D��3@ʚ �6�g��53@hm ��)kf���@�2�9D��3@ʚ �6�g��53@hm ��)kf���@�2�9D��3@ʚ �6�g��53@hm ��)kf���@�2�9D��3@ʚ �6g��t����p<���Biy�X�Y ��)kf���@�R������<���Bky�X�Y ��)kf���@�R������<���Bky�X�Y ��)kf���@�R������<���Bky�X�Y ��)�>�Ə0�R�1�����rf� � a}�� +� e�Z�3@ʚ �6�g��53@hm ���"�� e�Z�3@ʚ �6�g��53@hm ���"�� e�Z�3@ʚ �6�g��53@hm ��if���8�R�1�����rf� � e�Z�3@�:g�Ⱥ�yHY3�����f� � e�Z�3@�:g�Ⱥ�yHY3�����f� � e�Z�3@�:g�Ⱥ�yHY3�����f� � %3@�,��ef�H�8�R������<���BkyHY3������ �.@�R������<���BkyHY3������ �.@�R������<���BkyHY3���������u���f� � e�Z�3@J:f��Y8�2�9D��3@ʚ �6�g��53@hm ��)kf���@�2�9D��3@ʚ �6�g��53@hm ��)kf���@�2�9D��3@ʚ �6�g��53@hm ��)kf���@�2�9D��3@ʚ �6g��t����p<���Biy�X�Y ��)kf���@�R������<���Bky�X�Y ��)kf���@�R������<���Bky�X�Y ��)kf���@�R������<���Bky�X�Y ��)�Bg�xH93�����f� � c�3@d]�<���BkyHY3�����f� � a}�� +� e�Z�3@ʚ �6�g��53@hm ���"�� e�Z�3@ʚ �6�g��53@hm ��if���8�R�1�����rf� ���}5��c���2`��u�u3@�?Q�n��f��#c�2f����_����������������������sr�� +���z7��|��N�W���g���W��_T�d]�\!*k*D�6�+DeM���r������@��uV�d]�\!*k*D�6�+DeM���r������@��uV�d]�\!*k*D�6+D%":��r�BDi�B4�Y!�ur������@��5"Z����BDk�B4�Y!�ur������@��5"Z����BDk�B4�Y!�ur������@��5"Z����BDk�B4�Y!�uR���{��Ə0��pT�h,W�ʙ +� � +QX�+D��@��5"Z����BDk�BT�T�hm W��:+D�.@��5"Z����BDk�BT�T�hm W��:+D�.@��5"Z����BDk�BT�T�hm V�F� +���� +Q)G����q����Q�@��5"Z���� +���+DeM���r������@��5"Z���� +���+DeM���r������@��5"Z���� +���+DeM���r������@��tT��,V�F� +���� +Q9S!���\!*k*D�6�+DeM���r�h��B$�� +QYS!���\!*k*D�6�+DeM���r�h��B$�� +QYS!���\!*k*D�6�+DeM���r�(��"XW W�ʚ +� � +QYS!���X!*��Y8��sV�$]�\!*k*D�6�+DeM���r������@��uV�d]�\!*k*D�6�+DeM���r������@��uV�d]�\!*k*D�6�+DeM���r������@��uV�d]�\!*k*D�6+D%":��r�BDi�B4�Y!�ur������@��5"Z����BDk�B4�Y!�ur������@��5"Z����BDk�B4�Y!�ur������@��5"Z����BDk�B4�Y!�ub����BDg�BT�T�(m W�ʚ +� � +�Xg�H�����BDk�BT�T�hm W�ʚ +� � +QX�+D��@��5"Z����BDk�BT�T�hm W��:+D�.@��5"Z����BDk�BT�T�hm V�F� +���� +Q)G����q����Q�@���"���B��2�B<~x8���~�_�(���3������+�l/�����������ϣD��_�|���?����O�^���������߹��au8�F^���/��k4?����Dg��k4�s~�&I ����k4��@�Me��h����5�ʚ�� ��Xg�J����&`Ek9`U��hm �ʚ�� ��Xg�J����&`Ek9`U��hm �ʚ�� ��Xg�J����&`Ek1`U����p�*gV�6�Vc�+Y �ʚ�� �UY�����*kV�6�Vc�+Y �ʚ�� �UY�����*kV�6�Vc�+Y �ʚ�� �UY�����*kV�6�Vc�+Y �ʹ�h�ÀU G����q��� XQ�@X��=`� +�UY�����*kV�6�VeM���r�j�3`%��UY�����*kV�6�VeM���r�j�3`%��UY�����*kV�6�VeM���b�j� X��8X�r��,�ʙ�� �UY������Xɺ�9`U��hm �ʚ�� �UY������Xɺ�9`U��hm �ʚ�� �UY������Xɺ�9`U��hm �ʚ�� ĀUIG����a�j� XI�8X�3+J���&`Ek9`U��hm ��:V�.@X�5+Z���&`Ek9`U��hm ��:V�.@X�5+Z���&`Ek9`U��hm �����ur��� X��@X�5+Z���������8g�J����&`Ek9`U��hm �ʚ�� ��Xg�J����&`Ek9`U��hm �ʚ�� ��Xg�J����&`Ek9`U��hm �ʚ�� ��Xg�J����&`Ek1`U����p�*gV�6�Vc�+Y �ʚ�� �UY�����*kV�6�Vc�+Y �ʚ�� �UY�����*kV�6�Vc�+Y �ʚ�� �UY�����*kV�6�Vc�+Y �J:Vt�V�L���r��� X��@X�u�d]��*kV�6�VeM���r��� X��@X��=`� +�UY�����*kV�6�VeM���r�j�3`%��UY�����*kV�6�VeM���b�j� X��8X�r��,�ʙ�� 䀕2L�����/���0`=~K�z��n����X�33`�����ۏ�y���ۗ_�k��ˈZ�;{�k������H�ݿ����a�焃�uv0��g���w0�_t0d]���(k:�6�;eM��r���`��@�`�uv0d]���(k:�6�;eM��r���`��@�`�uv0d]���(k:�6�;eM��r���`��@�`�uv0d]���(�����#;%��r��Ai�����+�;eM��r���`��@�`�5Z�������;eM��r���`��@�`�5Z�������;eM��r���`��@�`�5Z�����!g㰃Q�����p��(g:�6�;eM��rc���!��FY�������(k:�6�;eM��rc���!��FY�������(k:�6�;eM��rc���!��FY�������(k:�6;%:��Q��!e㸃Q�t0(m w0ʚ� �FY���������`Ⱥ���Q�t0hm w0ʚ� �FY���������`Ⱥ���Q�t0hm w0ʚ� �FY��������{������Ak��Q�t0hm v0J::t�;�I w0ʚ� �FY�������(k:�6�;c�Y w0ʚ� �FY�������(k:�6�;c�Y w0ʚ� �FY�������(k:�6�;c�Y w0ʚ� �FIG���q���`P�@�`�uv0d]���(k:�6�;eM��r���`��@�`�uv0d]���(k:�6�;eM��r���`��@�`�uv0d]���(k:�6�;eM��r���`��@�`�uv0d]���(��`�Y8�`�3J�����Ak��1����ur���`��@�`�5Z�����Ak�����+�;eM��r���`��@�`�5Z�������;eM��r���`��@�`�5Z�����!g㰃Q�����p��(g:�6�;��lCu0�:����xx:�`�_�_�En����=w0���\�w0_��m|��/?��5��i c����?���������_n��s�vsp�7���~=��ï�������V�6��Z�5G�hm ��<j%��Ve�Q+Z�G�ʚ�V�6��Z�5G�hm ��<j%��Ve�Q+Z�G�ʚ�V�6��Z�5G�hm �i�Z��8<jU�qԊ���Q�r�� �Ve�Q+Z�G��:�Zɺ���UYsԊ��Q���� �Ve�Q+Z�G��:�Zɺ���UYsԊ��Q���� �Ve�Q+Z�G��:�Zɺ���UYsԊ��Q���� ģV%G��,�e�ZI�8>jU�����|Ԫ�9jEk��UYsԊ��Q��ΣV�.@>jU�����|Ԫ�9jEk��UYsԊ��Q��ΣV�.@>jU�����|Ԫ�9jEk��UYsԊ��Q�����u�Q���� �Ve�Q+Z�G�J:�Z�Y8>j5�y�J��G�ʚ�V�6��Z�5G�hm �*k�Z��@>j5�y�J��G�ʚ�V�6��Z�5G�hm �*k�Z��@>j5�y�J��G�ʚ�V�6��Z�5G�hm �*k�Z��@>j5�y�J��G�ʚ�V�6�Z�t���p|Ԫ�9jEi���X�Q+Y �*k�Z��@>jU�����|Ԫ�9jEk���X�Q+Y �*k�Z��@>jU�����|Ԫ�9jEk���X�Q+Y �*k�Z��@>jU�����|Ԫ�9jEk���X�Q+Y �*�8jEg���U9sԊ��Q���� �Vc�G�d]�|Ԫ�9jEk��UYsԊ��Q���� �Va}?j� +�Ve�Q+Z�G�ʚ�V�6��Z�5G�hm ��<j%��Ve�Q+Z�G�ʚ�V�6��Z�5G�hm �i�Z��8<jU�qԊ���Q�r�� ���KuԊ�c?j��2���u����w����g>j�̣ևSNW���~�y������㟾��������8e��]=w�z�z�����j��}��\�GW��~A���/�����;D�6���u�!�u����� �;De�"Z�w�ʚ;D�6��4w��l�!*�CDe��Q9s�������� �;Dc�w�d]�|����CDk�QYs�������� �;Dc�w�d]�|����CDk�QYs�������� �;Dc�w�d]�|����CDk�QYs�������;Dt��2w��l�!*g�Q�@�CT��!���|����CDk��X�"Y �!*k���@�CT��!���|����CDk��X�"Y �!*k���@�CT��!���|����CDk�QX�����QYs�������� �;D%w��,�!�C$��;De�"Z�w�ʚ;D�6���5w�hm �!�C$��;De�"Z�w�ʚ;D�6���5w�hm �!�C$��;De�"Z�w�ʚ;D�6���5w�hm �!�C$��;De�"Z�w�J:��Y8�CT��!���|�h�������5w�hm �!*k���@�CT��!���|�h�������5w�hm �!*k���@�CT��!���|�h�������5w�hm �!*k���@�CT��!���|�h������t�!��p|����CDi�QYs�������;D�.@�CT��!���|����CDk�QYs��������!�u����� �;De�"Z�w�ʚ;D�6���u�!�u����� �;De�"Z�w�ʚ;D�6��4w��l�!*�CDe��Q9s����"]ɉ;D|�⇗w�ǯ��ׇ����|���~?��l?k_��!���̇;��D��/?������Ͽ}�u%��O_~{�E|x�����������?��/�˯?��?>�'^9�;?}��}��~������܈�/-}��ވ\y!�7"lm ވ8�ak�F�YǍ[�7"ʚ�.@�q�q#��⍈���6�nD�t�ag��FD)Ǎ*�7"�9nDX�@�q�q#��⍈���6oD�57"h]�x#��F�� �g7"lm ވ8�ak�FDYs#���7"�:nD��@�q�q#��⍈���6oD�uވ�u⍈���6oD�u܈���t#���;�7"ʙ�.@�q�q#��⍈���6oD�u܈���x#���A��g7"lm ވ8�ak�F�YǍ[�7"ʚ�.@�q�q#��⍈���6oD�u܈���x#���A��g7"lm ݈8�~#���ፈs��6oD�57"h]�x#��F�� �g7"lm ވ8�ak�FDYs#���7"�:nD��@�q�q#��⍈���6oD�57"h]�x#��F�� �g7"lm ވ8�ak�FDYs#��H7"N�߈��px#��F�� �g7"lm ވ(knDк��F�YǍ[�7"�:nD��@�q�q#��⍈����@�q�q#��⍈���6oD�u܈���x#���A��g7"lm ވ8�ak�F�YǍ[H7"J:nD��8�q��F�����7",m ވ����~_���2��nD�u,7"�7"�,��x�Í������^;��z�S������_��������A;���~���~����p�A�Q�vR6�?hW�|Ў���ʚ���@��]Y�A;Z��������?hW�|Ў���ʚ���@��]Y�A;Z��������?hW�|Ў���ʚ���@��]Y�A;Z�����`]��A���v�6�?hW�|Ў���J:>hGg���v���t��ʚ���@��]Y�A;Z��+k>hGk��vc���u��ʚ���@��]Y�A;Z��+k>hGk��vc���u��ʚ���@��]Y�A;Z��+k>hGk��vc���u��ʚ���@��]I���,Ю���� �ڍu~�N���+k>hGk��ve��hm Ю���� �ڍu~�N���+k>hGk��ve��hm Ю���� �ڍu~�N���+k>hGk��ve��hm Ю���� �ڍu~�N���+������ڕ3�����A���v�6�?h7��A;Y Ю���� �ڕ5�����A���v�6�?h�������ve��hm Ю���� �ڕ5�����A����ɺ���ve��hm Ю���� �ڕ5�����A���vr6?hW��A;*��+g>hGi��v��W|Ў�c����ˀڏ_�_�A����O��A�x���SD����/������P_����������;���0\^N�o����E����tw�p��z���~Qy��/��+X����`ak�+X�u|[�_���+X��@� +e��d]�<�����@ky^CY3���f^� �y c��d]�<�����@ky^CYs����Տ���t�~�2W?�l_�(g�~P�@��Q�\����|�����Ak���X��Y _�(k�~��@��Q�\����|�����Ak���X��Y _�(k�~��@��Q�\����|�����Ak��GX߯~����GYs����Տ���� ī%W?�,_���!��e��Z�W?ʚ��6��~�5W?hm _���!��e��Z�W?ʚ��6��~�5W?hm _���!��e��Z�W?ʚ��6��~�5W?hm _���!��e��Z�W?J:�~�Y8��Q�\����|�c��ꇬ��~�5W?hm _�(k�~��@��Q�\����|�c��ꇬ��~�5W?hm _�(k�~��@��Q�\����|�c��ꇬ��~�5W?hm _�(k�~��@��Q�\����|�c��ꇬ�~�t\���p|�����Ai��GYs����Տ�Ϋ�.@��Q�\����|�����Ak��GYs����Տ��_��u�Տ���� �e��Z�W?ʚ��6��~�u^��u�Տ���� �e��Z�W?ʚ��6�~�4W?�l^�(��Ae���G9s�������=����ױ_�|xp�s�:������OL�+X��:O_�}��9�����q��0�}�������?������/���?�|w��������ӗ��������_���F}����/`}����|�/����G�/ }�|zg�/�����B�X�goXx`}:��~()��� k�/��;kݟ�am�u���t����Y�.������CIY�goXx`}:�=[��� k�/�ǷJʺ?{�������mx|u��,[��u{�u������m�����,܁r{.g�ܟ�!m�u����K�x������o�Gʺ?{�����.�Y��� k�/��R�H��� k�[���� � +ϲuX/��gkݟ�am���q{^���ް6���� ����x����/��� ��Y�.���6\䏹�� k���p/̍goXx`�ކ����ް6��u{�䏹�,[��u{����Ə������"�>z�X�����"��goHx�P������~��Y�����ty�����X�w��"���7� <�no�Ã���ް6���� iϲuX����QZ�goXx`�ކ���ް6���� wֺ?{�����������gٺ������AZ�goXx`}<=?[��� k�/���Wiݟ�am�u�e{�_L���l܁r{�W�Go(w��ހ��t��ސ6������f<{����hmT|�:�@�.@��5Y Z�Y��&Dk9T�d�hm g��:�@�.@��5Y Z�Y��&Dk9T�d�hm g��:�@�.@��5Y Z�Y��&Dk1Tґ��p�e�@R6��@�L��r�����@��5Y Z�Y���,����@eM��r�����@��5Y Z�Y���,����@eM��r�����@��5Y Z�Y���g�`]��*k�@�6��@eM��b��#Dg�84Ι�tr�����@��5Y Z�Y��&Dk94֙�ur�����@��5Y Z�Y��&Dk94֙�ur�����@��5Y Z�Y��&Dk94֙�ur�����@��td��,g�ʙ,� �,�XgH��Y��&Dk9T�d�hm g�ʚ,� �,�XgH��Y��&Dk9T�d�hm g�ʚ,� �,�XgH��Y��&Dk9T�d�hm g�ʚ,� �,�XgH��Y���,���,P9�����*k�@�6��@c�Y Y g�ʚ,� �,PY�����*k�@�6��@a}���9T�d�hm g�ʚ,� �,PY�������ɺ�9T�d�hm g�ʚ,� �,PY�����i�@r6�@�Y *�Y�r&Di9<��T��c�?�����,��u����rz��?�nA��������p}|<�gfxi�|w>�����os�������|���>����$���9|}=L�ߠ��?O�5硏��J7z��/D�.@�5"Z���&@Dk9@T��hm ��:D�.@�5"Z���&@Dk9@T��hm ��:D�.@�5"Z���������Q9 ��� �ɺ�9@T��hm �ʚ�� ��QY ��� �ɺ�9@T��hm �ʚ�� ��QY ��� �ɺ�9@T��hm �ʚ�� ��QY ��� �ɺ�)@T�=@D�G�J8D4�D�L���r�(��"XW �ʚ�� ��QY ��� *kD�6�Dc�"Y �ʚ�� ��QY ��� *kD�6�Dc�"Y �ʚ�� ��QY ��� *kD�6D#M�H��a���#@De�8@T��(m �ʚ�� ���Xg�H����&@Dk9@T��hm �ʚ�� ���Xg�H����&@Dk9@T��hm �ʚ�� ���Xg�H����&@Dk9@T��hm �J:DtD�L�H��q��� Q�@�5"Z���&@Dk9@4� �ur��� ��@�5"Z���&@Dk9@4� �ur��� ��@�5"Z���&@Dk9@����+�DeM���r��� ��@�t��,��9D�.@�5"Z���&@Dk9@T��hm ��:D�.@�5"Z���&@Dk9@T��hm ��:D�.@�5"Z���&@Dk9@T��hm ��:D�.@�5"Z���������Q9 ��� �ɺ�9@T��hm �ʚ�� ��QY ��� �ɺ�9@T��hm �ʚ�� ��QY ��� �ɺ�9@T��hm �ʚ�� ��QY ��� �ɺ�1@T� ��p *gD�6�DeM���r�h�3@$���QY ��� *kD�6�DeM���r�(��"XW �ʚ�� ��QY ��� *kD�6�Dc�"Y �ʚ�� ��QY ��� *kD�6D#M�H��a���#@De�8@T��(m ��� +�u�⇗���X������p���q<3����M���Մ����[��������J�Ƿ�|���s��|������?k�/�����:�kt�k�L��r�c���!���GYS����\�(kj�6�keM��r�c���!���GYS����\�(kj�6�keM��r�c���!���GYS����\�(kj�6�keM��r�c���!���G9���aX�(�}�X8�}�3�Jȵ����>`]�\�(kj�6�keM��r����}��@�}�u�>d]�\�(kj�6�keM��r����}��@�}�u�>d]�\�(kj�6�keM��r����}��@�}�4�9���R������G9S����\�(kj�6�kc��Y �>ʚ�� ��GYS����\�(kj�6�kc��Y �>ʚ�� ��GYS����\�(kj�6�kc��Y �>ʚ�� ��GYS����X�(�}�Y8�}�2�)ǵ�r��Ai��Q��>hm �>ʚ�� ���Xg�C�ȵ����Ak��Q��>hm �>ʚ�� ���Xg�C�ȵ����Ak��Q��>hm �>ʚ�� ��GX�k��@�}�5�Zȵ����Ak��Q�Q���p\��}H����Q��>hm �>ʚ�� ��GYS����\��}Ⱥ���Q��>hm �>ʚ�� ��GYS����\��}Ⱥ���Q��>hm �>ʚ�� ��GYS����\��}Ⱥ���Q��>hm �>J:jt�k�L��r�c���!���GYS����\�(kj�6�keM��r�c���!���GYS����\�(kj�6�keM��r�c���!���GYS����\�(kj�6�keM��r�c���!���GIG���q����}P�@�}�5�Zȵ���ڇ��keM��r����}��@�}�5�Zȵ����>`]�\�(kj�6�keM��r����}��@�}�u�>d]�\�(kj�6�keM��r����}��@�}�4�9���R������G9S����\��)���ױ�>^�>ǯ������X��gf�s����������o������?�������/���_~���T�����y�������z~>�r1��\��_~p1���Ű��_�u�Ű��b� �ae��0Z��ʚ�a�6�/��u^�u�Ű��b� �ae��0Z��ʚ�a�6�/��u^�u�Ű��b� �ae��0Z��ʚ�a�6/��4��l^+�Fe��bX9s1���Ű��b� �ac��d]�|1���Fk�bXYs1���Ű��b� �ac��d]�|1���Fk�bXYs1���Ű��b� �ac��d]�|1���Fk�bXYs1���Ű���at/��2äl_+g.�Q�@�V�\���|1���Fk�b�X��0Y _+k.���@�V�\���|1���Fk�b�X��0Y _+k.���@�V�\���|1���Fk�bXX�/����bXYs1���Ű��b� ċa%��,_�&��ae��0Z��ʚ�a�6�/��5�hm _�&��ae��0Z��ʚ�a�6�/��5�hm _�&��ae��0Z��ʚ�a�6�/��5�hm _�&��ae��0Z��J:.��Y8�V�\���|1l��b���/��5�hm _+k.���@�V�\���|1l��b���/��5�hm _+k.���@�V�\���|1l��b���/��5�hm _+k.���@�V�\���|1l��b��/��t\��p|1���Fi�bXYs1���Ű�a�.@�V�\���|1���Fk�bXYs1���Ű��_�u�Ű��b� �ae��0Z��ʚ�a�6�/��u^�u�Ű��b� �ae��0Z��ʚ�a�6/��4��l^+�Fe��bX9s1����0ݴ��a|�������zx1|�:�py}�^��x�l��߿=��¶��v�bx<�g>\������/��_������������x���;8ξ9��<��5�_y!���lm �;��7gkq��YǾ9[���ʚ}s�.@�7wֱo��⾹��}s�6�͝u웳���o���7G��}s���o�Ə0�7w½V`c�Vp�Q+���X+�Ⱥ�Vp�Q+���X+8���@��u� +lm � +ʚZ�kg�[�����Z�� �Z�YG���b����к��Vp�Q+���X+8���@��u� +lm � +J:jt6�j��kVk��K�����Z�� �ZAYS+�ub�ଣV`k�Vp�Q+���X+8���@��5�Z � +�:j�6kg�[�����Z�� �ZAYS+�ub�ଣV`k�Vp�Q+���T+8�^+��pT+(�P�8��s� +,m � +�:j�6kg�[�����V@��Z�YG���b�ଣV`k�Vp�Q+���X+(kj�.@��u� +lm � +�:j�6kg�[�����Z��+kg�[�����Z�� �Z�I�Z����ZA9S+�tb�ଣV`k�Vp�Q+���X+8���@��5�Z � +�:j�6kg�[�����Z�� �ZAYS+�ub�ଣV`k�Vp�Q+���X+8���@��5�Z � +�:j�6�j'�kvk��K�����V@��Z�YG���b�ଣV`k�Vp�Q+���X+(kj�.@��u� +lm � +�:j�6kg�[�����V@��Z�YG���b�ଣV`k�Vp�Q+���X+(kj�.@��t��Y8��s� +,m � +�:j�6keM��������Z�� �Z�YG���b�ଣV`k�V0�Y+�ub�ଣV`k�Vp�Q+���X+8���@��5�Z � +�:j�6kg�[�����Z�� �ZAIG����Q���{����a����V`i�V�C{S+�����Ǘq\+��Xj��Z�e{��k��̇Z��f����~��m�������~�v�|~�G�����7����p�<���k���~ G�П_��54?��Z �54���ʙkh�6�������+����5��hm _C+k����@��V�\C���| m��������5��hm _C+k����@��V�\C���| m��������5��hm _C+k����@��V�\C���x m���&g��Z)�54*���ʙkh�6����5��hm _C뼆&��khe�54Z���ʚkh�6����5��hm _C뼆&��khe�54Z���ʚkh�6����5��hm _C뼆&��khe�54Z���ʚkh�6���t\C��px m���&e��Z9s ���5���� �khe�54Z����:��ɺ��ZYs ���5���� �khe�54Z����:��ɺ��ZYs ���5���� �khe�54Z�����~ ����ʚkh�6����5��hm ^C+鸆Fg���8�54I _C+k����@��V�\C���| ����Fk��X�54Y _C+k����@��V�\C���| ����Fk��X�54Y _C+k����@��V�\C���| ����Fk��X�54Y _C+k����@��V�q ����5�r�� �khc���d��+��^�����oE���]���KY����g# ���;g(�A63�_������j=�������l�O���&�~k�%�����khT;�����khT;�����khT;����:��I]�Z���F��Z���F��Z���F��ڨ���%�����khT;�����khT;�����khT;����:��I]�Z��͊�khe���kh����kh��khR�@��Vj��Q�@��Vj��Q�@��Vj��Q�@�����5�����khT;�����khT;�����khT;����:��I]�Z���F��Z���F��Z���F��ڠ��&���Z��Ɋ�khe���kh:����9�k諏��i�z�s����/�s��| =����>ݽ������������5�����E������y�z.}�'�K�W�|�����oT;������oT;������oT;����:o�I]�]��m;��axۮ�qێb��m�2sێh�m�P/�����|ۮ�ܶ�ځ|ۮ�ܶ�ځ|ۮ�ܶ�ځ|�n�y�N�ȷ�J�m;�ȷ�J�m;�ȷ�J�m;�ȷ�F����.�|ۮ�ܶ�ځ|ۮ�ܶ�ځ|ۮ�ܶ�ځx�n�ܶ��qxۮ�qێd��m�2sێh�m�Rsێj�m�Q�m;�K ߶+5���v ߶+5���v ߶+5���v ߶u���m�Rsێj�m�Rsێj�m�Rsێj�m�Q�m;�K ߶+5���v ߶+5���v +tܶ�Yqx�n�ܶ�q|ۮ�ܶ#ځ|ۮ�ܶ�ځ|ۮ�ܶ�ځ|�n�y�N�ȷ�J�m;�ȷ�J�m;�ȷ�J�m;�ȷ�F����.�|ۮ�ܶ�ځ|ۮ�ܶ�ځ|ۮ�ܶ�ځ|�.��m;�k ߶+5���v ߶+5���v +tܶ�Yq|�n�y�N�ȷ�J�m;�ȷ�J�m;�ȷ�J�m;�ȷ�F����.�|ۮ�ܶ�ځ|ۮ�ܶ�ځ|ۮ�ܶ�ځ|�n�y�N�ȷ�J�m;�ȷ�J�m;�ȷ�J�m;�ȷ�F����.�|ۮ�ܶ�ځxۮ�qێf��m�2sێh�m�Q�m;�K ߶+5���v ߶+5���v ߶+5���v ߶u���m�Rsێj�m�Rsێj�m�Rsێj�m�Q�m;�K ߶+5���v ߶+5���v ߶+5���v ߶u���m�B�m;�Ƿ���m;�ȷ�J�m;�ȷ�F����.�|ۮ�ܶ�ځ|ۮ�ܶ�ځ|ۮ�ܶ�ځ|�.��m;�k ߶+5���v ߶+5���v ߶+5���v ߶u���m�Rsێj�m�Rsێj�m�Rsێj�m�As�Nf��m�"�m;�Ƿ���m;�ȷ����?�v�~�1�������������ӝ�����?P������y�>�3��q\����_����_�=��������_~��r�������������<^%���|���~z>|�x�?����O����O�㭏q�ܞ��v�m��x�AKu<�����O��n��Q;pG=�>Yu{��ځ;������B�۳w��������ѩ�YV���tx|�����wԧ��ORݞ��v��z�1<=Ku{��ځ;��Q�1�lސ�r�F�iޠځܼQj�7�v 7o��� ������ �K 5o��5oP���G�Ŋ��2ӼA��y#�K��5��7JM����RӼA��y��4oP�@n�u6oH]�y��4oP�@n�(5�T;��7JM����Qg��%��7JM����RӼA��y��4oP�@l�4�2;�7��$+��7�L����RӼA��yc�ټ!u ��RӼA��y��4oP�@n�(5�T;��7F��R�@n�(5�T;��7JM����RӼA��yc�ټ!u ��RӼA��y��4oP�@l�(t4oЬ8l�2�";��7�L����RӼA��y��4oP�@n�u6oH]�y��4oP�@n�(5�T;��7JM����Qg��%��7JM����RӼA��y��4oP�@n��Ҽu ��RӼA��y��4oP�@l�(t4oЬ8n�s6o]�y��4oP�@n�(5�T;��7JM����Qg��%��7JM����RӼA��y��4oP�@n�u6oH]�y��4oP�@n�(5�T;��7JM����Qg��%��7JM����BG�͊��2ӼA��yc�ټ!u ��RӼA��y��4oP�@n�(5�T;��7F��R�@n�(5�T;��7JM����RӼA��yc�ټ!u ��RӼA��y��4oP�@n�(5�T;��7F��R�@l�(t4oЬ8n�(3�D;��7JM����Qg��%��7JM����RӼA��y��4oP�@n��Ҽu ��RӼA��y��4oP�@n�(5�T;��7F��R�@n�(5�T;��7JM����RӼA��yc�4o��8l�(r4o��8n�(3�D;��7T��[���c@�f�s��6�����g�������J�/�q�r:��:=\>�x&���Tn��?���?����������������xx���b||}������5;>=�]��g�C����s��ޏ_>~�����o������O�:�eu �QO��W�n��Q;pG}>�ޏ_��={G���������Jݞ��v�m���'��gY]w�����1�P�g����������;j��ÃU�g�x[}=��=�f�����(���;h���'�n��Q;pG}=���_���;j�Vߎ��דSdz�.�;����b���;j������os��;j��Ó� g<{G����O�ãS�,�k��z�1����={G����cxx�����w���h���;j�V���'��\�eu �QO��7�n��Q;pG}>_��={G����O��ۣẘ�M>��N�et �Q�?�g�n��Q;pG}�6��={G����Sx<Iu{��ځ�����p��x��%pG=���={G����c8��pƳw��Q�?�OVݞ��v�m��x��&�ϲ��ӫ� g<{G������Ū۳w��Q_O���dzw��9���o8�YV����cx�����w�mxE�c�͊�ef�����R�@�qQjv\P�@�qQjv\P�@�qQjv\P�@�q1��q!u ��f����f����f�����R�@�qQjv\P�@�qQjv\P�@�qQjv\P�@�q1��q!u �en;.(^�ᎋǎ��;.�̎��;.B�츀��R��j�R��j�R��j�Q��K �(5;.�v �(5;.�v �(5;.�v �u��R��j�R��j�R��j⎋A��Bf�ᎋ"ǎ��;.�̎��;.J͎��;.F�;.�.����츠ځ���츠ځ���츠ځ��bԹ�B��;.J͎��;.J͎��;.J͎��;.F�;.�.����츠ځ���츠ځ��б�f�ᎋ!��Bd��2��h�R��j�R��j�Q��K �(5;.�v �(5;.�v �(5;.�v �u��R��j�R��j�R��j�P/;.������츠ځ���츠ځ��б�f��1��K �(5;.�v �(5;.�v �(5;.�v �u��R��j�R��j�R��j�Q��K �(5;.�v �(5;.�v �(5;.�v �u��R��j⎋Bǎ��;.�̎��;.F�;.�.����츠ځ���츠ځ���츠ځ��bԹ�B��;.J͎��;.J͎��;.J͎��;.F�;.�.����츠ځ���츠ځ���츠ځ��bԹ�B��;. +;.hV�(3;.�v �(5;.�v �u��R��j�R��j�R��j�P/;.������츠ځ���츠ځ���츠ځ��bԹ�B��;.J͎��;.J͎��;.J͎��;.͎��;.�;.HV�(3;.�v ��o���ێ���x:����o>�߲���~�����[��o2}kWf<2��V\�c�����_���9������������Ng\�����3�2�?��|��������8�����x9�� ��x6��Y ��x3��� ��x0�>y��'�8^0d���8� +0d���8� 0df��8 �����x!�� ��x��Y ��p��c���0�����x�� ��x��Y ��x��� ��x@�s�Ȏ�%�Cf�Ȋ��Cf�Ȋ� �Cf�Ȋ��A��?���C��Od�q�ߐi�Yq��7dj�DV��9;�@v7� ��?��u#��?��a��7`��$V�9{�@v�� ��?��C��Od�q�ߐ��Yq\�����q��7d��DV�� �V?�ǝ~C��Od�q�_���d�q�ߐ)�Yq\�7d��DV�� �?��%~A�?�G ~n~⮢��o���'�:���Lu�Ċ���}����'�8n�2�}"+�+��Lc�Ȋ㾾!S�'�⸬/����㸩o����8��2-}"+�;��LE�Ȋゾ g?Ȏ�v�!S�'�⸚o�4�8��2�|"+K�BL'� +�F��F!���0��0m|+����L�Ȋ�"� gȎ��!S�'�⸂o�4���8��2�{"+������{ ;����L�Ȋ�ڽ!Ӻ'��so�T8.�r���8n�2e{"+����LӞȊÞ�G͞��0,�/{�*��L��Ċ�z�!Ӯ'��[o�T뉬8.�r���8n�2�z"+�+��L��Ȋ�>�!S�'��L/�٥��Io�鉬8��2-z"+�;�L��Ȋ��}�ҟ�'�8n�2�y"+���Ls�Ȋ�Gm���0.�pv�A�8n�2�y"+���L[�Ȋ㮼!S�'��(/�ٓ��%oȔ䉬8��2 y"+���L=�Ȋ�r� g7Ȏ�f�!S�'��oȴ≬8��2�x"+��}x ;����L�Ȋ�*�G���0��05x+�K���x ;���L�Ȋ���!�~'���n�T߉�8.�r�ށ�8n�2�w"+�+�L�Ȋ㾻!Sw'���.��u���n�݉�8��2-w"+�;�LŝȊセ g�Ȏ�v�G����0��0�v+�{�L��Ȋ�R� g�Ȏ�F�!Sh'���nȴى�8�2Uv"+�����K�}�\��nȔ؉�8��2 v"+���L}�Ȋ�� gwȎ��!S\'�⸶nȴ։�8�2�u"+�BL_� +ö��FY���0��0Mu+�{껝kUS����/�J�����������ǟ7�Ƿ����OǷ���P�IO=M��������Oۿ��/�|��c���pz���|��?><���gϘ>d��Wr�i��@��5���JM��侱RS8F��r��t�Q�@nu֎I]�x��4�Q�@�+5�cT;�� +�c4+��ƜdB�@.!+5-dT;�{�JM��*�R�EF���l�YG&u �B�R�HF����Ԕ�Q�@�%+5�dT;���F��dR�@.'+5�dT;���JMA�䊲R�QF���l�YS&u 䢲R�TF�����QVF�⸮�����@n,uV�I]���Դ�Q�@�-+5�eT;���JMw����Qg}��%��JM����RSbF��Ƭ���Q�@n2uV�I]�̬Դ�Q�@�3+5�fT;�+�JM���V�Qg���%����ܚ�(^�a�Y��܌b�q�Y��7#ځ�p����%g���jr�Y�):�ځ\uVj�Ψv ���:�Τ.�\xVjϨv w����3�ȵg����jr�٨��L���g����jr�Y�)@�ځ\�Vj:Шv �� �4��EhE�&4��]he��hrZ��C�ځ܈6�D��r)Z�iE�ځ܋Vj�Ѩv W���n4���h��z4�K ����4��i��$�jrMZ��I�ځܔ6�J��rYZ�iK�ځܗVj +Өv V�::�hV�� ��4���ie�9�hrwZ�)O�ځ\�Vj�Өv 7��:+Ԥ.�\�VjZԨv ����"5��Uj��K�jr�ڨ�NM�ȅj��Q�jr�Z�)U�ځ\�Vjzըv 7��z�V��r�Z�iW�ځܯVj +֨v V�::�hV���9kք.�\�Vj�֨v w����5��uk��o�jr�ڨ�rM�ȥk��u�jr�Z�)^�ځ\�Vj�רv ���:�פ.�\�Vjبv w���6��5l����jrۨ��M��el����jb[����f�q%[��d#ځ��6�e��r1[�if�ځ��Vj�٨v ׳��~6�� m�Ί6�K �����6��=m����jrU[��j�ځ��6�k��ra[�il�ځ��VjJۨv ���6���m���6�K ��:��hV����7��n��Íjr�ۨ��M��En��ɍjr�[�)s�ځ\�Vj�ܨv 7��z�t��r�[�iu�ځ��Vj�ݨv W���n7���n��z7�K ����7��o���jr�[��y�ځ��6h��dv��9��HV�����7�ȕ����|���J�WZ���c�}?ܩ}�������3�}?�����������_�����������oK_~w%~�%|��%�����r��'�/�}� P�C��g�Y�#u �r�RS�C���Ԕ�P�@.�)5�8T;��qF��8R�@.�)5�8T;�q +�84+��q�L9��r�Qg9��%��qJM9��r�RS�C���Ԕ�P�@.�u��H]��Ԕ�P�@.�)5�8T;��qJM9��r�Qg9��%��qJM9��r�RS�C���Ԕ�P�@.�u��H]��̭��u��8�q(V�㔙r���8�^�q���\�Sj�q�v �㔚r���8���jr9Ψ�G���8���jr9N�)ǡځ\�Sj�q�v ��:�q�.�\�Sj�q�v �㔚r���8���jb9Π)Ǒ�qX�S�(�!Yq\�Sf�q�v �㔚r���8��r�K �㔚r���8���jr9N�)ǡځ\�3�,Ǒ�r9N�)ǡځ\�Sj�q�v �㔚r���8��r�K �㔚r���8���jb9N���f�a9ΐ)��q\�Sf�q�v �㔚r���8���jr9Ψ�G���8���jr9N�)ǡځ\�Sj�q�v ��:�q�.�\�Sj�q�v �㔚r���8���jr9N��r�k �㔚r���8���jb9N���f�q9Θ�G���8���jr9N�)ǡځ\�Sj�q�v ��:�q�.�\�Sj�q�v �㔚r���8���jr9Ψ�G���8���jr9N�)ǡځ\�Sj�q�v ��:�q�.�\�Sj�q�v ��:�qhV�㔙r���8��r�K �㔚r���8���jr9N�)ǡځ\�3�,Ǒ�r9N�)ǡځ\�Sj�q�v �㔚r���8��r�K �㔚r���8���jr9N�)ǡځ\�3�,Ǒ�b9N���f�q9N�)�!ځ\�Sj�q�v ��:�q�.�\�Sj�q�v �㔚r���8���jr9N��r�k �㔚r���8���jr9N�)ǡځ\�3�,Ǒ�r9N�)ǡځ\�Sj�q�v �㔚r���8��Gf�a9N���d�q9N�)�!ځ\��f�(�����qW�q���o{'�����x|�r\�I9�w��������<=����������������?�ß�����P���y'�������.?=�����}��>�Lu��������_���/o|���_�ځ��K���_�ځ��K�n��d��������/]���N��d����N��d����N��d����J��/Q]���N��d����N _V;�N _V;�JM��%�N _V;�N _V;�N _V;�JM��%�N _V;����lV6|�9��v 6|���/�K 6|�:��v 6|�:��v 6|�:��v 6|���/�K 6|�:��v 6|�:��v 6|�:��v 6|���/�K 6|�:��v 6|�:��v 6|�:��v 6|���/�K 4|������u5|�5|Y�8l�:s4|�@l�u6|I]������e�������e�������e����4|Q]������e�������e�������e����4|Q]������e�������e�������e������E����ȭ��d�a�י���hb�ש���jb�W�i���b�ש���jb�ש���jb�ש���jb�W�i���b�ש���jb�ש���jb�ש���jb�W�i���b�ש���jb�ש���jR�ס[×͊���"G�ɎÆ�3G×�Ć�SG×�Ć�SG×�Ć�R��Eu Ć�SG×�Ć�SG×�Ć�SG×�Ć�R��Eu Ć�SG×�Ć�SG×�Ć�SG×�Ć�Qg×�5�N _V;�N _V;����lV6|���/�K 6|�:��v 6|�:��v 6|�:��v 6|���/�K 6|�:��v 6|�:��v 6|�:��v 6|���/�K 6|�:��v 6|�:��v 6|�:��v 6|���/�K 6|�:��v 5|�5|٬8l�:s4|�@l�*5 _T�@l�:u4|Y�@l�:u4|Y�@l�:u4|Y�@l�*5 _T�@l�:u4|Y�@l�:u4|Y�@l�:u4|Y�@l�*5 _T�@l�:u4|Y�@l�:u4|Y�@l�:u4|Y�@l�*5 _T�@j�:tk��Yq��u�h�2ځ��u�h��ځ��Uj��.���u�h��ځ��u�h��ځ��u�h��ځ��5�l���b�ש���jb�ש���jb�ש���jb�W�i���b�ש���jb�ש���jb�ש���jR�W���f�Q�ב[×ɊÆ�3G×�Ć/6N�7|�s|{��c�7|�s|��������/Ͽ�<�zy>�V�x��g����ͫ/��������Ow|�2y��K��_���ޯ������t�S��u��A^oW���C�g�x[}:�Ϙ�:�eu �QO����T�g����G�n��Q;pG=��Ϙ��={G������pz��`��gY]w����ժ۳w��Q���3&�n��Q;pG}=���y�R�g�x[}9���:�eu �Q�?��3&�n��Q;pG=���<X�۳w��Q�?��n��Q;��z�1���e��v����(���A;pG=�>Yu{��ځ;�������n��Q;��v<<���pƳ�.�;����b���;j�χ�g���x��ځ;����$���Q;�vM�������<������g�n��Q;pG=�^��={G����c8Zu{��ځ;{1c@Ǩs���%�y��ET;�y��ET;y:yЬ8^�1�\�!t �E�f���E�f���E�f���E��ER�@^�QjyP�@^�QjyP�@^�QjyP�@^�1�\�!u �E�f���E�f���E�f���E��ER�@^�QjyP�@\�Q�X�A��x�G�Y�A�y�Ǩs���%�y��ET;�y��ET;�y��ET;�y�:yH]y�G�Y�A�y�G�Y�A�y�G�Y�A�y�Ǩs���%�y��ET;�y��ET;�y��ET;�y�:yH]i�G��"��a�ȣ��ȃb��"�2�ȃh�"�P/�<����ȣ�,�ځ�ȣ�,�ځ�ȣ�,�ځ��cԹ�C�ȋ<J�"�ȋ<J�"�ȋ<J�"�ȋ<F��<�.��ȣ�,�ځ�ȣ�,�ځ�ȣ�,�ځ��c�,��q�ȣȱȃd��"�2�ȃh�"�R�ȃj�"�Q�"�K /�(5�<�v /�(5�<�v /�(5�<�v /�u.��"�R�ȃj�"�R�ȃj�"�R�ȃj�"�Q�"�K /�(5�<�v /�(5�<�v .�(t,�Yq��c�,��q�ȣ�,� ځ�ȣ�,�ځ�ȣ�,�ځ��cԹ�C�ȋ<J�"�ȋ<J�"�ȋ<J�"�ȋ<F��<�.��ȣ�,�ځ�ȣ�,�ځ�ȣ�,�ځ��#��"�k /�(5�<�v /�(5�<�v .�(t,�Yq��c̹�C�ȋ<J�"�ȋ<J�"�ȋ<J�"�ȋ<F��<�.��ȣ�,�ځ�ȣ�,�ځ�ȣ�,�ځ��cԹ�C�ȋ<J�"�ȋ<J�"�ȋ<J�"�ȋ<F��<�.��ȣ�,�ځ�ȣбȃf��"�2�ȃh�"�Q�"�K /�(5�<�v /�(5�<�v /�(5�<�v /�u.��"�R�ȃj�"�R�ȃj�"�R�ȃj�"�Q�"�K /�(5�<�v /�(5�<�v /�(5�<�v /�u.��"�B�"�Nj<��"�ȋ<J�"�ȋ<F��<�.��ȣ�,�ځ�ȣ�,�ځ�ȣ�,�ځ��#��"�k /�(5�<�v /�(5�<�v /�(5�<�v /�u.��"�R�ȃj�"�R�ȃj�"�R�ȃj�"�A��Cf��"�"�"�Nj<��"�ȋ<�5#y�sl�<Wy�?��=_����bo������z�J��(7��<�M��X����|=���_��_���/ۿ����×�~�z�r|�$���<��t�W�R�?�!W~���s@1��b�RSA��b�Y!u �b�RSA����CP�@.�(5�T;��!F��R�@.�(5�T;��!JM1��b�RSA��b�Y!u �b�2�b��aXQ�(��Xq\Qf�!�v C�z)���r1D�)��ځ\Qj�!�v C��b�����b�K C��b������jr1D�)��ځ\1�,���r1D�)��ځ\Qj�!�v C��b�����Bf�a1D���d�q1D�)� ځ\Qj�!�v C�:�!�.�\Qj�!�v C��b������jr1Ĩ�B������jr1D�)��ځ\Qj�!�v C�:�!�.�\Qj�!�v C��b�����b���C�Bd�q1D�)� ځ\Qj�!�v C��b�����b�K C��b������jr1D�)��ځ\1�,���r1D�)��ځ\Qj�!�v C��b����^�!���\Qj�!�v C��b�����b���c�b�K C��b������jr1D�)��ځ\1�,���r1D�)��ځ\Qj�!�v C��b�����b�K C��b������jr1D�)��ځ\1�,���r1D�)��ځXQ�(��Yq\Qf�!�v C�:�!�.�\Qj�!�v C��b������jr1Ĩ�B������jr1D�)��ځ\Qj�!�v C�:�!�.�\Qj�!�v C��b������jr1Ĩ�B�����b���e��hr1D�)��ځ\1�,���r1D�)��ځ\Qj�!�v C��b����^�!���\Qj�!�v C��b������jr1Ĩ�B������jr1D�)��ځ\Qj�!�v C�b���E�b���e��hr1�����c+�\}����b�����!��}x~�b�x&Ő(������/_�|=�����������/߾�}�;>�����ۯ�g���Ͽ���p�xx>�����u�8�~r���r7��n��/q�n����9T;��攚�9T;����92;��9�搬8��Sf���@��Sj��P�@��3꼛#u �9��n��9��n��9��n��9�λ9R�@��Sj��P�@��Sj��P�@��Sj��P�@��3꼛#u �9��n��9��n�Ļ9���94+����9";��攙�9D;��攚�9T;��攚�9T;���:��H]�nN���C��nN���C��nN���C��nΨ�n��%��攚�9T;��攚�9T;��攚�9T;���z��u �9��n��9��n�Ļ9���94+���9��]�nN���C��nN���C��nN���C��nΨ�n��%��攚�9T;��攚�9T;��攚�9T;���:��H]�nN���C��nN���C��nN���C��nΨ�n��%��攚�9T;��:��Ь8��Sf���@��3꼛#u �9��n��9��n��9��n��9�λ9R�@��Sj��P�@��Sj��P�@��Sj��P�@��3꼛#u �9��n��9��n��9��n��9�λ9R�@��S踛C���nN���C��nN���C��nΨ�n��%��攚�9T;��攚�9T;��攚�9T;���z��u �9��n��9��n��9��n��9�λ9R�@��Sj��P�@��Sj��P�@��Sj��P�@��3h����8��S丛C���nN���C��nn��K�������>�����n�����9�t䳹�\͝����������������f?��Ͽ~�~{�t|�)7��^��������O��9�����8�y<�����Ƨ�An�2Yq;�����$�=�d�퐯��W'~{�������p|��C�GQ���+�,��Q&+n�<��?=8r{�Ɋ�!Ͽ��Wh��Q&+�6y:��9E��v��/�ã#�G��������7���e��v��/�'In�2Yq������۳"ǣHv�y:<��=�!�G�������E�ۣLV��zx�� ;e��n�O�_�'���xɎ�!Ͽ����e��v��/��o��I��v�����62e��v^�p��p�xɎ�!�K%��TYq�� +C� DV��y=��/��|7��o�0d^LAd��k)��RYq�N +C�DV��B��}@v��y�ǯ�0d�DAd��{(��PYq� +A�wP��q� +n/� �* +_?a��� ����̫'H�8~��}��މ}r��N2/� ������'��8~߄!� "+�_6!��� ;��4aȼh�Ȋ��L2o� �����+&��8~�� ��%��8~��!S�%��"k�4d��8��2�X"+˱BL7� +�f��F1���0��0�X+�;��L%�Ȋ�B� gȎ�6�!S�%�� +k�4a��8��25X"+�K���X ;���L�Ȋ���!�~%���j�T_��8.� +r�^��8n�2�W"+�+��L�Ȋþ�Gݕ��0,� +/]W�*���LѕĊ㚫!�r%���j�T\��8.� +r�[��8n�2�V"+����L��Ȋ�^�!Sk%���*��i���j�Z��8��2mV"+����L��Ȋ�"�}��c�'�8n�2%V"+�+��L��Ȋ���G}���0.� +pvWA�8n�2�U"+�k��Lk�Ȋ�Ϊ!SY%�⸰*��W�㸭jȔU��8��2MU"+�{��LM�Ȋ㒪 gGȎㆪ!SP%�⸞jȴS��8�2�T"+������T ;�[��L)�Ȋ�J�G#���0�0uT+�˨��]T ;����L�Ȋ��!�B%�⸃j�TP��8.� +r�O��8n�2�S"+����L�Ȋ�ީ!S;%��t*��9��qj�N��8��2mS"+����LՔȊ㢩 g�ȎÖ�Gɔ��0��0 S+����L��Ȋ�r� g�Ȏ�f�!S,%��VjȴJ��8�2�R"+����K�t�\�MjȔI��8��2MR"+�{��L��Ȋ�� g�Ȏ��!S %��>jȴG��8�2�Q"+��BLo� +�֨�Fi���0��0�Q+�����GU���E/�ʢ���?�����ޱp����ۅ����t��ҭ�3��#[W4M�������ۿ���/���� �Y?����������|��O{U��������|�<t�A?��������O�>~���x��%pG=^_��={G����pz?�P����w������)u{��ځ���I��YV����cx|�����w�����ڔ�={G����cx�����o���ÃC�G����38��={����3�d���;j��7��={G������.�ɩ�YV���txy�����w�����T�g����O�7����oWJ>��Nͳ���;���pz�����w����E�۳w��Q�?��U�g���=1V8�:W=H]y�C��@�y�C���@�q�C�c�͊�c΅B�@��PjF>P�@��Pjv>P�@^�Pj�>P�@�0�\� u ��f�����f�����f�������R�@��Pj�?P�@��Pj�?P�@^�Qj&@P�@1�\!u ��f��)��-4+��@��9D;�A�:AH]yD�A�yD��A�yD��A�yĨs��%��A���T;�'B���T;�WB���T;��B�:�BH]y+D�A�y.D��A�y1D��A�y4Ĩs5��%�vC�� ��x��! +�!(V��(3�!�v ��� ��"J͈��3"J͎��K"J͔��c"F�k"�.��'����ځ<)��l��ځ�*��̊�ځ<,bԹ,B���"J���"J;��#J����##����;#�C#HVO�(3[#�v ��(5s#�v �u.�����R3:�j��R�;�j��R3=�j���Q���K �(5$�v O�(5$�v ��(53$�v �u.�����R3F�j��R�G�j�"�B�$ ���$��* �ǻ$��0 ���$J�6 ���$J�< ��%F�%�.��Q�Ԍ��ځ<S��씠ځ�T��L��ځ<VbԹVB��{%J�` �ȓ%J�f �ȫ%J�l ���%B�,����v�R3^�j�|�R�_�j₉BDŽ ��#&Ɯ+&�.��c����ځ<e��l��ځ�f��̙�ځ<hbԹhB�ț&Jͨ �ȳ&Jͮ ���&Jʹ ���&F��&�.��o����ځ<q��l��ځ�r��̜�ځ<tbԹtB��['J�� ��s' +{'hV/�(3�'�v ��u������R3|�j��R�}�j���R3�j���Q� +�K o�(5#(�v Ϡ(5;(�v /�(5S(�v ��u������R3��j�$�R���j�*�R3��j�0�Q�2 +�K n�(t���Yq<���� ځ����L��ځ<�bԹ�B��;)J�P +��S)J�V +��k)J�\ +�ȃ)B�,����f�R3��j�l�R���j�r�R3��j�x�Q�z +�K �(5*�v O�(5*�v ��(53*�v �4K*dvn�(r�� Yq<���� ځ�����&U�sl�*W��iwTe�s��������W��bnϕ����z�ʰ��^n7��Cy&�*DZ��~�����ӏ?�i�����|��y���������ۿ��e���?���?�������������ß~����?~�y���?}���w�O�E�˧�8����7�r���j��W��_�~� �-��_�u~AK��_�*5_Тځ��R�-��_�*5_Тځ��Q���.���R�-��_�*5_Тځ��R�-��_� +��-�k A��|A�j��J���v ~A���-��_�s~AK��_�*5_Тځ��R�-��_�*5_Тځ��Q���.���R�-��_�*5_Тځ��R�-��_�u~AK��_�*5_Тځ��R�-��_�*5_Тځ��Q���.���R�-��_�*t|A�f�������v Ak��-�K A��|A�j��J���v A��|A�j��F�_В���J���v A��|A�j��J���v Ak��-�K A��|A�j��J���v A��|A�j��F�_В��� +_ТYq��2�-��_�*5_Тځ��Q���.���R�-��_�*5_Тځ��R�-��_� +��-�k A��|A�j��J���v A��|A�j��F�_В���J���v A��|A�j��J���v ~Ak�|AKf����_�"Yq��2�-��_��C����ϱ}A{�1���ϱ|A{�/h�g������<�/h���������O���xz�����y���o�^���������?����ן>o�^����6ͷ�������~��H����p|����?�y9�R<�����������>�+���%v7|n|�� T�@��q���a�q�ǩcÇ�� �� V;7|�� T�@��q���a�q�ǩcÇ�� �� V;�6|:6|��8��q���d�ᆏ3dž��>N>�v n�(5>�.����Ա��jSdž��>N>�v n�(5>�.����Ա��jSdž��>N>�v n�(5>�.����Ա��jSdž�H>�6|ج8��Q���A��p�ǙcÇ�� ��QV;OD�:NDY�@<UjNDQ]�Dԩ�D���Q��QV;OD�:NDY�@<UjNDQ]�Dԩ�D���Q��QV;OD�:NDY�@<5�<%u �Q��QV;OD�:NDY�@:u�v"�f�ቨ2s"���'�N'��v ��:u���ځx"��q"�j≨Rs"���'�N'��v ��:u���ځx"��q"�j≨Rs"���'�N'��v ��:u���ځx"��q"�j≨Rs"���'�N'��v ��:t;e���Dԙ�D���Q��D�%OD�:NDY�@<u�8e��Dԩ�D���Q��D�%OD�:NDY�@<u�8e��Dԩ�D���Q��D�%OD�:NDY�@<u�8e��Dԩ�D���Q��D�%�ND����Yqx"��q"�h≨Slj(��'�J͉(�K ��:u���ځx"��q"�j≨Slj(��'�F�'����x"��q"�j≨Slj(��'�N'��v ��*5'��.�x"��q"�j≨Slj(��'�N'��v ��*t����qt"���D�Ɋ�Qg�QF;OD����(�o�\���Q���|���OL�7|ο�<�z������4��#ہ��aY�Y>���y�s�K��?����a����zx������'��;>��7E?�Gu<�����o�8����;j�χǣU�g�����7EJݞ��v�m��x8���Qdz�.�;����j���;j�χ��M�R�g����^��pV�۳w�����ORϲ�����M�R�g������K�={G����cx�����o��������Q6;n�<��Gin��A;pG=�>Yu{��ځ;�������n��Q;��v<<���pƳ�.�;����b���;j�χ�g���x��ځ;����$���Q;��{�?��Nͳ���;���pz�����w����E�۳w��Q�?��U�g�x[=���osy��%pG=��ޤ�={G����p|�����w��ó������n��������g]w����٪۳w��Q�?���n��Q;pG=�ORݞ��v�m�t�1��:�eu �Q�?��G�n��Q;pG=���7����w���U�g�x[}<>����Ƴ�.�;����*���Q;pG}>|z�����w��Ó�o����o�O�Ó� g<������Vݞ��v��z�1�����cV�y���o8��;h�V��?���gY]w����(���Q;pG=�>Yu{��ځ;����M�67���v�m�����U�'x<������/Vݞ��v���t~^�67���v���}5����;j�V_�?�G��gY]w���$���Q;pG=��os��;j���Ѫ۳w�������os�YV����c����w����`��u{�Xq;����*���A;�va�ӧ����&Ϣ���٪۳w��Q�?���T�g����5�f��y��yR�@��Qj�qP�@��Qj�qP�@��Qj�qP�@��1��!u �y�f��y�f��y�f��y�f�̎�yE�y$+��q��yD;��q��yT;��q�:�qH]yG���A�yG���A�yG���A�yǨs��%��q��yT;��q��yT;��q��yT;��q�:�qH]yG���A�yG���A�qG�c͊�yCf�Ȏ�yef��y�f��y�f��y��yR�@��Qj�qP�@��Qj�qP�@��Qj�qP�@��1��!u �y�f��y�f��y�f��y�^�q@]yG���A�yG���A�qG�c͊�yc�yB�@��Qj�qP�@��Qj�qP�@��Qj�qP�@��1��!u �y�f��y�f��y�f��y��yR�@��Qj�qP�@��Qj�qP�@��Qj�qP�@��1��!u �y�f��y��y4+��q��yD;��q�:�qH]yG���A�yG���A�yG���A�yǨs��%��q��yT;��q��yT;��q��yT;��q�:�qH]yG���A�yG���A�yG���A�yǨs��%�q:�qЬ8��Qf�q�@��Qj�qP�@��1��!u �y�f��y�f��y�f��y�^�q@]yG���A�yG���A�yG���A�yǨs��%��q��yT;��q��yT;��q��yT;�q�y2;�q9�q��8��Qf�q�@���_}Q�8�9�y����8���o|���oQ�ο���3�9�U������_�����������w���i������~���/������=|:��C����_~���������wW������z�y'��N��/s�N���;AR�@�Tj�Q�@�Tj�Q�@�Tj�Q�@�4h���8�T�D���NP��D��NP��D��NШ�N��%����;AT;����;AT;����;AT;���:�I]�NP��D��NP��D��NP��D��NШ�N��%����;AT;����;AT;�:�Ѭ8�4d���8�Tf��@�Tj�Q�@�Tj�Q�@�4�$u �;A��N��;A��N��;A��N��;A��;AR�@�Tj�Q�@�Tj�Q�@�Tj�Q�@���N�5����;AT;����;AT;�:�Ѭ8�4�$t �;A��N��;A��N��;A��N��;A��;AR�@�Tj�Q�@�Tj�Q�@�Tj�Q�@�4�$u �;A��N��;A��N��;A��N��;A��;AR�@�Tj�Q�@�T�D���NP��D��NШ�N��%����;AT;����;AT;����;AT;���:�I]�NP��D��NP��D��NP��D��NШ�N��%����;AT;����;AT;����;AT;���:�I]�NP��N͊�;Ae�N��;A��N��;A��;AR�@�Tj�Q�@�Tj�Q�@�Tj�Q�@���N�5����;AT;����;AT;����;AT;���:�I]�NP��D��NP��D��NP��D��NР�$���NP��NɊ�;Ae�N��;A�Ww��9�;���w��������翯���8�x�������/�������.�g<2���q�}�������6����a�o���z:���L�t��!����#W��p�~�O�>� p{�Ŋ�!���Yq��@Aη�q��@C�U�DV�(АyO ��o 4d^Hd��+9�d��� ��Yq�r@C�݀DV�Аy1 �ǯ�|+ ���4d^ Hd�� ��Yq�6@C�e�DV� +P�y ���4`^Hb��K� �w�Yq�@C��DV��O���@v��ϐy���/�3d��Gd��[����Yq�ʿ��������3d^�Gd�����w�Yq��?C�EDV��O��-@v��ϐy���/�3d��Gd�����8^�G�u��O���~ v��ϐy���/�3d��Gd�����Yq�:?Aη��q�.?C�U~DV��ϐy���o�3d^�Gd��+�9��d�������Yq��>C��}DV��ϐyq�ǯ��|k����3d^�Gd����8��G�u��πyY�ǯ��|S����3d^�Gd��K��w�Yq��>C�}DV��O���|@v��ϐy5��/�3d��Gd��[����Yq�J>A�7��q�>>C�u|DV��ϐy��o�3d^�Gd��k�9��d��;�������(|���������0/�#����{��˛���%�gȼv�Ȋ��2��#����{�����8~ݞ �����8~מ!�="+�_�gȼg�Ȋ��2�9DVO�r.���q��c���Yq<�c�l�Yq��c��Yq8�#Ĭ��Xa��c�1�C�u�0;9$V��2#9DVO�r.���q��c���Yq<�c�l�Yq��c��Yq<�#ȹ�d��&�!3�Cd�� �!��Cd���!3�Cd��� ���;8����#8����8F8^�����~^����3}Cb����!�{Cd���!3zCd��� �� ��{7��� ��c7��� ��K7��� ��37��+7@vo�27DV�2�6DV��2�6DVO��'/�6��ǻ6�̬ �ǣ6�̦ ���6F�6^���� ��[6�̔ ��C6�̎ ��+6�̈ ��6��6@v��2�5DV��2�5DV/�2�5DV��r����q�Yc�L�Yq<Xc���Yq�VcȌ�Yq<U#ȹTd��N�!3SCd��H��F ��a�Pc�ԐXq<O#ȹNd��6�!3MCd��0�!�KCd��*�!3JCd��$� �" ��{4�� ��c4�� ��K4�� ��34��+4@vo�24DV�2�3DV��2�3DVO�r.���q�;c�1;C�u��0�3$V/�2�3DV��r����q�5c�L�Yq<4c���Yq�2cȌ�Yq<1s��,��K��2�2DV��2�2DV/�2�2DV��r����q�)c�L�Yq<(c���Yq�&cȌ�Yq8%#�,��Xa�#c�1#C�u��02$V/��"������\�������~�o��~z�z���gο�<��y<^���5g3��#�~L�0���˗�퇯?~���V���.��7>����P;�1s�>ܜ���t�;?U�ځ<U��lU�ځ�Va�9WA�ȃJ�b�țJ�h�ȳJ�n����t�����z���J̀��J͆��+F�3�.�<d��,Y�ځ�e�ԌY�ځ<g���Y�ځ�h!�ˤ�k �Z(5��v �Z(5��v O[(5��v �[u�[�����R�p�j�ƅR3r�j�̅B����KƜS�.�<v�Ԭ]�ځ�w��^�ځ<y��l^�ځ�za�9{A���J�����J�����J����F��.�<��Ԭ`�ځ����a�ځ<���la�ځ��a�9�A�ȃJ�"��� +�hV�b(3��v /cuNc���8�R���j�>�R3��j�D�R���j�J�Q�L�K e(5K�v oe(5c�v �e(5{�v /fuNf���h�R���j�n�R3��j�t�R���j�z�Q�|�K h(s[�@�:748F4P�8��Pfv4�@^��eJ�5��4��5 T;��4��A T;�'5��M T;�W5�:g5H]yXC�Y�@�y[C��@�y^C���@�yaèsb��%�G6��� T;�w6��� T;��6��� T;�6�� 2;797��8��PfF7�@��Pjv7P�@^�0�� u �� �f}��� �f��� �f�����R�@�Pj�8P�@��Pj�8P�@��Pj�8P�@^�0�� u �Q�f���]�f���i��m4+�9�y";�:���D;�7:���T;�g:���T;��:�:�:H]y�C�Y�@�y�C��@�y�C���@�y�ès���%��;���T;��;���T;��;���T;�<�z���u ��f����f���)��-4+��<�9�<]y�C�Y�@�y�C��@�y�C���@�y�èsڃ�%��=��uT;��=���T;�'>���T;�W>�:g>H]y�C�Y�@�y�C��@�y�C���@�y�ès��%�G?���T;w?:�?Ь8��Pf�?�@^�0�� u ��f�� �f���f��%��)R�@Qj�@P�@�QjAP�@�Qj6AP�@^1�!u �a�f��m�f��y�f���ΉR�@ Q�X A��x'D� +A�y*D�� +A�y-Ĩs.��%�C���T;�7C���T;�gC���T;��C�z�u ���f=����f@�� �fC����R�@Qj�DP�@�Qj�DP�@�Qj�DP�@\1h&E��8Q�XA��xWD�A�yZd1Cm�����E��<��E�?�ռ��G�8/rFߎ/8/2��EƼ������ۿ�~���?���?�4��~���o?�U#}|�C�����v�����R�ܩ�^}��j�Ǐ�RB�@��*5�RT;���JM���j�RS-E��Zj�Y-%u �j�RS-E��Z��TKQ�@��*5�RT;���F��RR�@��*5�RT;���JM���j�RS-E��Zj�Y-%u �j�RS-E��Z��Q-E��Z��TK�@��uVKI]�Z��TKQ�@��*5�RT;���JM���j�Qg���%���JM���j�RS-E��Z��TKQ�@��uVKI]�Z��TKQ�@��*5�RT;���JM���j�Qg���%����ܪ�(^�a�T��Z�b�q�T���"ځ\-�Z +���R��Z�jr�T����ځ\-Uj���v WK�:���.�\-Uj���v WK��j)���R��Z�jr�Ԩ�ZJ���R��Z�jr�T����ځ\-Uj���v VK �j)���RE�j)���Re�Z�hr�T����ځ\-5ꬖ��r�T����ځ\-Uj���v WK��j)���R��j)�K WK��j)���R��Z�jr�T����ځ\-5ꬖ��r�T����ځ\-Uj���v VK:��hVVK �j)���Re�Z�hr�T����ځ\-Uj���v WK�:���.�\-Uj���v WK��j)���R��Z�jr�Ԩ�ZJ���R��Z�jr�T����ځ\-Uj���v WK�z����r�T����ځ\-Uj���v VK:��hVWK�9���.�\-Uj���v WK��j)���R��Z�jr�Ԩ�ZJ���R��Z�jr�T����ځ\-Uj���v WK�:���.�\-Uj���v WK��j)���R��Z�jr�Ԩ�ZJ���R��Z�jb�T��Z�f�q�T���"ځ\-5ꬖ��r�T����ځ\-Uj���v WK��j)���R��j)�K WK��j)���R��Z�jr�T����ځ\-5ꬖ��r�T����ځ\-Uj���v WK��j)���R��j)�K VK:��hVWK��j)���R��Z�jr�Ԩ�ZJ���R��Z�jr�T����ځ\-Uj���v WK�z����r�T����ځ\-Uj���v WK��j)���R��j)�K WK��j)���R��Z�jr�T����ځX-5h��dvVK9��HVWK��j)���RjD�j)~��Zz��ܯ����Zz���������㑭Zz��?����/���o��ϵcz��o��r�>����r�e����y�;��>��;�?~xg4�K �3Z�yg4���Vj��j�;���wF�ځ��h�^� ���Vj��j�;���wF�ځ��h��Ѩv �3ڨ�Ѥ.���h��Ѩv �3Z�yg4���V�(��Yq\�7�,��r�_�)��ځ\�Wj���v ���b?���~��b?�K ���b?���~��؏jr�_�)��ځ\�7�,���r�_�)��ځ\�Wj���v ���b?���~��b?�K ���b?���~��b?���~e�؏hr�ߨ��O���~��؏jr�_�)��ځ\�Wj���v ��:���.�\�Wj���v ���b?���~��؏jr�ߨ��O���~��؏jr�_�)��ځ\�Wj���v ��:���.�T�W�V�G�:�� +�~+����L���b�P/�~P�@.�+5�~T;���JM���b�RS�G���o�Y�'u �b�RS�G��د��Q�@.�+5�~T;���F��~R�@.�+5�~T;���JM���b�RS�G���o����8,�+r���8.�+3�~D;���JM���b�Qg���%���JM���b�RS�G��د��Q�@.�u�I]�د��Q�@.�+5�~T;���JM���b�Qg���%���JM���b�RS�G��د�Q�G���o����8.�+3�~D;���JM���b�RS�G���o�Y�'u �b�RS�G��د��Q�@.�+5�~T;���F��~R�@.�+5�~T;���JM���b�RS�G���/�K��5���JM���b�RS�G��د�Q�G���o�Y�'t �b�RS�G��د��Q�@.�+5�~T;���F��~R�@.�+5�~T;���JM���b�RS�G���o�Y�'u �b�RS�G��د��Q�@.�+5�~T;���F��~R�@.�+5�~T;�� +�~4+����L���b�Qg���%���JM���b�RS�G��د��Q�@.�u�I]�د��Q�@.�+5�~T;���JM���b�Qg���%���JM���b�RS�G��د��Q�@.�u�I]�د�Q�G��د���@.�+5�~T;���F��~R�@.�+5�~T;���JM���b�RS�G���/�K��5���JM���b�RS�G��د��Q�@.�u�I]�د��Q�@.�+5�~T;���JM���b�AS�'��د�Q�G��د���@.���U�?�V��ѿ���?�����O�ç�#��#[��q����s�1����Ϻ��M����/�ǂ���n����s�����/�� PzG����Ԕ�Q�@.��Rzu �һRSzG����Ԕ�Q�@.�+5�wT;�K�F��wR�@.�+5�wT;�K�JM���һBG�͊�һ1g��%�K�JM���һRSzG����Ԕ�Q�@.�u��I]���Ԕ�Q�@.�+5�wT;�K�JM���һQg��%�K�JM���һRSzG����Ԕ�Q�@.�u��I]���Ԕ�Q�@,�+t��Ѭ8.�+3�wD;�K�F��wR�@.�+5�wT;�K�JM���һRSzG���n�Yz'u �һRSzG����Ԕ�Q�@.�+5�wT;�K�F��wR�@.�+5�wT;�K�JM���һRSzG���n�Yz'u �һ2��;��aXzW�(��Xq\zWfJ�v �ޅz)���r�]�)��ځ\zWjJ�v �ޕ��;�ȥw���;�K �ޕ��;�ȥw���jr�]�)��ځ\z7�,���r�]�)��ځ\zWjJ�v �ޕ��;���w���Nf�a�]���d�q�]�)�#ځ\zWjJ�v �ލ:K�.�\zWjJ�v �ޕ��;�ȥw���jr�ݨ��N�ȥw���jr�]�)��ځ\zWjJ�v �ލ:K�.�\zWjJ�v �ޕ��;���w���;���wC��Nd�q�]�)�#ځ\zWjJ�v �ޕ��;�ȥw���;�K �ޕ��;�ȥw���jr�]�)��ځ\z7�,���r�]�)��ځ\zWjJ�v �ޕ��;�ȥw�^J�\zWjJ�v �ޕ��;���w���;�ǥwc��;�K �ޕ��;�ȥw���jr�]�)��ځ\z7�,���r�]�)��ځ\zWjJ�v �ޕ��;�ȥw���;�K �ޕ��;�ȥw���jr�]�)��ځ\z7�,���r�]�)��ځXzW�(��Yq\zWfJ�v �ލ:K�.�\zWjJ�v �ޕ��;�ȥw���jr�ݨ��N�ȥw���jr�]�)��ځ\zWjJ�v �ލ:K�.�\zWjJ�v �ޕ��;�ȥw���jr�ݨ��N���w���;�ǥwe��hr�]�)��ځ\z7�,���r�]�)��ځ\zWjJ�v �ޕ��;�ȥw�^J�\zWjJ�v �ޕ��;�ȥw���jr�ݨ��N�ȥw���jr�]�)��ځ\zWjJ�v �� ��;���wE��;�ǥwe��hr�}���J��9���u��m����9��|������x�{��o�9^N��.��z|����O��s:}���x�������s����_vVNendstream endobj -1470 0 obj << +1498 0 obj << /Type /Page -/Contents 1471 0 R -/Resources 1469 0 R +/Contents 1499 0 R +/Resources 1497 0 R /MediaBox [0 0 609.714 789.041] -/Parent 1174 0 R -/Annots [ 1473 0 R 1474 0 R 1475 0 R 1476 0 R 1477 0 R 1478 0 R 1479 0 R 1480 0 R 1481 0 R 1482 0 R 1483 0 R 1484 0 R 1485 0 R 1486 0 R 1487 0 R 1488 0 R 1489 0 R 1490 0 R 1491 0 R 1492 0 R 1493 0 R 1494 0 R 1495 0 R 1496 0 R 1497 0 R 1498 0 R 1499 0 R 1500 0 R 1501 0 R 1502 0 R 1503 0 R 1504 0 R 1505 0 R 1506 0 R 1507 0 R 1508 0 R 1509 0 R 1510 0 R 1511 0 R 1512 0 R 1513 0 R 1514 0 R 1515 0 R 1516 0 R 1517 0 R 1518 0 R 1519 0 R 1520 0 R 1521 0 R 1522 0 R 1523 0 R 1526 0 R 1527 0 R 1528 0 R 1529 0 R 1530 0 R 1531 0 R 1532 0 R 1533 0 R 1534 0 R 1535 0 R 1536 0 R 1537 0 R 1538 0 R 1539 0 R 1540 0 R 1541 0 R 1542 0 R 1543 0 R 1544 0 R 1545 0 R 1546 0 R 1547 0 R 1548 0 R 1549 0 R 1550 0 R 1551 0 R 1552 0 R 1553 0 R 1554 0 R 1555 0 R 1556 0 R 1557 0 R 1558 0 R 1559 0 R 1560 0 R 1561 0 R 1562 0 R 1563 0 R 1564 0 R 1565 0 R 1566 0 R 1567 0 R 1568 0 R ] +/Parent 1202 0 R +/Annots [ 1501 0 R 1502 0 R 1503 0 R 1504 0 R 1505 0 R 1506 0 R 1507 0 R 1508 0 R 1509 0 R 1510 0 R 1511 0 R 1512 0 R 1513 0 R 1514 0 R 1515 0 R 1516 0 R 1517 0 R 1518 0 R 1519 0 R 1520 0 R 1521 0 R 1522 0 R 1523 0 R 1524 0 R 1525 0 R 1526 0 R 1527 0 R 1528 0 R 1529 0 R 1530 0 R 1531 0 R 1532 0 R 1533 0 R 1534 0 R 1535 0 R 1536 0 R 1537 0 R 1538 0 R 1539 0 R 1540 0 R 1541 0 R 1542 0 R 1543 0 R 1544 0 R 1545 0 R 1546 0 R 1547 0 R 1548 0 R 1549 0 R 1550 0 R 1551 0 R 1552 0 R 1553 0 R 1554 0 R 1555 0 R 1556 0 R 1557 0 R 1558 0 R 1559 0 R 1560 0 R 1561 0 R 1562 0 R 1563 0 R 1564 0 R 1565 0 R 1568 0 R 1569 0 R 1570 0 R 1571 0 R 1572 0 R 1573 0 R 1574 0 R 1575 0 R 1576 0 R 1577 0 R 1578 0 R 1579 0 R 1580 0 R 1581 0 R 1582 0 R 1583 0 R 1584 0 R 1585 0 R 1586 0 R 1587 0 R 1588 0 R 1589 0 R 1590 0 R 1591 0 R 1592 0 R 1593 0 R 1594 0 R 1595 0 R 1596 0 R ] >> endobj -1473 0 obj << +1501 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 706.187 232.298 715.098] +/Rect [143.462 706.187 237.269 715.098] /Subtype /Link -/A << /S /GoTo /D (flags-edit) >> +/A << /S /GoTo /D (flags-create) >> >> endobj -1474 0 obj << +1502 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 706.187 537.983 715.098] /Subtype /Link -/A << /S /GoTo /D (flags-edit) >> +/A << /S /GoTo /D (flags-create) >> >> endobj -1475 0 obj << +1503 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 693.235 164.612 702.147] +/Rect [143.462 693.235 237.269 702.147] /Subtype /Link -/A << /S /GoTo /D (edit-values) >> +/A << /S /GoTo /D (flags-delete) >> >> endobj -1476 0 obj << +1504 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 693.235 537.983 702.147] /Subtype /Link -/A << /S /GoTo /D (edit-values) >> +/A << /S /GoTo /D (flags-delete) >> >> endobj -1477 0 obj << +1505 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 680.284 259.386 689.195] +/Rect [143.462 680.284 232.298 689.195] /Subtype /Link -/A << /S /GoTo /D (edit-values-list) >> +/A << /S /GoTo /D (flags-edit) >> >> endobj -1478 0 obj << +1506 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 680.284 537.983 689.195] /Subtype /Link -/A << /S /GoTo /D (edit-values-list) >> +/A << /S /GoTo /D (flags-edit) >> >> endobj -1479 0 obj << +1507 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 667.333 228.124 676.244] +/Rect [95.641 669.27 170.928 676.244] /Subtype /Link -/A << /S /GoTo /D (edit-values-delete) >> +/A << /S /GoTo /D (custom-fields) >> >> endobj -1480 0 obj << +1508 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 667.333 537.983 676.244] +/Rect [528.02 669.27 537.983 676.244] /Subtype /Link -/A << /S /GoTo /D (edit-values-delete) >> +/A << /S /GoTo /D (custom-fields) >> >> endobj -1481 0 obj << +1509 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 654.381 144.448 663.293] +/Rect [119.552 654.381 234.689 663.293] /Subtype /Link -/A << /S /GoTo /D (voting) >> +/A << /S /GoTo /D (add-custom-fields) >> >> endobj -1482 0 obj << +1510 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 654.381 537.983 663.293] /Subtype /Link -/A << /S /GoTo /D (voting) >> +/A << /S /GoTo /D (add-custom-fields) >> >> endobj -1483 0 obj << +1511 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 641.43 141.858 650.341] +/Rect [119.552 641.43 234.141 650.341] /Subtype /Link -/A << /S /GoTo /D (quips) >> +/A << /S /GoTo /D (edit-custom-fields) >> >> endobj -1484 0 obj << +1512 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 641.43 537.983 650.341] /Subtype /Link -/A << /S /GoTo /D (quips) >> +/A << /S /GoTo /D (edit-custom-fields) >> >> endobj -1485 0 obj << +1513 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 628.478 227.905 637.39] +/Rect [119.552 628.478 239.112 637.39] /Subtype /Link -/A << /S /GoTo /D (groups) >> +/A << /S /GoTo /D (delete-custom-fields) >> >> endobj -1486 0 obj << +1514 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 628.478 537.983 637.39] /Subtype /Link -/A << /S /GoTo /D (groups) >> +/A << /S /GoTo /D (delete-custom-fields) >> >> endobj -1487 0 obj << +1515 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 615.527 215.571 624.438] +/Rect [95.641 615.527 169.594 624.438] /Subtype /Link -/A << /S /GoTo /D (1544) >> +/A << /S /GoTo /D (edit-values) >> >> endobj -1488 0 obj << +1516 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 615.527 537.983 624.438] /Subtype /Link -/A << /S /GoTo /D (1544) >> +/A << /S /GoTo /D (edit-values) >> >> endobj -1489 0 obj << +1517 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 602.575 257.085 611.487] +/Rect [119.552 602.575 264.367 611.487] /Subtype /Link -/A << /S /GoTo /D (1571) >> +/A << /S /GoTo /D (edit-values-list) >> >> endobj -1490 0 obj << +1518 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 602.575 537.983 611.487] /Subtype /Link -/A << /S /GoTo /D (1571) >> +/A << /S /GoTo /D (edit-values-list) >> >> endobj -1491 0 obj << +1519 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 589.624 302.205 598.535] +/Rect [119.552 589.624 233.105 598.535] /Subtype /Link -/A << /S /GoTo /D (1581) >> +/A << /S /GoTo /D (edit-values-delete) >> >> endobj -1492 0 obj << +1520 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 589.624 537.983 598.535] /Subtype /Link -/A << /S /GoTo /D (1581) >> +/A << /S /GoTo /D (edit-values-delete) >> >> endobj -1493 0 obj << +1521 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 576.673 315.485 585.584] +/Rect [95.641 576.673 144.448 585.584] /Subtype /Link -/A << /S /GoTo /D (1599) >> +/A << /S /GoTo /D (voting) >> >> endobj -1494 0 obj << +1522 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 576.673 537.983 585.584] /Subtype /Link -/A << /S /GoTo /D (1599) >> +/A << /S /GoTo /D (voting) >> >> endobj -1495 0 obj << +1523 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 563.721 350.016 572.633] +/Rect [95.641 563.721 141.858 572.633] /Subtype /Link -/A << /S /GoTo /D (1601) >> +/A << /S /GoTo /D (quips) >> >> endobj -1496 0 obj << +1524 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 563.721 537.983 572.633] /Subtype /Link -/A << /S /GoTo /D (1601) >> +/A << /S /GoTo /D (quips) >> >> endobj -1497 0 obj << +1525 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 550.77 365.238 559.681] +/Rect [95.641 550.77 227.905 559.681] /Subtype /Link -/A << /S /GoTo /D (1605) >> +/A << /S /GoTo /D (groups) >> >> endobj -1498 0 obj << +1526 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 550.77 537.983 559.681] /Subtype /Link -/A << /S /GoTo /D (1605) >> +/A << /S /GoTo /D (groups) >> >> endobj -1499 0 obj << +1527 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 537.818 338.718 546.73] +/Rect [119.552 537.818 215.571 546.73] /Subtype /Link -/A << /S /GoTo /D (1609) >> +/A << /S /GoTo /D (1659) >> >> endobj -1500 0 obj << +1528 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 537.818 537.983 546.73] /Subtype /Link -/A << /S /GoTo /D (1609) >> +/A << /S /GoTo /D (1659) >> >> endobj -1501 0 obj << +1529 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 524.867 229.309 533.778] +/Rect [119.552 524.867 257.085 533.778] /Subtype /Link -/A << /S /GoTo /D (upgrading) >> +/A << /S /GoTo /D (1686) >> >> endobj -1502 0 obj << +1530 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 524.867 537.983 533.778] /Subtype /Link -/A << /S /GoTo /D (upgrading) >> +/A << /S /GoTo /D (1686) >> >> endobj -1503 0 obj << +1531 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 513.973 226.649 520.827] +/Rect [119.552 511.915 302.205 520.827] /Subtype /Link -/A << /S /GoTo /D (upgrading-version-defns) >> +/A << /S /GoTo /D (1696) >> >> endobj -1504 0 obj << +1532 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 513.973 537.983 520.827] +/Rect [528.02 511.915 537.983 520.827] /Subtype /Link -/A << /S /GoTo /D (upgrading-version-defns) >> +/A << /S /GoTo /D (1696) >> >> endobj -1505 0 obj << +1533 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 498.964 294.973 507.875] +/Rect [119.552 498.964 315.485 507.875] /Subtype /Link -/A << /S /GoTo /D (upgrading-methods) >> +/A << /S /GoTo /D (1714) >> >> endobj -1506 0 obj << +1534 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 498.964 537.983 507.875] /Subtype /Link -/A << /S /GoTo /D (upgrading-methods) >> +/A << /S /GoTo /D (1714) >> >> endobj -1507 0 obj << +1535 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 486.013 269.379 494.924] +/Rect [143.462 486.013 350.016 494.924] /Subtype /Link -/A << /S /GoTo /D (upgrade-cvs) >> +/A << /S /GoTo /D (1716) >> >> endobj -1508 0 obj << +1536 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 486.013 537.983 494.924] /Subtype /Link -/A << /S /GoTo /D (upgrade-cvs) >> +/A << /S /GoTo /D (1716) >> >> endobj -1509 0 obj << +1537 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 473.061 290.121 481.973] +/Rect [143.462 473.061 365.238 481.973] /Subtype /Link -/A << /S /GoTo /D (upgrade-tarball) >> +/A << /S /GoTo /D (1720) >> >> endobj -1510 0 obj << +1538 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 473.061 537.983 481.973] /Subtype /Link -/A << /S /GoTo /D (upgrade-tarball) >> +/A << /S /GoTo /D (1720) >> >> endobj -1511 0 obj << +1539 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 460.11 279.88 469.021] +/Rect [143.462 460.11 338.718 469.021] /Subtype /Link -/A << /S /GoTo /D (upgrade-patches) >> +/A << /S /GoTo /D (1724) >> >> endobj -1512 0 obj << +1540 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 460.11 537.983 469.021] /Subtype /Link -/A << /S /GoTo /D (upgrade-patches) >> +/A << /S /GoTo /D (1724) >> >> endobj -1513 0 obj << +1541 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 447.158 255.152 456.07] +/Rect [95.641 447.158 229.309 456.07] /Subtype /Link -/A << /S /GoTo /D (upgrading-completion) >> +/A << /S /GoTo /D (upgrading) >> >> endobj -1514 0 obj << +1542 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 447.158 537.983 456.07] /Subtype /Link -/A << /S /GoTo /D (upgrading-completion) >> +/A << /S /GoTo /D (upgrading) >> >> endobj -1515 0 obj << +1543 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.731 431.95 154.48 440.837] +/Rect [119.552 436.264 226.649 443.118] /Subtype /Link -/A << /S /GoTo /D (security) >> +/A << /S /GoTo /D (upgrading-version-defns) >> >> endobj -1516 0 obj << +1544 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 431.95 537.983 440.837] +/Rect [528.02 436.264 537.983 443.118] /Subtype /Link -/A << /S /GoTo /D (security) >> +/A << /S /GoTo /D (upgrading-version-defns) >> >> endobj -1517 0 obj << +1545 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 416.473 184.746 425.385] +/Rect [119.552 421.255 251.825 430.167] /Subtype /Link -/A << /S /GoTo /D (security-os) >> +/A << /S /GoTo /D (upgrading-notifications) >> >> endobj -1518 0 obj << +1546 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 416.473 537.983 425.385] +/Rect [528.02 421.255 537.983 430.167] /Subtype /Link -/A << /S /GoTo /D (security-os) >> +/A << /S /GoTo /D (upgrading-notifications) >> >> endobj -1519 0 obj << +1547 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 405.579 197.329 412.433] +/Rect [119.552 408.304 294.973 417.215] /Subtype /Link -/A << /S /GoTo /D (security-os-ports) >> +/A << /S /GoTo /D (upgrading-methods) >> >> endobj -1520 0 obj << +1548 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 405.579 537.983 412.433] +/Rect [528.02 408.304 537.983 417.215] /Subtype /Link -/A << /S /GoTo /D (security-os-ports) >> +/A << /S /GoTo /D (upgrading-methods) >> >> endobj -1521 0 obj << +1549 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 390.57 235.217 399.482] +/Rect [143.462 395.353 269.379 404.264] /Subtype /Link -/A << /S /GoTo /D (security-os-accounts) >> +/A << /S /GoTo /D (upgrade-cvs) >> >> endobj -1522 0 obj << +1550 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 390.57 537.983 399.482] +/Rect [528.02 395.353 537.983 404.264] /Subtype /Link -/A << /S /GoTo /D (security-os-accounts) >> +/A << /S /GoTo /D (upgrade-cvs) >> >> endobj -1523 0 obj << +1551 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 379.588 211.048 386.53] +/Rect [143.462 382.401 290.121 391.312] /Subtype /Link -/A << /S /GoTo /D (security-os-chroot) >> +/A << /S /GoTo /D (upgrade-tarball) >> >> endobj -1526 0 obj << +1552 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 379.588 537.983 386.53] +/Rect [528.02 382.401 537.983 391.312] /Subtype /Link -/A << /S /GoTo /D (security-os-chroot) >> +/A << /S /GoTo /D (upgrade-tarball) >> >> endobj -1527 0 obj << +1553 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 364.668 145.733 373.579] +/Rect [143.462 369.45 279.88 378.361] /Subtype /Link -/A << /S /GoTo /D (security-mysql) >> +/A << /S /GoTo /D (upgrade-patches) >> >> endobj -1528 0 obj << +1554 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 364.668 537.983 373.579] +/Rect [528.02 369.45 537.983 378.361] /Subtype /Link -/A << /S /GoTo /D (security-mysql) >> +/A << /S /GoTo /D (upgrade-patches) >> >> endobj -1529 0 obj << +1555 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 351.716 263.172 360.628] +/Rect [119.552 356.498 255.152 365.41] /Subtype /Link -/A << /S /GoTo /D (security-mysql-account) >> +/A << /S /GoTo /D (upgrading-completion) >> >> endobj -1530 0 obj << +1556 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 351.716 537.983 360.628] +/Rect [528.02 356.498 537.983 365.41] /Subtype /Link -/A << /S /GoTo /D (security-mysql-account) >> +/A << /S /GoTo /D (upgrading-completion) >> >> endobj -1531 0 obj << +1557 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 338.765 321.663 347.676] +/Rect [71.731 341.29 154.48 350.177] /Subtype /Link -/A << /S /GoTo /D (security-mysql-root) >> +/A << /S /GoTo /D (security) >> >> endobj -1532 0 obj << +1558 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 338.765 537.983 347.676] +/Rect [528.02 341.29 537.983 350.177] /Subtype /Link -/A << /S /GoTo /D (security-mysql-root) >> +/A << /S /GoTo /D (security) >> >> endobj -1533 0 obj << +1559 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 327.871 209.922 334.725] +/Rect [95.641 325.813 184.746 334.725] /Subtype /Link -/A << /S /GoTo /D (security-mysql-network) >> +/A << /S /GoTo /D (security-os) >> >> endobj -1534 0 obj << +1560 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 327.871 537.983 334.725] +/Rect [528.02 325.813 537.983 334.725] /Subtype /Link -/A << /S /GoTo /D (security-mysql-network) >> +/A << /S /GoTo /D (security-os) >> >> endobj -1535 0 obj << +1561 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 314.919 157.768 321.773] +/Rect [119.552 314.919 197.329 321.773] /Subtype /Link -/A << /S /GoTo /D (security-webserver) >> +/A << /S /GoTo /D (security-os-ports) >> >> endobj -1536 0 obj << +1562 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 314.919 537.983 321.773] /Subtype /Link -/A << /S /GoTo /D (security-webserver) >> +/A << /S /GoTo /D (security-os-ports) >> >> endobj -1537 0 obj << +1563 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 299.91 373.596 308.822] +/Rect [119.552 299.91 235.217 308.822] /Subtype /Link -/A << /S /GoTo /D (security-webserver-access) >> +/A << /S /GoTo /D (security-os-accounts) >> >> endobj -1538 0 obj << +1564 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 299.91 537.983 308.822] /Subtype /Link -/A << /S /GoTo /D (security-webserver-access) >> +/A << /S /GoTo /D (security-os-accounts) >> >> endobj -1539 0 obj << +1565 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 286.959 307.406 295.87] +/Rect [119.552 288.928 211.048 295.87] /Subtype /Link -/A << /S /GoTo /D (security-webserver-mod-throttle) >> +/A << /S /GoTo /D (security-os-chroot) >> >> endobj -1540 0 obj << +1568 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 286.959 537.983 295.87] +/Rect [528.02 288.928 537.983 295.87] /Subtype /Link -/A << /S /GoTo /D (security-webserver-mod-throttle) >> +/A << /S /GoTo /D (security-os-chroot) >> >> endobj -1541 0 obj << +1569 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 274.008 146.839 282.919] +/Rect [95.641 274.008 145.733 282.919] /Subtype /Link -/A << /S /GoTo /D (security-bugzilla) >> +/A << /S /GoTo /D (security-mysql) >> >> endobj -1542 0 obj << +1570 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 274.008 537.983 282.919] /Subtype /Link -/A << /S /GoTo /D (security-bugzilla) >> +/A << /S /GoTo /D (security-mysql) >> >> endobj -1543 0 obj << +1571 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 261.056 317.935 269.968] +/Rect [119.552 261.056 263.172 269.968] /Subtype /Link -/A << /S /GoTo /D (security-bugzilla-charset) >> +/A << /S /GoTo /D (security-mysql-account) >> >> endobj -1544 0 obj << +1572 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 261.056 537.983 269.968] /Subtype /Link -/A << /S /GoTo /D (security-bugzilla-charset) >> +/A << /S /GoTo /D (security-mysql-account) >> >> endobj -1545 0 obj << +1573 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.731 245.848 143.421 254.735] +/Rect [119.552 248.105 321.663 257.016] /Subtype /Link -/A << /S /GoTo /D (using) >> +/A << /S /GoTo /D (security-mysql-root) >> >> endobj -1546 0 obj << +1574 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 245.848 537.983 254.735] +/Rect [528.02 248.105 537.983 257.016] /Subtype /Link -/A << /S /GoTo /D (using) >> +/A << /S /GoTo /D (security-mysql-root) >> >> endobj -1547 0 obj << +1575 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 232.429 162.331 239.283] +/Rect [119.552 237.211 209.922 244.065] /Subtype /Link -/A << /S /GoTo /D (using-intro) >> +/A << /S /GoTo /D (security-mysql-network) >> >> endobj -1548 0 obj << +1576 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 232.429 537.983 239.283] +/Rect [528.02 237.211 537.983 244.065] /Subtype /Link -/A << /S /GoTo /D (using-intro) >> +/A << /S /GoTo /D (security-mysql-network) >> >> endobj -1549 0 obj << +1577 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 217.42 218.489 226.331] +/Rect [95.641 224.259 157.768 231.113] /Subtype /Link -/A << /S /GoTo /D (myaccount) >> +/A << /S /GoTo /D (security-webserver) >> >> endobj -1550 0 obj << +1578 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 217.42 537.983 226.331] +/Rect [528.02 224.259 537.983 231.113] /Subtype /Link -/A << /S /GoTo /D (myaccount) >> +/A << /S /GoTo /D (security-webserver) >> >> endobj -1551 0 obj << +1579 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 204.468 186.958 213.38] +/Rect [119.552 209.25 373.596 218.162] /Subtype /Link -/A << /S /GoTo /D (bug_page) >> +/A << /S /GoTo /D (security-webserver-access) >> >> endobj -1552 0 obj << +1580 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 204.468 537.983 213.38] +/Rect [528.02 209.25 537.983 218.162] /Subtype /Link -/A << /S /GoTo /D (bug_page) >> +/A << /S /GoTo /D (security-webserver-access) >> >> endobj -1553 0 obj << +1581 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 191.517 192.209 200.428] +/Rect [119.552 196.299 307.406 205.21] /Subtype /Link -/A << /S /GoTo /D (lifecycle) >> +/A << /S /GoTo /D (security-webserver-mod-throttle) >> >> endobj -1554 0 obj << +1582 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 191.517 537.983 200.428] +/Rect [528.02 196.299 537.983 205.21] /Subtype /Link -/A << /S /GoTo /D (lifecycle) >> +/A << /S /GoTo /D (security-webserver-mod-throttle) >> >> endobj -1555 0 obj << +1583 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 178.565 189.997 187.477] +/Rect [95.641 183.348 146.839 192.259] /Subtype /Link -/A << /S /GoTo /D (query) >> +/A << /S /GoTo /D (security-bugzilla) >> >> endobj -1556 0 obj << +1584 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 178.565 537.983 187.477] +/Rect [528.02 183.348 537.983 192.259] /Subtype /Link -/A << /S /GoTo /D (query) >> +/A << /S /GoTo /D (security-bugzilla) >> >> endobj -1557 0 obj << +1585 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 167.671 206.166 174.525] +/Rect [119.552 170.396 317.935 179.308] /Subtype /Link -/A << /S /GoTo /D (boolean) >> +/A << /S /GoTo /D (security-bugzilla-charset) >> >> endobj -1558 0 obj << +1586 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 167.671 537.983 174.525] +/Rect [528.02 170.396 537.983 179.308] /Subtype /Link -/A << /S /GoTo /D (boolean) >> +/A << /S /GoTo /D (security-bugzilla-charset) >> >> endobj -1559 0 obj << +1587 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 154.72 260.263 161.574] +/Rect [71.731 155.188 143.421 164.075] /Subtype /Link -/A << /S /GoTo /D (pronouns) >> +/A << /S /GoTo /D (using) >> >> endobj -1560 0 obj << +1588 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 154.72 537.983 161.574] +/Rect [528.02 155.188 537.983 164.075] /Subtype /Link -/A << /S /GoTo /D (pronouns) >> +/A << /S /GoTo /D (using) >> >> endobj -1561 0 obj << +1589 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 139.711 212.164 148.623] +/Rect [95.641 141.768 162.331 148.623] /Subtype /Link -/A << /S /GoTo /D (negation) >> +/A << /S /GoTo /D (using-intro) >> >> endobj -1562 0 obj << +1590 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 139.711 537.983 148.623] +/Rect [528.02 141.768 537.983 148.623] /Subtype /Link -/A << /S /GoTo /D (negation) >> +/A << /S /GoTo /D (using-intro) >> >> endobj -1563 0 obj << +1591 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 126.76 238.664 135.671] +/Rect [95.641 126.76 218.489 135.671] /Subtype /Link -/A << /S /GoTo /D (multiplecharts) >> +/A << /S /GoTo /D (myaccount) >> >> endobj -1564 0 obj << +1592 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 126.76 537.983 135.671] /Subtype /Link -/A << /S /GoTo /D (multiplecharts) >> +/A << /S /GoTo /D (myaccount) >> >> endobj -1565 0 obj << +1593 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 114.182 194.251 122.72] +/Rect [95.641 113.808 186.958 122.72] /Subtype /Link -/A << /S /GoTo /D (quicksearch) >> +/A << /S /GoTo /D (bug_page) >> >> endobj -1566 0 obj << +1594 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 114.182 537.983 122.72] +/Rect [528.02 113.808 537.983 122.72] /Subtype /Link -/A << /S /GoTo /D (quicksearch) >> +/A << /S /GoTo /D (bug_page) >> >> endobj -1567 0 obj << +1595 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 100.857 182.933 109.768] +/Rect [95.641 100.857 192.209 109.768] /Subtype /Link -/A << /S /GoTo /D (list) >> +/A << /S /GoTo /D (lifecycle) >> >> endobj -1568 0 obj << +1596 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 100.857 537.983 109.768] /Subtype /Link -/A << /S /GoTo /D (list) >> +/A << /S /GoTo /D (lifecycle) >> >> endobj -1472 0 obj << -/D [1470 0 R /XYZ 71.731 729.265 null] +1500 0 obj << +/D [1498 0 R /XYZ 71.731 729.265 null] >> endobj -1469 0 obj << -/Font << /F27 1180 0 R /F32 1187 0 R /F35 1525 0 R /F33 1278 0 R >> +1497 0 obj << +/Font << /F27 1208 0 R /F32 1215 0 R /F35 1567 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1618 0 obj << -/Length 56109 +1646 0 obj << +/Length 57373 /Filter /FlateDecode >> stream -xڜ�O�%�}%���e�O��.I��l$ad2��h��@5��)���DV�s3����6��{T=�������n���~�t�<�m����r������77��������\�����ۇ���?�w}��o����\^n��>s��\6��n�/w�����������O߽\^������Cy���?��<\�/?�����������O�_����?�p���������?�����������O�n�����?���_��������_���?��?�~��������w/��n.��������h��?��Ǘ�����go�s�D��O�w77��[eͳh]�ֻ�ݣ��ϞXx`�>��;iݟ=�6�����κ?sbm�����1�I�x�����}�Һ?{bm��u���Һ?{bm��u�o�u����ϭۯ�O/O�:�e�<��]n���u���������ϞXx`}�H��쉵��[ﶏA��i���;Pn������色p����J��쉴�����_mƳ'�~n��>�[iϲuX�O�*�ƍgO� <�nÍ�j3�=�6���|��X��쉵��[n.���7�Y�.����j�ϞXx`}�<>Z��쉵���cx�_�Ƴ'�~n}�>�{��f<��x`�>�;kݟ=�6���}��k�x������1�_�GO���\��}����(+w��>��ܟ=�6����V�E��gO� <�>_n��u����ϭ�7��'�5n<��x`���<ʯ6��k����`���'�X���^~�ϞX���e��u<��x`�>�[�5n<{bm��u���k�x������1�X��쉵��Z�on.�/�k\�E� -<��^^�_�u���������Z�gO� <�>]� -�GO���\y�>��5ϲtX����Z�gO� <�n������ϞXx`�>��;iݟ=�6�s���1�J�x�����}�{iݟ=�6���}7Һ?{bm������b���'�~n����=�/sy����z{y~��2�gO� <�>\��u������1<�/s��k?��oý��3�e�<�nÝ��ϞXx`�>�K��艳p��3��_pƳ'�~n}�>����gٺ���gp#�̍gO� <�>\n_�:�=�6���tyz����k?�>�\n�䗹�,[������(���gO� <�nÃ��ϞXx`�>�{�en<{bm��֧�c��_pƳl]���c�����k���p�_�Ƴ'�X���F~�ϞX�����r}���,[�����h��=q�@�p���<{"m������d���'�~n}�>y|�gٺ��ۧ �O�쉵���c�����k��� �O�쉵��Zn��A��y�+���}Wkݟ=�6���}��$ϞXx`}�<�?gʳ'�~n��\n��u<��x`��<��<{bm����r�h���'�X����EZ�gO� ��z�}�8���l܁r���ۣ'��(���*���'�X���㓷���?B�������r����L]�|x������ͪ?�{��o{��3�W���[���/�^n?}��L�χ�������x��^����>�\��{�_����J�����x��m�~y��~�ஏw����^���쉵�����ӣ��ϞXx`}�~Ο�u����ϭO��� ��Y�.���1�?K��쉵���c�{����k���pk���'�~n}�>�['�eg���gp�J��쉴���3�����k�ϗ���?{bm��֗��v�����Y�.������Z�gO� <�>^n�u������1<�/8��k?�]n����Y�,ZW��u���u������1�>I��쉵���c�Z��쉵��[���p���Y�.������EZ�gO� <�>^��ֺ?{bm�����h��=z�,�����e���ϲtX����Z�gO� <�n��í��ϞXx`�>��;iݟ=�6�s���1�I�x�����}��Һ?{bm��u����x������1�X��쉵��[ﯗ��en<��x`��<<�/8��k����'kݟ=�6���|y�� -�gO� ����}��x�����}�ֺ?{bm��u��/��'��(���N~�ϞH���q�n�u<��x`�>���27�=�6���} -7ֺ?{bm����r�"�̍gO� ���tsyy�� ϲuX�.�Oֺ?{bm���a{^~�ϞXx`�>��en<{bm�����c����,[��u��䗹�쉵���c��_�Ƴ'�X���j���'��olÍ�27�e�<�n�t�>yb|;�}"q�}ׄ���]��&,m ���5!� -�]g�&lm �8��5akq��YǮ [��&ʚ]�.@�5qֱk��⮉��]�6wM�u우���k���5A��]g�&lm �8��5akq��YǮ [H�&J:vM��8�5q�}ׄ���]��&,m �8��5akq�DY�k����&�:vM��@�5qֱk��⮉��]�6wM�5�&h]��k�cׄ� �]g�&lm �8��5akq�DY�k����&�:vM��@�5qֱk��Ү���&�,�(��5Ae�p��9Ǯ K��&�:vM��@�5qֱk��⮉�f��wM�u우���k�cׄ� �]g�&lm �(kvMк�q��YǮ [��&�:vM��@�5qֱk��⮉��]��@�5qֱk��⮉��]�6�vM�t�5ag�p�D9�k����&�:vM��@�5qֱk��⮉��]�6wM�5�&h]��k�cׄ� �]g�&lm �8��5akq�DY�k����&�:vM��@�5qֱk��⮉��]�6wM�5�&h]��k�cׄ� �]'�wM�Y8�5qαk��⮉�f��wM�u우���k�cׄ� �]g�&lm �(kvMк�q��YǮ [��&�:vM��@�5qֱk��⮉�f��wM�u우���k�cׄ� �]g�&lm �(kvMк�i��I�]vwM�s우���k�cׄ� �]eͮ Z �8��5akq��YǮ [��&�:vM��@�51ֹkB���&�:vM��@�5qֱk��⮉��]�6wM�5�&h]��k�cׄ� �]g�&lm �8��5aki�DIǮ :G�&N��p�k�cׄ� �]��0�&�ߞ���]x��o�8�(�1���73��W�ƈy&�&ױm�_���Ͽ�6�M~�������$���<����{z�~�z��m��<x��{��4��@���r���I���@N�u�yd]���)k�<�6��<eM���r���I���@N�u�yd]���)k�<�6�<%i:�i�r&�Ci9�3֙�ur���I���@N�5iZ�i��&�Ck9�3֙�ur���I���@N�5iZ�i��&�Ck9�3֙�ur���I���@N�5iZ�i��&�Ck9�3֙�uR���{����0L�p�yh,�yʙ4� �4OX��<��@N�5iZ�i��&�Ck9�S֤yhm �y�:�<�.@N�5iZ�i��&�Ck9�S֤yhm �y�:�<�.@N�5iZ�i��&�Ck9�S֤yhm �yF�4����4O)G����q���I�P�@N�5iZ�i���4����<eM���r���I���@N�5iZ�i���4����<eM���r���I���@N�5iZ�i���4����<eM���r���I���@L�t�y�,�yF�4����4O9�桴���)k�<�6��<eM���r�g�3�#��4OY�桵���)k�<�6��<eM���r�g�3�#��4OY�桵���)k�<�6��<eM���r�'�oiXW �yʚ4� �4OY�桵���)�H��Y8N�s�y$]���)k�<�6��<eM���r���I���@N�u�yd]���)k�<�6��<eM���r���I���@N�u�yd]���)k�<�6��<eM���r���I���@N�u�yd]���)k�<�6�<%i:�i�r&�Ci9�3֙�ur���I���@N�5iZ�i��&�Ck9�3֙�ur���I���@N�5iZ�i��&�Ck9�3֙�ur���I���@N�5iZ�i��&�Ck9�3֙�ub���#�Cg�8�SΤy(m �yʚ4� �4�Xg�G��i��&�Ck9�S֤yhm �yʚ4� �4OX��<��@N�5iZ�i��&�Ck9�S֤yhm �y�:�<�.@N�5iZ�i��&�Ck9�S֤yhm �yF�4����4O)G����q���I�P�@N�{2���{�i���8�;~�%ͻ=I�_.��/��g��ݎ4������/#������o?�����E��L��^���wޏߋ����(�K"�=�w�}��}|H���@N�u&rd]���)k9�6�9eM"��r"��I���@N�u&rd]���)k9�69%�:lj�r&�Ci9�3֙ȑur"��I���@N�5�Zȉ��&�Ck9�3֙ȑur"��I���@N�5�Zȉ��&�Ck9�3֙ȑur"��I���@N�5�Zȉ��&�Ck9�3֙ȑuR"��{"���0L�p$rh,'rʙD� �DNX�9��@N�5�Zȉ��&�Ck9�S�$rhm 'r�:9�.@N�5�Zȉ��&�Ck9�S�$rhm 'r�:9�.@N�5�Zȉ��&�Ck9�S�$rhm &rF�D����DN)G"���q"��I�P�@N�5�Zȉ���D���9eM"��r"��I���@N�5�Zȉ���D���9eM"��r"��I���@N�5�Zȉ���D���9eM"��r"��I���@L�t$r�,&rF�D����DN9�ȡ����)k9�6�9eM"��r"g�3�#��DNY�ȡ����)k9�6�9eM"��r"g�3�#��DNY�ȡ����)k9�6�9eM"��r"'�o�XW 'rʚD� �DNY�ȡ����)�H��Y8N�s&r$]���)k9�6�9eM"��r"��I���@N�u&rd]���)k9�6�9eM"��r"��I���@N�u&rd]���)k9�6�9eM"��r"��I���@N�u&rd]���)k9�69%�:lj�r&�Ci9�3֙ȑur"��I���@N�5�Zȉ��&�Ck9�3֙ȑur"��I���@N�5�Zȉ��&�Ck9�3֙ȑur"��I���@N�5�Zȉ��&�Ck9�3֙ȑub"��#�Cg�8�S�$r(m 'rʚD� �D�Xg"G�ȉ��&�Ck9�S�$rhm 'rʚD� �DNX�9��@N�5�Zȉ��&�Ck9�S�$rhm 'r�:9�.@N�5�Zȉ��&�Ck9�S�$rhm &rF�D����DN)G"���q"��I�P�@N��.���{�ܻ�x�9L���۟ܽ��)|������[�������/4��#{ �4�����������_�w�>��x?~��������������ۍ�[z�r��/�x�{��E>��ϞXx`}�<��ٖ��ϞX����z�{���,[��u�^O2�u������1��ٖ��ϞXx`�>�[kݟ=�6�s���1�:��(;w��>��U:�gO� <�n�����ϞXx`}�<�؟���k?��\/�����x����zwyz����k����eݟ=�6���}Һ?{bm������1�;k�E� -<�n�ݣ��ϞXx`�>��'iݟ=�6���}Wkݟ=�6�s�u�nܗ�<��x`��<��H��쉵������Z�gO� <�>_�O�GO���\y{�\���<��x`�>�Gkݟ=�6���}�Һ?{bm��u���u�������c����,[��u|�le�7�Fk�p+k�E��@^Q֬�����.b�s]����E�5�"hm ��(k�E��@^Q֬�����.b�s]����E�5�"hm ��(�XAg�x]D9�.���u�.@^Q֬�����.��YAky]DY�.���u�.@^Q֬�����.��YAky]DY�.���u�.@^Q֬�����.��YAky]DY�.���u�.@ZQ�}]��a�.��c]���u�̺J��"���.���"ʚu�6��E�5�"hm ��(k�E��@^1ֹ.B���"ʚu�6��E�5�"hm ��(k�E��@^1ֹ.B���"ʚu�6��E�5�"hm ��(k�E��@\1Ҭ���q�.��c]���u�̺J��"ʚu�6��E�u���uf]� �ueͺZ��"ʚu�6��E�u���uf]� �ueͺZ��"ʚu�6��E�u���uf]� �ueͺZ��"J:�E�Y8\1ʬ���q�.��YAiy]DY�.��f]� �uc��"d]��.��YAky]DY�.��f]� �uc��"d]��.��YAky]DY�.��f]� �ua}[� -�ueͺZ��"ʚu�6�E�t����p�.b�s]����E�5�"hm ��(k�E��@^Q֬�����.b�s]����E�5�"hm ��(k�E��@^Q֬�����.b�s]����E�5�"hm ��(k�E��@^Q֬�����.b�s]����E�5�"hm ��(�XAg�x]D9�.���u�.@^Q֬�����.��YAky]DY�.���u�.@^Q֬�����.��YAky]DY�.���u�.@^Q֬�����.��YAky]DY�.���u�.@\Qұ.����rf]� �ueͺZ��"�:�EȺ�y]DY�.��f]� �ueͺZ��"���.���"ʚu�6��E�5�"hm ��(k�E��@^1ֹ.B���"ʚu�6��E�5�"hm ��(k�E��@\1Ҭ���q�.��c]���u�̺J��"��q�.�ﱯ��{ X9~��p_O�����p�g�/r#������?������������?}������������r����o�y�n������L�酓��{����@�� ��&Gk9W�$�hm '�ʚ� ��XgN�� ��&Gk9W�$�hm &�J:pt�p� 8I '�ʚ� �\Y�������+kp�6�pc� 8Y '�ʚ� �\Y�������+kp�6�pc� 8Y '�ʚ� �\Y�������+kp�6�pc� 8Y '�ʚ� �\IG���q��I�Q�@N��u&�d]���+kp�6�peM��r��I���@N��u&�d]���+kp�6�peM��r��I���@N��u&�d]���+kp�6�peM��r��I���@N��u&�d]���+瞀��=p% 8� �r&Gi9ַ�+�peM��r��I���@N��5 8Z� ������peM��r��I���@N��5 8Z� ������peM��r��I���@N��5 8Z� ��&'g�0Wʑ���p��+gp�6�peM��rn�3'��\Y�������+kp�6�peM��rn�3'��\Y�������+kp�6�peM��rn�3'��\Y�������+kp�6p% 8:� �Q&'e�8W�$�(m '�ʚ� �\Y��������L�ɺ�9W�$�hm '�ʚ� �\Y��������L�ɺ�9W�$�hm '�ʚ� �\Y��������[�� ��&Gk9W�$�hm &�J:pt�p� 8I '�ʚ� �\Y�������+kp�6�pc� 8Y '�ʚ� �\Y�������+kp�6�pc� 8Y '�ʚ� �\Y�������+kp�6�pc� 8Y '�ʚ� �\IG���q��I�Q�@N��u&�d]���+kp�6�peM��r��I���@N��u&�d]���+kp�6�peM��r��I���@N��u&�d]���+kp�6�peM��r��I���@N��u&�d]���+�H��Y8N��3 8J� ��&Gk97֙��ur��I���@N��5 8Z� ��&Gk9ַ�+�peM��r��I���@N��5 8Z� ������peM��r��I���@N��5 8Z� ��&'g�0Wʑ���p��+gp�6���Y%��{��5�� ��{����~{�$ෟ�ۿ����ớ�+���E�x(ϼ%����W�?}�������O������j�n����o�����O�����O���'�����������O�.@>�T����|���9�Dk��SYs�������O�.@>�T����|���9�Dk��SYs������������O�ǟ�,*g�?Q�@>�T����|�i�������?�5ǟhm *k�?��@>�T����|�i�������?�5ǟhm *k�?��@>�T����|�i�������?�5ǟhm *k�?��@<�T�q������Q�������O���'J�ǟʚ�O�6��?�5ǟhm �<�$���Oe��'Z�ǟʚ�O�6��?�5ǟhm �<�$���Oe��'Z�ǟʚ�O�6��?�5ǟhm -���'XW *k�?��@>�T����x���������O�ǟ$]�|���9�Dk��SYs�������� ��Oc�ǟd]�|���9�Dk��SYs�������� ��Oc�ǟd]�|���9�Dk��SYs�������� ��Oc�ǟd]�|���9�Dk��SI��':�ǟʙ�O�6��?�u�u����� ��Oe��'Z�ǟʚ�O�6��?�u�u����� ��Oe��'Z�ǟʚ�O�6��?�u�u����� ��Oe��'Z�ǟʚ�O�6��?�u�u��Ot��?�3ǟ(m *k�?��@>�4�y�I��ǟʚ�O�6��?�5ǟhm *k�?��@>�ַ�O��@>�T����|���9�Dk��SYs�������O�.@>�T����|���9�Dk��SYs������������O�ǟ�,*g�?Q�@>��;Dq����{ 8�<~����zr���'�����?�3oǟ������e�|���_���?�����O_~�������������e������������?<�p�p�����ǟ�����y�?�y����y|���E�t� �� e��Zȧ�:O7Ⱥ��tCYs����醲�t� �� %��,�neN7H�8>�PΜn���|���9�@k�tCYs����醱�� �.@>�P֜n���|���9�@k�tCYs����醱�� �.@>�P֜n���|���9�@k�tCYs����醰��n�u�醲�t� �� e��Z��J:N7�Y8>�0�y�A�ȧʚ� �6�O7�5�hm �n(kN7��@>�0�y�A�ȧʚ� �6�O7�5�hm �n(kN7��@>�0�y�A�ȧʚ� �6�O7�5�hm �n(kN7��@>�0�y�A�ȧʚ� �6O7�t�n��p|���9�@i�t�X��Y �n(kN7��@>�P֜n���|���9�@k�t�X��Y �n(kN7��@>�P֜n���|���9�@k�t�X��Y �n(kN7��@>�P֜n���|���9�@k�t�X��Y �n(�8�@g��tC9s����醲�t� �� c��d]�|���9�@k�tCYs����醲�t� �� a};��� -�� e��Zȧʚ� �6�O7�5�hm �n�<� ��� e��Zȧʚ� �6�O7�5�hm �niN7��8<�P�q������r�t� �� � ����ƻ׀Ӎ���+w�n�/Ow�|�1�y;ݸ�����������/�x����ۗ�s����X��������q�����������>�=����������~`�����DZ�a�:'�Ⱥ�y"LY3���D��f"� �0e�DZ�a�:'�Ⱥ�y"LY3���D��f"� �0e�DZ�aF��0r6'rL���p<���Ciy"LY3���D��Ή0�.@�S�L����<���Cky"LY3���D��Ή0�.@�S�ܙ���|g���3Ek��TYsg���;S�.@�3U�ܙ���|g���3Ek��TIǝ):�w�F�;SR6��L�3w�(m ߙ*k�L��@�3U�ܙ���|gj��Δ���L�5w�hm ߙ*k�L��@�3U�ܙ���|gj��Δ���L�5w�hm ߙ*k�L��@�3U�ܙ���|g*�ow�`]�|g���3Ek��TYsg��❩��;St��L�sޙ�t��� �;Se͝)Z�w�ʚ;S�6��L�uޙ�u��� �;Se͝)Z�w�ʚ;S�6��L�uޙ�u��� �;Se͝)Z�w�ʚ;S�6��L�uޙ�u��� �;S%w��,ߙ*g�LQ�@�35�ygJ��w�ʚ;S�6��L�5w�hm ߙ*k�L��@�35�ygJ��w�ʚ;S�6��L�5w�hm ߙ*k�L��@�35�ygJ��w�ʚ;S�6��L�5w�hm ߙ*k�L��@�35�ygJ��w�J:�L�Y8�3U�ܙ���|g���3Ek���X�)Y ߙ*k�L��@�3U�ܙ���|g���3Ek��TX��L����TYsg����� �;Se͝)Z�w��:�Lɺ���TYsg����� �;Se͝)Z�w�F�;Sr6�L�rܙ��p|g���3Ei�Δ�ŝ)��~g��5����=��������۬+ޙ晷;��KJ������yj���?����_���v^�OY��o?��u|�؟�$�N��y~���k~�y|<::�Y�(�����Y�'�q|V���Y�����6�� -�t?+`g��@)�Y*�g�9� -X�@<+p�qV���Y�����6� -�5gh]�xV�㬀� ijgglm �8�8+`k�@YsV���g�:� -��@<+p�qV���Y�����6� -�u��u�Y�����6� -�u����tV��Y;�gʙ��.@<+p�qV���Y�����6� -�u����xV��9+@�ijgglm �8�8+`k��Y�Y[�gʚ��.@<+p�qV���Y�����6� -�u����xV��9+@�ijgglm �8�~V����Y�s���6� -�5gh]�xV�㬀� ijgglm �8�8+`k�@YsV���g�:� -��@<+p�qV���Y�����6� -�5gh]�xV�㬀� ijgglm �8�8+`k�@YsV��HgN����pxV��㬀� ijgglm �(k� -к���Y�Y[�g�:� -��@<+p�qV���Y��γ��@<+p�qV���Y�����6� -�u����xV��9+@�ijgglm �8�8+`k��Y�Y[HgJ:� -��8:+p������ó�g,m ����}~V������q|V�����Wm� �~���g㙷���qV�~��/o�z��:w���_N�n_^�_6��{�Z�_��V�h�����t���C�X��W�]����y�j����뾫�c��� ġ.gC]lm u)k��к�q��Y�P[�C]�:����@�r�1����P��f�����uu���8��c��� ġ.gC]lm u)��Bg�h��)��.V���su���8��c��� ġ.e�PZ u9��bkq��Y�P[�C]�:����@�R�u�u�P����.�6���uu���8��c��� ġ.e��d]�|Q����Ek��VYsQ���E����Zt/j�2��l_�*g.jQ�@��U�\Ԣ��|Q����Ek���X�E-Y _�*k.j��@��U�\Ԣ��|Q����Ek���X�E-Y _�*k.j��@��U�\Ԣ��|Q����Ek��VX�.j����VYsQ���E���� ċZ%��,_�缨%��Ze�E-Z��ʚ�Z�6�/j�5�hm _�뼨%��Ze�E-Z��ʚ�Z�6�/j�5�hm _�뼨%��Ze�E-Z��ʚ�Z�6�/j�5�hm _�뼨%��Ze�E-Z��J:.j�Y8��U�\Ԣ��|Qk��/j�5�hm _�*k.j��@��U�\Ԣ��|Qk��/j�5�hm _�*k.j��@��U�\Ԣ��|Qk��/j�5�hm _�*k.j��@��U�\Ԣ��|Qk�/j�t\Ԣ�p|Q����Ei��VYsQ���E��Z�.@��U�\Ԣ��|Q����Ek��VYsQ���E���]Ԃu�E���� �Ze�E-Z��ʚ�Z�6�/j�u^Ԓu�E���� �Ze�E-Z��ʚ�Z�6/j�4��l^�*帨Ee���V9sQ���E�����/j߽����E��{��C]�o����E�x����1��������_�i���O�����ˇ���o��_���w�k~R_��/�~�?�<���p��"���w_���쉵�և������ϞXx`}��_�u����ϭ��ҽ����Xdzl]���c���'O��a��_�?�o��w�|�ܽ��@9�gO� <��G���v���W�ʚ+w�6��ܕ5W�hm _�+k����@�r7�y�N��W�ʚ+w�6��ܕ5W�hm _�+k����@�r7�y�N��W�ʚ+w�6��ܕ5W�hm _�+k����@�r7�\���qx宔�����+w�̕;J�W�ʚ+w�6��܍u^��u��� �+we͕;Z�W�ʚ+w�6��܍u^��u��� �+we͕;Z�W�ʚ+w�6��܍u^��u��� �+we͕;Z�W�J:���Y8�r7�\���q|宜�rGi��]Ys����� �+wc�W�d]�|宬�rGk��]Ys����� �+wc�W�d]�|宬�rGk��]Ys����� �+wa}�r� -�+we͕;Z�W�ʚ+w�6�ܕt\���p|�n��ʝ���ܕ5W�hm _�+k����@�rW�\����|�n��ʝ���ܕ5W�hm _�+k����@�rW�\����|�n��ʝ���ܕ5W�hm _�+k����@�rW�\����|�n��ʝ���ܕ5W�hm ^�+�rGg���]9s���+w�.@�rW�\����|宬�rGk��]Ys���+w�.@�rW�\����|宬�rGk��]Ys���+w�.@�rW�\����|宬�rGk��]Ys���+w�.@�rW�q����r��� �+we͕;Z�W��:��ɺ���]Ys����� �+we͕;Z�W���v���W�ʚ+w�6��ܕ5W�hm _�+k����@�r7�y�N��W�ʚ+w�6��ܕ5W�hm _�+k����@�r7�\���qx宔�����+w�̕;J�W�����;��~���5����=��+����/�k���x����)ߎ��/?���ͨ���_������~���?�p����>��>>_n_(oo����zt������~�y������[�������u<��x`�~n��u�����������ϞXx`�>��Giݟ=�6���� �:� �.@&�5�Z����&�@k9�P�hm �:� �.@ -&�s&������`���`B9L���L�[0�����&�@k9�P�hm ʚ`� �`�Xg0A�����&�@k9�P�hm ʚ`� �`�Xg0A�����&�@k9�P�hm ʚ`� �`�HL��qL(�&PY8&�3�J����&�@k9�0�L�ur0�� &��@&�5�Z����&�@k9�0�L�ur0�� &��@&�5�Z����&�@k9�0�L�ur0�� &��@&�5�Z�����`���`�(L��qL(g� �6�� eM0��r0�� &��@&�ud]�L(k� �6�� eM0��r0�� &��@&�ud]�L(k� �6�� eM0��r0�� &��@&��-��� -�`BYL���L(k� �6� %�:���q�`���� eM0��r0�� &��@&�5�Z�����`���� eM0��r0�� &��@&�5�Z�����`���� eM0��r0�� &��@&�5�Z�����`���� eM0��b0��#�@g�8�P�(m �:� �.@&�5�Z����&�@k9�P�hm �:� �.@&�5�Z����&�@k9�P�hm �:� �.@&�5�Z����&�@k9�P�hm �:� �.@&�t�,ʙ`� �`BYL���L�&Ⱥ�9�P�hm ʚ`� �`BYL���L�[0�����&�@k9�P�hm ʚ`� �`�Xg0A�����&�@k9�P�hm ʚ`� �`�HL��qL(�&PY8&�3�J��]��`�c&������^������~���U���-���z���3yd�%�G*�?����_�����p���O�����ק����W�7��B�����6��twy�v�/�����<^�^�P��|bݟ=�6���gݟ=�6�s����~����l܁r��W�ܟ=�6���}7ֺ?{bm������b~�gO� ���r�##cϲuX�.OOֺ?{bm����r��?�+��쉵���cx�Ceݟ=�6��V�f��5ϢuX����QZ�gO� <�n�퓴�ϞXx`�>����ϞX����}7��:�e�<��]_^�u��������l���'�X�/��'�ۣ'��}���^�O�N�e�<�n�����ϞXx`�>��[iݟ=�6���} -�wҺ?{bm��ֻ�c����,[��u�n�u������1\���쉵���c�����k?��_/7/���x����zwyx�_pƳ'�X/7Oֺ?{bm�����`ϞX���a����,[��u��u������1�_$�GO��;Pn�����3�=�6�s����J�x�����}W�en<{bm��u�n�u�����X�P��R���<Ka�s����g)�5�hm �R(kf)��@��P��R���<Ka�s����g)�5�hm �R(kf)��@��P��R���<Ka�s����f)�s��@�{�R(ᘥ@c�x�B93K���,����R�u�,��f�� �Y -e�,ZȳʚY -�6�g)�u�R�u�,��f�� �Y -e�,ZȳʚY -�6�g)�u�R�u�,��f�� �Y -e�,ZȳʚY -�6g)�4��l�R(嘥@e�x�B93K���,��f�� �Y -c��d]�<K����@ky�BY3K���,��f�� �Y -c��d]�<K����@ky�BY3K���,��f�� �Y -c��d]�<K����@ky�BY3K���,���Y -tg)�2��l�R(gf)P�@��P��R���<K����@ky��X�,Y �R(kf)��@��P��R���<K����@ky��X�,Y �R(kf)��@��P��R���<K����@ky�BX�f)��y�BY3K���,��f�� �Y -%��,�R眥 ��Y -e�,ZȳʚY -�6�g)�5�hm �R뜥 ��Y -e�,ZȳʚY -�6�g)�5�hm �R뜥 ��Y -e�,ZȳʚY -�6�g)�5�hm �R뜥 ��Y -e�,Z��J:f)�Y8��P��R���<Ka�s����g)�5�hm �R(kf)��@��P��R���<Ka�s����g)�5�hm �R(kf)��@��P��R���<Ka�s����g)�5�hm �R(kf)��@��P��R���<Ka�s���g)�t�R��p<K����@iy�BY3K���,���Y -�.@��P��R���<K����@ky�BY3K���,����R�u�,��f�� �Y -e�,ZȳʚY -�6�g)�u�R�u�,��f�� �Y -e�,ZȳʚY -�6g)�4��l�R(嘥@e�x�B93K���,�����g)�R����ϗ�����y}����F������z<�g2Lq��o���矾�˷o���������O� �ɻ\��|����k�h��kG�_�Y�6�Y%�,:�Ѭq�h����YeM4��r4���f��@�f�5�,Z�Ѭ��h����YeM4��r4���f��@�f�5�,Z�Ѭ��h����YeM4��r4���f��@�f�5�,Z�Ѭ��h����YeM4��b4��#�Eg�8�U�D�(m G��:�Y�.@�f�5�,Z�Ѭ�&�Ek9�U�D�hm G��:�Y�.@�f�5�,Z�Ѭ�&�Ek9�U�D�hm G��:�Y�.@�f�5�,Z�Ѭ�&�Ek9�U�D�hm G��:�Y�.@�f�s�f���Ѭ�h���hV9͢��� -�[4��Ѭ�&�Ek9�U�D�hm G�ʚh� �h�Xg4K��Ѭ�&�Ek9�U�D�hm G�ʚh� �h�Xg4K��Ѭ�&�Ek9�U�D�hm G�ʚh� �h�H͒�q�*�fQY8�f�3�,J�Ѭ�&�Ek9�5�͒ur4���f��@�f�5�,Z�Ѭ�&�Ek9�5�͒ur4���f��@�f�5�,Z�Ѭ�&�Ek9�5�͒ur4���f��@�f�5�,Z�Ѭ��h���h�(͒�q�*g�Y�6��YeM4��r4���f��@�f�uF�d]��*k�Y�6��YeM4��r4���f��@�f�uF�d]��*k�Y�6��YeM4��r4���f��@�f��-�� -�hVY͢���*k�Y�6�Y%�,:�Ѭq�h����YeM4��r4���f��@�f�5�,Z�Ѭ��h����YeM4��r4���f��@�f�5�,Z�Ѭ��h����YeM4��r4���f��@�f�5�,Z�Ѭ��h����YeM4��b4��#�Eg�8�U�D�(m G��:�Y�.@�f�5�,Z�Ѭ�&�Ek9�U�D�hm G��:�Y�.@�f�5�,Z�Ѭ�&�Ek9�U�D�hm G��:�Y�.@�f�5�,Z�Ѭ�&�Ek9�U�D�hm G��:�Y�.@�f�tD��,G�ʙh� �hVY͢����fɺ�9�U�D�hm G�ʚh� �hVY͢��� -�[4��Ѭ�&�Ek9�U�D�hm G�ʚh� �h�Xg4K��Ѭ�&�Ek9�U�D�hm G�ʚh� �h�H͒�q�*�fQY8�f�3�,J���q���Y|�=�}�����ޞD������-G��D��#������/�������~�����;�g�����n�����-���ݻ��/����������[_�������5��� �o}�����hm �ka}���`]�����5��� �o}�����hm �keͷ�Fk�[_����d]�����5?Z�����Gk��W�Q�p\���I����W�T�hm W�ʚ�� �_YS\���ɺ���W�T�hm W�ʚ�� �_YS\���ɺ���W�T�hm W�ʚ�� �_YS\���ɺ���W�T�hm V�J:*~t�+~�Lŏ�r�o���'��_YS\�+k*~�6�+~eMŏ�r�o���'��_YS\�+k*~�6�+~eMŏ�r�o���'��_YS\�+k*~�6�+~eMŏ�r�o���'���_9����aX�+���X8���3?J����U�`]�\�+k*~�6�+~eMŏ�rů�����@���uV�d]�\�+k*~�6�+~eMŏ�rů�����@���uV�d]�\�+k*~�6�+~eMŏ�rů�����@���4?9��R�����_9S\�+k*~�6�+~c�?Y W�ʚ�� �_YS\�+k*~�6�+~c�?Y W�ʚ�� �_YS\�+k*~�6�+~c�?Y W�ʚ�� �_YSX�+���Y8���2?)��r��Gi��W�T�hm W�ʚ�� ��Xg�O������Gk��W�T�hm W�ʚ�� ��Xg�O������Gk��W�T�hm W�ʚ�� �_X�*~��@���5?Z�����Gk��W�Q�p\���I����W�T�hm W�ʚ�� �_YS\���ɺ���W�T�hm W�ʚ�� �_YS\���ɺ���W�T�hm W�ʚ�� �_YS\���ɺ���W�T�hm V�J:*~t�+~�Lŏ�r�o���'��_YS\�+k*~�6�+~eMŏ�r�o���'��_YS\�+k*~�6�+~eMŏ�r�o���'��_YS\�+k*~�6�+~eMŏ�r�o���'�Ċ_IGŏ��qů���Q�@���5?Z���Ί���+~eMŏ�rů�����@���5?Z����U�`]�\�+k*~�6�+~eMŏ�rů�����@���uV�d]�\�+k*~�6�+~eMŏ�rů�����@���4?9��R�����_9S\�������+�w���{��������|�<���nT���˿~���/_�������o��~������|��1��~~�{��X�?��~�t��c}������8�X�Y8�X�sv�$]�ܱ*k:V�6�;VeMNJ�rǪ��X��@�X�uv�d]�ܱ*k:V�6�;VeMNJ�rǪ��X��@�X�uv�d]�ܱ*k:V�6�;VeMNJ�rǪ��X��@�X�uv�d]�ܱ*k:V�6;V%+:��r�cEi�c5�ٱ�urǪ��X��@�X�5+Z����cEk�c5�ٱ�urǪ��X��@�X�5+Z����cEk�c5�ٱ�urǪ��X��@�X�5+Z����cEk�c5�ٱ�uRǪ�{NJ��0�X�pt�h,w�ʙ�� �UX�:V��@�X�5+Z����cEk�cU�t�hm w��:;V�.@�X�5+Z����cEk�cU�t�hm w��:;V�.@�X�5+Z����cEk�cU�t�hm v�F�����ÎU)GNJ��qǪ��XQ�@�X�5+Z���Ύ���;VeMNJ�rǪ��X��@�X�5+Z���Ύ���;VeMNJ�rǪ��X��@�X�5+Z���Ύ���;VeMNJ�rǪ��X��@�X�tt��,v�F������U9ӱ���ܱ*k:V�6�;VeMNJ�r�j��c%��UYӱ���ܱ*k:V�6�;VeMNJ�r�j��c%��UYӱ���ܱ*k:V�6�;VeMNJ�r�*�o+XW w�ʚ�� �UYӱ���ر*��X�Y8�X�sv�$]�ܱ*k:V�6�;VeMNJ�rǪ��X��@�X�uv�d]�ܱ*k:V�6�;VeMNJ�rǪ��X��@�X�uv�d]�ܱ*k:V�6�;VeMNJ�rǪ��X��@�X�uv�d]�ܱ*k:V�6;V%+:��r�cEi�c5�ٱ�urǪ��X��@�X�5+Z����cEk�c5�ٱ�urǪ��X��@�X�5+Z����cEk�c5�ٱ�urǪ��X��@�X�5+Z����cEk�c5�ٱ�ubǪ��cEg�cU�t�(m w�ʚ�� ��Xg�J�����cEk�cU�t�hm w�ʚ�� �UX�:V��@�X�5+Z����cEk�cU�t�hm w��:;V�.@�X�5+Z����cEk�cU�t�hm v�F�����ÎU)GNJ��qǪ��XQ�@�X�3Lձ�{���x�;�X���۟ܽ��)|7��������xԾ|�B�<�W�/�w��O��^������������~��/?����_?�:_{����>]��4���y���6����qs��bs鬣�dk��T�4�h]��\:�h.��@l.�u4�lm 6��:�K�6�KeMs���ͥ��播 ���YGs��bs鬣�dk��T�4�h]��\:�h.��@j.�to.�Y8l.�s4�,m 6�ʚ���Kg�%[�ͥ��播 ���YGs��bs��i.Ѻ���t��\����\:�h.��@l.�u4�lm 6�ʚ���Kg�%[�ͥ��播 ���YGs��bs��i.Ѻ���t�o�%�è�t½�dct��\����\�l.ɺ��t��\����\:�h.��@l.�u4�lm 6�ʚ���Kg�%[�ͥ��播 ���YGs��bs��i.Ѻ���t��\����\:�h.��@l.�u4�lm 5�J:�Kt6��K�ܛKV�K��%K�ͥ��播 ��RY�\�ubs鬣�dk��t��\����\:�h.��@l.�5�%Z 6��:�K�6�Kg�%[�ͥ��播 ��RY�\�ubs鬣�dk��t��\����\:��\��p�\*�h.Q�8l.�s4�,m 6��:�K�6�Kg�%[�ͥ���D����YGs��bs鬣�dk��t��\����\*k�K�.@l.�u4�lm 6��:�K�6�Kg�%[�ͥ��撬+�Kg�%[�ͥ��播 ���I�撝���R9�\�tbs鬣�dk��t��\����\:�h.��@l.�5�%Z 6��:�K�6�Kg�%[�ͥ��播 ��RY�\�ubs鬣�dk��t��\����\:�h.��@l.�5�%Z 6��:�K�6��K'ݛKv�K��%K�ͥ���D����YGs��bs鬣�dk��t��\����\*k�K�.@l.�u4�lm 6��:�K�6�Kg�%[�ͥ���D����YGs��bs鬣�dk��t��\����\*k�K�.@j.�to.�Y8l.�s4�,m 6��:�K�6�KeMs���ͥ��播 ���YGs��bs鬣�dk��4��\�ubs鬣�dk��t��\����\:�h.��@l.�5�%Z 6��:�K�6�Kg�%[�ͥ��播 ��RIGs���Qs�{s���as霣�di���N�4��ߞy���%���\^���H��xdo.����Q����/�_��_����/_���˯��^��ky~�i{�|����r��v}~��ݜ�fz����/�|yz��E>��ϞX����z�}���u<��x`��<=Y��쉵������������'�X������ʺ?{bm���7��p�y�+���}w�Һ?{bm��u�^����'�X���j���'�|_��c�yv��,[���n��䋴�ϞXx`ݿѲ�������wnv��;7��p����3߹��s��fE�� �e͊�Z�+ʚ�6�W�u��ufE�� �e͊�Z�+ʚ�6�W�u��ufE�� �e͊�Z�+ʚ�6�W�u��ufE�� �%+�,�(gVP�@^0ֹ"@��+ʚ�6�W�5+hm �(kV��@^0ֹ"@��+ʚ�6�W�5+hm �(kV��@^0ֹ"@��+ʚ�6�W�5+hm �(kV��@^0ֹ"@�H+ʹ���=W�p���p�"��Y@iyE@X�V��yE@Y�"��fE�� �e͊�Z�+�:WȺ�yE@Y�"��fE�� �e͊�Z�+�:WȺ�yE@Y�"��fE�� �e͊�Z�+F�r6W�r���p�"��Y@iyE@Y�"����.@^P֬����"��Y@kyE@Y�"����.@^P֬����"��Y@kyE@Y�"����.@^P֬����"��Y@kqE@INJ�:�+F�R6�W�3+(m �(kV��@^P֬����"`�sE���W�5+hm �(kV��@^P֬����"`�sE���W�5+hm �(kV��@^P֬����" �o+`]��"��Y@kyE@Y�"��⊀��t�W�s��tfE�� �e͊�Z�+ʚ�6�W�u��ufE�� �e͊�Z�+ʚ�6�W�u��ufE�� �e͊�Z�+ʚ�6�W�u��ufE�� �%+�,�(gVP�@^0ֹ"@��+ʚ�6�W�5+hm �(kV��@^0ֹ"@��+ʚ�6�W�5+hm �(kV��@^0ֹ"@��+ʚ�6�W�5+hm �(kV��@^0ֹ"@��+J:V�Y8^Pά����"��Y@kyE�X��Y �(kV��@^P֬����"��Y@kyE@X�V��yE@Y�"��fE�� �e͊�Z�+�:WȺ�yE@Y�"��fE�� �e͊�Z�+F�r6W�r���p�"��Y@iyE�s��|�}E��k����{����|��QÊ������v�������E�x(����X��?������������E��w��߫y�!}��Y��������x_j<�6�k<eM���r�g���#��OYS㡵�\�)kj<�6�k<eM���r�g���#��OYS㡵�X�)���Y8��35J�5������k<eM���r�������@��55Z�5������k<eM���r�������@��55Z�5������k<eM���r�������@��55Z�5������j<��k<4��a�����Cc��S��x(m �x��V�ur�������@��55Z�5����Ck��3�Y�ur�������@��55Z�5����Ck��3�Y�ur�������@��55Z�5����Ck��3��x�l�xJ9j<T�k<�L���r�������@��u�xd]�\�)kj<�6�k<eM���r�������@��u�xd]�\�)kj<�6�k<eM���r�������@��u�xd]�\�)kj<�6�k<eM���b�����Cg��3��x�l�xʙ� �OYS㡵�\�)kj<�6�k<c�5Y �xʚ� �OYS㡵�\�)kj<�6�k<c�5Y �xʚ� �OYS㡵�\�)kj<�6�k<a}������S��xhm �xʚ� �OIG����q�g���#��OYS㡵�\�)kj<�6�k<eM���r�g���#��OYS㡵�\�)kj<�6�k<eM���r�g���#��OYS㡵�\�)kj<�6�k<eM���r�g���#��OYS㡵�X�)���Y8��35J�5������k<eM���r�������@��55Z�5������k<eM���r�������@��55Z�5������k<eM���r�������@��55Z�5�����k<%5:�5�r��Ci��S��xhm �x�:k<�.@��55Z�5����Ck��S��xhm �x��V�ur�������@��55Z�5����Ck��3�Y�ur�������@��55Z�5����Ck��3��x�l�xJ9j<T�k<�L���r�wܓ��c���x���x�'5��������3�ƻ5�?~����|^��n�~�}��n�_-�j�|G>x�����w���"�������*k@�6�@eM��rh��$��PY�������*k@�6�@eM��rh��$��PY�������*�h��Y8n��3 J� ������@eM��r��i���@n��5 Z� ������@eM��r��i���@n��5 Z� ������@eM��r��i���@n��5 Z� ������@��@4��a���Dc�T�4�(m 7������ur��i���@n��5 Z� ���Dk�4����ur��i���@n��5 Z� ���Dk�4����ur��i���@n��5 Z� ���Dk�4�4��l6�J9@T�@�L��r��i���@n��u6�d]���*k@�6�@eM��r��i���@n��u6�d]���*k@�6�@eM��r��i���@n��u6�d]���*k@�6�@eM��b���Dg�4�4��l7�ʙ� �PY�������*k@�6�@c� Y 7�ʚ� �PY�������*k@�6�@c� Y 7�ʚ� �PY�������*k@�6�@a}k����T�4�hm 7�ʚ� �PIG���qh��$��PY�������*k@�6�@eM��rh��$��PY�������*k@�6�@eM��rh��$��PY�������*k@�6�@eM��rh��$��PY�������*�h��Y8n��3 J� ������@eM��r��i���@n��5 Z� ������@eM��r��i���@n��5 Z� ������@eM��r��i���@n��5 Z� �����@% :� �r�Di�T�4�hm 7��:@�.@n��5 Z� ���Dk�T�4�hm 7������ur��i���@n��5 Z� ���Dk�4����ur��i���@n��5 Z� ���Dk�4�4��l6�J9@T�@�L��rx\���co�߽4����W~G������=7����ލ����O�������w�O�����㻽�<~��nx�<��U?^�>^��~<x<�=�6���|y|� -����'��#�4��X�urc��i,��@n,�5�%Zȍ����Dk��4��X�urc��i,��@n,�5�%Zȍ����Dk��4��X�urc��i,��@l,�t4��,7�ʙ�� ���XgcI�ȍ����Dk��T�4�hm 7�ʚ�� ���XgcI�ȍ����Dk��T�4�hm 7�ʚ�� ���XgcI�ȍ����Dk��T�4�hm 7�ʚ�� ���XgcI�H��r�%�ð�T��X��p�X*gK�6�Ka}k,����T�4�hm 7�ʚ�� ��RY�X����X�l,ɺ���T�4�hm 7�ʚ�� ��RY�X����X�l,ɺ���T�4�hm 7�ʚ�� ��RY�X����XiKr6K��%*Ǎ�r��Di��T�4�hm 7��:K�.@n,�5�%Zȍ����Dk��T�4�hm 7��:K�.@n,�5�%Zȍ����Dk��T�4�hm 7��:K�.@n,�5�%Zȍ����Dk��T��X��p�XeKR6�K�Lc��rc��i,��@n,�5�%Zȍ���ƒ��KeMc��rc��i,��@n,�5�%Zȍ���ƒ��KeMc��rc��i,��@n,�5�%Zȍ���5�`]��X*kK�6�KeMc��bc����Dgḱ4��X�trc��i,��@n,�5�%Zȍ����Dk��4��X�urc��i,��@n,�5�%Zȍ����Dk��4��X�urc��i,��@n,�5�%Zȍ����Dk��4��X�urc��i,��@l,�t4��,7�ʙ�� ���XgcI�ȍ����Dk��T�4�hm 7�ʚ�� ���XgcI�ȍ����Dk��T�4�hm 7�ʚ�� ���XgcI�ȍ����Dk��T�4�hm 7�ʚ�� ���XgcI�����������R9�X����X*kK�6�Kc��%Y 7�ʚ�� ��RY�X����X*kK�6�Ka}k,����T�4�hm 7�ʚ�� ��RY�X����X�l,ɺ���T�4�hm 7�ʚ�� ��RY�X����XiKr6K��%*Ǎ�r��Di��<�Uc��7��^�����<~����,��]�X�gfcy?���嗿���?���CXy}y�����w��a�� ��?aח��ӷ��������3��������x<�E� -<��]���u����������ʺ?{bm��u��ֺ?{bm������|v��,[���n�{�iݟ=�6�����Ϳ��ϞXx`}�<ڟ�o��8w�#o�(��~�8dz,]��h+k�o�6��oeM��r�)���@.��u�d]�\|+k�o�6��oeM��r�)���@.��u�d]�\|+k�o�6��oeM��r�)���@.��u�d]�\|+k�o�6�o%�7:�ŷr��Fi��6�Y|�ur�)���@.��5�7Z�ŷ���Fk��6�Y|�ur�)���@.��5�7Z�ŷ���Fk��6�Y|�ur�)���@.��5�7Z�ŷ���Fk��6�Y|�uR�{���0,��p�h,�ʙ�� ��[Xߊo��@.��5�7Z�ŷ���Fk��V��hm ��:�o�.@.��5�7Z�ŷ���Fk��V��hm ��:�o�.@.��5�7Z�ŷ���Fk��V��hm �F�⛜���[)G���q�)�Q�@.��5�7Z�ŷ��⛬��oeM��r�)���@.��5�7Z�ŷ��⛬��oeM��r�)���@.��5�7Z�ŷ��⛬��oeM��r�)���@,��t��,�F�⛔���[9S|���\|+k�o�6��oeM��r�m���&���[YS|���\|+k�o�6��oeM��r�m���&���[YS|���\|+k�o�6��oeM��r�-�o�7XW �ʚ�� ��[YS|���X|+�(��Y8.��s�$]�\|+k�o�6��oeM��r�)���@.��u�d]�\|+k�o�6��oeM��r�)���@.��u�d]�\|+k�o�6��oeM��r�)���@.��u�d]�\|+k�o�6�o%�7:�ŷr��Fi��6�Y|�ur�)���@.��5�7Z�ŷ���Fk��6�Y|�ur�)���@.��5�7Z�ŷ���Fk��6�Y|�ur�)���@.��5�7Z�ŷ���Fk��6�Y|�ub�Fg��V��(m �ʚ�� ���Xg�M��ŷ���Fk��V��hm �ʚ�� ��[Xߊo��@.��5�7Z�ŷ���Fk��V��hm ��:�o�.@.��5�7Z�ŷ���Fk��V��hm �F�⛜���[)G���q�)�Q�@.��fU|�{�����x|8,����۟ܽ��)|W�������?I���3yd���Q{��/���/�������q�����_�������kܛ�c��zyT?^n����y���^>��H�?�4�hm 7���֜�urs��i���@nΕ5�9Z���9Gk�97�ٜ�urs��i���@nΕ5�9Z���������8gsN����9Gk�9W�4�hm 7�ʚ�� ���XgsN����9Gk�9W�4�hm 7�ʚ�� ���XgsN����9Gk�9W�4�hm 7�ʚ�� ���XgsN����9Gk�9W�ќ��pܜ+g�s�6��sc��9Y 7�ʚ�� ��\YӜ���ܜ+k�s�6��sc��9Y 7�ʚ�� ��\YӜ���ܜ+k�s�6��sc��9Y 7�ʚ�� ��\YӜ���ܜ+k�s�6��sc��9Y 5�ʹ7�h|��\ Gs���qs��i�Q�@n΅��9� -��\YӜ���ܜ+k�s�6��seMs��rsn��9'���\YӜ���ܜ+k�s�6��seMs��rsn��9'���\YӜ���ܜ+k�s�6��seMs��bsn�i���8lΕr4�,7�ʙ�� ��\YӜ���ܜ�l�ɺ��9W�4�hm 7�ʚ�� ��\YӜ���ܜ�l�ɺ��9W�4�hm 7�ʚ�� ��\YӜ���ܜ�l�ɺ��9W�4�hm 7�ʚ�� ��\IGs���asn�i�I�8nΕ3�9J���9Gk�9W�4�hm 7��:�s�.@nΕ5�9Z���9Gk�9W�4�hm 7��:�s�.@nΕ5�9Z���9Gk�9W�4�hm 7���֜�urs��i���@nΕ5�9Z���������8gsN����9Gk�9W�4�hm 7�ʚ�� ���XgsN����9Gk�9W�4�hm 7�ʚ�� ���XgsN����9Gk�9W�4�hm 7�ʚ�� ���XgsN����9Gk�9W�ќ��pܜ+g�s�6��sc��9Y 7�ʚ�� ��\YӜ���ܜ+k�s�6��sc��9Y 7�ʚ�� ��\YӜ���ܜ+k�s�6��sc��9Y 7�ʚ�� ��\YӜ���ܜ+k�s�6��sc��9Y 6�J:�st��s�Ls��rs��i���@nu6�d]�ܜ+k�s�6��seMs��rs��i���@n΅��9� -��\YӜ���ܜ+k�s�6��seMs��rsn��9'���\YӜ���ܜ+k�s�6��seMs��bsn�i���8lΕr4�,7�ʙ�� ���8�V�9��ޜ�{ hΏ���.�w�� |��6�.�yfV�kw����ߔ���}����'����;�?_/wg��?���>��w�������Ĺ?{"m����rwc���'�X�/O/�Һ?{bm�A���>�9�x����zwyz����k��������6W�u�$�����`�s%��+W�u�$������c%�� ĕg+ lm �$(kVк�q%�Y�J[�+ �:V��@ZIp�}%���Õ��JJ �$8�XI`kq%�Y�J[�+ �:V��@\IP֬$�u�J�����6W�u�$������c%�� ĕe�JZ �$8�XI`kq%�Y�J[�+ �:V��@\IP֬$�u�J�����6�V�t_I`g�p%�9�JK�+ ʚ��.@\Ipֱ����J�����6W�u�$�������YI@�ĕg+ lm �$8�XI`kq%�Y�J[�+ ʚ��.@\Ipֱ����J�����6W�u�$�������YI@����������0ZIp�}%���Õ�+ ,m �$�\I � -ĕg+ lm �$8�XI`kq%�Y�J[�+ ʚ��.@\Ipֱ����J�����6W�u�$�������YI@�ĕg+ lm �$8�XI`kq%�Y�J[H+ J:V��8ZIp�}%���Õ�+ ,m �$8�XI`kq%AY�����+ �:V��@\Ipֱ����J�����6W�5+ h]����c%�� ĕg+ lm �$8�XI`kq%AY�����+ �:V��@\Ipֱ����J���+ �,�$(�XI@e�p%�9�JK�+ �:V��@\Ipֱ����J���mz$�����d�wNE��_ئ��&��]p�K���@��7���'b�̻bq`���ֺUIu7���WY�����+ �:V��@\Ipֱ����J�����6W�5+ h]����c%�� ĕg+ lm �$8�XI`kq%�X�JYW �$8�XI`kq%�Y�J[H+ N��$��p����YI@�ĕg+ lm �$8�XI`kq%�Y�J[�+ ʚ��.@\Ipֱ����J�����6W�u�$�������YI@�ĕg+ lm �$8�XI`kq%�Y�J[�+ ʚ��.@\Ipֱ����J��n+ �,�$8�XI`iq%AY�����+ �:V��@\Ipֱ����J�����6W�5+ h]����c%�� ĕg+ lm �$8�XI`kq%AY�����+ �:V��@\Ipֱ����J�����6W�5+ h]�����J;�+ �9VX�@\Ipֱ����J��f%�W�u�$������c%�� ĕg+ lm �$�\I � -ĕg+ lm �$8�XI`kq%�Y�J[�+ ʚ��.@\Ipֱ����J�����6W�u�$�������c%������VXY8\Ipα����J���W�=�?s��+ ��J���J����<�J�xf�$��?���_�_����# O����{�^m<t�jo������{/�u{����;�ۀ��f����=��J�{ʚ=�6�� �5{hm �A�܃ ��=e�Z�{ʚ=�6�� �5{hm �A�y�+�� �5{hm �A(k� ��@ރP��A����a�s���� �5{hm �A(k� ��@܃Pұ�����q�=�.@ރP��A������ك@kyBY�������=�.@ރP��A������ك@kyBY�������=�.@ރP��A������ك@kyBY�������=�.@ރP��A������c���=��J�{�:� Ⱥ�yBY������f� �=e�Z�{�:� Ⱥ�yBY������f� �=e�Z�{�:� Ⱥ�yBY������f� �=e�Z�{�:� Ⱥ�iB9�=4^�pB ��{ʙ=�6�� �����{ʚ=�6�� �5{hm �A(k� ��@ރ0ֹA��{ʚ=�6�� �5{hm �A(k� ��@ރ0ֹA��{ʚ=�6�� �5{hm �A(k� ��@܃0��A��q���c���=��J�{ʚ=�6�� �u�A�u���f� �=e�Z�{ʚ=�6�� �u�A�u���f� �=e�Z�{ʚ=�6�� �u�A�u���f� �=e�Z�{J:� �Y8܃0��A��q���ك@iyBY������f� �=c�{d]����ك@kyBY������f� �=c�{d]����ك@kyBY������f� �=a=�A�u���f� �=e�Z�{J:� �Y8ރ0ιA��{ʚ=�6�� �5{hm �A(k� ��@ރ0ֹA��{ʚ=�6�� �5{hm �A(k� ��@ރ0ֹA��{ʚ=�6�� �5{hm �A(k� ��@ރ0ֹA��{ʚ=�6� �t�A��p���ك@iy�X�Y �A(k� ��@ރP��A������ك@ky�X�Y �A(k� ��@ރP��A������ك@ky�X�Y �A(k� ��@ރP��A������ك@ky�X�Y �A(�@g�xB9������f� �=c�{d]����ك@kyBY������f� �=a=�A�u���f� �=e�Z�{ʚ=�6�� �u�A�u���f� �=e�Z�{ʚ=�6� �4{�l�A(�@e�xB9����m�=|�m��5w� ����w/���m� n�]��;�������x��ԻE�x(�\�A�����o����!^{���X��Z���p���;�S𪳞�x��z��@=��r=e���"��zJYSO���XO)騧�Y8���3�J�����z����)eM=��r=������@���5�Z�����z����)eM=��r=������@���5�Z�����z����)eM=��r=������@���5�Z�����z����)���)4^°�R�QO��p\O)g�)�6��)a=�S`]�\O)k�)�6��)eM=��r=������@���u�Sd]�\O)k�)�6��)eM=��r=������@���u�Sd]�\O)k�)�6��)eM=��r=������@���4�9���R�z -���zJ9SO���\O)k�)�6��)c��Y �Sʚz -� �zJYSO���\O)k�)�6��)c��Y �Sʚz -� �zJYSO���\O)k�)�6��)c��Y �Sʚz -� �zJYSO���XO)騧�Y8���2�)���r��Bi��R��Shm �Sʚz -� �z�Xg=E�������Bk��R��Shm �Sʚz -� �z�Xg=E�������Bk��R��Shm �Sʚz -� �zJX��XW �Sʚz -� �zJYSO���XO)騧�Y8���s�S$]�\O)k�)�6��)eM=��r=������@���u�Sd]�\O)k�)�6��)eM=��r=������@���u�Sd]�\O)k�)�6��)eM=��r=������@���u�Sd]�\O)k�)�6�)%�:���r��Bi��2�YO�ur=������@���5�Z������Bk��2�YO�ur=������@���5�Z������Bk��2�YO�ur=������@���5�Z������Bk��2�YO�ub=����BgḞR��S(m �Sʚz -� �z�Xg=E�������Bk��R��Shm �Sʚz -� �zJX��XW �Sʚz -� �zJYSO���\O)k�)�6��)c��Y �Sʚz -� �zJYSO���\O)k�)�6�)#M=E��a=����BeḞR��S(m �S�����=�z��5������:^���O�{�zj<sQOݾ[O��~�}����?�Ǐ�>n�菟~8~x��zz<<<������|�c;U�<��_�<���%�ֿ}8�'���ze�i=Zȧ�ʚ�z�6�O�5��hm ���<�'���z��N��x ��z%��h,��+gN�Q�@>���i=XW ��+kN���@>�W֣֜��|Z��9�Gk���X�i=Y ��+kN���@>�W֣֜��|Z��9�Gk���X�i=Y ��+kN���@>�W֣֜��|Z��9�Gk��HsZO���i�R��zT�O�3��(m ��+kN���@>�7�yZO�ȧ�ʚ�z�6�O�5��hm ��+kN���@>�7�yZO�ȧ�ʚ�z�6�O�5��hm ��+kN���@>�7�yZO�ȧ�ʚ�z�6�O�5��hm ��+�8�Gg���(sZO���i�r�� ��ze�i=Zȧ�ʚ�z�6�O�u�֓u�i���� ��ze�i=Zȧ�ʚ�z�6�O�u�֓u�i���� ��ze�i=Zȧ�ʚ�z�6�O��|Z�ȧ�ʚ�z�6�O�5��hm ��+�8�Gg����8�i=I ��+kN���@>�W֣֜��|Z��9�Gk���X�i=Y ��+kN���@>�W֣֜��|Z��9�Gk���X�i=Y ��+kN���@>�W֣֜��|Z��9�Gk���X�i=Y ��+kN���@<�W�qZ����i�r�� ��zc���d]�|Z��9�Gk��^YsZ���i���� ��zc���d]�|Z��9�Gk��^YsZ���i���� ��zc���d]�|Z��9�Gk��^YsZ���i���� ��zc���d]�xZ�������z��i=Jȧ�ʚ�z�6�O�u�֓u�i���� ��ze�i=Zȧ�ʚ�z�6�O��|Z�ȧ�ʚ�z�6�O�5��hm ��+kN���@>�7�yZO�ȧ�ʚ�z�6�O�5��hm ��+kN���@<�7Ҝ֓�qxZ�������z��i=Jȧ��g���c;��x�ǧ���������^��)�֟���xq<���g��8��Q����o��w/�����]`߹�����m:�����^+]�כ��k���{�[�<^snG�x�8J���iw�χ�{kݞ�bm��և����`�Xdzl]�;��O���|+���kw����Z�g�X�c=�^��u{�����[����m��Y�.������Z�g�X�c}<�=�?F�g�X�c}><���oeݞ�bm��֧ӏ�AZdzl]�;�ӏ��`KY�g�X�c=��^�u{����;�ӏ��Z�g�X�����c��eg�v����Q� g<{E����gpc�۳W� ܱ>�^�����k߷����O8�Y�.������Z�g�X�c}<�>�?͍g�X�c=��pƳW� |?H�9��5Ϣu�XO?��Giݞ�bm����c�}����+��XO?���n�^�6�}�kl|��4�gٺ�w�w�Ǘiݞ�bm����p|����+��XO�i���p�+o����N�e�ܱ�~�ֺ={�����g�p+�۳W� ܱ�~ -�wҺ={�����w�Ý��gٺ�w������n�^�6p�z�1�pƳW� ܱ�~7ֺ={������7����Y�.�����Y� g<{����� -��泾hm �WY�Y_�6�?�k��d]��Y_e�g}��@���������p�Y_��g}Q�@��������u�g}�5��Ek���ʚ������Y_e�g}��@��������u�g}�5��Ek���ʚ������Y_e��Z��C�:��Ⱥ�y{HY�=������f{� ��!e��Z��C�:��Ⱥ�i{H9��!4^�p{H ����Cʙ�!�6������=���Cʚ�!�6����5�Chm o)k����@�2ֹ=D���Cʚ�!�6����5�Chm o)k����@�2ֹ=D���Cʚ�!�6����5�Chm o)k����@�2�l��q�=��c{����!���J��Cʚ�!�6����un�u����f{� ��!e��Z��Cʚ�!�6����un�u����f{� ��!e��Z��Cʚ�!�6����un�u����f{� ��!e��Z��CJ:���Y8�2�l��q�=���Biy{HY�=������f{� ��!c��Cd]��=���Bky{HY�=������f{� ��!c��Cd]��=���Bky{HY�=������f{� ��!a=o�u����f{� ��!e��Z��CJ:���Y8�2ι=D���Cʚ�!�6����5�Chm o)k����@�2ֹ=D���Cʚ�!�6����5�Chm o)k����@�2ֹ=D���Cʚ�!�6����5�Chm o)k����@�2ֹ=D���Cʚ�!�6���tl��p�=���Biy{�X��Y o)k����@�R�l����=���Bky{�X��Y o)k����@�R�l����=���Bky{�X��Y o)k����@�R�l����=���Bky{�X��Y n)��Bg�x{H9�=������f{� ��!c��Cd]��=���Bky{HY�=������f{� ��!a=o�u����f{� ��!e��Z��Cʚ�!�6����un�u����f{� ��!e��Z��Cʚ�!�6���4�C�ln)��Be�x{H9�=�����������ض�.^����c�������_�n��n�G�������>���=�7�)'��Ys���z9�!jg}hN����ɘ�7۟�y�"0���d��f2� ��c��1d]�<����Aky2FY3���d��f2� ��c��1d]�<����Aky2FY3���d��f2� ��#�d9Ǔ1ʙ��6�'c�5�1hm O�(k&c��@��1�9C�ȓ1ʚ��6�'c�5�1hm O�(k&c��@����dXW O�(k&c��@��Q�LƠ��<����Aky2�X�dY O�(k&c��@��Q�LƠ��8��c2����㜓1$]�<����Aky2FY3���d��f2� ��c��1d]�<����Aky2FY3���d��f2� ��c��1d]�<����Aky2FY3���d��f2� ��c��1d]�<����Akq2FI�d:Ǔ1ʙ��6�'c�uNƐu�d��f2� ��e�dZȓ1ʚ��6�'c�uNƐu�d��f2� ��e�dZȓ1ʚ��6�'c�uNƐu�d��f2� ��e�dZȓ1ʚ��6�'c�uNƐu�d�rn�1h���d���4�'c�3�1(m O��y2�+�'c�5�1hm O�(k&c��@��Q�LƠ��<c�s2���'c�5�1hm O�(k&c��@��Q�LƠ��<c�s2���'c�5�1hm O�(k&c��@��Q�LƠ��8c���!g�p2F)�d*Ǔ1ʙ��6�'c�5�1hm O�뜌!���e�dZȓ1ʚ��6�'c�5�1hm O�뜌!���e�dZȓ1ʚ��6�'c�5�1hm O�뜌!���e�dZȓ1ʚ��6'c�tLƠ�p8c���!e�x2F93���d��f2� ��e�dZȓ1�:'cȺ�y2FY3���d��f2� ��e�dZȓ1�:'cȺ�y2FY3���d��f2� ��e�dZȓ1�z��� -��e�dZȓ1ʚ��6'c�tLƠ�p<c�s2���'c�5�1hm O�(k&c��@��Q�LƠ��<c�s2���'c�5�1hm O�(k&c��@��Q�LƠ��<c�s2���'c�5�1hm O�(k&c��@��Q�LƠ��<c�s2���'c�5�1hm N�(阌Ag�x2F93���d�����.@��Q�LƠ��<����Aky2FY3���d�����.@��Q�LƠ��<����Aky2FY3���d�����.@��Q�LƠ��<����Aky2FY3���d�����.@��Q�1����d�rf2� ��e�dZȓ1�:'cȺ�y2FY3���d��f2� ��e�dZȓ1�z��� -��e�dZȓ1ʚ��6�'c�5�1hm O�뜌!���e�dZȓ1ʚ��6�'c�5�1hm N�i&c��8��Q�1����d�rf2� ��ZB�1��d��k�d��{����|��U����4����o��7:�����E�x(��ј㘍���>m��?��LJ�~����9<�����y�������vN��5��_��~Z��E �Gk9�W֤�hm ��ʚ�� �^X�i=XW ��ʚ�� �^Y�֣����+k�z�6��zc�i=Y ��ʚ�� �^Y�֣����+�H��Y8N�s��$]���+k�z�6��zeMZ��rZ��I���@N�u��d]���+k�z�6��zeMZ��rZ��I���@N�u��d]���+k�z�6��zeMZ��rZ��I���@N�u��d]���+k�z�6�z%i=:�i�r&�Gi9�7֙֓urZ��I���@N�5i=Z�i��&�Gk9�7֙֓urZ��I���@N�5i=Z�i��&�Gk9�7֙֓urZ��I���@N�5i=Z�i��&�Gk9�7֙֓uRZ��[Z��K��J8�z4��z�LZ��rZ/���+��zeMZ��rZ��I���@N�5i=Z�i��δ����zeMZ��rZ��I���@N�5i=Z�i��δ����zeMZ��rZ��I���@N�5i=Z�i��&�'g�0�Wʑ֣�p��+g�z�6��zeMZ��rZo�3�'��^Y�֣����+k�z�6��zeMZ��rZo�3�'��^Y�֣����+k�z�6��zeMZ��rZo�3�'��^Y�֣����+k�z�6�z%i=:�i�Q&�'e�8�WΤ�(m ��ʚ�� �^Y�֣�����L�ɺ�9�W֤�hm ��ʚ�� �^Y�֣�����L�ɺ�9�W֤�hm ��ʚ�� �^Y�֣�����9�� -�^Y�֣����+k�z�6�z%i=:�i�qδ����zeMZ��rZ��I���@N�5i=Z�i��δ����zeMZ��rZ��I���@N�5i=Z�i��δ����zeMZ��rZ��I���@N�5i=Z�i��δ����zeMZ��bZ��#�Gg�8�WΤ�(m ���:�z�.@N�5i=Z�i��&�Gk9�W֤�hm ���:�z�.@N�5i=Z�i��&�Gk9�W֤�hm ���:�z�.@N�5i=Z�i��&�Gk9�W֤�hm ���:�z�.@L�t���,��ʙ�� �^Y�֣�����L�ɺ�9�W֤�hm ��ʚ�� �^Y�֣�����9�� -�^Y�֣����+k�z�6��zeMZ��rZo�3�'��^Y�֣����+k�z�6��zeMZ��bZo�I���8L�r���,��ʙ�� 䴞q���{li��k<>���ﱤ��W���������㙙�ߎ�������_~�����ӧ?����zʻ�3��ߺ����ߺsb o:ˋ7�O,߾$�hm '�ʚ�� ���XgbI�ȉ��&�Dk9�T�$�hm '�ʚ�� ���XgbI�ȉ��&�Dk9�T�$�hm '�ʚ�� ���XgbI�ȉ��&�Dk1�TґX��p�X*gK�6�Kc��%Y '�ʚ�� ��RY�X����X*kK�6�Kc��%Y '�ʚ�� ��RY�X����X*kK�6�Kc��%Y '�ʚ�� ��RY�X����X*kK�6�Kc��%Y %�ʹ%�h��ab��#�Dc�8�T�$�(m '��zN,��9�T�$�hm '�ʚ�� ��RY�X����X�L,ɺ�9�T�$�hm '�ʚ�� ��RY�X����X�L,ɺ�9�T�$�hm '�ʚ�� ��RY�X����XiKr6K��%*lj�r&�Di9�T�$�hm '��:K�.@N,�5�%Zȉ��&�Dk9�T�$�hm '��:K�.@N,�5�%Zȉ��&�Dk9�T�$�hm '��:K�.@N,�5�%Zȉ��&�Dk1�TґX��p�XeKR6�K�Lb��rb��I,��@N,�5�%Zȉ���Ē��KeMb��rb��I,��@N,�5�%Zȉ���Ē��KeMb��rb��I,��@N,�5�%Zȉ���K��@N,�5�%Zȉ��&�Dk1�TґX��p�X�L,I��9�T�$�hm '�ʚ�� ��RY�X����X�L,ɺ�9�T�$�hm '�ʚ�� ��RY�X����X�L,ɺ�9�T�$�hm '�ʚ�� ��RY�X����X�L,ɺ�9�T�$�hm &�J:Kt�K�Lb��rbi�3�$���RY�X����X*kK�6�KeMb��rbi�3�$���RY�X����X*kK�6�KeMb��rbi�3�$���RY�X����X*kK�6�KeMb��rbi�3�$���RIGb���qb��I,Q�@N,�5�%Zȉ���Ē��KeMb��rb��I,��@N,�5�%Zȉ���K��@N,�5�%Zȉ��&�Dk9�T�$�hm '��:K�.@N,�5�%Zȉ��&�Dk9�T�$�hm &�F�Ē����R)Gb���qb��I,Q�@N,��%�ǖX^�$�����}���v���ޔX晙X�X���>}�������s܅������Y;���\'��x��5w?���k���?�鬣%ek�%u�ђ���ؒ:�hI��@lI�5-)Z ���:ZR�6[Rg-)[�-������ ĖTYӒ�ubKꬣ%ek�%u�ђ���ؒ:�hI��@lI�5-)Z ���:ZR�6�ZR'�ZRv[R�-)K�-���%E�Ė�YGK��bKꬣ%ek�%u�ђ���ؒ*kZR�.@lI�u��lm ���:ZR�6[Rg-)[�-���%E�Ė�YGK��bKꬣ%ek�%u�ђ���ؒ*kZR�.@hI��{K��K��N���l,���9ZR�6[Rc�-)YW ���:ZR�6[Rg-)[�-������ ĖTYӒ�ubKꬣ%ek�%u�ђ���ؒ:�hI��@lI�5-)Z ���:ZR�6[Rg-)[�-������ ��TIGK���QK�[K���aKꜣ%ei�%u�ђ���ؒ*kZR�.@lI�u��lm ���:ZR�6[Rg-)[�-���%E�Ė�YGK��bKꬣ%ek�%u�ђ���ؒ*kZR�.@lI�u��lm ���:ZR�6�ZR'�ZRv�ZR�-)*�-�s���� Ė�YGK��bKꬣ%ek�%Uִ�h]�ؒ:�hI��@lI�u��lm ���:ZR�6[ReMK���-������ Ė�YGK��bKꬣ%ek�%5�ْ�ubKꬣ%ek�%u�ђ���Ԓ:�֒��pؒ*gZR�.@lI�u��lm ���:ZR�6[Rg-)[�-���%E�Ė�YGK��bKꬣ%ek�%u�ђ���ؒ*kZR�.@lI�u��lm ���:ZR�6[Rg-)[�-���%E�Ė�YGK��RK�[K���aKꜣ%ei�%Uִ�h]�ؒ:�hI��@lI�u��lm ���:ZR�6[ReMK���-������ Ė�YGK��bKꬣ%ek�%Uִ�h]�ؒ:�hI��@lI�u��lm ���:ZR�6[ReMK��H-��n-);�-�s���� Ė�YGK��bK��iIѺ��%u�ђ���ؒ:�hI��@lI�u��lm ���:[R��@lI�u��lm ���:ZR�6[Rg-)[�-���%E�Ė�YGK��bKꬣ%ek�%u�ђ���Ԓ*�hI��8jI�rkIYY8lI�s��,m ��XD^oI�=�?s��/{-)������\�cK:��-��hI���ۛ�6s�����x���o_����>���;u������ot��o/nw��9+9x�Y�]��~%��E��Ck��3�Yɑur%������@��5�Zȕ����Ck��3�Yɑur%������@��tTr�,WrʙJ� �J�Xg%G�ȕ����Ck��S�Trhm WrʚJ� �J�Xg%G�ȕ����Ck��S�Trhm WrʚJ� �J�Xg%G�ȕ����Ck��S�Trhm WrʚJ� �J�Xg%G�H��rn�/aX�)���X8��3�Jȕ���+9��@��5�Zȕ����Ck��S�Trhm Wr�:+9�.@��5�Zȕ����Ck��S�Trhm Wr�:+9�.@��5�Zȕ����Ck��S�Trhm VrF�J����JN)G%���q%����P�@��5�Zȕ���J���+9eM%��r%������@��5�Zȕ���J���+9eM%��r%������@��5�Zȕ���J���+9eM%��r%������@��tTr�,VrF�J����JN9Sɡ��\�)k*9�6�+9eM%��r%g���#��JNYSɡ��\�)k*9�6�+9eM%��r%g���#��JNYSɡ��\�)k*9�6�+9eM%��r%'��J�+�+9eM%��r%������@��tTr�,Wr�9+9�.@��5�Zȕ����Ck��S�Trhm Wr�:+9�.@��5�Zȕ����Ck��S�Trhm Wr�:+9�.@��5�Zȕ����Ck��S�Trhm Wr�:+9�.@��5�Z�����J���JN9Sɡ��\���Ⱥ���S�Trhm WrʚJ� �JNYSɡ��\���Ⱥ���S�Trhm WrʚJ� �JNYSɡ��\���Ⱥ���S�Trhm WrʚJ� �JNYSɡ��\���Ⱥ���S�Qɡ�p\�)g*9�6�+9eM%��r%g���#��JNYSɡ��\�)k*9�6�+9eM%��r%'��J�+�+9eM%��r%������@��5�Zȕ���J���+9eM%��r%������@��5�Z������#g㰒S�Qɡ�p\�)g*9�6�+9*�D%��Ur��t�[�����/�O]����zw�~%�t<<}��y��o���ݞ_h<�G�g{#���o�~����}�?����>�����}���p���.������Ow���w�y��Eo_��p���C�;���+��X�Ϸֺ={���������5��n���q;����x����+��XO?�kݞ�bm������b�g�X����x�}��|cϲu�X�OOֺ={�����`��M��n�^�6p�z�1���eݞ�bm�������p�y�+p�z�1�=J���kw�����Q���+��XO?���n�^�6�}���c�yv��,[�������"�۳W� ܱ>��ֺ={������e%�mFg�����9��L���mV�|�� ��6+k�ی��w��5�mFk����:��L���mV�|�� ��6+k)��@^�P�,R����Ha�s����)�5�hm /R(k)��@^�P�,R����Ha�s����)�5�hm .R(�X�@g�x�B9�H���"���E -�.@^�P�,R����H��Y�@ky�BY�H���"���E -�.@^�P�,R����H��Y�@ky�BY�H���"���E -�.@^�P�,R����H��Y�@ky�BY�H���"���E -�.@Z�P�m���0\�P±H����"�rf�� �E -a=/R�u�"��f�� �E -e�"ZȋʚE -�6�)�u.R�u�"��f�� �E -e�"ZȋʚE -�6�)�u.R�u�"��f�� �E -e�"ZȋʚE -�6)�4��l.R(�X�@e�x�B9�H���"��f�� �E -c��d]��H��Y�@ky�BY�H���"��f�� �E -c��d]��H��Y�@ky�BY�H���"��f�� �E -c��d]��H��Y�@ky�BY�H���"���E -t)�2��l/R(g)P�@^�P�,R����H��Y�@ky��X�"Y /R(k)��@^�P�,R����H��Y�@ky��X�"Y /R(k)��@^�P�,R����H��Y�@ky�BXϋ`]��H��Y�@ky�BY�H���"���E -t�)�s.R�t�"��f�� �E -e�"ZȋʚE -�6�)�u.R�u�"��f�� �E -e�"ZȋʚE -�6�)�u.R�u�"��f�� �E +xڜ�O�d�}%���e�����K�$㌍��Lf�=�B��@�� R�^���s3��x�,oܣ*�Nt������������n��/��LJ�~����|������;�'�O���?��/�����tw��onoN/��ϼ<����t�={���������?�>}�rzy�����n<�G~����������}���_>���O���������/�?��_���������������1_��{#[?��t��x��9�|�W���桷���ܝ���.}����+�X�o��^Z�g�Xx`}>==<H���k/Zoo����Y�,ZW��u���u������k�}����+�X���l���W� �l=o_�ͳ��gٺ��w�Ǘiݟ�bm�����%KZ�g�Xx`}>=���o�^q���|:?��s<��x`ݾ�Gkݟ�bm��u���κ?{�����-��I���k/[ﶯ�NZdzl]���k������+�X���,��g�Xx`ݾ�kݟ�bm�e���t�"̍gٺ��w��g�g<{��������Z�g�Xx`}>=ؿ +�g�Xx���} ��x�����} �ֺ?{�����5ȿH�^q�@�}w��x��������wp+��Y�.����叹��k�۷pc���W� <�>��_䏹��k/[����~��ϲuX�N�Oֺ?{��������17��bm��u�䏹��k/[����^Zdzl]���k��?�ƳW� <�n_í�17��bm��u��ֺ?{����֗�k��?�Ƴl]���k�ίO^1���N�oY�G�w����g�n<{E���ֻ�����Q�gѺ�w��Gkݟ�bm��u��u������_t���+�^�����NZdzl]���k�}����+�X����(���W� <�n�⍵��^�6�������~��Y�.���i�� ���W� <�>����u��������㋴��^�6��n�俙�G�ٸ����[���,܁r���ҹ?{E�����ɟ6��+�^��o_����gٺ��۷p�?�ƳW� <�n_��c�<{�������b���W� �l}�9=>���ϲuX�Ng����k���Gkݟ�bm��u��ϸ��k/[���^��ϲuX����Z�g�Xx`ݾ�[�3n<{�����5ȿ �^q��i��ϛ�QV6�@�}7ֹ?{E������E��g�Xx`}>�<[���k/[�oNrv�gٺ��w�9;ɳW� <�n_Ã���^�6���} rv�g�Xx���} w�:�e�<�n_í�7��bm��u���$�^�6���} 7ֺ?{�������������gѺ����gxy����և������^�6���t�(0��,�e�y���<��x`ݾ�kݟ�bm��u��o�u������[���<{�������k����,[��u���Һ?{�����5��I��bm������b���W� �l��9�=�sy����z{z���<{��������Z�g�Xx`ݾ��cn<{�������k���<��x`ݾ�;kݟ�bm��u��_��G�8w�ܾ9;ɳW� �l}ؾ����gٺ���w g'y����ևӭ����+�X�NO�ֺ?{�����Ǜӭ���Y�.����I�N��k����`���W� <�n_�����+�^�>m_����Y�.���5�Z���k��� g'y������k���<{�������Yy����z{z��o�^q�@�p:��I��"m������d���W� �l}پ9>ɳl]���[��<{�����5�[���k��� �'y�����7�� ��<��x`ݾ�����^�6���} r|�g�Xx`}:=�?gʳW� �l=ߜnd0�gٺ����9>ɳW� <�>�n�u������k��D��bm�e���5����eg���wp/����,܁r�d-�g�Hx`ݾ���<����D����t�o��3o?��ͻ�q�tz���Yo����t��W��bo/7����P�'z�~�ܽ�^.��Cy&��y4�����O~��������_��z�A>?>~�F������|��6�d��y���<̒/|��,�� �,YY�%�ub��#Kfk1Kv֑%����%;�%��p�%+g�d�.@̒�ud�lm f��:�d�6�dgY2[�Y��&KF��,�YG���b��#Kfk1Kv֑%����%+k�d�.@̒�ud�lm f��:�d�6�dgY2[�Y��&KF��,�YG���R��{����a��#Kfi1KV�d�h]��%;�Ȓ��@̒�ud�lm f��:�d�6�deM����Y���,�� �,�YG���b��#Kfk1KV�d�h]��%;�Ȓ��@̒�ud�lm f��:�d�6�deM���Y�s~˒��FY��Y2�Y�s�,�� �,�Xg�L��Y���,�� �,�YG���b��#Kfk1KV�d�h]��%;�Ȓ��@̒�ud�lm f��:�d�6�deM����Y���,�� �,�YG���b��#Kfk)KVґ%��q�%;�%��p�%;�ȒY�@̒�ud�lm f�ʚ,��dgY2[�Y���,�� �,�YG���b���ɒѺ�1Kv֑%����%;�Ȓ��@̒�ud�lm f�ʚ,��dgY2[�Y���,�� �,�I�,����,Y)G����a��#Kfi1Kv֑%����%;�Ȓ��@̒�5Y2Z f��:�d�6�dgY2[�Y���,�� �,YY�%�ub��#Kfk1Kv֑%����%;�Ȓ��@̒�uf�d]��%;�Ȓ��@̒�ud�lm e�N�g��,f�ʙ,��dgY2[�Y���,�� �,�YG���b���ɒѺ�1Kv֑%����%;�Ȓ��@̒�ud�lm f�ʚ,��dgY2[�Y���,�� �,�YG���b���ɒѺ�1Kv֑%����%;�%��p�%;�ȒY�@̒�5Y2Z f��:�d�6�dgY2[�Y���,�� �,YY�%�ub��#Kfk1Kv֑%����%;�Ȓ��@̒�5Y2Z f��:�d�6�dgY2[�Y���,�� �,YY�%�uR��{����a��#Kfi1Kv֑%����%+k�d�.@̒�ud�lm f��:�d�6�dgY2[�Y���,��+�dgY2[�Y���,�� �,�YG���b���ɒѺ�1Kv֑%����%;�Ȓ��@̒�ud�lm e�J:�dt6��d�ܳdV�d�Y2K�Y2�׳d�ߞy�1�GY2|��ܽ�o�5Y���~o?rN��~o�a���|9K��,9a�����a������㗿~�����b��������������k�w(o>�q����@���r��� P��@P�5 +Z��������eM���r��� P��@P�5 +Z��������eM���r��� P��@P�5 +Z����������4��a���#@Ac�8@Q�((m (����ur��� P��@P�5 +Z���&@Ak9@1���ur��� P��@P�5 +Z���&@Ak9@1���ur��� P��@P�5 +Z���&@Ak1@1�(�l(J9T��L���r��� P��@P�u(d]��(k�6�eM���r��� P��@P�u(d]��(k�6�eM���r��� P��@P�u(d]��(k�6�eM���b���#@Ag�0@1�(�l(ʙ�� ��EY�����(k�6�c� +Y (ʚ�� ��EY�����(k�6�c� +Y (ʚ�� ��EY�����(k�6�a} P��9@Q�(hm (ʚ�� ��EIG����q�b�3@!���EY�����(k�6�eM���r�b�3@!���EY�����(k�6�eM���r�b�3@!���EY�����(k�6�eM���r�b�3@!���EY�����(�P�Y8P�3 +J��������eM���r��� P��@P�5 +Z��������eM���r��� P��@P�5 +Z��������eM���r��� P��@P�5 +Z�������% +:��r&@Ai9@Q�(hm (�:�.@P�5 +Z���&@Ak9@Q�(hm (����ur��� P��@P�5 +Z���&@Ak9@1���ur��� P��@P�5 +Z���&@Ak1@1�(�l(J9T��L���r�B�P�s�ʛ����X��+����������k�r;�������?�����������7r�������J��|g|��ζ7���m�?�� � �w�)�xg:��l3���6�.@~g���mhm ��MY��6�6��٦�ygZ��l3���6�.@~g���mhm ��MY��6�6��٦�ygZ��l3���6�.@~g���mhm ��MY��6�6��٦�ygZ��l3���6�.@~g���mhm ��MI�;��Y8~g�r�m(m ���Xg2K��ɬ�&�Ek9�U�$�hm '�ʚd� �d�Xg2K��ɬ�&�Ek9�U�$�hm '�ʚd� �d�Xg2K��ɬ�&�Ek9�U�$�hm '�ʚd� �d�Xg2K�Hɬr��,��0�U̢�p��*g�Y�6��Ya}Mf��9�U�$�hm '�ʚd� �dVY�̢�����Lfɺ�9�U�$�hm '�ʚd� �dVY�̢�����Lfɺ�9�U�$�hm '�ʚd� �dVY�̢����i�Yr6�Y��,*�ɬr&�Ei9�U�$�hm '��:�Y�.@Nf�5�,Z�ɬ�&�Ek9�U�$�hm '��:�Y�.@Nf�5�,Z�ɬ�&�Ek9�U�$�hm '��:�Y�.@Nf�5�,Z�ɬ�&�Ek1�Uґ̢�p��e�YR6��Y�L2��r2��If��@Nf�5�,Z�ɬ��d����YeM2��r2��If��@Nf�5�,Z�ɬ��d����YeM2��r2��If��@Nf�5�,Z�ɬ��&�`]���*k�Y�6��YeM2��b2��#�Eg�8�5Ι̒tr2��If��@Nf�5�,Z�ɬ�&�Ek9�5֙̒ur2��If��@Nf�5�,Z�ɬ�&�Ek9�5֙̒ur2��If��@Nf�5�,Z�ɬ�&�Ek9�5֙̒ur2��If��@Lf�t$��,'�ʙd� �d�Xg2K��ɬ�&�Ek9�U�$�hm '�ʚd� �d�Xg2K��ɬ�&�Ek9�U�$�hm '�ʚd� �d�Xg2K��ɬ�&�Ek9�U�$�hm '�ʚd� �d�Xg2K��ɬ��d���dV9�̢����*k�Y�6��Yc��,Y '�ʚd� �dVY�̢����*k�Y�6��Ya}Mf��9�U�$�hm '�ʚd� �dVY�̢�����Lfɺ�9�U�$�hm '�ʚd� �dVY�̢����i�Yr6�Y��,*�ɬr&�Ei9�=�?U2��cOf�|Hf�?���ζ�����3'���d�n$������/��������_��z�E��_˽�֏s{���=�fg(�t�bo>�q(���@(��r(�� ���@Ŕ5�Zȡ���P���C1eM(��b(��#Cg�8S΄b(m �b�:C1�.@Ŕ5�Zȡ��&Ck9Sքbhm �b�:C1�.@Ŕ5�Zȡ��&Ck9Sքbhm �b�:C1�.@Ŕ5�Zȡ��&Ck9Sքbhm �b�:C1�.@ +Ŕs�������P���PL9����� �k(�ȡ��&Ck9Sքbhm �bʚP� �P�Xg(F�ȡ��&Ck9Sքbhm �bʚP� �P�Xg(F�ȡ��&Ck9Sքbhm �bʚP� �P�H���q�)��PY8Ŕ3�Jȡ��&Ck93���ur(�� ���@Ŕ5�Zȡ��&Ck93���ur(�� ���@Ŕ5�Zȡ��&Ck93���ur(�� ���@Ŕ5�Z�����P���P�(���q�)gB1�6�C1eM(��r(�� ���@Ōu�bd]��)kB1�6�C1eM(��r(�� ���@Ōu�bd]��)kB1�6�C1eM(��r(�� ���@ń�5� +�PLY�����)kB1�6C1%�:ǡ�q�P���C1eM(��r(�� ���@Ŕ5�Zȡ���P���C1eM(��r(�� ���@Ŕ5�Zȡ���P���C1eM(��r(�� ���@Ŕ5�Zȡ���P���C1eM(��b(��#Cg�8S΄b(m �b�:C1�.@Ŕ5�Zȡ��&Ck9Sքbhm �b�:C1�.@Ŕ5�Zȡ��&Ck9Sքbhm �b�:C1�.@Ŕ5�Zȡ��&Ck9Sքbhm �b�:C1�.@Ŕt�b�,�bʙP� �PLY�������Ⱥ�9Sքbhm �bʚP� �PLY����� �k(�ȡ��&Ck9Sքbhm �bʚP� �P�Xg(F�ȡ��&Ck9Sքbhm �bʚP� �P�H���q�)��PY8Ŕ3�Jȡ�q��B1�{(��c<��bǟ�7�����ݕP������'���Pl<�g��͊��_?��o�~����~������������a7练߯�������Go<���������y�A.X�g�Xxy{|s>��;k�E� +<�ޝ���u������k��79ʺ?{�����5��u����o�ܾ��ggϲuX��C�5�#Ek�}�ʚ������>R%�#Eg��}��9�GJ���#Uּ�� ���*k�G����H�5�#Ek�}��:�GJ���#Uּ�� ���*k�G����H�5�#Ek�}��:3s�.@�̕5�9Zș��&3Gk93W�d�hm g��:3s�.@�̕5�9Z����������\9����������ɺ�93W�d�hm g�ʚ�� ��\Y����������ɺ�93W�d�hm g�ʚ�� ��\Y����������ɺ�93W�d�hm g�ʚ�� ��\Y����������ɺ�)3W�=3G�[f�J82s4�3s�Lf��rf.���9XW g�ʚ�� ��\Y�������+k2s�6�3sc��9Y g�ʚ�� ��\Y�������+k2s�6�3sc��9Y g�ʚ�� ��\Y�������+k2s�63s#MfN��af��#3Ge�83W�d�(m g�ʚ�� ���XgfN�ș��&3Gk93W�d�hm g�ʚ�� ���XgfN�ș��&3Gk93W�d�hm g�ʚ�� ���XgfN�ș��&3Gk93W�d�hm f�J:2st3s�LfN��qf����Q�@�̕5�9Zș��&3Gk937֙��urf������@�̕5�9Zș��&3Gk937֙��urf������@�̕5�9Zș��&3Gk93����+�3seMf��rf������@�̕td��,g��93s�.@�̕5�9Zș��&3Gk93W�d�hm g��:3s�.@�̕5�9Zș��&3Gk93W�d�hm g��:3s�.@�̕5�9Zș��&3Gk93W�d�hm g��:3s�.@�̕5�9Z����������\9����������ɺ�93W�d�hm g�ʚ�� ��\Y����������ɺ�93W�d�hm g�ʚ�� ��\Y����������ɺ�93W�d�hm g�ʚ�� ��\Y����������ɺ�13Wґ���p��+g2s�6�3seMf��rfn�33'���\Y�������+k2s�6�3seMf��rf.���9XW g�ʚ�� ��\Y�������+k2s�6�3sc��9Y g�ʚ�� ��\Y�������+k2s�63s#MfN��af��#3Ge�83W�d�(m g��ٴ���s��������X2��+��������3��L2����y�������!=o�1�۟�����=?�����N���6�>�x��'|_�??��nΗ>����k�ϧ��[iݟ�bm�AU>�>�9�x����zwzz����+�XǙe���6��(k����|�@X_��u��e���6��(k����|�@Ys��� ��:��u��e���6��(k����x�@I��t���[@��w�5w��@�[���[����e���6���[@��w�5w��@�[���[����e���6���[@��w�5w��@�[���[����e���6���[@��w�5w��@�[���n:�w�3wP�@�[`��nY �-P��-@k�n���nZ�w�5w��@�[`��nY �-P��-@k�n���nZ�w�5w��@�[`��nY �-P��-@k�n���nZ�w�5w��@�[`��nY �-P��n���n���h,�-P��-@i�n����-�� +�ʚ�hm �-P��-@k�n���nZ�w�u�- ��ʚ�hm �-P��-@k�n���nZ�w�u�- ��ʚ�hm �-P��-@k�n���nZ�w�4w��8�[���n*�w�3wP�@�[���[����c�wȺ��n���nZ�w�5w��@�[���[����c�wȺ��n���nZ�w�5w��@�[���[����c�wȺ��n���nZ�w�5w��@�[���n:�w�2wH�8�[���[����e���6��(k����|��X���.@�[���[����e���6��(k����|��X���.@�[���[����e���6��(k����|�@X_��u��e���6��(k����x�@I��t���[@��w�5w��@�[���[����e���6���[@��w�5w��@�[���[����e���6���[@��w�5w��@�[���[����e���6���[@��w�5w��@�[���n:�w�3wP�@�[`��nY �-P��-@k�n���nZ�w�5w��@�[`��nY �-P��-@k�n���nZ�w�5w��@�[`��nY �-P��-@k�n���nZ�w�5w��@�[`��nY �-P�q�����ʙ�(m �-P��-@k�n��λd]�|�@Ys��� �ʚ�hm �-P��-@k�n����-�� +�ʚ�hm �-P��-@k�n���nZ�w�u�- ��ʚ�hm �-P��-@k�n���nZ�w�4w��8�[���n*�w�3wP�@�[@��[��c�[��c�݂�ϱ�-8_�[��;������gr��~�-����~��_>�����������u������?�����?�?��|�ן}��~���ͫ��g>o������u� ��9�~��9�c�� 0�&��9�r�sl4���[ ����9�rf����[X_��`]�<�V�̱��@�c+k��hm ϱ�5sl�6����:��d]�<�V�̱��@�c+k��hm ϱ�5sl�6����:��d]�<�V�̱��@�c+k��hm ϱ�5sl�6��F�969�sl�slT���ʙ96J�sle�� �9���96Y ϱ�5sl�6���ʚ96Z�sle�� �9���96Y ϱ�5sl�6���ʚ96Z�sle�� �9���96Y ϱ�5sl�6���ʚ96Z�sl%slt��F�96)�sl��� �9��f����[Y3�Fky�m�s�M��sle�� �9��f����[Y3�Fky�m�s�M��sle�� �9��f����[Y3�Fky�-��sl��@�c+k��hm ϱ�5sl�6��J:���,ϱ�sαI��y����c���<�V�̱��@�c+k��hm ϱ�uαɺ�y����c���<�V�̱��@�c+k��hm ϱ�uαɺ�y����c���<�V�̱��@�c+k��hm ϱ�uαɺ�y����c���8�V�1�Fg�x����c���<�6�9�&��9��f����[Y3�Fky����c���<�6�9�&��9��f����[Y3�Fky����c���<�6�9�&��9��f����[Y3�Fky����c���<�6�9�&��9���96:�sl��� �9��f�����X������ʚ96Z�sle�� �9��f����[X_��`]�<�V�̱��@�c+k��hm ϱ�5sl�6����:��d]�<�V�̱��@�c+k��hm ϱ�5sl�6��F�969�sl�slT���ʙ96J�s�㹰�c�����o>̱�?Ƿ?���'�������-����������}��8�����������燗��?�z忟W����!�x>�}�c:�|y��|�֯ǻ���år��?{��������QZ�g�Xx`}�~ϟ�u������O��� ��Y�.���5|�(���k�����OՔu������k�����+��q�n�t���;P��B*g^3���k&�5��Dk�5�ʚ�L�����Ic���$���L*k^3���k&�5��Dk�5�ʚ�L�����Ia}}�$XW �fRY�I�6�_3��y�$Zȯ�Tּf� ��L�|�$Y �fRY�I�6�_3��y�$Z���T��It�_3i��5�$]���Ie�k&��@~ͤ��5�hm �fRY�I�6�_3i��5�d]���Ie�k&��@~ͤ��5�hm �fRY�I�6�_3i��5�d]���Ie�k&��@~ͤ��5�hm �fRY�I�6�_3i��5�d]���Ie�k&��@|ͤ���L��p��I��k&Q�@~ͤ���L�u�k&�5��Dk�5�ʚ�L�����Ie�k&��@~ͤ���L�u�k&�5��Dk�5�ʚ�L�����Ie�k&��@~ͤ���L�u�k&�5��Dk�5�ʚ�L�����Ie�]�6���kB�HwM�s�k�Ʒ0�k��� �wM�3wMP�@�k"��wM������� Z�wM�5wM��@�k���k���]c�wMȺ������ Z�wM�5wM��@�k���k���]c�wMȺ������ Z�wM�5wM��@�k���k���]#�]r6�(�k����]��]�6��(k��|��X�]�.@�k���k���]e�]�6��(k��|��X�]�.@�k���k���]e�]�6��(k��|��X�]�.@�k���k���]e�]�6�(�k����]��]R6��(g��|�DYs�� �&ʚ�&hm �51�yׄ���(k��|�DYs�� �&ʚ�&hm �51�yׄ���(k��|�DYs�� �&ʚ�&hm �5�&`]�|�DYs�� �&ʚ�&hm �5Q�q����&�9t�]e�]�6��(k��|�DYs�� �&�:u�]e�]�6��(k��|�DYs�� �&�:u�]e�]�6��(k��|�DYs�� �&�:u�]e�]�6�(�k����]��]�6���kB��wM�5wM��@�k���k���]e�]�6���kB��wM�5wM��@�k���k���]e�]�6���kB��wM�5wM��@�k���k���]e�]�6���kB��wM�t�5Ag����r� J�wM�5wM��@�kb�� Y �5Q��5Ak����� Z�wM�5wM��@�k"��wM������� Z�wM�5wM��@�k���k���]c�wMȺ������ Z�wM�5wM��@�k���k���]#�]r6�(�k����]��]�6����PwM�s�wM�|�ǻû&ǟ�o{����y�۬3�f2���y�6������/�ɏ����~�}����ɓK����+��ǻ�����荒I��硷��0ͻ�A��<�6�<gi[�i��&�C��4�YG���b��#�ck1�s֑汵���)k�<�.@L�u�ylm �yN��y�,�y�9�<�6�<eM����i���4�� �4�YG���b��#�ck1�S֤yh]���9�H���@L�u�ylm �y�:�<�6�<eM����i���4�� �4�YG���b��#�ck1�S֤yh]���9�4��oa��9�汱p��9�H�X�@L�u�yd]���9�H���@L�u�ylm �y�:�<�6�<eM����i���4�� �4�YG���b��#�ck1�S֤yh]���9�H���@L�u�ylm �y�:�<�6��<%i:Gi�S�i+�i�s�4�� �4�YG���b���I�к�1�s֑汵���9�H���@L�u�ylm �yʚ4��<gi[�i���4�� �4�YG���b���I�к�1�s֑汵���9�H���@J�tO��Y8J�r�y�l�y�9�<�6�<gi[�i���4�� �4OY��ub��#�ck1�s֑汵���9�H���@L�5iZ �y�:�<�6�<gi[�i���4�� �4�Xg�G��i���4�� �4�YG���R��{����a���I�P��1�s֑汵���9�H���@L�u�ylm �yʚ4��<gi[�i���4�� �4�YG���b���I�к�1�s֑汵���9�H���@L�u�ylm �yʚ4��<gi[Hi���i;�i�s�4�� �4OY��ub��#�ck1�s֑汵���9�H���@L�5iZ �y�:�<�6�<gi[�i���4�� �4OY��ub��#�ck1�s֑汵���9�H���@L�5iZ �yN��y�,�y�9�<�6�<gi[�i��&�C��4�YG���b��#�ck1�s֑汵����L�Ⱥ1�s֑汵���9�H���@L�u�ylm �yʚ4��<gi[�i���4�� �4�YG���R���#�Cg�(�s�=�ce�0�sΑ汴���AOf�<�ߞy�1��<�K�w{%�o�4o<�4�v�y����OF��i�������]��˴��C=����]�_�Ga^9��3�{���9�6�9c��Y 'rʚD� �DNY�ȡ����)k9�6�9c��Y 'rʚD� �DNIG"���q"��I�P�@N�u&rd]���)k9�6�9eM"��r"��I���@N�u&rd]���)k9�6�9eM"��r"��I���@N�u&rd]���)k9�6�9eM"��r"��I���@N�u&rd]���)�ȡ�-9%�lj�r&�Ci9���D�+�9eM"��r"��I���@N�5�Zȉ���D���9eM"��r"��I���@N�5�Zȉ���D���9eM"��r"��I���@N�5�Z����&�#g�0�Sʑȡ�p��)g9�6�9eM"��r"g�3�#��DNY�ȡ����)k9�6�9eM"��r"g�3�#��DNY�ȡ����)k9�6�9eM"��r"g�3�#��DNY�ȡ����)k9�69%�:���Q&�#e�8�S�$r(m 'rʚD� �DNY�ȡ�����L�Ⱥ�9�S�$rhm 'rʚD� �DNY�ȡ�����L�Ⱥ�9�S�$rhm 'rʚD� �DNY�ȡ���� �k"�ȉ��&�Ck9�S�$rhm &rJ:9t�9㜉I 'rʚD� �DNY�ȡ����)k9�6�9c��Y 'rʚD� �DNY�ȡ����)k9�6�9c��Y 'rʚD� �DNY�ȡ����)k9�6�9c��Y 'rʚD� �DNIG"���q"��I�P�@N�u&rd]���)k9�6�9eM"��r"��I���@N�u&rd]���)k9�6�9eM"��r"��I���@N�u&rd]���)k9�6�9eM"��r"��I���@N�u&rd]���)�H��Y8N�3�Jȉ��&�Ck9�3֙ȑur"��I���@N�5�Zȉ��&�Ck9���D�+�9eM"��r"��I���@N�5�Zȉ���D���9eM"��r"��I���@N�5�Z����&�#g�0�Sʑȡ�p��)g9�6���K%r�9�D���x�?L�?Ƿ?���'��������-�������]�@�<�rO#���/_~�����˯�g<?~�x?~��}������������o�ly��;�� ������u���������g[ʺ?{����֧���AZdzl]���k�:�P���+�X����m)���k����9���k/[�����I�G�ٸ����ҹ?{E�����X���k�ϧ����?{����֗����_ōu<��x`�;==Y���k���ۯ�eݟ�bm��u��u���������k�w�<��x`ݾ��Giݟ�bm��u�n��u������k8[���k/[���p�~��Y�.������EZ�g�Xx`}<���u������ӣ� ���g�.+oϧ����gY����w�h���W� <�n��í���^�6���}�wҺ?{�������p'��Y�.��x_����hm ��[Ys]� ��"ʚ�"hm _1�y]�����(k�����|]DYs]� ��"ʚ�"hm _1�y]�����(k�����x]DI�ut���(g�����|]�X�u�.@�.���.���ue�u�6���(k�����|]�X�u�.@�.���.���ue�u�6���(k�����|]�X�u�.@�.���.���ue�u�6���(k�����|]�X�u�.@�.���u4���u%�E�X8�.���.���ua}�.���E�5�E��@�.���.���ue�u�6����.B���E�5�E��@�.���.���ue�u�6����.B���E�5�E��@�.���.���ue�u�6��i����qx]D)�uT���(g�����|]DYs]� ��"�:���u�ue�u�6���(k�����|]DYs]� ��"�:���u�ue�u�6���(k�����|]DYs]� ��"�:���u�ue�u�6���(k�����x]DI�ut��e����q|]D9s]� ��"ʚ�"hm _Q�\Ak������"d]�|]DYs]� ��"ʚ�"hm _Q�\Ak������"d]�|]DYs]� ��"ʚ�"hm _Q�\Ak�����^� +��"ʚ�"hm _Q�\Ak��"�,_1�y]�����(k�����|]DYs]� ��"ʚ�"hm _1�y]�����(k�����|]DYs]� ��"ʚ�"hm _1�y]�����(k�����|]DYs]� ��"ʚ�"hm _1�y]�����(k�����x]DI�ut���(g�����|]�X�u�.@�.���.���ue�u�6���(k�����|]�X�u�.@�.���.���ue�u�6���(k�����|]�X�u�.@�.���.���ue�u�6���(k�����|]�X�u�.@�.���:��E�3�EP�@�.���.���uc��EȺ������Z��E�5�E��@�.���.���ua}�.���E�5�E��@�.���.���ue�u�6����.B���E�5�E��@�.���.���ue�u�6��i����qx]D)�uT���(g�����|]/f\�.��c�.��c�u��ϱ���|����R�l_�=��}��0��~8?|�㗟�������Ǜ�?~������������t��?� +߿y�n����#3����>N��H���9W�$�hm '�ʚ� �\Y��������L�ɺ�9W�$�hm '�ʚ� �\IG���qn�3'��\Y�������+kp�6�peM��rn�3'��\Y�������+kp�6�peM��rn�3'��\Y�������+kp�6�peM��rn�3'��\Y�������+�H��Y8N��3 8J� ������peM��r��I���@N��5 8Z� ������peM��r��I���@N��5 8Z� ������peM��r��I���@N��5 8Z� ������p��p4��a��#Gc�8W�$�(m '������ur��I���@N��5 8Z� ��&Gk97֙��ur��I���@N��5 8Z� ��&Gk97֙��ur��I���@N��5 8Z� ��&Gk17�$��l&�J9pT�p�L��r��I���@N��u&�d]���+kp�6�peM��r��I���@N��u&�d]���+kp�6�peM��r��I���@N��u&�d]���+kp�6�peM��b��#Gg�07�$�l'�ʙ� �\Y�������+kp�6�pc� 8Y '�ʚ� �\Y�������+kp�6�pc� 8Y '�ʚ� �\Y�������+kp�6�pa}M���9W�$�hm '�ʚ� �\IG���qn�3'��\Y�������+kp�6�peM��rn�3'��\Y�������+kp�6�peM��rn�3'��\Y�������+kp�6�peM��rn�3'��\Y�������+�H��Y8N��3 8J� ������peM��r��I���@N��5 8Z� ������peM��r��I���@N��5 8Z� ������peM��r��I���@N��5 8Z� �����p% 8:� �r&Gi9W�$�hm '��:p�.@N��5 8Z� ��&Gk9W�$�hm '������ur��I���@N��5 8Z� ��&Gk97֙��ur��I���@N��5 8Z� ��&Gk17�$��l&�J9pT�p�L��r~0�?Ǟ����� ���������Y���^.���N��~�m���rQ=�3� x"����O?/e��_����O�/�p��U�w�_;�m��g|�����r��:��_���5�?��u��SY3�Dky������<�T?��@��u��SY3�Dky������<�T?��@iƟ�l�?�r�?QY8*gƟ(m �?�5�O�6�ǟ�:ǟd]�<�T?��@*kƟhm �?�5�O�6�ǟ�:ǟd]�<�T?��@*kƟhm �?�5�O�6�ǟ�:ǟd]�<�T?��@*kƟhm �?�t�?�Y8eƟ�l�?�3�O�6�ǟʚ�'Z��Oe��� ����'Y �?�5�O�6�ǟʚ�'Z��Oe��� ����'Y �?�5�O�6�ǟʚ�'Z��Oe��� ��?��y������<�T?��@*���p<�4�9�$���f�����SY3�Dky������<�4�9�$���f�����SY3�Dky������<�4�9�$���f�����SY3�Dky������<�4�9�$���f�����SI������rf������X�����ǟʚ�'Z��Oe��� ��f������X�����ǟʚ�'Z��Oe��� ��f������X�����ǟʚ�'Z��Oe��� ��f������X����ǟJ:Ɵ�,�?�3�O�6�ǟʚ�'Z��Oc��O�.@*kƟhm �?�5�O�6�ǟʚ�'Z��Oa}�u��SY3�Dky������<�T?��@��u��SY3�Dky������<�T?��@iƟ�l�?�r�?QY8*gƟ(m �?i�(Ɵ�9��盏���ϱ�?�WƟ�/����ǟ������ˇs��������u����|��������������?|#����|����p����������~,��s����;����:�t�ͯ�x�����t� �醲f����t�X�t����ʚ�Z�� e�t� �醒��:�� ��t�����rf����tCY3�@ky����n���<�0�9� ��醲f����tCY3�@ky����n���<�0�9� ��醲f����tCY3�@ky����n���<����XW O7�5� �6��ʚ�Z�� %� t���9�$]�<�P�L7��@�n(k�hm O7�5� �6���:�d]�<�P�L7��@�n(k�hm O7�5� �6���:�d]�<�P�L7��@�n(k�hm O7�5� �6���:�d]�<�P�L7��@�n(�n��p<�P�L7P�@�n�n�u�tCY3�@ky����n���<�P�L7��@�n�n�u�tCY3�@ky����n���<�P�L7��@�n�n�u�tCY3�@ky����n���<�P�L7��@�n�n�u�tCI�t����rf����tCY3�@ky�a�s�A��� e�t� �醲f����tCY3�@ky�!��� ��@�n(k�hm O7�5� �6��ʚ�Z�� c�� �.@�n(k�hm O7�5� �6��ʚ�Z�� #�t�����R��*�� ��t� ��-�t?�>�x�1`�q�9�ƻ]�����-O7�3�Ӎ�1����|�ۍ����1����O_>|�c�Ǘq����c���ָ�2ػ�W��]8�u{|�+_�|?�_���a�8���0c�'�Ⱥ��D���DZ�'5'���@>��9���0c�'�Ⱥ��D���DZ�'5'���@>��9���0#͉0r6O�)�8����0�̉0�6�O�)kN����|"�X�0�.@>��9���0e͉0�6�O�)kN����|"�X�0�.@>��ٙ����3U��L��@ޙ*kv�hm �L�u�Lɺ�yg��ٙ����3U��L��@ܙ*�ؙ��p�35��LI�8ޙ*gv�(m �L�5;S�6�w�ʚ�)Z�;Sc�;S�.@ޙ*kv�hm �L�5;S�6�w�ʚ�)Z�;Sc�;S�.@ޙ*kv�hm �L�5;S�6�w�ʚ�)Z�;Sa}ݙ�u��TY�3Ekyg��ٙ����3Uұ3Eg�xgj�sgJ��;Se��� 䝩�fg����TY�3Ekygj�sgJ��;Se��� 䝩�fg����TY�3Ekygj�sgJ��;Se��� 䝩�fg����TY�3Ekygj�sgJ��;Se��� ĝ����):�;S���� 䝩�Ν)Y �L�5;S�6�w�ʚ�)Z�;Se��� 䝩�Ν)Y �L�5;S�6�w�ʚ�)Z�;Se��� 䝩�Ν)Y �L�5;S�6�w�ʚ�)Z�;Se��� 䝩�Ν)Y �L�t�L�Y8ޙ*gv�(m �L�5;S�6�w��:w�d]��3U��L��@ޙ*kv�hm �L�5;S�6�w����3� +䝩�fg����TY�3Ekyg��ٙ����35ֹ3%�䝩�fg����TY�3Ekyg��ٙ����35��L��8ܙ*�ؙ��p�3U��LQ�@ޙ��Q�L�s�;�7v�ǟ�o<vs���|��x�ugzʠ�O��/�Ω鏟�u������y�Ϲ&�ӗ��?�W�~��\�>l�����c��}|<��Y�*��ͯ�xV��s���� �Y��fV���@IǬ����Y�QfV@���@93+@iyV������<+P�� +��@���u�@Y3+@kyV������<+P�� +��@���u�@Y3+@kyV������<+P�� +��@�����+�gʚYZȳeͬ�� �Y���Y:dz㜳�.@�(kfhm � +�5��6�gʚYZȳc���.@�(kfhm � +�5��6�gʚYZȳc���.@�(kfhm � +�5��6�gʚYZȳc���.@�(kfhm � +�t� +�Y8�(gf(m � +�u� +Ⱥ�yV������<+P�� +��@�(kfhm � +�u� +Ⱥ�yV������<+P�� +��@�(kfhm � +�u� +Ⱥ�yV������<+P�� +��@�(kfhm � +�u� +Ⱥ�qV��cV����@93+@iyV������<+0�9+ ��Y��fV���@Y3+@kyV������<+��YXW � +�5��6�gʚYZȳeͬ�� �Y���YY � +�5��6�gʚYZȳeͬ�� �Y��fV@���@)Ǭ����Y�rfV�����m1+�ϱ� +�|����|�������gy�uV�0f���ӿ��z�sMƎ�͌�������e����wo>������V��x������/+��e]8^uw�{�k��U��W� <��w��u�bk�P���C]lm �R��B��C]�:u���x��Yǡ.�6u9�8����.e͡.�.@<���P[����u�bk�P���C]lm �R�q����C]N��be��P�s�C],m �r�q��� �C]ʚC]h]�x��Yǡ.�6u9�8����.g����@<ԥ�9ԅ�����u�bk�P���C]lm �r�q��� �C]ʚE-Z .j�u,j��@\�:�XԲ����u�}Q���ѢV)Ǣ���E�s�E-K��Zg�Z�6��:�lm .j�5�Z�.@\�:�XԲ����uֱ�ekqQ�cQ���VY��E��E���E-[��Zg�Z�6��:�lm .j�u.jɺqQ�cQ����YǢ�� �E���Zv�ʙE-J .j�u,j��@\�:�XԲ����uֱ�ekqQ��YԢu��YǢ�� �E���E-[��Zg�Z�6�ʚE-Z .j�u,j��@\�:�XԲ����uֱ�ekqQ��YԢu��YǢ�� �E���Zv��9�,m .j�5�Z�.@\�:�XԲ����uֱ�ekqQ�cQ���VY��E��E���E-[��Zg�Z�6��:�lm .j�5�Z�.@\�:�XԲ����uֱ�ekqQ�cQ���VY��E��E���Zv��9�,m .j�u,j��@\�*k�h]���uֱ�ekqQ�cQ����YǢ�� �E���E-YW .j�u,j��@\�:�XԲ����uֱ�ekqQ��YԢu��YǢ�� �E���E-[��Zg�Z�6��J:��l-j�r_Բ�p��uα�eiqQKO�����홷���hQ��o;ԕ���������1/���nO��ϟ~���r��������w���?���/�_?�������˷�݀_Cz�k8�� �/����� ���W� <�>�^n��u���������Z�g�Xxٺ�G���w`��Y�.���5H��'���|�g�����c��ϧ��t��^�6�`�=F����r� +䕻�f����]Y�rGky宬Y�����r7ֹr'�䕻�f����]Y�rGky宬Y�����r7ֹr'�䕻�f����]Y�rGky宬Y�����r7Ҭ���8\�+�X���p�rWά�Q�@^�+kV�hm �܍u��ɺ�y宬Y�����rW֬���@^�+kV�hm �܍u��ɺ�y宬Y�����rW֬���@^�+kV�hm �܍u��ɺ�y宬Y�����rW֬���@\�+�X���p�r7ʬ�I�8^�+gV�(m �ܕ5+w�6�W�ʚ�;Z�+wc�+w�.@^�+kV�hm �ܕ5+w�6�W�ʚ�;Z�+wc�+w�.@^�+kV�hm �ܕ5+w�6�W�ʚ�;Z�+wa}]��u��]Y�rGky宬Y�����rWұrGg�x�n�s�N��+we��� 䕻�f����]Y�rGky�n�s�N��+we��� 䕻�f����]Y�rGky�n�s�N��+we��� 䕻�f����]Y�rGky�n�s�N��+we��� ĕ����;:�+w���� 䕻�Ε;Y �ܕ5+w�6�W�ʚ�;Z�+we��� 䕻�Ε;Y �ܕ5+w�6�W�ʚ�;Z�+we��� 䕻�Ε;Y �ܕ5+w�6�W�ʚ�;Z�+we��� 䕻�Ε;Y �ܕt���Y8^�+gV�(m �ܕ5+w�6�W��:W�d]��rW֬���@^�+kV�hm �ܕ5+w�6�W����r� +䕻�f����]Y�rGky宬Y�����r7ֹr'�䕻�f����]Y�rGky宬Y�����r7Ҭ���8\�+�X���p�rWά�Q�@^���dϕ;~�}���c����s��+��o=n�x�>�y]�?�uԿ|����˨���}�����~����n��û}������/����-�=Mܷ������~y��/��Nx�[����K��u<��x`�~o��u����և��iݟ�bm��u��u����s��7�&Ⱥ�9�P�hm ʚ`� �`BYL���L�&Ⱥ�)�P�=�@�[J8� 4�� �L0��r0!���XW ʚ`� �`BYL���L(k� �6�� c��Y ʚ`� �`BYL���L(k� �6�� c��Y ʚ`� �`BYL���L(k� �6� #M0A��a0��#�@e�8�P�(m ʚ`� �`�Xg0A�����&�@k9�P�hm ʚ`� �`�Xg0A�����&�@k9�P�hm ʚ`� �`�Xg0A�����&�@k9�P�hm J:� t� �L0A��q0�� &P�@&�5�Z����&�@k9�0�L�ur0�� &��@&�5�Z����&�@k9�0�L�ur0�� &��@&�5�Z����&�@k9���`�+�� eM0��r0�� &��@&�t�,�9� �.@&�5�Z����&�@k9�P�hm �:� �.@&�5�Z����&�@k9�P�hm �:� �.@&�5�Z����&�@k9�P�hm �:� �.@&�5�Z�����`���`B9L���L�&Ⱥ�9�P�hm ʚ`� �`BYL���L�&Ⱥ�9�P�hm ʚ`� �`BYL���L�&Ⱥ�9�P�hm ʚ`� �`BYL���L�&Ⱥ�1�P�L��pL(g� �6�� eM0��r0a�3� ��`BYL���L(k� �6�� eM0��r0!���XW ʚ`� �`BYL���L(k� �6�� c��Y ʚ`� �`BYL���L(k� �6� #M0A��a0��#�@e�8�P�(m ���~�=�x�1 �8���|��럘~���ۋ�l?u�m��_���}����3yd�%�G*�?}���������{���_~]?���|���W�W���nO�Gm������m�6�������t��E�����+�X�OϷֺ?{�������7��I�G�ٸ����ҹ?{E�����X���k�ϧ����?{����֗��x����zwzz����+�X����K���k�����E�u�����[���k�w�<��x`ݾ��Giݟ�bm��u�n��u������k8[���k/[���p���Y�.������EZ�g�Xx`}<���u������ӣ� ���g�.+oϧ����gY����w�h���W� <�n��í���^�6���}�wҺ?{����ֻ�k����,[��u�n�u������k8�8��+�X����Z�g�Xx�z>ݼ�s�Y�.�����Y���^�6���x�y����+�X�O�����+�^�>l_Ã��3�e�<�n_ý���^�6���} �/��W��;Pn�����3��"m�e����J�x�����}g�cn<{�����-�X���k�㊄��,Z�g)�u�� ��ʚ�hm ��P֜�@k�,���,Z�g)�u�� ��ʚ�hm ��P֜�@k�,���,Z�g)�u�� ���ʹ��@�[��P�q����ʙ�(m ���׳`]�|�BYs�� �ʚ�hm ��P֜�@k�,��γd]�|�BYs�� �ʚ�hm ��P֜�@k�,��γd]�|�BYs�� �ʚ�hm ��P֜�@k�,���,9�g)�r��@e��,�r�,J�g)�5g)��@>Ka��,Y ��P֜�@k�,���,Z�g)�5g)��@>Ka��,Y ��P֜�@k�,���,Z�g)�5g)��@>Ka��,Y ��P֜�@k�,���,Z�g)�t��@g��,�Q�,)�g)�3g)P�@>K��9K���Y +e�Y +�6��R�<KA��g)�5g)��@>K��9K���Y +e�Y +�6��R�<KA��g)�5g)��@>K��9K���Y +e�Y +�6��R��Y +��@>K��9K���Y +e�Y +�6�R(�8K����Y +�g)H���,���,Z�g)�5g)��@>K��9K���Y +c�g)Ⱥ��,���,Z�g)�5g)��@>K��9K���Y +c�g)Ⱥ��,���,Z�g)�5g)��@>K��9K���Y +c�g)Ⱥ��,���,Z�g)�t��@g��,�r�,J�g)�u�� ��ʚ�hm ��P֜�@k�,���,Z�g)�u�� ��ʚ�hm ��P֜�@k�,���,Z�g)�u�� ��ʚ�hm ��P֜�@k�,���,Z�g)�u�� �ijJ:�R��p|�B9s�� �ʚ�hm ��0�y�����R(k�R���|�BYs�� �ʚ�hm ���׳`]�|�BYs�� �ʚ�hm ��P֜�@k�,��γd]�|�BYs�� �ʚ�hm ��P֜�@k�,���,9�g)�r��@e��,�r�,J�g)�/+���9��o>��8���??��﮼�������'�{<�=�_.��Cy&�)��4�?����?}��o�^��ӏ_>~�������".|��)���:g4sF�o>�q4���@4��b4��#�Eg�8�5�͒tr4���f��@�f�5�,Z�Ѭ�&�Ek9�5�͒ur4���f��@�f�5�,Z�Ѭ�&�Ek9�5�͒ur4���f��@�f�5�,Z�Ѭ�&�Ek9�5�͒ur4���f��@�f�tD��,G�ʙh� �h�Xg4K��Ѭ�&�Ek9�U�D�hm G�ʚh� �h�Xg4K��Ѭ�&�Ek9�U�D�hm G�ʚh� �h�Xg4K��Ѭ�&�Ek9�U�D�hm G�ʚh� �h�Xg4K�HѬr��,��0�U�͢�p�*g�Y�6��Ya}�f��9�U�D�hm G�ʚh� �hVY͢����fɺ�9�U�D�hm G�ʚh� �hVY͢����fɺ�9�U�D�hm G�ʚh� �hVY͢���i�Yr6�Y��,*�Ѭr&�Ei9�U�D�hm G��:�Y�.@�f�5�,Z�Ѭ�&�Ek9�U�D�hm G��:�Y�.@�f�5�,Z�Ѭ�&�Ek9�U�D�hm G��:�Y�.@�f�5�,Z�Ѭ�&�Ek1�U�͢�p�e�YR6��Y�L4��r4���f��@�f�5�,Z�Ѭ��h����YeM4��r4���f��@�f�5�,Z�Ѭ��h����YeM4��r4���f��@�f�5�,Z�Ѭ��F�`]��*k�Y�6��YeM4��b4��#�Eg�8�5�͒tr4���f��@�f�5�,Z�Ѭ�&�Ek9�5�͒ur4���f��@�f�5�,Z�Ѭ�&�Ek9�5�͒ur4���f��@�f�5�,Z�Ѭ�&�Ek9�5�͒ur4���f��@�f�tD��,G�ʙh� �h�Xg4K��Ѭ�&�Ek9�U�D�hm G�ʚh� �h�Xg4K��Ѭ�&�Ek9�U�D�hm G�ʚh� �h�Xg4K��Ѭ�&�Ek9�U�D�hm G�ʚh� �h�Xg4K��Ѭ��h���hV9͢���*k�Y�6��Yc��,Y G�ʚh� �hVY͢���*k�Y�6��Ya}�f��9�U�D�hm G�ʚh� �hVY͢����fɺ�9�U�D�hm G�ʚh� �hVY͢���i�Yr6�Y��,*�Ѭr&�Ei9�=�?U4��c�f�|�f�?���^�fo�N��[�f�3�foG4����t���?]�{þT�>��}���>[^}�������W_�u5��Fk���ʚW_�����keͫ���@~�������+�_}��y�5Zȯ�Vּ�� �W_+k^}��u�����_}������@���5?Z���������8g�O������Gk��W�T�hm W�ʚ�� ��Xg�O������Gk��W�T�hm W�ʚ�� ��Xg�O������Gk��W�T�hm W�ʚ�� ��Xg�O������Gk��W�Q�p\�+g*~�6�+~c�?Y W�ʚ�� �_YS\�+k*~�6�+~c�?Y W�ʚ�� �_YS\�+k*~�6�+~c�?Y W�ʚ�� �_YS\�+k*~�6�+~c�?Y U�ʹW�h|Ê_ Gŏ��qů���Q�@������� +�_YS\�+k*~�6�+~eMŏ�r�o���'��_YS\�+k*~�6�+~eMŏ�r�o���'��_YS\�+k*~�6�+~eMŏ�b�o�����8���rT��,W�ʙ�� �_YS\���ɺ���W�T�hm W�ʚ�� �_YS\���ɺ���W�T�hm W�ʚ�� �_YS\���ɺ���W�T�hm W�ʚ�� Ċ_IGŏ��a�o���I�8���3?J�����Gk��W�T�hm W��:+~�.@���5?Z�����Gk��W�T�hm W��:+~�.@���5?Z�����Gk��W�T�hm W���Z�urů�����@���5?Z���������8g�O������Gk��W�T�hm W�ʚ�� ��Xg�O������Gk��W�T�hm W�ʚ�� ��Xg�O������Gk��W�T�hm W�ʚ�� ��Xg�O������Gk��W�Q�p\�+g*~�6�+~c�?Y W�ʚ�� �_YS\�+k*~�6�+~c�?Y W�ʚ�� �_YS\�+k*~�6�+~c�?Y W�ʚ�� �_YS\�+k*~�6�+~c�?Y V�J:*~t�+~�Lŏ�rů�����@���uV�d]�\�+k*~�6�+~eMŏ�rů�����@������� +�_YS\�+k*~�6�+~eMŏ�r�o���'��_YS\�+k*~�6�+~eMŏ�b�o�����8���rT��,W�ʙ�� ��8LW?~����1�+����7��z�)1V��T�w�������_?|�����������w������|�~��y���}���r��t��yg����v��?�qNJ��q�j��c%��UYӱ���ܱ*k:V�6�;VeMNJ�r�j��c%��UYӱ���ܱ*k:V�6�;VeMNJ�r�j��c%��UYӱ���ܱ*k:V�6�;VeMNJ�r�j��c%��UYӱ���ر*��X�Y8�X�3+J���Ύ���;VeMNJ�rǪ��X��@�X�5+Z���Ύ���;VeMNJ�rǪ��X��@�X�5+Z���Ύ���;VeMNJ�rǪ��X��@�X�5+Z���Ύ���:V��;V4��aǪ��cEc�cU�t�(m w���ڱ�urǪ��X��@�X�5+Z����cEk�c5�ٱ�urǪ��X��@�X�5+Z����cEk�c5�ٱ�urǪ��X��@�X�5+Z����cEk�c5�t��lv�J9:VT�;V�LNJ�rǪ��X��@�X�uv�d]�ܱ*k:V�6�;VeMNJ�rǪ��X��@�X�uv�d]�ܱ*k:V�6�;VeMNJ�rǪ��X��@�X�uv�d]�ܱ*k:V�6�;VeMNJ�bǪ��cEg�c5�t��lw�ʙ�� �UYӱ���ܱ*k:V�6�;Vc�+Y w�ʚ�� �UYӱ���ܱ*k:V�6�;Vc�+Y w�ʚ�� �UYӱ���ܱ*k:V�6�;Va}�X���cU�t�hm w�ʚ�� ĎUIGNJ��q�j��c%��UYӱ���ܱ*k:V�6�;VeMNJ�r�j��c%��UYӱ���ܱ*k:V�6�;VeMNJ�r�j��c%��UYӱ���ܱ*k:V�6�;VeMNJ�r�j��c%��UYӱ���ر*��X�Y8�X�3+J���Ύ���;VeMNJ�rǪ��X��@�X�5+Z���Ύ���;VeMNJ�rǪ��X��@�X�5+Z���Ύ���;VeMNJ�rǪ��X��@�X�5+Z���Ύ��;V%+:��r�cEi�cU�t�hm w��:;V�.@�X�5+Z����cEk�cU�t�hm w���ڱ�urǪ��X��@�X�5+Z����cEk�c5�ٱ�urǪ��X��@�X�5+Z����cEk�c5�t��lv�J9:VT�;V�LNJ�r�z�a��?�ޱ��б�o>p��OL�m��O���o�������Sۥ4��#{��rzӫ~����?���O?������>����|���R��r��������|�����Ϟ��~�����9n.��@l.�u4�lm 6�ʚ���Kg�%[�ͥ��播 ���YGs��bs��i.Ѻ���t��\����\:�h.��@l.�u4�lm 6�ʚ���Kg�%[Hͥ���%;�ͥs�撥 ��RY�\�ubs鬣�dk��t��\����\:�h.��@l.�5�%Z 6��:�K�6�Kg�%[�ͥ��播 ��RY�\�ubs鬣�dk��t��\����\:�h.��@l.�5�%Z 4�����d�[5�N�7�l,6��9�K�6�Kc��%YW 6��:�K�6�Kg�%[�ͥ��播 ��RY�\�ubs鬣�dk��t��\����\:�h.��@l.�5�%Z 6��:�K�6�Kg�%[�ͥ��播 ��RIGs���Qs�{s���as霣�di��t��\����\*k�K�.@l.�u4�lm 6��:�K�6�Kg�%[�ͥ���D����YGs��bs鬣�dk��t��\����\*k�K�.@l.�u4�lm 6��:�K�6��K'ݛKv��K��%*�ͥs�撥 ���YGs��bs鬣�dk��T�4�h]��\:�h.��@l.�u4�lm 6��:�K�6�KeMs���ͥ��播 ���YGs��bs鬣�dk��4��\�ubs鬣�dk��t��\����\:��\��p�\*g�K�.@l.�u4�lm 6��:�K�6�Kg�%[�ͥ���D����YGs��bs鬣�dk��t��\����\*k�K�.@l.�u4�lm 6��:�K�6�Kg�%[�ͥ���D����YGs��Rs�{s���as��_e�#Yzfٽ +��A9�/ᗡT]�&�&X!fB��Ff�꧗yؿ����e�3�p���0V���m��di��T�4�h@l.�u5�lm 6�κ�K�6�Kg]�%[�ͥ���D��bs鬫�dk��t��\����\:�j.��@l.�5�%Z�Kg]�%[�ͥ��播 ���YWs��bs��i.�:��\:鹹dgt��\����\:�j.��@l.�5�%Z�Kg]�%[�ͥ��播 ���YWs��bsi���$�bs鬫�dk��t��\����\:�j.��@l.�5�%Z�Kg]�%[�ͥ��播 ���YWs��Rs����Dg㨹t�ss���as霫�di���N�4��ߟ�~����c4���\�>�������z��\��_�U�_�������o���o�}��/�~��{�]����E�������������������㋼�}�"�X��ް6�s�������e��Y��������Z��ް6���|�����*����XO���a���� k??-�r���5Ϣu�����YZ��ް6��z������goXx`=}��z~�����+|���:�z��x`}<�y�MZ��ް6��z��eg]�����77;�����Y8��f��77�t�5+hm �(kV��@^P֬����"`�{E���+ʚ�6�W�5+hm �(kV��@^0ֽ"@��e͊�Z�+ʚ�6�W�5+hm ��^ ��fE�� �%]+�,�(gVP�@^0ֽ"@��e͊�Z�+ʚ�6�W�5+hm ��^ ��fE�� �e͊�Z�+ʚ�6�W�u��u�yE@Y�"��fE�� �e͊�Z�+ƺW�:��"���4^�pE@ ��+ʙ�6�W���"�� �e͊�Z�+ʚ�6�W�5+hm ��^ ��fE�� �e͊�Z�+ʚ�6�W�u��u�yE@Y�"��fE�� �e͊�Z�+F�r6W�r���p�"��Y@iyE@Y�"���� �(kV��@^P֬����"��Y@kyE�X���Y�W�5+hm �(kV��@^P֬����"`�{E���+ʚ�6�W�5+hm �(�Z@g�pE�(�"@���rfE�� �e͊�Z�+ʚ�6�W�u��u�yE@Y�"��fE�� �e͊�Z�+ƺW�:��"��Y@kyE@Y�"��fE�� �a���uyE@Y�"��fE�� �%]+�,��^ ��fE�� �e͊�Z�+ʚ�6�W�u��u�yE@Y�"��fE�� �e͊�Z�+ƺW�:��"��Y@kyE@Y�"��fE�� �c�+d@^P֬����"��kE�����̊�J�+ƺW�:��"��Y@kyE@Y�"��fE�� �c�+d@^P֬����"��Y@kyE@Y�"���� �(kV��@^P֬����"��Y@kyE�X���YW�t���p�"��Y@iyE@Y�"���� �(kV��@^P֬����"��Y@kyE@X/+`�@^P֬����"��Y@kyE@Y�"���� �(kV��@^P֬����"��Y@kqE�H�"@��ኀR�T�W�3+(m �`{E���"p��"p���t�z���O ��|�v�Ͽ��������O���P��;�kI���_~��/�xx|8�"���+���j>���軚w�/�k���=��>��xhm �xʚ� ��Xw�G��OYS㡵�\�)kj<�6�k<eM���r�g���#��r�������@��t�x�,�xʙ� ��Xw�G��OYS㡵�\�)kj<�6�k<eM���r�g���#��r�������@��55Z�5����Ck��3�]�u���S��xhm �xʚ� �OYS㡵�\����:�T�)��C�5k<%\5�5�r��Ci���K�� �OYS㡵�\�)kj<�6�k<eM���r�g���#��r�������@��55Z�5����Ck��3�]�u���S��xhm �xʚ� �OYS㡵�X�ij<r6k<�\5*�5�r��Ci��S��xhm �xƺk<� �xʚ� �OYS㡵�\�)kj<�6�k<c�5Y�k<eM���r�������@��55Z�5������5����Ck��S��xhm �xJ�j<tk<�L�G��q�����P�@��55Z�5����Ck��3�]�u���S��xhm �xʚ� �OYS㡵�\����:�\�)kj<�6�k<eM���r�������@���R�u��S��xhm �xʚ� �OIW����q�g���#��r�������@��55Z�5����Ck��3�]�u���S��xhm �xʚ� �OYS㡵�\����:�\�)kj<�6�k<eM���r�������@��u�xd@��55Z�5������O9S㡴�\����:�\�)kj<�6�k<eM���r�������@��u�xd@��55Z�5����Ck��S��xhm �xƺk<� �xʚ� �OYS㡵�\�)kj<�6�k<c�5Yk<%]5:�5�r��Ci��S��xhm �xƺk<� �xʚ� �OYS㡵�\�)kj<�6�k<a��x`�@��55Z�5����Ck��S��xhm �xƺk<� �xʚ� �OYS㡵�\�)kj<�6k<#M�G��a�����Ce��S��x(m �x�=����=�5��k@�w��ƻ�Q�}}=����k��̮�V���~���o?��v��pb��>�"�X�=��q�j�|#���F���=�F��/ Z� ���Dk�T�4�hm 7�ƺ@� 7�ʚ� �PY�������*k@�6�@c� Y�@eM��b���Dg�T�4�(m 7�ƺ@� 7�ʚ� �PY�������*k@�6�@c� Y�@eM��r��i���@n��5 Z� ������ ���Dk�T�4�hm 7�ʚ� ��XwH��P9� �a��*�j��X8n��3 J� ��^@�N 7�ʚ� �PY�������*k@�6�@c� Y�@eM��r��i���@n��5 Z� ������ ���Dk�T�4�hm 7�ʚ� ��H����q��*�j�QY8n��3 J� ���Dk�4����u��T�4�hm 7�ʚ� �PY��������n��:���*k@�6�@eM��r��i���@n��u7�d@n��5 Z� ���Dk�T�����p��e@R6�@�L��r��i���@n��5 Z� ������ ���Dk�T�4�hm 7�ʚ� ��XwH��PY�������*k@�6�@eM��r(���� ���Dk�T�4�hm 6�J�@t�@�� I�@eM��r��i���@n��5 Z� ������ ���Dk�T�4�hm 7�ʚ� ��XwH��PY�������*k@�6�@eM��rh��$��r��i���@l��t5��,7�ʙ� ��XwH��PY�������*k@�6�@eM��rh��$��r��i���@n��5 Z� ���Dk�4����u��T�4�hm 7�ʚ� �PY��������n��:���*�j��Y8n��3 J� ���Dk�4����u��T�4�hm 7�ʚ� �PY������� +��r��i���@n��5 Z� ���Dk�4����u��T�4�hm 7�ʚ� �PY�������i@r6@�\ *� �r�Di�<��T��qn��^����<~��\�!���gv�����6����h��R}�}|χ����x��|ϯ���_��E������?^�goXx`=}T��+�����+�4��X�u���T�4�hm 7�ʚ�� ��RY�X����X�n,�:��X*kK�6�KeMc��rc��i,��@n,�u7�d@n,�5�%Z����������R9�X����X�n,�:��X*kK�6�KeMc��rc��i,��@n,�u7�d@n,�5�%Zȍ����Dk��T�4�hm 7�ƺK� 7�ʚ�� ��RY�X����X*kK�6�Kcݍ%Y�K�<7�h��ac����DcḱT�4�(m 7��zi,�:��X*kK�6�KeMc��rc��i,��@n,�u7�d@n,�5�%Zȍ����Dk��T�4�hm 7�ƺK� 7�ʚ�� ��RY�X����X*kK�6K#McI��ac����DeḱT�4�(m 7�ʚ�� ���XwcI���RY�X����X*kK�6�KeMc��rci���$��rc��i,��@n,�5�%Zȍ����Dk��4��X�u���T�4�hm 7�ʚ�� ��RIWc���aci�i,I�8n,�3�%Jȍ����Dk��T�4�hm 7�ƺK� 7�ʚ�� ��RY�X����X*kK�6�Kcݍ%Y�KeMc��rc��i,��@n,�5�%Zȍ��^K�N 7�ʚ�� ��RY�X����X*�j,�Y8n,�s7�$@n,�5�%Zȍ����Dk��T�4�hm 7�ƺK� 7�ʚ�� ��RY�X����X*kK�6�Kcݍ%Y�KeMc��rc��i,��@n,�5�%Zȍ���ƒ�ȍ����Dk��T��X��p�X*gK�6�Kcݍ%Y�KeMc��rc��i,��@n,�5�%Zȍ���ƒ�ȍ����Dk��T�4�hm 7�ʚ�� ���XwcI���RY�X����X*kK�6�KeMc��rci���$��bc����DgḱT�4�(m 7�ʚ�� ���XwcI���RY�X����X*kK�6�KeMc��rc)����ȍ����Dk��T�4�hm 7�ʚ�� ���XwcI���RY�X����X*kK�6�KeMc��bci�i,��8l,�r5��,7�ʙ�� ���T�%�ǹ��z h,��c4�7���oQ�7���X>���?���������CXy���3�럮���������^O���7�o=t�~π���=<}��E>��g�:��ǻ��gi=?{���������7���� k�����Z��ް6�s���Ws�:�z��x`}<���MZ��ް6���|�Ϳ����am���������p=��'��?o�z��x`]�����Fk��V��hm �ʚ�� ���Xw�M���[YS|���\|+k�o�6��oeM��r�m���&��r�)���@.��5�7Z�ŷ���Fk��6�]|�u���V��hm �J��ot��o�L��r�m���&��r�)���@.��5�7Z�ŷ���Fk��6�]|�u���V��hm �ʚ�� ��[YS|���\|�.��:�\|+k�o�6��oeM��r�)���@.��u�d@*���\|���ŷ������[9S|���\|���r�)���@.��5�7Z�ŷ���Fk��6�]|�u���V��hm �ʚ�� ��[YS|���\|�.��:�\|+k�o�6��oeM��r�)���@,��4�79�ŷR������[9S|���\|+k�o�6��oc��7Y��oeM��r�)���@.��5�7Z�ŷ��⛬�ŷ���Fk��V��hm �ʚ�� ���Xw�M���[YS|���\|+k�o�6�o%]�7:�ŷQ��&e��V��(m �ʚ�� ��[YS|���\|�.��:�\|+k�o�6��oeM��r�)���@.��u�d@.��5�7Z�ŷ���Fk��V��hm ��z)��:�\|+k�o�6��oeM��b�Fg��6�]|�t���V��hm �ʚ�� ��[YS|���\|�.��:�\|+k�o�6��oeM��r�)���@.��u�d@.��5�7Z�ŷ���Fk��V��hm �ƺ�o� �ʚ�� ��[IW���q�)�Q�@.��u�d@.��5�7Z�ŷ���Fk��V��hm �ƺ�o� �ʚ�� ��[YS|���\|+k�o�6��oc��7Y��oeM��r�)���@.��5�7Z�ŷ��⛬�ŷ�������[9S|���\|+k�o�6��oc��7Y��oeM��r�)���@.��5�7Z�ŷ�^�o�N �ʚ�� ��[YS|���\|+k�o�6��oc��7Y��oeM��r�)���@.��5�7Z�ŷ���&g��V�U|��p\|+g�o�6����Y������5�����������c +ߪ{�U���-����O�����z&����~�������o�~�7?��o���?�����?ݽ�w�}���o!���织����l�~ۻ���/�9Z��^�s�N 7�ʚ�� ��\YӜ���ܜ+k�s�6��sc��9Y��seMs��rs��i���@lΕt5��,7�ƹ�s� 7�ʚ�� ��\YӜ���ܜ+k�s�6��sc��9Y��seMs��rs��i���@nΕ5�9Z���本���9Gk�9W�4�hm 7�ʚ�� ���XwsN���\YӜ���+�j��Y8nΕ3�9J���本���9Gk�9W�4�hm 7�ʚ�� ���XwsN���\YӜ���ܜ+k�s�6��seMs��rsn��9'��rs��i���@nΕ5�9Z���9Gk�97�ݜ�u��9W�ss��k6�J��s4��s�Ls��rs.�������9Gk�9W�4�hm 7�ʚ�� ���XwsN���\YӜ���ܜ+k�s�6��seMs��rsn��9'��rs��i���@nΕ5�9Z���9Gk�97�4��l6�J��sT��s�Ls��rs��i���@nu7�d@nΕ5�9Z���9Gk�9W�4�hm 7�ƺ�s� 7�ʚ�� ��\YӜ���ܜ+k�s�6��sc��9Y��seMs��rs��i���@lΕt5��,6�F�朔���\9Ӝ���ܜ+k�s�6��seMs��rsn��9'��rs��i���@nΕ5�9Z���9Gk�97�ݜ�u��9W�4�hm 7�ʚ�� ��\YӜ���ܜ�9�rs��i���@nΕ5�9Z���������8wsN���\YӜ���ܜ+k�s�6��seMs��rsn��9'��rs��i���@nΕ5�9Z���9Gk�97�ݜ�u��9W�4�hm 7�ʚ�� ��\YӜ���ܜ�n��:�ܜ+k�s�6�s%]�9:�r�9Gi�97�ݜ�u��9W�4�hm 7�ʚ�� ��\YӜ���ܜ�n��:�ܜ+k�s�6��seMs��rs��i���@nu7�d@nΕ5�9Z���9Gk�9W�4�hm 7�ƺ�s� 6�J��st��s�Ls��rs��i���@nu7�d@nΕ5�9Z���9Gk�9W�4�hm 7��zi��:�ܜ+k�s�6��seMs��rs��i���@nu7�d@nΕ5�9Z���9Gk�9W�4�hm 6�F�朜���\)Ws���qs��i�Q�@nΏ�i՜�{���׀���=��o��|�����2�������g�}�M���_\��^_�a�����֫���~�����������?��'��7� <�>�=~���7� <���=H����4��w��κ�e��X�^^���� k�k�@Y�����J��f%� �a��$�uy%AY�����J��f%� �e�JZ�+ ƺW�:�����YI@ky%AY�����J����t�W�s�$�t�y%AY�����J��f%� �e�JZ�+ ƺW�:�����YI@ky%AY�����J��f%� �c�+ d@^IP֬$�������YI@ky%AY�����J���� �$(kV��@\IPҵ�����J�rf%� �c�+ d@^IP֬$�������YI@ky%AY�����J���� �$(kV��@^IP֬$�������YI@ky%�X�JY�W�5+ hm �$(kV��@^IP֬$�����`�{%��H+ �y^I@�5W�p�$��p����YI@iy%AX/+ `�@^IP֬$�������YI@ky%AY�����J���� �$(kV��@^IP֬$�������YI@ky%�X�JY�W�5+ hm �$(kV��@^IP֬$�����`�YI g�p%A)�J*�+ ʙ��6�W�5+ hm �$�^I ���J��f%� �e�JZ�+ ʚ��6�W�u�$�u�y%AY�����J��f%� �e�JZ�+ ƺW�:�����YI@ky%AY�����J����tW�2+ �l�$(gVP�@^IP֬$�������YI@ky%�X�JY�W�5+ hm �$(kV��@^IP֬$�����`�{%���+ ʚ��6�W�5+ hm �$(kV��@^I��JX'�W�5+ hm �$(kV��@\IPҵ�����J�q�� �$(kV��@^IP֬$�������YI@ky%�X�JY�W�5+ hm �$(kV��@^IP֬$�����`�{%���+ ʚ��6�W�5+ hm �$(kV��@^I0ֽ�@��e�JZ�+ J�V�Y8^IPά$�����`�{%���+ ʚ��6�W�5+ hm �$(kV��@^I0ֽ�@��e�JZ�+ ʚ��6�W�5+ hm �$�^I ���J��f%� �e�JZ�+ ʚ��6�W�u�$�u�q%AI�J:�+ ʙ��6�W�5+ hm �$�^I ���J��f%� �e�JZ�+ ʚ��6�W������ �e�JZ�+ ʚ��6�W�5+ hm �$�^I ���J��f%� �e�JZ�+ ʚ��6W�4+ �l�$(�ZI@e�x%A9�����J��b%�㼒p�/_W��c�$��J������i%!�아�����?���H����OW��t$�������7���Cׯ�11y�{}x��E>����am��`��%]{�l�A8�ڃ`iq�Y�[�{κ� ��@܃P��A�u�q�Y�[�{κ� ��@܃pֵ������=�N �A8�ڃ`kq�Y�[�{κ� ��@܃P��A�u�q�Y�[�{κ� ��@ڃp��;�{ʙ=� �A8�ڃ`kq�Y�[�{κ� ��@܃P��A�u�q�Y�[�{κ� ��@܃pֵ�����f��{κ� ��@܃pֵ������=�6� �5{h@܃pֵ������� �Y8܃pε�����f��{κ� ��@܃pֵ������=�6� �5{h@܃pֵ������=�6� �u�A������ك@������=�6� �u�A�����k�� �=e�Z� ����a���=6� �s�A����a�{���{κ� ��@܃pֵ������=�6� �5{h@܃pֵ������=�6� �u�A������ك@������=�6� �u�A�����k�� �=%]{�l�A8�y����=�\{,m �A8�ڃ`kqBY����=g]{lm �A8�ڃ`kq�Y�[�{ʚ=� �A8�ڃ`kq�Y�[�{κ� ��@܃P��A�u�q�Y�[�{κ� ��@ڃp��;G{J�� P�8܃pε������=�6� �u�A������ك@������=�6� �u�A�����k�� �=e�Z� �u�A�����k�� �=g]{lm �A�ރ �����=�6� �u�A������=v� �3{(@܃pֵ������=�6� �u�A������ك@������=�6� �u�A�����k�� �=e�Z� �u�A�����k�� �=g]{lm �A(k� �:���k�� �='=�A��p��k�� �=e�Z� �u�A�����k�� �=g]{lm �A(k� �:���k�� �=g]{lm �A8�ڃ`kqBY����=g]{lm �A8�ڃ`kq�Y�[�{ʚ=� �A8�y����=�\{,m �A8�ڃ`kqBY����=g]{lm �A8�ڃ`kq�Y�[�{ƺ� �:���k�� �=g]{lm �A8�ڃ`kqBY����=g]{lm �A8�ڃ`kq�Y�[H{J�� ��8ڃp��+�{ι� X�@܃����{�ߟ�~��=x�z|{:�k� >]xz�{�������^噫=��,B����?~�寴��S=����|��������K=��멫W=��>��Shm �Sƺ�)� �Sʚz +� �zJIW=���q=����P�@���u�Sd@���5�Z������Bk��R��Shm �Sƺ�)� �Sʚz +� �zJYSO���\O)k�)�6��)c��Y��)eM=��r=������@���5�Z�����z��H��r��)4^ð�R�UO��p\O)g�)�6��)a��S`�@���5�Z������Bk��R��Shm �Sƺ�)� �Sʚz +� �zJYSO���\O)k�)�6��)c��Y��)eM=��r=������@���5�Z������"g㰞R�UO��p\O)g�)�6��)eM=��r=e���"��r=������@���5�Z������Bk��2�]O�u���R��Shm �Sʚz +� �zJYSO���\O뮧�:�\O)k�)�6��)eM=��b=����Bgᰞ2��S�l�Sʙz +� �zJYSO���\O)k�)�6��)c��Y��)eM=��r=������@���5�Z�����z��������Bk��R��Shm �Sʚz +� �zJX/�X'��)eM=��r=������@���t�S�,�Sƹ�)� �Sʚz +� �zJYSO���\O)k�)�6��)c��Y��)eM=��r=������@���5�Z�����z��������Bk��R��Shm �Sʚz +� �z�Xw=E��zJYSO���XO)骧�Y8���3�J�����z��������Bk��R��Shm �Sʚz +� �z�Xw=E��zJYSO���\O)k�)�6��)eM=��r=e���"��r=������@���5�Z������Bk��2�]O�u���R�UO��p\O)g�)�6��)eM=��r=e���"��r=������@���5�Z������Bk���K=� �zJYSO���\O)k�)�6��)eM=��r=e���"��r=������@���5�Z������Bk��2��S�l�SJ��)T��)�L=��r=u\��z +��\O]��S��1������oo_��Z�\�S��S�Ƿ??|�῟�������_�����O���绯��'�y�z���AU�O��a��_�#��|8�'���i���� ��ze�i=Zȧ�ʚ�z�6�O�u�֓u��^9ϧ�h���i���z4�O�3��(m �����ȧ�ʚ�z�6�O�5��hm ��+kN���@>�7�}ZO���ze�i=Zȧ�ʚ�z�6�O�5��hm ���>�'���i���� ��ze�i=Zȧ�ʚ�z�6O�4���l��+�:�Ge���^9sZ���i���� ��zcݧ�d@>�W֣֜��|Z��9�Gk��^YsZ���i����z� ��+kN���@>�W֣֜��|Z��9�Gk���X�i=Y�O�5��hm ��+kN���@<�W�uZ����i�Q洞����z��i=Jȧ�ʚ�z�6�O�5��hm ���>�'���i���� ��ze�i=Zȧ�ʚ�z�6�O�u�֓u���^YsZ���i���� ��ze�i=Zȧ��z9���i���� ��ze�i=Z���J�N��Y8>�7�}ZO���ze�i=Zȧ�ʚ�z�6�O�5��hm ���>�'���i���� ��ze�i=Zȧ�ʚ�z�6�O�u�֓u���^YsZ���i���� ��ze�i=Zȧ�ƺO��:�|Z��9�Gk�^I�i=:ǧ�ʙ�z�6�O�u�֓u���^YsZ���i���� ��ze�i=Zȧ�ƺO��:�|Z��9�Gk��^YsZ���i���� ��zcݧ�d@>�W֣֜��|Z��9�Gk��^YsZ���i����z� ��+�:�Gg���^9sZ���i���� ��zcݧ�d@>�W֣֜��|Z��9�Gk��^YsZ���i��^N��:�|Z��9�Gk��^YsZ���i���� ��zcݧ�d@>�W֣֜��|Z��9�Gk��^YsZ���i��洞����z�\���,��+gN�Q�@>�?>W��������x�?<�?~��?���7�pZ�U���-���v_��>}��LY��9��_���_?\��?���3���~r-��x��t�t����_�Zy���>|^�U�ۧ��ie��|�Y������{�<?{C�����ۓ����am��֯����`�X׳l���Sx��oe=?{�����c����7� <��>���-e=?{���ϭ��w���m��Y��������Z��ް6���|��"�X�ް6���z���7��z~�����[_N�Wi]ϲu������`KY��ް6��z�ߤ��� k�����Z��ް6�s���c�? �eg�����^�����!m����|���7� <������7� ���v��*�Yϲu���w//�z~�����织g���z��������U�����am��Aڗ����y�x`=}���z~���������"��goXx`=}��z~�����[�c�/<��<�>�=��I����X���_���� k��w�����7���\�pw��~�ɳ,���3x���7� <��>���z~�����ӧ��(��goX�����1<J�z��x`=}O�z~�������p/�Y�ް6��z��X����|�����7>y��x`}���*�Y�ް6�����WY�hm ����k}��@�Z_c�_�K���U�|�/Z�_뫤�k}�Y8�Z_����������ƺ�֗��_뫬�Z_�6���WY�hm ����k}��@�Z_c�_�K���U�|�/Z�_뫬�Z_�6���WY�=��������!� o)k����@�R�l����=���Bky{�X��Y�����=��kn)��Bc�x{H9�=������^���:��=���Bky{HY�=������f{� ��!c��Cd@�R�l����=���Bky{HY�=��������!� o)k����@�R�l����=���Bkq{�H�=D�����R��!T����3�C(m o)k����@�2ֽ=D���!e��Z��Cʚ�!�6����5�Chm o��"������f{� ��!e��Z��Cʚ�!�6����uo�u�y{HY�=������f{� ��!%]�C�,ne��H�8�R�l����=���Bky{HY�=��������!� o)k����@�R�l����=���Bky{�X��Y����5�Chm o)k����@�R�l����=$���!�N o)k����@�R�l����=��k{����!���C$@�R�l����=���Bky{HY�=��������!� o)k����@�R�l����=���Bky{�X��Y����5�Chm o)k����@�R�l����=d�{{����Cʚ�!�6���tm��p�=���Biy{�X��Y����5�Chm o)k����@�R�l����=d�{{����Cʚ�!�6����5�Chm o)k����@�2ֽ=D���!e��Z��Cʚ�!�6����5�Chm o��"��������!t����3�C(m o)k����@�2ֽ=D���!e��Z��Cʚ�!�6����5�Chm o �e{���Cʚ�!�6����5�Chm o)k����@�2ֽ=D���!e��Z��Cʚ�!�6����5�Chm ni����8�Rʵ=������rf{� ����Q�=��q��z �:~��=���C�g��=���zdm=������Ͽ���͔������?�@��~�:Xړ1�b{2��͎'c>�LƠ��<����Aky2�X�dY�'c�5�1hm O�(k&c��@��Q�LƠ��<c�{2��ȓ1ʚ��6�'c�5�1hm O�(k&c��@��1�LƐ�q<����Aiy2FY3���d��f2� ��cݓ1d@��Q�LƠ��<����Aky2FY3���d��^&c�:�<����Aky2FY3���d��f2� ��cݓ1d@��Q�LƠ��<����Akq2FI�d:Ǔ1ƹ'cH:�<����Aky2FY3���d��f2� ��cݓ1d@��Q�LƠ��<����Aky2FY3���d����� O�(k&c��@��Q�LƠ��<����Aky2�X�dY�'c�5�1hm N�(隌Ag�x2F93���d����� O�(k&c��@��Q�LƠ��<����Aky2�X�dY�'c�5�1hm O�(k&c��@��Q�LƠ��<c�{2��ȓ1ʚ��6�'c�5�1hm O�(k&c��@��1�=C����<OƠ���1J�&c�X8��Q�LƠ��<#����N O�(k&c��@��Q�LƠ��<����Aky2�X�dY�'c�5�1hm O�(k&c��@��Q�LƠ��<c�{2��ȓ1ʚ��6�'c�5�1hm O�(k&c��@��1�LƐ�q8��k2������dJȓ1ʚ��6�'c�uOƐu�y2FY3���d��f2� ��e�dZȓ1ƺ'c�:�<����Aky2FY3���d��f2� ��cݓ1d@��Q�LƠ��<����Akq2FI�d:��1F��R6�'c�3�1(m O�(k&c��@��Q�LƠ��<c�{2��ȓ1ʚ��6�'c�5�1hm O�(k&c��@��1�=C���e�dZȓ1ʚ��6�'c�5�1hm O��e2�ȓ1ʚ��6�'c�5�1hm N�(隌Ag�x2�8�dI�'c�5�1hm O�(k&c��@��Q�LƠ��<c�{2��ȓ1ʚ��6�'c�5�1hm O�(k&c��@��1�=C���e�dZȓ1ʚ��6�'c�5�1hm O�람!���d��f2� ��%]�1�,O�(g&cP�@��1�=C���e�dZȓ1ʚ��6�'c�5�1hm O�람!���d��f2� ��e�dZȓ1ʚ��6�'c�uOƐu�y2FY3���d��f2� ��e�dZȓ1ƺ'c�:�8��k2������dJȓ1ʚ��6�'c�uOƐu�y2FY3���d��f2� ��e�dZȓ1�z����d��f2� ��e�dZȓ1ʚ��6�'c�uOƐu�y2FY3���d��f2� ��e�dZ��1F��r6'c�rMƠ�p<����Aiy2��P�d��y2��5^'c��㟞�_�����_�~:�r�v�/��=��~�����^�=s�fc��O����_����_���+�/w_��h>���<��]�zzͤ�W�y��|H���@N�5i=Z�i��&�Gk9��KZ� �^Y�֣����+k�z�6��zeMZ��rZo�;�'��rZ��I���@N�5i=Z�i��������8wZO��^Y�֣����+k�z�6��zeMZ��rZo�;�'��rZ��I���@N�5i=Z�i��&�Gk9�7֝֓u�9�W֤�hm ��ʚ�� �^Y�֣�����N��:���+k�z�6�z%]i=:�i�r&�Gi9�7֝֓u�9�W֤�hm ��ʚ�� �^Y�֣�����N��:���+k�z�6��zeMZ��rZ��I���@N�u��d@N�5i=Z�i��&�Gk9�W֤�hm ��ƺ�z� ���yN��x ô^ WZ���qZ��I�Q�@N���փu9�W֤�hm ��ʚ�� �^Y�֣�����N��:���+k�z�6��zeMZ��rZ��I���@N�u��d@N�5i=Z�i��&�Gk9�W֤�hm ��F�����ô^)WZ���qZ��I�Q�@N�5i=Z�i����i��&�Gk9�W֤�hm ��ʚ�� ��XwZO��^Y�֣����+k�z�6��zeMZ��rZo�;�'��rZ��I���@N�5i=Z�i������ô�(�֓�q��+g�z�6��zeMZ��rZ��I���@N�u��d@N�5i=Z�i��&�Gk9�W֤�hm ��ƺ�z� ��ʚ�� �^Y�֣����+k�z�6��za���`�@N�5i=Z�i��&�Gk1�Wҕ֣�p���N�I:���+k�z�6��zeMZ��rZ��I���@N�u��d@N�5i=Z�i��&�Gk9�W֤�hm ��ƺ�z� ��ʚ�� �^Y�֣����+k�z�6��zc�i=Y��zeMZ��bZ��+�Gg�8�WΤ�(m ��ƺ�z� ��ʚ�� �^Y�֣����+k�z�6��zc�i=Y��zeMZ��rZ��I���@N�5i=Z�i����i��&�Gk9�W֤�hm ��ʚ�� ��XwZO�Ĵ^IWZ���qZ��I�Q�@N�5i=Z�i����i��&�Gk9�W֤�hm ��ʚ�� �^X/i=X'��zeMZ��rZ��I���@N�5i=Z�i����i��&�Gk9�W֤�hm ��ʚ�� Ĵ�H�֓�q��+�J�QY8N�3i=J�i=%�"���8��W�i��{����FZ��OL��3;�Xi����_~������ۿ��o�>�).�O��~�.�%��N,���8���"�X����X*kK�6�Kc݉%Y�KeMb��rb��I,��@N,�5�%Zȉ���Ē�ȉ��&�Dk9�T�$�hm '�ʚ�� ���XwbI���RY�X����X*�J,�Y8N,�3�%Jȉ���Ē�ȉ��&�Dk9�T�$�hm '�ʚ�� ���XwbI���RY�X����X*kK�6�KeMb��rbi�;�$��rb��I,��@N,�5�%Zȉ��&�Dk9�4֝X�u�)�T�sb��k&�J�K4�K�Lb��rb)����ȉ��&�Dk9�T�$�hm '�ʚ�� ���XwbI���RY�X����X*kK�6�KeMb��rbi�;�$��rb��I,��@N,�5�%Zȉ��&�Dk1�4�$��l&�J�KT�K�Lb��rb��I,��@N,�u'�d@N,�5�%Zȉ��&�Dk9�T�$�hm '�ƺK� '�ʚ�� ��RY�X����X*kK�6�Kc݉%Y�KeMb��rb��I,��@L,�t%��,&�F�Ē����R9�X����X*kK�6�KeMb��rbi�;�$��rb��I,��@N,�5�%Zȉ��&�Dk9�4֝X�u�9�T�$�hm '�ʚ�� ��RY�X����X +�%��rb��I,��@N,�5�%Z�����������8wbI���RY�X����X*kK�6�KeMb��rbi�;�$��rb��I,��@N,�5�%Zȉ��&�Dk9�4֝X�u�9�T�$�hm '�ʚ�� ��RY�X����X�N,�:��X*kK�6K%]�%:lj�r&�Di9�4֝X�u�9�T�$�hm '�ʚ�� ��RY�X����X�N,�:��X*kK�6�KeMb��rb��I,��@N,�u'�d@N,�5�%Zȉ��&�Dk9�T�$�hm '�ƺK� &�J�Kt�K�Lb��rb��I,��@N,�u'�d@N,�5�%Zȉ��&�Dk9�T�$�hm '��zI,�:��X*kK�6�KeMb��rb��I,��@N,�u'�d@N,�5�%Zȉ��&�Dk9�T�$�hm &�F�Ē����R)Wb���qb��I,Q�@N,��%��9��z H,������/����rb��ى�㧉���O�~��>�=��Lx1��;��fb o�˫7=N,?�$�hm '�ʚ�� ���XwbI���RY�X����X*kK�6�KeMb��rbi�;�$��rb��I,��@N,�5�%Zȉ��&�Dk9�4֝X�u�9�T�$�hm &�J�Kt�K�Lb��rbi�;�$��rb��I,��@N,�5�%Zȉ��&�Dk9�4֝X�u�9�T�$�hm '�ʚ�� ��RY�X����X�N,�:��X*kK�6�KeMb��rb��I,��@N,�u'�d@J,��X�����������R9�X����X +�%��rb��I,��@N,�5�%Zȉ��&�Dk9�4֝X�u�9�T�$�hm '�ʚ�� ��RY�X����X�N,�:��X*kK�6�KeMb��rb��I,��@L,�4�%9���R������R9�X����X*kK�6�Kc݉%Y�KeMb��rb��I,��@N,�5�%Zȉ���Ē�ȉ��&�Dk9�T�$�hm '�ʚ�� ���XwbI���RY�X����X*kK�6K%]�%:���Q&�$e�8�T�$�(m '�ʚ�� ��RY�X����X�N,�:��X*kK�6�KeMb��rb��I,��@N,�u'�d@N,�5�%Zȉ��&�Dk9�T�$�hm '��zI,�:��X*kK�6�KeMb��bb��+�Dg�8�4ΝX�t�9�T�$�hm '�ʚ�� ��RY�X����X�N,�:��X*kK�6�KeMb��rb��I,��@N,�u'�d@N,�5�%Zȉ��&�Dk9�T�$�hm '�ƺK� '�ʚ�� ��RIWb���qb��I,Q�@N,�u'�d@N,�5�%Zȉ��&�Dk9�T�$�hm '�ƺK� '�ʚ�� ��RY�X����X*kK�6�Kc݉%Y�KeMb��rb��I,��@N,�5�%Zȉ���Ē�����������R9�X����X*kK�6�Kc݉%Y�KeMb��rb��I,��@N,�5�%Zȉ��^K�N '�ʚ�� ��RY�X����X*kK�6�Kc݉%Y�KeMb��rb��I,��@N,�5�%Z����&�$g�0�TʕX��p�X*gK�6���NP%������5^����Ǿ����k���3&�yf'�O+��������ؕ������/?����������~�\>~��z�]�?�X~}8�Z�Tr��y���+�O^丒ck��S�Trh@��uUrlm Vrκ*9�6+9g]�[������C��b%笫�ck��s�s%���a%眫�ci��S�Trh@��uUrlm Vrκ*9�6+9g]�[������C��b%笫�ck��s�Uɱ��X�9����@��5�Z+9g]�[�����J�� �J�YW%��b%�����:�P�9��J���0���\ɱ�pX�9��X�@��uWrd�@��uUrlm Vrκ*9�6+9g]�[������C��b%笫�ck��s�Uɱ��X�9����@��5�Z+9g]�[�����J�� �J�YW%��R%����Cg㨒s�s%���a%眫�ci��s�Uɱ��X�)k*9� Vrκ*9�6+9g]�[�����J�� �JNYSɡu���s�Uɱ��X�9����@��uUrlm VrʚJ������J�� �J�YW%��R%��J����JN)W%���a%眫�ci��s�Uɱ��X�9����@��5�Z+9g]�[�����J�� �J�YW%��b%�����:�X�9����@��uUrlm Vrκ*9�6+9cݕY'+9g]�[�����J�� �J�Iϕ;���r��C��b%笫�ck��s�Uɱ��X�9����@��5�Z+9g]�[�����J�� �J�YW%��b%�����:�X�9����@��uUrlm Vrκ*9�6+9eM%���J�YW%��R%��J����J�9W%��b%�����:�X�9����@��uUrlm Vrκ*9�6+9eM%���J�YW%��b%笫�ck��s�Uɱ��X�)k*9� Vrκ*9�6+9g]�[�����J�� �JNYSɡu���s�s%���a%眫�ci��s�Uɱ��X�)k*9� Vrκ*9�6+9g]�[�����J�� �J�Xw%G� �J�YW%��b%笫�ck��s�Uɱ��X�)k*9� Vrκ*9�6+9g]�[�����J�� �JNIW%���Q%��J����J�9W%��b%�e��J����3ׯ��tT��{�~�|�}�������+������?0/OwoOO��./���#�/���������?��������?��o?���y���?]y>~���ѷ<~����C�/z��E����>��|b=?{������냵���am�������k*#=?���(O����t���!m����|���7� <������7� ���v���Gg]ϲu���w//�z~�������`��K�����am����1��}�����am������y�x`=}���z~����������!�z~�������po��goX�����1|yu��,[���x���&��goXx`=-�����am���������p�*|w��~�ɳ,���k��u}o3[�����{���@��fg]������6+k��������{���@��fg�"ZȋʚE +�6�)�u/R�u�y�BY�H���"��f�� �E +e�"Zȋƺ)�:��H��Y�@kq�BI�":NjʙE +�6�)�u/R�u�y�BY�H���"��f�� �E +e�"Zȋƺ)�:��H��Y�@ky�BY�H���"��f�� �E +cd@^�P�,R����H��Y�@ky�BY�H���"���E +� -R(�y���0\�PµH����"�rf�� �E +a�,R�uy�BY�H���"��f�� �E +e�"Zȋƺ)�:��H��Y�@ky�BY�H���"��f�� �E +cd@^�P�,R����H��Y�@ky�BY�H���"��f�����E +�\��,/R(g)P�@^�P�,R����Ha�{���ȋʚE +�6�)�5�hm /R(k)��@^�0ֽHA��E e�"ZȋʚE -�6�)�u.R�u�"��f�� �E -%��,/R(g)P�@^�0ֹHA�ȋʚE -�6�)�5�hm /R(k)��@^�0ֹHA�ȋʚE -�6�)�5�hm /R(k)��@^�0ֹHA�ȋʚE -�6�)�5�hm /R(k)��@^�0ֹHA���J:)�Y8^�P�,R����H��Y�@ky��X�"Y /R(k)��@^�P�,R����H��Y�@ky�BXϋ`]��H��Y�@ky�BY�H���"��f�� �E -c��d]��H��Y�@ky�BY�H���"��f�� �E -#�"9��J9)PY8^�P�,R����H����)�=�E���x:�.R����?�DA��?�<~�:������w'2�3yd[�8�M�����ç�����}ꕊ��>��m=��_������η��w��<�]xߙ�^��~���E �Ek9�U�$�hm &�J:�]t��]��.I '�ʚd� �dWY�좵���*k�]�6��]c��.Y '�ʚd� �dWY�좵���*k�]�6��]c��.Y '�ʚd� �dWY�좵���*k�]�6��]c��.Y '�ʚd� �dWIG����q���IvQ�@Nv�u&�d]���*k�]�6��]eM���r���Iv��@Nv�u&�d]���*k�]�6��]eM���r���Iv��@Nv�u&�d]���*k�]�6��]eM���r���Iv��@Nv�u&�d]���*����ɮ�d���dW9�좴��� -�9�� -�dWY�좵���*k�]�6��]eM���r�k�3�%��dWY�좵���*k�]�6��]eM���r�k�3�%��dWY�좵���*k�]�6��]eM���b�k�Iv��8Lv�r$��,'�ʙd� �dWY�좵����Lvɺ�9�U�$�hm '�ʚd� �dWY�좵����Lvɺ�9�U�$�hm '�ʚd� �dWY�좵����Lvɺ�9�U�$�hm '�ʚd� �dWIG����a�k�IvI�8Nv�3�.J�ɮ�&�Ek9�U�$�hm '��:�]�.@Nv�5�.Z�ɮ�&�Ek9�U�$�hm '��:�]�.@Nv�5�.Z�ɮ�&�Ek9�U�$�hm '��zNv��9�U�$�hm '�ʚd� �dWIG����q�k�3�%��dWY�좵���*k�]�6��]eM���r�k�3�%��dWY�좵���*k�]�6��]eM���r�k�3�%��dWY�좵���*k�]�6��]eM���r�k�3�%��dWY�좵���*�Hv�Y8Nv�3�.J�ɮ��d����]eM���r���Iv��@Nv�5�.Z�ɮ��d����]eM���r���Iv��@Nv�5�.Z�ɮ��d����]eM���r���Iv��@Nv�5�.Z�ɮ��d���]%�.:�ɮr&�Ei9�U�$�hm '��:�]�.@Nv�5�.Z�ɮ�&�Ek9�U�$�hm '��zNv��9�U�$�hm '�ʚd� �dWY�좵����Lvɺ�9�U�$�hm '�ʚd� �dWY�좵���i�]r6�]��.*�ɮr&�Ei9٥�T$��[�{�������χ��_�����3�����P�ot��}���x$��~�����~�ӷ/_����?~�����o����O��'O�;��7����sw�����B�/����y�BHY8nB�2I)�A�P�����(���p��eJR�;�LB��q"��e��1� �,�F��������(�~��p~��>@�8�>�p�>Hw�����F�A�K�F�܃�������z�+�F�Ѓ�����(Sy��p�xeR���}(�u�Q&� e�8�0ʔ�,wF������C(g���q�a� :HY8�9�25)�-�Q&� e�0��t ,V�7"�]�8�0�d,�F�|����xC(g���q�a� 7HY8�6�2�)�͆Q&� e�8���k��q\keb R�S �L�A��q�a��4HY8�4�r6�lF�@����<�(Sg��p�f�H3Hx �0C��e��`\ea�2���L�A��q�a��1HY8�1�r��l�F������(Sa��p�`eR����(���Q&� e�8�0ʔ�,wF�삔������\�+F��������(S[��p�Z�H-Hx ��Bgg��qea��,HY8N,�2�)�}�Q&� e�8���V��q\Ve� -R�� -�LUA��qSa�I*HY8*�r��l�F�������(SR��p�Qe2 -R�# -�� (��Q&� e�0�0�QO����&� c�8���M��q\Me� R�� �L1A��q/a��%HY8�%�r��l�F�P����L�(SI��p�He R� ��}(�u�Q&� e�8�0ʔ�,wF�,����(B(g��aa�#� �%�s#L A��qa�I!HY8!�rv�lWF������(S@��p�?e�R����s���\p\>e�R���L�@��q�`�IHY8�r��l�F������(S:��p�9e2R#aL��a�`|#p �%��#L�@��q۰{���z��l8�� �/�t �+]�������%�3)nG�����|���/?n����E���������?}��˟�~|��)�x�7ܞ^f�o�G����W������/w�hm _6�<m&���f�ܮ��x ��f%�h,�8+gn�Q�@�r��3XW :+k.���@�uV�;���|�wFk���X��3Y =+k����@�{V�>���|����}Fk���X��3Y @+k.���@��V�A���|����Fk��Hs -M���1�R�khT�3�(m �D+kn���@��6�yM�ȇ�ʚ�h�6�o��5��hm �G+k���@��6�y"M��G�ʚ+i�6�洛5��hm �J+kn���@��6�y.M���ʚ�i�6�o��5G�hm �M+鸛Fg��r�(s:M����r�z� ��ie�5Z�'�ʚj�6����u�Q�u�!���� �[je�15Z���ʚ{j�6�/��u�T�u�Q���� �je�a5Zȧ�ʚ�j�6�����|^ ���ʚk�6�o��5G�hm �Y+鸳Fg����8�5I [+k����@��V�\���|r����Fk���X��5Y ^+k.���@��V�_���|~����Fk��X� 6Y a+k����@��V�b���|�����Fk��X�96Y d+k.���@��V�q�����Y�r�.� ��lc���d]�|�����Fk�>[Ys����F� �+mc�g�d]�|�����Fk�V[Ys����^� �mc�'�d]�|�����Fk�n[Ys����鶲�v� ��mc���d]�x�������n��7J�g�ʚ;n�6�/��u�r�u�1���� �{ne�A7Z�'�ʚ�n�6�����|� �ȇ�ʚ�n�6�o��5��hm �w+k���@��6�y�M��G�ʚ+o�6�55��hm �z+kn���@��6Ҝ{��qx������o���7J�g��G����c;��x �����s��x<��<���x&��w����|����ÿg����×���?��v���7�wχ��?�������������p��ȿ�<t�kx{*|wxx���yǺ={��������Z�g�X�c}><��LY�g�X�����cx����gٺ�w��ý�n�^�6p�z�1�K��G�8��<�^���۳W� ��>��gp+��Y�.���X����hm �BY���6������Z��0���.@����Chm -CY�-�6������Z��0��E�.@�&���hm CY�������)k2�6�2c� Y %dʹ%dh��aB��#!Cc�8!S�$d(m 'd�zN���9!S�$dhm 'dʚ�� �LY��������L�Ⱥ�9!S�$dhm 'dʚ�� �LY��������L�Ⱥ�9!S�$dhm 'dʚ�� �LY�������i2r62� *� �r&!Ci9!S�$dhm 'd�:2�.@NȔ5 Z� ��&!Ck9!S�$dhm 'd�:2�.@NȔ5 Z� ��&!Ck9!S�$dhm 'd�:2�.@NȔ5 Z� ��&!Ck1!Sґ���p��e2R6�2�LB��rB��I���@NȔ5 Z� ��΄���2eMB��rB��I���@NȔ5 Z� ��΄���2eMB��rB��I���@NȔ5 Z� ���2��@NȔ5 Z� ��&!Ck1!Sґ���p���L�H��9!S�$dhm 'dʚ�� �LY��������L�Ⱥ�9!S�$dhm 'dʚ�� �LY��������L�Ⱥ�9!S�$dhm 'dʚ�� �LY��������L�Ⱥ�9!S�$dhm &dJ:2t�2�LB��rBf�3!#��LY�������)k2�6�2eMB��rBf�3!#��LY�������)k2�6�2eMB��rBf�3!#��LY�������)k2�6�2eMB��rBf�3!#�ĄLIGB���qB��I�P�@NȔ5 Z� ��΄���2eMB��rB��I���@NȔ5 Z� ���2��@NȔ5 Z� ��&!Ck9!S�$dhm 'd�:2�.@NȔ5 Z� ��&!Ck9!S�$dhm &dF�����ÄL)GB���qB��I�P�@N��k'���{l ��k<��&d����}=���ݞSB�g�����aۿ�~8>|���/��:>)�˟O���e+�����td/��ӯ��Eַ=���{Y�����_�n���)lm �)�:��6�gi -[�i��&MA��4�YG���b��#Mak1Mq֑������(k��.@LS�u�)lm �)�:��6�gi -[�i��&MA��4�9��)l��Q��[����a��#Mai1M1֙��ub��#Mak1Mq֑������8�HS��@LS�5i -Z �)�:��6�gi -[�i���4�� �4EY���ub��#Mak1Mq֑������8�HS��@JS�t�)�l�)N��)�,�)�9��6�gi -[�i��&MA��4�YG���b��#Mak1Mq֑������(k��.@LS�u�)lm �)�:��6�gi -[�i��&MA��4�YG���b��#Mak)Mq�-Mag�(MQʑ���q��8�HSX�@LS�u�)lm �)�:��6�eM����i���4�� �4�YG���b��#Mak1MQ֤)h]���8�HS��@LS�u�)lm �)�:��6�c�i -YW �)�:��6�gi -[Hi��ni -;�i�r&MA��4�YG���b��#Mak1Mq֑������(k��.@LS�u�)lm �)�:��6�gi -[�i��&MA��4�YG���b��#Mak1Mq֑������(k��.@LS�u�)lm �)N��)�,�)�9��6�eM����i���4�� �4�YG���b��#Mak1MQ֤)h]���8�HS��@LS�u�)lm �)�:��6�eM����i���4�� �4�YG���b��#Mak1MQ֤)h]���8閦��p��8�HSX�@LS�u�)lm �)ʚ4��gi -[�i���4�� �4�YG���b�b�3M!� -�4�YG���b��#Mak1Mq֑������(k��.@LS�u�)lm �)�:��6�gi -[Hi���4���4�)�4����4�9G���b��IS�=�?s��i -����u���}us�i�x&i��HS��k��������_��n��9;������^�r� z���Sx�<t��oO����{/��:�e�ܱ�o�u{����;�ӏ��Oʺ={������pc�۳W� ��r��)+eͷ�к���X�:����ⷱ�u|�� �oc9��6[���R�|������Xlm }�I�oc��p�m,���bi��X�:D�.@�5"Z���&@Dk9@T��hm ��:D�.@�5"Z���&@Dk9@T��hm ��:D�.@�5"Z���&@Dk9@T��hm ��:D�.@ -�s�x ��Q G����q��� Q�@�� �ur��� ��@�5"Z���&@Dk9@4� �ur��� ��@�5"Z���&@Dk9@4� �ur��� ��@�5"Z���&@Dk1@4���l�J9DT�D�L���r��� ��@�u�d]� *kD�6�DeM���r��� ��@�u�d]� *kD�6�DeM���r��� ��@�u�d]� *kD�6�DeM���b���#@Dg�0@4���l�ʙ�� ��QY ��� *kD�6�Dc�"Y �ʚ�� ��QY ��� *kD�6�Dc�"Y �ʚ�� ��QY ��� *kD�6�Da=�`]� *kD�6�DeM���b���#@Dg�8@4� �tr��� ��@�5"Z���&@Dk9@4� �ur��� ��@�5"Z���&@Dk9@4� �ur��� ��@�5"Z���&@Dk9@4� �ur��� ��@�t��,�ʙ�� ���Xg�H����&@Dk9@T��hm �ʚ�� ���Xg�H����&@Dk9@T��hm �ʚ�� ���Xg�H����&@Dk9@T��hm �ʚ�� ���Xg�H����������Q9 ��� *kD�6�Dc�"Y �ʚ�� ��QY ��� *kD�6�Da=�`]� *kD�6�DeM���r��� ��@�u�d]� *kD�6�DeM���r��� ��@�4"9��R������Q9 ��� �s*@���ċ�x�� �����6��/QN���q<���q���˿�������Ͽ���K��ۏ��������/�?��O�>��������߿~��~xx�0����>���o�����x�U?���e�~?������߀_�߸����o�}��@k�~CYs��������� �.@��P��o���|�����@k�~CI��:��F�� R6��7�3�(m �o(k�7��@��P��o���|�a��~����7�5�hm �o(k�7��@��P��o���|�a��~����7�5�hm �o(k�7��@��P��o���|�!��� ��@��P��o���|�����@k�~CI��:���9�7H���~CYs��������~� �� e��Z���:�7Ⱥ��~CYs��������~� �� e��Z���:�7Ⱥ��~CYs��������~� �� e��Z���:�7Ⱥ��~CYs��������� t��7�3�(m �o�� ��� e��Z��ʚ� �6��7�5�hm �o�� ��� e��Z��ʚ� �6��7�5�hm �o�� ��� e��Z��ʚ� �6��7�5�hm �o�� ��� %��,�o(g�7P�@��P��o���|�a��~����7�5�hm �o(k�7��@��P��o���|�!��� ��@��P��o���|�����@k�~CYs��������� �.@��P��o���|�����@k�~CYs��������~����� ���,�o(g�7P�@��ؿ P������k<���o����?p�����o�����}�����xs���g��v�q{x;��+��˗��f2���|x83��m�;������o?����5���{��������:��=�J�G�ٸ����x����+��Xw7ֺ={����������n�^�6�}���p���:�e�ܱ����u{����;��������ʺ={����������u{�����//ޜ~�ΚgѺw���ݣ�n�^�6p�z�1��-eݞ�bm����c8Z���k߷O?��ggϲu�X�N�q�EZ�g�X�c}<��ukݞ�bm�����h��?z�Y��������� 'ϲt�XO?�Gkݞ�bm����3x�����+��X�71�5�@k�#�:?�A���P�|d� �l(k>����G6�5�@k�#�:?�A���P�|d� �l(k>����G6�5�@k�#�:?�A���P�|d� ďl(���:��P�|d� �l���Y dCY� �6�?�����Z��P�|d� �l���Y dCY� �6�?�����Z��P�|d� �l���Y dCY� �6�?�����Z��P�|d� �l���Y }dC9��l����P�� 4�?�����J����G6���#ʚ�l����� e�G6��@�Ȇ��#hm d�X�G6Ⱥ��#ʚ�l����� e�G6��@�Ȇ��#hm d�X�G6Ⱥ��#ʚ�l����� e�G6��@�Ȇ��#hm ~d�H� r6?����#�,dC9� �6�?�����Z��0��� �.@�Ȇ��#hm dCY� �6�?�����Z��0��� �.@�Ȇ�f�� �e�HZ�# ʚ��6�G�u�4�u�H��f�� �e�HZ�# J:F�Y8i0ʌ4��q<Ҡ�i@iy�AY3Ҁ��H��f�� �c�# d]�<Ҡ�i@ky�AY3Ҁ��H��f�� �c�# d]�<Ҡ�i@ky�AY3Ҁ��H��f�� �a=�4�u�H��f�� �e�HZ�# J:F�Y8i0�9�@��# ʚ��6�G�5# hm �4(kF��@i0�9�@��# ʚ��6�G�5# hm �4(kF��@i0�9�@��# ʚ��6�G�5# hm �4(kF��@i0�9�@��# ʚ��6G�t�4��p<Ҡ�i@iy��X�HY �4(kF��@iP4���<Ҡ�i@ky��X�HY �4(kF��@iP4���<Ҡ�i@ky��X�HY �4(kF��@iP4���<Ҡ�i@ky��X�HY �4(�i@g�x�A93Ҁ��H��f�� �c�# d]�<Ҡ�i@ky�AY3Ҁ��H��f�� �a=�4�u�H��f�� �e�HZ�# ʚ��6�G�u�4�u�H��f�� �e�HZ�# ʚ��6G�4# �l�4(�i@e�x�A93Ҁ��H� ��|�m���5�vG��ci�呆��ӟ�p�a{b�h���5~��ۗ�|�����?�4>�����?��)|��^�r��_;̗X���p<�������_ìCο��8��[@B��qb� CHY8�B�rV!�l7!F�$���� �(Ӄ��p\�ebR�S��%(��Q&!e�81�4 �, F�������C(g���Q�a�[�A���6��]¸�0�Dd,'ו��c_���0���,�F�փ�����(z��p�y�<@�8n<�2�)ǁ�Q�� e��0���,�B9�P6���L�A��q�a�i:HY8.:�2A)�9�0���a���0��r���!��� c��0�D�,'B9P6�� �L�A��q�a�i7HY8.7�2�)�نP�j���f�(�l��plez R�k �L�A��q�!����e��0�d�,GF�F����B�G�A�K�:|�6��f��pfe�R���L�A��q�!����e��0���,�F������(b��p�a�0@�8n0�2 )��Q�� eḾ0���,�ו��b_�0�d�,GF�悔����GpA�K�B8k06�[�LjA��qha��,HY8�,�2�)lj�P������(�W��pWe� -R�� -�LXA��qV!����e㸩0�$�,F�������(S��p�R�,)@�8�(�2)��1�����0.(�0���P�z���v�(�N��pNe� R�� �L4A��q2!����e㸗0���,�F�V����R�(J��p�I�$@�8n$�2�)ǁ�Q�� eḎ0���,�B9�P6�cY /aEa�2���LA��q!����e㸅0ʤ�,�F����� -�(A��p�@\W��}����(�?��p?e�R���L�@��q� ��z�e�y0�$�,F�ށ�����(;��p�:cJ;���.a9a2���c|8�Kl}����v�ݗ�����p��� �����o��۾������Cy&��q4��˟?�����>~��eD ����������p�������������;�=�?�G��� -��oO_�+��!��𫘷�������/��d]�|��� ���@N��5 �Z���&@k90�Y�ur�����@��5=�Z�E��& @k9 -0�Y�uR��[��K�J8��4����L��r ��B��+�eM$��r&�����@.�5��Zȱ���Z���{eM0��r2��i��@��5��Z�ေ�r����eM<��r>�����@.�5 Z����" g�#P���p�(gZ�6�keMN��rP`��( ��@Y����(k��6��eMZ��r\`��. ��@Y����(k�6�+eMf��rh`��4 ���@Y����(kz�6�%�:�сQ�: e�;P΄(m �ʚ��� ��@Y���� �,Ⱥ��AP�Dhm gʚ� �AY�"���#�Ⱥ��GP� hm ' ʚ&� �*AY�%���&�L�� -�6AY'����'(k��6%�:Ǒ�q�J���;eM���r���i��@��5�Z�����b����eM���r������@.�5�Z���z����eM���r �i��@��5Z�!��Β���[eM̀�bΠ��g@g�hP�$ (m G �:��.@��5aZ�i���m@k�nP�� hm �:�.@n�5�Zș���s@k�tP֤hm ��:k�.@��5�Z�Ƀ��y@k�zP�dhm ��:��.@l�t��,�ʙ�� �BY�@���A� Ⱥ���Pքhm �ʚ� �BY�C���D빈�� -�&BYE����E(k��6��eM��ra��� ��>BYH����H(k �6�+ eM&��b(a�)%��8l%�r��,�ʙ^� �b���E2��5����M����M��k��'�(�xdk&�/������M�����x���o_���~���?��_����ç���н<ܾ�1��o? -�z���L�?���+�"����������o���^�u<���c�;���Z�g�X�c}<�)��G�8��<��ҹ={E���o�~��:�e�ܱ���(k�j���wM�56Ak��&ʚ� � ���Xg�D�ȁ��&pBk9pR�Nhm Nʚ� � ���Xg�D�ȁ��&pBk9pR�Nhm Nʚ� � ���Xg�D�H��rn�/a8)���X8��3�Jȁ���'��@��5�Zȁ��&pBk9pR�Nhm N�:'�.@��5�Zȁ��&pBk9pR�Nhm N�:'�.@��5�Zȁ��&pBk9pR�Nhm NF�������I)G����qज �P�@��5�Zȁ�������'eM���rब ���@��5�Zȁ�������'eM���rब ���@��5�Zȁ�������'eM���rब ���@��tN�,NF�������I98���8)k'�6�'eM���r�d�3p"���IY8���8)k'�6�'eM���r�d�3p"���IY8���8)k'�6�'eM���r�$��� �+�'eM���rब ���@��tN�,N�9'�.@��5�Zȁ��&pBk9pR�Nhm N�:'�.@��5�Zȁ��&pBk9pR�Nhm N�:'�.@��5�Zȁ��&pBk9pR�Nhm N�:'�.@��5�Z������ ����I98���8��Ⱥ�9pR�Nhm Nʚ� � ��IY8���8��Ⱥ�9pR�Nhm Nʚ� � ��IY8���8��Ⱥ�9pR�Nhm Nʚ� � ��IY8���8��Ⱥ�1pR�8��p8)g'�6�'eM���r�d�3p"���IY8���8)k'�6�'eM���r�$��� �+�'eM���rब ���@��5�Zȁ�������'eM���rब ���@��5�Z����&p"g�0pR�8��p8)g'�6���GN�[�t�8���89p:�������8=�������LJ?~��m�L��ۏ���������������_���������뷿�_�����Ͽ�=�~<����]�����xs��>��l�����_��u����l�.@��V��:��0��V�q�����u�r�:� ��la=_g�u�u���:� ��le�u6Z���ʚ�l�6����u^g�u�u���:� ��le�u6Z���ʚ�l�6����u^g�u�u���:� ��le�u6Z���ʚ�l�6���4���l^g+��Fe��:[9s����u���:� ��lc���d]�|�����Fk�:[Ys����u���:� ��lc���d]�|�����Fk�:[Ys����u���:� ��lc���d]�|�����Fk�:[Ys����u����lt���2�٤l_g+g��Q�@��V�\g���|�����Fk�:�X�u6Y _g+k����@��V�\g���|�����Fk�:�X�u6Y _g+k����@��V�\g���|�����Fk�:[X���`]�|�����Fk�:[Ys����u����lt����s^g�t�u���:� ��le�u6Z���ʚ�l�6����u^g�u�u���:� ��le�u6Z���ʚ�l�6����u^g�u�u���:� ��le�u6Z���ʚ�l�6����u^g�u�u���:� ��l%���,_g+g��Q�@��6�y�M����ʚ�l�6����5��hm _g+k����@��6�y�M����ʚ�l�6����5��hm _g+k����@��6�y�M����ʚ�l�6����5��hm _g+k����@��6�y�M����J:���Y8��V�\g���|�����Fk�:�X�u6Y _g+k����@��V�\g���|�����Fk�:[X���`]�|�����Fk�:[Ys����u���:� ��lc���d]�|�����Fk�:[Ys����u���:� ��l#�u69���J9��QY8��V�\g���|��.����=����xzٽ����_�?����d{x>�<����������_���k��z?�����������o��^猉���-��endstream +�6�)�5�hm /R�^� ���"��f�� �E +e�"Z��J�)�Y8\�0�,R��q�H��Y�@iy�BY�H���"��f�� �E +cd@^�P�,R����H��Y�@ky�BY�H���"���E +� /R(k)��@^�P�,R����H��Y�@ky�BX/�`�@^�P�,R����H��Y�@kq�BI�":Njƹ)H:��H��Y�@ky�BY�H���"��f�� �E +cd@^�P�,R����H��Y�@ky�BY�H���"���E +� /R(k)��@^�P�,R����H��Y�@ky��X�"Y�)�5�hm .R(�Z�@g�x�B9�H���"���E +� /R(k)��@^�P�,R����H��Y�@ky��X�"Y�)�5�hm /R(k)��@^�P�,R����Ha�{���ȋʚE +�6�)�5�hm /R(k)��@^�0ֽHA��E +%]��,/R(g)P�@^�P�,R����Ha�{���ȋʚE +�6�)�5�hm /R(k)��@^���"X'�)�5�hm /R(k)��@^�P�,R����Ha�{���ȋʚE +�6�)�5�hm /R(k)��@\�0�,R��q�H��k����E +��"Jȋ�� +j���Hq�/_)�����<>�"��W���@_�<|:����#�E��ڤX_�����ˇog�^�����G��p����~���H��y�� ?���{���{|2 +q~��x`]+ʚ� �6�g7�5�hm �n(kf7��@��0��n��q<�����@iyvCY3����솲fv� �� cݳd@��P��n���<�����@kyvCY3����솰^f7�:�<�����@kyvCY3����솲fv� �� cݳd@��P��n���<�����@kqvCI��:dzƹg7H:�<�����@kyvCY3����솲fv� �� cݳd@��P��n���<�����@kyvCY3����솱�� � �n(kf7��@��P��n���<�����@kyv�X��Y�g7�5�hm �n(��@g�xvC93����솱�� � �n(kf7��@��P��n���<�����@kyv�X��Y�g7�5�hm �n(kf7��@��P��n���<�a�{v��ȳʚ� �6�g7�5�hm �n(kf7��@��0�=�A��� �<�n����J�f7�X8��P��n���<�!��� �N �n(kf7��@��P��n���<�����@kyv�X��Y�g7�5�hm �n(kf7��@��P��n���<�a�{v��ȳʚ� �6�g7�5�hm �n(kf7��@��0��n��q8���kv���� ���Jȳʚ� �6�g7�u�n�u�yvCY3����솲fv� �� e��Zȳƺg7�:�<�����@kyvCY3����솲fv� �� cݳd@��P��n���<�����@kqvCI��:��F�� R6�g7�3�(m �n(kf7��@��P��n���<�a�{v��ȳʚ� �6�g7�5�hm �n(kf7��@��0�=�A��� e��Zȳʚ� �6�g7�5�hm �n�ev�ȳʚ� �6�g7�5�hm �n(��@g�xv�8��I�g7�5�hm �n(kf7��@��P��n���<�a�{v��ȳʚ� �6�g7�5�hm �n(kf7��@��0�=�A��� e��Zȳʚ� �6�g7�5�hm �n�� ���솲fv� �� %]��,�n(gf7P�@��0�=�A��� e��Zȳʚ� �6�g7�5�hm �n�� ���솲fv� �� e��Zȳʚ� �6�g7�u�n�u�yvCY3����솲fv� �� e��Zȳƺg7�:�8���kv���� ���Jȳʚ� �6�g7�u�n�u�yvCY3����솲fv� �� e��Zȳ�z�����솲fv� �� e��Zȳʚ� �6�g7�u�n�u�yvCY3����솲fv� �� e��Z��F�� r6g7�r�n��p<�����@iyv�F$����yv��5`v��=�f7��*�������=\�8?q�xX����/_~�����o?���z������?����v���}����������ޥ�=~ٝ�^������뒲p��eJ]R;]c\�. �a� +�nt��8.t�2�.)�y�Q��%e��5ʤ��,��B��\P6��\�L�K��q�k�)rIY8�q�29.)�1�P�����(⒲p��e*\R�\�L�K��q�+���e㸾5�ķ�,��Ƹ�[^ø�5�d�d,G�B��[P6��[�LpK��qnk��mIY8nm�2�-)ǡ�P�������(ْ�p��e +[R��Z�L^K��q\+���e㸬5ʄ��,g�F�������(�Ԓ�p� +��iA�8�i��Ӓ� +�)�����t�0�h�0-��m奡=V�F������|�(Sϒ�p��e�YR��Y���,(�լQ&�%e�8�5���,��F�\����XV(w+��q)k� eIY8�d�2�,)Ǎ�Q&�%e�0���� ,ֱƷ�X�]�8�5�d,w�F�,����(V(w��qk� bIY8�a�25,)�-�Q&�%e�8������q\�e"XR�X�LK��q�j��_IY8�_�r���l��F����(S���pؼ�J^Ix ��U�һ��`\�abW2�SW�L�J��q�j��\IY8�\�r7��l�F�������(S���pܶe�VR��V��]+(�U�Q&j%e�8i5���,��F���������Ҳ+�KV�L�J��q�j��XIY8lX�q%�$��q�*��_c�^5�ī�,��F�r����n�(����p� +�nVA�8.V�2�*)ǹ�Q�V%e�U5ʤ��,��B�;UP6�+U�L�J��q�j�)TIY8�S�2y*)�q�P�6���2�(���p���RIx �&�����p� +��QA�8�Q�21*)�)�Q�D%e�C5�d��,G�B�TP6�T�L�J��q~j��OIY8nO�2�))��P�������(���p��e�SR�{S�LnJ��ql*��5e�45����ƙ��2%c�15�$��,�B��RP6��R�L\J��qZj�)KIY8�J�2Y))�Q�m�)=V�F�������(S���pܒeRRR�CR��)(��Q&"%e�8!5���,��F�|����xTӎ��`X�� +G�w �l�S���p܌B�(�Qz�s1zyF_⟞�_�����ӯA�;�W��u�������3iF������o���ǯ������������/���o��/��ϗ|��7� �N��w�p���q����� �AY8����8�n�:�\9(k2�6�CeM��r렬���@��u�d@.�5�Z�у��z@k�{Pքhm �ƺ�� ��y��x ��B W���q��� P�@� ���A�u��P֤hm �ʚ� �BYD����D�n"�:�\E(k��6��eM��r���#��@�#�u�d@.$�5�Zȑ����@k��Pքhm �F�V����ZB)W.���q0��)&P�@n&�5�Z�ل��n���儲&�@k9�P��hm �ʚ�� ��XwCA��BY�Q���R(kJ +�6�[ +eML��rNa��� ��rQ��I*��@�*�5UZ�]������ô�(�V��q\W(g� +�6�eMa��rc���,��@�,�uwd@.-�5�Zȱ����@k��P�hm 'ƺ�� Wʚ�� ��BYS^����^(k��6��a��`�@.0�5 Z�����@k��P�b��p�b�n1H:�\c(kr�6��eM���r����2��@�2�uwd@.3�5iZ�q����@k��P�hm 'ƺ � WʚL� �PCYSj����j(kb �6�s cݽY�� eM���b�����@g��P΄(m �ƺ� � �ʚ|� �CYSp����p(k"�6�3c�Y�KeMʁ�r̡��9��@�9�5AZ�I����U��&�@k9�P֔hm �ʚ�� ��Xw�A���CIW���q䡜�<P�@�<�5�Zȩ���փ�ȵ��&�@k9�P�hm 7ʚ�� ��CX/�X'��eM���r����?��@�?�5Z� ��������&Ak9Q֔ hm � ʚ� ��HӃ��qX�(�JBPY8�B�3UJ�]�qʠ�|�sr�����hCn�!��jO/܆�g҆�����_���_�z�w?�/���߿W�������O���g������@���2��>���}�}�q|���E��� ��ocݧ�d@:�V���7�ax���������o���7Jȧ��z9���鷲��� ��oe��7Zȧ�ʚ�o�6�O��u�~�u���[Ys����鷲��� ��oe��7Zȧ�ƺO��:�|���9�Fk��[Ys����鷲��� ��o#��79���J�N�QY8>�VΜ~���|���9�Fk���X��7Y�O��5��hm �~+kN���@>�V֜~���|�m�����ȧ�ʚ�o�6�O��5��hm �~+kN���@>�6�}�M���oe��7Zȧ�ʚ�o�6O��t�~��px�m�9�&e���[9s����鷲��� ��oe��7Zȧ�ƺO��:�|���9�Fk��[Ys����鷲��� ��ocݧ�d@>�V֜~���|���9�Fk��[Ys����鷰^N��:�|���9�Fk��[Ys����鷒��ot�O��s�~�t���[Ys����鷲��� ��oe��7Zȧ�ƺO��:�|���9�Fk��[Ys����鷲��� ��ocݧ�d@>�V֜~���|���9�Fk��[Ys����鷱��o� �~+kN���@<�V�u������r��� ��ocݧ�d@>�V֜~���|���9�Fk��[Ys����鷱��o� �~+kN���@>�V֜~���|���9�Fk���X��7Y�O��5��hm �~+kN���@>�V֜~���|�m��������J�N��Y8>�VΜ~���|���9�Fk���X��7Y�O��5��hm �~+kN���@>�V֜~���|�-���o�N �~+kN���@>�V֜~���|���9�Fk���X��7Y�O��5��hm �~+kN���@>�V֜~���x�m�9�&g���[)��7*ǧ�ʙ�o�6�O������7������5����=���8�����̧�뙜~?������??|���;^�����_�˿����o��Å�������B�w�x��~�zp��t�������?��S�ǻ��?�}|�O��goXx`}���b��goXx`}���������am��֯����'0c]ϲu������Z��ް6��z������7��;P�>���Ô��� i����<H�z��x`]_������6��=DY��!hm {����C��@��c��B��oQ�|{Z�������6��=DY��!hm {���o!���(k�=� �oQ�$dhm 'dʚ�� ��XwBF���L9� �a��)�J��X8NȔ3 J� ��^2�N 'dʚ�� �LY�������)k2�6�2c� Y�2eMB��rB��I���@NȔ5 Z� ���� ��&!Ck9!S�$dhm 'dʚ�� Ą�H����q��)�J�PY8NȔ3 J� ��&!Ck9!3֝��u�9!S�$dhm 'dʚ�� �LY��������N��:���)k2�6�2eMB��rB��I���@NȌu'dd@NȔ5 Z� ��&!Ck1!Sҕ���p��e2R6�2�LB��rB��I���@NȔ5 Z� ���� ��&!Ck9!S�$dhm 'dʚ�� ��XwBF��LY�������)k2�6�2eMB��rB&����� ��&!Ck9!S�$dhm &dJ�2t�2�� I�2eMB��rB��I���@NȔ5 Z� ���� ��&!Ck9!S�$dhm 'dʚ�� ��XwBF��LY�������)k2�6�2eMB��rBf�;!#��rB��I���@LȔt%d�,'dʙ�� ��XwBF��LY�������)k2�6�2eMB��rBf�;!#��rB��I���@NȔ5 Z� ��&!Ck9!3֝��u�9!S�$dhm 'dʚ�� �LY��������N��:���)�J��Y8NȔ3 J� ��&!Ck9!3֝��u�9!S�$dhm 'dʚ�� �LY������� �%!�rB��I���@NȔ5 Z� ��&!Ck9!3֝��u�9!S�$dhm 'dʚ�� �LY�������i2r62�\ *� �r&!Ci9!;��TB��qNȮ^���0!;~��oßO��?پ��|� #/�w/��p�zI�Nz������۟���?�����t��endstream endobj -1617 0 obj << +1645 0 obj << /Type /Page -/Contents 1618 0 R -/Resources 1616 0 R +/Contents 1646 0 R +/Resources 1644 0 R /MediaBox [0 0 609.714 789.041] -/Parent 1174 0 R -/Annots [ 1620 0 R 1621 0 R 1622 0 R 1623 0 R 1624 0 R 1625 0 R 1626 0 R 1627 0 R 1628 0 R 1629 0 R 1630 0 R 1631 0 R 1632 0 R 1633 0 R 1634 0 R 1635 0 R 1636 0 R 1637 0 R 1638 0 R 1639 0 R 1640 0 R 1641 0 R 1642 0 R 1643 0 R 1644 0 R 1645 0 R 1646 0 R 1647 0 R 1648 0 R 1649 0 R 1650 0 R 1651 0 R 1652 0 R 1653 0 R 1654 0 R 1655 0 R 1656 0 R 1657 0 R 1658 0 R 1659 0 R 1660 0 R 1661 0 R 1662 0 R 1663 0 R 1664 0 R 1665 0 R 1666 0 R 1667 0 R 1668 0 R 1669 0 R 1670 0 R 1671 0 R 1672 0 R 1673 0 R 1674 0 R 1675 0 R 1676 0 R 1677 0 R 1678 0 R 1679 0 R 1680 0 R 1681 0 R 1682 0 R 1683 0 R 1684 0 R 1685 0 R 1686 0 R 1687 0 R 1688 0 R 1689 0 R 1690 0 R 1691 0 R 1692 0 R 1693 0 R 1694 0 R 1695 0 R 1696 0 R 1697 0 R 1698 0 R 1699 0 R 1700 0 R 1701 0 R 1702 0 R 1703 0 R 1704 0 R 1705 0 R 1706 0 R 1707 0 R 1708 0 R 1709 0 R 1710 0 R 1711 0 R 1712 0 R 1713 0 R ] +/Parent 1202 0 R +/Annots [ 1648 0 R 1649 0 R 1650 0 R 1651 0 R 1652 0 R 1653 0 R 1654 0 R 1655 0 R 1656 0 R 1657 0 R 1658 0 R 1659 0 R 1660 0 R 1661 0 R 1662 0 R 1663 0 R 1664 0 R 1665 0 R 1666 0 R 1667 0 R 1668 0 R 1669 0 R 1670 0 R 1671 0 R 1672 0 R 1673 0 R 1674 0 R 1675 0 R 1676 0 R 1677 0 R 1678 0 R 1679 0 R 1680 0 R 1681 0 R 1682 0 R 1683 0 R 1684 0 R 1685 0 R 1686 0 R 1687 0 R 1688 0 R 1689 0 R 1690 0 R 1691 0 R 1692 0 R 1693 0 R 1694 0 R 1695 0 R 1696 0 R 1697 0 R 1698 0 R 1699 0 R 1700 0 R 1701 0 R 1702 0 R 1703 0 R 1704 0 R 1705 0 R 1706 0 R 1707 0 R 1708 0 R 1709 0 R 1710 0 R 1711 0 R 1712 0 R 1713 0 R 1714 0 R 1715 0 R 1716 0 R 1717 0 R 1718 0 R 1719 0 R 1720 0 R 1721 0 R 1722 0 R 1723 0 R 1724 0 R 1725 0 R 1726 0 R 1727 0 R 1728 0 R 1729 0 R 1730 0 R 1731 0 R 1732 0 R 1733 0 R 1734 0 R 1735 0 R 1736 0 R 1737 0 R 1738 0 R 1739 0 R 1740 0 R 1741 0 R ] >> endobj -1620 0 obj << +1648 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 706.187 295.75 715.098] +/Rect [95.641 706.187 189.997 715.098] /Subtype /Link -/A << /S /GoTo /D (individual-buglists) >> +/A << /S /GoTo /D (query) >> >> endobj -1621 0 obj << +1649 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 706.187 537.983 715.098] /Subtype /Link -/A << /S /GoTo /D (individual-buglists) >> +/A << /S /GoTo /D (query) >> >> endobj -1622 0 obj << +1650 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 693.235 159.86 702.147] +/Rect [119.552 695.293 206.166 702.147] /Subtype /Link -/A << /S /GoTo /D (bugreports) >> +/A << /S /GoTo /D (boolean) >> >> endobj -1623 0 obj << +1651 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 693.235 537.983 702.147] +/Rect [528.02 695.293 537.983 702.147] /Subtype /Link -/A << /S /GoTo /D (bugreports) >> +/A << /S /GoTo /D (boolean) >> >> endobj -1624 0 obj << +1652 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 680.284 231.372 689.195] +/Rect [143.462 682.341 260.263 689.195] /Subtype /Link -/A << /S /GoTo /D (fillingbugs) >> +/A << /S /GoTo /D (pronouns) >> >> endobj -1625 0 obj << +1653 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 680.284 537.983 689.195] +/Rect [528.02 682.341 537.983 689.195] /Subtype /Link -/A << /S /GoTo /D (fillingbugs) >> +/A << /S /GoTo /D (pronouns) >> >> endobj -1626 0 obj << +1654 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 667.333 234.958 676.244] +/Rect [143.462 667.333 212.164 676.244] /Subtype /Link -/A << /S /GoTo /D (cloningbugs) >> +/A << /S /GoTo /D (negation) >> >> endobj -1627 0 obj << +1655 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 667.333 537.983 676.244] /Subtype /Link -/A << /S /GoTo /D (cloningbugs) >> +/A << /S /GoTo /D (negation) >> >> endobj -1628 0 obj << +1656 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 656.438 163.436 663.293] +/Rect [143.462 654.381 238.664 663.293] /Subtype /Link -/A << /S /GoTo /D (attachments) >> +/A << /S /GoTo /D (multiplecharts) >> >> endobj -1629 0 obj << +1657 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 656.438 537.983 663.293] +/Rect [528.02 654.381 537.983 663.293] /Subtype /Link -/A << /S /GoTo /D (attachments) >> +/A << /S /GoTo /D (multiplecharts) >> >> endobj -1630 0 obj << +1658 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 643.487 197.409 650.341] +/Rect [119.552 641.803 194.251 650.341] /Subtype /Link -/A << /S /GoTo /D (patchviewer) >> +/A << /S /GoTo /D (quicksearch) >> >> endobj -1631 0 obj << +1659 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 643.487 537.983 650.341] +/Rect [528.02 641.803 537.983 650.341] /Subtype /Link -/A << /S /GoTo /D (patchviewer) >> +/A << /S /GoTo /D (quicksearch) >> >> endobj -1632 0 obj << +1660 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 628.478 307.765 637.39] +/Rect [119.552 628.478 182.933 637.39] /Subtype /Link -/A << /S /GoTo /D (patchviewer_view) >> +/A << /S /GoTo /D (list) >> >> endobj -1633 0 obj << +1661 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 628.478 537.983 637.39] /Subtype /Link -/A << /S /GoTo /D (patchviewer_view) >> +/A << /S /GoTo /D (list) >> >> endobj -1634 0 obj << +1662 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 615.527 352.437 624.438] +/Rect [119.552 615.527 287.182 624.438] /Subtype /Link -/A << /S /GoTo /D (patchviewer_diff) >> +/A << /S /GoTo /D (individual-buglists) >> >> endobj -1635 0 obj << +1663 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 615.527 537.983 624.438] /Subtype /Link -/A << /S /GoTo /D (patchviewer_diff) >> +/A << /S /GoTo /D (individual-buglists) >> >> endobj -1636 0 obj << +1664 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 602.575 305.324 611.487] +/Rect [95.641 602.575 159.86 611.487] /Subtype /Link -/A << /S /GoTo /D (patchviewer_context) >> +/A << /S /GoTo /D (bugreports) >> >> endobj -1637 0 obj << +1665 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 602.575 537.983 611.487] /Subtype /Link -/A << /S /GoTo /D (patchviewer_context) >> +/A << /S /GoTo /D (bugreports) >> >> endobj -1638 0 obj << +1666 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 589.624 359.988 598.535] +/Rect [119.552 589.624 231.372 598.535] /Subtype /Link -/A << /S /GoTo /D (patchviewer_collapse) >> +/A << /S /GoTo /D (fillingbugs) >> >> endobj -1639 0 obj << +1667 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 589.624 537.983 598.535] /Subtype /Link -/A << /S /GoTo /D (patchviewer_collapse) >> +/A << /S /GoTo /D (fillingbugs) >> >> endobj -1640 0 obj << +1668 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 576.673 299.107 585.584] +/Rect [119.552 576.673 234.958 585.584] /Subtype /Link -/A << /S /GoTo /D (patchviewer_link) >> +/A << /S /GoTo /D (cloningbugs) >> >> endobj -1641 0 obj << +1669 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 576.673 537.983 585.584] /Subtype /Link -/A << /S /GoTo /D (patchviewer_link) >> +/A << /S /GoTo /D (cloningbugs) >> >> endobj -1642 0 obj << +1670 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 563.721 280.448 572.633] +/Rect [95.641 565.778 163.436 572.633] /Subtype /Link -/A << /S /GoTo /D (patchviewer_bonsai_lxr) >> +/A << /S /GoTo /D (attachments) >> >> endobj -1643 0 obj << +1671 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 563.721 537.983 572.633] +/Rect [528.02 565.778 537.983 572.633] /Subtype /Link -/A << /S /GoTo /D (patchviewer_bonsai_lxr) >> +/A << /S /GoTo /D (attachments) >> >> endobj -1644 0 obj << +1672 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 550.77 268.283 559.681] +/Rect [119.552 552.827 197.409 559.681] /Subtype /Link -/A << /S /GoTo /D (patchviewer_unified_diff) >> +/A << /S /GoTo /D (patchviewer) >> >> endobj -1645 0 obj << +1673 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 550.77 537.983 559.681] +/Rect [528.02 552.827 537.983 559.681] /Subtype /Link -/A << /S /GoTo /D (patchviewer_unified_diff) >> +/A << /S /GoTo /D (patchviewer) >> >> endobj -1646 0 obj << +1674 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 537.818 171.397 546.73] +/Rect [143.462 537.818 307.765 546.73] /Subtype /Link -/A << /S /GoTo /D (hintsandtips) >> +/A << /S /GoTo /D (patchviewer_view) >> >> endobj -1647 0 obj << +1675 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 537.818 537.983 546.73] /Subtype /Link -/A << /S /GoTo /D (hintsandtips) >> +/A << /S /GoTo /D (patchviewer_view) >> >> endobj -1648 0 obj << +1676 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 526.924 212.542 533.778] +/Rect [143.462 524.867 352.437 533.778] /Subtype /Link -/A << /S /GoTo /D (2233) >> +/A << /S /GoTo /D (patchviewer_diff) >> >> endobj -1649 0 obj << +1677 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 526.924 537.983 533.778] +/Rect [528.02 524.867 537.983 533.778] /Subtype /Link -/A << /S /GoTo /D (2233) >> +/A << /S /GoTo /D (patchviewer_diff) >> >> endobj -1650 0 obj << +1678 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 513.973 187.636 520.827] +/Rect [143.462 511.915 305.324 520.827] /Subtype /Link -/A << /S /GoTo /D (commenting) >> +/A << /S /GoTo /D (patchviewer_context) >> >> endobj -1651 0 obj << +1679 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 513.973 537.983 520.827] +/Rect [528.02 511.915 537.983 520.827] /Subtype /Link -/A << /S /GoTo /D (commenting) >> +/A << /S /GoTo /D (patchviewer_context) >> >> endobj -1652 0 obj << +1680 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 498.964 214.495 507.875] +/Rect [143.462 498.964 359.988 507.875] /Subtype /Link -/A << /S /GoTo /D (dependencytree) >> +/A << /S /GoTo /D (patchviewer_collapse) >> >> endobj -1653 0 obj << +1681 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 498.964 537.983 507.875] /Subtype /Link -/A << /S /GoTo /D (dependencytree) >> +/A << /S /GoTo /D (patchviewer_collapse) >> >> endobj -1654 0 obj << +1682 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 486.013 221.947 494.924] +/Rect [143.462 486.013 299.107 494.924] /Subtype /Link -/A << /S /GoTo /D (timetracking) >> +/A << /S /GoTo /D (patchviewer_link) >> >> endobj -1655 0 obj << +1683 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 486.013 537.983 494.924] /Subtype /Link -/A << /S /GoTo /D (timetracking) >> +/A << /S /GoTo /D (patchviewer_link) >> >> endobj -1656 0 obj << +1684 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 475.118 185.822 481.973] +/Rect [143.462 473.061 280.448 481.973] /Subtype /Link -/A << /S /GoTo /D (userpreferences) >> +/A << /S /GoTo /D (patchviewer_bonsai_lxr) >> >> endobj -1657 0 obj << +1685 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 475.118 537.983 481.973] +/Rect [528.02 473.061 537.983 481.973] /Subtype /Link -/A << /S /GoTo /D (userpreferences) >> +/A << /S /GoTo /D (patchviewer_bonsai_lxr) >> >> endobj -1658 0 obj << +1686 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 462.167 232.149 469.021] +/Rect [143.462 460.11 268.283 469.021] /Subtype /Link -/A << /S /GoTo /D (accountpreferences) >> +/A << /S /GoTo /D (patchviewer_unified_diff) >> >> endobj -1659 0 obj << +1687 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 462.167 537.983 469.021] +/Rect [528.02 460.11 537.983 469.021] /Subtype /Link -/A << /S /GoTo /D (accountpreferences) >> +/A << /S /GoTo /D (patchviewer_unified_diff) >> >> endobj -1660 0 obj << +1688 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 449.216 229.927 456.07] +/Rect [95.641 447.158 171.397 456.07] /Subtype /Link -/A << /S /GoTo /D (generalpreferences) >> +/A << /S /GoTo /D (hintsandtips) >> >> endobj -1661 0 obj << +1689 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 449.216 537.983 456.07] +/Rect [528.02 447.158 537.983 456.07] /Subtype /Link -/A << /S /GoTo /D (generalpreferences) >> +/A << /S /GoTo /D (hintsandtips) >> >> endobj -1662 0 obj << +1690 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 436.264 222.196 443.118] +/Rect [119.552 436.264 212.542 443.118] /Subtype /Link -/A << /S /GoTo /D (emailpreferences) >> +/A << /S /GoTo /D (2371) >> >> endobj -1663 0 obj << +1691 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 436.264 537.983 443.118] /Subtype /Link -/A << /S /GoTo /D (emailpreferences) >> +/A << /S /GoTo /D (2371) >> >> endobj -1664 0 obj << +1692 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 423.313 197.598 430.167] +/Rect [119.552 423.313 187.636 430.167] /Subtype /Link -/A << /S /GoTo /D (permissionsettings) >> +/A << /S /GoTo /D (commenting) >> >> endobj -1665 0 obj << +1693 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 423.313 537.983 430.167] /Subtype /Link -/A << /S /GoTo /D (permissionsettings) >> +/A << /S /GoTo /D (commenting) >> >> endobj -1666 0 obj << +1694 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 408.304 194.43 417.215] +/Rect [119.552 408.304 214.495 417.215] /Subtype /Link -/A << /S /GoTo /D (reporting) >> +/A << /S /GoTo /D (dependencytree) >> >> endobj -1667 0 obj << +1695 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 408.304 537.983 417.215] /Subtype /Link -/A << /S /GoTo /D (reporting) >> +/A << /S /GoTo /D (dependencytree) >> >> endobj -1668 0 obj << +1696 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 395.353 180.433 404.264] +/Rect [95.641 395.353 221.947 404.264] /Subtype /Link -/A << /S /GoTo /D (reports) >> +/A << /S /GoTo /D (timetracking) >> >> endobj -1669 0 obj << +1697 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 395.353 537.983 404.264] /Subtype /Link -/A << /S /GoTo /D (reports) >> +/A << /S /GoTo /D (timetracking) >> >> endobj -1670 0 obj << +1698 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 384.458 175.452 391.312] +/Rect [95.641 384.458 185.822 391.312] /Subtype /Link -/A << /S /GoTo /D (charts) >> +/A << /S /GoTo /D (userpreferences) >> >> endobj -1671 0 obj << +1699 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 384.458 537.983 391.312] /Subtype /Link -/A << /S /GoTo /D (charts) >> +/A << /S /GoTo /D (userpreferences) >> >> endobj -1672 0 obj << +1700 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 369.45 243.636 378.361] +/Rect [119.552 371.507 232.149 378.361] /Subtype /Link -/A << /S /GoTo /D (2361) >> +/A << /S /GoTo /D (accountpreferences) >> >> endobj -1673 0 obj << +1701 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 369.45 537.983 378.361] +/Rect [528.02 371.507 537.983 378.361] /Subtype /Link -/A << /S /GoTo /D (2361) >> +/A << /S /GoTo /D (accountpreferences) >> >> endobj -1674 0 obj << +1702 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.462 356.498 276.582 365.41] +/Rect [119.552 358.556 229.927 365.41] /Subtype /Link -/A << /S /GoTo /D (2368) >> +/A << /S /GoTo /D (generalpreferences) >> >> endobj -1675 0 obj << +1703 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 356.498 537.983 365.41] +/Rect [528.02 358.556 537.983 365.41] /Subtype /Link -/A << /S /GoTo /D (2368) >> +/A << /S /GoTo /D (generalpreferences) >> >> endobj -1676 0 obj << +1704 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 343.547 139.646 352.458] +/Rect [119.552 345.604 222.196 352.458] /Subtype /Link -/A << /S /GoTo /D (flags) >> +/A << /S /GoTo /D (emailpreferences) >> >> endobj -1677 0 obj << +1705 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 343.547 537.983 352.458] +/Rect [528.02 345.604 537.983 352.458] /Subtype /Link -/A << /S /GoTo /D (flags) >> +/A << /S /GoTo /D (emailpreferences) >> >> endobj -1678 0 obj << +1706 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 330.595 152.926 339.507] +/Rect [119.552 332.533 197.598 339.507] /Subtype /Link -/A << /S /GoTo /D (whining) >> +/A << /S /GoTo /D (permissionsettings) >> >> endobj -1679 0 obj << +1707 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 330.595 537.983 339.507] +/Rect [528.02 332.533 537.983 339.507] /Subtype /Link -/A << /S /GoTo /D (whining) >> +/A << /S /GoTo /D (permissionsettings) >> >> endobj -1680 0 obj << +1708 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 319.701 190.515 326.555] +/Rect [95.641 317.644 194.43 326.555] /Subtype /Link -/A << /S /GoTo /D (whining-overview) >> +/A << /S /GoTo /D (reporting) >> >> endobj -1681 0 obj << +1709 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 319.701 537.983 326.555] +/Rect [528.02 317.644 537.983 326.555] /Subtype /Link -/A << /S /GoTo /D (whining-overview) >> +/A << /S /GoTo /D (reporting) >> >> endobj -1682 0 obj << +1710 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 304.692 223.322 313.604] +/Rect [119.552 304.692 180.433 313.604] /Subtype /Link -/A << /S /GoTo /D (whining-schedule) >> +/A << /S /GoTo /D (reports) >> >> endobj -1683 0 obj << +1711 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 304.692 537.983 313.604] /Subtype /Link -/A << /S /GoTo /D (whining-schedule) >> +/A << /S /GoTo /D (reports) >> >> endobj -1684 0 obj << +1712 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 291.741 217.783 300.652] +/Rect [119.552 293.798 175.452 300.652] /Subtype /Link -/A << /S /GoTo /D (whining-query) >> +/A << /S /GoTo /D (charts) >> >> endobj -1685 0 obj << +1713 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 291.741 537.983 300.652] +/Rect [528.02 293.798 537.983 300.652] /Subtype /Link -/A << /S /GoTo /D (whining-query) >> +/A << /S /GoTo /D (charts) >> >> endobj -1686 0 obj << +1714 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 278.79 235.586 287.701] +/Rect [143.462 278.79 243.636 287.701] /Subtype /Link -/A << /S /GoTo /D (2421) >> +/A << /S /GoTo /D (2499) >> >> endobj -1687 0 obj << +1715 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 278.79 537.983 287.701] /Subtype /Link -/A << /S /GoTo /D (2421) >> +/A << /S /GoTo /D (2499) >> >> endobj -1688 0 obj << +1716 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.731 263.582 172.751 272.468] +/Rect [143.462 265.838 276.582 274.75] /Subtype /Link -/A << /S /GoTo /D (customization) >> +/A << /S /GoTo /D (2506) >> >> endobj -1689 0 obj << +1717 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 263.582 537.983 272.468] +/Rect [528.02 265.838 537.983 274.75] /Subtype /Link -/A << /S /GoTo /D (customization) >> +/A << /S /GoTo /D (2506) >> >> endobj -1690 0 obj << +1718 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 248.105 210.619 257.016] +/Rect [95.641 252.887 139.646 261.798] /Subtype /Link -/A << /S /GoTo /D (cust-templates) >> +/A << /S /GoTo /D (flags) >> >> endobj -1691 0 obj << +1719 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 248.105 537.983 257.016] +/Rect [528.02 252.887 537.983 261.798] /Subtype /Link -/A << /S /GoTo /D (cust-templates) >> +/A << /S /GoTo /D (flags) >> >> endobj -1692 0 obj << +1720 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 235.153 261.07 244.065] +/Rect [95.641 239.935 152.926 248.847] /Subtype /Link -/A << /S /GoTo /D (template-directory) >> +/A << /S /GoTo /D (whining) >> >> endobj -1693 0 obj << +1721 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 235.153 537.983 244.065] +/Rect [528.02 239.935 537.983 248.847] /Subtype /Link -/A << /S /GoTo /D (template-directory) >> +/A << /S /GoTo /D (whining) >> >> endobj -1694 0 obj << +1722 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 222.202 283.665 231.113] +/Rect [119.552 229.041 190.515 235.895] /Subtype /Link -/A << /S /GoTo /D (template-method) >> +/A << /S /GoTo /D (whining-overview) >> >> endobj -1695 0 obj << +1723 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 222.202 537.983 231.113] +/Rect [528.02 229.041 537.983 235.895] /Subtype /Link -/A << /S /GoTo /D (template-method) >> +/A << /S /GoTo /D (whining-overview) >> >> endobj -1696 0 obj << +1724 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 209.25 238.734 218.162] +/Rect [119.552 214.032 223.322 222.944] /Subtype /Link -/A << /S /GoTo /D (template-edit) >> +/A << /S /GoTo /D (whining-schedule) >> >> endobj -1697 0 obj << +1725 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 209.25 537.983 218.162] +/Rect [528.02 214.032 537.983 222.944] /Subtype /Link -/A << /S /GoTo /D (template-edit) >> +/A << /S /GoTo /D (whining-schedule) >> >> endobj -1698 0 obj << +1726 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 196.299 259.307 205.21] +/Rect [119.552 201.081 222.206 209.992] /Subtype /Link -/A << /S /GoTo /D (template-formats) >> +/A << /S /GoTo /D (whining-query) >> >> endobj -1699 0 obj << +1727 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 196.299 537.983 205.21] +/Rect [528.02 201.081 537.983 209.992] /Subtype /Link -/A << /S /GoTo /D (template-formats) >> +/A << /S /GoTo /D (whining-query) >> >> endobj -1700 0 obj << +1728 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 183.348 226.34 192.259] +/Rect [119.552 188.13 235.586 197.041] /Subtype /Link -/A << /S /GoTo /D (template-specific) >> +/A << /S /GoTo /D (2559) >> >> endobj -1701 0 obj << +1729 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 183.348 537.983 192.259] +/Rect [528.02 188.13 537.983 197.041] /Subtype /Link -/A << /S /GoTo /D (template-specific) >> +/A << /S /GoTo /D (2559) >> >> endobj -1702 0 obj << +1730 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 170.396 351.988 179.308] +/Rect [71.731 172.922 172.203 181.808] /Subtype /Link -/A << /S /GoTo /D (template-http-accept) >> +/A << /S /GoTo /D (customization) >> >> endobj -1703 0 obj << +1731 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 170.396 537.983 179.308] +/Rect [528.02 172.922 537.983 181.808] /Subtype /Link -/A << /S /GoTo /D (template-http-accept) >> +/A << /S /GoTo /D (customization) >> >> endobj -1704 0 obj << +1732 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 157.445 178.51 166.356] +/Rect [95.641 159.502 168.717 166.356] /Subtype /Link -/A << /S /GoTo /D (cust-hooks) >> +/A << /S /GoTo /D (cust-skins) >> >> endobj -1705 0 obj << +1733 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 157.445 537.983 166.356] +/Rect [528.02 159.502 537.983 166.356] /Subtype /Link -/A << /S /GoTo /D (cust-hooks) >> +/A << /S /GoTo /D (cust-skins) >> >> endobj -1706 0 obj << +1734 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 144.493 261.398 153.405] +/Rect [95.641 144.493 210.619 153.405] /Subtype /Link -/A << /S /GoTo /D (cust-change-permissions) >> +/A << /S /GoTo /D (cust-templates) >> >> endobj -1707 0 obj << +1735 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 144.493 537.983 153.405] /Subtype /Link -/A << /S /GoTo /D (cust-change-permissions) >> +/A << /S /GoTo /D (cust-templates) >> >> endobj -1708 0 obj << +1736 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 131.542 267.864 140.453] +/Rect [119.552 131.542 261.07 140.453] /Subtype /Link -/A << /S /GoTo /D (cust-group-check) >> +/A << /S /GoTo /D (template-directory) >> >> endobj -1709 0 obj << +1737 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 131.542 537.983 140.453] /Subtype /Link -/A << /S /GoTo /D (cust-group-check) >> +/A << /S /GoTo /D (template-directory) >> >> endobj -1710 0 obj << +1738 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 118.59 246.206 127.502] +/Rect [119.552 118.59 283.665 127.502] /Subtype /Link -/A << /S /GoTo /D (dbmodify) >> +/A << /S /GoTo /D (template-method) >> >> endobj -1711 0 obj << +1739 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 118.59 537.983 127.502] /Subtype /Link -/A << /S /GoTo /D (dbmodify) >> +/A << /S /GoTo /D (template-method) >> >> endobj -1712 0 obj << +1740 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 105.639 286.315 114.55] +/Rect [119.552 105.639 238.734 114.55] /Subtype /Link -/A << /S /GoTo /D (integration) >> +/A << /S /GoTo /D (template-edit) >> >> endobj -1713 0 obj << +1741 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 105.639 537.983 114.55] /Subtype /Link -/A << /S /GoTo /D (integration) >> +/A << /S /GoTo /D (template-edit) >> >> endobj -1619 0 obj << -/D [1617 0 R /XYZ 71.731 729.265 null] +1647 0 obj << +/D [1645 0 R /XYZ 71.731 729.265 null] >> endobj -1616 0 obj << -/Font << /F27 1180 0 R /F32 1187 0 R /F33 1278 0 R >> +1644 0 obj << +/Font << /F27 1208 0 R /F32 1215 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1763 0 obj << -/Length 47121 +1791 0 obj << +/Length 52483 /Filter /FlateDecode >> stream -xڜ�[�dg~��{~ -X7"̜�:�4<�t��,����9�PO7���ç����z��۵�|ơq��\�D�������o���w���|z�������������W��a�w��_���������_��o�����t����������3����nK����������C���_����y:=��|��&����{�;�O�����շ�����w?~����������>?\��7�J^��O�|{���7�����l<�����~!������^���������U�g/����x>�\;t�͎; ���|�������=���������Ó��ݟ��v�����t�x���,�K��zszx�������/i��Rݟ��v���� wwRݟ��v������6�:5Ϣ����ps/���j��۰�_9u��ځ��6���?{A������6\=:u<��x�ޜ��?{A����t~�������ӽ�������&�ϧ����g]��=��������=���������]��������Vo���F��YV��u{�o��?{A��u{���x��ځ��6\Yu��ځo����Փ�17�eu <PoNw���x��ځ���������<POw�����j���moÝ��3�eu <P���֪���<P��A�Eb�Yq����8��h���o���Tdz�.����叹�����]�����������17���v�������Q�'x<��x�ޜn��?{A���n{^���^P;�@�ކ;�cn<{A������m���x��%�@�ކ�cn<{A��u{�叹�����m8[u��ځo�O��p%̍gY]��m�����a����-��������|�?�Ƴ�|S���:=>�5y�5�@�9��[u��ځ��.��Hu��ځ��o:u�ځo���m���x��%�@�ކ�;���^P;�@�ކ�T�g/�x�n��U�g/���z}uzxr?��,�K��zs�~:Hu��ځ���������<PO��ORݟ��v�����6��0폲�q������^ +��ހ۳4�g/�x�no���3�^P;�m�v{��:�eu <P�w�,ƍg/�x�no���y��ځ����d���j���]���oƳ�.����l�1���v��zw���������m��?�Ƴ�|[��ކ[��f<��x�noÍU�g/�x�no��<ɳ�<P��A�q�Yqo��{ ��2�q��\Ys�ځ���N����j����G���^P;�m���t'�N�,�K��zs��g'y��ځ��6�Yu��ځ��6ȳ�<{A���է�m���x��%�@�ކk�3n<{A��u{��I���v���� WVݟ��v�����������˳������I�3�<{A����t�`���j�'�ƣ̊{�<o��њg]��=��������=���������]�g'y��ځo����p-��,�K���� �[���^P;�@��yv�g/�x�>����?{A���՛��ͣ�1�gY]��ӣ<;ɳ�<P�N7�Vݟ��v���� w���x��ځo���� �N�,�K���� 7Vݟ��v���� �/M��̊; ��@����h���m�,L�YV��u{��I���v��zw��g'y��ځ����Ѫ���|[��:]˳�<��x�^���I���v���� wVݟ��v���� ��$�^P;�m�a{��I�eu <P���ڪ���<P��A����j��� �N����V�NgY�ȳ�.����ޢ_�`V�yw:��<{����t�`���j��>m�<>ɳ�.���.��<{A��u{n��?{A��u{��I���v������6���,�k���� g���^P;�@��y|�g/�x�>���?gʳ�|[=_��da"ϲ��ק;y|�g/�x�ޝ�?{A��u{da"�^P;�m�z{�q�G��r{n%���d��� �y�ځ���}|�G������������܍g^�����^���������z���?����������5�P䙌P\����?��V�������W�_�:m��:�x��~>��W5z���n��ߟn��zo����<PO��Rݟ��v�����ts'��,�K����8u��ځ8,��1,�jⰈSǰ�H�" -�"hv�8s�0ځ8,��1,�jⰈSǰ���"JͰ�K �8u��ځ8,��1,�jⰈSǰ���"F��"���8,��1,�jⰈSǰ���"N�"�v �(5�"�.�8,��1,�jⰈSǰ�H�"݇Eج8Qf�E]qXĩcX���a��aV;�E�:�EX�@Qj�EP]qXĩcX���a��aV;�E�:�EX�@Qj�EP]qXĩcX���a��aV;�E�:�EX�@Qj�EP]qXĩcX���a���"lV�8s�0ځ8,�����ⰈSǰ���"N�"�v �8u��ځ8,�����ⰈSǰ���"N�"�v �8u��ځ8,�����ⰈSǰ���"N�"�v �8u��ځ8,�����°�3����:��E���Xq8,��1,�hⰈQ��k �8u��ځ8,��1,�jⰈSǰ���"JͰ�K �8u��ځ8,��1,�jⰈSǰ���"JͰ�K �8u��ځ8,��1,�jⰈSǰ�H�" -�"hv �8ra��pXęcX���a��aV;�E��aT�@q�a�qXĩcX���a��aV;�E��aT�@q�a�qXĩcX���a��aV;�E��aT�@q�a�qXĩcX���a���"lV �(r� �q8,��1,�hⰈSǰ���"N�"�v �(5�"�.�8,��1,�jⰈSǰ���"N�"�v �(5�"�.�8,��1,�jⰈSǰ���"N�"�v �u���ⰈSǰ���"N�"�v �8ta��pXD�At �a��aV;�E�:�EX�@q�a�qXD�Au �a��aV;�E�:�EX�@q�a�qXD�Au �a��aV;�E�:�EX�@q�a�qXD�Au �a��aV;��E���Yq8,��1,�hⰈR3,����"N�"�v �8u��ځ8,��1,�jⰈR3,����"N�"�v �8u��ځ8,��1,�jⰈR3,����"N�"�v �8u��ځ8,��1,�jⰈR3,��H�"݇Eج8q�a�qXĩcX���a�fX�%�E�:�EX�@q�a�qXĩcX���a��aR�@q�a�qXĩcX���a��aV;�E��aT�@q�a�qXĩcX���a��aV;��E:�E��8q�>,�d�ᰈ3ǰ���"8�qyX�_Ǘg^���ax˰��°������3��g2,r3�E�����������?����Ƿ����D�Y_�������W�� - /rV�_���*��/�Шv W���*4��Uh��*4�K W���*4��Uh�� -�jbZ�� -�f�qژ� -M��Uh�� -�jrZ��B�ځ\�Vj�Шv W��:�Ф.�\�Vj�Шv W���*4��Uh�� -�jrڨ� -M��Uh�� -�jrZ��B�ځ\�Vj�Шv W��:�Ф.�\�Vj�Шv V�:��hVW���*4��Uh��*4�K W���*4��Uh�� -�jrZ��B�ځ\�6�B��rZ��B�ځ\�Vj�Шv W���*4��Uh��*4�K W���*4��Uh�� -�jrZ��B�ځ\�6�B��RZ�{��aX�V�B�Xq\�Vf�Јv W���R�u �*�RS�F�� -��T�Q�@�B+5UhT;���F�UhR�@�B+5UhT;���JM��*�RS�F�� -m�Y�&u �*�RS�F�� -��T�Q�@�B+5UhT;��M�̎�*�"GɊ�*�2S�F�� -��T�Q�@�BuV�I]� -��T�Q�@�B+5UhT;���JM��*�Qg��%���JM��*�RS�F�� -��T�Q�@�BuV�I]� -��T�Q�@�B+5UhT;�� -Uh4+�ІL�Ȏ�*�2S�F�� -��T�Q�@�B+5UhT;���F�UhR�@�B+5UhT;���JM��*�RS�F�� -m�Y�&u �*�RS�F�� -��T�Q�@�B+5UhT;���B}�B��rZ��B�ځ\�Vj�Шv V�:��hVW��9�Є.�\�Vj�Шv W���*4��Uh�� -�jrڨ� -M��Uh�� -�jrZ��B�ځ\�Vj�Шv W��:�Ф.�\�Vj�Шv W���*4��Uh�� -�jrڨ� -M��Uh�� -�jbZ�� -�f�qZ��B#ځ\�6�B��rZ��B�ځ\�Vj�Шv W���*4��Uh��*4�K W���*4��Uh�� -�jrZ��B�ځ\�6�B��rZ��B�ځ\�Vj�Шv W���*4��Uh��*4�K V�:��hVW���*4��Uh�� -�jrڨ� -M��Uh�� -�jrZ��B�ځ\�Vj�Шv W���R�u �*�RS�F�� -��T�Q�@�B+5UhT;���F�UhR�@�B+5UhT;���JM��*�RS�F�� -m�T���8�B+rT���8�B+3UhD;���ǥ^U��ױW�_��B��� -}}� -}�t�}|�*�x&U��Q���_�����y������O����7������O��l/_2N�2_2��U���/�d��/Wj�d��/Wj�d��/�˗����+5�zT;���JM���f�RӬG��Yo�٬'u �f�RӬG��Y��4�Q�@l�+t4�Ѭ8n�s6� ]�Y��4�Q�@n�+5�zT;���JM���f�Qg���%���JM���f�RӬG��Y��4�Q�@n�u6�I]�Y��4�Q�@n�+5�zT;���JM���f�Qg���%���JM���f�BG�͊�f�2ӬG��Yo�٬'u �f�RӬG��Y��4�Q�@n�+5�zT;���F��zR�@n�+5�zT;���JM���f�RӬG��Yo�٬'u �f�RӬG��Y��4�Q�@n�+5�zT;���F��zR�@j�+so֣�:�� -�z+����L���f�P_�����ܬWj���v 7땚f=���z��Y�jr�ި�YO���z��Y�jr�^�i֣ځܬWj���v 7�:���.�ܬWj���v 7땚f=���z��Y�jb�ޠi֓�qجW�h�#YqܬWf���v 7땚f=���z��f=�K 7땚f=���z��Y�jr�^�i֣ځܬ7�l֓�r�^�i֣ځܬWj���v 7땚f=���z��f=�K 7땚f=���z��Y�jb�^��Y�f�a�ސi��qܬWf���v 7땚f=���z��Y�jr�ި�YO���z��Y�jr�^�i֣ځܬWj���v 7�:���.�ܬWj���v 7땚f=���z��Y�jr�^�/�zP�@n�+5�zT;���JM���f�BG�͊�f�1g���%���JM���f�RӬG��Y��4�Q�@n�u6�I]�Y��4�Q�@n�+5�zT;���JM���f�Qg���%���JM���f�RӬG��Y��4�Q�@n�u6�I]�Y��4�Q�@l�+t4�Ѭ8n�+3�zD;���F��zR�@n�+5�zT;���JM���f�RӬG��Yo�٬'u �f�RӬG��Y��4�Q�@n�+5�zT;���F��zR�@n�+5�zT;���JM���f�RӬG��Yo�٬'u �f�BG�͊�f�2ӬG��Y��4�Q�@n�u6�I]�Y��4�Q�@n�+5�zT;���JM���f�P_�����ܬWj���v 7땚f=���z��Y�jr�ި�YO���z��Y�jr�^�i֣ځܬWj���v 6� �f=���zE�f=���ze�Y�hr���"����:�f��������g~������摛��4��F��w���}�������������i��WQo����W������8x�����7�~!ЌC��g�ٌ#u �f�RӌC����4�P�@n�)5�8T;��qF��8R�@n�)5�8T;�q -�84+��q�L3��f�Qg3��%��qJM3��f�RӌC����4�P�@n�u6�H]���4�P�@n�)5�8T;��qJM3��f�Qg3��%��qJM3��f�RӌC����4�P�@n�u6�H]��̽���0l�)p4�P�8n�)3�8D;��qB}iƁ�r3N�iơځ܌Sj�q�v 7㔚f���8��f�K 7㔚f���8���jr3N�iơځ܌3�lƑ�r3N�iơځ܌Sj�q�v 7㔚f���8��Gf�a3N���d�q3N�i�!ځ܌Sj�q�v 7�:�q�.�܌Sj�q�v 7㔚f���8���jr3Ψ�G���8���jr3N�iơځ܌Sj�q�v 7�:�q�.�܌Sj�q�v 7㔚f���8��f���8C�Gd�q3N�i�!ځ܌Sj�q�v 7㔚f���8��f�K 7㔚f���8���jr3N�iơځ܌3�lƑ�r3N�iơځ܌Sj�q�v 7㔚f���8��4�@]���4�P�@n�)5�8T;�q -�84+��qƜ�8B�@n�)5�8T;��qJM3��f�RӌC��g�ٌ#u �f�RӌC����4�P�@n�)5�8T;��qF��8R�@n�)5�8T;��qJM3��f�RӌC��g�ٌ#u �f�RӌC����ьC����4��@n�u6�H]���4�P�@n�)5�8T;��qJM3��f�Qg3��%��qJM3��f�RӌC����4�P�@n�u6�H]���4�P�@n�)5�8T;��qJM3��f�Qg3��%�q -�84+��q�L3��f�RӌC��g�ٌ#u �f�RӌC����4�P�@n�)5�8T;��qB}iƁ�r3N�iơځ܌Sj�q�v 7㔚f���8��f�K 7㔚f���8���jr3N�iơځ،3h�qdv6�9�qHV7㔙f���f�j���؛q�^���a3��ul� ��~_�i�Ton���ه����/��y����|A7�//h<�G�_пN'�����_��?�����G���շ���ۻo������j����_W�nn}�~�w��s;x�y��+��Y�oN��wo��7���j���������^P;�@}<=>�c6���^P;�mu��͝Tdz�.���6<_�(u��ځ��6�<Iu��ځ��6\[u��ځo����p���Q6;��ރ�Y����<P���ʪ���<POO��w��ځ_P=��ۨ�+�I]�+�����G��+�����G��+�����G��+�������J�W��ځ��J�W��ځ��J�W��ځ��F�_N��_��|8��_��|8��_����hV�1�W���W�+5_�j�W�+5_�j�W�+5_�j�W�u~8�K �R��v �R3t�j�ЉR3t�j�ЉQ�� �K �(5C'�v �(5C'�v �(5C'�v �u����ЉR3t�j�ЉB�� ��C'��� ��C'F�C'�.�<t����ځ<t����ځ<t����ځ<tb�9tB��C'J�� ��C'J�� ��C'J�� ��C'F�C'�.�<t����ځ<t����ځ<t����ځ<tb�9tB�HC'�܇NP|�C' -C'(V�(3C'�v ��e��5��N���T;��N���T;��N���T;��N�:�NH]y�D�:A�y�D�:A�y�D�:A�y�Ĩs��%��N���T;��N���T;��N���T;�N��2;�N9�N��8:Qf�N�@:Qj�NP�@:1�:!u ��f����f����f����ΡR�@:Qj�NP�@:Qj�NP�@:Qj�NP�@:1�:!u ��f����f��ġ���4+�N��";��N���D;��N���T;��N���T;��N�:�NH]y�D�:A�y�D�:A�y�D�:A�y�Ĩs��%��N���T;��N���T;��N���T;��N��2t��C'J�� ��C'J�� ��C' -C'hV�s���ЉR3t�j�ЉR3t�j�ЉR3t�j�ЉQ�� �K �(5C'�v �(5C'�v �(5C'�v �u����ЉR3t�j�ЉR3t�j�ЉR3t�j�ЉQ�� �K �(5C'�v �(t��Yq<t��� ځ<tb�9tB��C'J�� ��C'J�� ��C'J�� ��C'F�C'�.�<t����ځ<t����ځ<t����ځ<tb�9tB��C'J�� ��C'J�� ��C'J�� ��C'F�C'�.�8t��1t�f��Љ23t�h�ЉR3t�j�ЉQ�� �K �(5C'�v �(5C'�v �(5C'�v ��e��5��N���T;��N���T;��N���T;��N�:�NH]y�D�:A�y�D�:A�y�D�:A�q�Ġ:!��p�D�c�Ɋ�ef��䡓�5t��c:y�2χC'ǯc:�ᡓ��⒆N�#�/��˿n�������O����������/?~��W���W��^�E�z����p�nrwsz��C�U��/�������|��yCݟ��v���xzz>�Q�����M�܋Q�~�K ��(5�1�v ��(5�1�v ��(5�1�v ��u�ǐ��~�R��j�~�R��j�~�R��j�~�A�Cf��~�2��h�~�R��j�~�R��j�~�Q�~�K ��(5�1�v ��(5�1�v ��(5�1�v ���e?�5��c���T;��c���T;��c���T;��c�:�cH]y?F�ُA�y?F�ُA�q?F�c?͊��c��B�@ޏQj�cP�@ޏQj�cP�@ޏQj�cP�@ޏ1�!u ���f?����f?����f?������R�@ޏQj�cP�@ޏQj�cP�@ޏQj�cP�@ޏ1�!u ���f?������4+��c���D;��c�:�cH]y?F�ُA�y?F�ُA�y?F�ُA�y?ƨs?��%��c���T;��c���T;��c���T;��c�:�cH]y?F�ُA�y?F�ُA�y?F�ُA�y?ƨs?��%��c���Ǡ�:�c8�cP�8ޏQf�c�@ޏ��~�k ��(5�1�v ��(5�1�v ��(5�1�v ��u�ǐ��~�R��j�~�R��j�~�R��j�~�Q�~�K ��(5�1�v ��(5�1�v ��(5�1�v ��4�1dv��(r�� Yq����� ځ����Ǡځ�cԹC���1J�~���1J�~���1J�~���1F��1�.�����Ǡځ����Ǡځ����Ǡځ�cԹC���1J�~���1J�~���1 -�1hV��2�1Dv��(3�1�v ��(5�1�v ��(5�1�v ��u�ǐ��~�R��j�~�R��j�~�R��j�~�Q�~�K ��(5�1�v ��(5�1�v ��(5�1�v ���e?�5��c���T;��c���T;�c:�cЬ8ޏ1�!t ���f?����f?����f?������R�@ޏQj�cP�@ޏQj�cP�@ޏQj�cP�@ޏ1�!u ���f?����f?����f?������R�@ޏQj�cP�@Q�؏A��x?F�ُA�y?ƨs?��%��c���T;��c���T;��c���T;��c�:�cH]y?F�ُA�y?F�ُA�y?F�ُA�y?ƨs?��%��c���T;��c���T;��c���T;��c�:�cH]q?F�c?͊��ef?����f?������R�@ޏQj�cP�@ޏQj�cP�@ޏQj�cP�@ޏ��~�k ��(5�1�v ��(5�1�v ��(5�1�v ��u�ǐ��~�R��j�~�R��j�~�R��j�~�A�Cf��~�"�~���1��~���1�K(j?_Ǿ��e<�����/�|��6�1�o>��Թ�r��W�n��ؼ��7���g�Ⱦs2�������}���_��/?~���9������̋��z�����z�\h��8^��Å��_��B�� ��B�� J�B�� J�B�� F� �.��Р�,4�ځ�Р�,4�ځ�Р�,4�ځ�� ԗ�P�@^hPjP�@^hPjP�@^hPjP�@^h0�\h u ��f����f��ą���4+��9]y�A�Yh@�y�A�Yh@�y�A�Yh@�y���s���%����T;����T;����T;��:H]y�A�Yh@�y�A�Yh@�y�A�Yh@�y���s���%����T;:Ь8^hPf�@^h0�\h u ��f����f����f����΅R�@^hPjP�@^hPjP�@^hPjP�@^h0�\h u ��f����f����f����΅R�@ZhP�Ѐ��0\hP�Xh@��x�A�Yh@�y�A�/ ����Р�,4�ځ�Р�,4�ځ�Р�,4�ځ��`Թ�@�� J�B�� J�B�� J�B�� F� �.��Р�,4�ځ�Р�,4�ځ�Р�,4�ځ��`�,4��q�РȱЀd��B�2�Ѐh�B�R�Ѐj�B�Q�B�K /4(5 �v /4(5 �v /4(5 �v /4u.4���B�R�Ѐj�B�R�Ѐj�B�R�Ѐj�B�Q�B�K /4(5 �v /4(5 �v .4(t,4�Yq��`�,4�q�Р�,4 ځ�Р�,4�ځ�Р�,4�ځ��`Թ�@�� J�B�� J�B�� J�B�� F� �.��Р�,4�ځ�Р�,4�ځ�Р�,4�ځ�� ԗ�P�@^hPjP�@^hPjP�@\hP�Xh@��x���s���%����T;����T;����T;��:H]y�A�Yh@�y�A�Yh@�y�A�Yh@�y���s���%����T;����T;����T;��:H]y�A�Yh@�q�A�c�͊�ef����΅R�@^hPjP�@^hPjP�@^hPjP�@^h0�\h u ��f����f����f����΅R�@^hPjP�@^hPjP�@^hPjP�@^h0�\h u ą���4+����D;����T;��:H]y�A�Yh@�y�A�Yh@�y�A�Yh@�y�A�/ ����Р�,4�ځ�Р�,4�ځ�Р�,4�ځ��`Թ�@�� J�B�� J�B�� J�B�� �B�� � HV/4(3 �v /4� ��|�Bë� ǯ��B��?�兆�/_�� yd_h� �������ӻ����������|w���������������_�>}�������o����>����wx����c���s�ͫW��������üc�?�<��O����r|��j��B��Gwl���ؘ�8�cs�cc��ͩ㎍��;6�� �%�:��X�@�cs�cc��ͩ㎍��;6�� �%�:��X�@�cs�cc��ͩ㎍��;6�� �%�:��X�@�cs�cc��͡��Gwl�wlHvޱ9sܱ1ځx���q��j��S���wlJ��K ޱ9uܱ�ځx���q��j��S���wlJ��K ޱ9uܱ�ځx���q��j��S���wlF�wl���x���q��j��S��Hwl���ج8�cSf��]�ͩ㎍��;6��;6V;�:��X�@�cSj��P]�ͩ㎍��;6��;6V;�:��X�@�cSj��P]�ͩ㎍��;6��;6V;�:��X�@�cSj��P]�ͩ㎍��;6��wllVޱ9sܱ1ځxǦ�ܱ����S���wlNwl�v ޱ9uܱ�ځxǦ�ܱ����S���wlNwl�v ޱ9uܱ�ځxǦ�ܱ����S���wlNwl�v ޱ9uܱ�ځxǦ�ܱ����C�;66+�9���@�cs�cc��M��cCu �;6��;6V;�:��X�@�cs�cc��ͨ��5�:��X�@�cs�cc��ͩ㎍��;6�� �%�:��X�@�cs�cc��ͩ㎍��;6��;64;����߱1Yqx���q��h�\S�;6~_�y�2����u,wlg�c{�=�_=��xd�c�wl�0��>��˻�����8H��?�� �ӧ~����O�~���շ������������q��|���i�K��Ҟ����������_~���Ӈ���/k�=���c�����?�S�����ù�/�y�s���3��_�7��������� -�"ΏV^�*�����VP�@�hE��h�ďV:>ZA����cΏV]����T;�?ZQj>ZA�����T;�?Z1��h��%�?ZQj>ZA�����T;�?ZQj>ZA����ΏVH]����T;�?ZQj>ZA�����T;�?Z1��h��%�?ZQj>ZA�����VЬ8�hE��h��V�:?Z!u �V���VP�@�hE��h��V���VP�@�hŨ�R�@�hE��h��V���VP�@�hE��h��V�:?Z!u �V���VP�@�hE��h��V���VP�@�hŨ�R�@�hE��4+�?ZQf>ZA�����T;�?Z1��h��%�?ZQj>ZA�����T;�?ZQj>ZA�����|����(5��ځ�ъR�� -���(5��ځ�ъQ�G+�.��ъR�� -���(5��ځ�ъR�� -���4���q�ъ"�G+HV���|��h�G+�O�/���c�h��ˀ�V�_ǟ7�p�~���G+�����������o�����O�������ߏ����?��<�������w?>�����~�F�W����ۃ_���������W���o���o\e��W��o\Eu �o\u���UV;��qա�7��Yq����߸�h�7�*5߸���߸��v ~�S�7��ځ���N߸�j�7�*5߸���߸��v ~�S�7��ځ���N߸�j�7�*5߸���߸��v ~�S�7��ځ���N߸�j�7�*5߸��߸��/߸���0��U�߸�b��7�:s|�*��߸j����������N߸�j�7�:u|�*��߸��v ~�R.����N߸�j�7�:u|�*��߸��v ~�R.����N߸�j�7�:5Ku�v /�)5Ku�v .�4Kudv.�)r,�!Yq�T��,�!ځ�T��,աځ�TgԹTG��KuJ�R��KuJ�R��KuJ�R��KuF�Ku�.��T��,աځ�T��,աځ�T��,աځ�TgԹTG��KuJ�R��KuJ�R��Ku -KuhV.�2KuDv/�)3Ku�v /�)5Ku�v /�)5Ku�v /�u.Ց��R�R�T�j�R�R�T�j�R�R�T�j�R�Q�R�K /�)5Ku�v /�)5Ku�v /�)5Ku�v /� ��N��u*��N�jr�J��S�ځX�R�S�Yq\�2�S�r�J��S�ځ\�Rj�T�v ש��:��u*��:�K ש��:��u*��N�jr�J��S�ځ\�2�S��r�J��S�ځ\�Rj�T�v ש��:��u*��:�K ש��:��u*��:��u*e�N�hr�ʨ�NE��u*��N�jr�J��S�ځ\�Rj�T�v ש�:�T�.�\�Rj�T�v ש��:��u*��N�jr�ʨ�NE��u*��N�jr�J��S�ځ\�Rj�T�v ש�:�T�.�X�R�S�Yq\�Rf�T�v ש��:��u*��:�K ש��:��u*��N�jr�J��S�ځ\��K� -�5��TJM� -��:�RS�B��N��ԩP�@�Su֩H]�N��ԩP�@�S)5u*T;��TJM� -��:�AS�"��N��Q�B��N��ԩ�@�S7�T� -_�^�z�2���Tǯ��[��{�~�v�u���^��u���}�[p���?�竻����w�w߾��������o���������_�o����N��K���������*����WǕ��_T�P�@�TuV�H]�R��T�P�@�T)tT�Ь8�T)3�*D;�+UF��*R�@�T)5�*T;�+UJM� -��J�RS�B��Re�Y�"u �J�RS�B��R��T�P�@�T)5�*T;�+UF��*R�@�T)5�*T;�+UJM� -��J�RS�B��Re�Y�"u �J�2�J��ðR��Q�B��R��T��@�T ��R�ȕ*��R�jr�J��T�ځ\�Rj*U�v W��:+U�.�\�Rj*U�v W���J�ȕ*��R�jr�ʨ�RE�ȕ*��R�jr�J��T�ځ\�Rj*U�v V��J���*E�J�Ǖ*e�R�hr�J��T�ځ\�2�T��r�J��T�ځ\�Rj*U�v W���J�ȕ*��J�K W���J�ȕ*��R�jr�J��T�ځ\�2�T��r�J��T�ځ\�Rj*U�v V�:*UhVV��J�Ǖ*e�R�hr�J��T�ځ\�Rj*U�v W��:+U�.�\�Rj*U�v W���J�ȕ*��R�jr�ʨ�RE�ȕ*��R�jr�J��T�ځ\�Rj*U�v W���R�u �J�RS�B��R��T�P�@�T)tT�Ь8�TsV�]�R��T�P�@�T)5�*T;�+UJM� -��J�Qg���%�+UJM� -��J�RS�B��R��T�P�@�TuV�H]�R��T�P�@�T)5�*T;�+UJM� -��J�Qg���%�+UJM� -��J�BG� -͊�J�2S�B��Re�Y�"u �J�RS�B��R��T�P�@�T)5�*T;�+UF��*R�@�T)5�*T;�+UJM� -��J�RS�B��Re�Y�"u �J�RS�B��R��T�P�@�T)5�*T;�+UF��*R�@�T)tT�Ь8�T)3�*D;�+UJM� -��J�Qg���%�+UJM� -��J�RS�B��R��T�P�@�T ��R�ȕ*��R�jr�J��T�ځ\�Rj*U�v W��:+U�.�\�Rj*U�v W���J�ȕ*��R�jb�ʠ�T��qX�R�T!Yq\�Rf*U�v W��@�R��c�T�zP�:~�7T=߅l?��R5�+U��R�}w>_}�������w�o������?��y��w����|uu�������ߝ���ˇ������ϟ�����������o���w_ߧ�o�����k^���OWWG_l�r���b�՟�����/.VH]�bE��XA��bE��XA��bE��XA��bŨ�b��%�/V���T;�/V���T;/V:.VЬ8�X1d.V��8�XQf.V�@�XQj.VP�@�XQj.VP�@�X1�X!u ���b����b����b���R�@�XQj.VP�@�XQj.VP�@�XQj.VP�@�X��� -�k _�(5+�v _�(5+�v ^�(t\��Yq|�b�y�B��+J�� -��+J�� -��+J�� -��+F�+�.�|���\��ځ|���\��ځ|���\��ځ|�b�y�B��+J�� -��+J�� -��+J�� -��+F�+�.�|���\��ځx���q��f��Ŋ2s��h�ŊQ�� -�K _�(5+�v _�(5+�v _�(5+�v _�u^����ŊRs��j�ŊRs��j�ŊRs��j�ŊQ�� -�K _�(5+�v _�(5+�v _�(5+�v _�u^����ŊB�� -��+��� -��+J�� -��+F�+�.�|���\��ځ|���\��ځ|���\��ځ|�"ԗ�P�@�XQj.VP�@�XQj.VP�@�XQj.VP�@�X1�X!u ���b����b����b�ċ��b�̎ËE��$+�/V���D;�/V��%�� -���b��ˀ���������GI+��b�a\���~�������c�_�8�T�����_�}�����������)���?}�>g+��+���?|�Ï��&�=�>��"� -���^��De�����I{�gy<�����4T;�GҌ:G�H]y$M�IC�y$M�IC�y$M�IC�y$ͨs$��%�GҔ��4T;�GҔ��4T;�GҔ��4T;G���42;G�9FҐ�8ISfF��@ISjF�P�@I3�I#u �4�f$ ��4�f$ ��4�����S�ΓSR�@>9UjNNQ�@>9UjNNQ�@>9UjNNQ�@>95�<9%u �S�����S����ēS���S4+ON ��S";�ON���SD;�ON���ST;�ON���ST;�ON�:ONI]��T�99E���T�99E���T�99E���Ԩ���%�ON���ST;�ON���ST;�ON���ST;�ON��rr -��'�J��)��'�J��)��'� -'�hV��s����ɩRsr�j�ɩRsr�j�ɩRsr�j�ɩQ��)�K ��*5'��v ��*5'��v ��*5'��v ��u�����ɩRsr�j�ɩRsr�j�ɩRsr�j�ɩQ��)�K ��*5'��v ��*t���Yq|r�̜�"ځ|rj�yrJ��'�J��)��'�J��)��'�J��)��'�F�'��.�|r�Ԝ��ځ|r�Ԝ��ځ|r�Ԝ��ځ|rj�yrJ��'�J��)��'�J��)��'�J��)��'�F�'��.�xr��qr�f��ɩ2sr�h�ɩRsr�j�ɩQ��)�K ��*5'��v ��*5'��v ��*5'��v �� -����5�ON���ST;�ON���ST;�ON���ST;�ON�:ONI]��T�99E���T�99E���T�99E���Ԡ99%����T���Ɋ�Se�������Gur��c?9}�2�ON�_ǟwrz~:=�����G����qr�O���~�W�����86}���W��O�W��NN�?����Ⱦ�ȯONo��NN�A$�I�W���_�8�D�� R�9�D�� Ҩ� ��%�"���HT;�"���HT;�"���HT;" ��H2;"9"��8>�Tf"�@>�Tj"Q�@>�4�<�$u �H�� ��H�� ��H�� ��H�HR�@>�Tj"Q�@>�Tj"Q�@>�Tj"Q�@>�4�<�$u �H�� ��H�� �ăH���H4+" ��H";�"���HD;�"���HT;�"���HT;�"�:"I]� R�9�D�� R�9�D�� R�9�D�� Ҩ� ��%�"���HT;�"���HT;�"���HT;�"��r ���J�A$���J�A$��� -�hVDsD��A�Rs�j�A�Rs�j�A�Rs�j�A�Q�A$�K D*5��v D*5��v D*5��v DuD���A�Rs�j�A�Rs�j�A�Rs�j�A�Q�A$�K D*5��v D*tD�Yq|��D"ځ|i�yI���J�A$���J�A$���J�A$���F���.�|��D�ځ|��D�ځ|��D�ځ|i�yI���J�A$���J�A$���J�A$���F���.�x��q�f��A�2s�h�A�Rs�j�A�Q�A$�K D*5��v D*5��v D*5��v D -�� �5�"���HT;�"���HT;�"���HT;�"�:"I]� R�9�D�� R�9�D�� R�9�D�� Ҡ9�$��� R�� Ɋ�He� �����<u��c?�|�2�"�_ǟ���W�����Ot9�"�������o�y��~p{-W�W_��������?��?�u:=]�>����_~w~�v|�������ݷ�m�Y�4������?�����f|����T��q�V�q�b����oߺ�9߽�����]m��8��ٜ��/�<�y��u|�����T;��z���T;��z�:�zH]��G�9�A���G�9�A���G�9�A���Ǩ��%��z���T;��z���T;�z:�zЬ8<�1d�z��8>�Qf�z�@>�Qj�zP�@>�Qj�zP�@>�1�<�!u ��������������γR�@>�Qj�zP�@>�Qj�zP�@>�Qj�zP�@>���Y�k ��(5g=�v ��(5g=�v ��(t���Yq|�c�y�C��g=J�Y��g=J�Y��g=J�Y��g=F�g=�.�|֣Ԝ��ځ|֣Ԝ��ځ|֣Ԝ��ځ|�c�y�C��g=J�Y��g=J�Y��g=J�Y��g=F�g=�.�|֣Ԝ��ځx֣�qփf��Y�2sփh�Y�Q�Y�K ��(5g=�v ��(5g=�v ��(5g=�v ��u�����Y�Rsփj�Y�Rsփj�Y�Rsփj�Y�Q�Y�K ��(5g=�v ��(5g=�v ��(5g=�v ��u�����Y�B�Y��g=��Y��g=J�Y��g=F�g=�.�|֣Ԝ��ځ|֣Ԝ��ځ|֣Ԝ��ځ|�#ԗ�P�@>�Qj�zP�@>�Qj�zP�@>�Qj�zP�@>�1�<�!u ������������ij�欇̎óE��$+��z���D;��z�2D������z^�8�9~�����������z��~ֳ�W}L���������������+����_� ο���'8�?����3��_}��C�_z�?i��������ˏ�ƭ�O�?����O3������_r���-~|y���?�o��������������������W�_O�}99z�W4�k�_�<�����w-o���ߵ�ځ����ߵ�ځ����ߵ�ځ����ߵ����Z�:~��j��Z�:~��j��Z�:~��j��Z��ߵ����Z�:~��j��Z�:~��j��Z�:~��j��Z:~ׂf���Z����Ɋ�ߵ8s�����ߵ�O=�~_�y�2���~���n��O�wϿk��~�r��3��×_������.��\����Ly~A3~��7�>����߯��������/�o̩>��*������g^Uz���z�����?H�o�����,�K��z��'�N����<P��h�Ku��ځ��6���?{A���՛�m�zp�x��%�@�����(���j����G���^P;�@}<==<Iu��ځo������Tdz�.���6���^0+��ރ��4�g/�x�n���U�g/���z�����Rdz�.���.\�Hu��ځ��6���?{A��u{�䏹����V��O���x��%�@�9=>Zu��ځ����A�5b<{A�����x/̍g/��������N��YV��u{n叹�����m��?pƳ�<P���ڪ���|[}������Q6;��ރ���3���v����WVݟ��v���xzx������|[}:�����,�K��zszx�������oh�叹�����m��?pƳ�|S���ކ[��YT��u{n?{A��u{���?{A��u{�Vݟ��v���y{��<��x�ޜ��?{A����t~�������ߴ��_�`V�������&Ǚ�YF��u{?{A��u{�?{A��u�7oo��?{A���՛�m���x��%�@�ކ�[���^P;�@�ކ���3���v�����Nݟ��v�����G����x��%�@�9�=�8��j�������^P;�@}<�ٿ -�g/���z�� w��x��%�@�ކ[���^P;�@������f���{p#��g/���z���Rϲ���{p�?�Ƴ�<P�w�ʪ���<PO�O���x��ځo�W��G����,�K��zs�}�����Ի�y�cn<{A��u{�䏹����V���V��YV��u{n䏹�����m��?�Ƴ�<P���l���j��>�bJϲ���� ��'/�������[���b�����G�n<{����6��N��GM�Eu <PoN7�Vݟ��v����w7Rݟ��v���� ��$�^P;��|���F��YV��u�rc��oKf��ے�:�-���oKv���dV;�-Y���dT�@��d��oKf��ے�:�-���oKv���dV;��-Y��ے��8��dG�ߖ�d��%;s|[2��ߖ���mɬv ~[�R�mɨ.��m�N���v Ϊ:u̪�ځ8���1��j⬪R3������N���v Ϊ:u̪�ځ8���1��j⬪R3������N���v Ϊ:u̪�ځ4���}V�͊�YUE�YU$;gU�9fU�@�Uu�Ue�qVթcV���YU�fV�%gU�:fUY�@�Uu�Ue�qVթcV���YU�fV�%gU�:fUY�@�Uu�Ue�qVթcV���YU��YUR�@�Uu�Ue�qVթcV���YU�lVΪ*3���.�8���1��j⬪SǬ*����N���v Ϊ*5���.�8���1��j⬪SǬ*����N���v Ϊ*5���.�8���1��j⬪SǬ*����N���v Ϊ*5���.�8���1��jҬ�C�YU6+gU�9fU�@�UUjfUQ]qVթcV���YU��YUV;gU�:fUY�@�UUjfUQ]qVթcV���YU��YUV;gU�:fUY�@�UUjfUQ]qVթcV���YU��YUV;gU�:fUY�@�UUjfUQ]iVա��*��������v Ϊ:u̪�ځ8���9PF��eJ�@��eJ�@��eJ�@��eB}(u �2�f���2�f���2�f���2�2R�@(Sj�P�@(Sj�P�@(Sj�P�@(3h���8(;�z��O��]7��K#��^������r��Ky�7z�����������F�#�r�ynw��O�>��W~�8���������y�����������w߿�B�t����������K� ^��7�z�����_��P�@�7)5�&T;��MF��&R�@�7)5�&T;�M -�&4+��M�L� ��~�Qg���%��MJM� ��~�R�oB��ߤ���P�@�7u��H]�ߤ���P�@�7)5�&T;��MJM� ��~�Qg���%��MJM� ��~�R�oB��ߤ���P�@�7u��H]�ߤ̽߄��0�7)p��P�8�7)3�&D;��MB}�7��r�I��7�ځ�oRj�M�v ����~���&��~�K ����~���&��߄jr�I��7�ځ�o2��7��r�I��7�ځ�oRj�M�v ����~���&���Df�a�I��߄d�q�I��7!ځ�oRj�M�v ���:�M�.��oRj�M�v ����~���&��߄jr�ɨ��D���&��߄jr�I��7�ځ�oRj�M�v ���:�M�.��oRj�M�v ����~���&��~���&C��Dd�q�I��7!ځ�oRj�M�v ����~���&��~�K ����~���&��߄jr�I��7�ځ�o2��7��r�I��7�ځ�oRj�M�v ����~���&����@]�ߤ���P�@�7)5�&T;�M -�&4+��MƜ�&B�@�7)5�&T;��MJM� ��~�R�oB���d��o"u �~�R�oB��ߤ���P�@�7)5�&T;��MF��&R�@�7)5�&T;��MJM� ��~�R�oB���d��o"u �~�R�oB��ߤ��oB��ߤ����@�7u��H]�ߤ���P�@�7)5�&T;��MJM� ��~�Qg���%��MJM� ��~�R�oB��ߤ���P�@�7u��H]�ߤ���P�@�7)5�&T;��MJM� ��~�Qg���%�M -�&4+��M�L� ��~�R�oB���d��o"u �~�R�oB��ߤ���P�@�7)5�&T;��MB}�7��r�I��7�ځ�oRj�M�v ����~���&��~�K ����~���&��߄jr�I��7�ځ�o2h�Mdv����8�߄/c��^��7��W���Fy��4���M㑽�t}�o��z���_���??כ>����o��_��ݏ�r��_>}��������o�^^���_�~Px�g3�w_��^�~���wQ�8��Uf�w�@�����.�k _�*5�v _�*5�v _�*5�v _�u^���Rs��j���Rs��j���Rs��j���Q��.�K _�*5�v _�*5�v _�*5�v ^�4dv^�*r\�"Yq|���\�"ځ|���\�ځ|�k�y�K��J��.��J��.��J��.��F��.�|���\�ځ|���\�ځ|���\�ځ|�k�y�K��J��.��J��.�� -hV^�2Dv_�*3�v _�*5�v _�*5�v _�u^���Rs��j���Rs��j���Rs��j���Q��.�K _�*5�v _�*5�v _�*5�v _� -��z�5��w���]T;��w���]T;�w:�wѬ8��5��%t ��]��z���]��z���]��z���]���]R�@��Uj�wQ�@��Uj�wQ�@��Uj�wQ�@��5��%u ��]��z���]��z���]��z���]���]R�@��Uj�wQ�@��U��E���zW���E��zר�z��%��w���]T;��w���]T;��w���]T;��w�:�wI]�zW���E��zW���E��zW���E��zר�z��%��w���]T;��w���]T;��w���]T;��w�:�wI]�zW��z͊��]e�z���]��z���]���]R�@��Uj�wQ�@��Uj�wQ�@��Uj�wQ�@�����.�k _�*5�v _�*5�v _�*5�v _�u^���Rs��j���Rs��j���Rs��j���As�Kf���.����]|�z�����㗲���~� /;�����e��v{Oo~a�x&�<����������>�~��݇�~���������������˷�G����~x��W'�7�����-//�_߇��ݛ����%���9��� WO�o��7�4`��%�@ߢ��|-��_ˠ�|-��_ˠ�|-��_�`����.���J��2�ځ�� -_ˀf���2(3_ˀh��2u~-�K -�R��v -�R��v -�R��v -�Q��2����2(5_ˀj��2(5_ˀj��2(5_ˀj��2u~-�K -�R��v -�R��v -�R��v -�Q��2����2(s/v��:�] -�.+��]�L���b�P_�]���\�Rj�]�v ���b���.��jr�˨��E���.��jr�K�)v�ځ\�Rj�]�v ��:�]�.�\�Rj�]�v ���b���.��jb�ˠ)v��qX�R�(v!Yq\�Rf�]�v ���b���.��b�K ���b���.��jr�K�)v�ځ\�2�,v��r�K�)v�ځ\�Rj�]�v ���b���.��b�K ���b���.��jb�K��f�a�ː)v�q\�Rf�]�v ���b���.��jr�˨��E���.��jr�K�)v�ځ\�Rj�]�v ��:�]�.�\�Rj�]�v ���b���.��jr�K�/�.P�@.v)5�.T;��]JM���b�BG�͊�b�1g���%��]JM���b�RS�B��إ��P�@.vu�H]�إ��P�@.v)5�.T;��]JM���b�Qg���%��]JM���b�RS�B��إ��P�@.vu�H]�إ��P�@,v)t�Ь8.v)3�.D;��]F��.R�@.v)5�.T;��]JM���b�RS�B���e�Y�"u �b�RS�B��إ��P�@.v)5�.T;��]F��.R�@.v)5�.T;��]JM���b�RS�B���e�Y�"u �b�BG�͊�b�2S�B��إ��P�@.vu�H]�إ��P�@.v)5�.T;��]JM���b�P_�]���\�Rj�]�v ���b���.��jr�˨��E���.��jr�K�)v�ځ\�Rj�]�v ��b���.,�b��Q�z�:�W��b��Ky���Ů�Z��������a<��Χ�:��_�ns}U��~�m�����8�0��_����������<��՝�~!����c��_����������?�Q�����VΧ�;��gY]��mx>VP������mx�/�R�g/�x�noõU�g/������ ��e����=8���?{��u{���?{A������d}�g/����t>]?�eܨ�YV������`���j�����{���^P;�@�ކ�;���^P;��2���6�:5Ϣ����ps/���j���p� ���j���p������V���p�~��YV����t��$���j����U�g/�x�>���/�G/��6y}>���<��x�n���U�g/�x�n��ݵT�g/�x�n���T�g/���z�� 7Rϲ����p}+���j���p�?pƳ�<P�L�R���j��Q���K �n(5��v �n(5��v �n(5��v �nu�n����R���j��B���ǻ����ȻF���.������n�ځ�����n�ځ�����n�ځ��aԹ�A�ȻJ���ȻJ���ȻJ���ȻF���.������n�ځ�����n�ځ�����n�ځ��aԹ�A�H���w7P|�� -�(V�n(3��v �n�ew�5�w7��� T;�w7��� T;�w7��� T;�w7�:w7H]ywC���@�ywC���@�ywC���@�ywèsw��%�w7��� T;�w7��� T;�w7��� T;w7�� 2;w79v7��8��Pfv7�@��Pjv7P�@��0��� u �� �fw��� �fw��� �fw��� ��� R�@��Pjv7P�@��Pjv7P�@��Pjv7P�@��0��� u �� �fw��� �fw��� ��� 4+w7�� ";�w7��� D;�w7��� T;�w7��� T;�w7�:w7H]ywC���@�ywC���@�ywC���@�ywèsw��%�w7��� T;�w7��� T;�w7��� T;�w7�����ȻJ���ȻJ����� -�hV�ns�n���R���j��R���j��R���j��Q���K �n(5��v �n(5��v �n(5��v �nu�n����R���j��R���j��R���j��Q���K �n(5��v �n(t�n�Yq�����n ځ��aԹ�A�ȻJ���ȻJ���ȻJ���ȻF���.������n�ځ�����n�ځ�����n�ځ��aԹ�A�ȻJ���ȻJ���ȻJ���ȻF���.����б��f���2���h��R���j��Q���K �n(5��v �n(5��v �n(5��v �n�ew�5�w7��� T;�w7��� T;�w7��� T;�w7�:w7H]ywC���@�ywC���@�ywC���@�qwà�� ��pw�xG��n����^�n��W��?��ݍ���'��n�G�ݍ뱻�����}��������~����3���l�Xo��]���V��{܊���@+�5�[�JM+��V�RӊF���Դ�Q�@nEu��I]��Դ�Q�@nE+5�hT;[� -�h4+�[�Ɯ�hB�@nE+5�hT;�[�JM+��V�RӊF��m�ي&u �V�RӊF���Դ�Q�@nE+5�hT;�[�F��hR�@nE+5�hT;�[�JM+��V�RӊF��m�ي&u �V�RӊF����ъF���̴��@nEu��I]��Դ�Q�@nE+5�hT;�[�JM+��V�Qg+��%�[�JM+��V�RӊF���Դ�Q�@nEu��I]��Դ�Q�@nE+5�hT;�[�JM+��V�Qg+��%�Z���[�(��V�G+Ŋ�V�2ӊF��-ԗV4�k ����V4�ȭh���jr+Z�iE�ځ܊6�lE��r+Z�iE�ځ܊VjZѨv ����V4�ȭh��V4�K ����V4�ȭh���jr+Z�iE�ځ؊6hZ�dv��9Z�HV����V4�ȭh���jr+ڨ�M�ȭh���jr+Z�iE�ځ܊VjZѨv ���:[Ѥ.�܊VjZѨv ����V4�ȭh���jr+ڨ�M�ȭh���jr+Z�iE�ځ؊V�hE�Yq؊6dZ�Dv����V4�ȭh���jr+Z�iE�ځ܊6�lE��r+Z�iE�ځ܊VjZѨv ����V4�ȭh��V4�K ����V4�ȭh���jr+Z�iE�ځ܊�K+�5�[�JM+��V�RӊF����ъF��m�ي&t �V�RӊF���Դ�Q�@nE+5�hT;�[�F��hR�@nE+5�hT;�[�JM+��V�RӊF��m�ي&u �V�RӊF���Դ�Q�@nE+5�hT;�[�F��hR�@nE+5�hT;[� -�h4+�[��L+��V�Qg+��%�[�JM+��V�RӊF���Դ�Q�@nEu��I]��Դ�Q�@nE+5�hT;�[�JM+��V�Qg+��%�[�JM+��V�RӊF���Դ�Q�@nEu��I]���ъF���̴��@nE+5�hT;�[�F��hR�@nE+5�hT;�[�JM+��V�RӊF��-ԗV4�k ����V4�ȭh���jr+Z�iE�ځ܊6�lE��r+Z�iE�ځ܊VjZѨv ����V4���h��Mf�a+k���/c��_�jE��?�������-����ފ�����s�݇������~x�uz��zw��敲�����!�G}�|�7��<��e~��/��ۿQ]�ۿ�:�����o�v���oV;��۩���jb�ݨ��N��=w���;��=w���;��=w���;��=w�����=w���;��=w���;�H=w��=w6+{��L��%{�N=wV;{�N=wV;{�N=wV;{�JM��%{�N=wV;{�N=wV;{�N=wV;{�JM��%{�N=wV;{�N=wV;{�N=wV;{�JM��%{�N=wV;�z��{�lV�ܝ9z�v �ܕ��;�K �ܝ:z�v �ܝ:z�v �ܝ:z�v �ܕ��;�K �ܝ:z�v �ܝ:z�v �ܝ:z�v �ܕ��;�K �ܝ:z�v �ܝ:z�v �ܝ:z�v �ܕ��;�K �ܝ������0�;pﹳXq�sw��3ځ�s7�칓�b�ݩ���jb�ݩ���jb�ݩ���jb�]�鹣�b�ݩ���jb�ݩ���jb�ݩ���jb�]�鹣�b�ݩ���jb�ݩ���jb�ݩ���jR�]���f�Q�ݑ{ϝɊÞ�3Gϝ�Ğ�SGϝ�Ğ�R�sGu Ğ�SGϝ�Ğ�SGϝ�Ğ�SGϝ�Ğ�R�sGu Ğ�SGϝ�Ğ�SGϝ�Ğ�SGϝ�Ğ�R�sGu Ğ�SGϝ�Ğ�SGϝ����C��;�G=wE��;��=wg��;��=w���;��=w���;��=w�����=w���;��=w���;��=w���;��=w�����=w���;��=w���;��=w���;��=w�Ξ;�k �ܝ:z�v �ܝ:z�v �����٬8�+3=wD�@�;u��Y�@�;u��Y�@�;u��Y�@�+5=wT�@�;u��Y�@�;u��Y�@�;u��Y�@�+5=wT�@�;u��Y�@�;u��Y�@�;u��Y�@�+5=wT�@�;u��Y�@�;tﹳYq�sw��3ځ�sWjz�.��sw�蹳ځ�sw�蹳ځ�sw�蹳ځ�sWjz�.��sw�蹳ځ�sw�蹳ځ�sw�蹳ځ�sWjz�.��sw�蹳ځ�sw�蹳ځ�sw�蹳ځ�sWjz�.��sw��sg������sg������sg������Q]�����sg������sg������sg���n��s'u Ğ�SGϝ�Ğ�SGϝ�Ğ�SGϝ�Ğ�R�sGu Ğ�SGϝ�Ğ�SGϝ�Ğ�SGϝ����BG�͎��;ԵUϝ_�����q��=��K�~z�������}���ܷ�y8�nƧk�ǞyI7�//i<�G�_�ߍ����w�i���������+����O�?���[�����ӷ�����������W��W�� ��ǻ�_җ���Y�{�'p\����@]�亜RS�C��.����P�@��u��H]�.����P�@��)5u9T;��rJM]�亜Qg]��%��rJM]�ĺ�BG]͊㺜2S�C��.g�Y�#u 亜RS�C��.����P�@��)5u9T;��rF�u9R�@��)5u9T;��rJM]�亜RS�C��.g�Y�#u 亜RS�C��.����P�@��)5u9T;��rF�u9R�@��)s�ˡ�:�r -u9+��r�L]�亜P_�r���\�Sj�r�v �唚���u9��.�jr]Ψ�.G��u9��.�jr]N��ˡځ\�Sj�r�v ��:�r�.�\�Sj�r�v �唚���u9��.�jb]Π�ˑ�qX�S��!Yq\�Sf�r�v �唚���u9�κ�K �唚���u9��.�jr]N��ˡځ\�3�ˑ�r]N��ˡځ\�Sj�r�v �唚���u9�κ�K �唚���u9��.�jb]N��.�f�a]ΐ���q\�Sf�r�v �唚���u9��.�jr]Ψ�.G��u9��.�jr]N��ˡځ\�Sj�r�v ��:�r�.�\�Sj�r�v �唚���u9��.�jr]N�/u9P�@��)5u9T;��rJM]�ĺ�BG]͊㺜1g]��%��rJM]�亜RS�C��.����P�@��u��H]�.����P�@��)5u9T;��rJM]�亜Qg]��%��rJM]�亜RS�C��.����P�@��u��H]�.����P�@��)t��Ь8��)3u9D;��rF�u9R�@��)5u9T;��rJM]�亜RS�C��.g�Y�#u 亜RS�C��.����P�@��)5u9T;��rF�u9R�@��)5u9T;�����v$���y���s]f�`�a�7sCQ-N�d�������beƪ�����V|��$�{E,��)5u9T;��rJM]�亜Qg]��%�r -u94+��r�L]�亜RS�C��.g�Y�#u 亜RS�C��.����P�@��)5u9T;��rB���@]�.����P�@��)5u9T;��rJM]�亜Qg]��%��rJM]�亜RS�C��.����P�@��4u92;�r��.W���u���8�k�.��*W��>}�+^���t-�x��Fw�.�?~���/��]�x>�q>�r�}�I�ܿ��{��+K�[�g������χǧ�G��={������h���j~�>�����,�K��z�*�wV�۳7��QO_��U�go������CEJݞ��v������p��Y��gY]wԇ��U�go���>^���={C�����z��Y�n��P;�c���ex��x��%pG=}·���={C����e8SS��� �w�ӗ�ު۳7��X}=}�߆�G����58�o8��h���U�go�����ߕ���Q�@�Nި�:yR�@�N^��N���䕚��Q�@�N^��N����z�N�5���Wj��G��:y��:yT;���Wj��G��:y����I]�:y��:yT;���Wj��G��:y����Ѭ8�Nޘ�:yB�@�N^��N���䕚��Q�@�N^��N����:�qH]yG���A�yG���A�yG���A�yǨs��%��q��}T;��q��}T;��q��}T;��q�:�qH]yG���A�qG�c͊�}ef��}��}R�@��Qj�qP�@��Qj�qP�@��Qj�qP�@��1���!u �}�f��}�f��}�f��}��}R�@��Qj�qP�@��Qj�qP�@��Qj�qP�@��1���!u �}en�8(^��>��>���8��>���8B��〺�>�R���j�>�R���j�>�R���j�>�Q�>�K ��(5�8�v ��(5�8�v ��(5�8�v ��u�㐺�>�R���j�>�R���j�>�R���j�>�A��Cf��>�"�>���8��>���8J�>���8F��8�.�������ځ������ځ������ځ��cԹ�C���8J�>���8J�>���8J�>���8F��8�.�������ځ������ځ���б��f��>�!��Cd��>�2���h�>�R���j�>�R���j�>�Q�>�K ��(5�8�v ��(5�8�v ��(5�8�v ��u�㐺�>�R���j�>�R���j�>�R���j�>�P/�8���������ځ������ځ���б��f��>�1�>�K ��(5�8�v ��(5�8�v ��(5�8�v ��u�㐺�>�R���j�>�R���j�>�R���j�>�Q�>�K ��(5�8�v ��(5�8�v ��(5�8�v ��u�㐺�>�R���j�>�B�>���8��>���8F��8�.�������ځ������ځ������ځ��cԹ�C���8J�>���8J�>���8J�>���8F��8�.�������ځ������ځ������ځ��cԹ�C���8 -�8hV��(3�8�v ��(5�8�v ��u�㐺�>�R���j�>�R���j�>�R���j�>�P/�8���������ځ������ځ������ځ��cԹ�C���8J�>���8J�>���8J�>���8�>���8��b�q�5�>��{�>���\�����>����i���|{����O��ϟ��/����?����_ǝ��������oWʿkW�^�����~�q�Kx�4.��z�q��5�qI�ȍK��q�jr�R�i\�ځܸTj��v 7.�:��.�ܸTj��v 7.���%�ȍK��q�jr�Ҩ�qI�ȍK��q�jr�R�i\�ځܸTj��v 7.�:��.�ܸTj��v 6.:�hV7.���%�ȍK���%�K 7.���%�ȍK��q�jr�R�i\�ځܸ4�l\��r�R�i\�ځܸTj��v 7.���%�ȍK���%�K 7.���%�ȍK��q�jr�R�i\�ځܸ4�l\��R�R�[���0l\*p4.Q�8n\*3�KD;��B�4.A]�q��4.Q�@n\*5�KT;��JM���ƥQg��%��JM���ƥRӸD��q��4.Q�@n\u6.I]�q��4.Q�@n\*5�KT;��JM���ƥAӸ$��q��ѸD��q��4.�@n\*5�KT;��F��KR�@n\*5�KT;��JM���ƥRӸD��qi�ٸ$u �ƥRӸD��q��4.Q�@n\*5�KT;��F��KR�@n\*5�KT;��JM���ƥBG�͊�ƥ!Ӹ$��q��4.�@n\*5�KT;��JM���ƥQg��%��JM���ƥRӸD��q��4.Q�@n\u6.I]�q��4.Q�@n\*5�KT;��JM���ƥP/�KP�@n\*5�KT;��JM���ƥBG�͊�ƥ1g��%��JM���ƥRӸD��q��4.Q�@n\u6.I]�q��4.Q�@n\*5�KT;��JM���ƥQg��%��JM���ƥRӸD��q��4.Q�@n\u6.I]�q��4.Q�@l\*t4.Ѭ8n\*3�KD;��F��KR�@n\*5�KT;��JM���ƥRӸD��qi�ٸ$u �ƥRӸD��q��4.Q�@n\*5�KT;��F��KR�@n\*5�KT;��JM���ƥRӸD��qi�ٸ$u �ƥBG�͊�ƥ2ӸD��q��4.Q�@n\u6.I]�q��4.Q�@n\*5�KT;��JM���ƥP/�KP�@n\*5�KT;��JM���ƥRӸD��qi�ٸ$u �ƥRӸD��q��4.Q�@n\*5�KT;�M�̎��%�M�_c4.���и���qy���)�����������G���|<����_~���/��������������[_����z���������]�/p~�p�3��8+58�ځ|��Rs�3��8u^�L��8+58�ځ|��Rs�3��8+58�ځ|��P/8����J�Ψv _��\��j��J�Ψv _�l�y�3�K _��\��j��J�Ψv ^��1'�f��1���K � (5s�v � (5s�v � (5s�v � u� ���R3'�j�R3'�j�R3'�j�Q���K � (5s�v � (5s�v � (5s�v � u� ���R3'�j✀Bǜ���s�̜���sF�s�.�<'��� �ځ<'��� �ځ<'��� �ځ<'`�9'@��sJ͜���sJ͜���sJ͜���sF�s�.�<'��� �ځ<'��� �ځ<'��� �ځ<'`�9'@�Hs���P��9�9+����9D;���z��u �9�fN���9�fN���9�fN���9��9R�@�Pj�P�@�Pj�P�@�Pj�P�@�0� u �9�fN���9�fN���9�fN���9�fN�̎�9E�9$+����9D;����9T;���:�H]yN@��@�yN@��@�yN@��@�yN��sN��%����9T;����9T;����9T;���:�H]yN@��@�yN@��@�qN@�cN�͊�9CfN�Ȏ�9efN���9�fN���9�fN���9��9R�@�Pj�P�@�Pj�P�@�Pj�P�@�0� u �9�fN���9�fN���9�fN���9�^�@]yN@��@�yN@��@�qN@�cN�͊�9c�9B�@�Pj�P�@�Pj�P�@�Pj�P�@�0� u �9�fN���9�fN���9�fN���9��9R�@�Pj�P�@�Pj�P�@�Pj�P�@�0� u �9�fN���9��94+����9D;���:�H]yN@��@�yN@��@�yN@��@�yN��sN��%����9T;����9T;����9T;���:�H]yN@��@�yN@��@�yN@��@�yN��sN��%�:�Ь8�Pf��@�Pj�P�@�0� u �9�fN���9�fN���9�fN���9�^�@]yN@��@�yN@��@�yN@��@�yN��sN��%����9T;����9T;����9T;��92;����nN�_c� \����ewN`�U������﷏8'09�����v����e�����/��/u~Wo9<��p���t<<<?�. -���;�W/��x�"�x'u �ƻR�xG����4�Q�@n�+5�wT;��B�4�A]���4�Q�@n�+5�wT;��JM���ƻQg��%��JM���ƻR�xG�����xG���n��x't �ƻR�xG����4�Q�@n�+5�wT;��F��wR�@n�+5�wT;��JM���ƻR�xG���n��x'u �ƻR�xG����4�Q�@n�+5�wT;��F��wR�@n�+5�wT;� -�w4+���L���ƻQg��%��JM���ƻR�xG����4�Q�@n�u6�I]���4�Q�@n�+5�wT;��JM���ƻQg��%��JM���ƻR�xG����4�Q�@n�u6�I]��̭��u6�8�(V7ޕ��;�ȍw�^��xWj�v 7ޕ��;�ȍw���jr�ݨ��N�ȍw���jr�]�i��ځ�xWj�v 7ލ:�.��xWj�v 7ޕ��;�ȍw���jb�ݠi���q�xW�h�#Yq�xWf�v 7ޕ��;�ȍw���;�K 7ޕ��;�ȍw���jr�]�i��ځ�x7�l���r�]�i��ځ�xWj�v 7ޕ��;�ȍw���;�K 7ޕ��;�ȍw���jb�]���f�a�ݐi��q�xWf�v 7ޕ��;�ȍw���jr�ݨ��N�ȍw���jr�]�i��ځ�xWj�v 7ލ:�.��xWj�v 7ޕ��;�ȍw���jr�]���;�k 7ޕ��;�ȍw���jb�]���f�q�ݘ��N�ȍw���jr�]�i��ځ�xWj�v 7ލ:�.��xWj�v 7ޕ��;�ȍw���jr�ݨ��N�ȍw���jr�]�i��ځ�xWj�v 7ލ:�.��xWj�v 6�:�hV7ޕ��;�ȍw���;�K 7ޕ��;�ȍw���jr�]�i��ځ�x7�l���r�]�i��ځ�xWj�v 7ޕ��;�ȍw���;�K 7ޕ��;�ȍw���jr�]�i��ځ�x7�l���b�]���f�q�]�i�#ځ�xWj�v 7ލ:�.��xWj�v 7ޕ��;�ȍw���jr�]���;�k 7ޕ��;�ȍw���jr�]�i��ځ�x7�l���r�]�i��ځ�xWj�v 7ޕ��;���w���Nf�a�}�������~��x����~�����y��,5��#�7z�������������~����o�Jϧ_^��Oz_�?���>�������w�������o_??^_�>z����j�χ��g�n��P;pG}=���I�۳7��X}9}��:�eu �QO_�� �n��P;pG=}��U��� �w�ӗ�ު۳7��X}=}��=�f�퐧���(���h���U�go����u�f����ιR�@��Pj�>P�@��Pj�>P�@��Pj�>P�@���e��5��>���T;��>���T;��>���T;��>�:�>H]y�C���@�y�C���@�q�C�c�͊�cιB�@��Pj�>P�@��Pj�>P�@��Pj�>P�@��0�� u ��f����f����f����ιR�@��Pj�>P�@��Pj�>P�@��Pj�>P�@��0�� u ��f��Ĺ���4+��>���D;��>�:�>H]y�C���@�y�C���@�y�C���@�y�ès��%��>���T;��>���T;��>���T;��>�:�>H]y�C���@�y�C���@�y�C���@�y�ès��%��>���}�x�s -s(V�}(3s�v �}�2���sJ����sJ����sJ����sF�s�.�<����}�ځ<����}�ځ<����}�ځ<�a�9�A��sJ����sJ����sJ����s����s�sHV�}(3s�v �}(5s�v �}u�}���܇R3��j�܇R3��j�܇R3��j�܇Q���K �}(5s�v �}(5s�v �}(5s�v �}u�}���܇R3��j�܇R3��j�܇B����s�����s�����sJ����sJ����sF�s�.�<����}�ځ<����}�ځ<����}�ځ<�a�9�A��sJ����sJ����sJ����sB��}���܇R3��j�܇R3��j�܇B����sƜs�.�<����}�ځ<����}�ځ<����}�ځ<�a�9�A��sJ����sJ����sJ����sF�s�.�<����}�ځ<����}�ځ<����}�ځ<�a�9�A��sJ����s -shV�}(3s�v �}u�}���܇R3��j�܇R3��j�܇R3��j�܇Q���K �}(5s�v �}(5s�v �}(5s�v �}u�}���܇R3��j�܇R3��j�܇R3��j�܇Q���K �}(t�}�Yq<����} ځ<����}�ځ<�a�9�A��sJ����sJ����sJ����sB��}���܇R3��j�܇R3��j�܇R3��j�܇Q���K �}(5s�v �}(5s�v �}(5s�v �}4sdv�}�z�����sW�q�{ݝ���?5�q>�y�zOs�#�oo�4�>���/�����/_��O_~�������oJ����{ܛ�H�꿾ۇ�~��>��߇&u �>�SG���>�SG���>�SG���>�RӇFu �>�SG���>�SG���>�C�>4��}he����}h��>4��}h��>4��}h��>4��}h�����}h��>4��}h��>4��}h��>4��}h�����}h��>4��}h��>4��}h��>4��}h�����}h��>4�H}h�n}h6+���}hF;��JM�%��N}hV;��N}hV;��N}hV;��JM�%��N}hV;��N}hV;��N}hV;��JM�%��N}hV;��N}hV;��N}hV;��JM�%����ևf�:������,V���9�Ќv ���:�Ф��؇v��C�ځ؇v��C�ځ؇v��C�ځ؇Vj�Ш.�؇v��C�ځ؇v��C�ځ؇v��C�ځ؇Vj�Ш.�؇v��C�ځ؇v��C�ځ؇v��C�ځԇV��C��qԇv�ևf����чf����чf������Q]���чf����чf����чf������Q]���чf����чf����чf������Q]���чf����чf���Э�f�QZ���d�aڙ��hbک��jbک��jbZ��C��bک��jbک��jbک��jbZ��C��bک��jbک��jbک��jbڨ�M��}h��>4��}h��>4�H}h�n}h6+���L�%��N}hV;��N}hV;��N}hV;��JM�%��N}hV;��N}hV;��N}hV;��JM�%��N}hV;��N}hV;��N}hV;��JM�%��N}hV;������lV���9�Ќv ����>4�K ���:�Ьv ���:�Ьv ���:�Ьv ����>4�K ���:�Ьv ���:�Ьv ���:�Ьv ����>4�K ���:�Ьv ���:�Ьv ���:�Ьv ����>4�K �����٬8�C;s���@�C;u��Y�@�C+5}hT�@�C;u��Y�@�C;u��Y�@�C;u��Y�@�Cu��I]���чf����чf����чf������Q]���чf����чf����чf����чF��ͭ��}h~�����8����U�\��ۯe��=q~��ن���O?����߶������������7:���O;�ɺ����zy��뻷�+��%VC��Jd�a�Ո��J�u�W8۫ vwW ��*���UC��Jd�qkՐ)�Yq\Y�l��q�W5d�DV�U ��*��MUC��Jd�qMU��� -d�qGՐ��Yq\P5d��DV�S �r*���TA�f*�ǽTC��Jd�a)Ո��J�u7R �B*��uTA�6*��]TC��Jd�qՐ�Yq�B5dJ�DVWP9�@v�O ��)���SC�{Jd�q�Ԑ)�Yq\;�l��q�95d*�DVN ��)��mSC�lJd�q�T��i -d�Q�Ԁ[͔��(,�mtL��ㆩS0%��^z���K��%����L��Ȋ�b�!�+%��UjȔJ��8�� -r6J��8�2uR"+�ˤ�L��Ȋ�&�!S$%��F*��"��Cj�TH��8.�2�Q"+�ۣ�Ly�Ȋ����°7j�Q%�:�K�Lg�Ċ�ƨ!S%��.*����+j�TE��8.�2=Q"+�[��LI�Ȋ㊨ gCȎ�~�!S%��j�tC��8n�2�P"+�k����P ;�;��L%�Ȋ�B�!�%�� j�Q%�:���K� -��S%��j�t@��8n�2P"+�럂��O ;����L��Ȋ��!��$���iȔ>��8�| -r6>��8�{2uO"+�˞�LדȊ㦧!S�$���y���<��%�;��LœȊェ!��$���i�Q�$�:�����N;�{��L��Ȋ�R�!��$���i�:��8�s -r�9��8�r2UN"+����L��Ȋ��!S�$���)����㸿i��7��8.o2�M"+����Lq�Ȋ�ڦ gkȎ�Φ!S�$�ⰰi���$�:�ۚLY�Ċ㪦 gSȎ㞦!S�$�⸤i�t4��8nh2M"+�뙂��L ;����L5�Ȋ�b�!��$�⸕iȔ2��8�d -r62��8�c2uL"+�˘�L�Ȋ�&�!S�$�⸆)����㰃i�Q�$�:��L��Ċ���!S�$��z)�ټ��wi��.��8.]2�K"+���L�Ȋ��m�Ҷ�'�8�Z2UK"+����LϒȊ㖥!S�$��b)�ٰ��_i��+��8.W2�J"+����L��Ȋ�Z�Ӫ�°S��t�Jz�Ѩ��*w����)O����������^F��~���O��������~87+���Ͽ�����뗿~���ӿ|����o����_�����{ߵ|:�.����}~��hg�~&�V\�L���_��v �+�:�.�\�Pj:�v �,�����E��i�jr�¨�lA��u��o�jr�B��\�ځ\�PjZ�v �.�:��.�\�Pj��v �/���������jrè��A�H5en=�ð���Q�@�⸌�̴1�@�c�R��u �J�R��@������2P�@.f(5�T;��F��R�@�g(5�T;�JME�䒆R��@���a�Y� u 䪆R��@������5P�@.l(5� T;;Mi�̎�چ"GoɊ��2S�@����Դ7P�@�ou8H]�¡�t8P�@nq(55T;��JM���.�Qg���%��JM���F�RS�@��ԡԴ:P�@�uu;H]�ڡ�t;P�@nw(5�T; - 4+;�LɃȎ㚇2��@����T=P�@.{(5mT;��F��R�@�|(5�T;�[JM����R��@���a�Y� u ���R��@����T@P�@.�(5-T;�{ B�A@]� -��tAP�@n�(5uT;! -�4+�;!Ɯ�B�@��(5�T;��!JM5��r�R�A��b�Y!u 䊈R�A��%���DP�@.�(5MT;��"F�eR�@��(5}T;�#JMe��҈R�A��7b�Y!u ��R�A��=��QA��@��4H�@�u�HH]�F���HP�@n�(5UT;��$JM���>�Qg���%�+%JM���V�RS+A��X��4KP�@�u�KH]�^���KP�@n�(5T;�K&JM��䞉Qgф�%�& -]4+��&�L���R�8A��sb�Y:!u �ډR�;A��y��TOP�@.�(5�T;��'B�P@]����tPP�@n�(55T;��(JM��.�Qg��%��(JM��F�RSIA����ԴRP�@�4�2;�)T�0�|�QN�zj���RO��z������TO����u�S���O���×�~)�[�G��rI���O�}������o�i��������������_�u{��ځ;����h���j�����n��P;�c��xxx{r�x��%pG}8��Zu{��ځ;����t�Rݞ��v���zx=�&�R�go����r�2<Iu<�������/Jݞ��v��z�2��ޫ���j/ýU�go����z�2�;t{�͎�!O_��Q�۳7��QO_�;�n��P;pG}=}c����� �?Vߎ��W� g<����>^^��={C����p�,�͍go�����O��x��ځw{�N_�G��YT����exx���� �w�ӗ��E�۳7��QO_��U�go��s#븛֨�[R�@��V�����o��oQ�@��V���[4+���5����%�o�Uj��E���[���[T;��Uj.�E�� -\��;pI]�\��\T;�/�Ujn�E��.\��2\T;���5���%�o�Uj��E��R\��V\T;���Uj.�E��j\�λqI]�v\��z\T;/�U�qA��x�E��qA�y�Ũsƅ�%�g\��T;�g\��T;�g\��T;�g\�:g\H]y�E��qA�y�E��qA�y�E��qA�y�Ũsƅ�%�g\��T;�g\��T;�g\��T;�g\�:g\H]i�E�ی��a8��1�b��23�h�P/3.���<��̸�ځ<��̸�ځ<��̸�ځ<�b�9�B��3.J͌��3.J͌��3.J͌��3.F�3.�.�<��̸�ځ<��̸�ځ<��̸�ځ8�b�̸��q8��1�d��23�h�R3�j�Q��K ϸ(53.�v ϸ(53.�v ϸ(53.�v ϸuθ���R3�j�R3�j�R3�j�Q��K ϸ(53.�v ϸ(53.�v θ(t̸�Yq8�b�̸�q<��̸ ځ<��̸�ځ<��̸�ځ<�b�9�B��3.J͌��3.J͌��3.J͌��3.F�3.�.�<��̸�ځ<��̸�ځ<��̸�ځ<�"�ˌ�k ϸ(53.�v ϸ(53.�v θ(t̸�Yq<�b�9�B��3.J͌��3.J͌��3.J͌��3.F�3.�.�<��̸�ځ<��̸�ځ<��̸�ځ<�b�9�B��3.J͌��3.J͌��3.J͌��3.F�3.�.�<��̸�ځ8��1�f��23�h�Q��K ϸ(53.�v ϸ(53.�v ϸ(53.�v ϸuθ���R3�j�R3�j�R3�j�Q��K ϸ(53.�v ϸ(53.�v ϸ(53.�v ϸuθ��⌋Bnj��3.�̌��3.J͌��3.F�3.�.�<��̸�ځ<��̸�ځ<��̸�ځ<�"�ˌ�k ϸ(53.�v ϸ(53.�v ϸ(53.�v ϸuθ���R3�j�R3�j�R3�j⌋A3�Bf�����|�1�r����������[���/�8�29��ۜqy���ӯ�|��3��x��v��~���&�ߝqɴ �ݜ6�z��i��/�&�v O�uN����R3m�j�R3m�j�R3m�j�Q� �K O�(5�&�v O�(5�&�v O�(5�&�v N�4�&dvO�(3�&�v O�(5�&�v O�(5�&�v O�uN����R3m�j�R3m�j�R3m�j�P/�&���<m��L��ځ<m��L��ځ<m��L��ځ<mb�9mB���&Jʹ ���&Jʹ ���& -�&hVO�sN���R3m�j�R3m�j�R3m�j�Q� �K O�(5�&�v O�(5�&�v O�(5�&�v O�uN����R3m�j�R3m�j�R3m�j�Q� �K O�(5�&�v N�(tL��Yq<m��L� ځ<mb�9mB���&Jʹ ���&Jʹ ���&Jʹ ���&F��&�.�<m��L��ځ<m��L��ځ<m��L��ځ<mb�9mB���&Jʹ ���&Jʹ ���&Jʹ ���&F��&�.�4m��m���0�6Q��6A��x�D��6A�y�D��iP�@�6Qj�MP�@�6Qj�MP�@�6Qj�MP�@�61�6!u �i�f���i�f���i�f���i��iR�@�6Qj�MP�@�6Qj�MP�@�6Qj�MP�@�61h�M��8�6Q�6A��x�D��6A�y�D��6A�y�Ĩsڄ�%��M��iT;��M��iT;��M��iT;��M�:�MH]y�D��6A�y�D��6A�y�D��6A�y�Ĩsڄ�%��M��iT;��M��iT;�M:�MЬ8�61d�M��8�6Qf�M�@�6Qj�MP�@�6Qj�MP�@�61�6!u �i�f���i�f���i�f���i��iR�@�6Qj�MP�@�6Qj�MP�@�6Qj�MP�@�6�e��5��M��iT;��M��iT;�M:�MЬ8�61�6!t �i�f���i�f���i�f���i��iR�@�6Qj�MP�@�6Qj�MP�@�6Qj�MP�@�61�6!u �i�f���i�f���i�f���i��iR�@�6Qj�MP�@�6Q�6A��x�D��6A�y�Ĩsڄ�%��M��iT;��M��iT;��M��iT;��M�:�MH]y�D��6A�y�D��6A�y�D��6A�y�Ĩsڄ�%��M��iT;��M��iT;��M��iT;��M�:�MH]q�D�c�͊�ief���i�f���i��iR�@�6Qj�MP�@�6Qj�MP�@�6Qj�MP�@�6�e��5��M��iT;��M��iT;��M��iT;��M�:�MH]y�D��6A�y�D��6A�y�D��6A�q�Ġ�6!��p�d��M��k�i����i��WY�M�y�����t���&�oot7�M����������O��?}������o�}���������������w?~��ۧ�%��ӯ�.��{<�r�i�ӽ4��2VW?��������� +��a�jr�J�iX�ځܰ2�lX��r�J�iX�ځذR�hX�YqܰRfV�v 7��:V�.�ܰRjV�v 7������ +��a�jr�ʨ�aE�� +��a�jr�J�iX�ځܰRjV�v 7��:V�.�ܰRjV�v 7������ +��a�jr�ʨ�aE�H +en +�ða��ѰB��a��4��@nX �Ұu 䆕RӰB��a��4�P�@nX)5 +T;�VF� +R�@nX)5 +T;�VJM� -�䆕RӰB��ae�ٰ"u 䆕RӰB��a��4�P�@nX)5 +T;VMÊ̎Æ�"G� -Ɋ㆕2ӰB��a��4�P�@nXu6�H]�a��4�P�@nX)5 +T;�VJM� -�䆕QgÊ�%�VJM� -�䆕RӰB��a��4�P�@nXu6�H]�a��4�P�@nX)5 +T;V - +4+V�LÊȎ㆕2ӰB��a��4�P�@nX)5 +T;�VF� +R�@nX)5 +T;�VJM� -�䆕RӰB��ae�ٰ"u 䆕RӰB��a��4�P�@nX)5 +T;�VB�4�@]�a��4�P�@nX)5 +T;V - +4+�VƜ +B�@nX)5 +T;�VJM� -�䆕RӰB��ae�ٰ"u 䆕RӰB��a��4�P�@nX)5 +T;�VF� +R�@nX)5 +T;�VJM� -�䆕RӰB��ae�ٰ"u 䆕RӰB��a��ѰB��a��4��@nXu6�H]�a��4�P�@nX)5 +T;�VJM� -�䆕QgÊ�%�VJM� -�䆕RӰB��a��4�P�@nXu6�H]�a��4�P�@nX)5 +T;�VJM� -�䆕QgÊ�%V - +4+�V�L� -�䆕RӰB��ae�ٰ"u 䆕RӰB��a��4�P�@nX)5 +T;�VB�4�@]�a��4�P�@nX)5 +T;�VJM� -�䆕QgÊ�%�VJM� -�䆕RӰB��a��4�P�@lX4 +2;V� װ�� ��>4��_��]}��5��#�7�/_�e������_�����>�V����������������_��O_~����������˛}P�:��w -W��=�����������/��Q�@>u�Ԝ�G��ԽQ�{R�@>u�Ԝ�G��ԽRs���S�Jͩ{T;�O�u��'u �S���Nݣx���8NݣXq|�^�9u�h�{�^N݃��{���=�ȧS��v ��WjNݣځ|�ި��=�K ��WjNݣځ|�^�9u�j�{���=�ȧ�:Oݓ��{���=�ȧS��v ��WjNݣځx�ޠ9uOf��{E�S�HV��WfN�#ځ|�^�9u�j�{��S��.�|�^�9u�j�{���=�ȧS��v ��7�<uO�ȧS��v ��WjNݣځ|�^�9u�j�{��S��.�|�^�9u�j�{���=����:NݣYqx�ސ9uOd��{e��=�ȧS��v ��WjNݣځ|�ި��=�K ��WjNݣځ|�^�9u�j�{���=�ȧ�:Oݓ��{���=�ȧS��v ��WjNݣځ|�^��S����|�^�9u�j�{���=����:NݣYq|�ޘ��=�K ��WjNݣځ|�^�9u�j�{���=�ȧ�:Oݓ��{���=�ȧS��v ��WjNݣځ|�ި��=�K ��WjNݣځ|�^�9u�j�{���=�ȧ�:Oݓ��{���=����:NݣYq|�^�9u�h�{��S��.�|�^�9u�j�{���=�ȧS��v ��7�<uO�ȧS��v ��WjNݣځ|�^�9u�j�{��S��.�|�^�9u�j�{���=�ȧS��v ��7�<uO����:NݣYq|�^�9u�h�{���=�ȧ�:Oݓ��{���=�ȧS��v ��WjNݣځ|�^��S����|�^�9u�j�{���=�ȧS��v ��7�<uO�ȧS��v ��WjNݣځ|�^�9u�j�{���=�������S������{Щ��W9�����xϧ�O�N}�������ۭ����_�����F����}���_��_��������p�G��z��|�����ӷ?���<s�2�H������������e��v�����qEn�2Yq;�������e��>&�O��#ǣHv�y���g��Q&+n�<}��?~3��(��C�>��$�G����ɇӇ��7A�G�����v�S7Cn�2Yq;����U�ۣLV��zx{ys��(��1�x<<>;r<�d�퐧��v{������?�=�b�퐧O�Q�ۣLV�����p߹ƣHv�y����w��(��C�>��$�G������߹�\�Q&+�c��xxxs߹ƣHv��px}���(��C>^��ƣLV��zx}v߹ƣLV������9E��v�Ӈ��s�G������?�o#�Q&+n�<}����e��>&_O��[��$���>���62e��v��''��Q&+n�|=��ɏu{�Ɋ��|;�_ݷ��(��C>^^$�=�d�퐧_�?��\�Q&+n�<}�O���x�Ɋ���zw���G�\�v�Ӈ�����Q&+n�<}��/��e��v�Ӈ���(��1y<}�w�;WE��vȇ��ۛ#�G�����p|���(��C������I��>���6�GQ����?Kr{�Ɋ�!O��ӽ#�G������?>8r{�Ɋ��|8}���"�q;��ÿt��(��C�>���62e��v�Ӈ'��Q&+n�*�q7� �]�@v��m�\�Md��5߆�-�DV��m�\�Md��߂��{�q|��!s�7��W{q��M�u��m�\�Mb��ނ�wz�q|��!s�7���y2�yYq|��!s�7��yr�� d��-ކ̜��cb�̖��Kb�̐��3b��+b@vo�2bDV�2�aDV��2�aDVO� r.��q�f�m6���( 3��#�:����0+���n����}r��0Cf*�Ȋ�0Cf'�Ȋ�0Cf$�Ȋ�0A΅0 ;����y0"+����m0"+����a0"+�g�9W���8�3d&���83d����8^3d����8�b����0�3ޘ#�:�G�� 0+���0"+��9��8��2d����8�2dv���8^�2dF���8���\���x�ː��"��x�ː��"��x�ː�"��x�K�s�Ȏ�/Cf�Ȋ�/CfߋȊ�u/#�q/��p�KxY���x�ˀ��"��x�ː��"��x�ː�"��x�K�s�Ȏ�-/CfʋȊ�!/CfNjȊ�/CfċȊ� /A�/ ;�����."+�ǻ��."+�����."+�g�n��ծ}r���.Cf��Ȋ��.Cf��Ȋõ.#��.��x�K�s�Ď�.Cf��Ȋ�.Cf��Ȋ�.Cf��Ȋ�y.A�u. ;����i."+����]."+�W��Q."+�'�9���8��2d済�8�2d����8^�2d����8���\���x�ː��"��p�ˈc���0^�2`ƷH�8���\���xwː��"��xtː��"��xqː�"��xnK�smȎ�-Cfj�Ȋ�-Cfg�Ȋ�-Cfd�Ȋ�-A΅- ;����y-"+�ǵ�m-"+����a-"+�g�9W���8��2��"�:���=-+�״�1-"+���9����8��2df���8�2d6���8^�2d���8�ϺM^ֳ��%�����,"+�����,"+�W���,"+�'�9���8��2d沈�8�2d����8^�2d����8��bV���0���݀rY�c!������@��{\�cm4���zx=�\^����^�_/�'����?��%'��؞k�endstream +xڜ�[�\镜���%�0㜑}�d7e-S�qD��bZ(T� +&P}��ډ�����픍�4[�$U��c��v��v�=�6����7��黷?�������ͮ�8�ϛ�i?��;�每���8�z��<�ww���7�)�����p<>?��?��o~���q�x>|��?���̟~��_M��y���i��O����~����/O���ӫ��~~����/�������ӳ�������������7���R����a�����v���~���n��~���C���͋r>lN���rG��]Q=pA=o��T��]Q=pA��#�x������ /�L�gYm��as|H��������)T�gWT\P���t����𧻓�m8�j=�j\P������+�.��۰��������6�Ru~vE������6l3��e�.�����O���a�isI��]-n�����.4�gWP������!�Q�gQ��as8�������.��:?��z��:���:?��z�}u7� �P�gYm���6�O�:?��z��:� �s��Ϯ���N��6U�gWT��N~x�~��YV[��z�L?Bu~vE����yxH��������X��:?��z�}�0� ���G���rz���Ώ���@No�q��+�.��p�Գ+��W��[��z����N��.�WϮ���No�6�iSϮ���^6��T��]Q=�z�nΗ�7�,�-pA=lv��@Գ+�.�������+�.���p +�ճ+��W���p�Գ���uz�:?��z��:� ��g\=��z��:� �� Ώ��w�|�ރ����(��@No�65�gWP\PO��c��[Ϯ���^6�K��Ϯ�x_�l7���g\=�j\P��9�iSϮ���No�)U�gWT\P������gWT��>No�!T�YV[��:� ��g\=��z��:� ��g\=��z��:� �T��]Q=�z�n7���g��E�.���c�������is|H����ԇM�7�����=��YF[��:��T��]Q=pA�ރ�>T�gWT\P�w�p�������m؇j=�j\P��aw������m؞Bu~vE���asyL����難��p�~��YV[����\��e�gWT\PO��9U�gWT\P������gWT��������gYm���6Ru~vE��uz��i�]1-n��ރ}���]A=�z�ރ]�ֳ���uz³=��z��z��ó=��z����y���������v��N�,�-pA�o³=��z��:� �T��]Q=pA�ކ��DϮ�x_}�ކ��Dϲ���mا������6�g'zvE��uz³=��z�}����C��e�.���9E�=�bZ�y����=��z����9?���������=�O�,�-pA�ޅ��DϮ���No�1U�gWT\P��!<>ѳ+��UO��m?�ֳ���uzv�:?��z��:� ��]Q=pA}¿ϤgWT���%T�YV[���ߜ��=��z��z�lϩ:?��z��:� ��P��]Q=ކ�8�lz�9�ǐ��� +iq��v�9?��z��:���O������(N��f�/��ۗ����u6���2�e5��ߊ�s5�<��9<�gTM9U5��E�7���{����O/�*/k(������1��o��Re� :?�<��n_�����n�;�j=�j\P�����+�.���n���+�.��۰M�������f�x��z����6���_��Ϯ����7ۇT��]Q=pA�lNӏ�L��]Q=�z�ކ��_�ֳ���uz��:?��z��:� ��H̏���@N���#3�gWP\���}�HU���L�"���L�"���L�"���HU���L�"���L�"���L�"���HU���L�"���L�"���L�"���HU����V@d�6� +�8Y�8, ff�@, &�( ������U@d�����U@d�����U@d����* ������U@d�����U@d�����U@d����* ������U@d�����U@d�����U@d����U@D�㨀��s�I��bfV�Q�b�V�U�b����j�b�V�U�b�V�U�b�V�U�b����j�b�V�U�b�V�U�b�V�U�b����j�b�V�U�b�V�U�b��D6-� +�YD$=��YDF=��ZDV=��ZDV=���"�-��ZDV=��ZDV=��ZDV=���"�-��ZDV=��ZDV=��ZDV=��: +���@, fjY�@, fjY�@* f�\@d�Ⰰ�* "�����U@d�����U@d�����U@d����* ������U@d�����U@d�����U@d����* ������U@d�����U@d�����U@d����* ������U@d�����s�M��bfV�Q�b����j�b�V�U�b�V�U�b�V�U�b����j�b�V�U�b�V�U�b�V�U�b����j�b�V�U�b�V�U�b�V�U�b����j�b��D6-��YDF=��ZDV=���"�-��ZDV=��ZDV=��ZDV=��: +���@, fjY�@, fjY�@, fjY�@, F� +���@, fjY�@, fjY�@, fjY�@* Fh��8* f�\@d�Ⰰ��U@d���ݹ��ȯ��3�/c����W��<�a�x�q��Q�\��}��/���ǯ��}�q��~����x������}y�{�q���������������O�~��tzUߤ���|����^0�_�廛����v�������b����/v�~���� T=��7"U��z �o$�� ���F��~U���H�����Z�hZ�o$��7��8�߈L�o �|����@��~#Ru�����F��� R[ �oD��7P�@�߈T�o��|����@��~#Q���-��7"U��z �oD��7P�@�߈T�o��|���� P{ �oD��7P�@�߈T�o��x��u������Fb�� B[ �oD��7P�@�߈T�o��|����@��~#Q���-��7"U��z �oD��7P�@�߈T�o��|����~������� T=��7"U��z �oD��7P�@��H�q�Aj���H�����Z�hZ�oD��7�@��H�q�Aj���H�������� T=��7"U��z �o$�� ���F��~U���H�������� T=��7u�o���~#Ru�����F��~U���H������:�7Hm�x��u������Fd�~Q���H������:�7Hm�|����@��~#Ru�����F��~U���@��o���~#Ru�����F��~U���H������:�7Hm�|����@��~#Ru�����F��~U��������Y�HZ�oD��7�@��X� ��7�u��7/��q�~c�u|����c +��O��-����xy����=2_o�v�O�������/O>���a�����z���Oo>�����o�__9���9�d +���dz�kX^2}�B`ɔ��K���%ST=��L#UK��z /�F��LQ�@^2MԱdJj�%�HՒ)��K���%ST=��L#UK��z /�&�X2%��i�j�U�%�HՒ)��K���%ST=��Lu,���i�42�%So�p�4k�E��%��Ԓ)��K��z]2��i�j�U�%�HՒ)��K���%ST=��Lu,���y�4R�d���i�j�U�%�HՒ)��K��:�LIm��d�Z2E�y�4R�d���i�j�U�%�Ւ)��K�YK�HZ/�F��L�@^2�T-��ꁼd��cɔ��K���%ST=��L#UK��z /�F��LQ�@^2MԱdJj�%�HUU�&L�� ��r&RՄA�� ��� Cj�&L�� ��r&RՄA�� �ՄA�� ��j��q܄�L5a�@n�D��0�z 7a"UMT=��0�:�0��@n�D��0�z 7a"UMT=��0��&��M�DMR[ 7a"UMT=��0��&��M�HUU�&L�^�0��@n�D��0�z 7a"UMT=�0ZM4-��0�9�0��@n�D��0�z 7a"UMT=��0��&��M�DMR[ 7a"UMT=��0��&��M�HUU�&L��&�-��0��&��M�HUU�&L�� ��r&QG���M�HUU�&L�VM��&Ld� ��r&QG���M�HUU�&L�� ��r&RՄA�� ��� Cj�&L�� ��r&RՄA�� �j �܄I�ф!�r&RՄA�� �j �܄�T5aP�@n�$�h�� �ՄA�� �j� �܄�T5aP�@n�$�h�� �j �܄�T5aP�@n�D��0�z 7a�ڄ�r&RՄA�� �j �܄�T5aP�@n�$�h�� �j �܄�T5aP�@n�D��0�z 6aTM2=�0YM$-��0��&��M���FԄ��17an^4a�_Gk�� s:oN�6aꑹ sԊ���_>���?Ɔ���Sm���M�`~���v�~|�o��+��?x����m���Ԇ �e���ͯc�!��@CU�H��!��rC$QGC��� �HUCU�H��!��rC$R�A��!���!Bj�H��!��rC$R�A��!�j����I��!�RC$2���a���j��hq��L5D�@n��!j�H��!��rC$R�A��!�j����I��!�rC$R�A��!�j�����T5DP�@n�$�h����!�j�����T5DP�@n�D�"�z 6DT 2="Y $-�"����� �HUCU�H����-�"����� �HUCU�H��!��rC$QGC��� �HUCU�H��!��rC$R�A��!���!Bj�H��!��rC$R�A��!��A��!��j��q��L5D�@n�D�"�z 7D"U T=�"�:"��@n�D�"�z 7D"U T=�"����� �D R[ 7D"U T=�"����� �HUCU�H�^"��@n�D�"�z 7D"U T="Z 4-�"�9"��@n�D�"�z 7D"U T=�"����� �D R[ 7D"U T=�"����� �HUCU�H����-�"����� �HUCU�H��!��rC$QGC��� �HUCUĆH�VCM��Hd�!��rC$QGC��� �HUCU�H��!��rC$R�A��!���!Bj�H��!��rC$R�A��!�j����I��!�rC$R�A��!�j�����T5DP�@n�$�h����!��A��!�j� ���T5DP�@n�$�h����!�j�����T5DP�@n�D�"�z 7D���rC$R�A��!�j�����T5DP�@n�$�h����!�j�����T5DP�@n�D�"�z 6DT 2="Y $-�"����� ��*C���17Dn^�e��Y~]C�x���RC��"�j���/O�w�W?~z�e�D�{S��ݗ��U^�^����������7���������Ǐ�?�<�>Oy}�����i�l�Ge\g�/o\g������_���&��uvd���(ކ�uv�u6���ّ��lD=����z� j���H�u6���ّ��lT=���#U�٨z _g'��&��uv��:U���H�u6���ّ��lT=���u\g���:;Ru����uv��:U���H�u6���� ��l2=��#�����8�ΎL]g#�|����F��:;Q�u6�-���#U�٨z _gG���Q�@�ΎT]g��|����:����ّ��lT=���#U�٨z _gG���Q�@��N�q�Mj���H�u6���ّ��lT=��#���Ѵ8��NH]g�q|����F��:;Ru����uv��:U���D�٤�@�ΎT]g��|����F��:;Ru����uv���lR[ _gG���Q�@�ΎT]g��|����F��:;P��٠�@�ΎT]g��|����F��:;B�:M������ل�@�ΎT]g��|����F��:;Ru����uv���lR[ _gG���Q�@�ΎT]g��|����F��:;Q�u6�-���#U�٨z _gG���Q�@�ΎT]g��|����:����ّ��lT=��#���Ѵ8�ΎL]g#�|����:����ّ��lT=���#U�٨z _gG���Q�@��N�q�Mj���H�u6���ّ��lT=���#U�٨z _g'��&��uv��:U���H�u6���ّ��lT=���u\g���:;B�:M������u6���ّ��lT=���u\g���:;Ru����uv��:U���H�u6���فz����uv��:U���H�u6���ّ��lT=���u\g���:;Ru����uv��:U���H�u6���� ��l2=��#�����8�ΎL]g#�|��|.]g�똯�o^��x���:~}�]6��_�������n�8�����O���W����wu��ۏ>�y�_�n�C���g�5�����&��|;�WVݾ���r�����rG��]Q=pA�l.�T��]Q=�z�m��e����=x�[ �9?��z��:��T��]Q=pA�l������𢡊������Zϲ�����!U�gWT\Pϛ����+�.������@"u~vE���̈́��63UϢ���m8�Cu~vE��uz��H��Ϯ���No�.U�gWT��a{��z����6���P��]Q=pA=ov�T��]Q=pA�l��o�GWL��O�w��C�G�2���=8����������:?��z��:��C��Ϯ�x_=Lo�!T�YV[��:� �c��Ϯ���No�.��SϮ���No�6U�gWT��w��c�c��e�.��_�e�����y�}H���������p=��z�}�4� ��N=�j\P��ᘪ�+�.��������iq���8�� +�_`7��P�gYm�j}�_��+Q�@���H�W�������D��+u|E �-��"0R���z E`��+Q�@���H�W�����:�"���_���@T=��"0R���z E`�j�U��D#��@���y���0����@��x�"25B���E�^G(@�<B��@�y�"R5B���E�j�U��D#��@��T�P��<B��@�y�"R5B���E�� +R[ �PD�F(P�@��T�P��<B��@�q�"A5BA���ED���#�� +D=�G("U#�z �P$�� ��E�j�U��H���#�� +T=�G(u�P��y�"R5B���E�j�U��H���#�:F(Hm�<B��@�y�"R5B���E����# � +"=�G("S#�z �PD�F(P�@��T�P��<B��c����#�� +T=�G("U#�z �PD�F(P�@�H�1BAj��H���#�� +T=�G("U#�z �P�u���#�� +T=�G("U#�z �PDh�P�iq<B��c����#�� +T=�G("U#�z �PD�F(P�@�H�1BAj��H���#�� +T=�G("U#�z �P$�� ��E�j�U��H���#�� +T=�G(u�P��y�"R5B���E����#�� +D=�G(u�P��y�"R5B���E�j�U��H���#�:F(Hm�<B��@�y�"R5B���E�j�U��D#��@��T�P��<B��@�y�"R5B���E�� +R[ �PDh�P�iq<B��@�y�"R5B���E�� +R[ �PD�F(P�@��T�P��<B��@�y�"P�#��@��T�P��<B��@�y�"R5B���E�� +R[ �PD�F(P�@��T�P��<B��@�q�"A5BA���ED���#�� +D=�G(��� +|���ˀ����F(v+#��Η#�P�3�������_��χ����k��ߧ�?U�����wЫ��n_��v���9<_c�|w�����������"u~vE���ً��p +�z�����H�jXU�a�Hհ���"��aT=�ET�"dz�D��E�@�T ���<,�A�yX$Qǰ�-��E"U�"�z �D��EP�@�T ���<,��aP{ �D��EP�@�T ���<,�A�yX$Qǰ�-��E"U�"�z �D��EP�@��A��xX$1ǰ�-��E"U�"�z �D��EP�@�T ���<,��cX����"��aT=��E"U�"�z �D��EP�@I�1,Bj�a�Hհ���"��aT=��E"U�"�z �$�!��H�jXU�a��a4-��E"S�"�z �$�!��H�jXU�a�Hհ���"��aT=��Eu���yX$R5,���H�jXU�a�Hհ���"�:�EHm�<,�A�yX$R5,���H�jXU�a�D�"��@��yX��0��A��xX$25,���H�^�E@�<,�A�yX$R5,���H�jXU�a�D�"��@�T ���<,�A�yX$R5,���H��aR[ �D��EP�@�T ���<,�A�qX$A5,B���HDְ���"��aD=��E"U�"�z �$�!��H�jXU�a�Hհ���"��aT=��Eu���yX$R5,���H�jXU�a�Hհ���"�:�EHm�<,�A�yX$R5,���H�ְ���" �a"=��E"S�"�z �D��EP�@�T ���<,��cX����"��aT=��E"U�"�z �D��EP�@I�1,Bj�a�Hհ���"��aT=��E"U�"�z ��uX���"��aT=��E"U�"�z �Dh ��iq<,��cX����"��aT=��E"U�"�z �D��EP�@I�1,Bj�a�Hհ���"��aT=��E"U�"�z �$�!��H�jXU�a�Hհ���"��aT=��Eu���yX$R5,���H�ְ���"��aD=��Eu���yX$R5,���H�jXU�a�Hհ���"�:�EHm�<,�A�yX$R5,���H�jXU�a�D�"��@�T ���<,�A�yX$R5,���H��aR[ �Dh ��iq<,�A�yX$R5,���H��aR[ �D��EP�@�T ���<,�A�yX$P��"��@�T ���<,�A�yX$R5,���H��aR[ �D��EP�@�T ���<,�A�qX$A5,B���HDְ���"��aD=��Eh0#��1�ܼY~mXd�2,�=n{�g4,r�a�?<}���Oo������ӽ������"���7��a�w�Z��9��7/r� +��@U�*t�� +��r:QG���U�HUU�*t�� +��b:B� +���q:1G���U�HUU�*t�� +��r:RU�F�� +��� +Mj�*t�� +��r:RU�F�� +��B��\�N�Q�&�r:RU�F�� +��B��\��TU�Q�@�B'�B��� +��B��X��ЪB�iq\��LU��@�B'�B��� +��B��\��TU�Q�@�BG��Шz W�uT�Im�\��TU�Q�@�BG��Шz W�#UUhT=��Љ:�Ф�@�BG��Шz W�#UUhT=��Б�*4��U�DUhR[ U�#s�B�x�U��*4��U��TQ�*t�^�Р�@�BG��Шz W�#UUhT=��Б�*4��U�DUhR[ W�#UUhT=��Б�*4��U�HUU�*t��*4�-��Б�*4��U�HUU�*t�� +��b:AU�&�� +�U�F�� +��B#�\��TU�Q�@�B'�B��� +��B��\��TU�Q�@�BG��Шz W�uT�Im�\��TU�Q�@�BG��Шz W�#UUhT=��Љ:�Ф�@�BG��Шz W�#UUhT=��ZUh4-�� �*4��U��TQ�*t�� +��r:RU�F�� +��� +Mj�*t�� +��r:RU�F�� +��B��\�N�Q�&�r:RU�F�� +��B��\��TU�Q�@�B� + j�*t�� +��r:RU�F�� +�U�F�� +��� +Mh�*t�� +��r:RU�F�� +��B��\�N�Q�&�r:RU�F�� +��B��\��TU�Q�@�B'�B��� +��B��\��TU�Q�@�BG��Шz W�uT�Im�\��TU�Q�@�BGhU�Ѵ8�BG��Јz W�uT�Im�\��TU�Q�@�BG��Шz W�#UUhT=��Љ:�Ф�@�BG��Шz W�#UUhT=��Б�*4��U�DUhR[ W�#UUhT=��Б�*4��U�HUU�*t��*4�-��ZUh4-��Б�*4��U�HUU�*t��*4�-��Б�*4��U�HUU�*t�� +��r:P�UhP{ W�#UUhT=��Б�*4��U�HUU�*t��*4�-��Б�*4��U�HUU�*t�� +��b:AU�&�� +�U�F�� +��B#�\�^.�FUh|s��e\��U���Ѫ�;�B�w�_f�� +�gT�>V��_��;���������w?������w7��.��q���6�d_e=t�*�d��Y��qV=�d<S�K�Y�@���L�/g��K�u|�8�=�d<S�YϪb�>S�YϪb�>S�YϪb�>RլG�b�>S�YϪb�>S�YϪR�>C�f=�����T�����L�f=����L�f=����L�f=����HU�����L�f=����L�f=����L�f=����HU�����L�f=����L�f=����L�f=����HU�����L�f=�H�����lZ6�3����z 6�#U�zT[ 6�3����z 6�3����z 6�3����z 6�#U�zT[ 6�3����z 6�3����z 6�3����z 6�#U�zT[ 6�3����z 6�3����z 6�3����z 6�#U�zT[ 4�3�[����0j�g�ܬg��Y��լg��Y���YOj�f}�V��U�f}�V��U�f}�V��U�f}��Y�j�f}�V��U�f}�V��U�f}�V��U�f}��Y�j�f}�V��U�f}�V��U�f}�V��U�f}�V�M��f}F��z&-���Y�zF=���Z�zV=����f=�-���Z�zV=���Z�zV=���Z�zV=����f=�-���Z�zV=���Z�zV=���Z�zV=����f=�-���Z�zV=���Z�zV=���:7�ٴ8j�Gd5��8l�gf5��@l�gj5�Y�@l�gj5�Y�@l�G�����@l�gj5�Y�@l�gj5�Y�@l�gj5�Y�@l�G�����@l�gj5�Y�@l�gj5�Y�@l�gj5�Y�@l�'�h֓��Y��լg��Y��լg��Y��s��M��f}d�Y�h�f}�V��U�f}�V��U�f}�V��U�f}��Y�j�f}�V��U�f}�V��U�f}�V��U�f}��Y�j�f}�V��U�f}�V��U�f}�V��U�f}��Y�j�f}�V��U�f}���z6-���Y�zF=����f=�-���Z�zV=���Z�zV=���Z�zV=����f=�-���Z�zV=���Z�zV=���Z�zV=����f=�-���Z�zV=���Z�zV=���Z�zV=����f=�-���:7�ٴ8l�gf5��@l�gj5�Y�@l�G�����@l�gj5�Y�@l�gj5�Y�@l�gj5�Y�@l�'�h֓��Y��լg��Y��լg��Y��լg��Y�j֣��Y��լg��Y��լg��Y��լg��Y�լG��Y��s��I��f}fV��Q�f=Tēf=��o�ܾ��f=����KƧ�M�����zF��S5����pz���O����o����H;nn����\����8x��w�r��q/_4�P�@n�%�hƑ���jơ�܌�T5�P�@n�E��q�z 7�u4�Hm�܌�T5�P�@l�Eh5�д8n�E��q�z 7�u4�Hm�܌�T5�P�@n�E��q�z 7�"U�8T=��q�:�q��@n�E��q�z 7�"U�8T=��q��f��D�8R[ 7�"U�8T=��q��f��HU3U�f\��f�-��q�97�P� �f\V3E��f\d���r3.P��8P{ 7�"U�8T=��q��f��HU3U�f\��f�-��q��f��HU3U�f\����r3.QG3���HU3U�f\����r3.RՌC����jƑ�q،��j�!iq܌�L5��@n�E��q�z 7�u4�Hm�܌�T5�P�@n�E��q�z 7�"U�8T=��q�:�q��@n�E��q�z 7�"U�8T=��q��f��D�8R[ 7�"U�8T=��q��f���f���T3�H��f\d���r3.RՌC���jơ�܌K�ь#�r3.RՌC���jơ�܌�T5�P�@n�%�hƑ���jơ�܌�T5�P�@n�E��q�z 7��ڌ�r3.RՌC���jơ�،��jơiq܌K�ь#�r3.RՌC���jơ�܌�T5�P�@n�%�hƑ���jơ�܌�T5�P�@n�E��q�z 7�u4�Hm�܌�T5�P�@n�E��q�z 7�"U�8T=��q�:�q��@n�E��q�z 6�"��qhZ7�"S�8D=��q�:�q��@n�E��q�z 7�"U�8T=��q��f��D�8R[ 7�"U�8T=��q��f��HU3U�f\��f�-��q��f��HU3U�f\����r3.QG3����f���T3Q�f\����r3.QG3���HU3U�f\����r3.RՌC����f�=��q��f��HU3U�f\����r3.QG3���HU3U�f\����r3.RՌC����jƑ�q،��j�!iq܌�L5��@n�-7��f���w�2���:�?���?�O�����~3�a�y��s>l�����T����w����4���~��?�f�g���}�w���W��/B=o���|Y�;�K�>{���o�^��}�/��u�7/�ӽrG��]Q=pA=o��!�:?��z��:����o�E�������?8�S�ֳ���uz��C"u~vE��uz��:?��z��:��?S�gWT��^��a���lz�9��]h�Ϯ���N��6U�gWT\P/�����w~vE���/��o�N��श@� +�H�W���������G��+�#U_���W���+�A�������G��+�#U_���W�G��U��O��श@� +�H�W���������G��+�#��M���O�����@� +�H�W���������G��+�#U_���W�'�� +pR[ x��+�Q�@� +�H�� ��C'���T=��Nu���y�$R5t����I�j�U䡓H�� ��C'�:�NHm�<t�:A�q�$Bk�M�㡓��� ��C'�:�NHm�<t�:A�y�$R5t����I�j�U䡓DC'��@:�T ���<t�:A�y�$R5t����I���R[ �D��NP�@:�T ���<t�:A�y�$Q�� �-��N"s:A�6�N"��NP�8:�L � �<t�סP{ �D��NP�@:�T ���<t�:A�y�$Q�� �-��N"UC'�z �D��NP�@:�T ���<t��c���C'���T=��N"UC'�z �D��NP�@:IP ���q8t�5t�����Idj�Q䡓H�� ��C'�:�NHm�<t�:A�y�$R5t����I�j�U䡓DC'��@:�T ���<t�:A�y�$R5t����I���R[ �D��NP�@:�T ���8t�5t�����IBj�H�㡓��� ��C'���T=��N"UC'�z �$�:!���I�j�U䡓H�� ��C'���T=��Nu���y�$R5t����I�j�U䡓H�� ��C'�z:���I�j�U䡓H�� ��C'ZC'hZ�$�:!���I�j�U䡓H�� ��C'���T=��Nu���y�$R5t����I�j�U䡓H�� ��C'�:�NHm�<t�:A�y�$R5t����I�j�U䡓DC'��@:�T ���8t�5t�����Idj�Q䡓DC'��@:�T ���<t�:A�y�$R5t����I���R[ �D��NP�@:�T ���<t�:A�y�$Q�� �-��N"UC'�z �D��NP�@:�T ���<t��c���C'ZC'hZ�D��N�@:�T ���<t��c���C'���T=��N"UC'�z �D��NP�@: ��� �=��N"UC'�z �D��NP�@:�T ���<t��c���C'���T=��N"UC'�z �D��NP�@:IP ���q8t�5t�����Idj�Q䡓坎h�_�<tr�2.�š���цN<t�|�q<��I=���~;�����������ǯ߿���Ǐ_�}��E�{���oֿ*/�MvK�&�������W��n_�˲��9��^�u~vE����y|>�������Mj�%Q�~�-��c"U�1�z ��D��cP�@ޏ�T�Ǡꁼ��c?����1���T=��c"U�1�z ��D��cP�@IP�ǐ�q��ڏA�y?&R����~L�j?U���D�1��@ޏ�T�Ǡꁼ�ڏA�y?&R����~L�^�c@큼�ڏA�y?&R����~L�j?U���D�1��@ޏ�T�Ǡꁼ�ڏA�q?&Bk?M������1��@ޏ�T�Ǡꁼ�ڏA�y?&R����~L���R[ ��D��cP�@ޏ�T�Ǡꁼ�ڏA�y?&Q�~�-��c"U�1�z ��D��cP�@ޏ�T�Ǡꁼ��c?����1���T=�c"��cд8ޏ�L�� ꁼ��c?����1���T=��c"U�1�z ��D��cP�@ޏIԱCj���H�~���1���T=��c"U�1�z ��$�؏!��~L�j?U���H�~���1���T=��cu�ǐ�i?&2��o�p?&k?E������~���1�zݏ��~L�j?U���H�~���1���T=��cu�ǐ�y?&R����~L�j?U���H�~���1�:�cHm���ڏA�y?&R����~L�j?U����~���1Y�1HZ��D��c�@ޏ�T�Ǡꁼ��c?����1���T=��c"U�1�z ��D��cP�@ޏIԱCj���H�~���1���T=��c"U�1�z ��$�؏!��~L�j?U���H�~���1Z�1hZ��$��c��8ޏ�L�� ꁼ�ڏA�y?&R����~L���R[ ��D��cP�@ޏ�T�Ǡꁼ�ڏA�y?&Q�~�-��c"U�1�z ��D��cP�@ޏ�T�Ǡꁼ���P{ ��D��cP�@ޏ�T�Ǡꁸ������~Lb��B[ ��D��cP�@ޏ�T�Ǡꁼ�ڏA�y?&Q�~�-��c"U�1�z ��D��cP�@ޏ�T�Ǡꁼ��c?����1���T=��c"U�1�z ��D��cP�@ޏIԱCj���H�~���1Z�1hZ��D��c�@ޏIԱCj���H�~���1���T=��c"U�1�z ��$�؏!��~L�j?U���H�~���1���T=��cu�ǐ�y?&R����~L�j?U���H�~���1�:�cHm��������~Ldj?Q���H�~���1�:�cHm���ڏA�y?&R����~L�j?U���@��ǀ�y?&R����~L�j?U���H�~���1�:�cHm���ڏA�y?&R����~L�j?U����~���1Y�1HZ��D��c�@ޏY^B��c�u��17/��qq?f�u|�����c�w��~ꜿ�濢����:^P=�G���]-����O�������wo�^�1L�g�?d�������ii=f,4�k 7/rq����X^h ��x�!2�Ѐ��BC�j�U䅆H�B�� �:Hm����Zh@�y�!R�Ѐ��BC�j�U䅆@�.4��y�!R�Ѐ��BC�j�U䅆H�B�� �:Hm����Zh@�y�!R�Ѐ��BC��B�� �9m����Zh@�y�!R�Ѐ��BC�j�U䅆D ��@^h�T-4�ꁼ��Zh@�y�!R�Ѐ��BC���R[ /4D�P�@^h�T-4�ꁼ��Zh@�y�!Q�B�-�"U �z .4Dh-4�iq���Zh@�y�!Q�B�-�"U �z /4D�P�@^h�T-4�ꁼА�c���� ���T=�"U �z /4D�P�@^hHԱ�@j䅆H�B�� ���T=�"U �z /4$�Xh ��BCd� (ކ�BC�B�� ���D=�����j䅆H�B�� ���T=�"U �z /4$�Xh ��BC�j�U䅆H�B�� ���T=�u,4��y�!R�Ѐ��BC�j�U䅆H�B�� ��2="���8^h�L-4 ꁼ��Zh@�y�!Q�B�-�"U �z /4D�P�@^h�T-4�ꁼА�c���� ���T=�"U �z /4D�P�@^hHԱ�@j䅆H�B�� ���T="�д8\hHH-4�q���Zh@�y�!R�Ѐ��BC�j�U䅆D ��@^h�T-4�ꁼ��Zh@�y�!R�Ѐ��BC���R[ /4D�P�@^h�T-4�ꁼ��Zh@�y�!P� ��@^h�T-4�ꁼ��Zh@�q�!Bk�M�ㅆ� ��@^h�T-4�ꁼ��Zh@�y�!R�Ѐ��BC���R[ /4D�P�@^h�T-4�ꁼ��Zh@�y�!Q�B�-�"U �z /4D�P�@^h�T-4�ꁼА�c���� ���T="�д8^h�L-4 ꁼА�c���� ���T=�"U �z /4D�P�@^hHԱ�@j䅆H�B�� ���T=�"U �z /4$�Xh ��BC�j�U䅆H�B�� ���T=�u,4��q�!Bk�M�ㅆ��B�� ���T=�u,4��y�!R�Ѐ��BC�j�U䅆H�B�� �z]h���BC�j�U䅆H�B�� ���T=�u,4��y�!R�Ѐ��BC�j�U䅆H�B�� ��2="���8^h�L-4 ꁼа�6-4��n^,4,������o��B��qs��Y\h�G慆}-4�駧Zg���[��}���ӧ��ޝ^=}���w�������_=?��Ï��ۯ?�ǻ������7?>}~y>v�ޞ�w7������qi��z���q�v�K]�c{�B�� U�;����wlYwlHZ߱E����@�c�Tݱ��|ǖ�㎍��wl��;6T=���"Uwl�z ߱E���P�@�cK�q�Fj�;�H���wl��;6T=���"Uwl�z ߱%�c#��[�� U�;�H���wlZwlhZޱ%��؈�8�c�Lݱ!�|���cC���-Rudž��[��;6R[ ߱E���P�@�c�Tݱ��|���cC���-Q��-���"Uwl�z ߱E���P�@�c�Tݱ��|���;6P{ ߱E���P�@�c�Tݱ��x��udž���[b�;6B[ ߱E���P�@�c�Tݱ��|���cC���-Q��-���"Uwl�z ߱E���P�@�c�Tݱ��|ǖ�㎍��wl��;6T=���"Uwl�z ߱E���P�@�cK�q�Fj�;�H���wlZwlhZ߱E����@�cK�q�Fj�;�H���wl��;6T=���"Uwl�z ߱%�c#��[�� U�;�H���wl��;6T=���uܱ����-Rudž��[�� U�;�H���wl�:��Hm�x��udž���[d� Q�;�H���wl�:��Hm�|���cC���-Rudž��[�� U�;�@�ޱ����-Rudž��[�� U�;�H���wl�:��Hm�|���cC���-Rudž��[�� U�;����wlYwlHZ߱E����@�c[������u�wl7/�ؖ_G�c[����ys���Dwl��|�v�;��3����y������A��>�w���������������_�M������e��߾��p�L��5��g��OOo���/_���~~��eM�>�/z���w?שܻ/�z}:��ùۗ���}��}>c��&�yS���7��� +�&��Vn~�?Zy�B�T=�?Z�T}����G+Z��iq��Jb��Vm���J��T=�?Z�T}����G+���VP�@�h%Q�G+��@�h%R�� +���D�>ZA����H�G+�z ����R[ ���hU�V"U�����J��T=�?ZI��� +�-�?Z�T}����G+Z��iq��Jd�D=�?ZI��� +�-�?Z�T}����G+���VP�@�h%R�� +���$��h����D�>ZA����H�G+�z ���hU�Vu|�Bj�V"U�����J��T=�?Z�T}����G+�:>Z!��G+Z��iq��Jd�D=�?Z�T}����G+�:>Z!��G+���VP�@�h%R�� +���D�>ZA����@�~�j�V"U�����J��T=�?Z�T}����G+�:>Z!��G+���VP�@�h%R�� +���D�>ZA���G+dz~���� +���D�>ZA����������?Z�y�������&������B�����c}���������?���ÏO��?|_�OO���T{~�۽z���c�_tz����7�������9�q�^��}��߸z�,�*��߸���UT[ ~�j��7����:�*��߸������z ~�j��WQm�����Z߸ʪ�7�fj}�*��߸������z ~�j��WQm�����Z߸ʪ�7�fj}�*��߸������z ~�j��WQm�����Z߸ʪ�7�fj}�*��߸������z ~�j��WQm�������WY� �o\���WY�8���̬o\e��Wu|�*�=�q5S�WY�@���L�o\e��W3��q�U�o\�T}�*�-�q5S�WY�@���L�o\e��W3��q�U�o\�T}�*�-�q5S�WY�@���L��:V=��2���X�@Z���Z�C��h�.#�:&-��2����@\���Z�c�q�.R�T�jĥ�L��:V=��2���X�@\���Z�c�q�.R�T�jĥ�L��:V=��2���X�@\���Z�c�q�.R�T�jĥ�L��:V=��2���X�@Z���y��M�������:$=��2����@\���Z�c�q�.Sk��Uĥ�H�R�-��2���X�@\���Z�c�q�.Sk��Uĥ�H�R�-��2���X�@\���Z�c�q�.Sk��Uĥ�Du*R{ ֩2��T�z ֩2��T�z թ2t�S�iqX��Lթm�X��ԪS��X��ԪS��X��ԪS��X��TթPm�X��ԪS��X��ԪS��X��ԪS��X��TթPm�X��ԪS��X��ԪS��X��ԪS��X��TթPm�X��ԪS��T��йNŦ�a�*3�NŨb�*RU�B�b�*S�NŪb�*S�NŪb�*S�NŪb�*RU�B�b�*S�NŪb�*S�NŪb�*S�NŪb�*RU�B�b�*S�NŪb�*S�NŪb�*S�NŪb�*RU�B�R�*C�:��u�̬:��u�L�:��u�HU� +��u�L�:��u�L�:��u�L�:��u�Du*R{ ֩2��T�z ֩2��T�z ֩2��T�z ֩"Uu*T[ ֩2��T�z ֩2��T�z ֩2��T�z թ"��Thzթ���7�KF��v�/d�����m�K=#x)Մ��,��3�G�ѩzFo�|#io��ݧٞ�������՛O����Ǐ����ݫ���������.���]���a�k���5��,w�^�����5J��5"�r�(R�5B��k��5B��k��!��5J��5"�r�(R�5B��k�����5�Tu�P�@�%�����k�����5�Tu�P�@�E��F�z w�ut�Hm��5�Tu�P�@�E��F�z w�"U]#T=��F�:�F��@�E��5B�6�FX]#-��F�����]�@�v�@��5�Tu�P�@�E��F�z w�"U]#T=��F�:�F��@�E��F�z w�"U]#T=��F�����]�D]#R[ w�"U]#T=��F�����]�HU�UĮQ��kD��a�("�k���q�(2�5B��k�����5J��5"�r�(R�5B��k�����5�Tu�P�@�%�����k�����5�Tu�P�@�E��F�z w�ut�Hm��5�Tu�P�@�E��F�z v�"��FhZv�R]#"=��F�����]�HU�U�Q��k��r�(QG��]�HU�U�Q��k��r�(R�5B��k���kDj�Q��k��r�(R�5B��k�����5 +�k���]�HU�U�Q��k��b�(B�k���q�(1G��]�HU�U�Q��k��r�(R�5B��k���kDj�Q��k��r�(R�5B��k�����5J��5"�r�(R�5B��k�����5�Tu�P�@�%�����k�����5����iq�5�Lu��@�%�����k�����5�Tu�P�@�E��F�z w�ut�Hm��5�Tu�P�@�E��F�z w�"U]#T=��F�:�F��@�E��F�z w�"U]#T=��F�����]�D]#R[ v�"��FhZw�"S]#D=��F�����]�D]#R[ w�"U]#T=��F�����]�HU�U�Q�^�F��@�E��F�z w�"U]#T=��F�����]�D]#R[ w�"U]#T=��F�����]�HU�UĮQ��kD��a�h��u��eT���uP�h���u�it�?`��Q=2w���5����ޝ^=}���?������sU�>~���͇/��_�����ݫ?�W}������8��OO�?����������)��E��#�?d��}��b�/r�b��*�o1_���D��3Q�-&�-�o1#U���z �bF�n1Q�@�ŌT�b��|������ȷ���[LT=�o1#U���z �bF�n1Q�@��LP�b��qx��u�����-fd�Q�[�H�-&�ȷ��:n1Im�|����D��3Ru����-f��U�[�D����@�ŌT�b��|����D��3Ru����-f��[LR[ �bF�n1Q�@�ŌT�b��x��u�����-fB��H��[���-&�ȷ���[LT=�o1#U���z �b&��$��-f��U�[�H�-&�ȷ���[LT=�o1u�b���3Ru����-f��U�[�H�-&�ȷ��z����-f��U�[�H�-&����Z��hZ�b&��$��-f��U�[�H�-&�ȷ���[LT=�o1u�b���3Ru����-f��U�[�H�-&�ȷ��:n1Im�|����D��3Ru����-f��U�[�D����@�ŌT�b��x��u�����-fd�Q�[�D����@�ŌT�b��|����D��3Ru����-f��[LR[ �bF�n1Q�@�ŌT�b��|����D��3Q�-&�-�o1#U���z �bF�n1Q�@�ŌT�b��|���������Z��hZ�bF�n1�@�ŌT�b��|������ȷ���[LT=�o1#U���z �bF�n1Q�@����-&�=�o1#U���z �bF�n1Q�@�ŌT�b��|������ȷ���[LT=�o1#U���z �bF�n1Q�@��LP�b��qx��|��b�˨[̛�A���/��}���g;�E�b�#�-�C�b����O�?����S]a���t����|��s�9���»�ȗ�����6��R~��R��W�|)���� �ȗ���KAT=�/u\ +���R0Ru)���`��RU�K�Hե ���� �KA2=/#�.��8��L] +"�|)��D��R0Qǥ �-�/#U���z _ +F�.Q�@��T] +��|)���R��ȗ���KAT=�/#U���z _ +F�.Q�@�L�q)Hj�K�Hե �ȗ���KAT=/#�.Ѵ8�LH] +�q|)��D��R0Ru)���`��RU�K�D����@��T] +��|)��D��R0Ru)���`��KAR[ _ +F�.Q�@��T] +��|)��D��R0P�����@��T] +��|)��D��R0B�RM��K������@��T] +��|)��D��R0Ru)���`��KAR[ _ +F�.Q�@��T] +��|)��D��R0Qǥ �-�/#U���z _ +F�.Q�@��T] +��|)���R��ȗ���KAT=/#�.Ѵ8��L] +"�|)���R��ȗ���KAT=�/#U���z _ +F�.Q�@�L�q)Hj�K�Hե �ȗ���KAT=�/#U���z _ +&�$��`��RU�K�Hե �ȗ���KAT=�/u\ +���R0B�RM��K��ԥ �ȗ���KAT=�/u\ +���R0Ru)���`��RU�K�Hե �ȗ��z���`��RU�K�Hե �ȗ���KAT=�/u\ +���R0Ru)���`��RU�K�Hե ���� �KA2=/�/ֲKA|u)x�:v�����K��V�gw�=^ +�#����o�o~8}w�<??�{�^�����w~x��������m�}�����>������\��O_�O�����������:D�����W��e�����݇::��������{�-���Wr���N?�.ǽ�f�{��߭�{��/�]P�@�w�Tݻ��|�ޅ���.��{T=��]"U�.�z D��]P�@�wI�q�Bj�{�Hս���.��{T=�]"��]д8�wIHݻ�q|���wA���%Ru�K���U�{�D�.��@�w�Tݻ��|���wA���%Ru�K��{R[ D��]P�@�w�Tݻ��|���wA���%P��.��@�w�Tݻ��|���wA���%B��M��{���.��@�w�Tݻ��|���wA���%Ru�K��{R[ D��]P�@�w�Tݻ��|���wA���%Qǽ�-��]"U�.�z D��]P�@�w�Tݻ��|�ޅ���.��{T=�]"��]д8�w�Lݻ �|�ޅ���.��{T=��]"U�.�z D��]P�@�wI�q�Bj�{�Hս���.��{T=��]"U�.�z $�w!��K���U�{�Hս���.��{T=��]uܻ����%B��M��{��Խ���.��{T=��]uܻ����%Ru�K���U�{�Hս���.�z�w��K���U�{�Hս���.��{T=��]uܻ����%Ru�K���U�{�Hս���. �{2=�]�^"�w��Q�.7�c��/,�����e�8��b��.��|��X�Xozz��>?}�����ڷ���/u������I�>�5��y���>|ԁ��_��Ԩ��/?M�{��˻�u��˧�_>��8���ק�_t��}�n}~�T_���tz��l���?.7���/����v�ݻ��~��[n~������u�[P�@�cK��?�����-��?����ǖH�[P�@�cK��-�z ��%P�l��["UlA���-��?����ǖH�[P�@�cK��?�����-��?����ǖH�[P�@�cK��-�z ��%A��2=�ز�s/�c���c���?�,��_������ǖ��Ǘ��������疇��x/鰿��zF�<����Z~��×O��n7�����\S�,p^�� }�|���~^��}Y/ް�~7�a�{/�Zϲ����G��.�:?��z��zޜ��]"u~vE��uzv�:?��z�}�0� ��.�Zϲ��������+�.�����+�.�����K��Ϯ�x_=�6�s�ֳ���uz��Ϗ���@N��i��+�.��{pL�����=x^%M�z����N���K��Ϯ���No�.U�gWT\P��a���gWT�����ᏹz����N��%U�gWT\Pϛ�C������es9�?��������P�gYm���of��̊���6�8�����6�Su~vE����ez���e�����܅?p�����=ئ�����e�����Ϯ�x_}�m���N=�j\P���T��]Q=pA�������gWT\P������gWT�����p�T=�j\P���p������m�?�������6�Ru~vE����nz�ُ9=�j\P���c��Ϯ����7�K��Ϯ���^6��7�ۣ+���'����!���gm����Su~vE��uzN�P��]Q=pA�ޅ�!T�gWT�������,�-pA�ކ�1T�gWT\P��a���gWT\P��a���+��W�ϟO�?��YV[��z.��zvE�����>������esJ�W��]Q=�z�ކS���e�.���pL������m�Gb~tŴ�rz��zv����yz��Zϲ���=?������]ئ�����es|�ճ+��W���K���z����6LJT��]Q=pA=Mχ?������m8�?����𧻓�m8�j=�j\P������gWT\P��a���gWT\P��a���+��W�u�H�gYm���6���+�mwڤ�:?�"Z�y�.��zv���������ѳ�����9�Su~vE��uzN�P��]Q=pA�ކ��DϮ�������p�z�������F��`U�/؍T}�.��_����]T=��`7Q����v#U_�����F��`U�/؍T}�.��_�����]2=�`7"�v��8������"�����/�E��vu|�.�-��`7R58����h�jpU���H��(�ȃ��:GIm�<8�E�yp4R58����h�jpU���D����@�T ���<8�E�qp4BkpM���ф��(�ǃ����QD=�G#U���z �F�GQ�@M�18Jj���H��(�ȃ����QT=�G#U���z �&�%���h�jpU���H��(�ȃ����QT=�G�:8 +j���H��(�ȃ����QT=G#�GѴ8M�18Jh���H��(�ȃ����QT=�G#U���z �&�%���h�jpU���H��(�ȃ����QT=�Gu���yp4R58����h�jpU���H��(�ȃ��:GIm�<8�E�qp4BkpM�������(�ȃ��:GIm�<8�E�yp4R58����h�jpU���D����@�T ���<8�E�yp4R58����h���QR[ �F�GQ�@�T ���<8�E�yp4Q��(�-G#�GѴ8�L-w!ꁼ��Z�B�y�+Q�r�-���"U�]�z /wE���P�@^�T-w�ꁼ����.P{ /wE���P�@^�T-w�ꁼ��Z�B�y�+Q�r�-���"U�]�z /wE���P�@^�T-w�ꁸܕ�Z�"��p�ky�*[�Q�]7�c�=,.w-�����ӷ�K���#�4��G�ȼܵ�]?�����~��C}����|z������×�W���z�}���ӽ +����}w��8�5�M������_�7�y!��&V=�M�Z�&V=�M��~�-�M�Z�&V=��M:��ش8�7ef���@�7E��M��@�7ej��X�@�7ej��X�@�7ej��X�@�7E��M��@�7ej��X�@�7ej��X�@�7ej��X�@�7E��M��@�7ej��X�@�7ej��X�@�7ej��X�@�7E��M��@�7e�~��a�o����Ģ�a�)3��Ĩb�)QG������L�~����L�~����L�~����HU� ����L�~����L�~����L�~����HU� ����L�~����L�~����L�~�H���~�G�����MLZ��2��M�z ��2��M�z ��"U�&T[ ��2��M�z ��2��M�z ��2��M�z ��"U�&T[ ��2��M�z ��2��M�z ��2��M�z ��"U�&T[ ��2��M�z ��2��M�z ��2t�7�iq�o���7!�q�o���71��o���7���o���7���o�T��Pm��o���7���o���7���o���7���o�T��Pm��o���7���o���7���o���7���oJ��o"�b�)S��Īb�)S��ĪR�)C�~�����T� ����L�~����L�~����L�~����HU� ����L�~����L�~����L�~����HU� ����L�~����L�~����L�~����HU� ����L�~�H����MlZ��2��M�z ��"U�&T[ ��2��M�z ��2��M�z ��2��M�z ��"U�&T[ ��2��M�z ��2��M�z ��2��M�z ��"U�&T[ ��2��M�z ��2��M�z ��2��M�z ��"U�&T[ ��2t�7�iq�o���71��o���7���o�T��Pm��o���7���o���7���o���7���oJ��o"�b�)S��Īb�)S��Īb�)S��Īb�)R�oB�b�)S��Īb�)S��Īb�)S��ĪR�)B�߄��Q� �8Q��_�����~���~��ߣ\�7��:�o�G�~�~����?>}�a������s��×����돿��ͻ����闏߿�b�o���w}=/����}��T��ݛ_�����װ|������nd�zQ���@�^���z7Ru�����n��zU���H��.���:�wIm�|����E��z7Ru�����n��zU���D��@�ލT]��|����E��z7Ru�����n��z�L���݈��]$-��w#S�z _�F��wQ�@��M�q�Kj���H��.�����]T=��w#U�z _�&��%���n��zU���H��.�����]T=��wu\���z7Ru�����n��zU�����]4-�wRDz_�F��w�@�ލT]��|����E��z7Q��.�-��w#U�z _�F��wQ�@�ލT]��|����z������]T=��w#U�z _�F��wQ�@�� ���.�=��w#U�z _�F��wQ�@�ލк�E���z71��.�-��w#U�z _�F��wQ�@�ލT]��|����z������]T=��w#U�z _�F��wQ�@��M�q�Kj���H��.�����]T=��w#U�z _�&��%���n��zU�����]4-��w#S�z _�&��%���n��zU���H��.�����]T=��wu\���z7Ru�����n��zU���H��.���:�wIm�|����E��z7Ru�����n��zU���D��@�ލк�E���z72u�����n��zU���D��@�ލT]��|����E��z7Ru�����n�^�wA�|����E��z7Ru�����n��zU���D��@�ލT]��|����E��z7Ru�����n��z�L���]:-M�w�e��������2���<������a�y8ԧ�����&�3z���}���ӛ_�7|�����7_�}�0�+�<��?��o_}���z��>������'���f��y������}X�ܝ�_�����k�C���ͽ�L�>�n;_0?�j\P�["U_ˀ���2D���U�e�T}-��_ː��kHm������e@��k"���M��e�L}-��_ː��kHm������e@��k"U_ˀ���2D���U�eH����@�Z�H��2�������e@��k"U_ˀ���2$��ZR[ -C��kP�@�Z�H��2�������e@��ku|-�-���!2�b��aX��*v�hq\�L��@.v��j�bW���r�+RU�B����*v��\�J�Q�"�r�+RU�B����*v��\�T�P�@.v%�(v�����*v��\�T�P�@.vE��]�z �T�.2=�]Y�.$-��]��b��ŮHU�U�bW��b�-��]��b��ŮHU�U�bW���r�+QG����ŮHU�U�bW���r�+RU�B��ؕ���Ej�bW���r�+RU�B����U�B��ؕ�*v�q\�L��@.vE��]�z �"U�.T=��]�:�]��@.vE��]�z �"U�.T=��]��b��ŮD�.R[ �"U�.T=��]��b��ŮHU�U�bW�^�]��@.vE��]�z �"U�.T=�]Z�.4-��]�9�]��@.vE��]�z �"U�.T=��]��b��ŮD�.R[ �"U�.T=��]��b��ŮHU�U�bW��b�-��]��b����3Y��H������ r��H�*ҳ�,���Y�Ȱ�.��?�p{�,�5�.]E�SՑ�d��rإ� ���@��5aZ�a��ΰ����.eM�bإ�#�Bg�8�R΄](m �]�:�.�.@��5aZ�a��&�Bk9�Rք]hm �]�:�.�.@��5aZ�a��&�Bk9�Rք]hm �]�:�.�.@��5aZ�a��&�Bk9�Rք]hm �]�:�.�.@��t�]�,�]ʙ�� �KYv���v��Ⱥ�9�Rք]hm �]ʚ�� �KYv���v �%�� +�KYv���v)k�.�6��.eM�r�e�3�"��KYv���v)k�.�6��.eM�b�e� ���8�0<a���������0�:~��k�®{�������}��k�#{�u>]r�_�����zjm�Զ� _��^���_&}��:?ݟ^��~���C�owz�"O���� +�_���� k�/���,���7� ���|>�?J�x�����}o��u������cx��EY�goXx`�>�;kݟ�am��֗�c�s��Qv6�@�}�t��ސ6���}��u����֗������ް6�c���t���qcϲuX�O��ֺ?{�������������ް6���}��Һ?{����c�O����y�+���}�OҺ?{�����1�=K��� k���p�����~l=o�'�m.ϲuX�OO��Һ?{�������b���7� <��������7���Xyw>���7�<��x`�>�'kݟ�am��u��u������Sx������~l��>�{iϲuX����AZ�goXx`�>����3��am��u�d(kv7��@��0ֹ�A�Ȼʚ� �6�w7�5�hm �n(kv7��@��0ֹ�A�Ȼʚ� �6w7�t�n��p������@iyw�X��Y �n(kv7��@��P��n���������@kyw�X��Y �n(kv7��@��P��n���������@kyw�X��Y �n(kv7��@��P��n���������@kyw�X��Y �n(羻��k�n(���@c�xwC9�����^v7��ywCY�����fw� �� e��ZȻ�:w7Ⱥ�ywCY�����fw� �� e��ZȻ�:w7Ⱥ�ywCY�����fw� �� e��Z��F�� r6w7�r�n��p������@iywCY������� �.@��P��n���������@kywCY������� �.@��P��n���������@kywCY������� �.@��P��n���������@kqwCI��:��F�� R6�w7�3�(m �n(kv7��@��P��n�����a�sw���w7�5�hm �n(kv7��@��P��n�����a�sw���w7�5�hm �n(kv7��@��P��n�����!��� ��@��P��n���������@kqwCI��:ǻ�9w7H��ywCY�����fw� �� e��ZȻ�:w7Ⱥ�ywCY�����fw� �� e��ZȻ�:w7Ⱥ�ywCY�����fw� �� e��ZȻ�:w7Ⱥ�ywCY������� t�w7�3�(m �n��� ��� e��ZȻʚ� �6�w7�5�hm �n��� ��� e��ZȻʚ� �6�w7�5�hm �n��� ��� e��ZȻʚ� �6�w7�5�hm �n��� ��� %��,�n(gv7P�@��P��n�����a�sw���w7�5�hm �n(kv7��@��P��n�����!��� ��@��P��n���������@kywCY������� �.@��P��n���������@kywCY�����fw����ݍ� ����1v7�ރv7�_�jwc�g����p>�n���ݍ�Ⱦ�q7v7�����篿|��O���÷��x���@�ۿظ�>���}�.U4�묢�^���~�"PE�ur������@���5U4Z�U����Fk��6�YE�ur������@���5U4Z�U���*���*�8gM��U����Fk��V�T�hm W�ʚ*� �*�XgM��U����Fk��V�T�hm W�ʚ*� �*�XgM��U����Fk��V�T�hm W�ʚ*� �*�XgM��U����Fk��V�QE��p\E+g�h�6��hc�U4Y W�ʚ*� �*ZYSE���\E+k�h�6��hc�U4Y W�ʚ*� �*ZYSE���\E+k�h�6��hc�U4Y W�ʚ*� �*ZYSE���\E+k�h�6��hc�U4Y U�ʹW�h��a����FcḊV�T�(m W��z������V�T�hm W�ʚ*� �*ZYSE���\E묢ɺ���V�T�hm W�ʚ*� �*ZYSE���\E묢ɺ���V�T�hm W�ʚ*� �*ZYSE���XEi�hr6�h�U4*�U�r��Fi��V�T�hm W��:�h�.@���5U4Z�U����Fk��V�T�hm W��:�h�.@���5U4Z�U����Fk��V�T�hm W��:�h�.@���5U4Z�U����Fk��V�QE��pXEe�hR6��h�L��r������@���5U4Z�U���*����heM��r������@���5U4Z�U���*����heM��r������@���5U4Z�U��^�h��@���5U4Z�U����Fk��V�QE��p\E笢I����V�T�hm W�ʚ*� �*ZYSE���\E묢ɺ���V�T�hm W�ʚ*� �*ZYSE���\E묢ɺ���V�T�hm W�ʚ*� �*ZYSE���\E묢ɺ���V�T�hm V�J:�ht��h�L��rm���&��*ZYSE���\E+k�h�6��heM��rm���&��*ZYSE���\E+k�h�6��heM��rm���&��*ZYSE���\E+k�h�6��heM��rm���&��*ZIG���q����Q�@���5U4Z�U���*����heM��r������@���5U4Z�U��^�h��@���5U4Z�U����Fk��V�T�hm W��:�h�.@���5U4Z�U����Fk��V�T�hm V�F�*����*�^QE�k�*��=��>~�����*��e{�'���#{}?������_�?������/�������Ƿq��&���!OG=����r��}��Ƿ������o�V��������ʚۿ��@��[Yӹ���ܹ�s� +��]Yӹ���ܹ+k:w�6�;weM��r�n��s'���]Yӹ���ܹ+k:w�6;w%�;:ǝ�q�Ν��;weM��r箬����@�ܕ5�;Zȝ���Ν��;weM��r箬����@�ܕ5�;Zȝ���Ν��;weM��r箬����@�ܕ5�;Zȝ���Ν��;weM��b箤�sGg�sW�t�(m w��:;w�.@�ܕ5�;Zȝ���sGk�sW�t�hm w��:;w�.@�ܕ5�;Zȝ���sGk�sW�t�hm w��:;w�.@�ܕ5�;Zȝ���sGk�sW�t�hm w��:;w�.@�ܕs���x ��] G���q箜��Q�@�܅�ҹ�ur箬����@�ܕ5�;Zȝ���sGk�s7�ٹ�ur箬����@�ܕ5�;Zȝ���sGk�s7�ٹ�ur箬����@�ܕ5�;Zȝ���sGk�s7�t��lv�J9:wT�;w�L��r箬����@�܍uv�d]�ܹ+k:w�6�;weM��r箬����@�܍uv�d]�ܹ+k:w�6�;weM��r箬����@�܍uv�d]�ܹ+k:w�6�;weM��b箤�sGg�s7�t�lw�ʙ�� ��]Yӹ���ܹ+k:w�6�;wc��;Y w�ʚ�� ��]Yӹ���ܹ+k:w�6�;wc��;Y w�ʚ�� ��]Yӹ���ܹ+k:w�6�;wa�t�`]�ܹ+k:w�6�;weM��b箤�sGg�s7�ٹ�tr箬����@�ܕ5�;Zȝ���sGk�s7�ٹ�ur箬����@�ܕ5�;Zȝ���sGk�s7�ٹ�ur箬����@�ܕ5�;Zȝ���sGk�s7�ٹ�ur箬����@�ܕtt��,w�ʙ�� ���Xg�N�ȝ���sGk�sW�t�hm w�ʚ�� ���Xg�N�ȝ���sGk�sW�t�hm w�ʚ�� ���Xg�N�ȝ���sGk�sW�t�hm w�ʚ�� ���Xg�N�����������]9ӹ���ܹ+k:w�6�;wc��;Y w�ʚ�� ��]Yӹ���ܹ+k:w�6�;wa�t�`]�ܹ+k:w�6�;weM��r箬����@�܍uv�d]�ܹ+k:w�6�;weM��r箬����@�܍4�;9���q��:w|�ѹ_����a�~�*ۯO��_�u��{���y>����i���+�twy��Ly{�3*������_���?�_~��9W����_>���-��=���_~�������+��wW��������������\��'p�˽����@��5�Zȹ��&�Ck9�3֙ˑur.������@��5�Zȹ��&�Ck9�3֙ˑur.������@��t�r�,�rʙ\� �\�Xg.G�ȹ��&�Ck9�S��rhm �rʚ\� �\�Xg.G�ȹ��&�Ck9�S��rhm �rʚ\� �\�Xg.G�ȹ��&�Ck9�S��rhm �rʚ\� �\�Xg.G�H��r��a��)����X8��3�Jȹ��^r9��@��5�Zȹ��&�Ck9�S��rhm �r�:s9�.@��5�Zȹ��&�Ck9�S��rhm �r�:s9�.@��5�Zȹ��&�Ck9�S��rhm �rF�\����\N)G.���q.����P�@��5�Zȹ���\���s9eM.��r.������@��5�Zȹ���\���s9eM.��r.������@��5�Zȹ���\���s9eM.��r.������@��t�r�,�rF�\����\N9�ˡ����)kr9�6�s9eM.��r.g�3�#��\NY�ˡ����)kr9�6�s9eM.��r.g�3�#��\NY�ˡ����)kr9�6�s9eM.��r.'��\�+�s9eM.��r.������@��t�r�,�r�9s9�.@��5�Zȹ��&�Ck9�S��rhm �r�:s9�.@��5�Zȹ��&�Ck9�S��rhm �r�:s9�.@��5�Zȹ��&�Ck9�S��rhm �r�:s9�.@��5�Z�����\���\N9�ˡ�������Ⱥ�9�S��rhm �rʚ\� �\NY�ˡ�������Ⱥ�9�S��rhm �rʚ\� �\NY�ˡ�������Ⱥ�9�S��rhm �rʚ\� �\NY�ˡ�������Ⱥ�1�Sґˡ�p��)gr9�6�s9eM.��r.g�3�#��\NY�ˡ����)kr9�6�s9eM.��r.'��\�+�s9eM.��r.������@��5�Zȹ���\���s9eM.��r.������@��5�Z����&�#g�0�;n�\.��1r���8z9��_��Z��\.�¾��{��ka�G��������˯���?��;����~Z�s>�J=߽����o��՟�������zG��������k|�ܟ�!m������`���7� ���x>=|�%oϲuX�O��^Z�goXx`�>�����ް6���}��u����[�Χ��GgϲuX�O//ֺ?{��������IZ�goXx`}9�<=K��� k?�>oã��gٺ������"���7� <�n��M�Y�goXx`�>�;kݟ�am��֗�c��eg���gp��pƳ7� <�n��'kݟ�am��u���Y�u�lm ^'���N���w�q�<[���;�N�� ���u\'���u��:��'� +���u\'���u��:��gk�:yg�ɳ��x����:y�.@�N�Y�u�lm ^'��:y�6���w��:yv��W�\'�����;�N�� ���u\'���u��:��gk�:ye�>Z ��8���akq�Y�>[��8�:�q��@��Q���u�>���}�6�q�u�㰵����c�� �}e�>Z ��8���aki�I�}v�q�s�㰴�������A��}g�8lm ��8���akq�Y�>[��8ʚ}�.@��qֱ����>���}�6�q�u�㰵�������A��}g�8lm ��8���akq�Y�>[��8ʚ}�.@��q���8l���>���8l,��8���aiq�X�>YW ��8���akq�Y�>[��8�:�q��@��Q���u�>���}�6�q�u�㰵����c�� �}e�>Z ��8���akq�Y�>[��8�:�q��@��Qұ�����>�S��8�,��8���aiq�Y�>[��8ʚ}�.@��qֱ����>���}�6�q�u�㰵�������A��}g�8lm ��8���akq�Y�>[��8ʚ}�.@��qֱ����>���}�6��q�t��ag�hG)�>*��8�9�qX�@��qֱ����>���}�6�q�5�8h]����c�� �}g�8lm ��8���akqGY������8�:�q��@��qֱ����>���}�6�q�u��u�>���}�6�q�u�㰵�����>;��8ʙ}�.@��qֱ����>���}�6�q�u�㰵�������A��}g�8lm ��8���akq�Y�>[��8ʚ}�.@��qֱ����>���}�6�q�u�㰵�������A��}g�8lm ��8龏����>�s�}�6�q�5�8h]����c�� �}g�8lm ��8���akqGY������8�:�q��@��qֱ����>���}�6�q�5�8h]����c�� �}g�8lm ��8���akqGY����H�8N��㰳p���c�� �}g�8lm ��(k�qк�q�Y�>[��8�:�q��@��qֱ����>���}��@��qֱ����>���}�6�q�u�㰵�������A��}g�8lm ��8���akq�Y�>[H�8J:�q��8������ï�?t����r����3J��y��{Y��ٟ��>c�_����|�����˗��e�����i�(���t�����ߵ���?M���9�/��-�_9��問c�w���%ǥ�Q&�$e�8�4�T��,7�F�Ē����R(g_ ��q]i��+IY8N+�2e%)�]�Q&�$e�8���T��q\Te�JR�sJ�LMI��qKi�I)IY8)�rv��lW�F�����Ä�GAI�k��F�|����xR(g; ��q9i� 'IY8�&�2�$)�ͤQ&�$e�8���K��q\KebIR�SI�L)I��q'i��$IY8�$�r6��l�F�@����<�(SG��p�Fe�HR��H��]$(GU��Q$�P�D�("Iw ���C��pC�V^Z�c���(B��p�Ae*HR�H�LI��q�)��e�~4�ď�,��F����(�=��p= +�lA�8.�2�#)ǹ�Q�v$e�u4ʤ��,��������F�H�k'�F�����(�7��p7 +�lA�8.�2a#)�Y�Q�j$e�i4�$��,�B9{FP6�kF�L�H��q�h�)IY8��2#)��PΆ����(0��p�/e�ER�Ec�" �a. +_�E���E#L�H��q�h�)IY8��2�")DZ�P�V���R�(*��p�)e*ER�E�L�H��q�(��Oe�N4�ĉ�,��F�2����.�(�%��p%�V^��c��"�($��p�#ejDR[Dc)" �a" +����8��2")� �Q�@$e�?4�䇤,LJB9�CP6��C�LxH��qvh��IY8n�2�!)���P�������(��p�eJCR�;C�LfH��qd(��1e�04���,��8�B^ø-4¤�d,��B9�BP6��B�LTH��qRh�) +IY8� �29!)�1�PΖ����(��p�e*BR�B�LBH��q@(��e�4�ă�,��F�r����n�(� ��p +�lA�8,�q�$��q.h���X8n�2� )ǡ�P�N���J�( ��p�e +AR��@�LH��qx[yi����@�LH��qh��IY8n�2I )�A�P�����(��p�eJ@R�;@�LH��a(�i�AX0,��\3 �����r;����o���_|�?�b�7y{�����������ǟ~�������_<��_�|������.����N/�/L�5� _���e��_.Fi�2ae�e�hm _&���L� �˄�u^&L�ȗ +k.Fk�2ae�e�hm _&���L� �˄��r�0XW _&���L� �˄�5� ���|����2a�6�/6�y�0Y _&���L� �˄�5� ���x���������8g�N�ȉ���qGk�rW�d�hm ��ʚ�� ���Xg�N�ȹ���wGk�xW�$�hm G�ʚ�� ���Xg�N��黲�}Gk�~W���hm �ʚ� ��XgO������Gk��Wґ£�p�+gjx�6�{xc�A<Y '�ʚ&� �*^Y�ţ���+k�x�6��xc�q<Y ��ʚ>� �B^Y�ȣ���+k*y�6�;yc��<Y ��ʚV� �Z^Y�ˣ���+k�y�6��yc��<Y e�ʹw�h��a9��#�Gc�8�W���(m ���z ���9�W�4�hm W�ʚ�� �^YSң������ɺ�9�W���hm �ʚ�� �^YSգ������ɺ�9�Wִ�hm ��ʚ�� ��^YSأ����i"{r63{��=*ǥ�r&�Gi9�W���hm ���:�{�.@N�5�=Z�ս�&�Gk9�W֔�hm ���:�{�.@��5�=Z���&�Gk9�W�T�hm w��:C|�.@N�5->Z�5��&�Gk1�W�Q䣳p��e�|R6��|�L���r���I���@��5u>Z�}���@���}eM���r�������@��5�>Zȭ���X���s}eM���r���I���@���5�>Z�ݾ�^�}��@N��5�>Z����&�Gk1�W�Q�p����I��9�W�t�hm ��ʚ�� �_YS����ɺ�9�W�4�hm W�ʚ�� �_YS��������ɺ�9�W���hm �ʚ�� ��_YS��������ɺ�9�Wִ�hm ��J:rt���L��r�o�3�'���_Y�����\�+k��6��eM���r�o�s����'��5�hm ��(kf���@P�,����`�s������5{�hm /(k&��@P֬����`�s����tl��p����@iy @Y����F��Α��.@� P��������� +@ky,@Y����^��^��y2@Y����j��f6�� ���e�r�Z���:�Ⱥ�y>@Y���fB�� �e͊�Z�;F�!r6��sx�%��1�������pM��U�9�;�x|==l�As㑷7�?����_����_�����oW��۟7���]��w:�R������ꅏ���/�;Y �ʚ�� ��]YS����\�+k�w�6��wa��`]�\�+k�w�6��weM��r�)���@.ލu�d]�\�+k�w�6��weM��bxGg�x7�Y��tr�)���@.ޕ5�;Z�Ż��xGk�x7�Y��ur�)���@.ޕ5�;Z�Ż��xGk�x7�Y��ur�)���@.ޕ5�;Z�Ż��xGk�x7�Y��ur�)���@,ޕt��,�ʙ�� ���Xg�N��Ż��xGk�xW��hm �ʚ�� ���Xg�N��Ż��xGk�xW��hm �ʚ�� ���Xg�N��Ż��xGk�xW��hm �ʚ�� ���Xg�N�HŻr��;�aX�+�(��X8.ޕ3�;J�Ż�^�w��@.ޕ5�;Z�Ż��xGk�xW��hm ��:�w�.@.ޕ5�;Z�Ż��xGk�xW��hm ��:�w�.@.ޕ5�;Z�Ż��xGk�xW��hm �F�❜���])G���q�)�Q�@.ޕ5�;Z�Ż��❬��weM��r�)���@.ޕ5�;Z�Ż��❬��weM��r�)���@.ޕ5�;Z�Ż��❬��weM��r�)���@,ޕt��,�F�❔���]9S����\�+k�w�6��weM��r�n��x'���]YS����\�+k�w�6��weM��r�n��x'���]YS����\�+k�w�6��weM��r�.����+��weM��r�)���@,ޕt��,��9�w�.@.ޕ5�;Z�Ż��xGk�xW��hm ��:�w�.@.ޕ5�;Z�Ż��xGk�xW��hm ��:�w�.@.ޕ5�;Z�Ż��xGk�xW��hm ��:�w�.@.ޕ5�;Z�Ż�������]9S����\��,�ɺ��xW��hm �ʚ�� ��]YS����\��,�ɺ��xW��hm �ʚ�� ��]YS����\��,�ɺ��xW��hm �ʚ�� ��]YS����\��,�ɺ��xW�Q���p\�+g�w�6��weM��r�n��x'���]YS����\�+k�w�6��weM��r�.����+��weM��r�)���@.ޕ5�;Z�Ż��❬��weM��r�)���@.ޕ5�;Z�Ż��x'g�x?ε]�1��������U����������� �����=���?~�ӗ������?�������E��o/^�Nz_�|�`�����?����Cׯ���~�?��<~�"X�goXx`}:�??I��� k�/���ؤ���7� ����}��:�e�<�n�� eݟ�am��u���U����X����Z�goX���e��t���;Pn���,���7� <�n��'kݟ�am��u�s(k�>��@��0�9�A��sʚ��6��>�5shm �}(k�>��@�����XW �}(k�>��@��P��}���<�����@ky��X��Y �}(k�>��@��P��}���8���c�����s$]�<�����@ky�CY3����܇�f�� �c�sd]�<�����@ky�CY3����܇�f�� �c�sd]�<�����@ky�CY3����܇�f�� �c�sd]�<�����@kq�CI��:�sʙ��6��>�u�}�u�܇�f�� �e��Z�sʚ��6��>�u�}�u�܇�f�� �e��Z�sʚ��6��>�u�}�u�܇�f�� �e��Z�sʚ��6��>�u�}�u�܇r�sh���܇��4��>�3s(m �}�e��+��>�5shm �}(k�>��@��P��}���<�a�s��>�5shm �}(k�>��@��P��}���<�a�s��>�5shm �}(k�>��@��P��}���8�a��� g�p�C)��*�sʙ��6��>�5shm �}�� ��e��Z�sʚ��6��>�5shm �}�� ��e��Z�sʚ��6��>�5shm �}�� ��e��Z�sʚ��6�>�t�}��p8�a��� e�x�C93����܇�f�� �e��Z�s�:�>Ⱥ�y�CY3����܇�f�� �e��Z�s�:�>Ⱥ�y�CY3����܇�f�� �e��Z�s�z���� +�e��Z�sʚ��6�>�t�}��p<�a�s��>�5shm �}(k�>��@��P��}���<�a�s��>�5shm �}(k�>��@��P��}���<�a�s��>�5shm �}(k�>��@��P��}���<�a�s��>�5shm �}(��@g�x�C93����܇�ι�.@��P��}���<�����@ky�CY3����܇�ι�.@��P��}���<�����@ky�CY3����܇�ι�.@��P��}���<�����@ky�CY3����܇�ι�.@��P�1�����܇rf�� �e��Z�s�:�>Ⱥ�y�CY3����܇�f�� �e��Z�s�z���� +�e��Z�sʚ��6��>�5shm �}�� ��e��Z�sʚ��6��>�5shm �}i�>��8���� +1���1�>���|�t8�q�*����}�ߟ�p�c<��F�c������|�������o?���_�������oJ�_���ُ�C�[���5�{���=4XW ��ʚ� �ZY�C����C+kzh�6�{hc�=4Y ��ʚ� �ZY�C����C+���Y8s��$]��C+kzh�6�{heM��r�����@u��d]��C+kzh�6�{heM��r�����@u��d]��C+kzh�6�{heM��r�����@u��d]��C+kzh�6{h%=4:�=�r��Fi��6��C�ur�����@5=4Z�=����Fk��6��C�ur�����@5=4Z�=����Fk��6��C�ur�����@5=4Z�=����Fk��6��C�uR��{��k��J8zh4�{h�L��r-���+�{heM��r�����@5=4Z�=������{heM��r�����@5=4Z�=������{heM��r�����@5=4Z�=����&g㰇V��C��p�C+gzh�6�{heM��rm���&��ZY�C����C+kzh�6�{heM��rm���&��ZY�C����C+kzh�6�{heM��rm���&��ZY�C����C+kzh�6{h%=4:�=�Q��&e㸇V���(m ��ʚ� �ZY�C����C��ɺ���V���hm ��ʚ� �ZY�C����C��ɺ���V���hm ��ʚ� �ZY�C����C륇� +�ZY�C����C+kzh�6{h%=4:�=�q����{heM��r�����@5=4Z�=������{heM��r�����@5=4Z�=������{heM��r�����@5=4Z�=������{heM��b����FgḇV���(m ���:{h�.@5=4Z�=����Fk��V���hm ���:{h�.@5=4Z�=����Fk��V���hm ���:{h�.@5=4Z�=����Fk��V���hm ���:{h�.@졕t���,��ʙ� �ZY�C����C��ɺ���V���hm ��ʚ� �ZY�C����C륇� +�ZY�C����C+kzh�6�{heM��rm���&��ZY�C����C+kzh�6�{heM��bm����8족�=4��衯��|>��ǯ���g����E=�x�퍞f��/���˷���?��n��w�^�o;��R���<�^bVx��^��q���E fEk9fU�Ĭhm ƬJ:bVt�cV�1+I Ǭʚ�� �UY�����*kbV�6�cVc�1+Y Ǭʚ�� �UY�����*kbV�6�cVc�1+Y Ǭʚ�� �UY�����*kbV�6�cVc�1+Y Ǭʚ�� ĘUIG̊��q̪��YQ�@�Y�uƬd]��*kbV�6�cVeM̊�r̪��Y��@�Y�uƬd]��*kbV�6�cVeM̊�r̪��Y��@�Y�uƬd]��*kbV�6�cVeM̊�r̪��Y��@�Y�uƬd]��*�����1������U9����� +�%f� +�UY�����*kbV�6�cVeM̊�r�j�3f%��UY�����*kbV�6�cVeM̊�r�j�3f%��UY�����*kbV�6�cVeM̊�b�j��Y��8�Y�rĬ�,Ǭʙ�� �UY������Yɺ�9fU�Ĭhm Ǭʚ�� �UY������Yɺ�9fU�Ĭhm Ǭʚ�� �UY������Yɺ�9fU�Ĭhm Ǭʚ�� ĘUIG̊��a�j��YI�8�Y�31+J�1��&fEk9fU�Ĭhm Ǭ�:cV�.@�Y�51+Z�1��&fEk9fU�Ĭhm Ǭ�:cV�.@�Y�51+Z�1��&fEk9fU�Ĭhm Ǭ�z�Y��9fU�Ĭhm Ǭʚ�� ĘUIG̊��q�j�3f%��UY�����*kbV�6�cVeM̊�r�j�3f%��UY�����*kbV�6�cVeM̊�r�j�3f%��UY�����*kbV�6�cVeM̊�r�j�3f%��UY�����*�Y�Y8�Y�31+J�1��Θ���cVeM̊�r̪��Y��@�Y�51+Z�1��Θ���cVeM̊�r̪��Y��@�Y�51+Z�1��Θ���cVeM̊�r̪��Y��@�Y�51+Z�1��Θ��cV%1+:�1�r&fEi9fU�Ĭhm Ǭ�:cV�.@�Y�51+Z�1��&fEk9fU�Ĭhm Ǭ�z�Y��9fU�Ĭhm Ǭʚ�� �UY������Yɺ�9fU�Ĭhm Ǭʚ�� �UY�����ibVr6c���Ŭ�#f�z�Y�_�o��w�+���1�x�퍞G������_?�x~���?>���[Ժ��?������?|���~����߷xx������o��������?��x>��>�}ug�?��)W?��<��k@���r�b�3O!��<EY�������(k��6��eM���r�b�3O!��<EY�������(k��6��eM���r�b�3O!��<EY�������(k��6��eM���r�b�3O!��<E9�<��0�S�p�)h,�)ʙ<� �<EX/y +XW �)ʚ<� �<EY�������(k��6��c�y +Y �)ʚ<� �<EY�������(k��6��c�y +Y �)ʚ<� �<EY�������(k��6�#M�B��a���#OAe�8OQ��)(m �)ʚ<� �<�Xg�B��y��&OAk9OQ��)hm �)ʚ<� �<�Xg�B��y��&OAk9OQ��)hm �)ʚ<� �<�Xg�B��y��&OAk9OQ��)hm �)J:�t��L�B��q����SP�@�S�5y +Z�y��&OAk9O1֙��ur����S��@�S�5y +Z�y��&OAk9O1֙��ur����S��@�S�5y +Z�y��&OAk9O�K���y��&OAk9OQ��)hm �)J:�t���y +I �)ʚ<� �<EY�������(k��6��c�y +Y �)ʚ<� �<EY�������(k��6��c�y +Y �)ʚ<� �<EY�������(k��6��c�y +Y �)ʚ<� �<EIG����q����SP�@�S�u�)d]���(k��6��eM���r����S��@�S�u�)d]���(k��6��eM���r����S��@�S�u�)d]���(k��6��eM���r����S��@�S�u�)d]���(��S�Y8�S�3y +J�y��&OAk9O1֙��ur����S��@�S�5y +Z�y��&OAk9O�K���y��&OAk9OQ��)hm �)ʚ<� �<�Xg�B��y��&OAk9OQ��)hm �)ʚ<� �<�H����q��P@a�|���\��)ǯ�7ݵv~}ؾ�Q�2�x{��������������)�;��&�?�݅����vt�����|zx;I��g�����-�O�w�����QV�@�tz8K��(+w�|9�~zp��QV�c���t�����QT6�@yzy���QV�@�t�~r��QV�@�rz��G��ee�>V>o_�G����q��������,܁r��ooU��QV�@�}��r����X��}��q�;�m_��� �G�X�����$����,܁�e�f%�����,��������}���q����T�pʧ�ݓ��5ee�����}���p�9��/��R�QR.���ſr��QV�@�}�r���;Pn_��T�p7��W�e�&e��b`����px+�R�K�QY8�X��Qx ����0���qx�R���QY8� X)�E��,^���`T��6�\L����J9��Ee���_�����px��R��QY8���(s�/)���*������r\�����u�J9n�Ee��_��U��l^����_T�n�U�}E��0�PQ�1����ညQf?�������)�,N�(�XNAe�p7E)�l +*��)F��R6S�r���p8���c-��í�S)�,�evRH�8\IQ�1�����D�R��T�Q�ṛ��p8�b��F!e�`E ���� +E�(ʶ������(J8&Q�X8Dʹ���k(J9�PPY8�BQʱ������R�TGP�2(�l.�(�@Ae�p�D)�� *��'J9�OPY8>1�자�q�z��c�������'�,�(�;Ae�h���� FK'ʷ����3'J8VN�X8�8Q�1q������Qf߄���u��&�,N�(�X6Ae�p�D)Ǭ *��&F�MR6M�r���p8g��c����-�S&�,�evLH�8\1Q�1b���ᄉR�T��K�q�/A�5��K�ol���`�\��c�������%�,n�(�,Ae�p��(�WB���Z�R��T�J�r,���p�S��c���Ñ��F )�%J9JPY8�'QʱN����6�R�iT�I�rr��*�R�QT'I�r,���p�G��� +�a8Fb��"!c�p�D)� *�3$J9VHPY8� Q�1A������Qf�������#�,N�(�XAe�pwD)��*��#F��R6G�r���p87��cm��í�S#�,�evFH�8\Q�12����Ĉ2�#(��ᾈ�y4�E�2�"�l.�(�Ae�pVD)Ǫ*��"J9&EPY81�쉐�q�&��cL���)�K"�,�(�Ae�pD�(�!B��ႈR�T�C�r����p���c:������n)G�!ʸ������!J8C�X8�Q�1����X�Qf+���å�C!�,΄(�X Ae�p#D)�D*�!B9�A@��pD)�8*�� J9�APY8�Q�1����(�Qf����E�� �,(�XAe�pD)�*GC �8v@HX0Z�Y1��?s�������{�m /����'@�#o/�:7@�?���|�z��}ú�����������c���}���;�x�"�����F��Α�.@��P��d���������@ky,CY�����^�����.@��P�lf���������@ky8CY�����v��f<�������~J�ʚ �6�G4�5+hm �h�� ��) e͖Z�kʚ9 �6�5�5�hm oj�eT�+�g5�5�hm /k(k�5��@�P֬k�����a�s`���'6�5hm �l(kf6��@�Pұ�����ֆqα �.@��P��m���������@kytCY������� �.@��P�lo���������@ky�CY���������.@��P��p����ġ���@ky�CY�Ɓ�����A�.@��P�lr����ʡ�c����a��2J���:�9Ⱥ�y�CY�ρ��B��f�� �e�JZ�;�:�:Ⱥ�y�CY�Ձ��Z��f�� ��e�bZț�:G;Ⱥ�y�CY�ہ��r��f�� ��e�zZ���:<Ⱥ�i�C9� 4^�p�C nj�Cʙ%�6��<��2���sʚ=�6�=�5�hm �z(kV=��@��0�9�A���ʚm�6��=�5�hm |(k>��@��0�9�A��3ʚ��6��>�5Shm �}(k�>��@��0�~��q8���c��������J��ʚ��6��?�u��u����f�� �e�Z�# ʚ�6�w@�u��u���f� �5e�Zȃ ʚE�6�7A�u���u�,��f� �ee�4Z�� J:�A�Y8�1����q<���Aiy%DY3���P��f)� �c�c!d]�<���Aky1DY3���h��f5� ��c��!d]�<���Aky=DY3��fA� � a����ufG� �%e͔Z�c"J:�D�Y8�1�9(B�ȓ"ʚM�6�WE�5�"hm �(k�E��@�1�9.B���"ʚ}�6�F�5#hm ��(kVF��@�1�94B��S#ʚ��6��F�5s#hm �(kG��@�1�9:B�ȳ#ʚ��6�G�tL���p<>��YAiy�X�� Y O�(k6H��@^!Q�̐���<D��Y"Aky��X� Y ϑ(k�H��@^$Q�L����<J��Y%Aky��X�0 Y O�(k�I��@^'Q�̓���<P��Y(Aky��X�H Y Δ(��)Ag�x�D93U���X��f�� �c��%d]�<Y���,Aky�DY3[���p��f�� ��a����u�|��f�� �ë́ Z�#&ʚ�6�wL�u��uf�� �5e͜ Zȃ&ʚE�67M�4�&�lΚ/u�]|�1lr��lr�*˴�O�<�l�$�i����7�4�M������������?�=�������������O�������/?������>���^��w]<��y�����W�RX�OeVW?������@a��ra��)���@.��5�Zȅ�����+eMa��ba����BgḰR�V(m V�:+�.@.��5�Zȅ����Bk��R�Vhm V�:+�.@.��5�Zȅ����Bk��R�Vhm V�:+�.@.��5�Zȅ����Bk��R�Vhm V�:+�.@*��s/��x ��J Ga���qa��)�P�@.���RX�ura��)���@.��5�Zȅ����Bk��2�YX�ura��)���@.��5�Zȅ����Bk��2�YX�ura��)���@.��5�Zȅ����Bk��2�V�lVJ9 ++T�+�La��ra��)���@.��uVd]�\X)k ++�6�+eMa��ra��)���@.��uVd]�\X)k ++�6�+eMa��ra��)���@.��uVd]�\X)k ++�6�+eMa��ba����Bgᰰ2�V�lVʙ� +� ��JYSX���\X)k ++�6�+c��Y Vʚ� +� ��JYSX���\X)k ++�6�+c��Y Vʚ� +� ��JYSX���\X)k ++�6�+a�V`]�\X)k ++�6�+eMa��ba����BgḰ2�YX�tra��)���@.��5�Zȅ����Bk��2�YX�ura��)���@.��5�Zȅ����Bk��2�YX�ura��)���@.��5�Zȅ����Bk��2�YX�ura��)���@,��tV�,Vʙ� +� ���XgaE�ȅ����Bk��R�Vhm Vʚ� +� ���XgaE�ȅ����Bk��R�Vhm Vʚ� +� ���XgaE�ȅ����Bk��R�Vhm Vʚ� +� ���XgaE������� +����J9SX���\X)k ++�6�+c��Y Vʚ� +� ��JYSX���\X)k ++�6�+a�V`]�\X)k ++�6�+eMa��ra��)���@.��uVd]�\X)k ++�6�+eMa��ra��)���@,��4�9���q� ++|�QX]�LPX���vy��~d� +������oo1�?�|�������}O��T�����������Ǐ�����������{��|z�M���>�����y�~f����O������S�hm ��W֜�Gk�Խ��S�d]�|�^Ys�� �S�ʚS�hm ��W֜�Gk�Խ��S�d]�t�^9�S�h���{%���X8>u��9u���{a���� +�S�ʚS�hm ��W֜�Gk�Խ���=Zȧ�u��'��S�ʚS�hm ��W֜�Gk�Խ���=Zȧ�u��'��S�ʚS�hm ��W֜�Gk�Խ���=Z���4����8<u����=*ǧ�3��Q�@>u��9u���{c���ɺ��Խ���=Zȧ�5����@>u��9u���{c���ɺ��Խ���=Zȧ�5����@>u��9u���{c���ɺ��Խ���=Zȧ�5����@<u����=:���2��I�8>u��9u���{eͩ{�6�O�+kNݣ��|��X�{�.@>u��9u���{eͩ{�6�O�+kNݣ��|��X�{�.@>u��9u���{eͩ{�6�O�+kNݣ��|�^X/�����Խ���=Zȧ�5����@<u����=:ǧ�s��'��S�ʚS�hm ��W֜�Gk�Խ���=Zȧ�u��'��S�ʚS�hm ��W֜�Gk�Խ���=Zȧ�u��'��S�ʚS�hm ��W֜�Gk�Խ���=Zȧ�u��'��S�ʚS�hm ��W�q����S�ʙS�(m ��7�yꞬ�O�+kNݣ��|�^Ys�� �S�ʚS�hm ��7�yꞬ�O�+kNݣ��|�^Ys�� �S�ʚS�hm ��7�yꞬ�O�+kNݣ��|�^Ys�� �S�ʚS�hm ��7�yꞬO�+�8u����{�̩{�6�O�+kNݣ��|��X�{�.@>u��9u���{eͩ{�6�O�+kNݣ��|�^X/�����Խ���=Zȧ�5����@>u��9u���{c���ɺ��Խ���=Zȧ�5����@>u��9u���{#ͩ{r6O�w���5Ʃ����S�ǯ����i���o>����?|��|z�~���������J�w�W�䑷7�w�|����~����Ο^O�o�X��V���� �����������C����:�N���>z����7� <�>���u��������s�u����[ﶏ�AZdzl]���cx�Wrʺ?{�����1��+9eݟ�am��u��ֺ?{������������u<��x`�?���+9eݟ�am������b���7� <���^�_�u����[Χ�'iϲuX��A����� g���g�x�����X����Z�goX���q��巹�,[��u��䷹�� k���p�����X����67��am��֧���U~�ϲuX�O//ֺ?{�������Y�=b<{�������I~��ް6�c��k��GiϲuX���A~��ް6���}���x������c������~l}�>����Qv6�@�}g� g<{C����|�����X_Nϯ��?{����������3�e�<�ޟ���u����֧�ݓ�67��am��u��7��� k?.e?mÃ��Y�����1�?I��� k���p�,���7� <�n��Z�goX����}�ܷ�<��x`�?=��J��� k�O����ް6���rz�_���p�c���t~v�p�,K��u���u������3x������X�O��^Z�goX���~��u<��x`�>��iݟ�am��u����x������c�d���7� <�({�n��*r�.@��\Ys9Z�W�+k�"Gk�*re�U�hm _En��*r�.@��\Ys9Z�W�+鸊���ȕ3W����|��Ϋ�ɺ��*re�U�hm _E����� �ȕ5W����|��Ϋ�ɺ��*re�(ZȣhʚQ4�6�Gє5�hhm ���E#��Q4e�(ZȣhʚQ4�6�Gє5�hhm ���E#��Q4��G��x �Q4%�hh,��)gF�P�@E��(XW ��)kF���@ES����<���ECky�X�(Y ��)kF���@ES����<���ECky�X�(Y ��)kF���@ES����<���ECkq�H3�F���(�R�Q4T�Gє3�h(m ��)kF���@E3�9�F�ȣhʚQ4�6�Gє5�hhm ��)kF���@E3�9�F�ȣhʚQ4�6�Gє5�hhm ��)kF���@E3�9�F�ȣhʚQ4�6�Gє5�hhm ��)�ECg�p�(3�F���(�rf � �Q4e�(ZȣhʚQ4�6�Gьu���u�(��f � �Q4e�(ZȣhʚQ4�6�Gьu���u�(��f � �Q4e�(ZȣhʚQ4�6�Gф�2��ȣhʚQ4�6�Gє5�hhm ��)�ECg�x�8�(I ��)kF���@ES����<���ECky�X�(Y ��)kF���@ES����<���ECky�X�(Y ��)kF���@ES����<���ECky�X�(Y ��)kF���@ES�1�����(�rf � �Q4c��hd]�<���ECkyMY3����(��f � �Q4c��hd]�<���ECkyMY3����(��f � �Q4c��hd]�<���ECkyMY3����(��f � �Q4c��hd]�8���c ���Q4��(JȣhʚQ4�6�Gьu���u�(��f � �Q4e�(ZȣhʚQ4�6�Gф�2��ȣhʚQ4�6�Gє5�hhm ��)kF���@E3�9�F�ȣhʚQ4�6�Gє5�hhm ��)kF���@E3Ҍ���q8�v<��F��5�(��{����hǯrE{}��� G�^N/�����ok�����&l<��>��˗���p�����}Nendstream endobj -1762 0 obj << +1790 0 obj << /Type /Page -/Contents 1763 0 R -/Resources 1761 0 R +/Contents 1791 0 R +/Resources 1789 0 R /MediaBox [0 0 609.714 789.041] -/Parent 1841 0 R -/Annots [ 1765 0 R 1766 0 R 1767 0 R 1768 0 R 1769 0 R 1770 0 R 1771 0 R 1772 0 R 1773 0 R 1774 0 R 1775 0 R 1776 0 R 1777 0 R 1778 0 R 1779 0 R 1780 0 R 1781 0 R 1782 0 R 1783 0 R 1784 0 R 1785 0 R 1786 0 R 1787 0 R 1788 0 R 1789 0 R 1790 0 R 1791 0 R 1792 0 R 1793 0 R 1794 0 R 1795 0 R 1796 0 R 1797 0 R 1798 0 R 1799 0 R 1800 0 R 1801 0 R 1802 0 R 1803 0 R 1804 0 R 1805 0 R 1806 0 R 1807 0 R 1808 0 R 1809 0 R 1810 0 R 1811 0 R 1812 0 R 1813 0 R 1814 0 R 1815 0 R 1816 0 R 1817 0 R 1818 0 R 1819 0 R 1820 0 R 1821 0 R 1822 0 R 1823 0 R 1824 0 R 1825 0 R 1826 0 R 1827 0 R 1828 0 R 1829 0 R 1830 0 R 1831 0 R 1832 0 R 1833 0 R 1834 0 R 1835 0 R 1836 0 R 1837 0 R 1838 0 R 1839 0 R 1840 0 R ] +/Parent 1879 0 R +/Annots [ 1793 0 R 1794 0 R 1795 0 R 1796 0 R 1797 0 R 1798 0 R 1799 0 R 1800 0 R 1801 0 R 1802 0 R 1803 0 R 1804 0 R 1805 0 R 1806 0 R 1807 0 R 1808 0 R 1809 0 R 1810 0 R 1811 0 R 1812 0 R 1813 0 R 1814 0 R 1815 0 R 1816 0 R 1817 0 R 1818 0 R 1819 0 R 1820 0 R 1821 0 R 1822 0 R 1823 0 R 1824 0 R 1825 0 R 1826 0 R 1827 0 R 1828 0 R 1829 0 R 1830 0 R 1831 0 R 1832 0 R 1833 0 R 1834 0 R 1835 0 R 1836 0 R 1837 0 R 1838 0 R 1839 0 R 1840 0 R 1841 0 R 1842 0 R 1843 0 R 1844 0 R 1845 0 R 1846 0 R 1847 0 R 1848 0 R 1849 0 R 1850 0 R 1851 0 R 1852 0 R 1853 0 R 1854 0 R 1855 0 R 1856 0 R 1857 0 R 1858 0 R 1859 0 R 1860 0 R 1861 0 R 1862 0 R 1863 0 R 1864 0 R 1865 0 R 1866 0 R 1867 0 R 1868 0 R 1869 0 R 1870 0 R 1871 0 R 1872 0 R 1873 0 R 1874 0 R 1875 0 R 1876 0 R 1877 0 R 1878 0 R ] >> endobj -1765 0 obj << +1793 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [119.552 706.187 259.307 715.098] +/Subtype /Link +/A << /S /GoTo /D (template-formats) >> +>> endobj +1794 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [528.02 706.187 537.983 715.098] +/Subtype /Link +/A << /S /GoTo /D (template-formats) >> +>> endobj +1795 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [119.552 693.235 226.34 702.147] +/Subtype /Link +/A << /S /GoTo /D (template-specific) >> +>> endobj +1796 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [528.02 693.235 537.983 702.147] +/Subtype /Link +/A << /S /GoTo /D (template-specific) >> +>> endobj +1797 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [119.552 680.284 351.988 689.195] +/Subtype /Link +/A << /S /GoTo /D (template-http-accept) >> +>> endobj +1798 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [528.02 680.284 537.983 689.195] +/Subtype /Link +/A << /S /GoTo /D (template-http-accept) >> +>> endobj +1799 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [95.641 667.333 256.138 676.244] +/Subtype /Link +/A << /S /GoTo /D (cust-hooks) >> +>> endobj +1800 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [528.02 667.333 537.983 676.244] +/Subtype /Link +/A << /S /GoTo /D (cust-hooks) >> +>> endobj +1801 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [95.641 654.381 261.398 663.293] +/Subtype /Link +/A << /S /GoTo /D (cust-change-permissions) >> +>> endobj +1802 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [528.02 654.381 537.983 663.293] +/Subtype /Link +/A << /S /GoTo /D (cust-change-permissions) >> +>> endobj +1803 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [95.641 641.43 286.315 650.341] +/Subtype /Link +/A << /S /GoTo /D (integration) >> +>> endobj +1804 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [528.02 641.43 537.983 650.341] +/Subtype /Link +/A << /S /GoTo /D (integration) >> +>> endobj +1805 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 708.125 172.134 715.098] +/Rect [119.552 630.536 172.134 637.39] /Subtype /Link /A << /S /GoTo /D (bonsai) >> >> endobj -1766 0 obj << +1806 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 708.125 537.983 715.098] +/Rect [528.02 630.536 537.983 637.39] /Subtype /Link /A << /S /GoTo /D (bonsai) >> >> endobj -1767 0 obj << +1807 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 695.173 163.835 702.147] +/Rect [119.552 617.584 163.835 624.438] /Subtype /Link /A << /S /GoTo /D (cvs) >> >> endobj -1768 0 obj << +1808 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 695.173 537.983 702.147] +/Rect [528.02 617.584 537.983 624.438] /Subtype /Link /A << /S /GoTo /D (cvs) >> >> endobj -1769 0 obj << +1809 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 682.222 201.733 689.195] +/Rect [119.552 604.633 201.733 611.487] /Subtype /Link /A << /S /GoTo /D (scm) >> >> endobj -1770 0 obj << +1810 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 682.222 537.983 689.195] +/Rect [528.02 604.633 537.983 611.487] /Subtype /Link /A << /S /GoTo /D (scm) >> >> endobj -1771 0 obj << +1811 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 669.27 188.991 676.244] +/Rect [119.552 591.681 188.991 598.535] /Subtype /Link /A << /S /GoTo /D (svn) >> >> endobj -1772 0 obj << +1812 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 669.27 537.983 676.244] +/Rect [528.02 591.681 537.983 598.535] /Subtype /Link /A << /S /GoTo /D (svn) >> >> endobj -1773 0 obj << +1813 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [119.552 656.438 234.52 663.293] +/Rect [119.552 578.73 234.52 585.584] /Subtype /Link /A << /S /GoTo /D (tinderbox) >> >> endobj -1774 0 obj << +1814 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 656.438 537.983 663.293] +/Rect [528.02 578.73 537.983 585.584] /Subtype /Link /A << /S /GoTo /D (tinderbox) >> >> endobj -1775 0 obj << +1815 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.731 639.173 160.059 648.06] +/Rect [71.731 561.465 160.059 570.351] /Subtype /Link /A << /S /GoTo /D (faq) >> >> endobj -1776 0 obj << +1816 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 639.173 537.983 648.06] +/Rect [528.02 561.465 537.983 570.351] /Subtype /Link /A << /S /GoTo /D (faq) >> >> endobj -1777 0 obj << +1817 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.731 623.831 152.746 632.717] +/Rect [71.731 546.122 152.746 555.009] /Subtype /Link /A << /S /GoTo /D (troubleshooting) >> >> endobj -1778 0 obj << +1818 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 623.831 537.983 632.717] +/Rect [528.02 546.122 537.983 555.009] /Subtype /Link /A << /S /GoTo /D (troubleshooting) >> >> endobj -1779 0 obj << +1819 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 610.291 177.534 617.265] +/Rect [95.641 532.583 177.534 539.557] /Subtype /Link /A << /S /GoTo /D (general-advice) >> >> endobj -1780 0 obj << +1820 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 610.291 537.983 617.265] +/Rect [528.02 532.583 537.983 539.557] /Subtype /Link /A << /S /GoTo /D (general-advice) >> >> endobj -1781 0 obj << +1821 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 595.402 324.033 604.314] +/Rect [95.641 517.694 324.033 526.605] /Subtype /Link /A << /S /GoTo /D (trbl-testserver) >> >> endobj -1782 0 obj << +1822 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 595.402 537.983 604.314] +/Rect [528.02 517.694 537.983 526.605] /Subtype /Link /A << /S /GoTo /D (trbl-testserver) >> >> endobj -1783 0 obj << +1823 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 583.168 400.057 591.362] +/Rect [95.641 505.46 400.057 513.654] /Subtype /Link /A << /S /GoTo /D (trbl-perlmodule) >> >> endobj -1784 0 obj << +1824 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 583.168 537.983 591.362] +/Rect [528.02 505.46 537.983 513.654] /Subtype /Link /A << /S /GoTo /D (trbl-perlmodule) >> >> endobj -1785 0 obj << +1825 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 569.499 244.133 578.411] +/Rect [95.641 491.791 244.133 500.702] /Subtype /Link /A << /S /GoTo /D (trbl-dbdSponge) >> >> endobj -1786 0 obj << +1826 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 569.499 537.983 578.411] +/Rect [523.039 491.791 537.983 500.702] /Subtype /Link /A << /S /GoTo /D (trbl-dbdSponge) >> >> endobj -1787 0 obj << +1827 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 556.548 244.81 565.459] +/Rect [95.641 478.839 244.81 487.751] /Subtype /Link /A << /S /GoTo /D (paranoid-security) >> >> endobj -1788 0 obj << +1828 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 556.548 537.983 565.459] +/Rect [523.039 478.839 537.983 487.751] /Subtype /Link /A << /S /GoTo /D (paranoid-security) >> >> endobj -1789 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 544.573 346.19 552.508] -/Subtype /Link -/A << /S /GoTo /D (trouble-filetemp) >> ->> endobj -1790 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 544.573 537.983 552.508] -/Subtype /Link -/A << /S /GoTo /D (trouble-filetemp) >> ->> endobj -1791 0 obj << +1829 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 530.645 304.407 539.557] +/Rect [95.641 465.888 304.407 474.799] /Subtype /Link /A << /S /GoTo /D (trbl-relogin-everyone) >> >> endobj -1792 0 obj << +1830 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 530.645 537.983 539.557] +/Rect [523.039 465.888 537.983 474.799] /Subtype /Link /A << /S /GoTo /D (trbl-relogin-everyone) >> >> endobj -1793 0 obj << +1831 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 517.694 312.018 526.605] +/Rect [95.641 452.937 312.018 461.848] /Subtype /Link /A << /S /GoTo /D (trbl-relogin-some) >> >> endobj -1794 0 obj << +1832 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 517.694 537.983 526.605] +/Rect [523.039 452.937 537.983 461.848] /Subtype /Link /A << /S /GoTo /D (trbl-relogin-some) >> >> endobj -1795 0 obj << +1833 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 504.742 343.151 513.654] +/Rect [95.641 439.985 343.151 448.897] /Subtype /Link /A << /S /GoTo /D (trbl-index) >> >> endobj -1796 0 obj << +1834 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 504.742 537.983 513.654] +/Rect [523.039 439.985 537.983 448.897] /Subtype /Link /A << /S /GoTo /D (trbl-index) >> >> endobj -1797 0 obj << +1835 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 491.791 489.072 500.702] +/Rect [95.641 427.034 484.091 435.945] /Subtype /Link /A << /S /GoTo /D (trbl-passwd-encryption) >> >> endobj -1798 0 obj << +1836 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 491.791 537.983 500.702] +/Rect [523.039 427.034 537.983 435.945] /Subtype /Link /A << /S /GoTo /D (trbl-passwd-encryption) >> >> endobj -1799 0 obj << +1837 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.731 478.486 117.668 485.469] +/Rect [71.731 413.729 117.668 420.712] /Subtype /Link /A << /S /GoTo /D (patches) >> >> endobj -1800 0 obj << +1838 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 478.486 537.983 485.469] +/Rect [523.039 413.729 537.983 420.712] /Subtype /Link /A << /S /GoTo /D (patches) >> >> endobj -1801 0 obj << +1839 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 463.163 241.901 470.017] +/Rect [95.641 398.406 241.901 405.26] /Subtype /Link /A << /S /GoTo /D (cmdline) >> >> endobj -1802 0 obj << +1840 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 463.163 537.983 470.017] +/Rect [523.039 398.406 537.983 405.26] /Subtype /Link /A << /S /GoTo /D (cmdline) >> >> endobj -1803 0 obj << +1841 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 448.155 292.402 457.066] +/Rect [95.641 383.397 292.402 392.309] /Subtype /Link /A << /S /GoTo /D (cmdline-bugmail) >> >> endobj -1804 0 obj << +1842 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 448.155 537.983 457.066] +/Rect [523.039 383.397 537.983 392.309] /Subtype /Link /A << /S /GoTo /D (cmdline-bugmail) >> >> endobj -1805 0 obj << +1843 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.731 434.849 238.135 441.833] +/Rect [71.731 370.092 238.135 377.076] /Subtype /Link /A << /S /GoTo /D (install-perlmodules-manual) >> >> endobj -1806 0 obj << +1844 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 434.849 537.983 441.833] +/Rect [523.039 370.092 537.983 377.076] /Subtype /Link /A << /S /GoTo /D (install-perlmodules-manual) >> >> endobj -1807 0 obj << +1845 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 419.527 162.331 426.381] +/Rect [95.641 354.77 162.331 361.624] /Subtype /Link /A << /S /GoTo /D (modules-manual-instructions) >> >> endobj -1808 0 obj << +1846 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 419.527 537.983 426.381] +/Rect [523.039 354.77 537.983 361.624] /Subtype /Link /A << /S /GoTo /D (modules-manual-instructions) >> >> endobj -1809 0 obj << +1847 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 406.575 198.326 413.43] +/Rect [95.641 341.818 198.326 348.672] /Subtype /Link /A << /S /GoTo /D (modules-manual-download) >> >> endobj -1810 0 obj << +1848 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 406.575 537.983 413.43] +/Rect [523.039 341.818 537.983 348.672] /Subtype /Link /A << /S /GoTo /D (modules-manual-download) >> >> endobj -1811 0 obj << +1849 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 391.567 187.516 400.478] +/Rect [95.641 326.81 187.516 335.721] /Subtype /Link /A << /S /GoTo /D (modules-manual-optional) >> >> endobj -1812 0 obj << +1850 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 391.567 537.983 400.478] +/Rect [523.039 326.81 537.983 335.721] /Subtype /Link /A << /S /GoTo /D (modules-manual-optional) >> >> endobj -1813 0 obj << +1851 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.731 378.262 229.548 385.245] +/Rect [71.731 313.504 229.548 320.488] /Subtype /Link /A << /S /GoTo /D (gfdl) >> >> endobj -1814 0 obj << +1852 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 378.262 537.983 385.245] +/Rect [523.039 313.504 537.983 320.488] /Subtype /Link /A << /S /GoTo /D (gfdl) >> >> endobj -1815 0 obj << +1853 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 362.939 143.232 369.793] +/Rect [95.641 298.182 143.232 305.036] /Subtype /Link /A << /S /GoTo /D (gfdl-0) >> >> endobj -1816 0 obj << +1854 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 362.939 537.983 369.793] +/Rect [523.039 298.182 537.983 305.036] /Subtype /Link /A << /S /GoTo /D (gfdl-0) >> >> endobj -1817 0 obj << +1855 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 347.93 217.961 356.842] +/Rect [95.641 283.173 217.961 292.085] /Subtype /Link /A << /S /GoTo /D (gfdl-1) >> >> endobj -1818 0 obj << +1856 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 347.93 537.983 356.842] +/Rect [523.039 283.173 537.983 292.085] /Subtype /Link /A << /S /GoTo /D (gfdl-1) >> >> endobj -1819 0 obj << +1857 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 334.979 178.839 343.89] +/Rect [95.641 270.222 178.839 279.133] /Subtype /Link /A << /S /GoTo /D (gfdl-2) >> >> endobj -1820 0 obj << +1858 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 334.979 537.983 343.89] +/Rect [523.039 270.222 537.983 279.133] /Subtype /Link /A << /S /GoTo /D (gfdl-2) >> >> endobj -1821 0 obj << +1859 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 322.028 187.426 330.939] +/Rect [95.641 257.27 187.426 266.182] /Subtype /Link /A << /S /GoTo /D (gfdl-3) >> >> endobj -1822 0 obj << +1860 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 322.028 537.983 330.939] +/Rect [523.039 257.27 537.983 266.182] /Subtype /Link /A << /S /GoTo /D (gfdl-3) >> >> endobj -1823 0 obj << +1861 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 311.133 160.956 317.988] +/Rect [95.641 246.376 160.956 253.23] /Subtype /Link /A << /S /GoTo /D (gfdl-4) >> >> endobj -1824 0 obj << +1862 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 311.133 537.983 317.988] +/Rect [523.039 246.376 537.983 253.23] /Subtype /Link /A << /S /GoTo /D (gfdl-4) >> >> endobj -1825 0 obj << +1863 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 296.125 198.315 305.036] +/Rect [95.641 231.368 198.315 240.279] /Subtype /Link /A << /S /GoTo /D (gfdl-5) >> >> endobj -1826 0 obj << +1864 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 296.125 537.983 305.036] +/Rect [523.039 231.368 537.983 240.279] /Subtype /Link /A << /S /GoTo /D (gfdl-5) >> >> endobj -1827 0 obj << +1865 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 285.111 209.653 292.085] +/Rect [95.641 220.473 209.653 227.327] /Subtype /Link /A << /S /GoTo /D (gfdl-6) >> >> endobj -1828 0 obj << +1866 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 285.111 537.983 292.085] +/Rect [523.039 220.473 537.983 227.327] /Subtype /Link /A << /S /GoTo /D (gfdl-6) >> >> endobj -1829 0 obj << +1867 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 270.222 255.401 279.133] +/Rect [95.641 205.465 255.401 214.376] /Subtype /Link /A << /S /GoTo /D (gfdl-7) >> >> endobj -1830 0 obj << +1868 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 270.222 537.983 279.133] +/Rect [523.039 205.465 537.983 214.376] /Subtype /Link /A << /S /GoTo /D (gfdl-7) >> >> endobj -1831 0 obj << +1869 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 259.328 150.635 266.182] +/Rect [95.641 194.571 150.635 201.425] /Subtype /Link /A << /S /GoTo /D (gfdl-8) >> >> endobj -1832 0 obj << +1870 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 259.328 537.983 266.182] +/Rect [523.039 194.571 537.983 201.425] /Subtype /Link /A << /S /GoTo /D (gfdl-8) >> >> endobj -1833 0 obj << +1871 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 246.257 154.161 253.23] +/Rect [95.641 181.499 154.161 188.473] /Subtype /Link /A << /S /GoTo /D (gfdl-9) >> >> endobj -1834 0 obj << +1872 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 246.257 537.983 253.23] +/Rect [523.039 181.499 537.983 188.473] /Subtype /Link /A << /S /GoTo /D (gfdl-9) >> >> endobj -1835 0 obj << +1873 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 233.425 239.291 240.279] +/Rect [95.641 168.668 239.291 175.522] /Subtype /Link /A << /S /GoTo /D (gfdl-10) >> >> endobj -1836 0 obj << +1874 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 233.425 537.983 240.279] +/Rect [523.039 168.668 537.983 175.522] /Subtype /Link /A << /S /GoTo /D (gfdl-10) >> >> endobj -1837 0 obj << +1875 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [95.641 218.416 271.65 227.327] +/Rect [95.641 153.659 271.65 162.57] /Subtype /Link /A << /S /GoTo /D (gfdl-howto) >> >> endobj -1838 0 obj << +1876 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 218.416 537.983 227.327] +/Rect [523.039 153.659 537.983 162.57] /Subtype /Link /A << /S /GoTo /D (gfdl-howto) >> >> endobj -1839 0 obj << +1877 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.731 203.208 109.369 212.095] +/Rect [71.731 138.451 109.369 147.337] /Subtype /Link /A << /S /GoTo /D (glossary) >> >> endobj -1840 0 obj << +1878 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.039 203.208 537.983 212.095] +/Rect [523.039 138.451 537.983 147.337] /Subtype /Link /A << /S /GoTo /D (glossary) >> >> endobj -1764 0 obj << -/D [1762 0 R /XYZ 71.731 729.265 null] +1792 0 obj << +/D [1790 0 R /XYZ 71.731 729.265 null] >> endobj -1761 0 obj << -/Font << /F27 1180 0 R /F32 1187 0 R /F35 1525 0 R /F33 1278 0 R >> +1789 0 obj << +/Font << /F27 1208 0 R /F32 1215 0 R /F35 1567 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1882 0 obj << -/Length 6836 +1925 0 obj << +/Length 6807 /Filter /FlateDecode >> stream -xڭ�O�Gz��>��k�����т���a������%��R�Cڻ���a�ӑS��X��%�U<=�[�"���!�o�;��yM�,�i9mw�~��p�1���a.��iZ�%���|����zY���$��������-��]�~�P��:-����?�ǫ?�?~}�f9_^=|������/�_������O?W�����u�n���M9yss�_��.}�i�y q���7���^̇��^�۫����>��W��}����������)~��������.�ô�gz���\:)��<-Ǎ��8��:��/dM_�i���v�j`GM�GYΦ�o�v��t�]5�T �W��O-��6�u�N��ہ���4�WͷU;�e:����L��'�y�ϳg�[F�������U��@�����A�Q�S��@������q5�|;P5p_]�cXM�ܲ�v������ہ��5=�y3�|;P5����pp�|;P5p_=���j�͕[V����N��|�)�U;�i:�]5�T 쨗is.�U��-=��|�)��6�5=����ہ��5=��|:0%�C�g��o8�v�j�zJ�`1�r�j�Q�3�ͷ�r;P5����pp�|;P5��^���|�+�U���!���p�e� ��t<�j���Q�to�͕ہ��5=��|�+�U��KzGS-��6�5=��|�+�U;jz��6Wn�v��fWͷU��kz�m�ܲ�v��L��r ކu�mrʚO��u�˴^�7�r;@5pW]��r��j��6����zr�|;P5��������o�v���GSͷU��9=��T�-�M`GM�a�L5�T ��1�'SͷU;jzWͷU���0���\ܲ�v�uJ���o�v�m:�]5�T 쨗i9]M5�T �W����3�S65�C�g`���O��u�����i����5=��|�)�U���ӿ�1�r�j�Q�S����r;P5����`�2D�T 쨗i��j����n��t1��)��6�u�f��r;P5��n����v�j`GM�a3����@��}����|�)��6�5=��U��@�����b�Ǖہ��5=��|:0%n�<�g`���S&5�C�pp�|;@5��n�v5��ہ���2.��o�ô����r�j�Q��p2�m��@�������v�j`GM��h�Ǖہ����5=��T�-�M`GM�a1����@������>;j���Q�c8�j������x�����6��.���5����Q��xv�|;P5���'������}rN��|k�[F��������v�j`GM�ธj���Q�S0k'q;P5p_]�cXL�ܲ�v��棩�ہ��5=�v�U;�y�\]5�T �W�ô^����e� ��t1k'q;P5��n�zr�|;P5���ǰ�os�v�j�zL�����-�M`GM�au�|;P5����`�ДO��u����I�P �W��fS-��6�5=�v�U;�6-f�$n�v��t��j������b�N��&��.�٬���@�������v�j`GM������@��}���Y;�[V�������v�j`GM������@�����Y;�ہ�����0��`"nYm;�2�\�������M�Y>�����<�ή�o������Iܲ�v����I�T ��1]5�T ��1�哸���n��������5=��U��@�����Y>�ہ���<m�3��@��}u>Ls0��6�u�6�|�U;�6N��o�v����D�T �W��̿q�)��!�38����)q2=�s-�T;jz����)��/�wV��e���� ���u�y7������3?��a���������O� �|���������<��c݀���������?����K���_��_���?�e���z~��5��1�?��"S�y��}|������×?�������_͒���؛�?|�����+�/_T�Im��o�Q�GU��o�Q�GU��o�Q�GU��卑�OjH��oð�o��⏢�q��2�⏨r��P�+����\�Ԩ����\�Ԩ����\�Ԩ����\�w�Z�'� 䊿�F�U 䊿�F�U 䊿�F�U 䊿�֊?�M W�-5*��j W�-5*��j W�-5*��j V�4*�djV�-�T���8��[fT��@��[jT�Q�@��;j����r��R�⏪r��R�⏪r��R�⏪r��Qkş�&�+��T5�+��T5�+��T5�+��Z+��6�\�Ԩ����\�Ԩ����X��R�GS���Q�'R��o�Q�GT��o�Q�GU��o�Q�GU��卑�Oj�K��?��K��?��K��?��G�R�@��[jT�Q�@��[jT�Q�@��[jT�Q�@���s��6�+��T5�+��T5+�Z*�hJW��V� m��o�Q�GU��o�Q�GU��o�Q�GU��卑�Oj�K��?��K��?��K��?��G�R�@��[jT�Q�@��[jT�Q�@��[jT�Q�@��;j����r��R�⏪b��BK�M�㊿eF�Q 䊿�֊?�M W�-5*��j W�-5*��j W�-5*��j W��V�Im��o�Q�GU��o�Q�GU��o�Q�GU��卑�Oj�K��?��K��?��K��?��G�R�@��[h���)q\�̨�#��\�Ԩ����\�w�Z�'� 䊿�F�U 䊿�F�U 䊿�F�U 䊿�>W�Am��o�Q�GU��o�Q�GU��o�Q�GU��卑�Oj�K��?��K��?��K��?����?���,$%�+��D5�+���U��ב+�7/c��(��g��)����<����$�R����Ƿ�4,�}=�������������i��|�����ݼ������S�l_?�����7_V��/^���R�@��K�Ͽ@U��/,5>�U �Ͽ����T5�?��Q��_����_Xj|��ȟa����j ����8U �q���q�M �c,5�1�j �c,5�1�j �c,5�1�j �c��cHmic�y��m�c,��cP�8�Xf�c�@���8�6��1��T5��1��T5��1��T5��1�Z�1�6�<���Ǡ��<���Ǡ��<���Ǡ��<�q�:�!� �q���8U �q���8U �q���8U �q���8�L��q�E�q���ˌq���K�q���G��R�@�Xj�cP�@�Xj�cP�@�Xj�cP�@�8jǐ��8�Rc���8�Rc���8�Rc���8�Q�8��&��1��T5��1��T5�1Z�1hJ�c2�1Dj�c,3�1�j �c,5�1�j �c,5�1�j �c��cHmyc�1�AUyc�1�AUyc�1�AUy�uCj��K�q���K�q���K�q���C}ǀ��8�Rc���8�Rc���8�B�8M��q�c�q�M �c,5�1�j �c,5�1�j �c,5�1�j �c��cHmyc�1�AUyc�1�AUyc�1�AUy�uCj��K�q���K�q���K�q���G��R�@�Xj�cP�@�XhǠ)q<���� ��<�q�:�!� �q���8U �q���8U �q���8U �q���q�M �c,5�1�j �c,5�1�j �c,5�1�j �c��cHmyc�1�AUyc�1�AUyc�1�AUy�uCj��-�4%��1��D5��1��T5��1�Z�1�6�<���Ǡ��<���Ǡ��<���Ǡ��<�1��q�m �c,5�1�j �c,5�1�j �c,5�1�j �c��cHmyc�1�AUyc�1�AUyc�1�AUq�1�!S�pc�e����8�2c���8�?۰�1�:�8��e�8��:��q��TQN_�c�$�c��q�?��Z>^�����?�o�ײ�i۹�1��x��y/?t�p�~��r�槯���8�� -^ք�_�Sz�y!;j������4��ZnYm;�:�����ہ��5=����v�j`G�|�`OͷU���<�'O-��6�u�����v�j`G=M����ہ���2m����ہ����Cz��r�j�Q�c8�j���Q�c0�ȧS�:d^,zf�@2��8��Ԙ@����S��U � ��� $��HO-HV5'��HT�@�@zj�@���8���2�dUq�eɪ��Rc�j�HO-HV5'��Z&��j N =�L Y�@�@ZjL Qma��'�,ކ����E�� �g� $��HG�HR�@�@zj�@���8���2�dUq�eɪ��Rc�j�HO-HV5'��Z&��j N =�L Y�@�@ZjL Qmq�eɪ��S��U � ��� $�HH-H45�&��'�LJN =�L �@�@zj�@���8��Ԙ@����S��U � ��� $��HO-HV5'��HT�@�@zj�@���8���2�dUq�eɪ��Rc�j�HO-HV5'��Z&��j M =4O ٔ8�@Zd�@"�q8���2�dTq�eɪ��S��U � ����&'��Z&��j N =�L Y�@�@zj�@���8��Ԙ@����S��U � ��� $��HO-HV5'��Z'����8���2�dUq�eɪ��C��M�� �e��&'��Z&��j N =�L Y�@�@zj�@���8��Ԙ@����S��U � ��� $��HO-HV5'��HT�@�@zj�@���8���2�dUq�eɪ��Rc�j�HO-HV5�&��'�lJN =�L �@�@ZjL Qmq�eɪ��S��U � ��� $��HK� $�M N =�L Y�@�@zj�@���8���2�dUqi�1�D� � ��� $��HO-HV5'��Z&��j N -5&��6�4���<�dS�p�eɨ��S��U � ����&'��Z&��j N =�L Y�@�@zj�@���8�t�:�$� � ��� $��HO-HV5'��Z&��j N -5&��6�8���2�dUq�eɪ��S��U � ��� $�GH��H&%'��Y&��j N a��L �u|��}� $��f������Ḁ�O/��7s@���������c�����o_>�����߽{xx=�������~�%�����)����x��헺������d2�f��ӟ����y��1��|���F�����9�/�6s���~1�ū�^�ǭ��R�Ǖ��� 5��8u"%��8]"%��8E"%�k8Y[8@jwp2*8DJp2�7DJ�o��o� ���E�< �ލF�D��ҍCF�H��ƍCF�H�㺍Aֶ ��]��� ��E��� ��-��� ���� 5��5�"%��5�"%��5�"%�k5c�U�'�8��8dTj��8.�8d�i��8l�8b)�x�U�M5�{45"%�K4"%�4"%��3Y�3@jwg2�3DJg2z3DJ�f2J3DJWf�6f��8��8d�e��8.�8dte��8n�8de��8��dm���qܑqȨ�)qX�q�ҏ!�6��1�%��1Y�1@j�b2j1DJ�b2:1DJ7b2 -1DJ�a��a��8��8dTa��8.�8d�`��8n�8d�`��8��dm���q�qȨ�)q\~q��)q�|q�(�)q\{1��zR��∥�B�m^0�.$J�]2�.DJW]�6]��8�8d�\��8.�8dt\��8n�8d\��8�����vK�l���Qm!R����k!R���Qj!R��b�����q��!��B��q��!��B��q��!��B��a������a���J����0.�8`�WH�8n�@w�(�Ћ�ݕ��p�t�+���ǻ�����Օr��+��Cw��C����ǯ_��}-����N�e����N���_�w��~.�)�Ԯ|��lq����/_�-P�@.\Xj4.P�@�\Xj�.P�@�]8j�]��r��R�z��r��R�}��b��BKM�� -�CF�H���eF Q �"��FU �.��FU �:���>�M 72,5*�j �2,5Z�j �2,5��j W3�v3Hm��a�Q�@U��a���@U��a�Q�@U��a��= P�@njXjT5P�@.kXj�5P�@�kXh)l�)q\�p��� � �ֆ�FmU �↥FsU �FyU �������M 78,5*�j �8,5Z�j �8,5��j W9�v9Hm��a�Q�@U��a���@U��a�Q�@U��ᨵ�Aj��K�j���-�4%���D5�+�Z;�6���Ԩy���\���hz�������({���\�p��� � �Ƈ�F�U �҇�F�U �އ�F�U �ꇣ���M �?,5��j @,5 �j w@,5J �j �@��@Hm� b�� -���q�2� ��r�R���r%�Qk'��&�[!��T5��!��T5��!��T5��!���� 䆈�FEU 䒈�FKU 䞈�FQU 䪈�֮�M �E,5�"�j F,5#�j wF,5J#�j �F4z#dj6G,�TG��8.�Xf�G�@��{V�_Gn�ܼ���_�s�d���d��?9^���\iI?}��0���O�O�^�����^�sR`�G��endstream +xڭ�MsGz��>�䁽�2=/G+�u�c�������)�R� �]zP�4&]�ʍp��(��#R���fL��nN�pZ�7�e�����_o>�?�?L��p<�:�������4\��͇����w����y�����O�2.üo~������ӷ�����ç����?�{z�_?��?����=�.�e�}��ɇ���N7�;���K��痰~��D�cz1��>���w���.�˫J���o~����|��{?����~��8�t��:����K9��0V�2�����%}�ǽ���ێ�� 5�e>�j����P��ir�|�Q5p_��cϞZnY��2/SͷU�q�ή�o;�6��pt���vL��'�i�N�g�[F�������U�mG�����A�Q�S�mG������a1�|�Q5p_]�cXL�ܲZ6��惩�ێ�� 5=�i5�|�Q5����0�j������a��os��*��.�z6�p�mG���zƓ��ێ�� �<���嶣jྺ�ǰ�o8��*����pp�|�Q5����`� �O;��5��� ��vP �W��̦ZnY�jz��6Wn;�6��FWͷU�y8\̷�r�Q5p_=��'�����-�U`C]���U�mG�����{�m��vT l��1���\�������c8�j�e� +l��1,��\����P�c�ͷ�r�Q5����0�j�����^�cͷ�r�j�P�c0��ˎx�����)k>�� ��r6���m��]u��|��j��:��.�rt�|�Q5�����.��o;�6��SͷU��)=��T�-�U`CM�a^M5�vT l��1LGSͷUjz���ێ����<�����V� uһ���ێ�� uN'WͷU�y��SͷU��%=��L��M�k������)q 2=��d����j`CM`1�m�mG��}���/kL�ܲZ6��&�=��vT l��1���U�y�.��o;���8���7��*��.����Qn;�6�u8]5�vT l��1��{\������c8��6��*���ǰ�j����P�c����r�Q5����`���O;��퓧����|ʤ�5���F�̷T�:��/n����P��xv�|�Q5p_=��z2���-�U`C]��h�۔ێ�� 5=��U�mG������|�+�U��Kz���[V�����l�Ǖێ�� umu}v�|�Q5����0�j������q8\����E�l��p1 /n;�6�u8�\5�vT l����E�r�1%n���30�Z��*���g��j����P�38̦�o;�6����I�vT �W��fS-��V� 5=��`����j`CM�����mG���z�WͷU��e���6��V� u�f�$n;�6�uX���o;�6��V�m��vT �W�1����e� +l��1,��o;�6�����iǔ����Y;�����ꚞ�d���*���g`�Nⶣj`C]�٬��mG���zNgWͷU���8�f�$nY��<���I�vT l��1���o;�6����I�vT �WO�1����e� +l��1̮�o;�6����I�vT l��1����������a2q�j�P���/�S��:Lf�$n;�6��p<�j�����^�30�'q�j�P�S0�'q�Q5����pp�|�Q5����`�Oⶣj��1��B;nQ�jz���ێ�� 5=�|�U�iX�_g�ێ����4�9��[V���:�Y>�ێ�� uƣ��ێ�� 5=s0�U��9=�o�|ʦ�5��&�r�!%�A�`�%ⶃj`CM`�|�:%~�%��*{>��ܕD_�2���6��L����yص?��/��������2x�z�܀����p�6���t�������w��R�������?����y^�O����<������G����������O㻇�?��������_͜���К�o�J���ڮ��}!P�'� +䊿�F�U 䊿�F�U 䊿�F�U 䊿�nR�@��[f���x�,%�+��D5�+���Z��䊿�F�U 䊿�F�U 䊿�F�U 䊿�nR�@��[jT�Q�@��[jT�Q�@��[jT�Q�@��;�V�'� +䊿�F�U 䊿�F�U 䊿�F�U Ċ��FşL�Ê�E��?��ˌ�?��K��?��G�*��V�\�Ԩ����\�Ԩ����\�Ԩ����\�wԭ�Oj�K��?��K��?��K��?��G�*��V�\�Ԩ����\�Ԩ����X��R�GS���Q�'R��o�Q�GT��o�Q�GU��o�Q�GU���[ş�*�+��T5�+��T5�+��T5�+���U�I���o�Q�GU��o�Q�GU��o�Q�GU��o��P�@��[jT�Q�@��[jT�Q�@��[h���)q\�w̭�Oh�K��?��K��?��K��?��G�*��V�\�Ԩ����\�Ԩ����\�Ԩ����\�wԭ�Oj�K��?��K��?��K��?��G�*��V�\�Ԩ����X��R�GS��o�Q�GT���[ş�*�+��T5�+��T5�+��T5�+���U�I���o�Q�GU��o�Q�GU��o�Q�GU���[ş�*�+��T5�+��T5�+��T5�+���U�I���o��⏦�q��2�⏨r��R�⏪r��Q��?�U W�-5*��j W�-5*��j W�-5*��j W� ���j�K��?��K��?��K��?��G�*��V�\�Ԩ����\�Ԩ����\�Ԩ����X�wШ���qX��R�GR��o�Q�GT��߮�[|���2�C�������b��?N�rZ��_Nr.������n�������חOk����S����|��i��zU�+����V�~�����Ͽ���ڟ�����_�Z��_Xj|��ȟa����j �����_�������}��U �����_�����������_Xj�cP�@�8�6�!� +�q���8U �q���8U �q���8U �q��n�R�@�XfǠx��,�%��1��D5��1��:���q���8U �q���8U �q���8U �q��n�R�@�Xj�cP�@�Xj�cP�@�Xj�cP�@�8�6�!� +�q���8U �q���8U �q���8U �q���8�L��q�E�q���ˌq���K�q���G��1�V�<���Ǡ��<���Ǡ��<���Ǡ��<�q�mCj��K�q���K�q���K�q���G��1�V�<���Ǡ��<���Ǡ��8���2�AS�p�1�!R�xc�1�ATyc�1�AUyc�1�AUy��8��*��1��T5��1��T5��1��T5��1���cH�yc�1�AUyc�1�AUyc�1�AUyc���P�@�Xj�cP�@�Xj�cP�@�XhǠ)q<�q�mCh��K�q���K�q���K�q���G��1�V�<���Ǡ��<���Ǡ��<���Ǡ��<�q�mCj��K�q���K�q���K�q���G��1�V�<���Ǡ��8���2�AS�xc�1�ATy��8��*��1��T5��1��T5��1��T5��1���cH�yc�1�AUyc�1�AUyc�1�AUy��8��*��1��T5��1��T5��1��T5��1���cH�qc�e����8�2c���8�Rc���8�Q�q�U �c,5�1�j �c,5�1�j �c,5�1�j �c�uj��K�q���K�q���K�q���G��1�V�<���Ǡ��<���Ǡ��<���Ǡ��8�q�ǐ�q8���2�AR�xc�1�ATyӞmX�|ys�2`�~�8f}�(���1q��1��8�ユ�����}�_ӷ�K�������~|<�\���:1�:1���k�/ �����5�����ހw^Ȏ�o;���4L���[V������`����j`CM�!�{j����P�/�����j�z���r��r�j�P�aMo���o;�6��0�\5�vT l��a=�M5�vT �W������[V������U�mG�������D>�� �b�3��Q � ����*'��Z&��j N =�L Y�@�@zj�@���8��Ԙ@�Z��S��U � ��� $��HO-HV5'��HT�@�@zj�@���8���2�dUq�eɪ��Rc�jH�|�@�xFH�H%'��Y&��j N u�@�Z��S��U � ��� $��HO-HV5'��HT�@�@zj�@���8���2�dUq�eɪ��Rc�j�HO-HV5'��Z&��j N =�L Y�@�@Zh�@��q4���<�dR�p�eɨ��S��U � ����*'��Z&��j N =�L Y�@�@zj�@���8��Ԙ@�Z��S��U � ��� $��HO-HV5'��HT�@�@zj�@���8���2�dUi�yɦ���"�I�� �g� $��HO-HV5'��Z&��j N -5&��V�8���2�dUq�eɪ��S��U � ����*'��Z&��j N =�L Y�@�@zj�@���8�t�mIj�HO-HV5'��Z&��j M =4O ٔ8�@ZfL �q�eɪ��S��U � ��� $��HK� $�U N =�L Y�@�@zj�@���8���2�dUqi�1�D� +� ��� $��HO-HV5'��Z&��j N -5&��V�8���2�dUi�yɦ���3��Q � ����*'��Z&��j N =�L Y�@�@zj�@���8��Ԙ@�Z��S��U � ��� $��HO-HV5'��HT�@�@zj�@���8���2�dUq�eɪ��Rc�jHH�H6%'��Y&��j N =�L Y�@�@ZjL Q�q�eɪ��S��U � ��� $��HG�&��ց8���2�dUq�eɪ��S��U � ����*'��Z&��j N =�L Y�@�@zj�@���4���2�DS�h�yɤ���3��Q � $,�� $�����ў@��&�3O OϿ��|��r~�0��O����/wO��>�o�?~������>><��������o��?����c��������m/�����d2�f��ӟ����y��1�+~����F���^�9�/xk�~��bΛW�"%�[9�"%�+9�5r��8��8d�q��8.�8dtq��8n�8dq��8�����R㸃�Q�!R⸀�ѿ!R�}㈥|C�uVo/�7�I�n0j7$J�n2:7DJ7n2 +7DJ�mrk���qܵqȨ�)q\�q���)qܲq�(�)q\�1ȭa��q��!�^C��q��!�[C��q��!�XC��q��O��j�dǝ��J �Dž��> ��mG,e�øJc�[�D���CF��H���CF��H���CF��H����An� 5��3�"%��3�"%�[3�"%�+3�5f��8��8d�e��8.�8dte��8n�8de��8���֒R�#�Q�!R� ㈥C�u�c0�1$JWcrk���q܋qȨ�)q\�q���)q܈q�(�)q\�1ȭ ��q�!� +C��q�!�C��q�!�C��q� ��������������������ǵ��Z/@jv^�T^��F߅D�㶋CFمH�㪋AnM 5�{.5"%�K."%�."%��-}���&�8�8dT[��8.�8d�Z��8n�8d�Z��8����hR���Qg!R����e!R���Qd!R��b��bP°���Cz�m;�a��D3n�^�4N�fG�u�m�m����t�fG9�Վ������!�x��������5:{U��7�����?����ꍎ�VE��}�"\}��2��mT5����T5�+ ��T5�[ ���H���`��L@U��`�QN@U��`������aC�!��@��qI�2����rO�R����rU�R����r[�Q���U ,5�j w,5J�j �,5z�j 7u�.�Zry�R����r�R����r��R�À�r��P_k�ց\d��h2����e��(3���Xg���g@S����[���*�K ��T5�{ ��T5�� ��T5�� ���H���`��p@U��`�Qr@U��`��s@U���[Ձ�*���mT5����T5�+��T5�[���H���`��|@U��`������q��2����r�Q� +�U � ,5Z�j � ,5��j W!,5��j �!u�C�Zr!�R���r'�R���r-�R���r3�Q�j�U �#,5��j �#,5 +�j W$,5:�j �$u�I�ZbQ�BKSM�㮄eFYQ 亄�F_U �Ƅ�n� R�@.MXj�&P�@�MXj'P�@�NXjt'P�@nO�k}�:�� +T5�;�% +T5�k�= +T5����U)H��La�Ѧ@U�Oa�Q�@U�Ra�ѩ@U�U�Q� S�X����^�_F�V\��V�_�k�b����*���8������H?����ȼ>�ݾ�<������o��פ����T�endstream endobj -1881 0 obj << +1924 0 obj << /Type /Page -/Contents 1882 0 R -/Resources 1880 0 R +/Contents 1925 0 R +/Resources 1923 0 R /MediaBox [0 0 609.714 789.041] -/Parent 1841 0 R -/Annots [ 1884 0 R 1885 0 R 1886 0 R 1887 0 R 1888 0 R 1889 0 R 1890 0 R 1891 0 R 1892 0 R 1893 0 R 1894 0 R 1895 0 R ] +/Parent 1879 0 R +/Annots [ 1927 0 R 1928 0 R 1929 0 R 1930 0 R 1931 0 R 1932 0 R 1933 0 R 1934 0 R 1935 0 R 1936 0 R 1937 0 R 1938 0 R ] >> endobj -1884 0 obj << +1927 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [71.731 677.798 200.517 686.71] /Subtype /Link /A << /S /GoTo /D (lifecycle-image) >> >> endobj -1885 0 obj << +1928 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 677.798 537.983 686.71] /Subtype /Link /A << /S /GoTo /D (lifecycle-image) >> >> endobj -1886 0 obj << +1929 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [71.731 612.168 276.242 621.079] /Subtype /Link /A << /S /GoTo /D (security-mysql-account-root) >> >> endobj -1887 0 obj << +1930 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 612.168 537.983 621.079] /Subtype /Link /A << /S /GoTo /D (security-mysql-account-root) >> >> endobj -1888 0 obj << +1931 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [71.731 599.216 256.975 608.128] /Subtype /Link /A << /S /GoTo /D (security-mysql-account-anonymous) >> >> endobj -1889 0 obj << +1932 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 599.216 537.983 608.128] /Subtype /Link /A << /S /GoTo /D (security-mysql-account-anonymous) >> >> endobj -1890 0 obj << +1933 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [71.731 586.265 224.108 595.176] /Subtype /Link /A << /S /GoTo /D (security-mysql-network-ex) >> >> endobj -1891 0 obj << +1934 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [528.02 586.265 537.983 595.176] /Subtype /Link /A << /S /GoTo /D (security-mysql-network-ex) >> >> endobj -1892 0 obj << +1935 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [71.731 573.313 343.17 582.225] /Subtype /Link /A << /S /GoTo /D (trbl-relogin-everyone-share) >> >> endobj -1893 0 obj << +1936 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 573.313 537.983 582.225] +/Rect [523.039 573.313 537.983 582.225] /Subtype /Link /A << /S /GoTo /D (trbl-relogin-everyone-share) >> >> endobj -1894 0 obj << +1937 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [71.731 560.362 348.43 569.273] /Subtype /Link /A << /S /GoTo /D (trbl-relogin-everyone-restrict) >> >> endobj -1895 0 obj << +1938 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [528.02 560.362 537.983 569.273] +/Rect [523.039 560.362 537.983 569.273] /Subtype /Link /A << /S /GoTo /D (trbl-relogin-everyone-restrict) >> >> endobj -1883 0 obj << -/D [1881 0 R /XYZ 71.731 729.265 null] +1926 0 obj << +/D [1924 0 R /XYZ 71.731 729.265 null] >> endobj 10 0 obj << -/D [1881 0 R /XYZ 214.067 703.236 null] +/D [1924 0 R /XYZ 214.067 703.236 null] >> endobj 14 0 obj << -/D [1881 0 R /XYZ 235.902 637.605 null] +/D [1924 0 R /XYZ 235.902 637.605 null] >> endobj -1880 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F33 1278 0 R >> +1923 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1904 0 obj << -/Length 2590 +1947 0 obj << +/Length 2588 /Filter /FlateDecode >> stream -xڝYݏ۸�_��'�eK�,9���nӽ��MQ�}�%�b"�.Eew��|P����E���ΐ��|P�l�_t�Ea���xƻ��h^mnN�y�*��n�i��*�f�>�ެF�Z��ۛx�����q��ن�vws_�3xW���v���<�B�}s0���}�Z��T)�����FYG)*݀�8�d��^�;s^Di�dթ����qoc��^Yv�����Ga��]�v� JSt�Ԏg=�@�� �k�n�E��S��f���2����U��q�L絾�N���� ��:�;g��y��X�PQ����p��O���E|���6�m���mƇ�fQp�B;Y2���O�إ���J�^6$YL�rm,�S��˺�����N���"^�����x�{��o<��R2�'�p�H����2�~S�ԭ�M��}�yEQ -)��� BZxR�$�!�V.VQ��x��j+t��2�T�ߢ,�g���=���,x�J ����#��x� /�Ӌ�A��'Y�v9�������;���A7��Dʣ#=)ݢoF���(��f������io���3�� �k��i@)]�])�~�gy����f���P�M�'�n���D��j$ęh�Ko�g�K������D $����{��ھV����h�M�!� �IH��-�ݡ�$x2Ҡ�|'̺����dKPa���:-N��'�(E~�K�*ײ�$�y&� �|(�eAyI!ӕf�6z%k�1�V�;��,���� �\K�#ӡ(��F)!c[4��b�'��"���'���Z������E���A�ʡ��=��2�7�.�e2��?����L>H&���Pː��5��`Bx`Qo*�B^����RI+��(� ��e -+�L���2�����F��GA#(��|%dg�)�r�� * �(��,W�k5�h�I2����S�d�dr!:��{�(8����03�^�i/��LK��YK�A�Ĕ���_�.~!�Պ���Tf&���j�^;Em�\��W�Sm���p϶1�+�h�پ�,�4Y�5��~���hBtN� ���ܗ��A4� -�#ѩ��j4�@�?[���2�X<@�P�<n+��%�5��ĔR�HxqH����� -�$�2.#X�*��Mz^ �;�:��oJw�?��� ��E�����EղB��OL�� 7 0�z -�&ԑ�^����o��P˳���5ry�p��H�S@���EAZ��a�P��k�f�u31i�҂J�9\��(�P|!֏�3�Q�-%�E�z$7 -�����6J�shzS;�� �q�&ށ��K�F2��q�I���C����*� ��W�9��'�a��pVPGEb�)�Tt���D]3�/�\E�f"�����ǩ����'��S.g��JHs�@�t�^}6�m՞û�F��EL�C��Y�B2���)�/�~5��L��������Ȇ��/0. �'n��ʼnX]˩y�aװ�Z]�cxEQ��&�x�pt� O��0m��qgOJ0L=F��\3��=h<�/��o���W ���`��B��!^�u��+�3TeE��D���]�.��|���[Y�]��Ò��K����[v(����)���C[�} �>���m[���^��������Ш�a�����?���p_a>�{�'��̸�z���GZ4��w����j'�2;d��M�w3��bRЖA���"F3�'�ʒi�24:ѧRχ���C��'/w�BG|*�2�TΝ_���6} -��"��,�X#K�,8���9��M�H���i���^�y��.��� D,Rɣ8���7�k���A�j���ls]|k��553�E�^�SP!�OA4�?�pI���̚�%os� Θ�]�Y�JG*t���9�#�^�mA����E�n��/�Q�܀Us��D�A��� ~%S�m8��e*�hE^!/ŝ��a����M� -����O�qV�Z����ϲ��}���\2q��� a��c�ȿ�yy?�5�*������rL�^��=���C�!���AQj_���/58�9�g 謀fv@ ��qٮ�i -yv=�5�N����61na��Տ� SAŀrq�fd��c[�w0W{����/�,��n��K�G�_ά8����,��?N�A�k��__�Y� �J��ڗ)�� 2`�<M�(>��iN��%�7��8%�[�9<���U�4dl�3�T��M!j��oL�ϑ/��"(�<�g��/(3�%d�7�Z8C7<��i+m�����m�<��?�d�5������7:��+]�X��"8'�v�$�|+�ֵB?^4�����Af�}ɠ�G�8(��:R�}lԠύJ}�]NS}V0��w���Xם:B+�h�?q�����-T��������_τ/���S�*ʓ��#�fL/�F5Cι�y:�S���~���ԏU�9��_���F�D e.� ��|7{�~({ �����y�z��.�)&"@�x�A��A)��<�f?�z��E�>�B��|����j�� ��zn鿋mKendstream +xڝYݏ۸�_��'�eK�,+��ٻMsw]�6E����h��D���_���d��M���193�!����6�Yÿ�& �t?QD��&�߬o��y�&��vDI�+�e�I�l��Y�4�{|���67�:�&���a����f{�X�svW��I;_F�n�{�7���c�Z��T!��~����i� *]��(X�)��^ɝi�a2{��Xze�a�g���)����&����� �݂.o;Y� +�w�Ԏg=5G� �k���y��!S��z���R���ו���Q2V��k}�WU%z�Y��mw�X/s*�X�PQ�͔���@[<�� �P��U���I��� +�d�Dg��?�|��,W���!�bB+cy\�B�Y֕�}�@�u����:��6��������Jɼ����"��B8f¸�M�R�6e���<Ù�|l��Np��ᾑ 4��'�`L��i�|�4�n_��Dw���/�K�=��^q��� �(�d�{Tj� ���xR��6�����g���?�����4(����_�4�¸y��7%R��I�=�x#0�f�D�uyU�6�L����J'���~��t^u�,����ϏC����C%7�.���j&�e�#!�D���T�^�m�������1$��wm�2ߵ}�m/S�roHp��Z7���n��ٳ�p��J���w¬3����N��Y����T(}d!�R��Q��r-KL�gR��χ\��2]i�j���`Uμ�kf����(Ƞ�࡛J�)�E�.�4J��ۢ^)k(>�/�/?�6GOVB����Q0,v;��ثJ9��.�3X��ƀ�ۅ�L� 6��#��=��{����c�FUL'��v�\��]��6PJi���7��La%��V�_�?�=��^��h�Y8�%�����d�b-)`p>��p�Ί\I�r��TS�Z%�.��>�N�&�#���g��NK/�1��������B:���k�S(��2v��ǃ��w���^���D��Y�\��c�� ��#����u��^T����Fw9�2ۗ�y���hM.�_��8��S`��`8�9�<��RA�e��/:U�]��bH���,�^-�e�=t E��4]U�XáH�LL)5���dP��(�@H�-�2�5IQq�0��=ޤ��9��r�?@��M���p�d�>�a�1tQ�,��b�3���x� �� u$�,?��)�"��l��`�\-��7��P�+lQ��:�&Tj�ڸ�jݕ�4����R9$B�>; +7_������ygT`I�B��ɍ��}n{9����54�V`p�k�$�w �����}|�w�i|c��yA�0!���8G� ��5���r�H�0��n�����*&�e4�Q�n&��moy�:�/�zL�8�� +�Z iΗȿ�.ث�Ƹ��sx�H�4庈�~(�0i��%�����B�R��J�W�Ȅ@��ڑ��l()P���~↚X���յ����r ��Q�K�`�(����a]��2]p͓Z�{�-LD�BbeܙF�S�ѡ@�$� q��K�����c�EC��)��5�6�W��沍�{���mUY�&�$@aW�s�)k��VV}�l��dp�>�ϨÖ +@{��Zb��#����C�O>�ѶEJK��k��������t����U���q���5�0������K��Ң�_������!� [� +9���L�c���.>1�q<9WoIS�x�ё�cА>@r�<{��:�;�� o�t�y�Z�N'|�>�NZ!��D���R� +������<�}�4_���h���N����Q�����5�b�r���L��ʿ�A��?��i#��)��ŧ �i��#`xxcM����:ɽ3�jW{t>ё +mm�z �?V�PEy��CG�%�h���(�ab���`z��O�������6L��2�R!Z����Kq[�lX�!�n|g�GPm��&~/�SB��=���,MG�t��`� +�@ +�C� �����~�!*U^��6Tŵ���{؎���C^%����Ծ��=z_jp�K _���:��|�!�e��w)$��8�V�N8I��� �jb��$�/XB��r�����@KǶ��`��J_��_D#����ΖP��4�8 +�i�Y� NzA�k���^�M� � +����(j� 2`��&W��~��p�7�8M�#=����н6�Oy��3��T�$�[䋤���~m�]@�� X!νr�/�a� +�kx8�tt[����O"���K$�/�����wk�cɽ���^�KV��_��D��$<պCP��G��f`1Z�����L���*�x�^�@�H9<#��V�R<7*�x�?N�Y� ��5_�Gc]w��Уe���6=��[������+������{�F�0��N��c�1�,� +a��X\RO��W���ԞW��-�ם�g��QƔ��'�]���ą���%�O=�/��� +�o�A� ��C��CR�vaz�S��X�E�C,䧡�'��:h���P�w�����k�endstream endobj -1903 0 obj << +1946 0 obj << /Type /Page -/Contents 1904 0 R -/Resources 1902 0 R +/Contents 1947 0 R +/Resources 1945 0 R /MediaBox [0 0 609.714 789.041] -/Parent 1841 0 R -/Annots [ 1908 0 R ] +/Parent 1879 0 R +/Annots [ 1951 0 R ] >> endobj -1908 0 obj << +1951 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [371.655 582.727 414.738 590.748] /Subtype /Link /A << /S /GoTo /D (gfdl) >> >> endobj -1279 0 obj << -/D [1903 0 R /XYZ 71.731 718.306 null] +1307 0 obj << +/D [1946 0 R /XYZ 71.731 718.306 null] >> endobj 18 0 obj << -/D [1903 0 R /XYZ 350.659 703.236 null] +/D [1946 0 R /XYZ 350.659 703.236 null] >> endobj -1280 0 obj << -/D [1903 0 R /XYZ 71.731 692.504 null] +1308 0 obj << +/D [1946 0 R /XYZ 71.731 692.504 null] >> endobj 22 0 obj << -/D [1903 0 R /XYZ 285.389 651.159 null] +/D [1946 0 R /XYZ 285.389 651.159 null] >> endobj -1905 0 obj << -/D [1903 0 R /XYZ 71.731 638.721 null] +1948 0 obj << +/D [1946 0 R /XYZ 71.731 638.721 null] >> endobj -1906 0 obj << -/D [1903 0 R /XYZ 71.731 627.443 null] +1949 0 obj << +/D [1946 0 R /XYZ 71.731 627.443 null] >> endobj -1907 0 obj << -/D [1903 0 R /XYZ 71.731 617.481 null] +1950 0 obj << +/D [1946 0 R /XYZ 71.731 617.481 null] >> endobj -1909 0 obj << -/D [1903 0 R /XYZ 71.731 577.746 null] +1952 0 obj << +/D [1946 0 R /XYZ 71.731 577.746 null] >> endobj -1281 0 obj << -/D [1903 0 R /XYZ 71.731 546.646 null] +1309 0 obj << +/D [1946 0 R /XYZ 71.731 546.646 null] >> endobj 26 0 obj << -/D [1903 0 R /XYZ 191.962 503.549 null] +/D [1946 0 R /XYZ 191.962 503.549 null] >> endobj -1910 0 obj << -/D [1903 0 R /XYZ 71.731 494.726 null] +1953 0 obj << +/D [1946 0 R /XYZ 71.731 494.726 null] >> endobj -1911 0 obj << -/D [1903 0 R /XYZ 71.731 448.949 null] +1954 0 obj << +/D [1946 0 R /XYZ 71.731 448.949 null] >> endobj -1912 0 obj << -/D [1903 0 R /XYZ 71.731 405.113 null] +1955 0 obj << +/D [1946 0 R /XYZ 71.731 405.113 null] >> endobj -1282 0 obj << -/D [1903 0 R /XYZ 71.731 348.326 null] +1310 0 obj << +/D [1946 0 R /XYZ 71.731 348.326 null] >> endobj 30 0 obj << -/D [1903 0 R /XYZ 216.752 305.229 null] +/D [1946 0 R /XYZ 216.752 305.229 null] >> endobj -1913 0 obj << -/D [1903 0 R /XYZ 71.731 296.406 null] +1956 0 obj << +/D [1946 0 R /XYZ 71.731 296.406 null] >> endobj -1914 0 obj << -/D [1903 0 R /XYZ 71.731 276.531 null] +1957 0 obj << +/D [1946 0 R /XYZ 71.731 276.531 null] >> endobj -1915 0 obj << -/D [1903 0 R /XYZ 345.258 265.737 null] +1958 0 obj << +/D [1946 0 R /XYZ 345.258 265.737 null] >> endobj -1916 0 obj << -/D [1903 0 R /XYZ 184.718 252.785 null] +1959 0 obj << +/D [1946 0 R /XYZ 184.718 252.785 null] >> endobj -1917 0 obj << -/D [1903 0 R /XYZ 71.731 239.834 null] +1960 0 obj << +/D [1946 0 R /XYZ 71.731 239.834 null] >> endobj -1918 0 obj << -/D [1903 0 R /XYZ 71.731 219.744 null] +1961 0 obj << +/D [1946 0 R /XYZ 71.731 219.744 null] >> endobj -1919 0 obj << -/D [1903 0 R /XYZ 510.317 208.95 null] +1962 0 obj << +/D [1946 0 R /XYZ 510.317 208.95 null] >> endobj -1920 0 obj << -/D [1903 0 R /XYZ 302.6 195.998 null] +1963 0 obj << +/D [1946 0 R /XYZ 302.6 195.998 null] >> endobj -1921 0 obj << -/D [1903 0 R /XYZ 71.731 183.047 null] +1964 0 obj << +/D [1946 0 R /XYZ 71.731 183.047 null] >> endobj -1922 0 obj << -/D [1903 0 R /XYZ 71.731 175.909 null] +1965 0 obj << +/D [1946 0 R /XYZ 71.731 175.909 null] >> endobj -1923 0 obj << -/D [1903 0 R /XYZ 269.484 152.162 null] +1966 0 obj << +/D [1946 0 R /XYZ 269.484 152.162 null] >> endobj -1924 0 obj << -/D [1903 0 R /XYZ 495.373 152.162 null] +1967 0 obj << +/D [1946 0 R /XYZ 495.373 152.162 null] >> endobj -1925 0 obj << -/D [1903 0 R /XYZ 266.563 139.211 null] +1968 0 obj << +/D [1946 0 R /XYZ 266.563 139.211 null] >> endobj -1926 0 obj << -/D [1903 0 R /XYZ 501.46 139.211 null] +1969 0 obj << +/D [1946 0 R /XYZ 501.46 139.211 null] >> endobj -1927 0 obj << -/D [1903 0 R /XYZ 315.916 126.26 null] +1970 0 obj << +/D [1946 0 R /XYZ 315.916 126.26 null] >> endobj -1928 0 obj << -/D [1903 0 R /XYZ 71.731 113.308 null] +1971 0 obj << +/D [1946 0 R /XYZ 71.731 113.308 null] >> endobj -1929 0 obj << -/D [1903 0 R /XYZ 312.349 113.308 null] +1972 0 obj << +/D [1946 0 R /XYZ 314.212 113.308 null] >> endobj -1930 0 obj << -/D [1903 0 R /XYZ 512.529 113.308 null] +1973 0 obj << +/D [1946 0 R /XYZ 512.529 113.308 null] >> endobj -1931 0 obj << -/D [1903 0 R /XYZ 270.827 100.357 null] +1974 0 obj << +/D [1946 0 R /XYZ 270.827 100.357 null] >> endobj -1932 0 obj << -/D [1903 0 R /XYZ 509.011 100.357 null] +1975 0 obj << +/D [1946 0 R /XYZ 509.011 100.357 null] >> endobj -1902 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F33 1278 0 R >> +1945 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1935 0 obj << +1978 0 obj << /Length 2084 /Filter /FlateDecode >> @@ -6046,190 +6057,191 @@ xڭXmo s�4òv�=L���v�ҧ�K�g-����z����gktG��}���$1�<�q�5%�9�cg�pVD@Lk%��u[�U�ԛ%"W4#������I7�v])�=��]`v���\��������E�`����7\+Y��cMh���_����26~��q#���P�pG��;n�z��� �m+5V���Yp��ɟ;7�[J����ǘ�h�/k|<0��~� �s҈f��4zc�U�q��\�D�u,�W���/S��V4ձg��`85.�ٌmpr��OY�%Nߵ�P~��B�½��Y����{�ݳ�r��R-iX_��{r?��������Q���X�����U��ZDY�/T��CB*JL�����Qpv��Za��z�ò�����1�6��������� �=�����È��y��䎮����eg{�{�MY�m���)�l�⍢�q������l]�w���8{�y|�r�:�2F�(LN=w��;���endstream endobj -1934 0 obj << +1977 0 obj << /Type /Page -/Contents 1935 0 R -/Resources 1933 0 R +/Contents 1978 0 R +/Resources 1976 0 R /MediaBox [0 0 609.714 789.041] -/Parent 1841 0 R +/Parent 1879 0 R >> endobj -1936 0 obj << -/D [1934 0 R /XYZ 258.45 708.344 null] +1979 0 obj << +/D [1977 0 R /XYZ 258.45 708.344 null] >> endobj -1937 0 obj << -/D [1934 0 R /XYZ 506.431 708.344 null] +1980 0 obj << +/D [1977 0 R /XYZ 506.431 708.344 null] >> endobj -1938 0 obj << -/D [1934 0 R /XYZ 71.731 688.254 null] +1981 0 obj << +/D [1977 0 R /XYZ 71.731 688.254 null] >> endobj -1939 0 obj << -/D [1934 0 R /XYZ 487.099 677.46 null] +1982 0 obj << +/D [1977 0 R /XYZ 487.099 677.46 null] >> endobj -1283 0 obj << -/D [1934 0 R /XYZ 71.731 657.37 null] +1311 0 obj << +/D [1977 0 R /XYZ 71.731 657.37 null] >> endobj 34 0 obj << -/D [1934 0 R /XYZ 164.538 614.272 null] +/D [1977 0 R /XYZ 164.538 614.272 null] >> endobj -1940 0 obj << -/D [1934 0 R /XYZ 71.731 605.45 null] +1983 0 obj << +/D [1977 0 R /XYZ 71.731 605.45 null] >> endobj -1941 0 obj << -/D [1934 0 R /XYZ 71.731 564.654 null] +1984 0 obj << +/D [1977 0 R /XYZ 71.731 564.654 null] >> endobj -1942 0 obj << -/D [1934 0 R /XYZ 71.731 549.71 null] +1985 0 obj << +/D [1977 0 R /XYZ 71.731 549.71 null] >> endobj -1943 0 obj << -/D [1934 0 R /XYZ 154.5 538.915 null] +1986 0 obj << +/D [1977 0 R /XYZ 154.5 538.915 null] >> endobj -1944 0 obj << -/D [1934 0 R /XYZ 71.731 538.727 null] +1987 0 obj << +/D [1977 0 R /XYZ 71.731 538.727 null] >> endobj -1945 0 obj << -/D [1934 0 R /XYZ 91.656 520.982 null] +1988 0 obj << +/D [1977 0 R /XYZ 91.656 520.982 null] >> endobj -1946 0 obj << -/D [1934 0 R /XYZ 71.731 508.863 null] +1989 0 obj << +/D [1977 0 R /XYZ 71.731 508.863 null] >> endobj -1947 0 obj << -/D [1934 0 R /XYZ 138.849 498.068 null] +1990 0 obj << +/D [1977 0 R /XYZ 138.849 498.068 null] >> endobj -1948 0 obj << -/D [1934 0 R /XYZ 71.731 495.911 null] +1991 0 obj << +/D [1977 0 R /XYZ 71.731 495.911 null] >> endobj -1949 0 obj << -/D [1934 0 R /XYZ 91.656 480.135 null] +1992 0 obj << +/D [1977 0 R /XYZ 91.656 480.135 null] >> endobj -1950 0 obj << -/D [1934 0 R /XYZ 71.731 455.065 null] +1993 0 obj << +/D [1977 0 R /XYZ 71.731 455.065 null] >> endobj -1951 0 obj << -/D [1934 0 R /XYZ 137.315 444.27 null] +1994 0 obj << +/D [1977 0 R /XYZ 137.315 444.27 null] >> endobj -1952 0 obj << -/D [1934 0 R /XYZ 71.731 442.862 null] +1995 0 obj << +/D [1977 0 R /XYZ 71.731 442.862 null] >> endobj -1953 0 obj << -/D [1934 0 R /XYZ 91.656 426.337 null] +1996 0 obj << +/D [1977 0 R /XYZ 91.656 426.337 null] >> endobj -1954 0 obj << -/D [1934 0 R /XYZ 71.731 414.218 null] +1997 0 obj << +/D [1977 0 R /XYZ 71.731 414.218 null] >> endobj -1955 0 obj << -/D [1934 0 R /XYZ 136.508 403.423 null] +1998 0 obj << +/D [1977 0 R /XYZ 136.508 403.423 null] >> endobj -1956 0 obj << -/D [1934 0 R /XYZ 71.731 403.235 null] +1999 0 obj << +/D [1977 0 R /XYZ 71.731 403.235 null] >> endobj -1957 0 obj << -/D [1934 0 R /XYZ 91.656 385.49 null] +2000 0 obj << +/D [1977 0 R /XYZ 91.656 385.49 null] >> endobj -1958 0 obj << -/D [1934 0 R /XYZ 71.731 373.371 null] +2001 0 obj << +/D [1977 0 R /XYZ 71.731 373.371 null] >> endobj -1959 0 obj << -/D [1934 0 R /XYZ 128.578 362.576 null] +2002 0 obj << +/D [1977 0 R /XYZ 128.578 362.576 null] >> endobj -1960 0 obj << -/D [1934 0 R /XYZ 71.731 361.169 null] +2003 0 obj << +/D [1977 0 R /XYZ 71.731 361.169 null] >> endobj -1961 0 obj << -/D [1934 0 R /XYZ 91.656 344.644 null] +2004 0 obj << +/D [1977 0 R /XYZ 91.656 344.644 null] >> endobj -1962 0 obj << -/D [1934 0 R /XYZ 71.731 319.573 null] +2005 0 obj << +/D [1977 0 R /XYZ 71.731 319.573 null] >> endobj -1963 0 obj << -/D [1934 0 R /XYZ 145.324 308.778 null] +2006 0 obj << +/D [1977 0 R /XYZ 145.324 308.778 null] >> endobj -1964 0 obj << -/D [1934 0 R /XYZ 71.731 306.621 null] +2007 0 obj << +/D [1977 0 R /XYZ 71.731 306.621 null] >> endobj -1965 0 obj << -/D [1934 0 R /XYZ 91.656 290.845 null] +2008 0 obj << +/D [1977 0 R /XYZ 91.656 290.845 null] >> endobj -1966 0 obj << -/D [1934 0 R /XYZ 71.731 278.726 null] +2009 0 obj << +/D [1977 0 R /XYZ 71.731 278.726 null] >> endobj -1967 0 obj << -/D [1934 0 R /XYZ 122.291 267.931 null] +2010 0 obj << +/D [1977 0 R /XYZ 122.291 267.931 null] >> endobj -1968 0 obj << -/D [1934 0 R /XYZ 71.731 266.524 null] +2011 0 obj << +/D [1977 0 R /XYZ 71.731 266.524 null] >> endobj -1969 0 obj << -/D [1934 0 R /XYZ 91.656 249.998 null] +2012 0 obj << +/D [1977 0 R /XYZ 91.656 249.998 null] >> endobj -1970 0 obj << -/D [1934 0 R /XYZ 71.731 231.966 null] +2013 0 obj << +/D [1977 0 R /XYZ 71.731 231.966 null] >> endobj -1971 0 obj << -/D [1934 0 R /XYZ 450.945 219.114 null] +2014 0 obj << +/D [1977 0 R /XYZ 450.945 219.114 null] >> endobj -1972 0 obj << -/D [1934 0 R /XYZ 518.615 219.114 null] +2015 0 obj << +/D [1977 0 R /XYZ 518.615 219.114 null] >> endobj -1973 0 obj << -/D [1934 0 R /XYZ 108.346 206.163 null] +2016 0 obj << +/D [1977 0 R /XYZ 108.346 206.163 null] >> endobj -1974 0 obj << -/D [1934 0 R /XYZ 175.219 206.163 null] +2017 0 obj << +/D [1977 0 R /XYZ 175.219 206.163 null] >> endobj -1975 0 obj << -/D [1934 0 R /XYZ 228.813 206.163 null] +2018 0 obj << +/D [1977 0 R /XYZ 228.813 206.163 null] >> endobj -1976 0 obj << -/D [1934 0 R /XYZ 281.858 206.163 null] +2019 0 obj << +/D [1977 0 R /XYZ 281.858 206.163 null] >> endobj -1977 0 obj << -/D [1934 0 R /XYZ 359.541 206.163 null] +2020 0 obj << +/D [1977 0 R /XYZ 359.541 206.163 null] >> endobj -1978 0 obj << -/D [1934 0 R /XYZ 429.483 206.163 null] +2021 0 obj << +/D [1977 0 R /XYZ 429.483 206.163 null] >> endobj -1979 0 obj << -/D [1934 0 R /XYZ 477.557 206.163 null] +2022 0 obj << +/D [1977 0 R /XYZ 477.557 206.163 null] >> endobj -1980 0 obj << -/D [1934 0 R /XYZ 71.731 193.211 null] +2023 0 obj << +/D [1977 0 R /XYZ 71.731 193.211 null] >> endobj -1981 0 obj << -/D [1934 0 R /XYZ 140.493 193.211 null] +2024 0 obj << +/D [1977 0 R /XYZ 140.493 193.211 null] >> endobj -1982 0 obj << -/D [1934 0 R /XYZ 197.219 193.211 null] +2025 0 obj << +/D [1977 0 R /XYZ 197.219 193.211 null] >> endobj -1983 0 obj << -/D [1934 0 R /XYZ 71.731 186.791 null] +2026 0 obj << +/D [1977 0 R /XYZ 71.731 186.791 null] >> endobj -1984 0 obj << -/D [1934 0 R /XYZ 419.446 175.279 null] +2027 0 obj << +/D [1977 0 R /XYZ 419.446 175.279 null] >> endobj -1284 0 obj << -/D [1934 0 R /XYZ 71.731 129.286 null] +1312 0 obj << +/D [1977 0 R /XYZ 71.731 129.286 null] >> endobj -1933 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F35 1525 0 R >> +1976 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F35 1567 0 R >> /ProcSet [ /PDF /Text ] >> endobj -1987 0 obj << +2030 0 obj << /Length 1360 /Filter /FlateDecode >> stream -x��WY��6~��PѢ����[R�4����M�$(hY��H��#i��;<䕭x[,�P,<<�of8�pH$� �4ET� �8��/O�KD^$��\�OR�J����X1�(4Xmބ����vQ�C��x��C嶺}ѹ�ӡ���w��ǫ�`1Jv�i���6�#J�1n����F�0�I�HgC�[=�����#l��M�,�v��Ej�\���V����~���d��R/�?��melID��z�Ih)x�j����Q�em�8#3N�˦�U��lG�0r��7�p��p�X`��$�s�H�ՂK�(�[��_���Y�L�� M�s�@��.��� U[�P����@H&Q��̟�O���ARJ�A��4eA��#��( �7�p�Z99W��D"���(9b�� �@��@R[�c�����<H V8" $� 9����BA��[}*���uY�u����%���HLL����rh�Y�ۇ~7y�nHSD�ˋg0ld�!b� $�͖�EswU8��&^����P��E�[��{���J�a��j�s6<�`4G #8�F�������|�`* ���<n;�z_#���/ �$9�^ou[)�h�����h�k�X�P�n����s���Y�X'��x�"��s��P��"�P&8�'ϧ��yq���*W>MzW�a��qǧI�<9wy�e��#����9T��'"����IQ�[M��}S�y����[֪�y�Ĺ�߂�k��T���T~��J��j7����&�x@:�:��3�����Zل:�ֈ�=|������� �v�h�,�}Kд�j�F�ތ�Zu���4��y �ƒr�����G����o�ސ~�� ���o��m]�S.��s!���뀊V�����%@�B�K�F. [&��W�/�^>�B@V��v[���0�JQ�tb�Rw��T=�qZ&&ӑU��s��&B�f�T�1�j��]����rf�ԍ�^f:�(p���3f�=�M�����r�J�@3��k���qN]��/t��ږ�Hb(�&�f���5# ��]���\����8����½� � ?�pB/�+#%|�z�6�ޞ�v���W -�k����E�����_qD�����K�����D^^4�.aU���:��CJ��5��U7* �,U�ƦT�3����ne��-��l���¶��k�{��G}��]7�M�2���-ƴ�����!�j|)(������-x���c�G�v#XN���(o��R(��Xl���?�~���5�?<���h�!���ˠ3���U��`��QT0�0>h1>�s�9�?ɡ��endstream +x��W[��F~���jՀT����F�����ZM�$���4��I�_��>�ħ�Q*���|3���$��#ABP�`��Ry����<]/{�x"s�\\<a,�P&Y���R$$��T�`�~>ܩv(�(����r����.we�fO�庈�-_,/��%(Kٍ��23�(H�(Ƹ�G,P�SkA����#�����n"�Ï�Q�76����Q�^�Us���Z ��}���]�&]U:�2�T6[��{���������R�0�a!-꣢ϻ�u�$a���m[�N5�,��{)`�6Bo��` �|���ei� ��,��Q8B���.~������5�(��dJ\\_G)UטP����@H&Q��̟�O�[� )%� BP���+�͑ip�Q��t�w�����Gkb�%sy��1��I!@i )��ıC�����<H!V8&)$� 9�n��BA����T;7���u�3K�!�<��xKo9��,�r��4n�ݐ"��0��J`�ȐC�(H �-'���<�pM����P��爚�[T�{�,�J�a�j�s 6<�`4G c8�F������|�`* ���<n;�z� ���/ �$=��ltW+�h��tŇ}�*P�y�PUn����s���Y�X'��x�!��s��P��"�P�8�'ϧ��yI�R���P>MW�a��qǧI�<9���e��#����9T��'"����IY�[M��}]vE>��[6��y�Ĺ�߀�k��T���T~��Z5k�j7����X{@:�:��s�����Z���:�֘�=|�<upG���@���tw"!B����۱Qh�c��R��0<�]Q������~g1��+��ۨ7���-B +��}����C~�Bʥ�u.ij8=vP���{�Q$-ժ2m���0^�z~y�������]=v[�1W���V����i�#��00����5��L<�5ç��yW���eU�(g�H��ef�s�2�)�<c����t������� +4�Ƚ����ePo�BWŶll �%�rj"m&�8�3��(�v���P���M����^�w1?�'N��c�����ބC����'��s��Z�} ���(�������#�����^��4t�'�2�E�l�Vu����~8��q�X���.�F�%����V��`��;���L15��7�u�1T��?x à�ݨ�A�놕i[�[�x�1�FA��+�qHF�����CE�GG�����{q�q�Tk7jx��\������R(ߖ�Z���p��*q����ez�DƏ#/��|������/�k�Gc��$;�:G����endstream endobj -1986 0 obj << +2029 0 obj << /Type /Page -/Contents 1987 0 R -/Resources 1985 0 R +/Contents 2030 0 R +/Resources 2028 0 R /MediaBox [0 0 609.714 789.041] -/Parent 1841 0 R -/Annots [ 1995 0 R ] +/Parent 1879 0 R +/Annots [ 2038 0 R ] >> endobj -1995 0 obj << +2038 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [310.336 367.004 343.551 381.948] @@ -6237,323 +6249,331 @@ endobj /A << /S /GoTo /D (gloss-bugzilla) >> >> endobj 38 0 obj << -/D [1986 0 R /XYZ 297.751 705.748 null] +/D [2029 0 R /XYZ 297.751 705.748 null] >> endobj -1988 0 obj << -/D [1986 0 R /XYZ 71.731 705.533 null] +2031 0 obj << +/D [2029 0 R /XYZ 71.731 705.533 null] >> endobj -1989 0 obj << -/D [1986 0 R /XYZ 71.731 696.925 null] +2032 0 obj << +/D [2029 0 R /XYZ 71.731 696.925 null] >> endobj -1990 0 obj << -/D [1986 0 R /XYZ 71.731 682.032 null] +2033 0 obj << +/D [2029 0 R /XYZ 71.731 682.032 null] >> endobj -1991 0 obj << -/D [1986 0 R /XYZ 71.731 667.088 null] +2034 0 obj << +/D [2029 0 R /XYZ 71.731 667.088 null] >> endobj -1992 0 obj << -/D [1986 0 R /XYZ 71.731 667.088 null] +2035 0 obj << +/D [2029 0 R /XYZ 71.731 667.088 null] >> endobj -1996 0 obj << -/D [1986 0 R /XYZ 71.731 329.146 null] +2039 0 obj << +/D [2029 0 R /XYZ 71.731 329.146 null] >> endobj -1997 0 obj << -/D [1986 0 R /XYZ 433.454 306.232 null] +2040 0 obj << +/D [2029 0 R /XYZ 433.454 306.232 null] >> endobj -1985 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F44 1994 0 R /F35 1525 0 R /F32 1187 0 R >> +2028 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F44 2037 0 R /F35 1567 0 R /F32 1215 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2001 0 obj << -/Length 2414 +2044 0 obj << +/Length 2413 /Filter /FlateDecode >> stream -xڭ�r+���_���f,�\����'M;��$i�6�I�(i�ծ�+�� ���Ls��YA7��I�S�X�X��O�����N�6���;�A ?�a|aq�X���-F>��=���3_�(Lg/���������G��m�oM=_�q����Oe�fE����6�͋"����%�b�IJ8�2�-5_�)��ͫ�ߖ�4�p�JEꇳ������o��| � 0�P���8Ok ��q�K��p��_��%�a�B/+y�VL-��R$�gj]c��S�He�����]U,+>�4fEK-/�$���V��JC����n�֖�6pGC��f���>�����L �=��k�&K5�r�P�I�p��O.H:�V��̛��+�em�V���ݤ����0���˥i��4�[�V��=��)�d^��I<ӈ4�b�$��d%/v����y�4�~Ǔ�!8�֭��Vͻ�H��5(���d�k`��M^v�1�i>����� ߣ� -ؔ�'�]������5�{�'�rk�o(���^z�e"d��(������p��Gb<!�R|6K� ] n_�`ȏ�Sn�@�$��a(�8�� �,F8g�$���'����ue�J$@zu��j�PQ��$G��i�k^�93(�%�ȑw��2ϊ�v�Y�4�=&i���تIr��Y��ܵ�(��M�7u�uU.�������I��vّ�Z�l�D!��Ii�X�p����.[�"���yzV�B�y?I�k+o�0�n���n��חl�4R��Ewk�p�d(�m����p8�Q���j��۴ ��2��|Y����X�<h��� ���a��f���fai��l���q�5X��]�`�h!:��E���y{ȡ����l+Ǧ5;��6�sLB$ho��+�C��M����m��jA������E�kBl[�C# ��qP ����yi�=������fL�VZ%Y!ZvP�����r�C���1ŚƇ��V�n_�"�K�� ���ٷL��/=0��~�YW��\)�GG��^�no֞-: - Xc��3i�3[Yo�g���K��8��Ji��,�(�� �z���r����5����;D�/t�ΔHS=��l}�|����W�\�� ��xg$�xG!@�87����h��`(Z�k���Y]b�:˔*��BB� 9S���}�A��R� R��+�RL*�n��`��Zx͚sO�,������-����|�� �G�j�-\i�6A�O��Lh��^��x�fQ$&��(�qқWC!И��C����[�t���r��̨�@��g#%���@֭���x�8ǖ�\|��Љ�V`��eA$)?�0�0Q�WiV�e�ۙre3����;|�߬`��}^��[���M��˹��1]��I��Q`��l�(<�u���7<�F��'��Y�\�֎�5kWz��M��/��9�� -,��>��&@C���'ˬ����;$͇SSr*��D��b.�(��U�2 -���6��4�t���N��27IE���-�g���P�I�{Sg[k�n�Qn�t>7�Z@��&�+�E.eD��ZY�z�r�*��(���y��5!�P$�n��d#�5�K-�+�E������k�??�Ϩ�WN�#�&�����^��E�U��G��*R%�:�)(Ej�މo �O@a�,���D9P������X�$�� ����T��>��9�=3i � �s�"�b�\)-�9� -q��9�x�+'�W9�{k��R$ؽ;�t�J -����l/�����Y� -n��9w�+'�W�qvժ+���Z^jXL/��U�1 B2$�S����FW%8��= * ��5����_�3�k�a�['���)��2סWge��f��=n��:��/�������9����F'��|��o�ج����yO0ZSԘ����y����a�v�q', ��C:e�a\8`q�n�����ɚ֑�^B� "�^Mr=� dh7�^�-�'� n��jp���W ���k��-7�v�9:�K���7]�gs^Z�OR؉����B_�:_\hp���Wp�,|�e�pS�$� <M�5��o�9+� /�5-��á���?�n�W�� 4�����B��q']¾˘�C�'�'��(��*Ӕ_�UB���)�r�l�Hθ֒�Ѵ�V��<�آ�sۯ$j2�`U�H.0���"(�+�����ј\�)N�����!�F��ndy{���mP��c7��'�ET�����X`�i��ٸz��u���@> #'�ȳY9��}�f�}SU+^^�QA I߮��1�&~�(���4m�Ԧ@�q�W�D�@�ߌ�uS������=����g�����endstream +xڭ�r+���_���f,����>��iǙ�$��f:I�%m��U�bE����[2��gIA�@j&�O�"%"����N�6���;�~ +h_X\&Ilf���/w�f���d���O�Fh�^V?z_n�}c��BG��}���I�<+64��n���y:���kGREB��IJ8[E��jJ"m����" Cܥ��`�0RhM�|[6�a�����"�&�<��x���\K�lqb�_ں!�a�/-x֔L-�ER�R3�����P$2f�����]�,J>��vEK /e$�4�V�-K����l��֖�6pGM���vn��>���zc�����o�� +o9[(�E+�=D�����.+����JziS�U���n�l- ���oR������x�g }K� +�x�����s_z��$��i�U�����d%/n����\y�<�j[��I������O��]N��m�sĉ���k`��MV��1�i>�2O��p ߣ� +ؔ�'�]����p����=�t���7���W/�S22 fA�\v{FY8��#1��A)>�e� ] +� n-0���)7�/T�ς ~_�Q#�3n�P�QГ��^��tb$ ���a�X��Qǿ�#��4�5/�����m��;�v���@�j�\j���G�@l5$�G�ɴ�o�Z@�C�&������d +��mm������v��ZVo�D!��Ii�Xu��y�ͪ]��E��� �8���z?I��'o�a��~_"��/�"�i�P~ݝÝ���6������p���'��lc�n݀���>�^�en�3���`̃z����'z�-lȖ[���k�}��/�W<p�����W`��Y�����4�YzgE�����L�ζr��cːl�c"�x�6[YB���vg�lӆ�N�ڦ�;�q;��{bM��bkMxhD�7�A0�6+�������B��: ��Ɂ� +�$'D���VmqAn#{�1��6_���5۲E�����B��R8��mi� ,�KO8�i�y�6Wʳ��#�S/�noڜ-vj�Ɯif�0$c���BϦ����� q+�2"���Q.�A ���ǟ�lA�k���w��-L�̔H3��l}�|����W�\�� ��xg$7��B���qn!��.�1R ��P$����|�Ӫ��u�)-T ���r��D��l��Q�� �\vF��J1�8v�7tKx}��kΜ{�v�V���%�ToqІ�{�M<�UM�m�J�휵 e�@�'��A`ƌ��!`Eb° +x@�2P� �y��-0$��/��5N�� +�� �lΌ*� �~6R��i>d�&� +��g�slY������K���p]D���%x�f�]���-V.1�{������ � ��5]��{����; q���8`<I�`> +l0×���4g��M�CG���^�4�/D +gG隵+�|�o �O�A���}��L�!��� �eW�P����é)u*�`"Qx1�c���f�Wgf�b�_:���s'��J�'"�T�W�3��i(Ĥ����m�P��(7�V&���J-(��O�����.eD��ZQz�b�*��(���y���!D��N6�lDC��~iDt����?�\U?�P�pM��g����S�����S��5m�״f�Ul�9��D ��n +JA��G�w�[��1(Lݒ%c ��(*�A�7Xb�K����<�~T}� +1�_8g�g&��}N}S�a$�+�e'CFA���B�|)��㈫�ǽ���)b�ޝs:H%��^�1��#?�)8FA����|���܈��8�F�r��T�M-/q��,�A�j��!�Jߔ � ��U t~O�J�3rM� �f����di�đ�>�^�&𪴨�Ԭ������h��g.ݥ�ùɠ�4:�����3d}���XD�f�,M��{�њ���?����P�p%ˮ�Hw�r�=�S�ƅ�͖j�۴n:R�K��A�!�5�$��0XC�v���Pm)�6���1 +]5��܂��<�s���_�e�}����r}��N�'�_�B��Ņ��t��B����X�q7eL"���$XPS^z���C�b�2��P��&j[x�}��~ػ@J�-�/t�w�%컌q4T�:v= lE�dUں�b�bD'M!�p�d�5@2�u��u��p�ؿ����~5 Q��r�@|���8.�⾢���;�k`?�S�����z��������tc]��؍��Ig�!�m�>��n�li6��Bl]�4:�Oè�h�g��eM�/�oߔ劗W�aT��PBҷ��r���7� e�u�7�)�r'ĕ �ǐ1E7cĀ���o��C�"eOťCg=���������endstream endobj -2000 0 obj << +2043 0 obj << /Type /Page -/Contents 2001 0 R -/Resources 1999 0 R +/Contents 2044 0 R +/Resources 2042 0 R /MediaBox [0 0 609.714 789.041] -/Parent 1841 0 R -/Annots [ 2008 0 R 2009 0 R 2019 0 R 2021 0 R 2023 0 R 2025 0 R 2027 0 R 2029 0 R ] +/Parent 1879 0 R +/Annots [ 2051 0 R 2052 0 R 2062 0 R 2064 0 R 2066 0 R 2068 0 R 2070 0 R 2072 0 R ] >> endobj -2008 0 obj << +2051 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [508.095 566.273 537.983 575.184] /Subtype /Link /A << /S /GoTo /D (os-specific) >> >> endobj -2009 0 obj << +2052 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [71.731 553.321 84.184 562.233] /Subtype /Link /A << /S /GoTo /D (os-specific) >> >> endobj -2019 0 obj << +2062 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.664 319.519 133.11 328.43] /Subtype /Link /A << /S /GoTo /D (install-perl) >> >> endobj -2021 0 obj << +2064 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.664 301.586 191.202 310.498] /Subtype /Link /A << /S /GoTo /D (install-database) >> >> endobj -2023 0 obj << +2066 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.664 285.711 166.176 292.565] /Subtype /Link /A << /S /GoTo /D (install-webserver) >> >> endobj -2025 0 obj << +2068 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.664 265.721 150.823 274.632] /Subtype /Link /A << /S /GoTo /D (install-bzfiles) >> >> endobj -2027 0 obj << +2070 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [89.664 249.845 169.364 256.699] /Subtype /Link /A << /S /GoTo /D (install-perlmodules) >> >> endobj -2029 0 obj << +2072 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [92.371 229.855 209.093 238.767] /Subtype /Link /A << /S /GoTo /D (install-MTA) >> >> endobj -1285 0 obj << -/D [2000 0 R /XYZ 71.731 718.306 null] +1313 0 obj << +/D [2043 0 R /XYZ 71.731 718.306 null] >> endobj 42 0 obj << -/D [2000 0 R /XYZ 354.129 703.236 null] +/D [2043 0 R /XYZ 354.129 703.236 null] >> endobj -1286 0 obj << -/D [2000 0 R /XYZ 71.731 692.184 null] +1314 0 obj << +/D [2043 0 R /XYZ 71.731 692.184 null] >> endobj 46 0 obj << -/D [2000 0 R /XYZ 196.111 651.159 null] +/D [2043 0 R /XYZ 196.111 651.159 null] >> endobj -2002 0 obj << -/D [2000 0 R /XYZ 71.731 650.944 null] +2045 0 obj << +/D [2043 0 R /XYZ 71.731 650.944 null] >> endobj -2003 0 obj << -/D [2000 0 R /XYZ 71.731 632.374 null] +2046 0 obj << +/D [2043 0 R /XYZ 71.731 632.374 null] >> endobj -2004 0 obj << -/D [2000 0 R /XYZ 187.629 620.933 null] +2047 0 obj << +/D [2043 0 R /XYZ 187.629 620.933 null] >> endobj -2007 0 obj << -/D [2000 0 R /XYZ 71.731 581.381 null] +2050 0 obj << +/D [2043 0 R /XYZ 71.731 581.381 null] >> endobj -2010 0 obj << -/D [2000 0 R /XYZ 71.731 548.34 null] +2053 0 obj << +/D [2043 0 R /XYZ 71.731 548.34 null] >> endobj -2011 0 obj << -/D [2000 0 R /XYZ 71.731 524.594 null] +2054 0 obj << +/D [2043 0 R /XYZ 71.731 524.594 null] >> endobj -2012 0 obj << -/D [2000 0 R /XYZ 71.731 504.504 null] +2055 0 obj << +/D [2043 0 R /XYZ 71.731 504.504 null] >> endobj -2013 0 obj << -/D [2000 0 R /XYZ 71.731 467.707 null] +2056 0 obj << +/D [2043 0 R /XYZ 71.731 467.707 null] >> endobj -2014 0 obj << -/D [2000 0 R /XYZ 118.555 429.143 null] +2057 0 obj << +/D [2043 0 R /XYZ 118.555 429.143 null] >> endobj -2015 0 obj << -/D [2000 0 R /XYZ 71.731 387.21 null] +2058 0 obj << +/D [2043 0 R /XYZ 71.731 387.21 null] >> endobj -2016 0 obj << -/D [2000 0 R /XYZ 71.731 360.739 null] +2059 0 obj << +/D [2043 0 R /XYZ 71.731 360.739 null] >> endobj -2017 0 obj << -/D [2000 0 R /XYZ 71.731 347.414 null] +2060 0 obj << +/D [2043 0 R /XYZ 71.731 347.414 null] >> endobj -2018 0 obj << -/D [2000 0 R /XYZ 71.731 337.452 null] +2061 0 obj << +/D [2043 0 R /XYZ 71.731 337.452 null] >> endobj -2020 0 obj << -/D [2000 0 R /XYZ 71.731 319.519 null] +2063 0 obj << +/D [2043 0 R /XYZ 71.731 319.519 null] >> endobj -2022 0 obj << -/D [2000 0 R /XYZ 71.731 301.586 null] +2065 0 obj << +/D [2043 0 R /XYZ 71.731 301.586 null] >> endobj -2024 0 obj << -/D [2000 0 R /XYZ 71.731 285.711 null] +2067 0 obj << +/D [2043 0 R /XYZ 71.731 285.711 null] >> endobj -2026 0 obj << -/D [2000 0 R /XYZ 71.731 265.721 null] +2069 0 obj << +/D [2043 0 R /XYZ 71.731 265.721 null] >> endobj -2028 0 obj << -/D [2000 0 R /XYZ 71.731 249.845 null] +2071 0 obj << +/D [2043 0 R /XYZ 71.731 249.845 null] >> endobj -2030 0 obj << -/D [2000 0 R /XYZ 71.731 217.277 null] +2073 0 obj << +/D [2043 0 R /XYZ 71.731 217.277 null] >> endobj -1287 0 obj << -/D [2000 0 R /XYZ 71.731 198.971 null] +1315 0 obj << +/D [2043 0 R /XYZ 71.731 198.971 null] >> endobj 50 0 obj << -/D [2000 0 R /XYZ 138.296 161.756 null] +/D [2043 0 R /XYZ 138.296 161.756 null] >> endobj -2031 0 obj << -/D [2000 0 R /XYZ 71.731 154.403 null] +2074 0 obj << +/D [2043 0 R /XYZ 71.731 154.403 null] >> endobj -2032 0 obj << -/D [2000 0 R /XYZ 163.177 141.631 null] +2075 0 obj << +/D [2043 0 R /XYZ 163.177 141.631 null] >> endobj -2033 0 obj << -/D [2000 0 R /XYZ 71.731 135.242 null] +2076 0 obj << +/D [2043 0 R /XYZ 71.731 135.242 null] >> endobj -2034 0 obj << -/D [2000 0 R /XYZ 164.427 110.747 null] +2077 0 obj << +/D [2043 0 R /XYZ 164.427 110.747 null] >> endobj -1999 0 obj << -/Font << /F23 1173 0 R /F44 1994 0 R /F48 2006 0 R /F27 1180 0 R /F35 1525 0 R /F33 1278 0 R >> +2042 0 obj << +/Font << /F23 1201 0 R /F44 2037 0 R /F48 2049 0 R /F27 1208 0 R /F35 1567 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2037 0 obj << -/Length 1960 +2080 0 obj << +/Length 1965 /Filter /FlateDecode >> stream -x��Xݓ� ���O�<����L�Nһ|M�����t�LG�i�s�GHi}�__��d���N�З�H� �����"�O.2)��h-�4Y�իp����_I�X��j"��ë���x��4^<�J�b�-�8y-���|(�N��*J� �~[��8M�'��~�os<�_�{��a4�ęX��~ 23Ǣx!��U�� 3�+�=��ޡ,^]�)�&�M�7�Fg@KvY^�XE��Q��e� -���⾧"�w�U��۶���.��VoId�Xb����M�hZh�=����$P�[�k\��z�^ց�}\�$�� ��R�0hz���x&I�����~ոP�uB�jjM�����1˝]�+���ڪ��v����!\�#�$�X�!��P�t�$o�]����~ -��/�������yXfa�]�)i��LN}���P�.�WT�ݯ��* �`���ꊅW�� �����mS�a)�#�P,�0�-AN��S-�~x?���JKk��h���( ~è4ő���C����G�S��k?��?�N�4 �_�(�J��%C���ޒ�oϐ���rl�pJo:����09n�x a�S��R�z�i:���E.JD�Kޠ�E��1��9%����٘��P���#F��t�9��d�u�գ&c��NJz������P�yU*2�������l��8�XD��j��Tl����<>c�ػ�5&�aWZ\� -1Gxe�OЗ"]8� K��[ĕ�Y�*<&�h ����Q�� Xw�$́NU,9�@�4's;��u6��� �:���r��A���Ј^2�q��R�8塨��&�>�$�|�]3l���{we�9O����0Q -�g渝�����3ܭޖ\4�u9}��#6� e1ĺ#�p[�A�ڦ��A���ήx-�,��)�zg����S1�]Rl�^q�0_�.C=�F��f<za����������X ��g���z5-`�"��gu�P�}�D_x��VؖM�&����PtD��!��!��Vo.�V�O ��8>�>2<GI������`�m� sr$�����8��XVW9C=T�֔�qͮ#�C�����l�d;�xX��RXC��X�Iưc��vT���t��E�4t7���`�⾁��)ɐ%J哒<ܛ�ap.w��WmnSi0��^G�Ҍ��Ҍ�G���J3��4��IiƁ�Ҍ��Ҍ�&�E�4�/͐@���Rl�D����� ��Mn=�i�Cjㆬ���X||�d{m7�� R�p��g�D�p�X��6�#�Ps���\�+�Pj��.���@�k�P� A��@��3��9Z0�/����� 2a#f��i�"ޣ7��Gm�ۃ���q��&�����z�q+�cG��>�t��-��+x�/���@b������TP�.�2U� � gg5� GE4^A�-�)Y���nk�� ��Ld�{���;�N}*�"p���)ZL��qx��u�����rx,��i���z}2�������"�_��og����ɋ�Xdfm�4 �.x@N��Қ�st)VP�"u��'���I�����I� �c�HCh���yaM��lS��1�s��T�ƺ����Ǯ�A���AJ6Ĥ�K��!�8� �% -J�hj����Ha���͂kD��m_v�$B��� r&�p��4�z��L˜q]���â���oN���ŀC��&���:A=�㬼A���*�����O{�=0����}w ��92 �[m��K|���������3���9܂�J�������)!�5�S�(c�盄{�@� -�I�P��/�H���(��Op���.~6X��mj�l0��Mc�<[�쨚#JN�G���#�)졲ގ�-���#y=�;���~]ߑ< -_�H��tAcl��ݘn@���\�2{���Ed`I��pԂK��W9���0��endstream -endobj -2036 0 obj << +x��X[��4~�_�'H�S�8q.]q��M,,�a���m�m.���_όgris�"x���=��=3�\��D�$�&X� �y��_�a�'�%V,���|z����0\��:w����X'�$D���/�g��nu�\���گJ�fǣ)�D���4�c�����'���Q��u�s]��laA��J�*ƕ���*�V)܂��{���&�����ޔZ�q{�b�B���yS ���������lW�U��Xn���m��DvUC�Β;�����B+=M��W�CY����ʶ�F�qh^7�Ky����^J�{UGTU�$��?:�d�kܨ�:"GU��c�vԶm�e϶Յe~Em��;�t�jz�.��s�`,b�J�dzD���Щ`�k7�C˹l���Ht��J��-�Ӷ}J��h�c$k)���g��q��}�[��[]��JB��p�a�!�;��������2�Z"�2�=:���w�<���w�z�^h�� +5ܛ�&�5��_}?�Mvd�,����!����ԡm맷���iG�p�yU#�R�-�����}� .Vxl|�|�f����p��%x.�*�E�4~[���G�Q.�D�J>�Y�v1��)����٘2CO���=:�Vi�s����m�F�LC]�U�C'5�7�$��ĭP�"Q/���0��6��껒�W���4o��W6{�/�a ,��Rjܫ�1DxgxLЗ"^6����Yĝ��g�% �@U-Q�2ӂ�n�I��"[�S�(iN:�v�B��<Bo�*6uF9�8m�T����d�����Dq"�CV�5M�s�I���۪?t ����c+���D!H+3��{\wG���iuM�9�ߗ�G��b��P]�["�������.�iU���E��:yU�̾k�<�Trc���+�C�8eH���^��/�BR"xӒB��* !U�(B|:�}@/���p8ҷ�.��>�o���O�Ԋ�f����������!p0$Y����(�HhY��`=0? +=��-�sN�OK� ��V0'K��I*� `�S��^�� +k��j^���l�kIs����\�5}��?^�:����!���ᅁ֦��z��.GS7PiVd����}��>��!J�J'�/�^�s��J���������`�����Q��]``PfFff�1��8p���q��q�$3�gfq�hL�5�34��� +��r�>M#Bd�@�ub��S6@�ߟ�m�@���^9��J]�� +A ���b5�ᨎPC�Qg��.PC�5�b�PWO�.�C��t�q��!z�A���7z�.�!�=BƎ��!,bC�+\ l�^7���(B�n�;��z\�V��oYwl�q�ǜ�/ �lϽ���l����`Ŋ����ŭ '��3V�� g�h���h�D����Y.���n�@� ��Ld�{C �� ���� �.p8�g��d5���8����z�W)<��J�5}� �ˬ&B�W��ׁ/����}��w�c���i�D���9�f��ԭ��XAV�El�W"]�#�HFޗt�] ��U��sZ�6U��'5b�* +���y�]�(� 䂃�l�I���Cq@�K����*f�-#R�����F�Q���[z�Lg;9�Y��D�;fÜa_���ä��N�n����C�d�~g����rT^!QVrI��g]��:���}��=��Ø�92 �k�]������o08�Yj7gqo@Z p3�2(aJbN�Գ*?��\���Ο�5��a����������I7������c(?�p��f߃���?$�0̣m�G�9��s��I��(xY'��a���v��Z���J���}�������r��F8�f+Уn�*� +U���JE*�w~�Ef��j�-��O�sK���endstream +endobj +2079 0 obj << /Type /Page -/Contents 2037 0 R -/Resources 2035 0 R +/Contents 2080 0 R +/Resources 2078 0 R /MediaBox [0 0 609.714 789.041] -/Parent 2059 0 R -/Annots [ 2055 0 R ] +/Parent 2102 0 R +/Annots [ 2098 0 R ] >> endobj -2055 0 obj << +2098 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [487.887 245.191 505.55 254.102] /Subtype /Link /A << /S /GoTo /D (gloss-cgi) >> >> endobj -1288 0 obj << -/D [2036 0 R /XYZ 71.731 718.306 null] +1316 0 obj << +/D [2079 0 R /XYZ 71.731 718.306 null] >> endobj 54 0 obj << -/D [2036 0 R /XYZ 227.213 707.841 null] +/D [2079 0 R /XYZ 227.213 707.841 null] >> endobj -2038 0 obj << -/D [2036 0 R /XYZ 71.731 697.476 null] +2081 0 obj << +/D [2079 0 R /XYZ 71.731 697.476 null] >> endobj -1289 0 obj << -/D [2036 0 R /XYZ 71.731 672.608 null] +1317 0 obj << +/D [2079 0 R /XYZ 71.731 672.608 null] >> endobj 58 0 obj << -/D [2036 0 R /XYZ 156.121 640.294 null] +/D [2079 0 R /XYZ 156.121 640.294 null] >> endobj -2039 0 obj << -/D [2036 0 R /XYZ 71.731 631.842 null] +2082 0 obj << +/D [2079 0 R /XYZ 71.731 631.842 null] >> endobj -2040 0 obj << -/D [2036 0 R /XYZ 163.177 621.365 null] +2083 0 obj << +/D [2079 0 R /XYZ 163.177 621.365 null] >> endobj -2041 0 obj << -/D [2036 0 R /XYZ 71.731 614.976 null] +2084 0 obj << +/D [2079 0 R /XYZ 71.731 614.976 null] >> endobj -2042 0 obj << -/D [2036 0 R /XYZ 367.427 603.432 null] +2085 0 obj << +/D [2079 0 R /XYZ 367.427 603.432 null] >> endobj -2043 0 obj << -/D [2036 0 R /XYZ 71.731 588.324 null] +2086 0 obj << +/D [2079 0 R /XYZ 71.731 588.324 null] >> endobj -2044 0 obj << -/D [2036 0 R /XYZ 71.731 573.38 null] +2087 0 obj << +/D [2079 0 R /XYZ 71.731 573.38 null] >> endobj -2045 0 obj << -/D [2036 0 R /XYZ 363.982 563.881 null] +2088 0 obj << +/D [2079 0 R /XYZ 363.982 563.881 null] >> endobj -2046 0 obj << -/D [2036 0 R /XYZ 331.234 540.568 null] +2089 0 obj << +/D [2079 0 R /XYZ 331.234 540.568 null] >> endobj -2047 0 obj << -/D [2036 0 R /XYZ 71.731 512.673 null] +2090 0 obj << +/D [2079 0 R /XYZ 71.731 512.673 null] >> endobj -1290 0 obj << -/D [2036 0 R /XYZ 71.731 468.738 null] +1318 0 obj << +/D [2079 0 R /XYZ 71.731 468.738 null] >> endobj 62 0 obj << -/D [2036 0 R /XYZ 183.546 433.37 null] +/D [2079 0 R /XYZ 183.546 433.37 null] >> endobj -2048 0 obj << -/D [2036 0 R /XYZ 71.731 424.733 null] +2091 0 obj << +/D [2079 0 R /XYZ 71.731 424.733 null] >> endobj -2049 0 obj << -/D [2036 0 R /XYZ 163.177 414.441 null] +2092 0 obj << +/D [2079 0 R /XYZ 163.177 414.441 null] >> endobj -2050 0 obj << -/D [2036 0 R /XYZ 71.731 408.052 null] +2093 0 obj << +/D [2079 0 R /XYZ 71.731 408.052 null] >> endobj -2051 0 obj << -/D [2036 0 R /XYZ 364.877 396.508 null] +2094 0 obj << +/D [2079 0 R /XYZ 364.877 396.508 null] >> endobj -2052 0 obj << -/D [2036 0 R /XYZ 71.731 376.419 null] +2095 0 obj << +/D [2079 0 R /XYZ 71.731 376.419 null] >> endobj -1291 0 obj << -/D [2036 0 R /XYZ 71.731 324.678 null] +1319 0 obj << +/D [2079 0 R /XYZ 71.731 324.678 null] >> endobj 66 0 obj << -/D [2036 0 R /XYZ 190.186 285.405 null] +/D [2079 0 R /XYZ 190.186 285.405 null] >> endobj -2053 0 obj << -/D [2036 0 R /XYZ 71.731 278.053 null] +2096 0 obj << +/D [2079 0 R /XYZ 71.731 278.053 null] >> endobj -2054 0 obj << -/D [2036 0 R /XYZ 71.731 258.142 null] +2097 0 obj << +/D [2079 0 R /XYZ 71.731 258.142 null] >> endobj -2056 0 obj << -/D [2036 0 R /XYZ 435.451 208.493 null] +2099 0 obj << +/D [2079 0 R /XYZ 435.451 208.493 null] >> endobj -2057 0 obj << -/D [2036 0 R /XYZ 71.731 188.404 null] +2100 0 obj << +/D [2079 0 R /XYZ 71.731 188.404 null] >> endobj -2058 0 obj << -/D [2036 0 R /XYZ 384.386 177.609 null] +2101 0 obj << +/D [2079 0 R /XYZ 384.386 177.609 null] >> endobj -1292 0 obj << -/D [2036 0 R /XYZ 71.731 170.471 null] +1320 0 obj << +/D [2079 0 R /XYZ 71.731 170.471 null] >> endobj -2035 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F44 1994 0 R >> +2078 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F44 2037 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2063 0 obj << +2106 0 obj << /Length 3030 /Filter /FlateDecode >> @@ -6578,29 +6598,29 @@ Hs~BNґ �e]�G���� ��gW����!]�,od���Cz>zN�ܛ���BjǦP{3U��\�-�� �S�]�z�2R�<Y�N$ZF%�q\P������N���r�endstream endobj -2062 0 obj << +2105 0 obj << /Type /Page -/Contents 2063 0 R -/Resources 2061 0 R +/Contents 2106 0 R +/Resources 2104 0 R /MediaBox [0 0 609.714 789.041] -/Parent 2059 0 R -/Annots [ 2076 0 R 2085 0 R 2086 0 R ] +/Parent 2102 0 R +/Annots [ 2119 0 R 2128 0 R 2129 0 R ] >> endobj -2076 0 obj << +2119 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [146.43 466.808 191.262 475.719] /Subtype /Link /A << /S /GoTo /D (configuration) >> >> endobj -2085 0 obj << +2128 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [446.147 316.671 505.908 325.582] /Subtype /Link /A << /S /GoTo /D (win32-perl-modules) >> >> endobj -2086 0 obj << +2129 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [71.731 290.768 120.707 299.679] @@ -6608,12330 +6628,12871 @@ endobj /A << /S /GoTo /D (install-perlmodules-manual) >> >> endobj 70 0 obj << -/D [2062 0 R /XYZ 166.615 707.841 null] +/D [2105 0 R /XYZ 166.615 707.841 null] >> endobj -2064 0 obj << -/D [2062 0 R /XYZ 71.731 697.476 null] +2107 0 obj << +/D [2105 0 R /XYZ 71.731 697.476 null] >> endobj -2065 0 obj << -/D [2062 0 R /XYZ 180.572 674.765 null] +2108 0 obj << +/D [2105 0 R /XYZ 180.572 674.765 null] >> endobj -2066 0 obj << -/D [2062 0 R /XYZ 231.734 674.765 null] +2109 0 obj << +/D [2105 0 R /XYZ 231.734 674.765 null] >> endobj -2067 0 obj << -/D [2062 0 R /XYZ 172.004 661.813 null] +2110 0 obj << +/D [2105 0 R /XYZ 172.004 661.813 null] >> endobj -2068 0 obj << -/D [2062 0 R /XYZ 71.731 659.657 null] +2111 0 obj << +/D [2105 0 R /XYZ 71.731 659.657 null] >> endobj -2069 0 obj << -/D [2062 0 R /XYZ 118.555 624.105 null] +2112 0 obj << +/D [2105 0 R /XYZ 118.555 624.105 null] >> endobj -2070 0 obj << -/D [2062 0 R /XYZ 393.169 612.628 null] +2113 0 obj << +/D [2105 0 R /XYZ 393.169 612.628 null] >> endobj -2071 0 obj << -/D [2062 0 R /XYZ 273.304 600.972 null] +2114 0 obj << +/D [2105 0 R /XYZ 273.304 600.972 null] >> endobj -2072 0 obj << -/D [2062 0 R /XYZ 71.731 579.052 null] +2115 0 obj << +/D [2105 0 R /XYZ 71.731 579.052 null] >> endobj -2073 0 obj << -/D [2062 0 R /XYZ 202.34 559.346 null] +2116 0 obj << +/D [2105 0 R /XYZ 202.34 559.346 null] >> endobj -1293 0 obj << -/D [2062 0 R /XYZ 71.731 552.207 null] +1321 0 obj << +/D [2105 0 R /XYZ 71.731 552.207 null] >> endobj 74 0 obj << -/D [2062 0 R /XYZ 200.472 514.992 null] +/D [2105 0 R /XYZ 200.472 514.992 null] >> endobj -2074 0 obj << -/D [2062 0 R /XYZ 71.731 507.64 null] +2117 0 obj << +/D [2105 0 R /XYZ 71.731 507.64 null] >> endobj -2075 0 obj << -/D [2062 0 R /XYZ 303.371 494.867 null] +2118 0 obj << +/D [2105 0 R /XYZ 303.371 494.867 null] >> endobj -2077 0 obj << -/D [2062 0 R /XYZ 71.731 461.826 null] +2120 0 obj << +/D [2105 0 R /XYZ 71.731 461.826 null] >> endobj -2078 0 obj << -/D [2062 0 R /XYZ 179.188 451.032 null] +2121 0 obj << +/D [2105 0 R /XYZ 179.188 451.032 null] >> endobj -2079 0 obj << -/D [2062 0 R /XYZ 71.731 425.961 null] +2122 0 obj << +/D [2105 0 R /XYZ 71.731 425.961 null] >> endobj -2080 0 obj << -/D [2062 0 R /XYZ 71.731 425.961 null] +2123 0 obj << +/D [2105 0 R /XYZ 71.731 425.961 null] >> endobj -2081 0 obj << -/D [2062 0 R /XYZ 71.731 405.091 null] +2124 0 obj << +/D [2105 0 R /XYZ 71.731 405.091 null] >> endobj -2082 0 obj << -/D [2062 0 R /XYZ 71.731 405.091 null] +2125 0 obj << +/D [2105 0 R /XYZ 71.731 405.091 null] >> endobj -2083 0 obj << -/D [2062 0 R /XYZ 71.731 362.564 null] +2126 0 obj << +/D [2105 0 R /XYZ 71.731 362.564 null] >> endobj -2084 0 obj << -/D [2062 0 R /XYZ 71.731 329.622 null] +2127 0 obj << +/D [2105 0 R /XYZ 71.731 329.622 null] >> endobj -2087 0 obj << -/D [2062 0 R /XYZ 71.731 280.805 null] +2130 0 obj << +/D [2105 0 R /XYZ 71.731 280.805 null] >> endobj -2088 0 obj << -/D [2062 0 R /XYZ 71.731 280.805 null] +2131 0 obj << +/D [2105 0 R /XYZ 71.731 280.805 null] >> endobj -2089 0 obj << -/D [2062 0 R /XYZ 71.731 259.935 null] +2132 0 obj << +/D [2105 0 R /XYZ 71.731 259.935 null] >> endobj -2090 0 obj << -/D [2062 0 R /XYZ 125.419 235.44 null] +2133 0 obj << +/D [2105 0 R /XYZ 125.419 235.44 null] >> endobj -2091 0 obj << -/D [2062 0 R /XYZ 71.731 233.283 null] +2134 0 obj << +/D [2105 0 R /XYZ 71.731 233.283 null] >> endobj -2092 0 obj << -/D [2062 0 R /XYZ 71.731 218.339 null] +2135 0 obj << +/D [2105 0 R /XYZ 71.731 218.339 null] >> endobj -2093 0 obj << -/D [2062 0 R /XYZ 204.375 197.184 null] +2136 0 obj << +/D [2105 0 R /XYZ 204.375 197.184 null] >> endobj -2094 0 obj << -/D [2062 0 R /XYZ 465.976 173.871 null] +2137 0 obj << +/D [2105 0 R /XYZ 465.976 173.871 null] >> endobj -2095 0 obj << -/D [2062 0 R /XYZ 76.712 145.577 null] +2138 0 obj << +/D [2105 0 R /XYZ 76.712 145.577 null] >> endobj -2096 0 obj << -/D [2062 0 R /XYZ 71.731 125.652 null] +2139 0 obj << +/D [2105 0 R /XYZ 71.731 125.652 null] >> endobj -2061 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F44 1994 0 R /F48 2006 0 R >> +2104 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F44 2037 0 R /F48 2049 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2099 0 obj << -/Length 1991 +2142 0 obj << +/Length 2133 /Filter /FlateDecode >> stream -xڭZێ��}�W��N_ؼA��z=;�N2Y���<�R�D�e�g���b7E�d�&���vX��T7Y�Xp�'�`���L���bsx�;�r�N8��AV̇�w���"ei�OϋP$,���,�r��g��>;5�Z���dv{���(���8���E���ӟ���t!�*fi�H�:�ı0\�7Q����E:Z�<a -Σc�r{.L�:��T�������r%�����z�7�C�2l��_�]�1X��R� ��^���9�� �5z��;��l��8���u������˳=�*�ӹn���=vw�($[ �"n5(�6e�ȇ�"R�A9�E�"� �<e�1Zm͋)� #��T�;��.�~��D�!O�br��m��l0 -�� ��6��My8�q���aNp�e��s��5� ?����`�MU��5��>�3cj��zoϴ�� -���d)�P���l�8j����{8�7��nR<�EQ������E�H�鄈_ͷs^�����*�sr=�)q�b&���������ΓarFf���\Iʢ(��o/���{d�8�~,�8)܃�7��`Z�V�$��� -A��J� ��J0�-�=2�>?����a)*�H0�Ft�=��� ��>�:�=2���&[�?�����dG��������e�1^] �2L�n�@p��:�z� �.�C����R3uC�ī�E�#�+�~�k����_%T�<f -j2�� �A�>��=�z���#�V������V�}�թ$�0$��1ǡ�Һ�����&!�[Wo�������IHф���%d��%���W�/!3\7Aq��^�x�:R�籄"3hv�!D��Z+I��c�"9:�xE�r����E�Oy���P1�:a�G��P+�)�@��*� �E�U`�u[�{d�W�i��No{{�,��Pi0�y�����2���H[�q�S���A�02�NtB@�l&0�l���Ð�>�y����LpBp��c������ -g�nMp���B��w�^���cOrxXq��_��,�c���!Z1����M1(�Y$��b����$|�Ƅ�`I�� -���*�-�g�n+@p�̶ -�?��^�j����@��3C� -���*g�n+@p��� -<�Ȫz84yD�F><Iz�O�he���3T�e �Gf��sSVٗ�x�D����w����NY�?�B(xً8$����]�A�U���kH�02�>�}���xȸ&�u�Kpx�]s���}e�\��k��\q��gU���|&d߈!]W0�Ltr1d��͙�|�w��Uc�k���\���;I+T�D_�ڬ��D!S�.uoR�\���z{RF���X����OS��2*�C�b��8�b?�~GZ�q�bz�l���A�e������ad�K�uU�C�$iͤ�I:��P���ʇ�c�d�^�`�IrrYk���I"|�G���f)���|7�?1�qH��aHb\�#f:5mw -w�A��qlL��<�6Ɨ$��Ԃ�B0�$9�7���$>�̣��l6�_M��Jr�&��4}�!�E(����]AIY8��Se�������%�%7���5u�2�����$N�F�;`|�� �Z��̈́Q�#��}�v?�w���|�{��<.Cѵ ��?���F?Z��Y�d�����͕ҕ��s]O���Z۶�+����ЕR�i��X�ĻĎ�[�� K�}��f��V�ў9U���ؓ���- Y��B^��1�d��s7V�ܷ���Z� _ʶ��MG�5��N��أ��� �&��" v��ٶfse��q����bu�,�C߆�=z� �>C����=����3���� Zxɷ��pfk���\4��p鋻 f��s֘�������=v�[��:��s��^4�t(�}����䴿�����mF��4C+�"8� �����b��_�{!endstream +xڭZmo�������T���Vu��f7M�l�M�{�۪"�ب6�'����f0���V��s�9�r f��,,Pp���7Kv��l �\��0�E������J�"�j��<sEȢ`(�BO�W�u����*-��qG2}��U��f�Z�<���m������}z<�z*`Q�H���1ם�7���E���?x�\G�v��Ms�9�� +��I�!�<�����Y�^m҃A�c$sɝ��u|�>h��\zN�V�yӗV�>�Wu�k��ɨn�i��¹L4`�*0��eO�s���7</��$.�O�Cm\8��ssW�qA��@-�Z��J��B'�x�+�@H=P�uDQ0nC���8��>���%��zRG�g�`�w�cd!|q�g��l#��{!=����CR��۴2?nA���'_���������'/��<���/=�t��&F�4^_��o��z����pPB/p���F��n�,K6'�%�̤x.��������H5F2L'D|M�8fe����>-��e�\�gJ��Ä��}1>�5d�������D�>W1�wǸ��������fሔnf)9�����=룙ҍP���(�E.8 +�r��\�.K�\C�i��Y侊�t�����(wq����{\2)�(l:���ȧuh1V}QV�\�:�=��oڮ�]w�F��z��v�@�v}�u��=�Z���r�v�c0�,�^$Ɏ7�U�o6�.�k窖|tZB����[[@���D<Nk84]��M�N|n�����H�HY�HG�j]��<<` +r,R�c�@�QߪАkZ"��g�?g[X�`omu´���.�qmI�Q���)�@Ћ�����JP>�̣��;)d;����a>zd��+ G�wF�笐���{JҒ������U�!״�w�,r���F]���[$��y#Z�c��@Ѝ�*��kZ��g�#����'�_��ʣ.� kB9�ӈ�F�Sr�MR�cMo�b����:I�`�R���p].)�C�<�p}5���e�#�k $��0�Ϲ�v"y��<7��.�̎�l���e< +�*:��`l�h d�;�5��g����ֻ=��|���m�f+T���xT��2�o���_�}QV�|��D�މ:�|B��#\��H��3oٔ�r�1>7"����C� +eK�����1 �\� dc ��� ���A!|��d�Ð�̅-��w�!I1nQ����w����]:*'�5(A��C��Cbw��x��<VÜ-��BQo 1flnt��E�Lp���`�a1���<0�=����n16!w^��p��\�� �$�"����Bh�n-�����-FP�`b�k��,wF��cCp��"��8��qyh^�ns�O��饪�P2��KcS����פjw�,r������r�3H�a��g{�����cU��*3����U\�,�KQ�� �;��8�w��t���X�4���\P�y�A�*�|M����"Y%��T�I-\ɔ�q�g����l_�U����?����K���(̓�=���@Τ�3X�ֈE2ۙ����ְ ���Ep��"���w(T�u��~��O�|��Oվi��o��S9WU�lv0��BU���˵E\2�U��-�&�A��Z��iq �Y$��B�{5waŸ�D�s�#>�܀|�^J,���� 5k!6����Zj�P]��C�<:���\y �U���C�� �d*d��Q�1��+c�5}� �9^��\���]e�<0�t<f"���T�:K�D3k};B5+��g�~���y�X� ���_�i5�r�<���T���ח��CRf�� U���HI[�MR��%�V�#TӒ�=���Iy|z� +j�w i�Ok��,�Դ��45�ZSku9B5�)��3;x4�A�M8WsX�*Pb��7�Sql�p�F-���21�O�vPKg-��<��ىύvt���o�_o\ ��wR�Q��d�J�l�jZ&��g�|�T!�OC�(�R�ȄhPi�+ +�/|�+\R�b� jq���մ8w���''�U��H2���D΅�Z�Gt-d� ��$�ႁ������!��LC�endstream endobj -2098 0 obj << +2141 0 obj << /Type /Page -/Contents 2099 0 R -/Resources 2097 0 R +/Contents 2142 0 R +/Resources 2140 0 R /MediaBox [0 0 609.714 789.041] -/Parent 2059 0 R -/Annots [ 2116 0 R 2125 0 R 2139 0 R 2142 0 R 2145 0 R 2148 0 R 2151 0 R 2154 0 R ] +/Parent 2102 0 R +/Annots [ 2155 0 R 2162 0 R 2170 0 R 2175 0 R 2178 0 R 2181 0 R 2184 0 R 2191 0 R 2198 0 R ] >> endobj -2116 0 obj << +2155 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [89.664 505.24 140.592 514.152] +/Rect [89.664 541.106 140.592 550.017] /Subtype /Link /A << /S /GoTo /D (install-modules-dbd-mysql) >> >> endobj -2125 0 obj << +2162 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [89.664 433.509 126.595 442.421] +/Rect [89.664 487.308 126.595 496.219] /Subtype /Link /A << /S /GoTo /D (install-modules-template) >> >> endobj -2139 0 obj << +2170 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [89.664 298.018 104.05 306.929] +/Rect [89.664 405.614 104.05 414.525] /Subtype /Link /A << /S /GoTo /D (install-modules-gd) >> >> endobj -2142 0 obj << +2175 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [89.664 280.085 136.707 288.996] +/Rect [89.664 369.749 136.707 378.66] /Subtype /Link /A << /S /GoTo /D (install-modules-chart-base) >> >> endobj -2145 0 obj << +2178 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [89.664 262.152 134.485 271.063] +/Rect [89.664 351.816 134.485 360.727] /Subtype /Link /A << /S /GoTo /D (install-modules-gd-graph) >> >> endobj -2148 0 obj << +2181 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [89.664 244.219 155.237 253.131] +/Rect [89.664 333.883 127.003 342.794] /Subtype /Link -/A << /S /GoTo /D (install-modules-gd-text-align) >> +/A << /S /GoTo /D (install-modules-gd-text) >> >> endobj -2151 0 obj << +2184 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [89.664 226.287 137.574 235.198] +/Rect [89.664 315.95 137.574 324.862] /Subtype /Link /A << /S /GoTo /D (install-modules-xml-twig) >> >> endobj -2154 0 obj << +2191 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [89.664 208.354 139.865 217.265] +/Rect [89.664 262.152 139.865 271.063] /Subtype /Link /A << /S /GoTo /D (install-modules-patchreader) >> >> endobj -2100 0 obj << -/D [2098 0 R /XYZ 140.002 696.687 null] +2198 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [89.664 208.354 136.368 217.265] +/Subtype /Link +/A << /S /GoTo /D (install-modules-soap-lite) >> >> endobj -2101 0 obj << -/D [2098 0 R /XYZ 71.731 668.792 null] +2143 0 obj << +/D [2141 0 R /XYZ 140.002 696.687 null] >> endobj -2102 0 obj << -/D [2098 0 R /XYZ 71.731 637.808 null] +2144 0 obj << +/D [2141 0 R /XYZ 71.731 668.792 null] >> endobj -2103 0 obj << -/D [2098 0 R /XYZ 170.798 624.956 null] +2145 0 obj << +/D [2141 0 R /XYZ 71.731 637.808 null] >> endobj -2104 0 obj << -/D [2098 0 R /XYZ 71.731 617.818 null] +2146 0 obj << +/D [2141 0 R /XYZ 170.798 624.956 null] >> endobj -2105 0 obj << -/D [2098 0 R /XYZ 89.664 597.061 null] +2147 0 obj << +/D [2141 0 R /XYZ 71.731 617.818 null] >> endobj -2106 0 obj << -/D [2098 0 R /XYZ 71.731 594.904 null] +2148 0 obj << +/D [2141 0 R /XYZ 89.664 597.061 null] >> endobj -2107 0 obj << -/D [2098 0 R /XYZ 89.664 579.128 null] +2149 0 obj << +/D [2141 0 R /XYZ 71.731 594.904 null] >> endobj -2108 0 obj << -/D [2098 0 R /XYZ 71.731 577.345 null] +2150 0 obj << +/D [2141 0 R /XYZ 89.664 579.128 null] >> endobj -2109 0 obj << -/D [2098 0 R /XYZ 89.664 561.196 null] +2151 0 obj << +/D [2141 0 R /XYZ 71.731 577.345 null] >> endobj -2110 0 obj << -/D [2098 0 R /XYZ 71.731 559.039 null] +2152 0 obj << +/D [2141 0 R /XYZ 89.664 561.196 null] >> endobj -2111 0 obj << -/D [2098 0 R /XYZ 89.664 543.263 null] +2153 0 obj << +/D [2141 0 R /XYZ 71.731 559.412 null] >> endobj -2112 0 obj << -/D [2098 0 R /XYZ 71.731 541.48 null] +2154 0 obj << +/D [2141 0 R /XYZ 89.664 543.263 null] >> endobj -2113 0 obj << -/D [2098 0 R /XYZ 89.664 525.33 null] +2156 0 obj << +/D [2141 0 R /XYZ 71.731 541.106 null] >> endobj -2114 0 obj << -/D [2098 0 R /XYZ 71.731 523.547 null] +2157 0 obj << +/D [2141 0 R /XYZ 89.664 525.33 null] >> endobj -2115 0 obj << -/D [2098 0 R /XYZ 89.664 507.397 null] +2158 0 obj << +/D [2141 0 R /XYZ 71.731 523.173 null] >> endobj -2117 0 obj << -/D [2098 0 R /XYZ 71.731 505.24 null] +2159 0 obj << +/D [2141 0 R /XYZ 89.664 507.397 null] >> endobj -2118 0 obj << -/D [2098 0 R /XYZ 89.664 489.465 null] +2160 0 obj << +/D [2141 0 R /XYZ 71.731 505.24 null] >> endobj -2119 0 obj << -/D [2098 0 R /XYZ 71.731 487.308 null] +2161 0 obj << +/D [2141 0 R /XYZ 89.664 489.465 null] >> endobj -2120 0 obj << -/D [2098 0 R /XYZ 89.664 471.532 null] +2163 0 obj << +/D [2141 0 R /XYZ 71.731 487.308 null] >> endobj -2121 0 obj << -/D [2098 0 R /XYZ 71.731 469.375 null] +2164 0 obj << +/D [2141 0 R /XYZ 89.664 471.532 null] >> endobj -2122 0 obj << -/D [2098 0 R /XYZ 89.664 453.599 null] +2165 0 obj << +/D [2141 0 R /XYZ 71.731 469.749 null] >> endobj -2123 0 obj << -/D [2098 0 R /XYZ 71.731 451.442 null] +2166 0 obj << +/D [2141 0 R /XYZ 89.664 453.599 null] >> endobj -2124 0 obj << -/D [2098 0 R /XYZ 89.664 435.666 null] +2167 0 obj << +/D [2141 0 R /XYZ 169.145 435.666 null] >> endobj -2126 0 obj << -/D [2098 0 R /XYZ 71.731 433.509 null] +2168 0 obj << +/D [2141 0 R /XYZ 71.731 428.528 null] >> endobj -2127 0 obj << -/D [2098 0 R /XYZ 89.664 417.734 null] +2169 0 obj << +/D [2141 0 R /XYZ 89.664 407.771 null] >> endobj -2128 0 obj << -/D [2098 0 R /XYZ 71.731 415.577 null] +2171 0 obj << +/D [2141 0 R /XYZ 71.731 405.614 null] >> endobj -2129 0 obj << -/D [2098 0 R /XYZ 89.664 399.801 null] +2172 0 obj << +/D [2141 0 R /XYZ 89.664 389.838 null] >> endobj -2130 0 obj << -/D [2098 0 R /XYZ 71.731 398.018 null] +2173 0 obj << +/D [2141 0 R /XYZ 71.731 387.681 null] >> endobj -2131 0 obj << -/D [2098 0 R /XYZ 89.664 381.868 null] +2174 0 obj << +/D [2141 0 R /XYZ 89.664 371.905 null] >> endobj -2132 0 obj << -/D [2098 0 R /XYZ 71.731 380.085 null] +2176 0 obj << +/D [2141 0 R /XYZ 71.731 369.749 null] >> endobj -2133 0 obj << -/D [2098 0 R /XYZ 89.664 363.935 null] +2177 0 obj << +/D [2141 0 R /XYZ 89.664 353.973 null] >> endobj -2134 0 obj << -/D [2098 0 R /XYZ 71.731 362.152 null] +2179 0 obj << +/D [2141 0 R /XYZ 71.731 351.816 null] >> endobj -2135 0 obj << -/D [2098 0 R /XYZ 89.664 346.002 null] +2180 0 obj << +/D [2141 0 R /XYZ 89.664 336.04 null] >> endobj -2136 0 obj << -/D [2098 0 R /XYZ 169.145 328.07 null] +2182 0 obj << +/D [2141 0 R /XYZ 71.731 333.883 null] >> endobj -2137 0 obj << -/D [2098 0 R /XYZ 71.731 320.932 null] +2183 0 obj << +/D [2141 0 R /XYZ 89.664 318.107 null] >> endobj -2138 0 obj << -/D [2098 0 R /XYZ 89.664 300.174 null] +2185 0 obj << +/D [2141 0 R /XYZ 71.731 315.95 null] >> endobj -2140 0 obj << -/D [2098 0 R /XYZ 71.731 298.018 null] +2186 0 obj << +/D [2141 0 R /XYZ 89.664 300.174 null] >> endobj -2141 0 obj << -/D [2098 0 R /XYZ 89.664 282.242 null] +2187 0 obj << +/D [2141 0 R /XYZ 71.731 298.018 null] >> endobj -2143 0 obj << -/D [2098 0 R /XYZ 71.731 280.085 null] +2188 0 obj << +/D [2141 0 R /XYZ 89.664 282.242 null] >> endobj -2144 0 obj << -/D [2098 0 R /XYZ 89.664 264.309 null] +2189 0 obj << +/D [2141 0 R /XYZ 71.731 280.085 null] >> endobj -2146 0 obj << -/D [2098 0 R /XYZ 71.731 262.152 null] +2190 0 obj << +/D [2141 0 R /XYZ 89.664 264.309 null] >> endobj -2147 0 obj << -/D [2098 0 R /XYZ 89.664 246.376 null] +2192 0 obj << +/D [2141 0 R /XYZ 71.731 262.152 null] >> endobj -2149 0 obj << -/D [2098 0 R /XYZ 71.731 244.219 null] +2193 0 obj << +/D [2141 0 R /XYZ 89.664 246.376 null] >> endobj -2150 0 obj << -/D [2098 0 R /XYZ 89.664 228.443 null] +2194 0 obj << +/D [2141 0 R /XYZ 71.731 244.219 null] >> endobj -2152 0 obj << -/D [2098 0 R /XYZ 71.731 226.287 null] +2195 0 obj << +/D [2141 0 R /XYZ 89.664 228.443 null] >> endobj -2153 0 obj << -/D [2098 0 R /XYZ 89.664 210.511 null] +2196 0 obj << +/D [2141 0 R /XYZ 71.731 226.287 null] >> endobj -2155 0 obj << -/D [2098 0 R /XYZ 71.731 208.354 null] +2197 0 obj << +/D [2141 0 R /XYZ 89.664 210.511 null] >> endobj -2156 0 obj << -/D [2098 0 R /XYZ 89.664 192.578 null] +2199 0 obj << +/D [2141 0 R /XYZ 71.731 208.354 null] >> endobj -1294 0 obj << -/D [2098 0 R /XYZ 76.712 174.645 null] +2200 0 obj << +/D [2141 0 R /XYZ 89.664 192.578 null] >> endobj -78 0 obj << -/D [2098 0 R /XYZ 182.984 140.174 null] +2201 0 obj << +/D [2141 0 R /XYZ 71.731 190.421 null] >> endobj -2157 0 obj << -/D [2098 0 R /XYZ 71.731 131.722 null] +2202 0 obj << +/D [2141 0 R /XYZ 89.664 174.645 null] >> endobj -2097 0 obj << -/Font << /F33 1278 0 R /F44 1994 0 R /F35 1525 0 R /F27 1180 0 R /F23 1173 0 R >> +2203 0 obj << +/D [2141 0 R /XYZ 71.731 172.488 null] +>> endobj +2204 0 obj << +/D [2141 0 R /XYZ 89.664 156.712 null] +>> endobj +2205 0 obj << +/D [2141 0 R /XYZ 71.731 154.556 null] +>> endobj +2206 0 obj << +/D [2141 0 R /XYZ 89.664 138.78 null] +>> endobj +2207 0 obj << +/D [2141 0 R /XYZ 71.731 136.623 null] +>> endobj +2208 0 obj << +/D [2141 0 R /XYZ 89.664 120.847 null] +>> endobj +2209 0 obj << +/D [2141 0 R /XYZ 71.731 118.69 null] +>> endobj +2210 0 obj << +/D [2141 0 R /XYZ 89.664 102.914 null] +>> endobj +2211 0 obj << +/D [2141 0 R /XYZ 71.731 100.757 null] +>> endobj +2140 0 obj << +/Font << /F33 1306 0 R /F44 2037 0 R /F35 1567 0 R /F27 1208 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2160 0 obj << -/Length 1859 +2214 0 obj << +/Length 1900 /Filter /FlateDecode >> stream -xڵY��6콿"�K������Ԯ:������A��D�c��ݯٯ)R�s�B7�AE�H'��gy��1,Q�GY:�v���N���b�$� ͣ������,�-׳$,�2��q�i4[�y?mž��|����>oM/�F��?6����?�{���q�E�Y�ͅbQ~T��~�$V������y���ً݈��<��F���@��ꡩ���z���$�2^t��d:�J�f|ڽ�)�;0���4<�B�/n�-K֬4�����Y��_r>�������jC�J���W+ը�@�;�o "���MMQ,F��~B'=�-)��$�Ek���?��f���W���A�^�֧��^-��B14��e���nޫ_����O�a{[m0HI��5a�]���rTm��6�V��av=* -�����X����/,��b��#AK;�x��^c#����\�]̣��0SO�3��Qj5��l{�[U�VPe7�W\�z��tK+G9�(N�Z�b%��\zw[Um�`́��: ���㩨��Ԁ��gaz�X��T�IRZ�"?�S߾9�A���XBS���y�zB� ��.���}R�h1<E1�c+�R�K��iG��<��K�� � �f�n����=�R����!\j�V���˵ �:i�u�{�����G�ɩ[�W�G��7W�-1w>Vr2�4�`���,"\; o賓m�� �z���o�dA�Vm���$��{�P�{a��ª �|���H2 � ��� -U��ekB�j�$��U"W�7x��㷗�Zw;�V�syXL�0�<|���l�}U�-]-�˰�t=4�Sc�5�:�~P*_3ɚVN������9�6��C��]��7G�@�,C�B�/Jg�(�3��+��[��8�E �E`�Q�(�~�st<xE���=p4����M^81 ��i�wG`��`�Q�L��D��vb��|��������=+<aY\�և�ɾA�>�۩fe����rw�nU�P�b���� G�,�+ȓ,%�5j�w�S°G ;P��3H�(*���l�Q���i ��,�` ���!�7(>�����2v�@�O�*��p" -É�'¿?y����|M+��A��y�x7���3�eC��a�V�"O�<ُ9�c�Wb���5�嵒���n8f�IǸ�2��E�Z����&�v�0�/axW*+Br������� ���*ʀ^v�e6�����J9)�2pV��Z"ھGƬ�EU���7��!5�v�hQsw!�2�C��0hZH ͡'�;c�ȧ ���t�u��'%s���&��&�c$O��D�$@�/� bH�/ژ�M�������@3 -��H�^�1��Ӕ���[��w���@_.�m�^�;�0�A��e1XO�O���������pB��z�&r:2 �U��6 ��5�p|fj>_���M O�PL���n�P����C���c�]�l��4u�1"'�x�"$<5!���O͵yg2��t@Ӡ����}��a�jZ�0ܮg�0N'���~����P��C���3t�1���\9|�xqd��)�t2h�GS����lb)��v�|بM��v��y�t��f����`��7/_����;/Ǫp���(Vr�c��B����t�!�0�����l���B � {ذ���q��5"7%1�0���k�}sim��I�#Suj���y�u6)�&pz'��iP{.t'&-�<�z�?�G������,����i��eΒd'8�Dc�����@��Z�óS�[���.�ں����駸�'��#M����Hr��]�~�\бŧ�����/+�:�endstream +xڥَ�6�=_�Ȁ����>e�I��w�E[�E�Bd��lܯ�����I�b��p8��-˙�?9�d�E��"Ti2����N^?��b�H�����/^EѬ�4��w�X�a�ͲH�y�f��ૃ>���/U"����������n��Uյ��������(4���ȣO���E��a��m��0S��<��xT]eՙ�S����ɋ0M�ل�u���ݕOʾb��_���`V���7l��E"��)��1��Y�ؖ�ep2]�Pc`ͤ�$A�K F/-Ƃ٫P� ��,���W��<�پ���~x�cUAw�3_FR{Q�U�0�Ե[c-nT��:�Sy��;&9��vf��%���X�fɦz{/�4��Lɗ���T� g�A���2����M9J������o�߀��%>�^��p�^�O#E" ^�e��#���m��v�++�� @9��6��CU���)�n.E���g�6m�%]�����¡�J��>��Q�q���[9�܃��b4�tj $�h:�篳��bz<��A���7v�r/��u�`S�m�0�b���8��1�͆��Fsݘre!�ql&o�-���=8ɭSdt�-�o0��`{ �t�e��æ���̨��?0į��K.v�h9��Nh�/y��0 `���חo���>�BޮYp1<��#����>O�0��8���@q�bEq���ȵn��Ƴ��Br�~B5&�cף� ����`��M��D�|��M�H���r8:ik�)mW.��5f�L2���ₚm+���k)�2e747L�z9�au��9ZL�}�{�і$�����c�`��i�q8y��:�(�T,�8�'�[�ҽ����f���n[��zF`�K�:�gj��TST��ͼv�Yϳ���"�c�sܸkTk�f+l?�{tW��eĤx97�d�3���;M�,0���w��'��VϫsG���o0v>n� +c�Qe�a�V��(���4\�ǝ ���oq�̡��'��q��[F���=0��I�\.>�7�Lܻp:5�BV`v���Q0CT�_}V rCE�V�� ���n����a�����%�d�Ŀ ���%�̃�P;\5&^}f��V]�/ɎW�"��My�}�O�����Om����@�4E�`�+Td��#Ỷ7+���l�T1P*x�E}?́=�l�����"8_����.���]��_m:�>Ĵ�8 ��QӸ�n��G�:=hڞ� �8Y.�)�U!@��z��@�ᅳ��q�om�ĉ��%`��|鬲�HI��'�js�SA�bg@�̮�Ax(�;�/ozA����t�&n(`G�!goHQ,���@]Y:��I}�p�ND�;q��D���/�}�Ŀ��J)���m.w�`�~�Um�2N6tf)�+%���C�F��GY� �1[M7�gĤs�ce-X�F��@�SO"��E +�� �yp�t[�nd䏈�GYQ����4�#�~�p�(Q�I�¿ +72h�^"�* �ӛPۺ��m��oHnN�u���QE��HK�\JG��A�Di=I$�YJ��7&�����Ļ:#��W�{�,�x��x����G���d�R���7f��47��P�?>hGA������>���y?�rN�c�R�@� o~��0�`0�؏R5i@�k@_0��K�Z�i� �C7��DN&��xHA(cߖ�XfJw�c��A��I[�i[��Ԗ�:d��t�;�������yD(�J[FB�(���yeoM<�9��G��u���7v8�������j��ĺ�{�����+��W�q�X�^��.�� ���?6�<g����{Θ�v�~?�j��쓿�]H����DQ(����ӏfO%� �&�endstream endobj -2159 0 obj << +2213 0 obj << /Type /Page -/Contents 2160 0 R -/Resources 2158 0 R +/Contents 2214 0 R +/Resources 2212 0 R /MediaBox [0 0 609.714 789.041] -/Parent 2059 0 R +/Parent 2102 0 R >> endobj -2161 0 obj << -/D [2159 0 R /XYZ 71.731 677.36 null] ->> endobj -1295 0 obj << -/D [2159 0 R /XYZ 71.731 644.419 null] ->> endobj -82 0 obj << -/D [2159 0 R /XYZ 242.807 611.108 null] +1328 0 obj << +/D [2213 0 R /XYZ 71.731 741.22 null] >> endobj -2162 0 obj << -/D [2159 0 R /XYZ 71.731 602.656 null] +2215 0 obj << +/D [2213 0 R /XYZ 89.664 708.344 null] >> endobj -1296 0 obj << -/D [2159 0 R /XYZ 71.731 559.138 null] +1322 0 obj << +/D [2213 0 R /XYZ 76.712 690.411 null] >> endobj -86 0 obj << -/D [2159 0 R /XYZ 167.419 525.828 null] +78 0 obj << +/D [2213 0 R /XYZ 182.984 655.94 null] >> endobj -2163 0 obj << -/D [2159 0 R /XYZ 71.731 517.376 null] +2216 0 obj << +/D [2213 0 R /XYZ 71.731 647.488 null] >> endobj -2164 0 obj << -/D [2159 0 R /XYZ 71.731 504.742 null] +2217 0 obj << +/D [2213 0 R /XYZ 71.731 580.125 null] >> endobj -2165 0 obj << -/D [2159 0 R /XYZ 71.731 489.798 null] +1323 0 obj << +/D [2213 0 R /XYZ 71.731 547.183 null] >> endobj -2166 0 obj << -/D [2159 0 R /XYZ 91.656 468.643 null] +82 0 obj << +/D [2213 0 R /XYZ 242.807 513.873 null] >> endobj -2167 0 obj << -/D [2159 0 R /XYZ 142.208 468.643 null] +2218 0 obj << +/D [2213 0 R /XYZ 71.731 505.421 null] >> endobj -2168 0 obj << -/D [2159 0 R /XYZ 76.712 440.349 null] +1324 0 obj << +/D [2213 0 R /XYZ 71.731 461.903 null] >> endobj -2169 0 obj << -/D [2159 0 R /XYZ 71.731 420.423 null] +86 0 obj << +/D [2213 0 R /XYZ 167.419 428.593 null] >> endobj -2170 0 obj << -/D [2159 0 R /XYZ 373.496 408.767 null] +2219 0 obj << +/D [2213 0 R /XYZ 71.731 420.141 null] >> endobj -2171 0 obj << -/D [2159 0 R /XYZ 193.02 397.111 null] +2220 0 obj << +/D [2213 0 R /XYZ 71.731 407.507 null] >> endobj -1297 0 obj << -/D [2159 0 R /XYZ 71.731 369.215 null] +2221 0 obj << +/D [2213 0 R /XYZ 71.731 392.563 null] >> endobj -90 0 obj << -/D [2159 0 R /XYZ 210.827 333.748 null] +2222 0 obj << +/D [2213 0 R /XYZ 91.656 371.407 null] >> endobj -2172 0 obj << -/D [2159 0 R /XYZ 71.731 325.296 null] +2223 0 obj << +/D [2213 0 R /XYZ 142.208 371.407 null] >> endobj -1298 0 obj << -/D [2159 0 R /XYZ 71.731 294.73 null] +2224 0 obj << +/D [2213 0 R /XYZ 76.712 343.113 null] >> endobj -94 0 obj << -/D [2159 0 R /XYZ 207.683 261.42 null] +2225 0 obj << +/D [2213 0 R /XYZ 71.731 323.188 null] >> endobj -2173 0 obj << -/D [2159 0 R /XYZ 71.731 252.967 null] +2226 0 obj << +/D [2213 0 R /XYZ 373.496 311.532 null] >> endobj -1299 0 obj << -/D [2159 0 R /XYZ 71.731 235.353 null] +2227 0 obj << +/D [2213 0 R /XYZ 193.02 299.875 null] >> endobj -98 0 obj << -/D [2159 0 R /XYZ 234.008 202.042 null] +1325 0 obj << +/D [2213 0 R /XYZ 71.731 271.98 null] >> endobj -2174 0 obj << -/D [2159 0 R /XYZ 71.731 193.405 null] +90 0 obj << +/D [2213 0 R /XYZ 210.827 236.513 null] >> endobj -1300 0 obj << -/D [2159 0 R /XYZ 71.731 175.975 null] +2228 0 obj << +/D [2213 0 R /XYZ 71.731 228.061 null] >> endobj -102 0 obj << -/D [2159 0 R /XYZ 206.297 142.665 null] +1326 0 obj << +/D [2213 0 R /XYZ 71.731 197.494 null] >> endobj -2175 0 obj << -/D [2159 0 R /XYZ 71.731 134.027 null] +94 0 obj << +/D [2213 0 R /XYZ 207.683 164.184 null] >> endobj -2176 0 obj << -/D [2159 0 R /XYZ 415.651 123.736 null] +2229 0 obj << +/D [2213 0 R /XYZ 71.731 155.732 null] >> endobj -1301 0 obj << -/D [2159 0 R /XYZ 71.731 103.646 null] +1327 0 obj << +/D [2213 0 R /XYZ 71.731 138.117 null] >> endobj -2158 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F44 1994 0 R /F35 1525 0 R >> +2212 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F44 2037 0 R /F35 1567 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2179 0 obj << -/Length 2420 +2232 0 obj << +/Length 2233 /Filter /FlateDecode >> stream -xڝَ��}���<X �h���k��5��:;I؆�������%�L�>uI�>< ��,�T�.�`�M���&�* a0�2I�)ۻ`��/�ӂ����y�p���a��U�����&ҙ��M��f�P��}s(������(�wn,����<;��S7M���ỻw�8LU����5�\ f�*�c�lV0�TE$�QZ�*C����� �˭���lQ���� �������r��Qi�͇��]Q�t��N�`��������w�C�����T���/��� -Wt#�ƞ��]���?�I��vkb� $��?<,F����4�s����v��}%ߏd(�`E��CÐ-X�OĖc��<L��i,xh{������*Y��C���p�c"��a���L9�E�0��̀bѹp>�7�|8%{�Ax����7��J��X�̇�8+{�]�4aڋ~#�E��������uS�/��S�뷬���ō�]!,G�9-�,&`ԍ5N1�3���.���'�X���dY���AoP�7�b����nЂg����4Dh������0��@��������N�V���=o?����� ��@;{˾ŏ�Ǝժv� -9�,��98:���q��x������w7�{�2D}��}�5I̖j�s�/G��0���8�)�K5�A���EH^�sj���G;Q��X�a��fd2� &�f���=+^�!�n�n۠�B�dMI/�z���{� p2���1����w �������,㑦��T<mm!�C12���xk�¬�c�n����a3��F�ë�& -�(��$��=/����#%U�Y{�sJ:����AX�{ #��xR� /��@�p�B&��|2�,Q��[��o��=rVp8�`<3&D��R٦��Z{tz��/�}H���������:!�q��4��&T��[ y��WH���Q�*�ɖ'��J_2�����k�g�W�_B��:��!�6@Qe��_)����u7=����5���� .�܇�9���z�WB� O(�Hl��Ɯ�8"����3)�� "��i�Lj����=O?�n���2��.�$��e���M���h!�R~Oهa�Z: �?@�a���Y�ղWR�}����]�,���=���Q����b��� ��p5�V�T,(a����6;5&�s�5��I&�l��x�Ǧ��*�0{��C��yJ��w�,�x�� �@5�G�����m1@� Tb=ZUĻ)(����8U��pC�G;>Y{�K�S��B<��S1����� �\�����i������C{�J�x�b����H���ꥒW���b\��mz�Q0�G�� �x���s�ôTnr�X=�J�&�*�y.�D�S!7�wn_���M R3Z��p����R�����-k��<?�3�����ΞрT��;�,�Z.<��Ӕ���;�ϰ�����IJ0m����u��|�ڬsQ���Ҕ��A�:�������\-9�<� &��E�O�|���v����7NmB��>-İHV���B�kG���ҹ����Ѓ��ʛ���J��5y�������1��]���/Te`J~E+-E�|��� �thR���*�5�a��_r��8vgX)���1���v��bQ8t7�{i1�"6u\�ݺ�wg�#S̻���Ɲ��d��o�r���p�W�I��T��VdN�[?@�ѹ�[��5}��g����2:�1�1ϥ5Ҍ~s����֡��hc�b�A�j�r�������;��7�=�!r��F�<7����>���PB�e�k4x��]��gi|��P��gO*K� �� -�lc�B�n������I3p^v�:3*B�t3������V�y�W�͟�އ�O?|�`"���3������^W�XG�x��$#�t����qq˻�2*"��8Y��F�ù�j��Y��9B��>b��bp,�'����-'6�� �T�S���SK��a��S����BoH��D�`�^Y5��{F:_ZdzC]U�)��'zj��"����/��/A)����(4��Ҵ�s;Y����3|�.���"����������_!]u���_.�{t�:��6��Zp^g�%p��3ֻu���vn�.�Y��ν-V?�\>�F!pݬn��Q�0���G�u� U%�C����8Q:�Kh��<M_�8�ݿ�����|�<v���1�0>�į�ᷮ�`��Ύ�Q�k��Q��q��_��%���c��Sr��,�] ��f�@U�'|~Wv�2��i8@�v��<�� �67�U��`%�����c���o�3��R__�`�mrhQ=v��O -'��_�0TA�PA��o�Jp��\aqendstream +xڥX��6�������Z�[��S�K��h|w�CAK�M�^��n���ey�Y=,�R���p�7C�����U�yCT�Q����U�:�_�±�͂��ݫ����U�Y��VI���|�Ǒ�M�ծ��{{R����&J/�y�����k�y��t��ԵZ�g��W�v�i���6~Q/��L�(^��_�)j��~�$�Y�~�g�R�������n��^���0��oA�v�#�!�����j�6G�ܝ4���4Xm�j���X��~djX���c2������c71q�O�"�8��dJU�v�w�h}�qi<(�~��s������{s�?�.'j�D��l1�d1�b1P�F���r��-ba1��N�4u>��=*<��rp�.ЏL��h�ehB��`�X����������Y�'ۭ��r0������#�7�ӓ`����!m..�l�q��2�_��ԓ����t:��p:���A�q�7O��QO��ݵ�y����NҴ1[�\����m.4�I�F�WV���En%?����o�noߛQ��\�I�MPd�.D�nվ֖'ୁ�zhfXߡ�������^$���֚}�棌<���RCe��;ǕcN�覇O���<���;� ��d�(����5D��绷�����d�jӃ(5�.���|�[Z��OF1��nwG�Qҗ^X!v��A�X�Χ���(��`K�6��A����(X��hJ28���K]V!ˁG� !3 +y9�g��_�F��Ի ������s��L�R�=u��geW���坴a�+w��H��aB;�<�r 6�Z2h� +��ޕ��fq� T�L���$��;u��25S߃j-E���7�W8me��n]@�~����#���-*_�{�V��RH&�`(��'th���6.����"��a���v��@3��1O�����ˡq"�'{p7*��E���IvG)���Y����nԷ� ���쁟��tEe�������g��ǐǕt������yۏ��������.<E_0����z��Vƪs�i�$~�p;��7��q��y����9$��v��%cH&�G�@��� `�:0Ey���0�-"R ��!���.���7����UOB�pŊXin3� �٠&!��1@+^9��n�vߠ�"��MQ)�7T�i�����ή�GE��������K�J*K�[��dZ�|di7�O�D�xR#S�Ү�Nc-S��z�q�Kߵ��a�ۉ���/�'�ҕ�)��D_��%����e6�`V���m7��s�"�k1����2.e���@��N��OV� "Z����+]աG��=�����U��0{�*0��0��}�z������*|ȷ����,����D����菺<�-�ç�'AB/��w</�T�?G�MA�� ��O������=�"`CV>\�� �TI#�+������P�t��}�'��JD��rxy��j�^#"H���#oxz���?���f>H�@�{0 Sj�l����SM_s��9�a�� �?@�a���+N��+���hZ%��ٚ�Rnx�IGMN�؋K�A�����\zE��̈@6���!��kMis���Iw=]^�o��VXTe��f�f<15�����0����q�g�#��a[�����P?4�(�"�^��O���ήE*�$��S/iOWnw��{�ϝIsƟ�/ ���A�H�`�(�F�+�.B/�w�`�����3�x�9J�I��OI��_t��<�I��ˈ��C���P�kQ�s��w�k��IVj�7!gS�M+�kϭ�S����e�QZJ�!8Q~D�4k˯�ץ����S"�/ �S�Y}!J5����" +�����2P=n)�a面��ĺ����w��������b�yZ�����qH�L�{���9uE-\�n���2�H� �����S�lAP��,j�`�pì�gE<��@QKVST[L�����7���ʨ���|����1 -�:�d�K��%��p�<�ox��X�פ�h���)H���/l>�K!�c{���#��@p��6V( +����b�������}f��%W�]���JN���d�8fSs�+�q�k�{R5�����Ul��X�P����z��^�8�� ��"�l�m��������i�A0KA7����I�DY�endstream endobj -2178 0 obj << +2231 0 obj << /Type /Page -/Contents 2179 0 R -/Resources 2177 0 R +/Contents 2232 0 R +/Resources 2230 0 R /MediaBox [0 0 609.714 789.041] -/Parent 2059 0 R -/Annots [ 2187 0 R 2194 0 R ] +/Parent 2102 0 R +/Annots [ 2244 0 R ] >> endobj -2187 0 obj << +2244 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [359.873 521.928 404.731 530.41] +/Rect [359.873 317.893 404.731 326.376] /Subtype /Link /A << /S /GoTo /D (parameters) >> >> endobj -2194 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [244.495 198.627 283.866 207.109] -/Subtype /Link -/A << /S /GoTo /D (security) >> ->> endobj -2180 0 obj << -/D [2178 0 R /XYZ 71.731 729.265 null] ->> endobj -106 0 obj << -/D [2178 0 R /XYZ 225.412 708.344 null] ->> endobj -2181 0 obj << -/D [2178 0 R /XYZ 71.731 699.891 null] +2233 0 obj << +/D [2231 0 R /XYZ 71.731 729.265 null] >> endobj -1302 0 obj << -/D [2178 0 R /XYZ 71.731 659.362 null] +98 0 obj << +/D [2231 0 R /XYZ 196.159 708.344 null] >> endobj -110 0 obj << -/D [2178 0 R /XYZ 287.71 622.147 null] +2234 0 obj << +/D [2231 0 R /XYZ 71.731 699.891 null] >> endobj -2182 0 obj << -/D [2178 0 R /XYZ 71.731 611.782 null] +102 0 obj << +/D [2231 0 R /XYZ 206.297 648.966 null] >> endobj -2183 0 obj << -/D [2178 0 R /XYZ 71.731 599.866 null] +2235 0 obj << +/D [2231 0 R /XYZ 71.731 640.329 null] >> endobj -2184 0 obj << -/D [2178 0 R /XYZ 71.731 584.922 null] +2236 0 obj << +/D [2231 0 R /XYZ 415.651 630.037 null] >> endobj -2185 0 obj << -/D [2178 0 R /XYZ 71.731 533.585 null] +1329 0 obj << +/D [2231 0 R /XYZ 71.731 609.948 null] >> endobj -2186 0 obj << -/D [2178 0 R /XYZ 211.436 523.816 null] +106 0 obj << +/D [2231 0 R /XYZ 209.082 576.638 null] >> endobj -2188 0 obj << -/D [2178 0 R /XYZ 71.731 495.92 null] +2237 0 obj << +/D [2231 0 R /XYZ 71.731 568.185 null] >> endobj -2189 0 obj << -/D [2178 0 R /XYZ 71.731 439.034 null] +1330 0 obj << +/D [2231 0 R /XYZ 71.731 537.619 null] >> endobj -2190 0 obj << -/D [2178 0 R /XYZ 71.731 406.092 null] +110 0 obj << +/D [2231 0 R /XYZ 225.412 504.309 null] >> endobj -2191 0 obj << -/D [2178 0 R /XYZ 71.731 351.362 null] +2238 0 obj << +/D [2231 0 R /XYZ 71.731 495.857 null] >> endobj -1303 0 obj << -/D [2178 0 R /XYZ 71.731 321.41 null] +1331 0 obj << +/D [2231 0 R /XYZ 71.731 455.328 null] >> endobj 114 0 obj << -/D [2178 0 R /XYZ 218.078 278.312 null] +/D [2231 0 R /XYZ 287.71 418.112 null] >> endobj -2192 0 obj << -/D [2178 0 R /XYZ 71.731 274.482 null] +2239 0 obj << +/D [2231 0 R /XYZ 71.731 407.747 null] >> endobj -2193 0 obj << -/D [2178 0 R /XYZ 118.555 232.292 null] +2240 0 obj << +/D [2231 0 R /XYZ 71.731 395.831 null] >> endobj -1304 0 obj << -/D [2178 0 R /XYZ 71.731 188.665 null] +2241 0 obj << +/D [2231 0 R /XYZ 71.731 380.887 null] >> endobj -118 0 obj << -/D [2178 0 R /XYZ 187.345 156.161 null] +2242 0 obj << +/D [2231 0 R /XYZ 71.731 329.55 null] >> endobj -2195 0 obj << -/D [2178 0 R /XYZ 71.731 145.796 null] +2243 0 obj << +/D [2231 0 R /XYZ 211.436 319.781 null] >> endobj -2196 0 obj << -/D [2178 0 R /XYZ 154.51 136.036 null] +2245 0 obj << +/D [2231 0 R /XYZ 71.731 291.885 null] >> endobj -2197 0 obj << -/D [2178 0 R /XYZ 338.14 136.036 null] +2246 0 obj << +/D [2231 0 R /XYZ 71.731 234.999 null] >> endobj -2198 0 obj << -/D [2178 0 R /XYZ 71.731 123.917 null] +2247 0 obj << +/D [2231 0 R /XYZ 71.731 202.057 null] >> endobj -2199 0 obj << -/D [2178 0 R /XYZ 71.731 123.917 null] +2248 0 obj << +/D [2231 0 R /XYZ 71.731 147.328 null] >> endobj -2177 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F44 1994 0 R /F35 1525 0 R >> +1332 0 obj << +/D [2231 0 R /XYZ 71.731 127.338 null] +>> endobj +2230 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F44 2037 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2202 0 obj << -/Length 2851 +2251 0 obj << +/Length 2655 /Filter /FlateDecode >> stream -xڝk����� -�Z�Rq���}���i�<�&�})àV<i�}y�kE����W+�rp�ÁCrv8�7G�?��" a2�r�Ww�b;�����f�������0\d"�����"�S�%�$D*�������A�Fw�u �e h���*ˢ���հ��(K�z����?�Ce��, ������3c�~^*�(��=�N�å)*��G�e�n��2���A����6C+ڒp/���p�C3�;��˒�S3 -�AZRn�4y�u:7�X��e�J��\u�U��4��j��#�+��T'���*��j�$Զ���b���@�~ 2�����h� �x^P�^nٹ!Dߓ`>K�l�1o�b?��̄���Ɇ�J�>���!Ќ��N?�|`o(��([����=5���Pm�a6OW�hg��T��z{���������D�c�PVa�Xf���i�w�]a�)�-a����M]��� -$�ǠǏY�o�3��L��j �0j��(f������9��n��U}�����vD�6ߒ�8�zݝٴ�["�id��'���F���'��;�,T�Z��OE��� ��<`�E�.a�Oz#龨ڲ�sZ�r�@���M��U��"[����[m�ih�?�r~��;����y>-���j;��I��u�ɖ<6��J�+��`�zn��S������ή4�M�����"!3��z:�j��[E�n��'"�OD���/�%�|�Լ�k0l!d��lvCM+E}q�ly�Z����0#h��5�N�,K�t|���z[��>�QxK�\��@㚷^Z�<��j��Ѹ�����S��1�{�=њ5pl,Ɲ}c���Ԍg��9�i��0UԚ&(���hga�J@�8�l��pP+ GR�����t���=��/������0���4��Վ�Gԫ=�� �i���f� ���9�O�hq�N�,��әm�I(/�m3��t�:�����^pa.žn��������ω�&��,�����(p��E����iе�qs֘�%�.�1K�_v��� A'`��54���Lę��)�Ub0<�+F�8X6�)�ms'�-���`v�,�E�$u�P^�c��/f7��vM>T�����XڞƳ������V�(�� -s丂�M/h����b���E�F_�J��'<,b'fQ7�ʩz�:�yޜ���#+5�@� ���ʎE`55\���eE���3��ӗ�h�NK��c6�����@{�C�(w�dΒ�A����ᕑG�#`��Z�'�2g��`�ۮ��1��5 �s��hZ�)�wꍮz� -�o�Ke lW|(�k���,t1ɖ��H�������b��W����ر��<��a���\Y�A�ۓ�z�5��TzͨO�~I\�m�̓���k����v�����$��5戙Å��^|Y�� -]8z���� �H$t��٭�I{�Q��"�� 0�ѩ�^ady���%�^ ���.��ԉ5�ޢ̀��@$����K,���r-LvL��caABI���d��h�;3a靋���08�3e��M_��q�KFXs�!�����%���/�8�v��p���k�� -��T4$�`�\�D/��p8�2pM��:T�d\1U]8��`� �}��zKP~���E$��Ip�O��� ���&t)(�p����D -��s8�g�&4 -��.�sv�*�(ն���A�i��з(|E�����&�ӹ���]�����ca�g��.�ή�����D�qv^64�g���-��i��`L����lt)��P$�M�a��WP⦍v�ؘ�)7���l�9^�(�-�j��eB�K���pr3z/����D���1�1���!F3�N�yW�lmqFi3v/c�&�B���`F�Lq ���5�M*���g�뮅�הa/�R�{�j��^��Ȅ�m�9j�zXӄ����e�A�-�LM��§̦�<�8e�Jiw�0�xӉ�<CQ�:�`k!��a棳~�{��[������_��x��Q!�p<�;�x�{{��H ������9�-��H�7��*��;��4�B�A� =�7��k5V��(:�����H;qHr!I@Q�|�BY�[2�m�е�p�3m�C���A������T:::����=x$r�R��o�O��� YL/uM�"~#�<�A�!$<6�=�q�?\�6�M�����o����,��Ph���ұ:�YԪ���g��K�V�����u��_�2�ꤺt -E������;X���5"!f�bbn�r��a_�ϻ��b��s��Y_>���d�������,�$�4-U��gۄF��4����}�WU#9�cY�˺H���k�Ji �����6��a� �q�Öv��V��w���>[a��x��6S��cY0�k�������U;���������F�$�W $��{�ݭ.�/�t���6��:��~���c�>p1�Kz��`N�<A�c�����*w��ۜ}�/�u�Fr$UdՃT�xA}��77�T� -������f~'xш$�v��|�;���@R<��[\Q4L���Z�8i9���;/������^�R?u �W������T�"L�8���tMٻuf�*����a0(R�hK�0&6Isl ������bq�ZlJ�sk��V`��2���.lOd����"�P|�tH���#9+J.�):3�\��qn��A:H.:�i��i��l�p>�=M�3���Ϯ�6��(��<���e���Rx�;"ȣ������n���endstream +xڝYm�۶�~�Bs��s� ���d;M�4�&��t:I&C��Ě"e�XU}��uҝ��L`����+���O.)��� G�b�/�X��NZϢx3���w���E&�8X<n�LE�,�@�4R����]~t��T�/�����-�ߎ��Uu��~y���/�ӥQ��, ^���\���E�D�{���4��2%�#���� �'�̬m��o�_���L����/<��"s���q��z�f˦]�hyd���j]k� -�t+�;�8����Ǖ��y�qlJls =A���c�\%!�4]D��t��H��h晸��!/vZ\��B�/<t�����%;/�j��U��}��8V��谅DJDA����,bi�u3��-�g����� ��i.��na�v�╌2�_Ul���x��b��G>K �Bs�2�J�ã��������;�&엂�*�L�2��j[���r��<Q"I���#���A��t��|zŚ������*v<+���]y�蒡R�vϓ�0^�zE4��U��z���V�ўx ar���T���v��RdY�+�3�ě��q�����w *"_����kz1K����\�u��h�3�����,�F��Z��;���v��i�C�8����<0b3k{�+�Z[T{���֭k!�%��o{��1���'�9�Qp�_W��������/͊nxc����<� � +��>v-�_������R����|��9Zz������}QH��]��41bFc�R�zec�������v���$I�( t�O)�|���Q"$}�����xG�!�_�d��`�����ǻ����8�w~��k��1^W)3u;�A�"��E�%���B� �M��YX``*c���yX��e�O^1�ɰ>��?���w4���lA#'+�؞A�|�|h0|�fȶ�,\ꆧ�0��|����ތum�B�j����]�{w�E��[y?�-*���Z�Q�d9�|'�b��^#��N:�����b���ێU��Zh��k{�K�>X��Ǒ�!��o��_��Òܡ \vY�&Ȁh?�k�i��t��^�x���[zY��"�;���y���-�}q^ٴ�y����S�Qa(�,BN��ӛ���fHF���������WW��Sl~�j����i3�.�>&�R����u�i��Dk�cա'�7p�bfտ�A��/�c���殆�f�b~"�$2�<���S�E^;��|������4ҦW�v���?'Ҝ�]���R"Cj��ƃ8�ȋ�>�������j\nY�l��ۀs��bSNJ`���,K�.�y���Cr���_�����K�z�P�扷�����PXy�1�EB^���72`��Q��gX�YtO!�r{���<��F��N ��y�cd��DIgk��1:I������n�]/E�u�qOY'3�̹ �<%�c;8V����u~���Gɷ��| ?�t4*����Sz���Ť��I}U۵¦k�z�G(���8��T7�����|[A?N�yq[ې[v��*�RoL�1�Dh��% ���i���q�v���.s?D�|��z{W�đ)�� �wmN� +2gLM�bl��'�=iԅ�%��+x�Yܶ�O<2�1�G=m����!�:��X�k�.�� +K��:�DtX�˛���R��r�+R���=Ů�tmg_�l��&�;2��j"]�p9hf�"Ei9��dF�/��9,_�|_+�O?t�)��x �*��z:�G�����M�������������H�ck��(qq�� 6�M��q��.w���o�c�X�����E���q={���� +h3e!8��ZWԣ�y��^Cf� ���[� +#�}�Q�$"���U>�E#*����t�i</[SE�3�ȤHf Us�lyυ�=�m;#x��U"p_��_�u�S$�d= +L6*��C��.q5ƫ��g�!��-��G�m�{^����� Ì����bZٶ�cNj�;0��13ū26��iG@7.�Vv�֦p���UR�\i!����ky-= ��-�#�:hf +��v�h�Ӟ(ȹ���Hr5�����&�-�vlR�ƛ�s�X��Ev8�%nj�+����D�59?�?8�6��i�ե�6m7�ͦ�a{��9P��}#�����| T.�Y�P�7�mG���S̚uD�K�4�\v���Y5�������d"��b�S8��P<��<a����)�6�ssR�Fp��,j���c�ũ�Z6����p����ܨf-�>MwW�E�~�yC,8���X�{�!s$|־X>5����h���편m�/|���Ԣiﲷ��|I���'"�f�{'�c��.�6St���q�gp+m�qLz褄�=E�?�ϒr��<��Au?SF- +n\di��&���1h���n�!ά��<>t�g����1S������?2�^��SP��+�u>�m��kl&�Jt)��ލ��Y��� $Ŏ$��َ� ��k�5��mU���Yr��P7���䢿Ë����� ��?�J�yr7���:�ݬ�P�"�S�����=LWX��J�W�E ����䓶�z�%Y���4R�{R���7�L^���r��Y�P�)wQ&��~����vV,endstream endobj -2201 0 obj << +2250 0 obj << /Type /Page -/Contents 2202 0 R -/Resources 2200 0 R +/Contents 2251 0 R +/Resources 2249 0 R /MediaBox [0 0 609.714 789.041] -/Parent 2059 0 R -/Annots [ 2218 0 R 2219 0 R 2224 0 R ] +/Parent 2102 0 R +/Annots [ 2265 0 R ] >> endobj -2218 0 obj << +2265 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [474.449 466.366 534.665 475.278] +/Rect [244.495 455.18 283.866 463.663] /Subtype /Link -/A << /S /GoTo /D (mysql) >> +/A << /S /GoTo /D (security) >> >> endobj -2219 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.123 453.415 202.898 462.326] -/Subtype /Link -/A << /S /GoTo /D (postgresql) >> +2252 0 obj << +/D [2250 0 R /XYZ 71.731 729.265 null] >> endobj -2224 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [308.275 283.326 353.582 291.916] -/Subtype /Link -/A << /S /GoTo /D (security-mysql) >> +118 0 obj << +/D [2250 0 R /XYZ 323.661 707.841 null] >> endobj -2203 0 obj << -/D [2201 0 R /XYZ 71.731 729.265 null] +2253 0 obj << +/D [2250 0 R /XYZ 71.731 697.476 null] >> endobj -2204 0 obj << -/D [2201 0 R /XYZ 71.731 718.306 null] +2254 0 obj << +/D [2250 0 R /XYZ 284.618 687.716 null] >> endobj -2205 0 obj << -/D [2201 0 R /XYZ 113.898 708.344 null] +2255 0 obj << +/D [2250 0 R /XYZ 378.557 687.716 null] >> endobj -2206 0 obj << -/D [2201 0 R /XYZ 177.702 695.392 null] +2256 0 obj << +/D [2250 0 R /XYZ 231.401 674.765 null] >> endobj -2207 0 obj << -/D [2201 0 R /XYZ 71.731 688.254 null] +2257 0 obj << +/D [2250 0 R /XYZ 71.731 667.627 null] >> endobj -2208 0 obj << -/D [2201 0 R /XYZ 263.826 677.46 null] +2258 0 obj << +/D [2250 0 R /XYZ 144.509 656.832 null] >> endobj -2209 0 obj << -/D [2201 0 R /XYZ 71.731 657.37 null] +2259 0 obj << +/D [2250 0 R /XYZ 373.384 656.832 null] >> endobj -2210 0 obj << -/D [2201 0 R /XYZ 229.324 646.575 null] +2260 0 obj << +/D [2250 0 R /XYZ 71.731 637.116 null] >> endobj -2211 0 obj << -/D [2201 0 R /XYZ 444.938 620.672 null] +2261 0 obj << +/D [2250 0 R /XYZ 71.731 607.796 null] >> endobj -2212 0 obj << -/D [2201 0 R /XYZ 178.998 607.721 null] +2262 0 obj << +/D [2250 0 R /XYZ 193.672 595.064 null] >> endobj -2213 0 obj << -/D [2201 0 R /XYZ 71.731 600.583 null] +1333 0 obj << +/D [2250 0 R /XYZ 71.731 577.963 null] >> endobj -2214 0 obj << -/D [2201 0 R /XYZ 169.98 589.788 null] ->> endobj -2215 0 obj << -/D [2201 0 R /XYZ 71.731 569.699 null] ->> endobj -2216 0 obj << -/D [2201 0 R /XYZ 450.823 545.953 null] ->> endobj -1305 0 obj << -/D [2201 0 R /XYZ 71.731 525.863 null] ->> endobj -122 0 obj << -/D [2201 0 R /XYZ 224.186 488.648 null] ->> endobj -2217 0 obj << -/D [2201 0 R /XYZ 71.731 481.295 null] ->> endobj -1306 0 obj << -/D [2201 0 R /XYZ 71.731 453.415 null] ->> endobj -126 0 obj << -/D [2201 0 R /XYZ 266.299 421.101 null] ->> endobj -2220 0 obj << -/D [2201 0 R /XYZ 71.731 412.463 null] ->> endobj -2221 0 obj << -/D [2201 0 R /XYZ 247.769 402.172 null] ->> endobj -1307 0 obj << -/D [2201 0 R /XYZ 71.731 369.131 null] ->> endobj -130 0 obj << -/D [2201 0 R /XYZ 156.121 335.821 null] ->> endobj -2222 0 obj << -/D [2201 0 R /XYZ 71.731 333.346 null] ->> endobj -2223 0 obj << -/D [2201 0 R /XYZ 118.555 296.798 null] ->> endobj -2225 0 obj << -/D [2201 0 R /XYZ 71.731 261.815 null] ->> endobj -134 0 obj << -/D [2201 0 R /XYZ 221.647 234.791 null] ->> endobj -2226 0 obj << -/D [2201 0 R /XYZ 71.731 227.593 null] ->> endobj -2227 0 obj << -/D [2201 0 R /XYZ 173.289 203.907 null] ->> endobj -2228 0 obj << -/D [2201 0 R /XYZ 71.731 191.788 null] ->> endobj -2229 0 obj << -/D [2201 0 R /XYZ 71.731 147.605 null] ->> endobj -2230 0 obj << -/D [2201 0 R /XYZ 282.227 123.11 null] ->> endobj -2231 0 obj << -/D [2201 0 R /XYZ 71.731 108.002 null] ->> endobj -2200 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F35 1525 0 R /F23 1173 0 R /F44 1994 0 R /F48 2006 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -2234 0 obj << -/Length 2455 -/Filter /FlateDecode ->> -stream -xڕY{s�� �?�B��L����[d2�Ԏe�[�Ne�k.7�ZY���:�O_`�%)SI���}�,~���� �d7nL��=y���W����`������Mb��d���N$��d�" -��j���a�씬�37�-W���lT��Y�D�����,ϓ�o��Z�:��7q�}S/3f���M@�0D�bG�A8�ۑ�|_+v[)��^��=XǬ�Y��ֺ�L��""�l��m��̱R�gOD\f9Lp�+���B���Q�ĬSK"U�r��pլ����ĩJ�ɚ��e���a��y�u��Ǥ�SǷ�V[�ո�Ɍ�;s�@s��"��SǶ��GV���;��"�DVZ����4���!wɲ#�M��H��U�� �P�.�QLRH< p�#�O��� &���9)W�?Z�,�+T��-�h���C�U�Yk2Odm�<�)���Lך�ګ ���{]l�ΚGZ��_|�Zˍ�E���T ͢mQ��� �s���M��D�ۤNR�O������@��i�:��wF��]��N�s`}�߃Q�u3�]��4���`�k��Tul�FW��!4�+b��4i*�τ>�� ���n5;X�J�϶���Z�zo��{�o�5�\�P#+Ӽ]wP�:M_s��ڽfM�5��:{-:�ѝ��L��yv[(�@y�Q������E&*���:��V O�B���o#����p�Qt�ڃ����>��8���+�2+Z�He6�ڳ)�Nr�f�b�n+�@i�]��J}�h[�)�:��;?�`���\m�?ft=�*=-�"-7�`�G&i -��kW�M��I�˥Q �EHp��c=`L(\���b�X���7��u����]���h��d�A��$�eh;]0����_ds�0a-z]��~� 1s��B���P�Z�ǩ���d�a�G�E���4�<���9��DV��L[��De��T�(D/�n�ڽ==}~~���%��DZ�0�T���`$��l�ّè�v!��ȏ$� > -�����9�$& i<�+")�� -���L���u) 2c���J��H�:_�04�5�jS11����0P���k��p�5M���Ù���_��G��L�21Я���T�h���s�3+=?�a+9��`΄�P�m���!f�4pph�2� �!��($�8�r��`w���qA,����w��4�k�h����uP>y1�}2���hX�>�ČH�ٮ*�.�$�]]��,Q�6� ���6+�J��0�� �w�`� �)m�����L|�"��������Ȇ�c�~��H���46���U���@>#豪� Q�>��r!w/SB%�O�������)��|[���P<�3ߝ��� -��� ���!�ΛQ���� �{S" -�箖g�����HD�����E\��7�%:�H?��GY� �!���CT@�3�M�ljy���;KwP(�1\d�� �j'���1!B�P[]�jݴ����}I�5�`|�����b���J}EB�A��ڤ�KP8�܊eTe)Sfn�������P� �G@g/��%ԇ^�؞�yW�z��l��cY ��b����5��l�&ޚ[uת��i3��tG�ld-Kƀ� ���e[~���<�H�Y���˸��Y�i��Y�G��P���zX��s].]S嚖��#��������E���f�auB������s�q4?��~�tq�Z����5�o/?㥖�g7�Œ��E?����?�Z���,�O�T4�G->~�[�-�'��HZ,�>1�\\.����{j����D��H������;ۼ��ʹ]]_^/.�w�J��2R����|��4�� ����wc���-��w��r����ߓ~���?^�,��Ğ��ZD^|P>�\>~�W -#�H�;��S�Q�^k��L4������|�4[ za���J�M����W}�c�7zL����3�o��+����<��H�6|�����x�� �3�P�,��Y���\@� -su�Kug��XN��d��5�xo�e�o�,��Mx�:�|д�_ Ps��Z��aٶ�S��9V�0������F���]��8�(s��� �u�~�+�2�vݻ&P��Yn�$���'_����U��G_�2�3y�$=�����:7۪���m�+s$b���_�3�̨#E0û��#�� �I��˪�J�� �'Į�ߡ�������pn����֏ce�zt#�AX��p��H��&l���V��#���<u;~ ��Te]�5���£�,���Pc�>?�:�@w�Sa��.�:bE:BsX$p⣆<Ⱦh��Z��A$r����s����ǫ���O7�۫���[��ݏg?���.v�{y��*|(�����5�2�1#p���Y�r���@1��?"S��endstream -endobj -2233 0 obj << -/Type /Page -/Contents 2234 0 R -/Resources 2232 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2274 0 R -/Annots [ 2251 0 R ] ->> endobj -2251 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [446.952 409.499 499.255 418.411] -/Subtype /Link -/A << /S /GoTo /D (localconfig) >> ->> endobj -2235 0 obj << -/D [2233 0 R /XYZ 71.731 729.265 null] ->> endobj -2236 0 obj << -/D [2233 0 R /XYZ 71.731 718.306 null] ->> endobj -2237 0 obj << -/D [2233 0 R /XYZ 71.731 668.792 null] ->> endobj -138 0 obj << -/D [2233 0 R /XYZ 276.55 635.915 null] ->> endobj -2238 0 obj << -/D [2233 0 R /XYZ 71.731 630.82 null] ->> endobj -2239 0 obj << -/D [2233 0 R /XYZ 71.731 597.893 null] ->> endobj -2240 0 obj << -/D [2233 0 R /XYZ 277.08 574.147 null] ->> endobj -2241 0 obj << -/D [2233 0 R /XYZ 71.731 562.027 null] ->> endobj -2242 0 obj << -/D [2233 0 R /XYZ 71.731 518.204 null] ->> endobj -2243 0 obj << -/D [2233 0 R /XYZ 357.781 506.301 null] ->> endobj -2244 0 obj << -/D [2233 0 R /XYZ 71.731 486.212 null] ->> endobj -142 0 obj << -/D [2233 0 R /XYZ 211.285 455.492 null] ->> endobj -2245 0 obj << -/D [2233 0 R /XYZ 71.731 448.414 null] ->> endobj -2246 0 obj << -/D [2233 0 R /XYZ 271.067 424.608 null] ->> endobj -2247 0 obj << -/D [2233 0 R /XYZ 243.475 411.656 null] ->> endobj -2250 0 obj << -/D [2233 0 R /XYZ 375.041 411.656 null] ->> endobj -2252 0 obj << -/D [2233 0 R /XYZ 71.731 404.518 null] ->> endobj -2253 0 obj << -/D [2233 0 R /XYZ 137.593 393.724 null] ->> endobj -2254 0 obj << -/D [2233 0 R /XYZ 262.973 393.724 null] ->> endobj -2255 0 obj << -/D [2233 0 R /XYZ 403.449 393.724 null] ->> endobj -2256 0 obj << -/D [2233 0 R /XYZ 134.388 380.772 null] ->> endobj -2257 0 obj << -/D [2233 0 R /XYZ 344.012 380.772 null] ->> endobj -2258 0 obj << -/D [2233 0 R /XYZ 71.731 360.683 null] ->> endobj -2259 0 obj << -/D [2233 0 R /XYZ 105.494 349.888 null] ->> endobj -2260 0 obj << -/D [2233 0 R /XYZ 71.731 338.518 null] ->> endobj -2261 0 obj << -/D [2233 0 R /XYZ 82.491 328.269 null] ->> endobj -2262 0 obj << -/D [2233 0 R /XYZ 308.443 293.3 null] +122 0 obj << +/D [2250 0 R /XYZ 218.078 534.865 null] >> endobj 2263 0 obj << -/D [2233 0 R /XYZ 130.909 281.644 null] +/D [2250 0 R /XYZ 71.731 531.035 null] >> endobj 2264 0 obj << -/D [2233 0 R /XYZ 71.731 270.414 null] +/D [2250 0 R /XYZ 118.555 488.845 null] >> endobj -146 0 obj << -/D [2233 0 R /XYZ 318.721 238.805 null] +1334 0 obj << +/D [2250 0 R /XYZ 71.731 445.218 null] >> endobj -2265 0 obj << -/D [2233 0 R /XYZ 71.731 231.607 null] +126 0 obj << +/D [2250 0 R /XYZ 187.345 412.714 null] >> endobj 2266 0 obj << -/D [2233 0 R /XYZ 71.731 200.782 null] +/D [2250 0 R /XYZ 71.731 402.349 null] >> endobj 2267 0 obj << -/D [2233 0 R /XYZ 511.084 189.988 null] +/D [2250 0 R /XYZ 154.51 392.59 null] >> endobj 2268 0 obj << -/D [2233 0 R /XYZ 298.703 177.036 null] +/D [2250 0 R /XYZ 338.14 392.59 null] >> endobj 2269 0 obj << -/D [2233 0 R /XYZ 490.178 177.036 null] +/D [2250 0 R /XYZ 71.731 380.47 null] >> endobj 2270 0 obj << -/D [2233 0 R /XYZ 71.731 152.339 null] +/D [2250 0 R /XYZ 71.731 380.47 null] >> endobj 2271 0 obj << -/D [2233 0 R /XYZ 136.289 142.466 null] +/D [2250 0 R /XYZ 71.731 359.6 null] >> endobj 2272 0 obj << -/D [2233 0 R /XYZ 192.239 142.466 null] +/D [2250 0 R /XYZ 113.898 348.057 null] >> endobj 2273 0 obj << -/D [2233 0 R /XYZ 136.289 130.809 null] +/D [2250 0 R /XYZ 177.702 335.105 null] >> endobj -2232 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F44 1994 0 R /F48 2006 0 R /F27 1180 0 R /F35 1525 0 R /F55 2249 0 R /F32 1187 0 R >> -/ProcSet [ /PDF /Text ] +2274 0 obj << +/D [2250 0 R /XYZ 71.731 327.967 null] +>> endobj +2275 0 obj << +/D [2250 0 R /XYZ 263.826 317.172 null] >> endobj -2277 0 obj << -/Length 2154 -/Filter /FlateDecode ->> -stream -xڕXm�� ���"�0 0�X��)�ag�w�C{���P�b��N�e����ח)�q2�s�bh���C�r���%R$!<T&T�g�ݻ`��_~z'Yb�"ˑ��ӻ��p��,gO�Y$S�%�$T"�j���{��4��hK������o;S��~K�~������?O?���ӠT�����U��̅a*9���"�"g�SY��0���]H=���1kmw����}N�g0�)�~�R�ߡ�vU�d<�,�T�Ӄ �o��K=ݧ4�t��ܙ�xK�*vۘ��V�q��b̰zm�U컪�U}�>�-��(����Z��������&�-m_�Do�A�2-��b?�Ñ7]g���b!o����#� ��M�8�3Ȫ8�8J��ҳ��E�L��v�=�A\9�E(8&E�iHR0�`jo;"�f���k^?T["~�j�t~<;0���=K9wΆE�٦�Y�`��GZٽ綟��� -��.�����s�2m�Ɯ|"%�O�a��!d�2 �ݙ���P���(�۶�6ů���+nM���}ݱA�c?��&!�K���9�}K� �Dž&���d�IE $�؆Xe�-.@��e�����"t����J]9��C��ִ���,�������[�HV뒖.m� -L��f��_��cM)�Tb�z�! �% -��� -`HIvrzB����Ddg���y>$>~ku>�~�؏���`��k!%99��|_`&#��ħəa����a,�xJ:��X/�ɍ������PWk�9�7r�D���ɮ�EK9v�#���+F�~�z�uc��:�)O�t���kT�Ǵm�+���"/6�P��]�_$džzTT ��vm��o�_.b�3�,�'�rCO�] ������ -����sg�js���� Z[�B�g�����CSA -S�pJ�Z�^� -: ��p@���|���էx��#J�2yFG�&������q��JGo�{Ug,I[�Ǐ(�B���ix^?��r$t1~L7Bu�kJs����u"�D���e^W?���~�j�D���F��x��G�S��'����ځBd�ɥ���{�0`:I\� �[���#���XA��~F��Ms�8%F���!乂�K�@D��e�@���gE��A0_��@�����0AA!I�1�O-^?��d����+~�����c�{����褊�\������e�����~�F���@\�|�Ҵ�Ӓ��ts/>�pˬ���*/�A�?&�s�z�#]�!�bq�!d�%`� -R����?&=�~�������S�F��4=ke��;���1�B���;Nk!���Cg;��Q�ZF�հ���%�E��p�����Mnt�N���c���=Զ��6�8���r~���o7aȵ������f -��yWb�T Mk��\�q��o"��I���A�m�n]���ґ ��?�b��j���Z��pݼ���]���,>�*��'ݓ��.������`��r��ܬ�N���,U7�{���|��_�<��kUB�7���$\k���^Ki-F���������!�ٮ08#�A�Ad2|��w��=��OI/@r����$c�Qi9�76���O7�4�nB�`���.��fip|�B��� ͵�ة;Ì�� ���j���.^��p�p���� #>��?�zr2�I��F�4_'1�[h%��H�h�� -F0܆jT��\_]r���6��㣻pb�[�tη�;��e�M��.�H�T_���Y����9�٦n-���Tǜ H�"�U����J#!urn��I�%��$Ԥ�x\r��}������2�gC}#<A�Ro�@�����c��#�� -�}�:�]�nG�^���p�,;K��8���:|j��s�(�gzl��ŷ0�>ɽ�n/���W�W�z]�1����93a�3MG��ݷ����)���g�$��b��yE��,2]�i���{wIIg1~�m��o���@��NJ�\A͏@@ᴕ���p����ۯ{�J�d��$��\����a@ж�7�Q�yc?����<-]k����z��3:�ǐ�]�?�G�H_�������7���%�K��/5�;�J�endstream -endobj 2276 0 obj << -/Type /Page -/Contents 2277 0 R -/Resources 2275 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2274 0 R -/Annots [ 2289 0 R ] +/D [2250 0 R /XYZ 71.731 297.083 null] >> endobj -2289 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [405.169 459.412 457.472 468.324] -/Subtype /Link -/A << /S /GoTo /D (localconfig) >> +2277 0 obj << +/D [2250 0 R /XYZ 229.324 286.288 null] >> endobj 2278 0 obj << -/D [2276 0 R /XYZ 71.731 729.265 null] +/D [2250 0 R /XYZ 444.938 260.385 null] >> endobj 2279 0 obj << -/D [2276 0 R /XYZ 71.731 718.306 null] +/D [2250 0 R /XYZ 178.998 247.434 null] >> endobj 2280 0 obj << -/D [2276 0 R /XYZ 71.731 693.235 null] +/D [2250 0 R /XYZ 71.731 240.296 null] >> endobj 2281 0 obj << -/D [2276 0 R /XYZ 71.731 678.291 null] ->> endobj -1308 0 obj << -/D [2276 0 R /XYZ 71.731 630.934 null] ->> endobj -150 0 obj << -/D [2276 0 R /XYZ 183.546 595.467 null] +/D [2250 0 R /XYZ 169.98 229.501 null] >> endobj 2282 0 obj << -/D [2276 0 R /XYZ 71.731 592.807 null] +/D [2250 0 R /XYZ 71.731 209.412 null] >> endobj 2283 0 obj << -/D [2276 0 R /XYZ 71.731 576.867 null] +/D [2250 0 R /XYZ 450.823 185.666 null] >> endobj -2284 0 obj << -/D [2276 0 R /XYZ 76.712 538.281 null] +1335 0 obj << +/D [2250 0 R /XYZ 71.731 165.576 null] >> endobj -154 0 obj << -/D [2276 0 R /XYZ 233.392 505.405 null] +2249 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +2286 0 obj << +/Length 2202 +/Filter /FlateDecode +>> +stream +xڥێ۶�}�B�>�ĴH���99�%��ɾ���+Ѷ]\������pHK��(z`�Ù��)���^�Y� r&��+��������XZ�������]z9˓�{\{�X�zi(X������;���Rā/�?���u]���7_����O�?�����4S�g�M�΅`"�x��(A����e7� �? ��I-��h����F�H��o)�El�<n��?�BW]K�R�ڮ�+�%���߃@lƞ.����[p�iRNBz���}�;��;�c����h�������a���+Z{���/������4bQ�{I���'W5�p�3$��L=�PI�!��KSG,������� +�7��������0���-� �� z�+R̯)�G!?��g� �t8�҅��Ne���"��ʳ�8���:*�p����B@$,D�˪�ϵb6& �8�0FZKrƓ�[���t`܆�1Ư\��p۪F^�7�*"��Gx>Kf6�ΆHA`�M�P/nb�5����s�s�u�i�`����j���1�X�ʊ�Y�z`��F\��RW+�u���T�gķ/�''.h$�+T?�+�]b�f������H�� +2!��-ժ^j� i�����b�j(�jg� ������f�B��^0#q ���lZ�L�n@��,�7��`��R���F� +�_=t�K�U��3�PVkԉ����^){X�ѯ�y�G�g��vg��ACר���e��}DD����h���F��b���Y�:CY�<���i��p,�"�?�>~ +�"�'����"GPY�4��Yz���w�~;Rֱ`I nѠ����I��2,��z= ���4bq�J��5��]y�IB�!�X�����A&M�$����2��z�e�Z��T3ђ��5� jD0�5�h�j�������\�a�1����t=}:��ɨ`~�sB'�ň.�\�nA�7�[�����`�9s�����MוN'F�&Vc�EBr��=����u�Ŵ)�t��Ս=�P�W����$&sV��9���K��د�L\Z$�B�'������Fa��,��O�a4��P&dS]�e�ʳ�$�]�����"�4�e��� ��,� �i������Ť�&:8Evu������(-vmmȢP;M�N�����;�0Y�$���v��V��b����C7ZvF�V�iD��Sa�"��f���X�z{t+[Uë��e��W�j�*Osx�A8|�� +��x�p��DZ+��Us`ƅ�p�$��.�?+����'6���',�rb©_���?����6S�|�X&�${�D�<8A���đc��?�C�m#_�$Q�Qx��_� 4��p�O�f +�<�8�Nca�-�Hv���K)�3�-�S��m�; ����E����̉ � �Anh��gjC֦�]���ܺXU(��\qT�9��)��'i>�yru�}?�X\0�����x,������9���ٵףHX�:�K��gC#��#+j.䔜-�ja���j��"�NZ�Y�t���m�L�p1�|��f�Ӟ�Fg�'�����c䈿vZ����"f!d�`�^NS�씅H���"���®��6��j8��A��'��U̖y��0�7�B~H��B��+��ŝj�LV1%�ӡ�EG�R=��<�-A$U�:�u�"}4@'��X}u)f�����k�8��>}'������x �Rwp� +hw'�MjL�ƁKS�tvK ��I����H�9�چ���JM�b��%��`���J���(sbV�+e��K�6� 2����ZI����w��W�e�� �ۍ��2[&�s5��0���ӕv�VZ(Ġ�Ź��6�m��`��b�Fj`�jb��T�qP�ɓ�v�{������� +;��>af�UM�M5�|E��-�<~��/�{�s�ֻ{+��hr?��=;�=���&a`� ?�`�z��˔� 7B�8i����`��na�h��ԫ���Z?aa��'w�VV�j'\�皪����b�%U =���4�7�{��}���7�:�����N30u5GSXާ}� �D���k\���O����Hp��ju��q����G��D���I����<���t� �fp�`0�h�T/j�B �V�s�s�{�2����=�\|�E��b1�/���~}��/�T�endstream +endobj 2285 0 obj << -/D [2276 0 R /XYZ 71.731 498.207 null] +/Type /Page +/Contents 2286 0 R +/Resources 2284 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2310 0 R +/Annots [ 2290 0 R 2291 0 R 2296 0 R ] >> endobj -2286 0 obj << -/D [2276 0 R /XYZ 250.633 474.521 null] +2290 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [474.449 685.559 534.665 694.471] +/Subtype /Link +/A << /S /GoTo /D (mysql) >> +>> endobj +2291 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [143.123 672.608 202.898 681.519] +/Subtype /Link +/A << /S /GoTo /D (postgresql) >> +>> endobj +2296 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [308.275 502.52 353.582 511.109] +/Subtype /Link +/A << /S /GoTo /D (security-mysql) >> >> endobj 2287 0 obj << -/D [2276 0 R /XYZ 201.693 461.569 null] +/D [2285 0 R /XYZ 71.731 729.265 null] >> endobj 2288 0 obj << -/D [2276 0 R /XYZ 333.258 461.569 null] +/D [2285 0 R /XYZ 71.731 741.22 null] >> endobj -2290 0 obj << -/D [2276 0 R /XYZ 71.731 454.431 null] +130 0 obj << +/D [2285 0 R /XYZ 224.186 707.841 null] >> endobj -2291 0 obj << -/D [2276 0 R /XYZ 71.731 431.517 null] +2289 0 obj << +/D [2285 0 R /XYZ 71.731 700.488 null] +>> endobj +1336 0 obj << +/D [2285 0 R /XYZ 71.731 672.608 null] +>> endobj +134 0 obj << +/D [2285 0 R /XYZ 266.299 640.294 null] >> endobj 2292 0 obj << -/D [2276 0 R /XYZ 77.111 422.017 null] +/D [2285 0 R /XYZ 71.731 631.657 null] >> endobj 2293 0 obj << -/D [2276 0 R /XYZ 71.731 410.647 null] +/D [2285 0 R /XYZ 247.769 621.365 null] +>> endobj +1337 0 obj << +/D [2285 0 R /XYZ 71.731 588.324 null] +>> endobj +138 0 obj << +/D [2285 0 R /XYZ 156.121 555.014 null] >> endobj 2294 0 obj << -/D [2276 0 R /XYZ 71.731 386.984 null] +/D [2285 0 R /XYZ 71.731 552.539 null] >> endobj 2295 0 obj << -/D [2276 0 R /XYZ 77.111 377.484 null] ->> endobj -2296 0 obj << -/D [2276 0 R /XYZ 71.731 366.114 null] +/D [2285 0 R /XYZ 118.555 515.992 null] >> endobj 2297 0 obj << -/D [2276 0 R /XYZ 363.851 354.57 null] +/D [2285 0 R /XYZ 71.731 481.008 null] +>> endobj +142 0 obj << +/D [2285 0 R /XYZ 221.647 453.985 null] >> endobj 2298 0 obj << -/D [2276 0 R /XYZ 425.741 354.57 null] +/D [2285 0 R /XYZ 71.731 446.787 null] >> endobj 2299 0 obj << -/D [2276 0 R /XYZ 71.731 334.481 null] ->> endobj -158 0 obj << -/D [2276 0 R /XYZ 215.669 303.761 null] +/D [2285 0 R /XYZ 173.289 423.101 null] >> endobj 2300 0 obj << -/D [2276 0 R /XYZ 71.731 296.563 null] +/D [2285 0 R /XYZ 71.731 410.981 null] >> endobj 2301 0 obj << -/D [2276 0 R /XYZ 178.553 285.828 null] +/D [2285 0 R /XYZ 71.731 366.799 null] >> endobj 2302 0 obj << -/D [2276 0 R /XYZ 347.94 285.828 null] +/D [2285 0 R /XYZ 282.227 342.304 null] >> endobj 2303 0 obj << -/D [2276 0 R /XYZ 71.731 267.796 null] +/D [2285 0 R /XYZ 71.731 327.195 null] >> endobj 2304 0 obj << -/D [2276 0 R /XYZ 71.731 267.796 null] +/D [2285 0 R /XYZ 71.731 312.251 null] >> endobj 2305 0 obj << -/D [2276 0 R /XYZ 71.731 248.555 null] +/D [2285 0 R /XYZ 71.731 263.2 null] +>> endobj +146 0 obj << +/D [2285 0 R /XYZ 276.55 230.323 null] >> endobj 2306 0 obj << -/D [2276 0 R /XYZ 71.731 216.922 null] +/D [2285 0 R /XYZ 71.731 225.228 null] >> endobj 2307 0 obj << -/D [2276 0 R /XYZ 140.901 206.127 null] +/D [2285 0 R /XYZ 71.731 192.301 null] >> endobj 2308 0 obj << -/D [2276 0 R /XYZ 431.826 206.127 null] +/D [2285 0 R /XYZ 277.08 168.555 null] >> endobj 2309 0 obj << -/D [2276 0 R /XYZ 153.643 193.176 null] ->> endobj -2310 0 obj << -/D [2276 0 R /XYZ 71.731 186.037 null] ->> endobj -2311 0 obj << -/D [2276 0 R /XYZ 71.731 186.037 null] ->> endobj -2312 0 obj << -/D [2276 0 R /XYZ 71.731 168.854 null] ->> endobj -2313 0 obj << -/D [2276 0 R /XYZ 71.731 152.229 null] ->> endobj -2314 0 obj << -/D [2276 0 R /XYZ 71.731 152.229 null] ->> endobj -2315 0 obj << -/D [2276 0 R /XYZ 71.731 132.988 null] ->> endobj -2316 0 obj << -/D [2276 0 R /XYZ 240.44 108.493 null] +/D [2285 0 R /XYZ 71.731 156.436 null] >> endobj -2275 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F44 1994 0 R /F48 2006 0 R /F35 1525 0 R /F55 2249 0 R /F32 1187 0 R >> +2284 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F44 2037 0 R /F48 2049 0 R /F35 1567 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2319 0 obj << -/Length 2734 +2313 0 obj << +/Length 2378 /Filter /FlateDecode >> stream -xڍk����� -#(p6�护dI�"�%�K�9�f��h��+�6q�dH��6��3��,ٺm��c8/Γ��~r�J�j��\�M�(���v~|%b� �������k��E�ы��"����E����x,���ao��mWk�DK%��Pw��*W�h��i���*����_^�{�&:y�_�+��2�,����E��q����TESo��W�E�$2̀�B��q��5�T]�0����$�O��ʧ��������I��R�Ҵ�<U�����Ag�~ �z&��R�3�9#�یHR+�{S�&2���t�y%�e�2��oiJ�4��s���D$*̏��XDZ\�Z*���4�%�xnN48��2dK�����5��z^mM�qj%�|��?����%1a`��9ս`��B�p^�h���B���G %4o�-dco��������(�խЀ��#Y�_�J&�/=2��ek�ӌB�L$i��h��#LTڇ>��F{m��{�{�w8�Y�rh�Seд� - -�l&��A����V���[ ���h �����%9�o��b����`I��'2� ��3*�Ҋ-]�)��l��[u �\�n��f��5����S4���!��x�{8V���]��k[�ݔ�p�4�y2�N��\�4���#�^z�_?�P�]����s0�����O�1O��.[�]&�ݕK\�2h8<D -<�A낤�����!=��o���؛"�%tװd�O�l�*mo\ū͖�j����뺾5=I.��a���� -:_l�ѩ�ݱ�#�uG�ִEZ�yX)Z6�ș{=4ޙR�Dji�������C -�em��E@x�/d̖�A��49�~/h�������@�44e >����{9��H�U�p -�{b��@b{�qm�.�+y0�yywr=�qҧx>�`q�5��S%bB��y6�<ky�pݞˑ�$f�9�g|%HK�q���(=aŇ`�Eh~L�wV��^��ٳx��@�Rh,�bXK�!EŜ����`�O4��䛭CB�J�X�}B�Ց�@�#�<#:\t�=-���Z*�p�����q�A�מ|�����9���Oo����(����4EgA������eC��#�HTvL���u�b�@J�*e��fd����J��9������謸��h�0* �q��AѦ�������0�[\�����na�1~�0����`����v�{T^9ܑ ��ؔU -�F��,D�d|Q�ܬ!G��a�m�PR�L+c�FB$��L`/�����7��� -|K�A�}��$��#�z$�A� ���;y� 1���Zk���X��:��FǓ��A0WC��K#��9n�W�WHj��w4�7hxg*K�$�Qصuw��r(ƐHݹ�]���!����e� ��h�����h��9 �Wq���g��w�N�-�ߚ?x_�L��sb�#Rp���O� -�����P� �[5i0���TD��V-��G@�U�5"d��DB��7�T� _$�0/��B��5�� ����&��ϊG���d���ͨ=B�5��\�# -y>1R�l�ZRO��4�Re���/5+Gк-G H�����! �Q摜{0R�D�}���ă����/}]:NB���8���;�o�д/��9�QqA�)��~?-=�$.��"x�Ty3�śk[�� :M���ǒ̍�]�A5HqM+�b��s���m>�"�\ ���S�d��!����f��������.����{[6��jM0�/y�S��>����.ܔ����T��0�=[���2�G�۾�����K�E��th��j�%��0���1r�����k/�c��lB;8���љ�!����?;,O�����w -�f������U#�:����;Mo�]�Z�j�|��w����ݷeI�T���đi�l�5e�]*�H���x�0���V�S��(�j=�K�5�y�mW��ГpLղ�Yx�H����S��f�=�嵐�|�F�T�sh��ү1.R[�)H��g�g�ǒ� �R�r�>|�F�e��ޅP�%�(��C�y��c���~.%"ʂ�6���|�=T�O^���,����ҌN6c����T�E�s�xbzeҫ�똢��T+�M~!#���>T�?AD�0)! -(��]Ѻ#��i-��^�x��<r��0|�K�ņٻ/x�?��09ID��!:�h(o�1��#�P����t�C7$�K�ʹ�ᱥ�E�qf�[�x��I'���LpO���I��Sv$Xkрj{��l���as��>ix��}~� -F�jvk���)k���I0b -�����L5���R��O�O8.��o��D�\ �nk�K� -T�d_Ү9X�X�����������яˋY�_nh�j � -0�-� (�[� �����W�TB{�I~&a�AE-�I`�~ܛN��D��bR�������!���]�<~��t� 1ct�Jv��@%���O��V�!�8�"�!��ӱ���x#�7-9�Hz�Pi�|����e�9�~�0ѭ�`��w{�f�.���cf�ֺ��$�H#?g ǁ3���b7��Q�5"���Mp.���n�)�\�e��&�7Yr�� ��.*¶|�C�U�43U���W��D����'W�2���`��cl8�X-3�^��L�\�_@n�!M�O$���_��������=endstream +x��Y�s� ���?��ڝ�I=o�:Mv�\zy���c���"˱�dɕ�K}}��Ǧ�o�̬@ + �����?9�4<T$�� ��;g�o.�I�3˸�s>{wz�� ���������A��=5���9����MZ���s�J�8ϳ����?�<�G�����d�*�t �P�j��90L�a���Ph�5�Mӧ�r��,�;���2%"+��Hz���iM�I\��\�`�)��9�ea_&�UZ4q�٩E�)�+n�l�����///#��ն�w.�ru +�O���b�� ��<^�$X��q����R������b٬r��O/ܰ�|��] +���*AO#�g�91=6�9/�PXy�}��5I�o,Z�N��I�� ,q�a�� Ք��<[���/8��<[�Ԣd�u���(���x�U�~�yÚ�� u��HwW.c<�?�����y����}Uie�IR��M��@4{23�}>%�K���>&,�P�6 :IM�q]��К�.���lm�ɛ�f��NC{:��ӐQ$���Ԝ�I�'e�Ȟ�B���"d�֜ L$˸x6�hl)��d���_��\��l�%��|��D{(<�����*��@(���\WYܤ�����\F/ yN����2_�ݗJ~z����O�k��#;�-�!��xY���]� �N �By�[����#�$Q}�s]��/���(�Y�q��������4!T"PVB�OR���z�y]�� T/�\O�;��(tL@�.� ��*��������m�'Bߞ����vv��:�c#��8�n�I��ӱFR�E)MY��0t�(���gˬ�y��;K~A��D_& +d�k ��:�b�^Ƅ!�Yf����t\p�p'��&�T�*�|��&2���zBӴ @�E��)�R5��pEP8dz%�(�����\u��f4�O�����=QU��qt+�" +n��5����}i!34>ټ��`g0=��Җ&�8��e%O�5?����,�*-:G��t�<�{��G +�E��Ii����BE��]�筕I��v����UPp}���(l�Aʏ�PR�<2�����q�p�܉�����O�'g'4��}�La�_��|>��|������لy?��vpu�i��h,�<>��M�L�N�U�w"jvv~=y8iw�SC�krs7=���-B5������39�\L��ۏ����� D�eGO@y��c�[���A�&��vvuq5�Ds�l��6#ui:����3R�\-����8<Q��zg?�t�ן~$��W?_]O.'�q��D��"��N��r�x?B�33\���R�i ������� �)��|�4[�X���D/�m���Խ<�_��9����� ʹ�����<[!�64�2O��O��=cz���t����(Ag��@,��C;��\@� +kM�Kug�l��5n i�o �`�����M���e̢����z����f�Z˽��m�=�H�cU +�N2۲��:�PW���EcoT=�Ww���:O�����<&P��A���W��j�3X����=z�il%��K�0���u\55V�'{6��r��V��3�H�b{տrg[�~�ޅw��ޑ6�����"I�U�J����'4]�kx�� �с�JAYآ�;D���ӡ�P=��b�!���3Rݵ G��⨈Wl#���H�2�UY[i�A) �0ז5�=�`,܃�h���0����2�͙+�4!���n�N����oGj�{9�H�W�V� ��/�������/�ד��ُ?H���ݛ�_����/>qT�O ���Y�'�m$Ô�a���i�X�o�E���J�H�}T�R!*�7�$ړ������w<sk�JW벊�-[���F6�0�O�5���*k(>i9��yi1�mck�.�{����т�v%�R�E��2-�5���3�`�}y�nڲ�^�v��(���H��A��[6)��wfO��ENj��e�uUe��� Ox|�=q�A��:��:`i:Fo�,7e�2�����\I�;[��%�4�驪��K-I.�ͮ@�Dp!5@� ���8���zՍnkrf�<Wi���5@���Y+��X�|��f�'Taʠ��.���i_r�)|�.�!,�o�u��~�}������$z�R��<Kl[�'��ב O6�I��5�W��d`�p��(��5�{fJ�4�6̔�8��03�4� [����\Г���afl�Y���UJ�Wv ���\0�+ i$��7�Ɏ5ɨ:�)$���d���O�@ �Hx��h��Y��a�jW��d^ \��^��,����v����7�^�}�c9�y�S�F� +A=R}�'�CM��"��endstream endobj -2318 0 obj << +2312 0 obj << /Type /Page -/Contents 2319 0 R -/Resources 2317 0 R +/Contents 2313 0 R +/Resources 2311 0 R /MediaBox [0 0 609.714 789.041] -/Parent 2274 0 R -/Annots [ 2333 0 R ] +/Parent 2310 0 R +/Annots [ 2324 0 R 2355 0 R ] >> endobj -2333 0 obj << +2324 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [203.962 404.877 257.754 413.788] +/Rect [446.952 611.542 499.255 620.453] /Subtype /Link -/A << /S /GoTo /D (security-webserver-access) >> +/A << /S /GoTo /D (localconfig) >> >> endobj -2320 0 obj << -/D [2318 0 R /XYZ 71.731 729.265 null] +2355 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [405.169 97.37 457.472 106.281] +/Subtype /Link +/A << /S /GoTo /D (localconfig) >> >> endobj -2321 0 obj << -/D [2318 0 R /XYZ 71.731 708.344 null] +2314 0 obj << +/D [2312 0 R /XYZ 71.731 729.265 null] >> endobj -2322 0 obj << -/D [2318 0 R /XYZ 181.256 708.344 null] +2315 0 obj << +/D [2312 0 R /XYZ 71.731 741.22 null] >> endobj -2323 0 obj << -/D [2318 0 R /XYZ 336.036 708.344 null] +2316 0 obj << +/D [2312 0 R /XYZ 71.731 718.306 null] >> endobj -2324 0 obj << -/D [2318 0 R /XYZ 470.054 708.344 null] +2317 0 obj << +/D [2312 0 R /XYZ 357.781 708.344 null] >> endobj -1309 0 obj << -/D [2318 0 R /XYZ 71.731 668.329 null] +150 0 obj << +/D [2312 0 R /XYZ 211.285 657.534 null] >> endobj -162 0 obj << -/D [2318 0 R /XYZ 206.856 631.113 null] +2318 0 obj << +/D [2312 0 R /XYZ 71.731 650.456 null] +>> endobj +2319 0 obj << +/D [2312 0 R /XYZ 271.067 626.65 null] +>> endobj +2320 0 obj << +/D [2312 0 R /XYZ 243.475 613.699 null] +>> endobj +2323 0 obj << +/D [2312 0 R /XYZ 375.041 613.699 null] >> endobj 2325 0 obj << -/D [2318 0 R /XYZ 71.731 620.971 null] +/D [2312 0 R /XYZ 71.731 606.56 null] >> endobj 2326 0 obj << -/D [2318 0 R /XYZ 120.303 610.989 null] +/D [2312 0 R /XYZ 137.593 595.766 null] >> endobj 2327 0 obj << -/D [2318 0 R /XYZ 71.731 577.948 null] +/D [2312 0 R /XYZ 262.973 595.766 null] >> endobj 2328 0 obj << -/D [2318 0 R /XYZ 71.731 534.112 null] +/D [2312 0 R /XYZ 403.449 595.766 null] >> endobj 2329 0 obj << -/D [2318 0 R /XYZ 71.731 534.112 null] +/D [2312 0 R /XYZ 134.388 582.814 null] >> endobj 2330 0 obj << -/D [2318 0 R /XYZ 270.634 523.318 null] ->> endobj -1310 0 obj << -/D [2318 0 R /XYZ 71.731 516.179 null] ->> endobj -166 0 obj << -/D [2318 0 R /XYZ 188.593 478.964 null] +/D [2312 0 R /XYZ 344.012 582.814 null] >> endobj 2331 0 obj << -/D [2318 0 R /XYZ 71.731 471.612 null] +/D [2312 0 R /XYZ 71.731 562.725 null] >> endobj 2332 0 obj << -/D [2318 0 R /XYZ 99.301 432.936 null] ->> endobj -2334 0 obj << -/D [2318 0 R /XYZ 319.328 407.034 null] +/D [2312 0 R /XYZ 105.494 551.93 null] >> endobj -1311 0 obj << -/D [2318 0 R /XYZ 71.731 391.925 null] +2333 0 obj << +/D [2312 0 R /XYZ 71.731 540.56 null] >> endobj -170 0 obj << -/D [2318 0 R /XYZ 191.198 359.611 null] +2334 0 obj << +/D [2312 0 R /XYZ 82.491 530.311 null] >> endobj 2335 0 obj << -/D [2318 0 R /XYZ 71.731 351.159 null] +/D [2312 0 R /XYZ 308.443 495.342 null] >> endobj 2336 0 obj << -/D [2318 0 R /XYZ 71.731 338.526 null] +/D [2312 0 R /XYZ 130.909 483.686 null] >> endobj 2337 0 obj << -/D [2318 0 R /XYZ 71.731 328.563 null] +/D [2312 0 R /XYZ 71.731 472.457 null] +>> endobj +154 0 obj << +/D [2312 0 R /XYZ 318.721 440.847 null] >> endobj 2338 0 obj << -/D [2318 0 R /XYZ 115.118 312.787 null] +/D [2312 0 R /XYZ 71.731 433.649 null] >> endobj 2339 0 obj << -/D [2318 0 R /XYZ 429.318 312.787 null] +/D [2312 0 R /XYZ 71.731 402.825 null] >> endobj 2340 0 obj << -/D [2318 0 R /XYZ 71.731 310.63 null] +/D [2312 0 R /XYZ 511.084 392.03 null] >> endobj 2341 0 obj << -/D [2318 0 R /XYZ 147.188 294.854 null] +/D [2312 0 R /XYZ 298.703 379.078 null] >> endobj 2342 0 obj << -/D [2318 0 R /XYZ 314.747 268.951 null] +/D [2312 0 R /XYZ 490.178 379.078 null] >> endobj 2343 0 obj << -/D [2318 0 R /XYZ 71.731 261.813 null] +/D [2312 0 R /XYZ 71.731 354.381 null] >> endobj 2344 0 obj << -/D [2318 0 R /XYZ 71.731 177.395 null] +/D [2312 0 R /XYZ 136.289 344.508 null] >> endobj 2345 0 obj << -/D [2318 0 R /XYZ 155.056 151.492 null] +/D [2312 0 R /XYZ 192.239 344.508 null] >> endobj 2346 0 obj << -/D [2318 0 R /XYZ 89.664 138.54 null] +/D [2312 0 R /XYZ 136.289 332.852 null] >> endobj 2347 0 obj << -/D [2318 0 R /XYZ 71.731 136.384 null] +/D [2312 0 R /XYZ 71.731 299.577 null] >> endobj 2348 0 obj << -/D [2318 0 R /XYZ 71.731 121.44 null] +/D [2312 0 R /XYZ 71.731 271.517 null] >> endobj 2349 0 obj << -/D [2318 0 R /XYZ 130.903 100.284 null] +/D [2312 0 R /XYZ 71.731 256.573 null] >> endobj -2317 0 obj << -/Font << /F33 1278 0 R /F35 1525 0 R /F27 1180 0 R /F23 1173 0 R /F44 1994 0 R >> -/ProcSet [ /PDF /Text ] +1338 0 obj << +/D [2312 0 R /XYZ 71.731 209.215 null] +>> endobj +158 0 obj << +/D [2312 0 R /XYZ 183.546 173.748 null] +>> endobj +2350 0 obj << +/D [2312 0 R /XYZ 71.731 171.089 null] +>> endobj +162 0 obj << +/D [2312 0 R /XYZ 233.392 143.362 null] >> endobj -2352 0 obj << -/Length 2850 -/Filter /FlateDecode ->> -stream -xڝk�ܸ�{~� �tG�%?���<��kݽE�[3c�c~dw��K���YO6@1�X�(��H����?oy"Ra�ʎ���F><�c�(��/��^�Wj��$T�����b�D�HIru���ysH�^��\G -�^U]��eQ���˰�oQ���?�}��vd�H$�zR.����W M�`��� NV�(���s�z(��Fy���7�Sv5���|�fo@�sL�5|Z�\4e���w����t-�1]+�NݞVuO�-�ںThi��� ���e�;������)��r�0�4��<�Yy(@\�N]i�����/�nuO[m���2N���E����Z�#���b����PRE�=�A�iՓ9�T�V�{�3�Tܑ f"��'mw�cLDF��>"�zR^1(1���z�y�oL�H!#��wv���N�C#��x$�����:C��>5�b���N��c��s���V��y\��c_\W��;i�S#/Z��u[ؑb�_���_�w����)��zhX���Q����D���.7� njN��p����)�����C���@��$�zN�ד����B��^2�"M�jI�D��Q}��"��ݒf�D�X�"h��$���IZ���l9�$�� -�`����P�Ǭ���D��v~�����l��h�tk<38�x�AduY�YZ�ڋ���'f�G�=�:�Z �x�|,<�XK~��Ch)�ແ�V�Ob3��FAV�w����O$�����M�KТ�+�:MG����J��SAi�p�>�t�kA�B9#��xc��;��:��P�x� ����:�i�`�<@�Z3��ḭ�"��C����uN>�nty��$0{d<�p�� Ti�S˜C�M�8��DeI���?#��Q�ؚH����|W��4L �z�, �Z �i�)�(��>����3&�س�����EQ@$>_���e�N�5iU��z�I(�+�l�M���/�{�0ʶF&� xx�˅B!�P��r�?�G���<�M>�� M�$f��b��I��#�Z�C�:��:M�2 -lQ��i�o �z���8�Do���b�k`��-Ԑ��b�G����Z�.��s�|̳&�&CͲ!Ck�Z�)�+ �17��@Ҙ�`���o �oԨ/�ݛ��G����/L~ ��oE֢��]��|��cog��c�fO�<o�K����F���$�"š����˨��s�'�� T��0 H����١�;�g���pufec҂qqZ���fk����Er����m���J{�ޞ�țYB"�ϋV��X�q�RT/��](S��["�D��6�`��k?�Vt��0�覣��c@5y�=2D$f���BS( ��֞�r�>�8��1+��{.���d�+�� U�舢E�и=�������<间�V��E��%u�HP��Z�/^tC��m/��2d_���ه�i����ˊ��_�?���͙m���7����)��OkP�gܮ���tI�7�~hP6l�"8ΰ�2`�\��ǯԺ�ڢ��;�uԺ����/�jck$ �0H�c'1Z�e��B��W�[��GcOȑ��7g6�8-_��a�bC*/Ibj���K��y�h�P�X�h�����Z��˝�c0��r'�8v��6�5Ckn��Y?����~n:'� ���H�C���,�6�fs�vd���٠Fĸ$�两��&���[�1�$쟉r�Vㅀ���V����N,c7!9�/��Yh0�[A�k��O�O&�Y���+�s��)�R���3���]}ԐT\_�\/)K[*P�\�RRA�006At�F���[�D>���t�o��aC B� � �[&5pwA(�&2K�j�.�#���-�G����I�"���7�c�� -���u��8��D�y}L�>W�3�zaɣA_�� ��R�J#[�b��P?d�^h���dx�$�Ԛl�hmHqY�_�']�E�m��&���jp����5h��J�ꍕ���8R��li�*�������ԸŲ�̄(l�n�1o���x�����������-�Z�����u��$�^F�3?sc�#Ρ�����9��1a�0�EXj��=��3�T���̫Y'4b�� 5�{+����e�Iɂ��I�x��c6���]�cJ5%�1tFCk̺�D��:h%��M��VM����i�tu����AM�m�hxNp��� -#�t(�M�i��na]� 蟔 �������2���� h쁉3,ľܖ�k>��l_���V�6:������Gݍ�&s� *�Im�߯!O-*��{4p��5�rK�[CJh��(a�ݩʆ6T��X���:�c'v9�x�K< M�3�d��Y+�QV[��;n�8����u����=�qnu�k!�AG��xC��L� D�>�_/w�A肕���`E6Ȋ�����W_<��A��?9ߚ�+ƾ�%J�����»B#��5�s�z�XI�M����Ҋ��mQ���j� q;(3I�s����Ա�j �T�a�������d �����L����qӏy�� ��9����o#���`$9S���Db��������Cz��Aq�p�w��-Ӭ�8�i�H���w�}�L߽~����5����-�t�����(���(�$ �c~6���&sF�=���6�m� -�^G�m��o�PK�r'T$��&�mi�\�a�hL��������=�g�Mko�}�"�6ٝ�r7{DB�(��n�����=u)=�,VWZ"����c����T�pendstream -endobj 2351 0 obj << -/Type /Page -/Contents 2352 0 R -/Resources 2350 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2274 0 R +/D [2312 0 R /XYZ 71.731 136.164 null] +>> endobj +2352 0 obj << +/D [2312 0 R /XYZ 250.633 112.478 null] >> endobj 2353 0 obj << -/D [2351 0 R /XYZ 71.731 729.265 null] +/D [2312 0 R /XYZ 201.693 99.527 null] >> endobj 2354 0 obj << -/D [2351 0 R /XYZ 74.222 678.755 null] +/D [2312 0 R /XYZ 333.258 99.527 null] >> endobj -2355 0 obj << -/D [2351 0 R /XYZ 92.274 655.841 null] ->> endobj -2356 0 obj << -/D [2351 0 R /XYZ 188.676 642.889 null] +2311 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F48 2049 0 R /F35 1567 0 R /F54 2322 0 R /F32 1215 0 R /F23 1201 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +2358 0 obj << +/Length 2480 +/Filter /FlateDecode +>> +stream +xڍk����� +# p6�护��v9��6E�mES�D�l�pDi��_�����=,G3��P����*�,��q�*���;���֑lg4��>��Y�UƲX�v�U�S�%�D +�Fb�+���|�Ͻ�6[k���И>�*�i��p����|���_?|��F2aY*�<���:�H��y����0���!�ukz�̋�Um�hշ�,:�� +�0[�'E��x��c�l�����sϠA�R�y�=�ܸ-/�k۞�Zia�v��I48!Z�,HPՈ�t���<���ss�ӌ,�c�kEi6Dg��`��Ǚ�1��ܐ[����2N��ty����V��G���[���2���ۈh�<����T���I9Ԛ�������G�������� ��� ֨%.m���8��<#Aەwյ��t�a�{IL��.N����ޑ��3Щ�p:������r�2�V. + ��n���a����-�h��>�`�1�xN�ε�#J|k� �d<or��+%S�M)u�7"X?���E�{]���"�6|=��2�s�cf�r�u�a?�����z�2�D�N� b(���L0�����$]n�_�@�N�q�Z������\��r�����CKg�#�{R�ܓ��(�{�Yu`O����㘥������i�3���)b�B�D�hC3@�!$�KOG���'��S��Wz>�?�{t����(��8CA ��Ot�FW�il�T�4�1x]��|�NA�����=ԾC[U�'�͵�ޡ� +?�V�E(G����B\$,��͖�9�D��?!�2z/pv�D�Vy�`��/� ��W��}~�x$�� +�|���G��^���#�ܫJ��q�ښ�>zm�GB�����HԳ�ŝ�q���\pW:��`�K���XN��o���>��D��%���"[����}��dDX+��I�"���H�8s�K�xl��7�@���rFiۿ� ��0P�ӷgB�Y���"�"Nu�t��:O�7�g�SX��M��v�3����2��r���� ��m����hD�Ӳ��GG/_�8eI�+���^�vi���1b��`G^�Cqs;�����"�4G�"ʺ��"W��]����0�V��|GU KcS�|���+I0�0� e��(�.�L�~>x�0�;��h�'�H��Q�v��-e)4��*�� B߫F����,����[mH,I�wg�0b���ڬ��cM-. �2��1N�g]��]w��<�v0�}���r�D�{�֒��8T���nr�C��2q�D��Èt�H��8�����8�su�}�y�����q���I��n�a�0eQ�}T��7�����܈lzϾ�i�� a\AȶI��� +���r��#�;�(���0���5rU�)$�r$>��F(?VX�s�C���'"��ICm _���m�)o%W���#��X8�9��r�X�<89E[�u��F�����>W0��+�;�Y +_� �V����k4�����������������|��Y*[�Tyٯ��y���ZH&]ƺ5��nnuk��D�h���Pp4��!�P��s]9,6,K��:/kk[mz��J4%��?�ؽ�^ /c�j`4T�>Wj�ݳ6�ږ�Ȱ�.�Q +��u�ڵuK��� ���c�4`a������ �6���G �;`�;��Y�'F�w�(�\ +�����'����6�n� +>�z�!�t?@����K�ᇠ&�՝gW:�ƈi�Oƙ���8�1{o��@&�������>����B������ G�.m��ݒ_)�\�,L�/�Ջ���l���vч�oex���L���p�U��/ ���-)���i����>O�o�2���@������1�:�pi��5D��j�.6�^�$���=��+/��k������/HT�4B�-5���Ps�N��L-N-466���$�Yx"z��a\�5�a��k�`���sq��mv��6m��|R4�#��-��m��-lh�,"{�k Y1������M��>R~<[|�K`����G���8ꛁġ�uwE.}��!)�����f������"��+�,��6�B]��>Kg��La�B��V;(GN�?��u��d]VN��6�X,Å�m��8�dܩ�-�7(+a��Ib��w�<ѝ��S������C߯2>�d(�1���+D�h���謮�A���ѩ�핽|ڵ5�K��UX ڿ��K�>���s�B���y&ď*���]���Ş�Tt'��8! �"�JI���� O��]�8q����� %��+�Q(|[��y[�#��S����yn6��Cf����pR�� +�xvIB��j�$��r *��s��k�R�9�\����|n���Е�VWԌ�v���%�ɛ?�M$W��E"e��L�X\��{��� +5�endstream +endobj 2357 0 obj << -/D [2351 0 R /XYZ 248.13 642.889 null] +/Type /Page +/Contents 2358 0 R +/Resources 2356 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2310 0 R +/Annots [ 2388 0 R ] >> endobj -2358 0 obj << -/D [2351 0 R /XYZ 448.319 642.889 null] +2388 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [203.962 141.465 257.754 150.376] +/Subtype /Link +/A << /S /GoTo /D (security-webserver-access) >> >> endobj 2359 0 obj << -/D [2351 0 R /XYZ 134.236 629.938 null] +/D [2357 0 R /XYZ 71.731 729.265 null] >> endobj 2360 0 obj << -/D [2351 0 R /XYZ 241.553 629.938 null] +/D [2357 0 R /XYZ 71.731 718.306 null] >> endobj 2361 0 obj << -/D [2351 0 R /XYZ 71.731 628.498 null] +/D [2357 0 R /XYZ 71.731 675.354 null] >> endobj 2362 0 obj << -/D [2351 0 R /XYZ 280.437 599.054 null] +/D [2357 0 R /XYZ 71.731 651.691 null] >> endobj 2363 0 obj << -/D [2351 0 R /XYZ 400.465 599.054 null] +/D [2357 0 R /XYZ 77.111 642.192 null] >> endobj 2364 0 obj << -/D [2351 0 R /XYZ 71.731 578.964 null] +/D [2357 0 R /XYZ 71.731 630.821 null] >> endobj 2365 0 obj << -/D [2351 0 R /XYZ 71.731 552.827 null] ->> endobj -1312 0 obj << -/D [2351 0 R /XYZ 71.731 509.823 null] ->> endobj -174 0 obj << -/D [2351 0 R /XYZ 337.12 476.513 null] +/D [2357 0 R /XYZ 363.851 619.278 null] >> endobj 2366 0 obj << -/D [2351 0 R /XYZ 71.731 470.386 null] +/D [2357 0 R /XYZ 425.741 619.278 null] >> endobj 2367 0 obj << -/D [2351 0 R /XYZ 353.774 457.584 null] +/D [2357 0 R /XYZ 71.731 599.188 null] +>> endobj +166 0 obj << +/D [2357 0 R /XYZ 215.669 568.468 null] >> endobj 2368 0 obj << -/D [2351 0 R /XYZ 483.407 457.584 null] +/D [2357 0 R /XYZ 71.731 561.27 null] >> endobj 2369 0 obj << -/D [2351 0 R /XYZ 285.361 431.681 null] +/D [2357 0 R /XYZ 178.553 550.535 null] >> endobj 2370 0 obj << -/D [2351 0 R /XYZ 119.533 418.73 null] +/D [2357 0 R /XYZ 347.94 550.535 null] >> endobj 2371 0 obj << -/D [2351 0 R /XYZ 437.069 418.73 null] +/D [2357 0 R /XYZ 71.731 532.503 null] >> endobj 2372 0 obj << -/D [2351 0 R /XYZ 117.159 405.778 null] +/D [2357 0 R /XYZ 71.731 532.503 null] >> endobj 2373 0 obj << -/D [2351 0 R /XYZ 419.102 405.778 null] +/D [2357 0 R /XYZ 71.731 513.262 null] >> endobj 2374 0 obj << -/D [2351 0 R /XYZ 355.405 392.827 null] +/D [2357 0 R /XYZ 71.731 481.629 null] >> endobj 2375 0 obj << -/D [2351 0 R /XYZ 71.731 386.062 null] +/D [2357 0 R /XYZ 240.44 457.883 null] >> endobj 2376 0 obj << -/D [2351 0 R /XYZ 115.56 361.943 null] +/D [2357 0 R /XYZ 71.731 444.932 null] >> endobj 2377 0 obj << -/D [2351 0 R /XYZ 153.506 348.991 null] +/D [2357 0 R /XYZ 181.256 444.932 null] >> endobj 2378 0 obj << -/D [2351 0 R /XYZ 343.016 348.991 null] +/D [2357 0 R /XYZ 336.036 444.932 null] >> endobj 2379 0 obj << -/D [2351 0 R /XYZ 71.731 336.04 null] +/D [2357 0 R /XYZ 470.054 444.932 null] +>> endobj +1339 0 obj << +/D [2357 0 R /XYZ 71.731 404.917 null] +>> endobj +170 0 obj << +/D [2357 0 R /XYZ 206.856 367.701 null] >> endobj 2380 0 obj << -/D [2351 0 R /XYZ 163.765 310.137 null] +/D [2357 0 R /XYZ 71.731 357.558 null] >> endobj 2381 0 obj << -/D [2351 0 R /XYZ 71.731 302.999 null] +/D [2357 0 R /XYZ 120.303 347.577 null] >> endobj 2382 0 obj << -/D [2351 0 R /XYZ 71.731 254.182 null] +/D [2357 0 R /XYZ 71.731 314.536 null] >> endobj 2383 0 obj << -/D [2351 0 R /XYZ 71.731 223.064 null] +/D [2357 0 R /XYZ 71.731 270.7 null] >> endobj 2384 0 obj << -/D [2351 0 R /XYZ 71.731 197.993 null] +/D [2357 0 R /XYZ 71.731 270.7 null] >> endobj 2385 0 obj << -/D [2351 0 R /XYZ 71.731 176.837 null] +/D [2357 0 R /XYZ 270.634 259.905 null] +>> endobj +1340 0 obj << +/D [2357 0 R /XYZ 71.731 252.767 null] +>> endobj +174 0 obj << +/D [2357 0 R /XYZ 188.593 215.552 null] >> endobj 2386 0 obj << -/D [2351 0 R /XYZ 71.731 156.912 null] +/D [2357 0 R /XYZ 71.731 208.199 null] >> endobj 2387 0 obj << -/D [2351 0 R /XYZ 458.479 145.255 null] +/D [2357 0 R /XYZ 99.301 169.524 null] >> endobj -2388 0 obj << -/D [2351 0 R /XYZ 207.921 133.599 null] +2389 0 obj << +/D [2357 0 R /XYZ 319.328 143.621 null] >> endobj -2350 0 obj << -/Font << /F33 1278 0 R /F44 1994 0 R /F27 1180 0 R /F35 1525 0 R /F55 2249 0 R /F23 1173 0 R /F48 2006 0 R >> +1341 0 obj << +/D [2357 0 R /XYZ 71.731 128.513 null] +>> endobj +2356 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F35 1567 0 R /F54 2322 0 R /F48 2049 0 R /F23 1201 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2391 0 obj << -/Length 2486 +2392 0 obj << +/Length 2591 /Filter /FlateDecode >> stream -xڅk����� -��X�D�})\�4� H��E��-Ӷ����q��w�3�e����!9�r\��'W�Y�*�J�Uyz�����F�Lp�}~��Q�*D�F���*��(�U)�'j���w��Q�{Ӯ7* %h��t���9������?�?���yd�D�(��\g!�ʮ���� ���o�<̓W��P�z-��Ҥ1fG���k����u��GC@���Z&���<T���P��-���ѽ'�; gg�kz���Ζ��4���/� �"�;�3�^o 8���{�V���T�`���� ->Um?�&��5eo�Mϭ=���L��Qp������.F���%�g�\nΈ|�x9A�����k���N�BX-� N�����rrn09[�<�p�f�ȞMG����c�Kg wT���"��J�$x���jJ3����A��t�Wk z���c<���.,�ދ`Nb<$��"�}�Y`�Y5;H\�J=��)Z%��e�F7�/����tN������d5��#Um:�PY��0�� 6�)z��S�)H��ֶ�ui�}u ԩ�I�a s<�]��Qw��Kj*2�|'��m�^6��E��7fә��c]t�n����~�j��K�)��d�&R$Iv7|y��i��P��@��6�;��s� -�q�{���焐��ۍVp]Q���q* -�CP�5I�J(��?g�M��e�B!���%*�"�q��Ra��a��+ �����ҋ���e ���0�K�q���o��ֵ�2� ([��d�o�.�i$rO`C�(2�$�KGhz*guQ�4R7Az�Z�0������؞� 8O7�1�=��4h���<Zۏٶ#�yZ�K!E 4Ic!����0�f����!��g��?9��yG�Y=��q����Q�\�( ������aBĹ�豂��n#%��?�����-���w��(�P�]f�Ҷoh���xY+�s��"�a�j�����5 ݰ��� -�����a�崵uU�"�^/�����)E�Е�x-y��+��IW���l� Wd�8�����ĕa8jf���P���!�~�!?Y0�HFca��#�8^��w��� �ib{�,��畈�3��w=�L( -j��wr��,|�(��|�L?�Ź^�!�D�J�m�Feֈ���s�^����hg�� �"� �OSS�O -l�IE��P��"��U=-����oѹJ�0 )F�����!2L���ܤlIs��?F�fZ^�PL��X���B%�X��g����y0A��_A!N��[X������%v���4%��^�. o�j'��I~?a3�f��L�3B��]��5D.�ˇ�=�C�sB��kbK��L�X,���US_��j�����H!V�d�'��?�S�q!R%'5ے� ��ꆶ���,�DXmx:�(0��`��5m���)i:S"��C����gN�EH�%+�}��YC�Y"�XJڻ�%��'�n�ߡ"��2�[� �J�3��~#�����&��3��yȥ���E ����p�֡Ƞ�Npq�'� ��S�a��t�e�T(����0�3`yu�P�� -�YOdpR6��k-`���dJ���mE]*�1PwR� -xwB�z� �����=�t���$���j��p�]�ތHNX�������E2�ki<���43l��mO`��#�-���� �~4Nm�-6�L|�Z��N�D2V�_J]�c廨�KM����2�;=�h�����N�> }�t�� �3FET1/������c��$��s �No�����0��lå�5�:�xBڷr�vk��t���^�8�E�(��0��=�f���sB�fN�h�X�=��(Y�����L(��,�3(��+�p�sq�i�����1T���n�q����^<2�7Y����(=3V���8�Mo�w�w�GT��[�)j�q�4z[���ˬ�sA�25^���������|�������k�����M��hv�!S��^��i��Nv7�����cp4�k���i�A�]_��������e���;��ĥ0�A*��8��p�f�ƮB$c-�!��z�͝�a��AQƓl���Z���m�h�g��ͮlp�¾�PO+n"IA�w�@_i1j�;��XW>�_/ վYp7�Gq,��Z�8��Z���<�����簪f���Ƅ_�T.��Ok���b�vMu8���ܪ/!��4���P�hX�e�YƷ�o�k��/3������=�F����}ΏΚ�=�K��+��f���ث�[��k&����94a�}�*�ٶ}7}�Y����UJ�`�@oG���]�M�|��:ƩWM�c5m���y�ӵ��JCp3F�����O�OD���`������m[�\� A��&��2�T8���9�)fJ{:��ݻy2�s��e��+�⧪�>T����~~Zr�?���endstream +x��k�۸�{~�?8�护��C�����"��E�+ +Y���ʒ�G����<HI�do�~-�A��3Γ�~rIi��D�0Xd�7�b3�HK��$��O�o�?h�HD�����H�E����x��}��>=��^�U�-���CٴiQ���?u��E������7�<�L�$�7�r4��^H)� @���Xh�'ɔP�E��Au ���c����������z�5�X%���V���h�OW�[~Y�`i/��S�tul�lx�Z�e�pݕ%3��T0Օ[3�`{�t�K�i���a�_�k�ѬGD���/7��?�]>�E�6OKs�����3��{��n��2������K�|/2�oJ�hnJt������ń� ��Z��L�D����4+,O����ӏ-%B�֤2Y?6]�(��� �3Op��[���=nW��_��v�ȑL�b�������ų����Ԯ� #^��F���'�a�!Kg��t�݊ݨ~�#�jE�����f���w<��[Ǟ�(*R0,z{y�6��Ru3L��k=��j��K&�����j���(!��S�n�u�� �H�@>l�$t�n�iz�A(T�XB2³;5ۼ��U,����f[����c �^��M[>�e���]P�0�F���ឪ���L��IJie�7mvO'��?Y�.#K-�@��l�&0��f�������z�n�SH����sA�5x�i�J|�� +�c^�����T}!ĒD[�-��N�� �P�����!oƛ-�zW�yi�LG�M��iӶ���g�o��nYv�0r^��*��j�U-�H�<��(Լ�hV��sφ����X䦱3B�!���Җ�Q����3�Y�R`�T � +���n:`��-_�Cy� RVV<�r͛��g�F̢�y +�i�Z�+R�g� I�ֺSUa3�ȇod^��X�;�A�qާ�vcL霔m,��L +�;3������� ��P�oH��5D�tj*2�c�=�z���e(B_X�jzވ!���^]�i�O��_!���p5$�u����ű\ +�+/���J@\��w_���� ���g+#Z�KK�xI���E��ރg�~�b�:�*��|�����?��rp(0D �Bys���7 �.���D���J�S���q�u��h6%ä.��`�0�Ey�cΧ�Y��� �ۣ*^[g�S�p.Zs��1�Bc$T��@�|� &� ��a(���Jgl�����\��ۚ�����7�M��`�yP��C�ˑ���,�v�f���N�%�@e�������=����!;�(����>�&��"��Y8�6�2�43����pe�pݣj���æ��]Qm҂aL (��z<t#�.1dEO��\��-��q� "���%�����ddt��������˾�`�O˝��Yd�9 �w�82��N|+ҙn�u�6�ʶ�l��]@�l�LkS��=��f��� ��� �q�GK/"�H��?���Q#仩>%��㸿��;�����B��`pZ%�?[�ESY2���E����)x��Q�BX� �a���"�S� +�� �,�����H"Y���� +JԢ�V���c�fl�C�0���&�J�A`��I ���PWG 8O[�C&�LM2U�]��X��g�2+�-��4�����^�#���kg7P�q̌m̌I8����6sYđ=�)�_Ʉ� +1�����Am��IƠV�����q|! �W�Z�"з+�͵�ݑ�����}��%�qT����oȠ�3���Q�i\��|��d)�3TX>3��=_]��B�E*��ߋxO�!L�6Y �</w3��T(�j`�\���'����Uw�rQJ�Y�Y�kF4��Y>�k �Pwe�Pڠ�d�!�$������$�$�r�G�?Q!$ �<�]�7�a&�I}CE�8�;ސ�� +�O~�����ǒԃ$�'��~(��� ױ��Z3�n��k����Y��R�y��;����"�K�~ +<{��9}"d4:�}z�]Am�g���ԮBx��C�t�J���"���͈�Z p$�ʿfx�n�N�s9��]DZ`���%u������M<���J���r����������4�#)��!g �S+�oZ�ny��?���P��aSy渇�]�̹lu��d��x��{�����4�LDy���� )����@����x"�\5蚵����P�y�����G�,Gx�7�9�(�R���"E,�k�+�gx+��5X��V5$��4��������'Q�ˣ%ٌjq,���DB��z��?��O�_����ok(���A�v_Q��E�&Ahrh��^8�a [B\50\?��� јS���e�@����v�X,�p{�4�����N��v;�J�5�CvQ���n]�C#�k7lI�$f���3�ڧ���+��o^���������\����`�Smm�Ձ���^w.졤�4�O�W���o�����a[J-��[�Ds-�;����3�^���x�7�1�����/��P[`0�e����@A���&d ����������endstream endobj -2390 0 obj << +2391 0 obj << /Type /Page -/Contents 2391 0 R -/Resources 2389 0 R +/Contents 2392 0 R +/Resources 2390 0 R /MediaBox [0 0 609.714 789.041] -/Parent 2274 0 R -/Annots [ 2397 0 R 2400 0 R 2405 0 R 2414 0 R ] ->> endobj -2397 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [166.345 651.457 218.649 658.311] -/Subtype /Link -/A << /S /GoTo /D (security-webserver-access) >> ->> endobj -2400 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [291.365 562.008 339.793 570.919] -/Subtype /Link -/A << /S /GoTo /D (troubleshooting) >> +/Parent 2310 0 R +/Annots [ 2395 0 R 2396 0 R ] >> endobj -2405 0 obj << +2395 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [194.362 457.001 239.281 466.022] +/Rect [304.902 687.258 339.771 696.169] /Subtype /Link -/A << /S /GoTo /D (parameters) >> +/A << /S /GoTo /D (http-apache-mod_cgi) >> >> endobj -2414 0 obj << +2396 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [474.039 382.282 518.87 391.193] +/Rect [409.198 687.258 447.385 696.169] /Subtype /Link -/A << /S /GoTo /D (extraconfig) >> ->> endobj -2392 0 obj << -/D [2390 0 R /XYZ 71.731 729.265 null] +/A << /S /GoTo /D (http-apache-mod_perl) >> >> endobj 2393 0 obj << -/D [2390 0 R /XYZ 71.731 718.306 null] ->> endobj -2394 0 obj << -/D [2390 0 R /XYZ 71.731 675.303 null] +/D [2391 0 R /XYZ 71.731 729.265 null] >> endobj -2395 0 obj << -/D [2390 0 R /XYZ 358.177 664.508 null] +178 0 obj << +/D [2391 0 R /XYZ 242.365 708.344 null] >> endobj -2396 0 obj << -/D [2390 0 R /XYZ 461.001 664.508 null] +2394 0 obj << +/D [2391 0 R /XYZ 71.731 699.706 null] >> endobj -1313 0 obj << -/D [2390 0 R /XYZ 71.731 636.513 null] +2397 0 obj << +/D [2391 0 R /XYZ 71.731 687.258 null] >> endobj -178 0 obj << -/D [2390 0 R /XYZ 166.615 597.24 null] +182 0 obj << +/D [2391 0 R /XYZ 236.615 659.029 null] >> endobj 2398 0 obj << -/D [2390 0 R /XYZ 71.731 586.875 null] +/D [2391 0 R /XYZ 71.731 651.831 null] >> endobj 2399 0 obj << -/D [2390 0 R /XYZ 258.543 577.116 null] +/D [2391 0 R /XYZ 71.731 638.939 null] +>> endobj +2400 0 obj << +/D [2391 0 R /XYZ 71.731 628.976 null] >> endobj 2401 0 obj << -/D [2390 0 R /XYZ 71.731 562.008 null] +/D [2391 0 R /XYZ 115.118 613.2 null] >> endobj 2402 0 obj << -/D [2390 0 R /XYZ 71.731 547.064 null] +/D [2391 0 R /XYZ 429.318 613.2 null] >> endobj 2403 0 obj << -/D [2390 0 R /XYZ 71.731 498.012 null] +/D [2391 0 R /XYZ 71.731 611.044 null] >> endobj 2404 0 obj << -/D [2390 0 R /XYZ 321.927 485.061 null] +/D [2391 0 R /XYZ 147.188 595.268 null] +>> endobj +2405 0 obj << +/D [2391 0 R /XYZ 314.747 569.365 null] >> endobj 2406 0 obj << -/D [2390 0 R /XYZ 349.018 459.158 null] +/D [2391 0 R /XYZ 71.731 562.227 null] >> endobj 2407 0 obj << -/D [2390 0 R /XYZ 415.603 459.158 null] +/D [2391 0 R /XYZ 71.731 477.808 null] >> endobj 2408 0 obj << -/D [2390 0 R /XYZ 91.925 446.207 null] +/D [2391 0 R /XYZ 155.056 451.905 null] >> endobj 2409 0 obj << -/D [2390 0 R /XYZ 151.7 446.207 null] +/D [2391 0 R /XYZ 89.664 438.954 null] >> endobj 2410 0 obj << -/D [2390 0 R /XYZ 71.731 439.203 null] +/D [2391 0 R /XYZ 71.731 436.797 null] >> endobj 2411 0 obj << -/D [2390 0 R /XYZ 264.224 428.274 null] +/D [2391 0 R /XYZ 71.731 421.853 null] >> endobj 2412 0 obj << -/D [2390 0 R /XYZ 95.243 402.371 null] +/D [2391 0 R /XYZ 130.903 400.697 null] >> endobj 2413 0 obj << -/D [2390 0 R /XYZ 71.731 395.233 null] ->> endobj -1314 0 obj << -/D [2390 0 R /XYZ 71.731 367.338 null] +/D [2391 0 R /XYZ 74.222 359.452 null] >> endobj -182 0 obj << -/D [2390 0 R /XYZ 381.468 324.24 null] +2414 0 obj << +/D [2391 0 R /XYZ 92.274 336.538 null] >> endobj 2415 0 obj << -/D [2390 0 R /XYZ 71.731 311.802 null] ->> endobj -1315 0 obj << -/D [2390 0 R /XYZ 71.731 300.524 null] ->> endobj -186 0 obj << -/D [2390 0 R /XYZ 193.715 263.309 null] +/D [2391 0 R /XYZ 188.676 323.587 null] >> endobj 2416 0 obj << -/D [2390 0 R /XYZ 71.731 252.944 null] +/D [2391 0 R /XYZ 248.13 323.587 null] >> endobj 2417 0 obj << -/D [2390 0 R /XYZ 71.731 231.065 null] +/D [2391 0 R /XYZ 448.319 323.587 null] >> endobj 2418 0 obj << -/D [2390 0 R /XYZ 71.731 231.065 null] +/D [2391 0 R /XYZ 134.236 310.635 null] >> endobj 2419 0 obj << -/D [2390 0 R /XYZ 101.32 221.565 null] +/D [2391 0 R /XYZ 241.553 310.635 null] +>> endobj +2420 0 obj << +/D [2391 0 R /XYZ 71.731 309.196 null] +>> endobj +2421 0 obj << +/D [2391 0 R /XYZ 280.437 279.751 null] >> endobj 2422 0 obj << -/D [2390 0 R /XYZ 71.731 211.423 null] +/D [2391 0 R /XYZ 400.465 279.751 null] >> endobj 2423 0 obj << -/D [2390 0 R /XYZ 416.305 198.651 null] +/D [2391 0 R /XYZ 71.731 259.661 null] >> endobj 2424 0 obj << -/D [2390 0 R /XYZ 71.731 173.58 null] +/D [2391 0 R /XYZ 71.731 233.524 null] >> endobj 2425 0 obj << -/D [2390 0 R /XYZ 71.731 152.71 null] +/D [2391 0 R /XYZ 71.731 190.521 null] +>> endobj +186 0 obj << +/D [2391 0 R /XYZ 240.64 159.801 null] >> endobj 2426 0 obj << -/D [2390 0 R /XYZ 71.731 134.028 null] +/D [2391 0 R /XYZ 71.731 152.722 null] >> endobj -2389 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F35 1525 0 R /F23 1173 0 R /F44 1994 0 R /F32 1187 0 R /F58 2421 0 R >> -/ProcSet [ /PDF /Text ] +2427 0 obj << +/D [2391 0 R /XYZ 71.731 139.711 null] >> endobj -2429 0 obj << -/Length 1997 -/Filter /FlateDecode ->> -stream -x��]�۸�=��EW.V\}�N��z{�+i���C�(h����IA��8��f8#Y�כ��0 ���p��p�/���c�DKe�ؽ f[Xy�&d�Q� ���7?��l)�Y<[mfI��|�ǑX��lU���K%[����� ���{+���[��~��F����뛧��4�s�\į�5�\��"�Q�0LDr'��k-��w����t��,C�`懡���!��ς�����;�R�eݩ����3���Dd�m���7�I<�i�(����m���wj���V����D��N7�XD��{o�zK�p�5JE��q>պ4�0�=� �J���HK@%�Q�}�G��pf����w����ս��ڎ��[�m�hi5aI��4���T�o�Q��������� �m�q�:�9o�<F���1�rokN'�Y�:�<�ia�|��|�ɦ7٪�J���* <{�Yc�~@���Bj�Le߫r��o�C��F�v�� ���ȟ�k����Aem����p8̳��,@68��0B1zxz��k��Q:��\#�&�(��Z�K��yx|B�V�.�g��)��e�@�@I=����;��A('���(����\˩����1F�N��������Q`�߷��,s��m'[��2|�zہ�f�\1�T#mmt_�-1G�&&&��H,Ӑ�d���Q�����s��w軥�w�֞���6GT����WO��o��HӅѶ3��[������� -��������jA�:E �Y����$������Զ�P�v�,����^f�|)� �%9xX�|���?�qyz�bd�?����b)�,y���w��[^�}A��8�;��;^�h�kD í�A.��!Ѧ��% F��!5z��,M8G�w����(�����?�s���W��n]�?�8�. �*.S�(d�y՟Y��ucУ��̛�"����{¹i^F��t˼�m�Wx_��v�LJ_h;����#Sk;�(ξ�u��5h���Bhҙ�+��R�7� �@Fhb��Γ�ܰS;�� m@��^7� �a��4�5�o��d'�Y7R?_��K��u/�.��ueaEV`FA�?�nZV?N�"���B����S������efy�A�[ū��G<���Sp�N{jr�8�\xz#�����/t����AGr��'/c)�iv��{�QY�B�}]�:'ؑ��uɶ'�� �Ht<A)$�x�F�KS�;S��?@���5����&R���&�a� --N�ۃZ� ��oJ���,8�o_��j�E�'G�j�����/4pP0�8��[�~E�v�n�K(^%�R� �+�,���Rm���&��QN���c�g�O�7��L���X���]��b6F��1�c��U��� 7,f�^A���4jfd�)�!Q��;� -;��iToh���ٞ�Fc��(T�4 -��E)�~z����������4��|�y*kk�;�=��Ý r�N]�x��+U��9?՜�A����~g�r���Mx5=�-��=ks��'�K-|�%M�i26�17�.g!� ri��w�F�w��[cJ����Զ���I�u2*]q���G�;�Z� -��jZ�v���Ht��f�����:W�X�` -tX�3��cN��d�7Y���=��i��['Ƥʻ�O�\��+��1*ձ��+j�&>k��Wj~��(�E_8���O�A0���������4���v,~�2���ZnO] -(T�g�RG%�9h6\W3��·t���9�W�%̆����PFp�/��܌���̐�����U+�4�;p7&t���_���%� u�S:먁1H��$���1熘�=?J���Ύ�Ħ�������x��+�K�ʝ����x�Pd!]&Ҕu����Ń>�?:�'��G���A����������g�8�"�������́�s��X�i_{�=�\=��Qk#w_�n��^�� 5��endstream -endobj 2428 0 obj << -/Type /Page -/Contents 2429 0 R -/Resources 2427 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2274 0 R +/D [2391 0 R /XYZ 71.731 129.749 null] +>> endobj +2429 0 obj << +/D [2391 0 R /XYZ 115.118 113.973 null] >> endobj 2430 0 obj << -/D [2428 0 R /XYZ 71.731 729.265 null] +/D [2391 0 R /XYZ 429.318 113.973 null] >> endobj 2431 0 obj << -/D [2428 0 R /XYZ 71.731 718.306 null] ->> endobj -2432 0 obj << -/D [2428 0 R /XYZ 114.77 708.344 null] +/D [2391 0 R /XYZ 71.731 111.816 null] >> endobj -2433 0 obj << -/D [2428 0 R /XYZ 114.77 696.687 null] +2390 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F48 2049 0 R /F35 1567 0 R /F44 2037 0 R /F54 2322 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 2434 0 obj << -/D [2428 0 R /XYZ 114.77 685.031 null] +/Length 2960 +/Filter /FlateDecode +>> +stream +xڥko#���>8 ��}?����&W����sIPP%m����rOq~}g8�}Jv��`,9r�'u��"vE���K������Y`����kFYp�n���E*��_<����4^ľ'��[<�~X~y��V�j����},-�<+4h�ey.W?=}s��SG4�c�&��|Q$< ���z��;�����{ޭ +yv'%���`18�Қ~;ڼ�U�I*�(Ѿ��H7��h�/�\y����-+�e}�:[�˲`���/e�Z?j]�Ķ,�4��q�\�Ҥi7��t��C�GU3IYUuYՙ�8�L��-f /�2�a%��1Jy�G��.H�pe������R�/4�a�;��t̚�ڏ��c��;o�7?J�m���y)ɓrO�F���_�Zmu �� �_���gX��sGd�\x���4X~FY.�_�J�MI��k��v?� +����F(��� ##p Lפ?�8�щڋY'�r��J��\u��Y���9#���'`G��4F�L�$�ҔьR�續(�yZ�\��j�M��Z�b�!fP�;/`(�9��XE�r攮�X�@� 5���?9�x�7��3��o�O#���i�/j���|��Ww��X��q�WΠ�/���ܬ�$I��@4��6 +�W�a��\�ul���*����Ù��n����O� ��ݢ)�ۋ����RM[+���4zA#��g�UF`+�$w�;����"��e�]��>�>���4�i� +f�ڑXNj�� r_��QY,�(h��`W �4�p�+���7�b`2]J1���l���|�p� p������i 0'�7ȡ5AN�A�v�A85� �� �K�:>BL��'�g�~��,�3��|�;�S~��d0��}2jvF�����ߪ_�� +q�Lsww��w64�j�gN�!��$ ^���k9ۢ ����}�֛9{J{���^�h���ύ�m�"O��D���"o �4���H�L@o��i0ݖEC��wX�~� +�%�QN� �`�8�ev%� �N��R7/�M��ѡ.ۊ�2�W�fM��� 1A& +)7���!�!��-��#�`������q�� +M��z�����L���1ԏ��ˊ�q�dL�d�ᙡ/��"�ҁU.���հoB��[���v N�s2�B`GɅ��6v� �ZS�ᲰkH�~!��i�J�M�l8>��[]��lk\����p��\rr-W+���'��me���G0�-���OE��r�w���(B���� %�[���ê �����l�8����ۢ��� l����2`����.��*� �������U����6��&�������Q���� +�n�z�e.���������j�Ez����P���NdS��zR��W`�'q���U���v���g2-�>��s�Qr��6�c�b�S�Z��y]�e=�1�c��h| +j�G�g��]M/����ΠD��tD~\�@x�U�Q��^w83���|F;U��P���w���.�k>�tQ����A�A���s� C���B^��"P�9��� F��|����|g"x�l�� +,�/�a�������3��.�i6�& ������$B���F#o�q����zP��@���(��<츝��d -m��G'a�j�5�Qr�9��9`��Uj'h|Ϟ���C���o�Mw�[^�M>�8���u�p(O�v�OQ#I����]U\qU?+�^w��W�o��bo���3W����m�H����MB�V����m5G���z��N��i'�3�@[.s�m��8���6��03*3����M(��;}����$�K�[�{WJ���dDX�[�Z���'�{��c[��5�jP�x�j$'�� �[���1��`��z��m����>5�]V���o�,ٕ�� +�� +B�7��/I���L(7���j0s��� +���Q ��gӭM�]B�$�����l���n�Ş��L�>1ɣ��B���a+[[H�ci��V6֬k�^��� �����,-k;�������z%�`��FU0��j�P3'�v��������n6N�1D�a~��X�.�Æg�~���ZB��M ��Ύ6�6�ֺc�Ia�����I����\�]��3�~�zm�|�0b`�!~ �K�Ġa�$�fḋ�Zj���M���g�r�!��ݎ�]����?1n����YfL��ҷ˙�Rp��:<醣�$�М�#<֡�۹�^����'�-8W��b��������bH~����BQt��f@&��Z�-�g���p�s�h(~�-�>�-�,��T�-�*�"Ng�L��q�����f> +m^�p<�ITA�ʣ�o�*��z��>9S� A�nX��RH�5��`�` C��2� dD�j�P'՟�=jBە��}��Yf�% lT��k�W!����)�-�~��`��l�)#��?��1�6e� ���F�O�����5)_��%���gh^��#h��y��z�k~�o�ݜ��~7'>��yc��g�~G��w��+L&Up��<�2�� [^�x@��p8m�zD�fā��������ùmuYk����6�x���i$�beuY�A,��N��<Bq�$�b��&=��֞��y�C����M�ghO���f���\2K����l���� +f�?6<b$�"~����o0�03��k~�ʊ]��@����x{,�f�� �m-��3�u����gf��l���H,⣦�GU7ea�c�U�.�f�G��4x������1���� ~p����� +� J�jO:$�����0��z[[�"�eZ ��NPM��k�C{a ��L�chD�C��r��c[���P8�9IH|��y� ��N/��$"q�W��Qf�_$�&���!�\7��@��(�uendstream +endobj +2433 0 obj << +/Type /Page +/Contents 2434 0 R +/Resources 2432 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2310 0 R >> endobj 2435 0 obj << -/D [2428 0 R /XYZ 114.77 673.375 null] +/D [2433 0 R /XYZ 71.731 729.265 null] >> endobj 2436 0 obj << -/D [2428 0 R /XYZ 71.731 661.719 null] +/D [2433 0 R /XYZ 71.731 706.187 null] >> endobj 2437 0 obj << -/D [2428 0 R /XYZ 71.731 641.793 null] +/D [2433 0 R /XYZ 71.731 691.243 null] >> endobj 2438 0 obj << -/D [2428 0 R /XYZ 369.099 618.481 null] ->> endobj -1316 0 obj << -/D [2428 0 R /XYZ 71.731 590.585 null] ->> endobj -190 0 obj << -/D [2428 0 R /XYZ 246.48 551.213 null] +/D [2433 0 R /XYZ 132.516 670.087 null] >> endobj 2439 0 obj << -/D [2428 0 R /XYZ 71.731 541.07 null] +/D [2433 0 R /XYZ 254.242 670.087 null] >> endobj 2440 0 obj << -/D [2428 0 R /XYZ 71.731 500.105 null] +/D [2433 0 R /XYZ 76.712 653.45 null] >> endobj 2441 0 obj << -/D [2428 0 R /XYZ 71.731 500.105 null] +/D [2433 0 R /XYZ 136.488 609.904 null] >> endobj 2442 0 obj << -/D [2428 0 R /XYZ 71.731 495.123 null] +/D [2433 0 R /XYZ 329.949 601.44 null] >> endobj 2443 0 obj << -/D [2428 0 R /XYZ 89.664 472.309 null] +/D [2433 0 R /XYZ 71.731 567.863 null] >> endobj 2444 0 obj << -/D [2428 0 R /XYZ 290.096 472.309 null] +/D [2433 0 R /XYZ 71.731 538.817 null] >> endobj 2445 0 obj << -/D [2428 0 R /XYZ 71.731 457.201 null] +/D [2433 0 R /XYZ 92.274 520.884 null] >> endobj 2446 0 obj << -/D [2428 0 R /XYZ 89.664 441.425 null] +/D [2433 0 R /XYZ 188.676 507.933 null] >> endobj 2447 0 obj << -/D [2428 0 R /XYZ 71.731 439.268 null] +/D [2433 0 R /XYZ 248.13 507.933 null] >> endobj 2448 0 obj << -/D [2428 0 R /XYZ 89.664 423.492 null] +/D [2433 0 R /XYZ 448.319 507.933 null] >> endobj 2449 0 obj << -/D [2428 0 R /XYZ 71.731 400.578 null] +/D [2433 0 R /XYZ 134.236 494.981 null] >> endobj 2450 0 obj << -/D [2428 0 R /XYZ 255.817 387.626 null] +/D [2433 0 R /XYZ 241.553 494.981 null] >> endobj 2451 0 obj << -/D [2428 0 R /XYZ 511.98 387.626 null] +/D [2433 0 R /XYZ 71.731 483.579 null] >> endobj 2452 0 obj << -/D [2428 0 R /XYZ 482.926 348.772 null] ->> endobj -1317 0 obj << -/D [2428 0 R /XYZ 71.731 328.802 null] ->> endobj -194 0 obj << -/D [2428 0 R /XYZ 234.86 291.467 null] +/D [2433 0 R /XYZ 71.731 456.959 null] >> endobj 2453 0 obj << -/D [2428 0 R /XYZ 71.731 281.102 null] +/D [2433 0 R /XYZ 71.731 442.015 null] >> endobj 2454 0 obj << -/D [2428 0 R /XYZ 71.731 251.253 null] +/D [2433 0 R /XYZ 470.122 432.515 null] >> endobj 2455 0 obj << -/D [2428 0 R /XYZ 71.731 215.387 null] +/D [2433 0 R /XYZ 71.731 425.539 null] >> endobj 2456 0 obj << -/D [2428 0 R /XYZ 71.731 204.48 null] +/D [2433 0 R /XYZ 101.619 405.915 null] >> endobj 2457 0 obj << -/D [2428 0 R /XYZ 71.731 184.555 null] +/D [2433 0 R /XYZ 71.731 380.608 null] >> endobj 2458 0 obj << -/D [2428 0 R /XYZ 369.099 162.65 null] ->> endobj -1318 0 obj << -/D [2428 0 R /XYZ 71.731 134.755 null] +/D [2433 0 R /XYZ 101.619 365.965 null] >> endobj -2427 0 obj << -/Font << /F33 1278 0 R /F35 1525 0 R /F58 2421 0 R /F23 1173 0 R /F44 1994 0 R /F27 1180 0 R >> -/ProcSet [ /PDF /Text ] +2459 0 obj << +/D [2433 0 R /XYZ 230.398 354.309 null] >> endobj -2461 0 obj << -/Length 2694 -/Filter /FlateDecode ->> -stream -xڅk�۸�{~��_"l�D=}- -$M{ȡ8��E�h���Ȓ+��,?v�V�p8���h�_4�#����+��tV�߅�-���.���,'8_�=�=�g+�����f�D�Z�<֪H���w�ם9��/uZ��s���]����������?/?����xh�jU�o��q���,JT�dș0�U�DęV�J�����s r����"Q8[�PE:�-��2�����wuᛠZ�p��co;�-M��e���z{�,�\�Z��j��cm���;MӴ�(��{����y�6����m���Խ�� -;3�a����倽�(u��*eE�?�-��E��A�$Z HXӕ;�3���oi����'�ۏ밡��vo�w�E�Ag�c=>�H����j��i�x��s��_8�E%��x#+Ob�q��<tm }� -�f2|�Ol�:�w!�t>+ۗ�[��p -:��p��j�,�"UD�C�8� {��Qo !���rpm�g�*��N/r&�ۧ�ۧ���|���8�^6m'��K^'����Pß/��y�Z<�����k����K�Lb����Q��(�r�Q��!��,��W&1����U��C���؛�B�5C�뚽ѡ��r��������FCTŲk���yb��;ϳ��s��՛���vC xB�5v�!*�?8Z��~��z��٦����9�z��>C9���e@�驑U7x,����R��]�dK@�Ig9�$�Heъ���wda��Ƨ����s{)�`�����\��v�0ʟ���O�Vj)�<j�2�TZpj��쏌�$L�B`��2�`����낆�K>�M���y/F(Y���`�)H6�âyc��P��ǠD�,T$*y�о��0�3ڳ=����n#��ْ���B�(a��(|�g�Z�@�D�b���lL�z��j�Խ`Pߒ�H�)�f.�¤i��J�c*>���s�@\��q -:ֲ���]����6�H�����l���:9��C�"�u���惸�9��skQ��Զ� ������}4�.t ة�]�J -�%�^�b �R��5%�3T��"}��U` ]�"x�9�����+nI��햲�/��L���B�Qkl�@��'�;��n����匑�dK V��r�(9�dG��T4Ў9��t�x5U�l��Z�K�`[mK�B䛹��O�<>���$���/�:v3�G�2���ߦ�e���n?>?�N�y9��f�48>Ft�K��� .ˡ���~9�~�*�%��0��=��{]�ăͰ1�y�2���F����6[L4^[��Ǿ�~�m�l���JS�r=�3O�����UB퀜`��ٿ�Qĩ���wG~ �Qљ�z�<�'�eO������'���H����s��D���߫0�T��������&��f��C�mܑ�N�ȴ`�!iwO��<�dħQ*'ҝIu�x��V��_��!��:*��6�nhwݖ����N��$�5jq'h@���NXl�ei����&�Vn��5�^��:ȹwdp���}?yi�n��q��c҈s`���bVӭ@'�kF;�4y��w�<Q����<��u�� �e�r��=�|E��*�:�ǔR����t�˚cE�H��Q���M������o8�v �*^\w�������g���A{l��X���z� �M��.9�$��Pꯪ��3\m�@������<9A��5s�.�\F�/���qX��n�[<H3��>�48��; �H:i�9���<6��$JbǑO/�����$]�(/��q[Yt�U����X���%���Os(�����#p��S����d?�c����"��{�2�</9��a���u����� �3�����Z����Etqa�}�=9��2�-�����g#�ᥪ�pA����C�v�������C���\�J�(��i!����%�7}/�tY����d"��+�v�0������7Ā�\���Z� -�1 J��"�b4d7�͍��~�S|+k���pF�?��FVm��m#��*��䖋=�H����z쵯��>5�X��$����n�`>��U��V�C{��-�I��U<�.eǭZ�����`��h�ϡk ���n=jôܣ71~��gD�w�����֚�1+��@عc��`�*��Wt|�P��$o�;���-o� #ؔ�oO+|��1�Ե�ҭ��@�J���ط��0�-CR�l���o�Vd"�~4��̯�XL%��Bɔe{�NP����;j6� -M�Κ�̓1O�"%�������"�p�Z��_nfpDN5��Vr���$/v8��P��o� -�^8�p��|�!�YKD���*I���6J��FP��/�\���t����_���ev�s6��) �k�0�|ns75��'������:<��Zr����$��_ ȞD��q�����<t�&˅�Q��r'4F{��t⛏�_`�:�#1 -+ފS$N?l������������$���-��M���{9� ��TLO[U3z������m�����x���L�4>e�{��>�����P����9IC_���8�u����p��;� �r��-_~�J -U�E�_�.(w?�p�ґ -�)�_�U����o9endstream -endobj 2460 0 obj << -/Type /Page -/Contents 2461 0 R -/Resources 2459 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2487 0 R -/Annots [ 2465 0 R ] +/D [2433 0 R /XYZ 491.421 354.309 null] >> endobj -2465 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [235.966 659.657 287.048 668.568] -/Subtype /Link -/A << /S /GoTo /D (whining) >> +2461 0 obj << +/D [2433 0 R /XYZ 71.731 340.657 null] >> endobj 2462 0 obj << -/D [2460 0 R /XYZ 71.731 729.265 null] +/D [2433 0 R /XYZ 101.619 326.015 null] >> endobj 2463 0 obj << -/D [2460 0 R /XYZ 71.731 741.22 null] ->> endobj -198 0 obj << -/D [2460 0 R /XYZ 168.193 707.841 null] +/D [2433 0 R /XYZ 398.581 314.358 null] >> endobj 2464 0 obj << -/D [2460 0 R /XYZ 71.731 697.476 null] +/D [2433 0 R /XYZ 71.731 312.364 null] +>> endobj +2465 0 obj << +/D [2433 0 R /XYZ 101.619 297.721 null] >> endobj 2466 0 obj << -/D [2460 0 R /XYZ 71.731 643.781 null] +/D [2433 0 R /XYZ 71.731 272.521 null] >> endobj 2467 0 obj << -/D [2460 0 R /XYZ 71.731 605.858 null] +/D [2433 0 R /XYZ 101.619 257.771 null] +>> endobj +1342 0 obj << +/D [2433 0 R /XYZ 71.731 191.619 null] +>> endobj +190 0 obj << +/D [2433 0 R /XYZ 337.12 156.152 null] >> endobj 2468 0 obj << -/D [2460 0 R /XYZ 71.731 594.951 null] +/D [2433 0 R /XYZ 71.731 150.025 null] >> endobj 2469 0 obj << -/D [2460 0 R /XYZ 71.731 575.026 null] +/D [2433 0 R /XYZ 353.774 137.223 null] >> endobj 2470 0 obj << -/D [2460 0 R /XYZ 76.712 524.827 null] +/D [2433 0 R /XYZ 483.407 137.223 null] >> endobj -2471 0 obj << -/D [2460 0 R /XYZ 71.731 504.902 null] +2432 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F44 2037 0 R /F35 1567 0 R /F54 2322 0 R /F48 2049 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +2473 0 obj << +/Length 2952 +/Filter /FlateDecode +>> +stream +xڝYm�۸��_a8���")�RrM��Kk�^E��D{��%W/�n}g8CY��=�X,ė��p8/i��O.�R�5|T&T/���p����^H�X1�jB����Z/2�%zq�]D2�z��J��Z�� +~�7�˕��@ ���]o���w��~����*����_^����z-�T?����)��G����T�(r�� �^����Rc�TU�Tq���_˼m�f�S��5�W����M�-��e^��uU+S�S��}xu}� �C��b�9���_v��a`���;<�����O��^�z�f�ͮ��u�^��-AJ����?X�8���2 >���M�)�nh- ���d�0�]����}��_��1o�O~)�{j��|�F$�+j�ckd ZE�ɜ`�A�R����a��~`s2؛�lj������ҙ�s�ێ�����bCi�e)�����c|gy�,�8E�XFKc��� +Ð;?��`G���O�7�@�����f��� (�vMm���e +g�����RƁ�6gCG�AY�JG�Y| [�Á�;��5yF��b�"b����-�s)��̀G�n`EUQ�������LykMoi������+���9a�>��,\�1�a�G F����/�N��"�W�4h&�l�`z�c�ڠ�®�G�5{��c6���L�E�2�G��j�f����:f��i|!����q�9p�S�["�u�:����C�t�� �;f�`?WDRnG6s�z� 2����d� ���i�~�J�" +��h.��8��J`�m3�!�)�;�Z4{�ι6{��ڳG����-3*���T�z��M?7�L�L$SЅ�m [Gr +z�Nɒyn�C�E��]V*KDɉ��V�����`A���W�;T,횰�=��X��h�-�ֶ�G�&wFfF�6� /�#g���o�}Y�]��srg�T�E_�]��LB���l��$��������xI}���n�w4f���oUbd�(����|�9�x��L�=!]��4��3��> ,��Q�t���s���8�����y��B�Q��� 4LQP�t ^�����|S�ŘȻ!��a8��||{{�C�CU�vyҧ�~���~, +�,�}����́�>M��<�Vq�0U��!�|��]4�����4�}���r_Q�S���2�VN��o� +��1���Q�h�Q�ѝ�J_0ɣ��e���Y�`�d80),���h� �++�0W�vm�f���5Й��4dD㝭`�ڌ\� ��^����^��;�G����w�����ฐU��`�=-=?��y��7^�� I0�%E"3���n���e��Pe7�H�G�=��$u4h���z�.o���qz�M�������T_��{�2$;�f��n,���怜/h�\���7cA�h^�T%J�Yŋ� +�S'�oM�u���H�bC��zv��ۼ/?�ڏ��øc'��]jHE4so���l8I�Ӕ��L_t�#�-�#��8���aVU���;���o����woī��-����;*�Tgi�+ �'�7���)�4��W���Q���Hs�UA�eӦ�C���WO�mk� z Y����Xӵ�N�Z�G�@Ǹ�� �-�Qخ�Ֆ5�hw��/X�j�}. ���v��n:KgDJ�����$|��%�[(҈��i����@����~2���5��C=f�$��� ��P�q"I&g�+6L֏�0�Hh_@3���x���|QP�C}"3~�yfӛ 5f����=�Q5�ߩ:��jR ��R�a���2��/��T͌���S�����=���9>�������/ewE�qlo���E��!ƅ�?VS����>8p�k��=X.��u��A�{D*�3G�"�ѤET*��r(���ⵜe�� Y v�E�A=��K��-��I��|��VnF�E��/� ����->q�E�����uX���s�J8�r��{VoT������U���r7�DA�F>���̌��U)��7���;��$��\֍d$�89q��j�q�������l�pY�?�$:�8%*���iV��C�9#T�#(?b�Hh!��+��$ʞ�i��ŋ����t�P����t��aLR�UB�X�V���E�B���c@E'%QtL�0s���q�\mh�~/���� g� R��!�7���5��m?������6>�0�I��t�igY;�@�]9��q(�N���m|�t9���r>�����5f���N��6��Mӏ0�#Ϲ��K&�<� L���n�iV����1r9�����|�w.[C�3��lO��sF��:�<�@*�^C#����8���~�wf���m&���F��]Vżi[w �a|����Rt�q�ե`�����{��qC�n���a*ҹ��`χtO�Mwh����Z�d�n�N�h��k)zs1�,{��<��+^: �u��+ï�578b�_p]-5�Ɉߚq�^{`�y������� I�J$,,�*�;�,��*��jħ�|���m���~8 ؝�a�n�G�v�q>>6�@�pf�x%���tk��$����iij������e�z��{r���EG5���w�Q�!��Vɿh0?|�0i��7���$���%�Thy*���d�C��xYC���Ԕ�W'(�.�aL�g|�P� +vv�`gP�����P*�\��f5!��3Fg;.�k�\*�� +�4� +?g��_�X~���K`0�oʺzb{U�ׇzt�R�f�o�����/�Q(AN0ۜ��ģ���6�{䌏�"�=�� d�ee0j�.mq6}�3���J�cA����Wv� $��M�PZ�:3�$d�J6�%֩/-n����F����Nyƀ��.��� �)@��~�>��~�������k?`�E�,)�endstream +endobj 2472 0 obj << -/D [2460 0 R /XYZ 369.099 481.589 null] +/Type /Page +/Contents 2473 0 R +/Resources 2471 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2310 0 R +/Annots [ 2499 0 R 2502 0 R 2507 0 R ] >> endobj -1319 0 obj << -/D [2460 0 R /XYZ 71.731 453.694 null] +2499 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [166.345 312.528 218.649 319.382] +/Subtype /Link +/A << /S /GoTo /D (security-webserver-access) >> >> endobj -202 0 obj << -/D [2460 0 R /XYZ 200.128 414.322 null] +2502 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [291.365 223.079 339.793 231.99] +/Subtype /Link +/A << /S /GoTo /D (troubleshooting) >> >> endobj -2473 0 obj << -/D [2460 0 R /XYZ 71.731 406.969 null] +2507 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [194.362 118.072 239.281 127.093] +/Subtype /Link +/A << /S /GoTo /D (parameters) >> >> endobj 2474 0 obj << -/D [2460 0 R /XYZ 99.155 381.246 null] +/D [2472 0 R /XYZ 71.731 729.265 null] >> endobj 2475 0 obj << -/D [2460 0 R /XYZ 121.261 381.246 null] +/D [2472 0 R /XYZ 285.361 708.344 null] >> endobj 2476 0 obj << -/D [2460 0 R /XYZ 158.738 381.246 null] +/D [2472 0 R /XYZ 119.533 695.392 null] >> endobj 2477 0 obj << -/D [2460 0 R /XYZ 71.731 368.294 null] +/D [2472 0 R /XYZ 437.069 695.392 null] >> endobj 2478 0 obj << -/D [2460 0 R /XYZ 71.731 361.905 null] +/D [2472 0 R /XYZ 117.159 682.441 null] >> endobj 2479 0 obj << -/D [2460 0 R /XYZ 245.988 350.361 null] +/D [2472 0 R /XYZ 419.102 682.441 null] >> endobj 2480 0 obj << -/D [2460 0 R /XYZ 268.387 350.361 null] +/D [2472 0 R /XYZ 355.405 669.489 null] >> endobj 2481 0 obj << -/D [2460 0 R /XYZ 311.83 350.361 null] +/D [2472 0 R /XYZ 71.731 662.725 null] >> endobj 2482 0 obj << -/D [2460 0 R /XYZ 225.31 337.41 null] +/D [2472 0 R /XYZ 115.56 638.605 null] >> endobj 2483 0 obj << -/D [2460 0 R /XYZ 215.062 324.459 null] ->> endobj -1320 0 obj << -/D [2460 0 R /XYZ 71.731 317.32 null] ->> endobj -206 0 obj << -/D [2460 0 R /XYZ 254.069 280.105 null] +/D [2472 0 R /XYZ 153.506 625.654 null] >> endobj 2484 0 obj << -/D [2460 0 R /XYZ 71.731 272.753 null] +/D [2472 0 R /XYZ 343.016 625.654 null] >> endobj 2485 0 obj << -/D [2460 0 R /XYZ 71.731 252.842 null] +/D [2472 0 R /XYZ 71.731 612.702 null] >> endobj 2486 0 obj << -/D [2460 0 R /XYZ 71.731 136.279 null] +/D [2472 0 R /XYZ 163.765 586.8 null] >> endobj -2459 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F44 1994 0 R >> -/ProcSet [ /PDF /Text ] +2487 0 obj << +/D [2472 0 R /XYZ 71.731 579.661 null] +>> endobj +2488 0 obj << +/D [2472 0 R /XYZ 71.731 530.844 null] >> endobj -2490 0 obj << -/Length 2039 -/Filter /FlateDecode ->> -stream -xڭX[�۶~�_�GXsŋn�"۴)�6E�<Ih%�։,:�d���g�CJ���E�X�g�Ïߌ̃�x�r�Jx���$��Ula�?W�i���z�s{wu�A��Dw�@��i�J��Xw����]qt�Z�8 -�盶����-�ߎۿ�)V�~���nr˔�|6.%SQ��`y�Q�����QP��/��?��Bmq�48�st:�\�q��d* -�YL<g��:�3k�%�S�9�bJ��WL��$#�"�O��,K3JT1�i17?+@&���b1��2�ʷ�,�^��J�pع��F�V���_���Iؚ�e��AW�jusd, -?D��z�=�{�����:�m����O���agHeW���Q��:�,�i���nm�YL[���~n͊��C��&��������.Z7�큳GZY-3�ڙ�C'h���m�������+g˴CQ:c�8���hG���f)(������@`�C�kXɯi��* -�QԮ����KYҳ�������^�ڦa?�;'<��C(�:<�����V��``�����IP=���E� .B�kE ��1@8J���w�����C�ؖ��?G=�"�&)��5}In냅L8�g��-IC���H�J��$ ��^(�k�Q���8���ԥ����Y�^���rגG����gUw�0��� %�U�2qr^0ݛ�(�2֓��,��.�x���k�s 2ytջa8���q��� =M���wt7?9 Vn%�u���#���+ 9��/ ��,����K*O!�|��t�x�*&Q�r�m�������k�{=�N�+z�یO��8x���땊�W�H�j��R.�z�/<�@ YN����Wt��z���l��N�ꢋ@���Nj����(&��sg���{��xX�2<���+@el*#��T�=�+�9��!�[�+G.���'1t�)L�<��2,��:K*��L?���^rOaH�.�&0D��������_�GZ�1nO���1�Y8�˕�p0�ԳX�ÝK`���Kr�/'4$:K����6����:��y���ak�F��q���V����X�M�)y8����5 �����Q@=w֊��T�$ �K��>0��Ѡ�`mB19 ��F"L6J\A�A���e0qMg,�;��Y1$���#��UΓw�`�;�U�P���xL�w�E[����@k�S��03��~D'��� -�9��P&�W�Xs�.p��"�8�^��0w�3�ʂ3 'Kΐ��0e/�K�����3��ػ�.�g�3��t�G�� @�X�H`6��t4Z���3�1��,�@��LV��@/~_�A�5�b]]����<�?蝫��Kn�H[@�����Z�����r6Y�o*�O���_l��c�4��o��͠�鎵aWO-x!E�y��Q�"�����u[U-}��;��)s�U���0w �^C�� �$p��kid���'�#��S"�l{��IAOC�ۛ�.�-������ö��v.���%x({�l�^���ieY���98��K�M�.Bt;v5��m�lf��B����Ξ�1L./sF_5�����kG��+��U��Z�� -T�*U����W�8�=����l_.��5�b�/���U���p���s�e���֭-�]¹W!�������5p��{8y������u�⺝ڢ�k����,�=���仩?�@;�7�آ��A�m��g��{ݻ3�sŭGzc]9��O��\#x)�m�e�ƕ��k"m�D\>3? ����D�_�����k��Ǚs�� �b�߭�M��_�L%�����%�y�x� -{���G�@z����YKpf2 vu +v�fǩ��d�t�0�/h�y}�C@V�]+pw�@tǾb%(�NCHeTF,6��{�z6z���H���������#�Z���t�m#�q�g8>���P���M���i z�&��l=r��=Y��g��U�~��E�"፠k�]�a����j��9endstream -endobj 2489 0 obj << -/Type /Page -/Contents 2490 0 R -/Resources 2488 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2487 0 R -/Annots [ 2495 0 R ] +/D [2472 0 R /XYZ 71.731 499.726 null] >> endobj -2495 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [272.104 644.277 306.198 652.866] -/Subtype /Link -/A << /S /GoTo /D (gloss-contrib) >> +2490 0 obj << +/D [2472 0 R /XYZ 71.731 474.655 null] >> endobj 2491 0 obj << -/D [2489 0 R /XYZ 71.731 729.265 null] +/D [2472 0 R /XYZ 71.731 453.499 null] >> endobj 2492 0 obj << -/D [2489 0 R /XYZ 71.731 741.22 null] +/D [2472 0 R /XYZ 71.731 433.574 null] >> endobj 2493 0 obj << -/D [2489 0 R /XYZ 118.555 692.718 null] +/D [2472 0 R /XYZ 458.479 421.918 null] >> endobj 2494 0 obj << -/D [2489 0 R /XYZ 118.555 646.272 null] +/D [2472 0 R /XYZ 207.921 410.262 null] +>> endobj +2495 0 obj << +/D [2472 0 R /XYZ 71.731 382.366 null] >> endobj 2496 0 obj << -/D [2489 0 R /XYZ 492.354 646.272 null] +/D [2472 0 R /XYZ 71.731 336.374 null] >> endobj 2497 0 obj << -/D [2489 0 R /XYZ 71.731 603.784 null] +/D [2472 0 R /XYZ 358.177 325.579 null] >> endobj 2498 0 obj << -/D [2489 0 R /XYZ 71.731 588.84 null] +/D [2472 0 R /XYZ 461.001 325.579 null] >> endobj -2499 0 obj << -/D [2489 0 R /XYZ 71.731 575.888 null] +1343 0 obj << +/D [2472 0 R /XYZ 71.731 297.584 null] +>> endobj +194 0 obj << +/D [2472 0 R /XYZ 166.615 258.311 null] >> endobj 2500 0 obj << -/D [2489 0 R /XYZ 91.656 560.112 null] +/D [2472 0 R /XYZ 71.731 247.946 null] >> endobj 2501 0 obj << -/D [2489 0 R /XYZ 220.329 560.112 null] ->> endobj -2502 0 obj << -/D [2489 0 R /XYZ 257.513 560.112 null] +/D [2472 0 R /XYZ 258.543 238.187 null] >> endobj 2503 0 obj << -/D [2489 0 R /XYZ 162.267 547.161 null] +/D [2472 0 R /XYZ 71.731 223.079 null] >> endobj 2504 0 obj << -/D [2489 0 R /XYZ 446.625 534.21 null] +/D [2472 0 R /XYZ 71.731 208.135 null] >> endobj 2505 0 obj << -/D [2489 0 R /XYZ 173.957 521.258 null] +/D [2472 0 R /XYZ 71.731 159.083 null] >> endobj 2506 0 obj << -/D [2489 0 R /XYZ 71.731 509.139 null] ->> endobj -2507 0 obj << -/D [2489 0 R /XYZ 71.731 498.245 null] +/D [2472 0 R /XYZ 321.927 146.132 null] >> endobj 2508 0 obj << -/D [2489 0 R /XYZ 91.656 480.411 null] +/D [2472 0 R /XYZ 349.018 120.229 null] >> endobj 2509 0 obj << -/D [2489 0 R /XYZ 71.731 460.322 null] +/D [2472 0 R /XYZ 415.603 120.229 null] >> endobj 2510 0 obj << -/D [2489 0 R /XYZ 107.706 449.527 null] +/D [2472 0 R /XYZ 91.925 107.278 null] >> endobj 2511 0 obj << -/D [2489 0 R /XYZ 204.851 449.527 null] +/D [2472 0 R /XYZ 151.7 107.278 null] >> endobj -2512 0 obj << -/D [2489 0 R /XYZ 71.731 421.632 null] +2471 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F35 1567 0 R /F23 1201 0 R /F44 2037 0 R /F48 2049 0 R /F32 1215 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +2514 0 obj << +/Length 2012 +/Filter /FlateDecode +>> +stream +xڅXm���~��@���z��kQ���A� -.�A��D[�ʒ"R�����p����{8�qH 9Ùg^�p��p��"�a� +m�Uyx�����7!s���/x�yz���8^��ī��* sQd�,�D�F������~�^$h���F�m��i�ʹ�ܴ�\���_o�{���q&�<~U/�s�X��s�r'�U�n�ڏ��;���맶��luO�V� + ���,�g��:�O�{T�(�>6�1�`j��+��f���E$�"�Q��/e[�ݮ��R�Md7��� j�>�z�Ϩ;/�iTN�\�`��$h|P�f���s� cӏ�i�~����-�H�b几�R� �a�)���I� �4�~<h��~@���nƩ>i�f&�,��5��~"��蚿�4N��X���4"�Q-n�Q�M{-h�AY���G>/�-C{�Q�Sw�(i�7�Z��Z�iC{�|�����V]$�Zv{EtcٻHE���f�(�7�e��&�� ���~0Mo]�;0���리��S3�t��|2#�� "��:��8X_�6>�Gv� Y�b��dh��:���j�ID�w�������> ��*Qm�j�l�)�^��,���:%�@��Ea�l~�d"��DX#h�V�r��䱖f�+��Y�}{�[�l�P�������D��`ٝA�c�а�)C����.�f�U���#;��FC�G�I�Nn[吢�%��7|��q�&�hpG"��P��&kG�����ZbB��q��HU�Jl/U�CO��D+�Q#���WS�� �Fd8�4s��O�Ѧ)5Yc�r��9]E;���E^ +�36!�`+u�����U�4/\�����px��5���~I1\V˨�<]S�Dz;�Հ��&@�bp�� ک��r#�(�>X"M=A�+ �g1kg�C�lW�H�S�bƻY��H�ę���n�wy�M�1w%��ecy�1�� �^D�-����mϡ��f_�w��\�/%�4|}o(+�����gq�W��K0�����W���\���YsC��<��h�Z� ���r�l�m�|��F-��%�95���*T>���v��J���(y�7�-DQ���*�k����������� +��"'��jbzZ�d�mˡ������=�4$��XH�Q��!v#=q�$|�mp��l?�B��e���:�n��D�����w7�#���^e��n��L�N��|F�;ijq�eTTopK�vO��bs��2�C��}�b�a?�F� ��?'�ʵ��ߚ���8ZPe^�[9<�zC�C��ϽLPo�3a�З��G�v3�3@U��~������J�1���˼�*7��1���;���D-,���_�� V�Q�^�Zai|c���R"c�D%�'^��V;7@Q-b˧L�,?����V ��.0�["�do�����"�4FPm�����x<�7��������#F��!�E)�dЧm�=Y� �?Ԡ�Ju%&/�!�`Ѻp�/6�Q� ���&� #��c$�����[�,�\��V0��ʾ��E3�N�u= .�: 6q6�d)>��$�c�Z�Z�n�H8z8��=��i�e�,1*qRrCC�> v��<���'Y��8�[G�PF�j�����=�{w4<9Nn#�}8�-���h+���Yb#ȞND�v��E=Õ�St��6��\��� �IQ�]�7�BdA� +�Hl��� f�<��]\�� �KYy!�ArO��8��-�ʾ:�b�fXX xm��Ѓ45Q6�C��hӁ�Lfh���I�s�@>����Q�|v�.�� ���g���m�?�qll@�W\6��QȀpzS\a��H�}��A(r�6�����{��2�K�e��"��X�^��/~�� +[� �ij�����ù��&�=%��E�ڜ�6�Rqް�..���yv�q��~�1�c_�t�j���yf��)3�2(��)6겗~���'�@x endstream +endobj 2513 0 obj << -/D [2489 0 R /XYZ 71.731 406.523 null] +/Type /Page +/Contents 2514 0 R +/Resources 2512 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2550 0 R +/Annots [ 2520 0 R ] >> endobj -2514 0 obj << -/D [2489 0 R /XYZ 91.656 390.748 null] +2520 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [474.039 662.351 518.87 671.263] +/Subtype /Link +/A << /S /GoTo /D (extraconfig) >> >> endobj 2515 0 obj << -/D [2489 0 R /XYZ 71.731 357.707 null] +/D [2513 0 R /XYZ 71.731 729.265 null] >> endobj 2516 0 obj << -/D [2489 0 R /XYZ 107.706 346.912 null] +/D [2513 0 R /XYZ 71.731 718.306 null] >> endobj 2517 0 obj << -/D [2489 0 R /XYZ 71.731 319.017 null] +/D [2513 0 R /XYZ 264.224 708.344 null] >> endobj 2518 0 obj << -/D [2489 0 R /XYZ 71.731 305.966 null] +/D [2513 0 R /XYZ 95.243 682.441 null] >> endobj 2519 0 obj << -/D [2489 0 R /XYZ 91.656 288.132 null] +/D [2513 0 R /XYZ 71.731 675.303 null] >> endobj -2520 0 obj << -/D [2489 0 R /XYZ 71.731 268.043 null] +1344 0 obj << +/D [2513 0 R /XYZ 71.731 647.407 null] +>> endobj +198 0 obj << +/D [2513 0 R /XYZ 381.468 604.31 null] >> endobj 2521 0 obj << -/D [2489 0 R /XYZ 107.706 257.248 null] +/D [2513 0 R /XYZ 71.731 591.872 null] +>> endobj +1345 0 obj << +/D [2513 0 R /XYZ 71.731 580.594 null] +>> endobj +202 0 obj << +/D [2513 0 R /XYZ 193.715 543.378 null] >> endobj 2522 0 obj << -/D [2489 0 R /XYZ 71.731 229.353 null] +/D [2513 0 R /XYZ 71.731 533.013 null] >> endobj 2523 0 obj << -/D [2489 0 R /XYZ 71.731 216.302 null] +/D [2513 0 R /XYZ 71.731 511.134 null] >> endobj 2524 0 obj << -/D [2489 0 R /XYZ 91.656 198.469 null] +/D [2513 0 R /XYZ 71.731 511.134 null] >> endobj 2525 0 obj << -/D [2489 0 R /XYZ 71.731 178.379 null] +/D [2513 0 R /XYZ 101.32 501.635 null] >> endobj -2526 0 obj << -/D [2489 0 R /XYZ 107.706 167.584 null] +2528 0 obj << +/D [2513 0 R /XYZ 71.731 491.493 null] >> endobj -2488 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F44 1994 0 R /F35 1525 0 R /F55 2249 0 R /F27 1180 0 R >> -/ProcSet [ /PDF /Text ] +2529 0 obj << +/D [2513 0 R /XYZ 416.305 478.721 null] >> endobj 2530 0 obj << -/Length 2327 -/Filter /FlateDecode ->> -stream -xڕk��6�{~���=���ӝ��I�M���^&q��i�-�k]eѧ�z7����KJ:} ���)9 ���T�4�A-�J�I�}La�W�1�2?�y�|u�.'�H��r=�d&�$ ��b5Y�O��]g��\��T ���UU֏�~�?~-�J���������4S������q���(��_��0��`�ogQ0}�a��Jw]S�f*������&�@DR�ɠD������xTc$�R�� ���)�89pDi�3�����m�t���)����U��x�b�Γ�����bk��~S�B�m��n/���Ecږ�_lߠRAs��"�+��iZz�=<>�L}0���,�o'39u����},k����L�Sӊ/0�N�u�̖�E�ń1B<P|8�XE���Kx��(��ԝU")O��'N�'2]���@�Z��p��6[ݵ�݆ؗft�4�㦣����-��sbp��\?Y�X���,n�ӏ���F�=9-D�p�3��I�+ZY���i��5��۷Ӯt���ˇ{Aӻ�sn�2�+ݠE2E�jmf*��%0��2����4(hؾ��N�UW64E�ii�y4��E2���=M�q���INw&/uE�Xۃ@�S �twEk�������T�3xwìi�5�܍?}��������݅< �6a�Gܢ�>���d��=�{/@�p�J#�g�h��5X����O�����e,n�b�9 >� -A9M�|0T��9v ��t� ck��C��`l��m����]�2Kb4���|��[gsmM]0���Ҍ������=ɕ�+e9˂�%pa=Ͳ��)����E7�*댘\}��jw%�u7��m�i��L�K�Ǿ�]i�+��M1\�BR����x 4q�Hš� ����e���zo���X�b�59���h���AN�,�4"�<T��i|�7o�x��eD��X��vH"��E:)�~�̄� @∽.���$�z����)�� �i!�������W���]bM���'�b}L�P2�0��Bʐ�Eĩ⡯�rWq�?�@\��+ݚA���lΟ,�VrB�' )�xqR%d����À�``*-�4fmfp��x����.tÛ�2\h�y�ƅ��o_���y~���m�'�")]�:d�àS[�2�{ź���4nl��A*�d5�$E�ve�3��\6� -�c]ډB�L��{��%���J�eР��m��-h���ìy�ٶ-Wcc�Ʊo���/r㇏���|��r�^ %����[㔢�C���@ޯSӦ�s(�LqE'��r��`�y*�R���4unh�]\%.��3�Q��5�`���A���}#Bs�D+�.��`'.�(��̥G���<>m\Dg:����4.Fbry�qP�l�+ �.�͇��$r:��EM -,Y>J6��u�8���Q$(qP7�0�E��� SI�mf��� $y#�`�1�D�l��0�:^@������ѽ�h�Uk��7��3�$��n��WW��Rg�PQv��� -_��B��D���O+^�#��ũ¥:��)ܩ6����Ŏ���4�cKR�d�#��L�.��Ƞ� Y��o*]?B�0c�@�!�s�#�7/'2'2��A$(ۡ������:�ƈ�H��������YO�>#D����䱱�Ci�=-\���}D�;t#��(�c�{���Q�;��O��@� ���2؎�.��x��e�e&D�Kx���kA' -���2��a�M_�����x�P"�L�e�~'v�H����$��7�0���x!�r�*d�;?�2j�9Ѐ����%!PSh�r��5@*��!@G�1��b��H�Dun�G��m!ϸ�&���9�^Z��H&��mQ��w./�[��M�2,�^Y|fJ'W�����F2;�g �����j�/�ڷʸ�U����/�����D��C^�s+ C����]_�y�?����,��d'I��=I���̓~���o0���ݙ���Ɔ'{�� t��.<;��;�"^� -+�c��:��S 3_1f�\Ip{�N��q�����J��s.�]�p��\�F@.J%w=�b,D| |���Y�鰙�,�1Fo]g���r��H쬀jO���B�'QhM�+�����iV�@���Q��d�Pށ�h;b�ԯ$r1�j�ɂ����XGA�T�C�9�>�Q�F��>����W=�i)b������H���t��aJ6>:�V%>+"\�e�[>i�8�����-r���7ח���f(m2�[���~D�{�U9�A�r���CN�`4Xendstream -endobj -2529 0 obj << -/Type /Page -/Contents 2530 0 R -/Resources 2528 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2487 0 R +/D [2513 0 R /XYZ 71.731 453.65 null] >> endobj 2531 0 obj << -/D [2529 0 R /XYZ 71.731 729.265 null] ->> endobj -1323 0 obj << -/D [2529 0 R /XYZ 71.731 741.22 null] +/D [2513 0 R /XYZ 71.731 432.78 null] >> endobj 2532 0 obj << -/D [2529 0 R /XYZ 71.731 718.306 null] +/D [2513 0 R /XYZ 71.731 414.098 null] >> endobj 2533 0 obj << -/D [2529 0 R /XYZ 71.731 708.244 null] +/D [2513 0 R /XYZ 71.731 380.29 null] >> endobj 2534 0 obj << -/D [2529 0 R /XYZ 91.656 690.411 null] ->> endobj -1321 0 obj << -/D [2529 0 R /XYZ 71.731 636.613 null] ->> endobj -210 0 obj << -/D [2529 0 R /XYZ 460.106 597.24 null] +/D [2513 0 R /XYZ 114.77 368.733 null] >> endobj 2535 0 obj << -/D [2529 0 R /XYZ 71.731 586.875 null] +/D [2513 0 R /XYZ 114.77 357.077 null] >> endobj 2536 0 obj << -/D [2529 0 R /XYZ 344.279 577.116 null] +/D [2513 0 R /XYZ 114.77 345.421 null] >> endobj 2537 0 obj << -/D [2529 0 R /XYZ 197.388 564.164 null] +/D [2513 0 R /XYZ 114.77 333.764 null] >> endobj 2538 0 obj << -/D [2529 0 R /XYZ 438.35 564.164 null] +/D [2513 0 R /XYZ 71.731 322.108 null] >> endobj 2539 0 obj << -/D [2529 0 R /XYZ 474.766 564.164 null] +/D [2513 0 R /XYZ 71.731 302.183 null] >> endobj 2540 0 obj << -/D [2529 0 R /XYZ 114.062 551.213 null] +/D [2513 0 R /XYZ 369.099 278.87 null] +>> endobj +1346 0 obj << +/D [2513 0 R /XYZ 71.731 250.975 null] +>> endobj +206 0 obj << +/D [2513 0 R /XYZ 246.48 211.603 null] >> endobj 2541 0 obj << -/D [2529 0 R /XYZ 71.731 544.075 null] +/D [2513 0 R /XYZ 71.731 201.46 null] >> endobj 2542 0 obj << -/D [2529 0 R /XYZ 428.182 533.28 null] +/D [2513 0 R /XYZ 71.731 160.494 null] >> endobj 2543 0 obj << -/D [2529 0 R /XYZ 325.052 520.329 null] +/D [2513 0 R /XYZ 71.731 160.494 null] >> endobj 2544 0 obj << -/D [2529 0 R /XYZ 71.731 507.377 null] +/D [2513 0 R /XYZ 71.731 155.513 null] >> endobj 2545 0 obj << -/D [2529 0 R /XYZ 71.731 500.239 null] +/D [2513 0 R /XYZ 89.664 132.698 null] >> endobj 2546 0 obj << -/D [2529 0 R /XYZ 71.731 490.277 null] ->> endobj -1322 0 obj << -/D [2529 0 R /XYZ 71.731 431.263 null] ->> endobj -214 0 obj << -/D [2529 0 R /XYZ 533.821 386.008 null] +/D [2513 0 R /XYZ 290.096 132.698 null] >> endobj 2547 0 obj << -/D [2529 0 R /XYZ 71.731 373.57 null] +/D [2513 0 R /XYZ 71.731 117.59 null] >> endobj 2548 0 obj << -/D [2529 0 R /XYZ 332.179 325.595 null] +/D [2513 0 R /XYZ 89.664 101.814 null] >> endobj 2549 0 obj << -/D [2529 0 R /XYZ 135.507 312.644 null] ->> endobj -2550 0 obj << -/D [2529 0 R /XYZ 442.834 312.644 null] +/D [2513 0 R /XYZ 71.731 99.657 null] >> endobj -2551 0 obj << -/D [2529 0 R /XYZ 186.556 299.692 null] +2512 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F35 1567 0 R /F23 1201 0 R /F60 2527 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +2553 0 obj << +/Length 2137 +/Filter /FlateDecode +>> +stream +x��]��6�=���CW.V\Q�,�w�b�n��!-����D��J����ί�g$����^���"�p8盲\�'�IC��p/��U���ʛW�)|&�g4�7��E&�u���+��,Y$Q(�8\l�o��u���8�BA㏦�UU�fO����cYUj���O�6ӡq��,�^�k�"LÅ"��g" pR�V��ar��iF�=���X�W����q:���x�[<��4���y$��2�=U ��GPAE٩m��U��Ѧ�&_��;��U������%(��G�H�kw����e���J��49.e�Nb����k^�e7�����'"hἧ${�� J���:�ʏ��=��C�7_�����:���C�Q�v)So4R��;Ov ��|�A��WkF��e*m��s +Cm��Pd�tz�t��ߕ�5��j��ثU���f$:ޠ�Q�AOb6��j[���F����0_C��i!�+���-N�T'T�-��!an�� \�fA��\܋�P�Jo�<��*p�i[�N��_J)�͗�6ö������c�$!7�YB��΅�9?*f���H��V�R5�U5��EK ���o�P>��z�����%d1+� +t�0�<e�����E�C���5��4if::�P�#�17���>Ҭ���)��њ�D�*�u���)��p�+�����,�?(�P��mo��|���}Mb$���{�0�2����9?9Ya6�!���x�=*�7Vw��(�ݣ��e��`��h!W��(5�m�8rB�"�?ؗ���x��4��o]�ZìfI6p%B���: ��ڂ �jȧ���4toL�`��I�e6�w��� �6�D!�����Z="����#ώ�P�G��1c�)�au`~�ǜ����5n�]��6�6���L�;u��ki�m�T��'����f_b�Ժese~ �� +G�?�J���T�s�Lo�`��ׇ�yx��͠�`���_���m��S/� +���Q�s�N�ܩ��������FU�`����8#� ʸz�)k�>>B1cUV�1o��Ֆ&����a^���:U3��K"3�� �p���� �v�Ԟ1��^b�tܗ�����.�o��h���+��8V��t����1|C)�2s"���_����sC^��O����I��/�V琵N�"�� ���V���N4ՔE&)$$�{?�"N)�������qM�a,B�p�|_������`�ByxF����>d�O�4��--�+���Ī��n����%�=���Paa�� $S�%^�kw�[��^�gLٱ�Y1�����v�-���Z��c�)7B�U�KO �Y���x�C�O����F� �r ���`#=�e�҃����xK`7�[&0��_7���,@6�������⏮�N���NEf%.k�'� w� T��q��ͪ8bC�½[�u:A�ܚ߃ ��b\�܍ +±u1�*�bR��S�aJWKB�#���/� q��9q�����2�E���{`��o�������7�@�9;׀�QX0T����F�����@GU��:�ެkH��ݣё#�Y #�S� +ϫ���������%s>^��l�/��̳im7���z��D�'�̖�C@M�I�^���]ޖ[�NKs���u�9)�V�=ɳ�ڑƟ=y[^3Bi�A-1x��X����i"�U���L���W���[:wJ��W��&z���¹KF���h� B-6̣:ތY�+-��5�b�3��E�R���/沵��E�W����m�3��i�K��>�m|u'���� ,A���7>�i��t�j|�a�p�o�!$_�C� +����ňu*x�j3G�j(0�\}@�������c�QpKXzy����`#>�^lt^�We͞�\Q�Ac��V�.|�(��M uS����~#�j��=�jץ4�-�:�< ���j�� uf�l��KA�+>YLڂ��@\bK8q�D_Z`J��]�߹On��Ϝ�8�!��qؒA;��t�4�l�^g͒��ڢ�zCoW������ܶ�jڅ.1~�te|y��f������+����+R���#����oq�� ���d����OO�>�T�endstream +endobj 2552 0 obj << -/D [2529 0 R /XYZ 371.798 299.692 null] +/Type /Page +/Contents 2553 0 R +/Resources 2551 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2550 0 R +/Annots [ 2567 0 R ] >> endobj -2553 0 obj << -/D [2529 0 R /XYZ 192.546 286.741 null] +2567 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [235.966 332.05 287.048 340.961] +/Subtype /Link +/A << /S /GoTo /D (whining) >> >> endobj 2554 0 obj << -/D [2529 0 R /XYZ 71.731 279.603 null] +/D [2552 0 R /XYZ 71.731 729.265 null] >> endobj 2555 0 obj << -/D [2529 0 R /XYZ 381.821 268.808 null] +/D [2552 0 R /XYZ 89.664 708.344 null] >> endobj 2556 0 obj << -/D [2529 0 R /XYZ 156.806 255.857 null] +/D [2552 0 R /XYZ 71.731 685.43 null] >> endobj 2557 0 obj << -/D [2529 0 R /XYZ 282.571 255.857 null] +/D [2552 0 R /XYZ 255.817 672.478 null] >> endobj 2558 0 obj << -/D [2529 0 R /XYZ 190.714 242.905 null] +/D [2552 0 R /XYZ 511.98 672.478 null] >> endobj 2559 0 obj << -/D [2529 0 R /XYZ 71.731 235.767 null] +/D [2552 0 R /XYZ 482.926 633.624 null] +>> endobj +1347 0 obj << +/D [2552 0 R /XYZ 71.731 613.654 null] +>> endobj +210 0 obj << +/D [2552 0 R /XYZ 234.86 576.319 null] >> endobj 2560 0 obj << -/D [2529 0 R /XYZ 71.731 186.95 null] +/D [2552 0 R /XYZ 71.731 565.954 null] >> endobj -2528 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F35 1525 0 R /F32 1187 0 R >> -/ProcSet [ /PDF /Text ] +2561 0 obj << +/D [2552 0 R /XYZ 71.731 536.105 null] >> endobj -2563 0 obj << -/Length 2327 -/Filter /FlateDecode ->> -stream -xڅX�o���~�>�`���thR\�zi���+�^�ɕ�5E�|�����ג�d�Ї}pvfv�7/~�"T�nU�&����_�×�B��Ռ�ݛ��(Zl�6���"6j�-�(T�$\�y���M�\��ǟ���ei�{^�0��i�R/���盿�F�I���&zU/Gs�X�M�����1)��������Y�}����Ⱥ�y�e'3��[S���`;��[�e�x����4����?��<7]wyW&|���HG����ݐ/� �:�D�=t��4�h�*7 -� V�A�� A3�`._�QJU��m��oW����W�sޒ'ҽ%a���M'Lg��a��dK<?� -�� -�!h\����G�)O&K�ʞĝ\��N�=z,M!_��x֍i���Sכ#ϟ�A��z|�tY�8F^])����Gx -��^:�V0��a���h*T7��0�c4�,�1,uU0�{Ǜ�hZ9PX�,��P���w�9��|z�G��#���ʍ�D0��S6�Cf���*@tlD�ԑs�g���ޞ� ��"�ڡ�F�;�vspᾼ�J~(�2�C.&>4���$� ��/^g������2@�e�5�^&���+@��W� �m�B��;����O�np}�"�L��E��0V�.�m����=wP�$O������Lڔp�mZ:����<�v��qt��C�GS�����9�������z-�:�<J�k`d�߅J���oM[C���%��M]�wN4�E��`�bϩD�h��,#U ���[�Uw���_mU��_�O� -�D������(� �65u��+/��.c�� ���n��V�#Gz��}��my�?h�uŧ����R�o� ?��B�Kε����f�GQ��9�w0;�,p��.j�$�=�p0�l�qB*����ZT��ANt<����'[ �:�w�-�jK����3�3�(D>YBWr��]N�0��VS�5OƷ�[�sA"���,B�M�U���1�kBs�.�3t=���9��.�F���`�f�g�o��f���|�XZ��do��.�g �x��L(%���^ۊo -���ȳw�H� ���^��?������2���Oh��\����t�e��Xnw�����z.l�b���*�э����6�dHB`+�bG�-�Di(@�3�'u���|Y`�U���.���-��kżw�`8@��C;P>�D���H�_�ic.B.�]�8Lu���κ$��� -$J�}w��t/ 0�Uof��8�B�.�T��`��XN���Q]"?�濃m��ȹ���G�[ 郳�� ����}[�wQ���f%�J7�݂�Y͈.��sFx�[#���zɅ�M��tz]�м.���W,x�,u�Vt���� -�~����q�;��@��"�F�v�SCǥ��V���0���A=w)!Y�h.:�36�n>�@h�^��h.��M@%�E�y�F���f ���/�3Q��<�T���H���ڛ4`���5�b��| �L⍂����@lM}�,p�WF3.���T+�)#����'�L�gD(fs� � v�*~.%�dt�D�[�.f?� -3F�� ����*������t&��ω~��|o��ִ�x��E?��'nCVϖ�P�W�\\W,)z��S~����OX�V��F��^����;����i�=�����k�'��{�פNJ�f�bo�Ī�#}Pw�Ю��51� -{�����-Bj�����e��h(F��1�lR�m;nv���z���Rn)�� -l�u8ڱ�r]��]络��~M�k��x��?�&h��td*aUQR��I{� �W�ѭ�&T��c_��4=\H� P��� �(�b��$6�H��$]������\I�+I<�u �4���L��# �@8d+�?;!�q"��vВ��Ѓ��х/9T���O�c}{0����F5�%��P���HK]`���6n6�B���7�� ݕ;'%x�����1>��eV��ː���6�x�T(Y����O������&w�`��Mrq�;^|>!�hǀt-�����3��>0����ncI} n�'�s�%��MvU�� O�x�����a�`���MĿ�����Xc��K�P��X� -B -�Y� ����?I�fz�C���?v����`�o�R�H��18ض��?����?U��I��s���y UCԂ��� �ϼ1�LWU&؍X}Q����#2�|:����/G���G��o��տ�'���* 7�BA����?闒��JC#endstream -endobj 2562 0 obj << -/Type /Page -/Contents 2563 0 R -/Resources 2561 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2487 0 R -/Annots [ 2574 0 R 2575 0 R ] ->> endobj -2574 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [330.238 353.525 383.277 362.437] -/Subtype /Link -/A << /S /GoTo /D (install-perlmodules) >> +/D [2552 0 R /XYZ 71.731 500.239 null] >> endobj -2575 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [91.377 342.631 112.249 349.485] -/Subtype /Link -/A << /S /GoTo /D (gloss-ppm) >> +2563 0 obj << +/D [2552 0 R /XYZ 71.731 489.332 null] >> endobj 2564 0 obj << -/D [2562 0 R /XYZ 71.731 729.265 null] ->> endobj -1425 0 obj << -/D [2562 0 R /XYZ 71.731 741.22 null] +/D [2552 0 R /XYZ 71.731 469.407 null] >> endobj 2565 0 obj << -/D [2562 0 R /XYZ 71.731 718.306 null] +/D [2552 0 R /XYZ 369.099 447.502 null] >> endobj -218 0 obj << -/D [2562 0 R /XYZ 350.135 658.108 null] +1348 0 obj << +/D [2552 0 R /XYZ 71.731 419.606 null] >> endobj -2566 0 obj << -/D [2562 0 R /XYZ 71.731 645.937 null] +214 0 obj << +/D [2552 0 R /XYZ 168.193 380.234 null] >> endobj -2567 0 obj << -/D [2562 0 R /XYZ 71.731 603.508 null] +2566 0 obj << +/D [2552 0 R /XYZ 71.731 369.869 null] >> endobj 2568 0 obj << -/D [2562 0 R /XYZ 440.415 592.713 null] ->> endobj -1422 0 obj << -/D [2562 0 R /XYZ 71.731 577.605 null] ->> endobj -222 0 obj << -/D [2562 0 R /XYZ 242.621 540.39 null] +/D [2552 0 R /XYZ 71.731 316.174 null] >> endobj 2569 0 obj << -/D [2562 0 R /XYZ 71.731 533.037 null] ->> endobj -1423 0 obj << -/D [2562 0 R /XYZ 71.731 492.205 null] ->> endobj -226 0 obj << -/D [2562 0 R /XYZ 175.703 459.891 null] +/D [2552 0 R /XYZ 71.731 278.252 null] >> endobj 2570 0 obj << -/D [2562 0 R /XYZ 71.731 453.764 null] +/D [2552 0 R /XYZ 71.731 267.345 null] >> endobj 2571 0 obj << -/D [2562 0 R /XYZ 231.715 440.962 null] +/D [2552 0 R /XYZ 71.731 247.419 null] >> endobj 2572 0 obj << -/D [2562 0 R /XYZ 131.551 428.011 null] +/D [2552 0 R /XYZ 76.712 197.22 null] >> endobj -1424 0 obj << -/D [2562 0 R /XYZ 71.731 407.921 null] +2573 0 obj << +/D [2552 0 R /XYZ 71.731 177.295 null] >> endobj -230 0 obj << -/D [2562 0 R /XYZ 245.449 374.611 null] +2574 0 obj << +/D [2552 0 R /XYZ 369.099 153.983 null] >> endobj -2573 0 obj << -/D [2562 0 R /XYZ 71.731 368.484 null] +1349 0 obj << +/D [2552 0 R /XYZ 71.731 126.087 null] >> endobj -2576 0 obj << -/D [2562 0 R /XYZ 71.731 332.669 null] +2551 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F35 1567 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 2577 0 obj << -/D [2562 0 R /XYZ 120.149 321.112 null] +/Length 3115 +/Filter /FlateDecode +>> +stream +xڭk����� +��x�"�g�����A��&@��$��ɒ"�w����e��^��8D���pf8^� +��^%Z%>&S&�V��&X�`�7Z0��n�������֮2��v��]�:UY�J�QidV��/��]7��흉��Q�}h���u��x���OU����ǯo�z��F6QYj?+�ǹ�ؕ� c��+$* 5If�U +����nm�vc~����A?W孎�Av� +�%'=�՝ �6��`3l�&Y�|k�lx3������A��F�O�j +{K|qEkٴ�]��rW�v�<i����B�u(I9(���V�J�Q�\#�4#i��ҋ��X�{O��n�����6*��|�9�H%2��Vp�1��$*4!�@���piB+�6�"�r����L�:� ��c#Om3�ꒌ�Ty2c��kU�v�d�0]�ݭ ��h��a�çg��*<����6��ns7V ���^��p#��h@f�Lg"6�:����|R|ˢ;à��$��:(:�;�݁3k.��ǹ���C�#�CuhS���~�hG�W}G'�2Q�G�c���'�@ �E��^0�2i�Y�I���K�Rd��(������j�ۨ�X��X�OɭDq��X�Ɵ�a�E:��u �d�M�:<cy�����ko�<���n(��}HV�,^o�����8v_���$�Sٗ�{Ք��X�; �������p�Dj]����x��²iG^��iXw�(�~s%������m~ �;���J�3 FW !�n���V��{j ��vW�7S:I�w�,�@"0* +��]�(�RK,�囷�a�~��^c�9���XqHx9�0��~P�-������ϡ��c-�ٶ�2��Ԃ��>��eҮ���X�#[M��1��p��R}ra�}�%9� 3J^'�8%�A���R=���+��d��������g^��#��nd?eؔ�D�n>b�o{Yۅ��5�i���0;���p[*�������s���K��8&E)":Yܗ��8d7��M��Ac�ߢtBXs0)�����k��1t�v �W�&�0�w��'*^������7�[�� +-���o���Aφ�̶�����Ƕ��-�Ib�U6<�*eϥ��}��f��i5*<=/a�@�u�E�zԆiU� +����m�퍤x����o܁0"�*/� ����G<��#A���{Ղ���B�q� +������z��b Y=|舰o�#��Cy=l��9���Y�p8�����Xo����+�[����\���f\�9�ε�0�QF9�εB>�w#���c�9��RQbVh�\-6^��n!��(�V��ؗp�$&�&�]�c5]��H���`��J~��踮+��21���3�������Ah�Hq�-�)Z*��q)^;zbV��a FBJ&u_��'Şňo�����,�Ì3��'�p��F|;q�az�I'�'����ߦ]�^h�_n&��!�����0�Bl���� +�A!�G^do��M2"G�)�T�b�F0���F�R�ͮ ,�}�X�eg���^���[���+GN� 2ޫ�y�7!�t�@�x��%�_���=t�&��w�`�~�8�����o�rZ�^w�� �=q��Q16�v�{��5&����|�� Öŕ#�W5�豾a�����U,k�#��E�_�^�8��#�xy,�V*�?d������/x� ���嘫����VEI� +�P������7�����`�5��7��x�ȡ��5�VZe�]��j{����%0d�8�, �+x$�4p+Se��>� � +�he�L��B�� +�0��v�PEHxڄ�ߔ��KZ�qp�S8�Eh�zF >�ˍ@C{ψ��A���U�A���>H�A���_��P���w�<�����U%�j��H�4b�{l�C,ĦU����0.x�O�~ǡt�Q=`��;��B� +>�������?G�/�~�-��ft���W�w����ԃ;ֈ +�0>�Y'^�'QBN����0�s���7Kr�y< 78�jg/�`ہP�� b�F�?1��kA]�ݵ@���h����\�Q$$[��Y�#H�7���ӻ�p������z*�}dșmՑˤ�=C;���x����A�����n�G�;��%��I�3*��h(��A�t�~��G9�7W�j| �s��x�w&�KhT�u�lpvR�<�5���xT�Q�P �<1���0:�����П�"���Z����~��|'*ߡT���0}����L�:��?x!�(�� 6���,0�1Ȕ�b���ȭv�al�f�C��%����G8�Bz8�ϵҶ�r�"�^_��bHm|Q�q��������ҹQ�ta��L_�I��dz����G�Pc@��{d�,��&�j���L�S�u�c��%P6�#�9�1�W(0%��y4���CD���W���٪�L��0��س������;��ك����מU|��3�|��&Z�8�q�{ �eЅ9hU�YF�R<����Г�:Ϧd���u3��%L)ԡAe�R������ś�r(�=��Fy����bz�<������^C6a|H�7@�i�`f���H%��Z����谤$6b��@җB*-C�9:���d���(����nt��Kĥ?�FE����� ��]�.�N�q��/� ���7�ʇp��2d��� +Ԅ�1CǠW���bƌ�K1ã�b�M1�Ƨ�a��/f�E2��mw<G�(�3�}�O~���\�wm�M0y�Y��Ѱ��<���dF��@��NT�����Еy���{,�r���|<�����AQ�%���� GjУ���M�k��>���`������[u0�0CO�~� Z]��5q�c�đ�x�m��'�8���}0�f�W����}��l�y,}�X˯n����u};�y�MA�KU0���~d0�\3���9����!T{*/���~�Y��O?<l^<h��/ e%�>���6>�E����n���e���S� �}�{��k��^��S.�^����şUDjo㉠�t�ҟJ\r�/&C��endstream +endobj +2576 0 obj << +/Type /Page +/Contents 2577 0 R +/Resources 2575 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2550 0 R +/Annots [ 2595 0 R ] +>> endobj +2595 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [272.104 332.855 306.198 341.445] +/Subtype /Link +/A << /S /GoTo /D (gloss-contrib) >> >> endobj 2578 0 obj << -/D [2562 0 R /XYZ 71.731 299.493 null] +/D [2576 0 R /XYZ 71.731 729.265 null] +>> endobj +218 0 obj << +/D [2576 0 R /XYZ 200.128 707.841 null] >> endobj 2579 0 obj << -/D [2562 0 R /XYZ 71.731 261.471 null] +/D [2576 0 R /XYZ 71.731 700.488 null] >> endobj 2580 0 obj << -/D [2562 0 R /XYZ 71.731 261.471 null] +/D [2576 0 R /XYZ 99.155 674.765 null] >> endobj 2581 0 obj << -/D [2562 0 R /XYZ 71.731 240.315 null] +/D [2576 0 R /XYZ 121.261 674.765 null] >> endobj 2582 0 obj << -/D [2562 0 R /XYZ 71.731 220.39 null] +/D [2576 0 R /XYZ 158.738 674.765 null] >> endobj 2583 0 obj << -/D [2562 0 R /XYZ 91.656 185.421 null] +/D [2576 0 R /XYZ 71.731 661.813 null] >> endobj 2584 0 obj << -/D [2562 0 R /XYZ 76.712 168.783 null] +/D [2576 0 R /XYZ 71.731 655.424 null] >> endobj 2585 0 obj << -/D [2562 0 R /XYZ 71.731 148.858 null] +/D [2576 0 R /XYZ 245.988 643.881 null] >> endobj -2561 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F35 1525 0 R /F58 2421 0 R /F44 1994 0 R >> -/ProcSet [ /PDF /Text ] +2586 0 obj << +/D [2576 0 R /XYZ 268.387 643.881 null] +>> endobj +2587 0 obj << +/D [2576 0 R /XYZ 311.83 643.881 null] >> endobj -2589 0 obj << -/Length 2145 -/Filter /FlateDecode ->> -stream -xڍXm��6��_a��Vִ�_�Oi���p��-���>В�RW}g��w�3�d��,�λf�[���V�'��~&�8Z�7�� V>��b�$���o��`��,V��U�"KVI��4�W���w�<�[o��u|AϏm�e�����0<��n����?���8 -��DdipS/Ks���<OdQ����q���f���'T)I�w�(i��=ש$����ٮ��PweAoZ����@�� |4�'�c��]�gF�h��3G�=���/��u�Z��0u��xT�6�qà��{ꪤ�N}�M�Nh��ڋ���k�b|Ự�{���dΡ�-�ԕd!��g� -��Rr�O��dWҦ�����٧R�C������$����l�y�`[�0�fA9h�X�/�I���x*w48J���? �[�) -��Q��`"�=��a���J3;X+hؿ��<�wD"[t�-�FHSv��+54��B�)YE3���U�Rk?��o9C"��h����N�!Ry��^�zD5W�ƾ-z�z{�9r��*�3�0�:�F��� �O�����9�3<�58]�:�zQ �J�����;���4K8�V$��$��N2���T_�CW�J�Vi��~�ˢ����x��H��jQ�4��Y�-�eN*����w!>�D -�zS<���`��>�+�I������:�g���\��A�;\��c��8��;�;�y�k.�ю%�����<LR�F�M�-�M���.|�Q��}�A��oin�_2"�ۢe(��l�H\���"6T� %�#�0�(}0'�A��� Jbg�M=ġ�Rq�&��T���`�z���ٗ����D=o3��%rr���S�G ���]�ؕ0|PC�����ȭ�>~�������BuO�B���|��cu?�b.�����m�Ɉ[*}h��O���\tϢ=��B�Џ �_�@�4UcAp3kpG�cIs�1�i�xJ�7�T]aEs��)T9U����X.��zM�}�24٬�Դ�u������YD@e-k!�e��uuN|,�Ks��F�a�v@)�wA��(���!c��n;��vW�[��\�(b.xw�>�xt��d"��Y���F�c��� �����: I�qq;��{%�QHsS{��07C�K�EeuY��qkUڽ�v�eT�rsB�0:��юg&]�v���N��������A\��ه����Z���y@�߄1�2�/C�s �eN������@���|������Ss@������rx���a���WF��/��0����4�Q�,~�����`� a����f��W��Ǔ�06����#ǃbOҤL5RO�>+�gj�W����鴆=�D����D��� P���,B��&vX��ћ�u�I��d�B��ku�L��R��(���u�P5��A[�������{��-�)X�([5<U�E���<{lb3�F�Qﯥو4�"�*eh1Z�G� ���K�8]�2�;Z�Ɂ��A�82_2���3F���*^��w /YosЬ_u*P�j]�Y0sgG ��5��ۼ����O)A��X����6G�|�L� C��H�ڝ?�ВhZ=�NJ>���i"=�|�)�7[�S�^Q*l�0�&|��04�d�;s��b��ӂ�#{��.�k����l�(?V�1#"Q�~At� ��y�:� �X$p����U��NK��h.P���r�]h��-�LqK�9����M0��tV�m��W��dWۻ�o��A"�L�Ka�c�b��_���hu1m��f(� ���t��-���mh�n&����,���ս-~�Tù�=u�Xvw���=������Q^���G>(��H2����2���^z����;�]��Ae�.7�����Jm�s�9^Ѽ���|���3��sd�&U�,��uSx+qP�чO?��]7���a��L���`x�Ե� - Fܐ鄱�.\���[����1�[S۟��bB�Ƣ�E����`>�e���R������6�|���������-(��b�l����>o�C?2��@�q����4|Z����+���D�'�g ^\��� S�z�ͻ���*:��o����v�|)�%��*endstream -endobj 2588 0 obj << -/Type /Page -/Contents 2589 0 R -/Resources 2587 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2487 0 R -/Annots [ 2593 0 R 2594 0 R 2604 0 R ] +/D [2576 0 R /XYZ 225.31 630.929 null] >> endobj -2593 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [139.526 543.597 191.829 552.508] -/Subtype /Link -/A << /S /GoTo /D (security-webserver-access) >> +2589 0 obj << +/D [2576 0 R /XYZ 215.062 617.978 null] >> endobj -2594 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [478.054 543.597 530.357 552.508] -/Subtype /Link -/A << /S /GoTo /D (http) >> +1350 0 obj << +/D [2576 0 R /XYZ 71.731 610.84 null] >> endobj -2604 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [356.749 213.813 401.58 222.725] -/Subtype /Link -/A << /S /GoTo /D (parameters) >> +222 0 obj << +/D [2576 0 R /XYZ 254.069 573.624 null] >> endobj 2590 0 obj << -/D [2588 0 R /XYZ 71.731 729.265 null] ->> endobj -234 0 obj << -/D [2588 0 R /XYZ 341.46 662.914 null] +/D [2576 0 R /XYZ 71.731 566.272 null] >> endobj 2591 0 obj << -/D [2588 0 R /XYZ 71.731 654.277 null] ->> endobj -1426 0 obj << -/D [2588 0 R /XYZ 71.731 623.895 null] ->> endobj -238 0 obj << -/D [2588 0 R /XYZ 244.612 590.585 null] +/D [2576 0 R /XYZ 71.731 546.361 null] >> endobj 2592 0 obj << -/D [2588 0 R /XYZ 71.731 581.948 null] +/D [2576 0 R /XYZ 71.731 416.847 null] >> endobj -2595 0 obj << -/D [2588 0 R /XYZ 71.731 543.597 null] +2593 0 obj << +/D [2576 0 R /XYZ 118.555 381.296 null] +>> endobj +2594 0 obj << +/D [2576 0 R /XYZ 118.555 334.85 null] >> endobj 2596 0 obj << -/D [2588 0 R /XYZ 71.731 528.653 null] +/D [2576 0 R /XYZ 492.354 334.85 null] >> endobj 2597 0 obj << -/D [2588 0 R /XYZ 322.74 519.153 null] +/D [2576 0 R /XYZ 71.731 301.273 null] >> endobj 2598 0 obj << -/D [2588 0 R /XYZ 317.417 495.841 null] ->> endobj -1427 0 obj << -/D [2588 0 R /XYZ 71.731 467.945 null] ->> endobj -242 0 obj << -/D [2588 0 R /XYZ 197.318 432.478 null] +/D [2576 0 R /XYZ 71.731 292.362 null] >> endobj 2599 0 obj << -/D [2588 0 R /XYZ 71.731 423.841 null] ->> endobj -1428 0 obj << -/D [2588 0 R /XYZ 71.731 384.214 null] ->> endobj -246 0 obj << -/D [2588 0 R /XYZ 177.791 346.281 null] +/D [2576 0 R /XYZ 71.731 277.418 null] >> endobj 2600 0 obj << -/D [2588 0 R /XYZ 71.731 338.929 null] ->> endobj -1429 0 obj << -/D [2588 0 R /XYZ 71.731 324 null] ->> endobj -250 0 obj << -/D [2588 0 R /XYZ 168.088 291.686 null] +/D [2576 0 R /XYZ 71.731 264.467 null] >> endobj 2601 0 obj << -/D [2588 0 R /XYZ 71.731 285.559 null] +/D [2576 0 R /XYZ 91.656 248.691 null] >> endobj 2602 0 obj << -/D [2588 0 R /XYZ 187.795 272.757 null] +/D [2576 0 R /XYZ 220.329 248.691 null] >> endobj 2603 0 obj << -/D [2588 0 R /XYZ 71.731 252.668 null] ->> endobj -1430 0 obj << -/D [2588 0 R /XYZ 71.731 208.832 null] +/D [2576 0 R /XYZ 257.513 248.691 null] >> endobj -254 0 obj << -/D [2588 0 R /XYZ 331.166 175.522 null] +2604 0 obj << +/D [2576 0 R /XYZ 162.267 235.739 null] >> endobj 2605 0 obj << -/D [2588 0 R /XYZ 71.731 169.395 null] +/D [2576 0 R /XYZ 446.625 222.788 null] >> endobj 2606 0 obj << -/D [2588 0 R /XYZ 71.731 149.455 null] +/D [2576 0 R /XYZ 173.957 209.836 null] >> endobj 2607 0 obj << -/D [2588 0 R /XYZ 220.441 125.709 null] +/D [2576 0 R /XYZ 71.731 197.717 null] >> endobj 2608 0 obj << -/D [2588 0 R /XYZ 71.731 118.57 null] +/D [2576 0 R /XYZ 71.731 186.823 null] >> endobj 2609 0 obj << -/D [2588 0 R /XYZ 455.258 107.776 null] +/D [2576 0 R /XYZ 91.656 168.989 null] >> endobj -2587 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F44 1994 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +2610 0 obj << +/D [2576 0 R /XYZ 71.731 148.9 null] >> endobj -2612 0 obj << -/Length 2189 -/Filter /FlateDecode ->> -stream -xڵY�o�8��"�>4j�-�s������0�!����=���u�?����)�I�;`чPERE��z��E�H��L��Ev��.v0���%qF2��>���"I�����b�D�HIr���sy�O���W�ܥ��P6mZy����n���(�տ�����7�H$�z�/+3sLF�cvn,���ڕ�d�|�D��pd���V5)�$˲;��峮iXmiv�����2�5L7�4۞���oN7�����ٔ.[�6ڊ~s���������hs�dJ�&���H�4^W��L�lOqG�װ���������'M��2J ���D��S�=�v�>?H���"L�y� ��3�eع"�bO��]�}� ���FYfft�=2��S�Ĩ�lT "~��>隧�b�Z���_-!�w�إ��P�F�ת՟H����\G��ʓpLp�^ɫW�]�{%�(dFˬ�ikn�dU��uU�� M��(��h�m�,�Z�P�O[��;f��x^�'�7z�~�]�ޒ�Oy���;���-����k���Zg��s�3��M;�'���=�Hf�� - Jnd����KA�ؼ���A��%^��fe�J��=�����/���p������������i�� �Xu5���y�x��\X��b��gsˁ��t�k�r!�YS��r;��Ef���B�x�G4=����%K�35���p�&/���蹪 �ǂ�w��=��{"�}��k��ށ��y��\w/�k�C�g��ʧ\{S����[��d -b�� -���&w����M��yi8�#HW�3��攔Q<d�,2p � #e��P.Bص=��d�-�}f�Mg �����T3��y�D����\Q"N�R��SG�Џ(8�+b�2�h�߃N+���y���N��<��f䡽ۮ��G��m�O*z&����-� ��� X�C��Zvp���45��~�sP�[���%��AHp?�=:�o��,����ӧ'�2��)m<� -%}������xy^@[��q�\���Y���8�`��Y-)��+Am��s$Z7yUZ][��+�Ƞ{qKL� ��l��7�nʛ�/�@�|��X��U}�bp�~L�q��蠯lh)[�!�PO���{�@�s�nix��R[�c�3������\~�J�4���|����~�ɰG 5���X9��.�Q �<�?�!Z�U���/&�7���P��b�(��)O�-;Vh�:f<�/z��y�B�{u������n���� -ag��_���Q6�9�?6u�H��@���3��X�������oj���'?:�՛����A�`���bE�]�G�W�����^2�`\-c�ȡ?�`m�x�-)�T,!��Rqf���l��Ee:}�E��e�^ � �(c��3//�.͛Ѹ�kk���Xr5n�M�Z�>a5/�B��ٚ��k|���������`��i`�����d�ơ���Z�]]�U[MN ��V综Ly�ٹ��n*n���n���tc��XKD�/�֮�/�Y��j#��k4p�� ѣ�l��p��*E���cג� Qpҍ&k56qI�w;���Ue9ԓ��I��k�ק&�꺮������8�ĥ�y-���<�㻡�23=����U�9�>RZ�������B��ڄ�����XU:)�e+�}�K�e��y��Ԧ�"0�Ha�r�x���a�� �2K��\�b��R�H`h�8��[2]q�iA����:@;7&�N_� �����8��|t����{}`v39+BZϸVF=��2�V��@���X�3���!��G� �,b�ڼ�[[V���v�U*���x�ij��8�?dً�����G��Q�{��h���z3�(�Ѿ>?�b��JH?�����u��@�;�c1���BX� ���z8i^گPU�i���+���f�u&oF�o���\X����Uʃi�L�z�5-�<�'���ވ����� -��6�H2�G�e�'&N���é���k�5c��h��i��i�w�?M�#<�UU4s��E���Z/�������э^}{��i�4i邞$|�I�d�5i+2�Ѕ&}�ڻM����&=�n*��S>������E��p)����E�Eo�^d��8�p��*1�M^������0MOendstream -endobj 2611 0 obj << -/Type /Page -/Contents 2612 0 R -/Resources 2610 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2487 0 R -/Annots [ 2615 0 R ] +/D [2576 0 R /XYZ 107.706 138.105 null] >> endobj -2615 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [244.482 695.273 269.647 702.147] -/Subtype /Link -/A << /S /GoTo /D (gloss-cpan) >> +2612 0 obj << +/D [2576 0 R /XYZ 204.851 138.105 null] >> endobj 2613 0 obj << -/D [2611 0 R /XYZ 71.731 729.265 null] ->> endobj -2614 0 obj << -/D [2611 0 R /XYZ 71.731 718.306 null] +/D [2576 0 R /XYZ 71.731 130.967 null] >> endobj -2616 0 obj << -/D [2611 0 R /XYZ 71.731 695.273 null] +2575 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F44 2037 0 R /F54 2322 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 2617 0 obj << -/D [2611 0 R /XYZ 71.731 680.329 null] +/Length 1672 +/Filter /FlateDecode +>> +stream +xڭXݏ�6��"/��寸h\{�z��V��С-��$Z˓���_?R����=yEQ$%�H� G��Q�Y�}�&�bu����Ih%&Vd�!�jvr�6�F����h6���ϳQ1��Ѭ��^�z<aI�1��˺�xU�zA�W��?YU|�u��ɛ�`4�2?�F���d�c�ڱ<��$e�ԏ��8���:*y����P����0��i��D�S���A���8�Vzۆ�]���v���g�KD���� �w��oF��h�X2�ā?�3����8���7�.˚���餪y�u� +m��8��4>t�̏s�7�v�5b�16�l�;v�N]��Vb<��xp�f����[�<�[����UG@E���i�FE��R��yx'��)g��biyK�E)�(:�)bĻW�NNZg�8�,x+���U��zm�@���'�9t�j�)[��cl P�e�H�v���$f+:"�\1,6\�\BYE�vO���[�E�����!��Ԇپ��$������k����ts�������O��~Y��8<�W�)L��� o[��;\P�|�_A.~;��$N�<��7�ùAg&��_ ���!����ȵ; @���H:�W�� �Ҏ|[6�6-�S�;�@���`��ߐ!� ��Az�!\���(Ƽ,�h[�ژ�5� [�zYZ�����4�GX�Z��t�:<�q{# +�i%����b}�>�T��PM%N����z�$���봼3p�G�'������xQv�kXM�J���*0%�#� G�}Oe��-e;�4���q(';�����//�6�Fb���`0�l�����X��������k�r�z�{��q���{����i�[�z�+V�ƺ��\�-~V�݁���Nz�"��3!��AW��f�퓐����Fi�,�Q��Pw�Nd�.4e��m�7��S��(NL���9U57�FL������%����:�� +�y� �w�%� �����|����F��b�F�h��E������o~�Jʠj�f/�#?��������o ��9��᚛<��[�W�kiB�R�y�zZ.��ח�o��C#�3(���Y��&�F����/DK�c�(��íspg�3'�Ni��/M$�5Q��mguW\Z����O�e�,�N}�5"�j�^ͅ�D:�X��� �wMo�H]�#����4�vҝ"�>}�"�K�� �j���!�h~ s58��+�NiN��*���f��c��F��M~�x FC�(��ow�I)�$5?�;���~��rY`:��Ҷj���s�,<�h?��ЂZw[t�P+��eQ�Օ�>f:�so����A,Mk�-�����C^t���8%�yË��^�!��@�K�"�� ��#�a<)�P�.�'��x +/�K�t���H(Qn���˹�)J�ZKY�#�����dn&Á����9% �(a��Z��4�%�)��)E,���ề~��S���;�v?��J��l_m�瑍`�\����:��:��$b�f�V���p_�\J�K�=���p��C��\z~��U4� �����P@C�4������^�(������~U� Ά���=�L��l��@��cm�ԟ�٣�E��J���Sb����<����s�endstream +endobj +2616 0 obj << +/Type /Page +/Contents 2617 0 R +/Resources 2615 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2550 0 R >> endobj 2618 0 obj << -/D [2611 0 R /XYZ 121.379 657.136 null] +/D [2616 0 R /XYZ 71.731 729.265 null] >> endobj 2619 0 obj << -/D [2611 0 R /XYZ 101.884 645.479 null] +/D [2616 0 R /XYZ 71.731 718.306 null] >> endobj 2620 0 obj << -/D [2611 0 R /XYZ 156.232 645.479 null] +/D [2616 0 R /XYZ 107.706 708.344 null] >> endobj 2621 0 obj << -/D [2611 0 R /XYZ 254.126 645.479 null] +/D [2616 0 R /XYZ 222.016 708.344 null] >> endobj 2622 0 obj << -/D [2611 0 R /XYZ 313.316 645.479 null] +/D [2616 0 R /XYZ 348.501 708.344 null] >> endobj 2623 0 obj << -/D [2611 0 R /XYZ 138.317 633.823 null] +/D [2616 0 R /XYZ 71.731 680.448 null] >> endobj 2624 0 obj << -/D [2611 0 R /XYZ 239.635 633.823 null] +/D [2616 0 R /XYZ 71.731 665.34 null] >> endobj 2625 0 obj << -/D [2611 0 R /XYZ 71.731 605.928 null] +/D [2616 0 R /XYZ 91.656 649.564 null] >> endobj 2626 0 obj << -/D [2611 0 R /XYZ 175.156 592.976 null] +/D [2616 0 R /XYZ 71.731 616.523 null] >> endobj 2627 0 obj << -/D [2611 0 R /XYZ 71.731 554.954 null] +/D [2616 0 R /XYZ 107.706 605.729 null] +>> endobj +2628 0 obj << +/D [2616 0 R /XYZ 71.731 577.833 null] +>> endobj +2629 0 obj << +/D [2616 0 R /XYZ 71.731 564.782 null] >> endobj 2630 0 obj << -/D [2611 0 R /XYZ 71.731 498.829 null] +/D [2616 0 R /XYZ 91.656 546.949 null] >> endobj 2631 0 obj << -/D [2611 0 R /XYZ 71.731 488.867 null] +/D [2616 0 R /XYZ 71.731 526.859 null] >> endobj 2632 0 obj << -/D [2611 0 R /XYZ 71.731 450.844 null] +/D [2616 0 R /XYZ 107.706 516.065 null] >> endobj 2633 0 obj << -/D [2611 0 R /XYZ 390.582 435.069 null] ->> endobj -1431 0 obj << -/D [2611 0 R /XYZ 71.731 405.016 null] ->> endobj -258 0 obj << -/D [2611 0 R /XYZ 245.404 367.801 null] +/D [2616 0 R /XYZ 71.731 488.169 null] >> endobj 2634 0 obj << -/D [2611 0 R /XYZ 71.731 360.448 null] +/D [2616 0 R /XYZ 71.731 475.118 null] >> endobj 2635 0 obj << -/D [2611 0 R /XYZ 125.246 334.725 null] +/D [2616 0 R /XYZ 91.656 457.285 null] >> endobj 2636 0 obj << -/D [2611 0 R /XYZ 71.731 321.773 null] +/D [2616 0 R /XYZ 71.731 437.196 null] >> endobj 2637 0 obj << -/D [2611 0 R /XYZ 71.731 309.654 null] +/D [2616 0 R /XYZ 107.706 426.401 null] >> endobj 2638 0 obj << -/D [2611 0 R /XYZ 71.731 309.654 null] +/D [2616 0 R /XYZ 71.731 398.506 null] >> endobj 2639 0 obj << -/D [2611 0 R /XYZ 101.32 300.154 null] +/D [2616 0 R /XYZ 71.731 385.455 null] >> endobj 2640 0 obj << -/D [2611 0 R /XYZ 71.731 298.94 null] +/D [2616 0 R /XYZ 91.656 367.621 null] >> endobj 2641 0 obj << -/D [2611 0 R /XYZ 101.32 288.498 null] +/D [2616 0 R /XYZ 71.731 347.532 null] >> endobj 2642 0 obj << -/D [2611 0 R /XYZ 71.731 287.283 null] +/D [2616 0 R /XYZ 107.706 336.737 null] +>> endobj +1351 0 obj << +/D [2616 0 R /XYZ 71.731 313.823 null] +>> endobj +226 0 obj << +/D [2616 0 R /XYZ 460.106 274.451 null] >> endobj 2643 0 obj << -/D [2611 0 R /XYZ 101.32 276.842 null] +/D [2616 0 R /XYZ 71.731 264.086 null] >> endobj 2644 0 obj << -/D [2611 0 R /XYZ 71.731 275.627 null] +/D [2616 0 R /XYZ 344.279 254.326 null] >> endobj 2645 0 obj << -/D [2611 0 R /XYZ 101.32 265.186 null] +/D [2616 0 R /XYZ 197.388 241.375 null] >> endobj 2646 0 obj << -/D [2611 0 R /XYZ 71.731 263.971 null] +/D [2616 0 R /XYZ 438.35 241.375 null] >> endobj 2647 0 obj << -/D [2611 0 R /XYZ 101.32 253.529 null] +/D [2616 0 R /XYZ 474.766 241.375 null] >> endobj 2648 0 obj << -/D [2611 0 R /XYZ 71.731 241.873 null] +/D [2616 0 R /XYZ 114.062 228.423 null] >> endobj 2649 0 obj << -/D [2611 0 R /XYZ 71.731 231.91 null] +/D [2616 0 R /XYZ 71.731 221.285 null] >> endobj -1432 0 obj << -/D [2611 0 R /XYZ 71.731 191.896 null] +2650 0 obj << +/D [2616 0 R /XYZ 428.182 210.491 null] >> endobj -2610 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F44 1994 0 R /F35 1525 0 R /F61 2629 0 R /F32 1187 0 R /F58 2421 0 R >> -/ProcSet [ /PDF /Text ] +2651 0 obj << +/D [2616 0 R /XYZ 325.052 197.539 null] >> endobj -2653 0 obj << -/Length 1797 -/Filter /FlateDecode ->> -stream -xڥX_s�6ϧ���]̈��>���������f����N�hK�,��T���Pv7�m�%���A��(���R)R�0a{��"���y}!Yb�"�#�7W���r�'ʻYy��D�z� -E��M��Y�Q�e~(�yݙ�hۦ[���i�wӶ������7��X�"�ԓ~9�G��ʓ�e����H��z��I3�����S]�-�E�}?»$�\�M��m?j���H�(AS��T�P���H�t����J��6�����02��������.�4Q���(zH%��t - ���(��w{"8�%�u3��F�UM�q���=Q��/Km�0>;}G��7�a��~`������������`�]NC3��@�0=��@!D!C�s�u�����4�`Vz,���u�cG{ 6tc�2g��+L}3�5Q -&�q� -Z_��r�]����*]����Ede��9�Ӻ&2��4��4��^����lj;����Qʜ*�x}Х��2P>�E*�'�;�'��a(���OAf���@�1_���� �k=Ң���T��U���}�!|0 �Qo -�yj]q}�4����ݝE�]r��-+=�d�S�`�yQ��� |6���>��8�q2��x�����B*l"%��)����_U�i�Y&��&$�Z���.hiKl��naOMtH�� -�L[�ߑ0 �8u#��`�=��wP.yQ��C5�#�;�+vB��w|�e�u -�T0`G��}5��9A}�|pن֥˩9�l�ÐNkN v��8k�9�u8fB����{�A�8Ŝ�J�i��D$��o�콁�?�gw���O��y��A{���fM���&ç��f'�H������X�y��o�I� )�A��%�[�m@6��ȃ��� K�A���D$*s�Qn+Bn/� ^Ԝߡ�odo��^P�7�d�k.q�MX�P��&J@�8@Ξ�$l8-�����7��UL*�liN�7�1Pe�u6fU1w���N��Y{��PC�d�o�A�nHG��X�b)�T�,ĻI�X�ʺ���$��U�sIB[$�I0; ��m1�Uḋ��]�`'D�;$-6�=۾D���� -T=`ב�\�r����5k�%k����E�)���6�f��U�`��a���"/ =�1(��K�!��Ĝc�/s����Pt�Pf��ن�CsذH�i�ƌԞEv�*���s<�q�9>qjO̕��b4,��8عdvW]Y[�&�S�� }Ж���P������Fʙ�XN�$���0��$�[3��EXs�:�p߅» ��%d1�gb��fk��[�' �[;z��r`'v>"B���- �� u�P��p>����'Cv$��Þ��f{�&�<��!b��:�^���{G%����HAA��@0���(��F����(�����8�����I�fLY�>���{�J���ć9����Ԍ���m��5��'������~�c�Wg�-��}��< -75a�$��/���[� t�BxB�qFڰ|�g e`@����U�o�ժ����X����'�e�Զ��#}#�N��, �(i��ٛ�mu{��b%g��.]m�pV��8#o��^�'ⶐn����?��m?�ϲ ����dx����Z�o�%OSG�T�/z8,Ϭ�&vH�/�p�6w��b���z��0,�~}>�x(�s�j��i�Í�o�6��i�a�F0c��ɿ�D�GT�,aA�����ǖ��l�7endstream -endobj 2652 0 obj << -/Type /Page -/Contents 2653 0 R -/Resources 2651 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2667 0 R -/Annots [ 2656 0 R ] +/D [2616 0 R /XYZ 71.731 184.588 null] >> endobj -2656 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [474.611 631.143 519.716 640.054] -/Subtype /Link -/A << /S /GoTo /D (installation) >> +2653 0 obj << +/D [2616 0 R /XYZ 71.731 177.45 null] >> endobj 2654 0 obj << -/D [2652 0 R /XYZ 71.731 729.265 null] ->> endobj -262 0 obj << -/D [2652 0 R /XYZ 381.295 705.748 null] ->> endobj -1433 0 obj << -/D [2652 0 R /XYZ 71.731 702.184 null] ->> endobj -266 0 obj << -/D [2652 0 R /XYZ 195.006 666.375 null] ->> endobj -2655 0 obj << -/D [2652 0 R /XYZ 71.731 659.023 null] +/D [2616 0 R /XYZ 71.731 167.487 null] >> endobj -1434 0 obj << -/D [2652 0 R /XYZ 71.731 613.21 null] +1450 0 obj << +/D [2616 0 R /XYZ 71.731 108.473 null] >> endobj -270 0 obj << -/D [2652 0 R /XYZ 161.035 575.994 null] +2615 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F35 1567 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 2657 0 obj << -/D [2652 0 R /XYZ 71.731 565.852 null] +/Length 2617 +/Filter /FlateDecode +>> +stream +xڕk��6�{~�?]m`��v����i��M��s��z8В��EUQ�v��o^��Ip�R���pޤ�,���eZe�J�i2+�O��=���Dƭ���X?Y�E��Z��l���:W�l�E�ʓp�.�5�~g����a�C��� �i����_����1��y�r=1M�L���ry���h�3�%���9I�����oc3�]S��$}�f0�*ǟ��㙬;8��Y��P��2d���P�$Y��6E�j���"L�k;:�0�~,��c���V}_��5X�3� <����x,� �zNb�m�����2?��#+^�٢|,�B's�f̅��y��<��:T+1?���'�Yrw� ��ԓ5 �� u[��� ��v$�h�3�0��7y��9��v5�v+� h�с�k��я�u��4��y�qt�2"JLJ�t�7oQQ�����5��9�����f (Hk����x�w�I��(*����Ů*>8^�ڞ�|(d� +�TY�E�ktpX��g̅x��[�C��n�Xx�؈��h +���hu��"ifZ��D6>�� +�����sX�.�4�К=E[�� ��)F[�*�HH���R��^=}�VL���]��։� ���Z�#�"k��4"G����D�'���7�p^V[��7����G���H#�e��.�NVJg��@L+��j��4�2K�4e3���`��'L1�4T�"�<�R�c�}U�d��Y Ε�W"����'�J�ձǤ3R8�6���F����9%�5+\����&��u��0Y��O��C����KB��NU�^<�� ���v�"� +.%��%�!W$HT���:�\���7�$��ƈ���瑱�SʶcS���4M���f���0P��&����N��a 3Ca��"��w�B�Ρ�u���䐊?�*!��;:��ɱ��f{)��� +�M1"��m1�����1"��;0�W5����#CZ�&%q�i�v�`f뽐C�NJ�p�������$'��Dͩ%O9�`Ę͓C���Z�� +��J�Du\�5��)l�Θ��C�������;�)&����T;�2�DzrE_o*��l,���� ä��TQmd�}:?�.T��� -5�ỤAi%^����I4��S]���D���Rt�vo��i��;3H��$M#�����t*��Gzm�QJ�i���"�Z5��/�d�Pmx����'[;��C/�|�� �>D�s3� fm�2I{�N$�q���_�u*n,� �:��F�(M)�����4x�b���� �iX��"�P%��c̞n�@�q�6��#��|�y�iqJ� t|���w|G�o���3d�[�91��ғb����H1���.#��+�������~&-�\�4���>*� ��o� +��9��V��$��w�$U���'� )EmL�6��|�$���^�{j�d� :3x��hVDXn�6�>?��,K���>]����2o�B�`�o8+=��+���_0���U18�AM= .�R|��卙Ŧ�8�W�nK8�G�B�&��ZW��� ?g���Y�wi���la��5:�k��w�w]UԘ/ +�:���F�+��� �@Mp*������?0�p�4���&��� +N���d#��}A��<�Ѵ]�� T6~�G(n{�S�$�;k�ࣙ���ǀc-�b���WP�1Y]�L*qY������ޔ��P��j�1>AP����P�1���A��,��bt������8X���1vp"�1,益c�Ac[Vذh/ �m��Dr��P��S4Z����Z����ع.Vr�Ɇrg����8�MM���S�è��C���ݛ� O�V�׀�Q�S֤#Z�Wx�( E��ڊK���tD�O�5e���C[�}9�m=������'��免�'�Q��K�BQ2N�Z����`y�2�"�������`��!s�יK�%k7��v��D@�-�䫔1����K��ޖc1<�l�V�}�vxƼa3�G�|�RU���װz�,�R��o~u�#/��v`���-IW�IP��p3����d�����@������������5��2�9���8X�7��>�h2Bk?�O�1?��][���G<�Ӓ}=�_���ADp'Z�S�j�+&.-K��n�G~�ɕ�D`��˥�zO�9�e������w�_�v$��E��E\S���ܖ�s�᳡�?�9���#�d�y1|2�$y2� +��d.w��d�xcfe� �*��E�T���D}�t��*�;�f }�b%�;�wg��(��E����%$�"�q�m�~z棎�\�`�/�[���-6�vϳ������ W�tJ��[��8� .F�+p������\hz�`�n�_%�,x�kd� +O)lZ�2����o�����Hh��ЋV����Z�BCҞI|��ݛ��Xc-�Ԕny�T�R1��I<�A ���$qn���٘���P4�W}�� Ծ�&*ǖ����� ө�?c�/�8W�ξ�����$�Uz"���s��\r��6�endstream +endobj +2656 0 obj << +/Type /Page +/Contents 2657 0 R +/Resources 2655 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2550 0 R >> endobj 2658 0 obj << -/D [2652 0 R /XYZ 71.731 540.761 null] +/D [2656 0 R /XYZ 71.731 729.265 null] +>> endobj +230 0 obj << +/D [2656 0 R /XYZ 533.821 705.748 null] >> endobj 2659 0 obj << -/D [2652 0 R /XYZ 118.555 502.197 null] +/D [2656 0 R /XYZ 71.731 693.31 null] >> endobj 2660 0 obj << -/D [2652 0 R /XYZ 281.083 493.733 null] +/D [2656 0 R /XYZ 332.179 645.334 null] >> endobj 2661 0 obj << -/D [2652 0 R /XYZ 252.403 458.764 null] +/D [2656 0 R /XYZ 135.507 632.383 null] >> endobj 2662 0 obj << -/D [2652 0 R /XYZ 118.555 451.788 null] ->> endobj -1435 0 obj << -/D [2652 0 R /XYZ 71.731 418.62 null] ->> endobj -274 0 obj << -/D [2652 0 R /XYZ 282.307 389.974 null] +/D [2656 0 R /XYZ 442.834 632.383 null] >> endobj 2663 0 obj << -/D [2652 0 R /XYZ 71.731 387.314 null] ->> endobj -278 0 obj << -/D [2652 0 R /XYZ 268.211 359.588 null] +/D [2656 0 R /XYZ 186.556 619.431 null] >> endobj 2664 0 obj << -/D [2652 0 R /XYZ 71.731 352.39 null] +/D [2656 0 R /XYZ 371.798 619.431 null] >> endobj 2665 0 obj << -/D [2652 0 R /XYZ 71.731 329.536 null] +/D [2656 0 R /XYZ 192.546 606.48 null] >> endobj 2666 0 obj << -/D [2652 0 R /XYZ 71.731 123.573 null] +/D [2656 0 R /XYZ 71.731 599.342 null] >> endobj -2651 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F44 1994 0 R /F48 2006 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +2667 0 obj << +/D [2656 0 R /XYZ 381.821 588.547 null] +>> endobj +2668 0 obj << +/D [2656 0 R /XYZ 156.806 575.596 null] >> endobj -2670 0 obj << -/Length 1895 -/Filter /FlateDecode ->> -stream -xڭ�nܶ��_�E�-�\J�5o��)Z�m8�-Z˵�J�V���|}g8�.^�� p8��s�����,��9��+�������R�-�zF�b{�y%���<�v�EA���KEȲ8������Rխ�a�������Y�U{G�ǻU]��/�o/^n�Kc��<��ќ e�`N?�1EF��%,d32���-W�~� �/V���v߫��;r�*L'��[ X�o��G�&�B�TFg�W���ӻ�#P�v���ú�z��-��=�O�e��v'K�Ԏ�A3�[\5��P %A7?�|��Dث�}J:���% �$�eY��N�R7j��zӜ���sd�%���$�����+��[G"aq���B�ǁ�=tjM���&Q�U�����q����/�?��ڟ(t`?���Rk@=����,���p�tpa�ޱPt���$�Ϝ�p'm�� �1���i�l�3<eq��o13 -��N�+{k�P���JBx�.�\�xt��l��cێ9�[ZI[����qHcE�Ȋp�ӄ��,�U��%�S������}��2��z�$�W7t7��$F�O��%�"h*��`d�y�-Ԅ,�y.l��$�'��4��4�ߡ���QU�?����ce�Y�D��j��N63��ܿ]���u���݉6�9���gE�'E��8��Z�r�?�ʘ#��J��E��0�����1{}�ր�B�����L������-� B0��h$ �Cd��ަ�����Q��X����[��nxj;�b���[��r��S�['��_~J�ED���$6� $���i�K�� Uc\8�1��*��n[U8jMke�����9���-���J���a��H�������s 4I�DsP]S�=dt���U!�cv=sJ����*�e��1�,��E]9V0��6�B[�)��h��+�+.�R�.7���M�{�9�0�ʋ)0C�� ���փzf�L4х���ܵ��Z��;BԝBYq���c�()�=mNX"����ޯ�1B/�1��"W ,�ߖ,쵶����{U�:�*�-����(^3gZ�I���L��0�p�ַKa��r�p):�BQ��j��'܇�=� �����k��/_,�����@{�F|�t��RaCp2?�k�P�Z�ˈ�4���5���p�c��� P+"O$ԣG��/~��{;�g���_����#��E�{�s�u��_���a���"�#<�[C����,��h��!�d�p8�L��"�Yȩ*�g�u�3C�YF���~�x��#��~����o��-n&���hz�`\ ��.��]S� -�Z���(l�6H�g>ܘRkb�" -��X��s�|]D�|�*�=��o����`~�M -ij�B -�1� ��Mh`�#�*:j����ln-o�����t-i�2� =K��1�o�%�ܴtbʍ�����\�FP���tbXʪ( ���Fv�P҂�ⳳ�^$ ��YH����1a@��T��$̡#f��yb�����8r�q� ����Y2�,�f�Er;� -��W�ЩF�c�:cI<,J��q�B�x���W� �-���z�%2�zyoF�]���r�5s} >:gh*-�n����u -z�ؙ�J�gOL�[�����1��B7 䌝z�pdc'�;5<��珜�3s1.L���c�j�jt+k�ٗU_�Q̒�����l���"��C����r�6�f�����9��M���4(v����%�O�Kc�iux��?���wQ�#ƨ�F ����M�Γ�������ݙ�B�0=��ADh+=E9B�bµ0��&��2�\?�ȨҼRل�2���~*�H�~)�C�7tLLш�߯_�7� ��gendstream -endobj 2669 0 obj << -/Type /Page -/Contents 2670 0 R -/Resources 2668 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2667 0 R +/D [2656 0 R /XYZ 282.571 575.596 null] >> endobj -2671 0 obj << -/D [2669 0 R /XYZ 71.731 729.265 null] +2670 0 obj << +/D [2656 0 R /XYZ 190.714 562.644 null] >> endobj -282 0 obj << -/D [2669 0 R /XYZ 228.441 708.344 null] +2671 0 obj << +/D [2656 0 R /XYZ 71.731 555.506 null] >> endobj 2672 0 obj << -/D [2669 0 R /XYZ 71.731 703.158 null] +/D [2656 0 R /XYZ 71.731 506.689 null] >> endobj 2673 0 obj << -/D [2669 0 R /XYZ 427.619 690.411 null] +/D [2656 0 R /XYZ 71.731 422.669 null] >> endobj -2674 0 obj << -/D [2669 0 R /XYZ 387.295 677.46 null] +1451 0 obj << +/D [2656 0 R /XYZ 71.731 402.58 null] >> endobj -2675 0 obj << -/D [2669 0 R /XYZ 71.731 646.476 null] +234 0 obj << +/D [2656 0 R /XYZ 350.135 359.482 null] >> endobj -286 0 obj << -/D [2669 0 R /XYZ 199.549 613.699 null] +2674 0 obj << +/D [2656 0 R /XYZ 71.731 347.311 null] +>> endobj +2675 0 obj << +/D [2656 0 R /XYZ 71.731 304.882 null] >> endobj 2676 0 obj << -/D [2669 0 R /XYZ 71.731 606.501 null] +/D [2656 0 R /XYZ 440.415 294.087 null] +>> endobj +1452 0 obj << +/D [2656 0 R /XYZ 71.731 278.979 null] +>> endobj +238 0 obj << +/D [2656 0 R /XYZ 242.621 241.764 null] >> endobj 2677 0 obj << -/D [2669 0 R /XYZ 71.731 583.646 null] +/D [2656 0 R /XYZ 71.731 234.411 null] +>> endobj +1453 0 obj << +/D [2656 0 R /XYZ 71.731 193.579 null] +>> endobj +242 0 obj << +/D [2656 0 R /XYZ 175.703 161.266 null] >> endobj 2678 0 obj << -/D [2669 0 R /XYZ 147.048 574.147 null] +/D [2656 0 R /XYZ 71.731 155.139 null] >> endobj 2679 0 obj << -/D [2669 0 R /XYZ 147.048 562.491 null] +/D [2656 0 R /XYZ 231.715 142.337 null] >> endobj 2680 0 obj << -/D [2669 0 R /XYZ 71.731 540.872 null] +/D [2656 0 R /XYZ 131.551 129.385 null] >> endobj -2681 0 obj << -/D [2669 0 R /XYZ 71.731 517.858 null] +1454 0 obj << +/D [2656 0 R /XYZ 71.731 109.295 null] >> endobj -2682 0 obj << -/D [2669 0 R /XYZ 147.048 506.301 null] +2655 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F32 1215 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 2683 0 obj << -/D [2669 0 R /XYZ 147.048 494.645 null] ->> endobj -2684 0 obj << -/D [2669 0 R /XYZ 71.731 473.026 null] ->> endobj -2685 0 obj << -/D [2669 0 R /XYZ 361.161 460.075 null] +/Length 2238 +/Filter /FlateDecode +>> +stream +xڥ]��8"�=�L˟q��@�ؽ�a[0Y���pplebԑr��4��)ۉ���!@DQIQ����\�R�!A&�$^�7��V��F2ŊIV���oֿ��"Y.��E$7"Ki�M,����C~�T�\����������_���:_�{��7?o�q��l����� �"�c���߈0��f���V�t�=-C�SMM����k���h�t���;�/Vx� �\���� �[� �~_F�W��,��{mi�Q���F�;(�m�"������{���6Y�"7�d��H�6��YM��d�c]3��=����L�O�x&~� M�g����xA���RǼb]�j��ݫF邭W���C��ur�7hG \`��B۷��>U&E�����@�[�b�ՄfWlP����ka� ��4G375��8}v!���SyIag�4�Zf��� ���s� �U +�W �H$�����e�s�H�m�6�%R�N��*�}+�&'oƉ�4x���Z1�U�8���q��T�Ԛ~)�����i��,��6 � +�Z�R�W�0�A4"*�>5f����<��?G��2����}V�ץ�=��?���a҇_ak�˕�M��Rڳ�����^>ҝ���3����|�y��+�{���\�ćP������z�N��:Ӝ�CK���5������n{��V��Uz�r�p�������U��];N��4/k�Tzkv�p.�Y��z(�)����� I~�bf�}��(M� �ԅ,%ds*��g5+B�i�=� �����Q�A�/G~� ��)Y~N�Zd^W/��z` ���)ͬ�� �^;�QN�W�����H8x>@�� ^M��J�����pk1q�������Jz�����W{�a,�����l�����dTH���ӦJ��S�GR;�����j������s���.��K�����n�U]�z�AI ��(綠�h�c#�) �X���7q����gy�b#�fO1?̊�lpn�Ӎ�%M>:C�ȉ�0�E�N*�/,���c����cRL'� ��.e䁎�78�����d�c�:F��;h1(L��A�*�}W�Uw��m��f�����ȿ1�ˁ��1u���n�И�j���I��!��;<홻7�uTӍ��n����F��(�P���cv���yMhk����V�t���� ���}'~`�衸��aP������H�Rn�di�]؞5�xl�W.�'��`ҟ�ܟ�7%3���Qa�����L_EO�������3X9 �v8ةm"�D���p��w��=�d#�v�m���(n Z{K���·�?��$��5��k�64��=,�@�(�F�]�(�ԌX�y�1�����"���E���lri_�36:ҕ�_yU;��>�����y�R���0npB��[��a�7]}#��J)��G"�R +�?�i�4W]��Y+��|���5�:��@$��;��H�D<ajr�9bKx�q=mG�6��Vs<���%�;(46����B2`7Pľ��U)�ꓡi�nYh�`�M(ۀ"P�i�#�ݱ��o�X�)?� +�.`X'��7�U� %~pG }7���3�"HR�g���'�YM���+F/`�Av�3���ۀ���4��_1�0 +�hS=�*.��7���X�_�j��hiO��_М}ޟ�<۵ș�N�����p��Q�~�=���{�kF3�Cn��;�/B�f��;������mWB�Kd&��O8NL������A��q���>X��"vh�pbo��:�{���S������;+��Mo�˸����á9i� ���t�+~R�9�t�kxz�COq����Q|�/E�,��X�tP����P�����7�R�� �M+6q�8>�LU!?��H�o�3�,�6��RG����U�3�/&P���d����Oو��]^鋮�q�;\�q�oN+�ҵ���R�w?�nO�4qO�u�6�]������Ms���'��G@�PwN +}<z]5��c^�Uȷ� ��;� +�S���W�= +�ƕ�=Hk�[�ڥ��#�#o=(�wR�aν�ե܂�M����xЎ1��N;�\ ^쐬�ayyq���[���������u.^����&;�� O��L�~�If�"c��1�|���\���"N!�endstream +endobj +2682 0 obj << +/Type /Page +/Contents 2683 0 R +/Resources 2681 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2550 0 R +/Annots [ 2686 0 R 2687 0 R 2700 0 R 2701 0 R ] >> endobj 2686 0 obj << -/D [2669 0 R /XYZ 71.731 444.966 null] +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [330.238 687.258 383.277 696.169] +/Subtype /Link +/A << /S /GoTo /D (install-perlmodules) >> >> endobj 2687 0 obj << -/D [2669 0 R /XYZ 71.731 430.023 null] +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [91.377 676.364 112.249 683.218] +/Subtype /Link +/A << /S /GoTo /D (gloss-ppm) >> >> endobj -2688 0 obj << -/D [2669 0 R /XYZ 76.712 380.573 null] +2700 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [139.526 264.942 191.829 273.853] +/Subtype /Link +/A << /S /GoTo /D (security-webserver-access) >> >> endobj -2689 0 obj << -/D [2669 0 R /XYZ 118.555 337.028 null] +2701 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [478.054 264.942 530.357 273.853] +/Subtype /Link +/A << /S /GoTo /D (http) >> >> endobj -1436 0 obj << -/D [2669 0 R /XYZ 71.731 263.513 null] +2684 0 obj << +/D [2682 0 R /XYZ 71.731 729.265 null] >> endobj -290 0 obj << -/D [2669 0 R /XYZ 138.296 231.009 null] +246 0 obj << +/D [2682 0 R /XYZ 245.449 708.344 null] +>> endobj +2685 0 obj << +/D [2682 0 R /XYZ 71.731 702.217 null] +>> endobj +2688 0 obj << +/D [2682 0 R /XYZ 71.731 666.401 null] +>> endobj +2689 0 obj << +/D [2682 0 R /XYZ 120.149 654.844 null] >> endobj 2690 0 obj << -/D [2669 0 R /XYZ 71.731 223.657 null] +/D [2682 0 R /XYZ 71.731 633.225 null] >> endobj 2691 0 obj << -/D [2669 0 R /XYZ 71.731 185.814 null] +/D [2682 0 R /XYZ 71.731 595.203 null] >> endobj 2692 0 obj << -/D [2669 0 R /XYZ 114.77 176.314 null] +/D [2682 0 R /XYZ 71.731 595.203 null] >> endobj 2693 0 obj << -/D [2669 0 R /XYZ 114.77 164.658 null] +/D [2682 0 R /XYZ 71.731 574.047 null] >> endobj 2694 0 obj << -/D [2669 0 R /XYZ 114.77 153.002 null] +/D [2682 0 R /XYZ 71.731 554.122 null] >> endobj 2695 0 obj << -/D [2669 0 R /XYZ 114.77 141.345 null] +/D [2682 0 R /XYZ 91.656 519.153 null] >> endobj 2696 0 obj << -/D [2669 0 R /XYZ 114.77 129.689 null] +/D [2682 0 R /XYZ 76.712 502.516 null] >> endobj 2697 0 obj << -/D [2669 0 R /XYZ 114.77 118.033 null] +/D [2682 0 R /XYZ 71.731 482.59 null] +>> endobj +1455 0 obj << +/D [2682 0 R /XYZ 71.731 419.726 null] +>> endobj +250 0 obj << +/D [2682 0 R /XYZ 341.46 384.259 null] >> endobj 2698 0 obj << -/D [2669 0 R /XYZ 114.77 106.376 null] +/D [2682 0 R /XYZ 71.731 375.622 null] >> endobj -2668 0 obj << -/Font << /F33 1278 0 R /F48 2006 0 R /F27 1180 0 R /F35 1525 0 R /F58 2421 0 R /F32 1187 0 R /F23 1173 0 R /F44 1994 0 R >> -/ProcSet [ /PDF /Text ] +1456 0 obj << +/D [2682 0 R /XYZ 71.731 345.24 null] >> endobj -2701 0 obj << -/Length 1578 -/Filter /FlateDecode ->> -stream -xڍWmo�6��_!C+1#R��!I�!C�e��aX����H�,z����߾;eIqR��#y�7>w<q/��R���3���z{x���� wKDz��\�N�ކ���< ��Ƌx���KC��Xx��/���;���Rā/��Mgd]W�=�/��������W?���:(�Ô�Y�U��#���k� �<b)d,�"kXW.�I�W��T�}�h�,�ͮU�j�����g�ު���g;��h&8�� E��%qj%�ɮ��x�6L�e�ʏN�˗4�+Fu�h q���T�t��2 -Y��2��3�f �D��{�Qʅ�O�v+�o�)��D�b�M�$j���vO��8ص�N�����$:�s�L�xch�ó��s�@�4�#��_-x���s.v�K��;�M�Z���t��n�}0��I���p�u[�LwJ}(�uId��X(#+�����?��j�є�N�+�=�c ��`�V�` �0I�̿]��O�]���CD�����if�qB!��]1.m�$;��HC��e��mh���%�*�9^�L~)�������Qz3���(}����ªT�ۓa�5M�j���Qp�U��W���Lʔ���!T��P�a����(�,8a�j -�SM!A�]p��2�c2xe X�jZuQ;��ni$w�����N��7X'�I}k=�̝Vk3�F9 �����H�{�U��0�]ps�F3 �[&��y�|&� T�1� ������QDJ�rW�����>���Z�}� ���I�`8�^�B>��Q��D��s[0��l�,���!��u9&ݸ�\A����}�d<\�n;US���?�e9Ƙ����!���v����MҞ�/��Z��Q�'i�]⯬y@\���E��T ��W�V�� ��Z;��V�u�֝�Q*�V�����jK�cb�d��4è��Ј=%{ �4)�V�`���_��ҽ;��Ӄ� {��s�H�����.�>V(�#�n��/�;�RY��v�4L���uMQ8�0��l��� �����r���;�yρ�%�ԮC���Es-�Z�W��WO���`q@��ES�j�n��_�d���fS�q��s�7E��ϩ����o��Eio_j��f�����ܦ�y�O=�<T�1@���P�{��O���w[(��$�z�|�5�ul���n -D68qz�Y����QFP̰2bvv}���v�\C���em�,8.,Q��(���`� |�z�\V�VmgЍ<��c�5���`�?��A ��ƅ+�r̰ �Xd`�� �T�sWHaKf){�$�풋�n�K�oi�_,�O���;�w�p��tB9}���tU������ &9���@6\SR�-��v]>v�D�� N�H�C�����a��g[cU�F -��F���,���R�O�&�S��K��>��{Z���{�Ә���70T6>X�8m.��8ٌ�?���:1/�]_���_ζ{[�ꎶ>�0rb<������.��x��\�fO�+*4��#1��; -��x���>���e<����r����bb8~��X��\�!�endstream -endobj -2700 0 obj << -/Type /Page -/Contents 2701 0 R -/Resources 2699 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2667 0 R +254 0 obj << +/D [2682 0 R /XYZ 244.612 311.93 null] +>> endobj +2699 0 obj << +/D [2682 0 R /XYZ 71.731 303.293 null] >> endobj 2702 0 obj << -/D [2700 0 R /XYZ 71.731 729.265 null] +/D [2682 0 R /XYZ 71.731 264.942 null] >> endobj 2703 0 obj << -/D [2700 0 R /XYZ 114.77 708.344 null] +/D [2682 0 R /XYZ 71.731 249.998 null] >> endobj 2704 0 obj << -/D [2700 0 R /XYZ 114.77 696.687 null] +/D [2682 0 R /XYZ 322.74 240.498 null] >> endobj 2705 0 obj << -/D [2700 0 R /XYZ 114.77 685.031 null] ->> endobj -2706 0 obj << -/D [2700 0 R /XYZ 71.731 663.412 null] ->> endobj -2707 0 obj << -/D [2700 0 R /XYZ 307.022 650.461 null] +/D [2682 0 R /XYZ 317.417 217.186 null] >> endobj -1437 0 obj << -/D [2700 0 R /XYZ 71.731 630.371 null] +1457 0 obj << +/D [2682 0 R /XYZ 71.731 189.29 null] >> endobj -294 0 obj << -/D [2700 0 R /XYZ 200.472 593.156 null] +258 0 obj << +/D [2682 0 R /XYZ 197.318 153.823 null] >> endobj -2708 0 obj << -/D [2700 0 R /XYZ 71.731 585.803 null] +2706 0 obj << +/D [2682 0 R /XYZ 71.731 145.186 null] >> endobj -1438 0 obj << -/D [2700 0 R /XYZ 71.731 532.02 null] +1458 0 obj << +/D [2682 0 R /XYZ 71.731 105.559 null] >> endobj -298 0 obj << -/D [2700 0 R /XYZ 256.412 499.706 null] +2681 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F60 2527 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +2710 0 obj << +/Length 2630 +/Filter /FlateDecode +>> +stream +xڍYmo�8��_a���ČDI���}H{�nM7@��.��A��XY��n��ђ%;]���pfH�<3d���,�T��G'J/�Y�{��a��+O8²�Y��y���D%K���/VI4�|��P�V��8o��5�|�C�ъ�ʦM�"/���{�_^������iuT��Jb�E�,��0�ϼ@��-�t#Y�U�Ƞ(v�Ҍ�_>���2�~q�l�]��fߥOS�u�{�S�OܪJ�ޥs�ɘ&%������i��n ��(����QQ���kڝ)�F���HO%a(�� +���<Y�gS�wi^�]��Nh�4w����̅/���U>w�嚻��8p�k����u]��{����m��뛛��0�9jLġ�z���� 0y,0oxZ�Q�Jot<̵�ty�.r���i�1���:`U�z�P!X&V�� +���k�}TS�Ѧh�V�a�L�I^ֵ�Ca�Q�-S�|�gr� l5�c�ÔU���)�=ܪ8u�k9b�RT�Co�yY��c�Jз�fު� + 0 :q�(#o��7Nٜ&'�L02�{�c=0p������D=d�Z��2��0H��W&6�i���!o�U�2,�Eq��ef����a���8!�?W��Yr��z|�u�)zσ��zp��꒩J��*d�k(Y5���:�B9l>�MU?A�k�-+j�Ԥ���9�b�M����!�qdg5,�'��c'�w(j��;2�|�wi�m}�g ��4Y����byϐi��9� V6Fu?\�(Hfa�p��[�ŀ�Q}�]cA���&� ��7V�� +�uˋ�GbP�9D�#����P���m���?�i��A�����ñ����T���r���z����~o�k�^�Uk�)+��� ���A�d�d8Q���)M��Ҙ�1�卅@�FrA��:�o�s0��ܣ��2�s9!���]�iH�"J�A:B3�3�C�X����5��m�mE�ly�^�����2�0L�w+o��vn?�����[6�.�iĶj��V�{��Wޫ�͋�בM�E�a��Ap"lxN��6u�cJ�rSuu��E�بҴ7�c@<57��O7�΄ǖ*#����E���q��m��M��!����f�+L�M/��N�@� +��(XZ��)j +L���Dbo=E�� x�T@�����qяk= 6�4 �a�fO)�"m?Tbat�o�ulP�ۻ��r���������1(�@!G�fXl�,'ܾ���7<~�|%b0Q#��E�#:(�A@�KX]�O�6#��s�u�d�l{z�d�s�yx�@�`J�#�9(�=B}@]�Y��*�[����Y�&7�� ��@���c��D-�Q��L�KG�>~|����=l���SV���E�4u�m�./]/Ւ��Z�9����!$�P||5��]�e<,� �,����{���&�G��*G����9���M�i�()UP�$��I��NYu���L���H�r�f^FE2��1�<oe6]�L��X�R̡H�^Y���2��U[c��P�q=V�mR�"m��9L�a��qؚZ�QHr:�˃�oSDQF�l�튎��9a݄�kEI�d���w��� ���SS�BL�(�5S��5�n� ���E��K�8��3��I��~�nP�d�|��@0��]�f" +�F�F�Xw��;�x*�+�k���[�?�.ʹl^�<�:�b�~#��])�u?ǫ%�L�];*��`ӏ< +y>B�/0�6O�xw� +83<%qI,S�^1�8���Fؔ�����ܵ�����G�7��*���(PKo�C_�U��;8I� �{�DT���^r[4hA��M�^�n���<.ePy3-��T��Q��{��'�����Q���L@��5�뽨k���0?��B����)B�A�O�!8��K��}|���Q�1|�\x��|�dw1���+�Vܳ�2��ɪ��lpO�2Dίe��dl��c�'+k�#"ЁY;8.��V�OD���4����X�� +�ӫuQe��dy��]����/�;6�䁴W����Cx��P�^|E�n��;����Ag��Г��0�����拥�{�(�Zܽ���檨�'lX���b��!&@:�}c���{z�ya���41�.}2�*�����ӗ{�Y�����߮~��E;z�����qd��t�U;P���d + +���D}2`c��+���hh��n��E�����7o�&���<T}��#V���S;�1�T��s�ߣ2eb�-c�����+���s���X�[㍙=�R��Ϛ�,*����&ǔ d&`��Ԅ�G7/.��!�~�n��*�B���[���5b�9=��f4'���oe{��w�#>�R��^ӹoeÞ����pkN!�6��y�0M��$H��ǼLe�\]p7/��N�%w�\r7�2�m� +��rF�EW�)�g\m������k�Z���� ��V�tյ{|�A6~jA +N�1L�O��H�{;�6�Ee9��3w}��?��@��Й�k꺪�C&����F~���i~�L��J~Y�����U�>XL����%' b{/�H�2����Am�Г��_�SM���V�endstream +endobj 2709 0 obj << -/D [2700 0 R /XYZ 71.731 491.254 null] +/Type /Page +/Contents 2710 0 R +/Resources 2708 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2742 0 R +/Annots [ 2716 0 R 2723 0 R ] >> endobj -2710 0 obj << -/D [2700 0 R /XYZ 71.731 460.688 null] +2716 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [356.749 575.373 401.58 584.284] +/Subtype /Link +/A << /S /GoTo /D (parameters) >> +>> endobj +2723 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [244.482 438.332 269.647 445.206] +/Subtype /Link +/A << /S /GoTo /D (gloss-cpan) >> >> endobj 2711 0 obj << -/D [2700 0 R /XYZ 71.731 450.725 null] +/D [2709 0 R /XYZ 71.731 729.265 null] +>> endobj +262 0 obj << +/D [2709 0 R /XYZ 177.791 707.841 null] >> endobj 2712 0 obj << -/D [2700 0 R /XYZ 136.289 441.225 null] +/D [2709 0 R /XYZ 71.731 700.488 null] +>> endobj +1459 0 obj << +/D [2709 0 R /XYZ 71.731 685.559 null] +>> endobj +266 0 obj << +/D [2709 0 R /XYZ 168.088 653.246 null] >> endobj 2713 0 obj << -/D [2700 0 R /XYZ 136.289 429.569 null] +/D [2709 0 R /XYZ 71.731 647.119 null] >> endobj 2714 0 obj << -/D [2700 0 R /XYZ 71.731 390.017 null] +/D [2709 0 R /XYZ 187.795 634.317 null] >> endobj 2715 0 obj << -/D [2700 0 R /XYZ 71.731 371.985 null] +/D [2709 0 R /XYZ 71.731 614.227 null] >> endobj -2716 0 obj << -/D [2700 0 R /XYZ 71.731 362.023 null] +1460 0 obj << +/D [2709 0 R /XYZ 71.731 570.391 null] +>> endobj +270 0 obj << +/D [2709 0 R /XYZ 331.166 537.081 null] >> endobj 2717 0 obj << -/D [2700 0 R /XYZ 136.289 350.466 null] +/D [2709 0 R /XYZ 71.731 530.954 null] >> endobj 2718 0 obj << -/D [2700 0 R /XYZ 136.289 338.809 null] +/D [2709 0 R /XYZ 71.731 511.014 null] >> endobj 2719 0 obj << -/D [2700 0 R /XYZ 71.731 299.258 null] ->> endobj -1439 0 obj << -/D [2700 0 R /XYZ 71.731 268.274 null] ->> endobj -302 0 obj << -/D [2700 0 R /XYZ 219.101 232.907 null] +/D [2709 0 R /XYZ 220.441 487.268 null] >> endobj 2720 0 obj << -/D [2700 0 R /XYZ 71.731 226.78 null] +/D [2709 0 R /XYZ 71.731 480.13 null] >> endobj 2721 0 obj << -/D [2700 0 R /XYZ 71.731 195.945 null] +/D [2709 0 R /XYZ 455.258 469.335 null] >> endobj 2722 0 obj << -/D [2700 0 R /XYZ 71.731 185.983 null] +/D [2709 0 R /XYZ 71.731 462.197 null] >> endobj -2699 0 obj << -/Font << /F33 1278 0 R /F58 2421 0 R /F35 1525 0 R /F27 1180 0 R /F23 1173 0 R >> -/ProcSet [ /PDF /Text ] +2724 0 obj << +/D [2709 0 R /XYZ 71.731 438.332 null] >> endobj 2725 0 obj << -/Length 1713 -/Filter /FlateDecode ->> -stream -xڍko�6�{~�t��Ō��:l@��m�&�Q��@۴%T]JN� �oߑw�e;m����x<��N�#��(�, a r$�h^����9�D1!�ɀ�|zt�:G9˓p4]�"��<�a��8Mz�XwR�'A�{���i;QUe����f�wYUb������i�h�,��/��h�G M����(�3F���DƓ����Ǚh�W����I]Q��I�����{�A�h��G�PW�-B�4��*gk�k�Ȧ�mU�;��NJ��fy�X�'�ʮ8$uP]��1�8���tO��IL��b���wZ?���i��s$]Aw��nnϦoq#��R���5�7�]�Y�4lN���N�G���{���ZiQ�);�P9�8gI�Z�*�>"I�8!{�+s�����l��=�+�j�0�1����d�j�V:O���/.o~����ח��#�=>TΎ��L&C.,J�8rϐ����� �wW石&Y�)Ǟ5 -X�>��G��Td���iO�[:߸�� -�������ݔ\#�169:�r[l_h�C�d�:���Oh"=�� -�YmO_鶨L�b��&�ϲ�N�{N, �!n�F�1��1�aֹ���\0��(��wJ?�֘(�s -P�)T-�I��#DK"H'���cH�ϰ�<eI�Km(C����#"89��8s�M�>y?̟��d<?���pA� j��8��>��B8��������AKil�eh}X1�,w����d�.H���C��w6�{�b���qo��c�lB�d4�!� �L�2<�X�{�k%�+ɮ�[W���-��ʪ��J9��fu�������;W@�{w�T�R�tin���Jv�;�6�'��˨F�x`64� ">�~��Г���j�`ߘ��F[�������]����\VJ-*R0P��נ��Tߖ��`�}���M[��P"p1 -�X@2�����L ��JJ �ٷ��/�N��v '�D�CM�/n�;�*��5��|"��{q�b�k���ab��6�� ��ul��V]sb��b~�!p���-�*�ky8' � b�a��Ѭd�=-$�H��8��4$fv�j�*���U�ly���k���5�s�fQ�8�c�i,8Z~�9ת5�HBL�$"��M�����^�� �]�m�صFs`���l�W}�T�i����8�m��hk ��#b -1������g�>���E<��?�P�5�����<1p���^����o����YD��H ����D��x���D�#��Je�r�\{� �w���D[ ���U�{�t7�1����1ϼn $Le��H��tR|X�ڵ%� �@ʬ���(�I��5D�XI�L1C�f�Ĝ k�$ކؠ���y][�;��}��r����L|��|�� 8��&��������XZ�έ�#��a�܆��Vtka��JE�~̧�l���[��0�-C�8���"Q����k Q#�����P�h+Ig�¶�% �W� -LG҃�-bעmm���'b��V54Y@����b?����hL�l���{�l�$��Rbx�TU�E��z����b��Rj��caPU�Ϫ��a�|۠������Ӝ��~�o�����d �U�C���vH���ʧ�}�͏|wMճ�hA?�D�x�şR�$���A -g=�X�|��ç����dendstream -endobj -2724 0 obj << -/Type /Page -/Contents 2725 0 R -/Resources 2723 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2667 0 R +/D [2709 0 R /XYZ 71.731 423.388 null] >> endobj 2726 0 obj << -/D [2724 0 R /XYZ 71.731 729.265 null] +/D [2709 0 R /XYZ 121.379 400.194 null] >> endobj 2727 0 obj << -/D [2724 0 R /XYZ 71.731 552.229 null] +/D [2709 0 R /XYZ 101.884 388.538 null] >> endobj 2728 0 obj << -/D [2724 0 R /XYZ 389.403 539.278 null] +/D [2709 0 R /XYZ 156.232 388.538 null] >> endobj 2729 0 obj << -/D [2724 0 R /XYZ 410.125 539.278 null] +/D [2709 0 R /XYZ 254.126 388.538 null] >> endobj 2730 0 obj << -/D [2724 0 R /XYZ 430.846 539.278 null] +/D [2709 0 R /XYZ 313.316 388.538 null] >> endobj 2731 0 obj << -/D [2724 0 R /XYZ 494.944 539.278 null] +/D [2709 0 R /XYZ 138.317 376.882 null] >> endobj 2732 0 obj << -/D [2724 0 R /XYZ 71.731 493.285 null] +/D [2709 0 R /XYZ 239.635 376.882 null] >> endobj 2733 0 obj << -/D [2724 0 R /XYZ 71.731 475.353 null] +/D [2709 0 R /XYZ 71.731 348.987 null] >> endobj 2734 0 obj << -/D [2724 0 R /XYZ 71.731 465.39 null] +/D [2709 0 R /XYZ 175.156 336.035 null] >> endobj 2735 0 obj << -/D [2724 0 R /XYZ 136.289 455.89 null] ->> endobj -2736 0 obj << -/D [2724 0 R /XYZ 136.289 444.234 null] ->> endobj -2737 0 obj << -/D [2724 0 R /XYZ 71.731 404.682 null] +/D [2709 0 R /XYZ 71.731 298.013 null] >> endobj 2738 0 obj << -/D [2724 0 R /XYZ 71.731 373.699 null] +/D [2709 0 R /XYZ 71.731 241.888 null] >> endobj 2739 0 obj << -/D [2724 0 R /XYZ 71.731 363.736 null] +/D [2709 0 R /XYZ 71.731 231.926 null] >> endobj 2740 0 obj << -/D [2724 0 R /XYZ 136.289 352.179 null] +/D [2709 0 R /XYZ 71.731 193.903 null] >> endobj 2741 0 obj << -/D [2724 0 R /XYZ 136.289 340.523 null] ->> endobj -2742 0 obj << -/D [2724 0 R /XYZ 71.731 300.971 null] +/D [2709 0 R /XYZ 390.582 178.127 null] >> endobj -2743 0 obj << -/D [2724 0 R /XYZ 71.731 229.076 null] +1461 0 obj << +/D [2709 0 R /XYZ 71.731 148.075 null] >> endobj -2744 0 obj << -/D [2724 0 R /XYZ 71.731 219.113 null] +2708 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F44 2037 0 R /F64 2737 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +2746 0 obj << +/Length 2161 +/Filter /FlateDecode +>> +stream +xڵ]���}��>T.�\Q��c4��+r�E[�݃V�mue�'Jq�_��P��� p@v�+r8��r¯\eRd +>Q!�4YU��p�����$cle�������G�V�(R�zܮb��"[e*y�����8�~���0�}�tv(۶�v4�~���i�r���绿?NL��"W���qn��J�B�)J�f"���,�P(P��4�Z�����m��}�� ��eb�|�p��B!�đ���6$[U��V�A�U�XkK`���Lݟ ��_Ʀ�5�ʵ:��И�li�6O=��}[����O�ǽ&�.m��@��V������`�^l��xP�"!}=��(F��ME9� ��hVO�D"،���ͭ�20�����4 �y�%g3`k�֠�Ns�i�2�\���)o��7c[p_���5O�W1��T��`�v��6,{m����`�+�9�<A<T{]=[=�Gqlo�&")�B����h��<�%ت��Of䅲�c�ir��k'�rvӃ%���g-�N���me���ɥ�b́GfK_���S4%]VG�Ȝ6�d�H�TdM����0�0�4e�H�b24�M�����K{K��l$PO�o�^��~�Ө��?��۲i�i-��}2�D�b��I��) &J�$F�-b��l{s0��j{�9�&q!B���\8.��Y&��"�<�7�1z���w�N[n�/�3/D +�,���p���L�>�[]hח:����!5e"�(���!hR�"�ܔrf��7��ѧ0 ;�mz�Lc�KZ�tZb� �;3h;�� DtU�E)<���c5̂~5�ax���`aj�5A���(� �`�S��RZ���i� ��*=-�#S�l����� �B��*m-�P?'�D{c�4鞐8���%��c�YH��@�X����tD�<j0+�۴�Ȳ��`&Ee�z ����,\p'��wq�0@�+�;V{��p���oZ�{�)Pw5f+�h_�D�p�i�7�nO`��K���4|e*T��z�͌s�2WdPYt�4�7���@��q�(�qN�H���Oa���wؚ�"K.���pٝ�S*�p�ٱM7�)�9�����U;裥�/�8>�9�s>�l9n�V����K��E�LR�,�n�3�=>�I�&����ߞ?������VH3���b*J=5��jq�S���E/4t�#u��_���(t�d<��������n�� BcЇ����MYH�d�FtPޱx��j^_�x�pB�w��p��{s�����"�R��6U�/�ʚ�P��M��d*��h�w��AKh撶�� �C\;��P�g�JA�ϡuo�r��s����~�������c��TV��(����j{���*.��WF�������6��4�J7�B &�C=�D��U�kcr��u���62��4�"'�ʽm�d�JE`�k�j����;�f���q��%���A}��� +��X��;�\���wF9�P?����㭸*���WmGꞃ����ܙ�3��PB��r� �B���%����8@+ �Dt!���B.X�" +ˣE� +�2�(%�̯��C��#��������>��?t�!��i�`�Lt����B���ϵi�PT��#��o��1��fǸ�m����1Ň���msh]?t�L��ˎ�."*�"`��A<,00���@���p2Y���e7,�1�L˼�y�3$��ԇ�k��J5�r�T��U8p�$�2����-W =��P�B|瞗����1;_i�\@)���*�8���-jʳc]6�4���^x�w��d�c��i&�wa��]���%� 7ݰ�r��xY�� +|��~����y�S���G@��=��%�y��kZG{��ht~k�h ���dT�bY��_�I_ 殈X+��UW�@��E�����b^�C��l�Lp�Et�`S�,zB�)Bw6�8��y?5#�\���Z�(u��x=d��EćYR�t�~���>�1�vXi�Fv��#{����_,���s��� �Uc�z!����@�*�+�=�H����곂0p��q~z؛�~�sI��d�_��%�� +hz����xZ`'/�|>�����W��\�2{�y`F�yz��*��qW�9�����k�Aendstream +endobj 2745 0 obj << -/D [2724 0 R /XYZ 136.289 209.614 null] +/Type /Page +/Contents 2746 0 R +/Resources 2744 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2742 0 R +/Annots [ 2765 0 R ] >> endobj -2746 0 obj << -/D [2724 0 R /XYZ 136.289 197.958 null] +2765 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [474.611 414.233 519.716 423.144] +/Subtype /Link +/A << /S /GoTo /D (installation) >> >> endobj 2747 0 obj << -/D [2724 0 R /XYZ 71.731 158.406 null] +/D [2745 0 R /XYZ 71.731 729.265 null] +>> endobj +274 0 obj << +/D [2745 0 R /XYZ 245.404 707.841 null] >> endobj 2748 0 obj << -/D [2724 0 R /XYZ 71.731 133.335 null] +/D [2745 0 R /XYZ 71.731 700.488 null] >> endobj 2749 0 obj << -/D [2724 0 R /XYZ 125.529 123.836 null] +/D [2745 0 R /XYZ 125.246 674.765 null] >> endobj 2750 0 obj << -/D [2724 0 R /XYZ 125.529 112.179 null] +/D [2745 0 R /XYZ 71.731 661.813 null] >> endobj 2751 0 obj << -/D [2724 0 R /XYZ 125.529 100.523 null] +/D [2745 0 R /XYZ 71.731 649.694 null] >> endobj -2723 0 obj << -/Font << /F33 1278 0 R /F35 1525 0 R /F27 1180 0 R /F58 2421 0 R >> -/ProcSet [ /PDF /Text ] +2752 0 obj << +/D [2745 0 R /XYZ 71.731 649.694 null] >> endobj -2754 0 obj << -/Length 2156 -/Filter /FlateDecode ->> -stream -xڝێܶ�}��=/�;Z��um��'��$�ES[��ƶ\˓���)Rϥy(��Po�H�t��/��Pd~�BDi�U�M�=��7!S��d��y�ps�RJ�E*�����(2/��ȓ�{��ەä��:J?���7SٶM�H���ǿ��-W�?�x��ì4��(r�Y�ͅaI�5i���Q"��� 2��e �Z�A�f������(4���w�!s��P�If٪��&��G�^����O��߿-G~�������p�9 EB�E" :+���><�%�=�1�O����{0 -D��W���U����\���kB�_�F�W�6��is�h�'P5-K�����������hܤ-3��)[�=� 8��*L�������Q˦����B�S���V�?g����vO z?�S8m�WQ�?ђD�f����[�}&�dž�A����~2M�N�K�����oi�r�}Z����S�Z�h�a�O�B��R���+Aj�ʦ�bև ̾�1�q����?�n�EC`o q�{�N�ۚ`q�?j�k�r0T�2�Sx�sl��7᠔���p�!����`��PV�){;��g��_�Ø��Xm �Q�����!�دJ�3���A�V6 �씂~�*|� �=�i�ā�f�~"^ -�zd�ZJ��d�y�ڨ�tC�Θ��P�H��0�bA�-Q�ɦ�� -T���A!��K"�b7MCM�k8�ϗ����y��|LT�q���T��I��%���A����1��F����G��+Ǧ��x����A�H�90rR-+=`h����1��7�Z�a��F��/;ղ,�/�x���� ����b� 'ն����j�N���=�2���rj4�D��G8 ��V��L��t�i�������b� /<����;ʀ ��La��8���֡g]�:��ѳ�� *�,p�;�Q7��&=N���6�Tu3As>��S���H�,���Զ�������%\�`]ӯ��G�-�^��������[|����VM�$ΌP�}[�^�\\�I��f��Q�l�v&����H�7��P�7q�z�$u'�,���;J��OE�k=�{��vg��6(����S͔Q�r *c�K��|���6��K���� �jT�]���>Uc#�`d\���"X��P]��s�u��PpF��Nz<����ټn5�Ͻl�f�E�8�~ ��4��[�Z��K���j�{/7���ɨ��+z���0�#���LfσRw�B|$9�v{�0C<���lԨN�˚�N�l�H;�/\���C)�,��"q�bc���o�^ ]����'�=� q�� -�Bz��7�o�7Kui.�X~N�2݅���ڿ\������fZ��З�)���L�r���EF@�J��C�#s��n �|��E,��G[��q�q�$�BQFQ|j*�z�*�(�(8�'� -��.0G����b��d���F�K��"w��T��ʽ���'I��J(06�E�!j�I��B ��j�p�66�Օ+�XlX6�����h�tZ�-��+�ΜR-]K;��hf+���r�z���gH�c��kl����gjt��`W��ŀK$o��2��Π%K�\K��Sm�'��e�ӄ��H�"K��<�|9�_22�4��;Sٮ�O��yF�[52��zO ���df�56�/j�-�;�7�9��̋`H��O�f� "�,�v.� �8@;z(>W/�P$���zG�Y��P=�g��6�8���l_�#O�ح�߰ak��%$_L�ft�R�;��1-�ךe�Q���q�y�� -�(s뺒i�?�L�ڑUz���5�բE��R$�@���/�/+��X�K�U�CÀ�� -D ��/5_�olQC*��M5}e��)�+or�m� ���;l��Zߡ w�i�$��+���������J�èq�P�0�9���$�O��2���\T��kxQN�[r�wi���0��N�-��ݘp��\ѽ!��g\ؑ�9���v��>縢E�z�!��@}\��I1�����نoG-��l�8F����ՠ cz�N�S[����x9�]tI\Jc�Tm�������ie8�[���z����� endstream -endobj 2753 0 obj << -/Type /Page -/Contents 2754 0 R -/Resources 2752 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2667 0 R -/Annots [ 2768 0 R ] +/D [2745 0 R /XYZ 101.32 640.195 null] >> endobj -2768 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [288.837 216.479 341.583 225.39] -/Subtype /Link -/A << /S /GoTo /D (install-perlmodules-nonroot) >> +2754 0 obj << +/D [2745 0 R /XYZ 71.731 638.98 null] >> endobj 2755 0 obj << -/D [2753 0 R /XYZ 71.731 729.265 null] +/D [2745 0 R /XYZ 101.32 628.538 null] >> endobj 2756 0 obj << -/D [2753 0 R /XYZ 125.529 708.344 null] +/D [2745 0 R /XYZ 71.731 627.323 null] >> endobj 2757 0 obj << -/D [2753 0 R /XYZ 125.529 696.687 null] +/D [2745 0 R /XYZ 101.32 616.882 null] >> endobj 2758 0 obj << -/D [2753 0 R /XYZ 125.529 685.031 null] ->> endobj -1440 0 obj << -/D [2753 0 R /XYZ 71.731 653.45 null] ->> endobj -306 0 obj << -/D [2753 0 R /XYZ 197.861 614.077 null] +/D [2745 0 R /XYZ 71.731 615.667 null] >> endobj 2759 0 obj << -/D [2753 0 R /XYZ 71.731 606.725 null] ->> endobj -1441 0 obj << -/D [2753 0 R /XYZ 71.731 565.893 null] ->> endobj -310 0 obj << -/D [2753 0 R /XYZ 284.184 533.579 null] +/D [2745 0 R /XYZ 101.32 605.226 null] >> endobj 2760 0 obj << -/D [2753 0 R /XYZ 71.731 524.942 null] +/D [2745 0 R /XYZ 71.731 604.011 null] >> endobj 2761 0 obj << -/D [2753 0 R /XYZ 481.532 514.65 null] +/D [2745 0 R /XYZ 101.32 593.569 null] >> endobj 2762 0 obj << -/D [2753 0 R /XYZ 71.731 481.609 null] +/D [2745 0 R /XYZ 71.731 581.913 null] >> endobj 2763 0 obj << -/D [2753 0 R /XYZ 71.731 444.812 null] +/D [2745 0 R /XYZ 71.731 571.95 null] >> endobj -2764 0 obj << -/D [2753 0 R /XYZ 71.731 429.868 null] +1462 0 obj << +/D [2745 0 R /XYZ 71.731 531.936 null] >> endobj -2765 0 obj << -/D [2753 0 R /XYZ 76.712 378.361 null] +278 0 obj << +/D [2745 0 R /XYZ 381.295 488.838 null] >> endobj -2766 0 obj << -/D [2753 0 R /XYZ 118.555 334.816 null] +1463 0 obj << +/D [2745 0 R /XYZ 71.731 485.275 null] >> endobj -1442 0 obj << -/D [2753 0 R /XYZ 71.731 271.264 null] +282 0 obj << +/D [2745 0 R /XYZ 195.006 449.466 null] >> endobj -314 0 obj << -/D [2753 0 R /XYZ 166.615 238.76 null] +2764 0 obj << +/D [2745 0 R /XYZ 71.731 442.113 null] +>> endobj +1464 0 obj << +/D [2745 0 R /XYZ 71.731 396.3 null] +>> endobj +286 0 obj << +/D [2745 0 R /XYZ 161.035 359.085 null] +>> endobj +2766 0 obj << +/D [2745 0 R /XYZ 71.731 348.942 null] >> endobj 2767 0 obj << -/D [2753 0 R /XYZ 71.731 228.395 null] +/D [2745 0 R /XYZ 71.731 323.852 null] +>> endobj +2768 0 obj << +/D [2745 0 R /XYZ 118.555 285.288 null] >> endobj 2769 0 obj << -/D [2753 0 R /XYZ 71.731 198.546 null] +/D [2745 0 R /XYZ 281.083 276.823 null] >> endobj 2770 0 obj << -/D [2753 0 R /XYZ 71.731 188.583 null] +/D [2745 0 R /XYZ 252.403 241.855 null] >> endobj 2771 0 obj << -/D [2753 0 R /XYZ 105.494 132.857 null] +/D [2745 0 R /XYZ 118.555 234.878 null] >> endobj -2752 0 obj << -/Font << /F33 1278 0 R /F58 2421 0 R /F35 1525 0 R /F23 1173 0 R /F27 1180 0 R /F32 1187 0 R /F44 1994 0 R >> -/ProcSet [ /PDF /Text ] +1465 0 obj << +/D [2745 0 R /XYZ 71.731 201.711 null] +>> endobj +290 0 obj << +/D [2745 0 R /XYZ 282.307 173.064 null] +>> endobj +2772 0 obj << +/D [2745 0 R /XYZ 71.731 170.404 null] +>> endobj +294 0 obj << +/D [2745 0 R /XYZ 268.211 142.678 null] +>> endobj +2773 0 obj << +/D [2745 0 R /XYZ 71.731 135.48 null] >> endobj 2774 0 obj << -/Length 1040 +/D [2745 0 R /XYZ 71.731 112.626 null] +>> endobj +2744 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F32 1215 0 R /F35 1567 0 R /F60 2527 0 R /F64 2737 0 R /F44 2037 0 R /F48 2049 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2777 0 obj << +/Length 1357 /Filter /FlateDecode >> stream -xڝVI��6��W�V ����Z�M��ɡMQ=�9�m3�EW�����;���s��a�3���Eb �K*F*o/e�4�w%�(�_ɼZ-� -�4�)E��$�IS%�ख<Y����8�1˹�)'x�����-ү��7mL�}^}X�Y��JQ��/�u���W��N�њ�����Sx/����x��G�9�lHA9��J�۩n��4�Ѡ���R 1��d�n7�vRx�v*�� �U��#�Q�خ5�6z�������PʍZ�a=��@��h7]���G5��uz�}���(��I��zG�z���рvx�sP���0�9Ԡ�P�I���k�u����i�=�z;����� ��1���.�0�I��������5<��wp;�U��)�9xUFM�{W�gp_.'�������� �)8����v�ɴ�y�� "�")K�S��V�w��3Mz�����Dž.`�D�$�4�9�J6���-Q���4�~��F�;�)�\6��]&K$���5ʈ�uR ��\����r�������հ(L,+I)��� -*y�49b��]WբU�hJ��G��v'a"Y%�2�Mw�z��݄�]���q�F��Ѯ=Ϩ�CΣ�v1�șNA?f��j����N�����z����LȔ /�7Au��K��]��˱�/�Ɨ��Q���<���z���SHO6�7����.��z��t[}]k~nsI���X����$kǵ�{5Y�v�D���'�W�a�/?>*�~�Q�:"�����|��O�0�F(];�O�q�e����٣��XĦ�*"p�wE�?6xvY�|��?ƃ�C��휴�s�N!�u�iO^;�%���"��%C����-D�� �����_ZmT���R4Qa��p�7�}�SP�� ������d�y���%����q.�Y�f�֫>KX�ĖH�����1���Fƥ<��><3t�Ne!���������&����ϯ�`��`�ɂ�������Ԭ��0�<��z�����������rp�endstream +xڵWmo�6��_a� -J�^�C�E�5�Z���"ѱPItI:���w䑲{݀a��<<>'�EtQPR�0$Ir�h��xq;�/�ӈ�Jt�s��X�J�EE�<]����*E���%�U�1���[�e%,��Q����W���]����꧋���)KR��7��:���D��&0�_\�4�l`m�붓ϗ1��Z���aD��7����R����+�|����2�_���p�?;��c[!��2.��KR�R��#�������#gDq�����;�zn��l�Պ[�j�컻sT�柬���}.eԋ��K�k�u���Asn���9�|���b+,#Y�V���PbK�(�Ն�p�SZ(_�4�u���[�7�N��a +5�bڿ��Ɓ����M=���{=���?��3��r#�БB_�itk\�{���S�;]�[�� ���N���� J�|��7TT\�����I#eYBn&�c�]=�!(c�W^�� +�#ԑ��(Ks���JH�(^��B��L�2�!e���HA���]��%n�-o����zS�,���K�!�_��)�;��pE�� �;�p�8N�'N��<��g��YZC'Ѹ ��4�f +r�;��!ωz��#j(���O_DތK>X�$.��8N�*F1[s`�4��E$D�[���<���m.��^D�pGlu79sFܭ�B�k��w(�C�:x�p(�Ι� ��w-�d�읧��5��AlM��(��4L� ��K����$�;�����Rʪ�.LbO*�j�sw{� ��9�ð��_�����j�����1���L�W����~ #%G%�c2 ���V�l�C�<>��9[[<>�'���;5�ӌ�vd�r�cR?���惯0Km�=V�e��Fy���`}d��6�C���ũc�Q����{��64��R&�8��k;7� �g�m<sk��Tir�>)+����^�q�:�0�O"�jB�-�C�<h5w�I(��w�">)��YPw���Ҥ E�fx�ʉ�����^Bӈ��&��S�Ao&B����5��B�����sƉ�r�|z� +0$k��<�Xo��?:��� �G�6�=?Þ�&9DbZ���=�DkF5я[7��Z�do8(E�~!\����F�^��k�yn¹udoU̧R;�-(-m��BΣ��v +o���u�����d��G�������]��#z�lW0C#���>j$余'�?�X[;���jp��:5�������3�1�a��Ù�x�ߘ]P���ˆ�3���oSs�%O���YIJ��o��:����b �[������ҩ����n�endstream endobj -2773 0 obj << +2776 0 obj << /Type /Page -/Contents 2774 0 R -/Resources 2772 0 R +/Contents 2777 0 R +/Resources 2775 0 R /MediaBox [0 0 609.714 789.041] -/Parent 2667 0 R ->> endobj -2775 0 obj << -/D [2773 0 R /XYZ 71.731 729.265 null] ->> endobj -2776 0 obj << -/D [2773 0 R /XYZ 71.731 718.306 null] ->> endobj -2777 0 obj << -/D [2773 0 R /XYZ 131.133 708.344 null] +/Parent 2742 0 R >> endobj 2778 0 obj << -/D [2773 0 R /XYZ 247.791 708.344 null] +/D [2776 0 R /XYZ 71.731 729.265 null] >> endobj 2779 0 obj << -/D [2773 0 R /XYZ 431.073 695.392 null] +/D [2776 0 R /XYZ 71.731 523.537 null] +>> endobj +298 0 obj << +/D [2776 0 R /XYZ 228.441 490.66 null] >> endobj 2780 0 obj << -/D [2773 0 R /XYZ 71.731 680.284 null] +/D [2776 0 R /XYZ 71.731 485.475 null] >> endobj 2781 0 obj << -/D [2773 0 R /XYZ 118.555 641.72 null] +/D [2776 0 R /XYZ 427.619 472.727 null] >> endobj 2782 0 obj << -/D [2773 0 R /XYZ 189.395 633.256 null] +/D [2776 0 R /XYZ 387.295 459.776 null] >> endobj 2783 0 obj << -/D [2773 0 R /XYZ 194.423 621.599 null] +/D [2776 0 R /XYZ 71.731 428.792 null] >> endobj -2772 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F32 1187 0 R /F35 1525 0 R /F23 1173 0 R /F44 1994 0 R >> -/ProcSet [ /PDF /Text ] +302 0 obj << +/D [2776 0 R /XYZ 199.549 396.015 null] +>> endobj +2784 0 obj << +/D [2776 0 R /XYZ 71.731 388.817 null] >> endobj -2786 0 obj << -/Length 2388 -/Filter /FlateDecode ->> -stream -xڭ�n�6��|��'H��,k�N�v�v��(mQ�mq�,��RS��wn����S����I'���U�DE -UFj����xu���J�"�l"�+�oL>�i��t�����맗�U�Rq�����~�%N#�nV����o}L�����:����>��z�����o�ß�}L֭~�����8)"���8 T�L�$Z��%4��u�ı:����O�*�r� -�D9 -l��tm=~պ����gvg�V��,0������=O�t���䟘BW��>p������&x�������hm���lw�i�(̡z�|�y�<�#���@�f HJ�Z{w��3�#��c��c���<3I�xF�Z�vh��&b���F٩qc[�L?v����m�b�/�<���e���G9��ԻSo�`ZS�a1J�T�"���m�jy<�|R�*�m��Q�n�f�����ů��7��QQV&����;�R�EJ)�����S�bj3�⽒��b)'��b%Qaȗ��]ִ��u݃[��]�����&F�N��v� -���/%`��F�%D$�1�������|,0�,:Cq��� {B$}V�59"[[_�Z�W���%xN@�*�IFr�}����3}�A�I>��3���֑��I��`����GJ�g}A+HtZ;���}�U�����1�M�;����I����{vc�P7n4~��PFҔ�=rF�Jʒ���xj�c잿�CR.�=⿎�?3� �yN�i�ڂ>7��L�ݖ�;����o//ooo��rǗ�^�����������A�01)C-�,(�oJp��ӥE����~���q�2�������7�̡?^~G�������8�C>��j8�n<�;��%Y���G����=�$��_�j��/��ƀˋ��]� ��0��%"�����܁aCuJ��5$DTJJ��_�oL7�gڥ6{Ը��"������=-�e;�nÑ�t���h���d�y�1��(Y����UX�k�z��8p�������JL8����)��]G5�s;�f<��aq�t]o�-��L�?��j��I&�B�(��bcF��'& -\���p�Fxuv��e�(����?q���"4��HG�[���[�T�F�sju�[o�2�L,�gn���#*�eɷOM��H����,_{.'��i��H���GSK;��6�����\~�h#���iE��A^?���A�HZ��sq�e���9����BE�v�����n��d�����=��h�a��~��N��ڴ�$����c��;I��6���t��^�$srN�d�#]z��_2��c�B�k��V���t��C�|bs:M��;\�2�÷m#�K��$��C��j�ם�E g�v���� @ �J��p��~|}���g��� -�pJ�hx��������Lr��j�_)��kj�qԥ��5��B���=^kd�3*bX��Y9��6����/Ҿx������ɒ�,CS�A�����P�=@7h|�m!k���C�g�Y�͒-`�s��[��t��C -�L��`�)�p<*���" }���Z�� �"���pfw7���o�*����r��ܤgk=c�� �0����<z������69�b�5��0�]DT˓t-�)Ȯ�����W�5;L�V�x�Ͽ` -?�N�n�w.� -�p@?�֛��0��[j��l]���C%%�y�4�8h���hC��a���~ �K�����@���h&Ќ��"AB��*�$�Mxn!�m����Ѐ<m�uFe��ew\r�r;S;��� ������uk��D�� -�G��љ�n�iCh�"z��Cj�n�b�>e�z���:���!uJ� -�������M�9?��dMy� ����2(%����w�K��d?z�w韅�����d��D��_��tmN߲8��Ҙr~ ��\��Z�������D��m�������0L��Ɗ?�t]������>��N��2��Z�c�!�0���ʷ�V� �r��Ah���JQK� J�a�`��6��y�O�C���K�>�RP���X��,^�Y}:�,ao��1����qk�`����S@<Y��<#����_�ʓ��l�/W/��'RA� -�v,�=2����CR:�����Qo#���{ �P�n��$7u���hy�!�O�mE���Z�`ĄI��1XAo&��E��THEΦ)6�;q�!� ��Ō=���`��/B% S��=���5_�6r���&,����vVt�6�������N��?�xM84�V��6����,�3 u�S7��m�UGY�%����F��K�endstream -endobj 2785 0 obj << -/Type /Page -/Contents 2786 0 R -/Resources 2784 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2818 0 R +/D [2776 0 R /XYZ 71.731 365.963 null] >> endobj -2787 0 obj << -/D [2785 0 R /XYZ 71.731 729.265 null] ->> endobj -1443 0 obj << -/D [2785 0 R /XYZ 71.731 718.306 null] ->> endobj -318 0 obj << -/D [2785 0 R /XYZ 402.325 703.236 null] ->> endobj -1444 0 obj << -/D [2785 0 R /XYZ 71.731 692.184 null] +2786 0 obj << +/D [2776 0 R /XYZ 147.048 356.463 null] >> endobj -322 0 obj << -/D [2785 0 R /XYZ 288.867 651.159 null] +2787 0 obj << +/D [2776 0 R /XYZ 147.048 344.807 null] >> endobj 2788 0 obj << -/D [2785 0 R /XYZ 71.731 638.721 null] +/D [2776 0 R /XYZ 71.731 323.188 null] >> endobj 2789 0 obj << -/D [2785 0 R /XYZ 71.731 601.54 null] +/D [2776 0 R /XYZ 71.731 300.174 null] >> endobj 2790 0 obj << -/D [2785 0 R /XYZ 71.731 601.54 null] +/D [2776 0 R /XYZ 147.048 288.618 null] >> endobj 2791 0 obj << -/D [2785 0 R /XYZ 71.731 586.596 null] +/D [2776 0 R /XYZ 147.048 276.961 null] >> endobj 2792 0 obj << -/D [2785 0 R /XYZ 71.731 575.702 null] +/D [2776 0 R /XYZ 71.731 255.343 null] >> endobj 2793 0 obj << -/D [2785 0 R /XYZ 91.656 557.869 null] +/D [2776 0 R /XYZ 361.161 242.391 null] >> endobj 2794 0 obj << -/D [2785 0 R /XYZ 71.731 532.798 null] +/D [2776 0 R /XYZ 71.731 227.283 null] >> endobj 2795 0 obj << -/D [2785 0 R /XYZ 71.731 521.904 null] +/D [2776 0 R /XYZ 71.731 212.339 null] >> endobj 2796 0 obj << -/D [2785 0 R /XYZ 91.656 504.071 null] ->> endobj -2797 0 obj << -/D [2785 0 R /XYZ 71.731 496.933 null] +/D [2776 0 R /XYZ 76.712 162.889 null] >> endobj -2798 0 obj << -/D [2785 0 R /XYZ 263.545 486.138 null] +2775 0 obj << +/Font << /F33 1306 0 R /F35 1567 0 R /F48 2049 0 R /F27 1208 0 R /F60 2527 0 R /F32 1215 0 R /F23 1201 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 2799 0 obj << -/D [2785 0 R /XYZ 500.364 486.138 null] +/Length 1744 +/Filter /FlateDecode +>> +stream +xڭ]o�F�ݿB�F�N� +��6݆h�a���A�ΖV}��s�a�}䑒�8m���#�x<~��t<��N"E��g#g��<g'��$S,�d1�yq3[�N&�8pn�N(S�%N�"�|�x�^���(=_������Wmo�� �/v��U]��7�g�ތ�FA"�4��\���˜��EI��4{��s +�} �����C�+H2G�,������#+�Yĩ���k<�.ӝ�XH�( �S� +/���������xRQ�� +���kzn�[4 +�a�[:`��^X�(���X�Ajo���0�ܫ�x�邥e��Z:*r�tmOH���3�Ҵ�#��]�RUKT�#���õ�ʔ�����||��yc/�jc���~�����{�:ɋ�j����t�'T!�����t���� +�pK;����� ��m��lk[{Ե���|n%��-�Z�类�Mյ|iM�}��v���jjZ:Y�� x��s�i���M�*+��OR� \��jU���k&�i����( ��IH~gt��D�� ����T��IB�O� ל(IE�E�:��E H�k4��5募 +X����C{�-:�K]�{W���V���t��%�pU�u�����hq<.��l.����q���5JdI��wSr�\��:?� +���G�N���[<�UuA�#�C�G 9"�z-����H��/a�]wu�aNߏUx�5 �LOX�l +B7����o)8����+���^k �*�wm^F��m�1��h��p9��������72����}�3�ޡt'�#�<�4f{�\� ��͗��ϱ�]-{�Z�2��&�b����c��x��;p�g?�=� ��oѪ ƨ�"���|#�D ���{�ױ\���N1fc���,��F��S�#T�������<Qf��N-�T�K�}ٵ�j��,բ��[��J��˲��\w�uꏰh�䇞=���cToN�P>�8�M�!v�J�� +��O�" p\�4a���4�,�%��(�J���=�������x�7NC�"�g�c�k���@9� +D��� ���g����K*rb�ݰ�6������=��B��X��Ʉ�&= +]mM�e��dDQ�k�L^�u FL���PjL9Po���AX��D���=�bo�bWC)�FC�οv�(yD�ށ� s�aaXii�v�;��f��x������#�e���&� 3��u�M��}C�Y>����RTk��kl=Z����(���L�6Ta�һ��2��V�j��"o mp��}��,����l�s°��:i6�����>�!���V�`��3�h�� �X�F-)"�^Fcc��ͬh�f�rn��G�"��`%lLq��Л��v�Q���2ǯU���~���0��_f�`��3h8��Q5�D���z�j_t�a֩�A�r��6�!WAB`�R��fU�ݦW5Yy��Q-Kq���̇�Ud��Lj5��$�ah�"�Z(�a2�z�yO�����k���T ��c?�b^0�?�A{� � +���6��)�S��(&�9�[�}�@&�DG!ji״b����lM�}k��������Ҏ/��y�v`xj��F7���A��М�2�c��������w�_ 3��������{:O�Ћ��\����x��f��<-��Xy�0gV�'�A��|����bԪ�x�a��G�]��t��_m$'?�D~g#��~�9}�_Sձ�endstream +endobj +2798 0 obj << +/Type /Page +/Contents 2799 0 R +/Resources 2797 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2742 0 R >> endobj 2800 0 obj << -/D [2785 0 R /XYZ 101.898 473.187 null] +/D [2798 0 R /XYZ 71.731 729.265 null] >> endobj 2801 0 obj << -/D [2785 0 R /XYZ 71.731 445.291 null] +/D [2798 0 R /XYZ 118.555 684.724 null] +>> endobj +1466 0 obj << +/D [2798 0 R /XYZ 71.731 611.209 null] +>> endobj +306 0 obj << +/D [2798 0 R /XYZ 138.296 578.705 null] >> endobj 2802 0 obj << -/D [2785 0 R /XYZ 71.731 430.183 null] +/D [2798 0 R /XYZ 71.731 571.353 null] >> endobj 2803 0 obj << -/D [2785 0 R /XYZ 91.656 414.407 null] +/D [2798 0 R /XYZ 71.731 533.51 null] >> endobj 2804 0 obj << -/D [2785 0 R /XYZ 71.731 402.288 null] +/D [2798 0 R /XYZ 114.77 524.01 null] >> endobj 2805 0 obj << -/D [2785 0 R /XYZ 71.731 389.336 null] +/D [2798 0 R /XYZ 114.77 512.354 null] >> endobj 2806 0 obj << -/D [2785 0 R /XYZ 91.656 373.56 null] +/D [2798 0 R /XYZ 114.77 500.698 null] >> endobj 2807 0 obj << -/D [2785 0 R /XYZ 250.874 360.609 null] +/D [2798 0 R /XYZ 114.77 489.041 null] >> endobj 2808 0 obj << -/D [2785 0 R /XYZ 71.731 322.587 null] +/D [2798 0 R /XYZ 114.77 477.385 null] >> endobj 2809 0 obj << -/D [2785 0 R /XYZ 71.731 309.635 null] +/D [2798 0 R /XYZ 114.77 465.729 null] >> endobj 2810 0 obj << -/D [2785 0 R /XYZ 91.656 293.859 null] +/D [2798 0 R /XYZ 114.77 454.072 null] >> endobj 2811 0 obj << -/D [2785 0 R /XYZ 133.648 267.956 null] +/D [2798 0 R /XYZ 114.77 442.416 null] >> endobj 2812 0 obj << -/D [2785 0 R /XYZ 71.731 255.837 null] +/D [2798 0 R /XYZ 114.77 430.76 null] >> endobj 2813 0 obj << -/D [2785 0 R /XYZ 71.731 244.943 null] +/D [2798 0 R /XYZ 114.77 419.104 null] >> endobj 2814 0 obj << -/D [2785 0 R /XYZ 91.656 227.109 null] +/D [2798 0 R /XYZ 71.731 397.485 null] >> endobj 2815 0 obj << -/D [2785 0 R /XYZ 71.731 142.263 null] +/D [2798 0 R /XYZ 307.022 384.533 null] +>> endobj +1467 0 obj << +/D [2798 0 R /XYZ 71.731 364.444 null] +>> endobj +310 0 obj << +/D [2798 0 R /XYZ 200.472 327.228 null] >> endobj 2816 0 obj << -/D [2785 0 R /XYZ 110.407 131.468 null] +/D [2798 0 R /XYZ 71.731 319.876 null] +>> endobj +1468 0 obj << +/D [2798 0 R /XYZ 71.731 266.093 null] +>> endobj +314 0 obj << +/D [2798 0 R /XYZ 256.412 233.779 null] >> endobj 2817 0 obj << -/D [2785 0 R /XYZ 71.731 48.817 null] +/D [2798 0 R /XYZ 71.731 225.326 null] >> endobj -2784 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F33 1278 0 R >> -/ProcSet [ /PDF /Text ] +2818 0 obj << +/D [2798 0 R /XYZ 71.731 194.76 null] +>> endobj +2819 0 obj << +/D [2798 0 R /XYZ 71.731 184.797 null] >> endobj -2821 0 obj << -/Length 2396 -/Filter /FlateDecode ->> -stream -xڭٮ���~����������v�&]�Es��h�@K�EDJ����w6Z�v�.� r8g:�D��7E)|�*L�lS�?D����C,;A٭p�~���wi���*O7���>��"�6E��e�l^��ߴj����, -Ґ�����pӟ�����������������,-ªL?ɞǹ�/)��8̳|SDe��������J�FM�Fͳ��!�7` G������/<W�ڪ�n�,x{D�V��Ơ}��\o���#����Z3̜�<�mg�>�~ⅷV�(*�.N�J�a�%k{�j����`�{gPkNpZ���:� ~�����e���i/'��S>�#r_�$��N�iHD�³�m�x0���Z嚷m��=gK��m�281ށ�?m3��Z7d=8�9IR�ɢ����=/��h4��D���nu#�;;���(��T�F��N#P3���Be�N� ԝ��5��6b� -u������ �=�V<x�j��6ςk����k&�1���n�)đ�S+�A9u���o4�AO��������hq-WB�d?�!2�?��E3v2$�j�!��n�m�( ��+��$�;���M�(8:{���c��,�6�C����a0���3���,�r$�����cSpL`��u! ;�0A�1�����<��y6�dhd��~���'�Tv��@��Ѡ�U�z��|��#�I���kC$M��n��>g��$j������nIY�e�> -�I��p�Z��.Ih&I�~!�,�{d�oh�i������R1�4�{� �Wn -k��;�DI2sh�(��cvBݒ� u=���Y�fD�3��e��t>��,�����Bm�6�м -̑�p�/��n�v����Y,�=^ Gll8:��C}�)T�y`�$�[��Ѳ�����Eh8û���f ��"���ca�t��dC��A�|���N�_* q�L�3~Z�5e�d_�%��},���0���]��x�[k:�;`r�ƴ���ȋ�X�M ƚ���G�p���v�b<�P.xI�.N���Z;��8�<@O��i�c����V�:��L��!�S��) -�Y����"��\*������J����%X�>͐�KQ�m�(�f��J���/F�U<��Q�U�9{G懓��CP-{���C��=dR<$�AgG -����H��,�;�,h�\C������bK��*$0�f�;J��/<; �1`��Y���/[�e[�zN3�sT�9dajg5Cy3qz -듹��" -��� t2R >�>�C���~���<`IU��f��q/�~�/���kѸ@���!/�ٮN`1yO�(�<L<! ��/�q#�*��ve��i�PJ�D��8�1P�h]�K��(�d���k=p53pv���b�[�Pes_0t7j�0;�*�@-�a�s B�<3gȚOraZ%a�>S.\�{�= -2��#�@El(3ed�-�j�:�,�՞� L(������U�0���ld�����uz��8��L3z�$��#u<D��i|,����\q�v,�>S,%:P0��Z��G�������cC�O�"p��}髌�ڱ+_b_���_� ���q��`�s���+fm�N��[kG}��|�v���biG��V���?�Φ�E���@>������O���AȢ����-��+aG3�G�(����ٔ�c|�I�q�|.\�{���2#��$A�aJ��+J��=�t9G���I���b�-}W����X�aؤ1@Oo��5Whr��q��U�Z��\3�-:�{�� -;��\�.��D����(��xv��@,by�) -��ڭ)eRg �Ya$� y��N��B�ۡ%�J�L�2LJI�g��>���Cw��$L�J0=_�p��ْe�%�岺*�� �S��鶎�[jP�:��7h�s-�KI]i&_g��D�����U�&UO�|!I�4�|���{����re��M�q˿J\�/}5%Z5���͓����Nc0�z����E��>#~x���s�fe��F�Ŋ�l�0��DM��J�G������[�mؑ����k;��ùԌo�p�%�J�����ߦy��~�u�#��*����2��gF�Q�FP\�<A����8��A䗴Z���eq�P�x���m����(����i�L�"�;i�@��6�|�C��Fަr��������~r�{ز���/d�������/ڢ9g��[$B��]�ԭ@~��J��j�������.��DI4���[U�B-G�9��t�Q+W�"���H��Q��D*�.�+o"+K�����7j�n}ك�tݬ����'&�/�2.>��Ƃr��F�@��x"x�4z�7��I��˩Lendstream -endobj 2820 0 obj << -/Type /Page -/Contents 2821 0 R -/Resources 2819 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2818 0 R +/D [2798 0 R /XYZ 136.289 175.298 null] +>> endobj +2821 0 obj << +/D [2798 0 R /XYZ 136.289 163.642 null] >> endobj 2822 0 obj << -/D [2820 0 R /XYZ 71.731 729.265 null] +/D [2798 0 R /XYZ 71.731 124.09 null] >> endobj 2823 0 obj << -/D [2820 0 R /XYZ 71.731 657.37 null] ->> endobj -2824 0 obj << -/D [2820 0 R /XYZ 71.731 592.777 null] +/D [2798 0 R /XYZ 71.731 106.058 null] >> endobj -2825 0 obj << -/D [2820 0 R /XYZ 71.731 579.726 null] +2797 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F44 2037 0 R /F27 1208 0 R /F35 1567 0 R /F60 2527 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 2826 0 obj << -/D [2820 0 R /XYZ 91.656 561.893 null] +/Length 1603 +/Filter /FlateDecode +>> +stream +xڍko�6�{~�a�Č��2tC�%k�$�oðm1�PI4�H� �o���_i7���_<�?>I8K����h��O�� +N�;�cfPf;8��'gWA0�X���$�)˒I�,���<��yS�u/[w�G��3�^7]/��lV�~=��,�J��Ͽ?���B� aY|Q/�s�X4I���^<���f��KY�Z��Z4_������,�՛�8gq�h��ug��Z6y%��I[w�����O�>��!���Y���/n�9e_��i��E�!�9���r'?5k��$,#Z��jh�c�� �����Z�a�T����V�/�� �����9Cod<�F �Q<~ry�5D�#��j6�;�k$[����+w����1ڙ>�"����P��<?����mdƕ���E� F�0L5��b2�CI��57�n�O.���%�4?��Q�3��l���4�%r���|PO�^��z�y�jh%m�+�]�����N@�dgG�-A��% ����ڍG�S2����+7 �7���#�������ǐ4Pd�����9�7�P�u�<'������XSEhC��P �T��o�9�@)wJ`�>"�)?�-�^Y ��ܧl;���������F��s� X���~��Dt���Z���� �T�#�SX��5����&�cIl�w +�ɣ�%>�u��h ����k��ꟳz�TgU����< [��<�k@�wۋ;���;M�l4�Z4��ll��cL5PA~$��^�6�A����+�9ϏQGgl}hܬc����A#�E6���G��/O-͡�4��[�!����lOa�s�R�'���$��yE�����[Z��lUS��=��-�¦�hrkjgyI� +5����6W���+{d��bO�S)���Ur�HU.L�J�b-6�dY ���)?t�F�$�������������,���W&�v�P��v/����|w!#]=�{�x��^4t��Գ�76�]�]7T��)��T�666q�B�j�t�UfB#Zl�P���[ �|��9�n$<�'Zy�\��={f�Mn�4�xPx�q�3Cp�D��A}}�w�J�K�}(��^Qz�o3/����m�� +���AtFiU�;�yt�<aq�CHu*C���c�C�pz����c�>Kd��5�#.a��.dY����yQ��/x&�!����{_[��z���&��L�`�h����[I��~hTz�p9�v,<xr�h۠h� ���W��f$��j��h���x\��@O'L�gڈl�L%ރm �A�ʣ�v|M�4�IόAk6��Z��z�ŕ!6�k|0��N�0L���/k��ı���d��ȱ���q +�Y)���,���˒�s'��y�8���ߧ��P�O�f�ޙ#q�(�ݡ��K� 3~p�/�뱴���{��a��^v(���{0]� +��Ĩ{��+HLb���2�:jc���7��q'��������23�uM ������0q�� ��mD�hbF���Q����jX_z!�����ؼ�Ô�<��[}�r�T�|h���E���Ͻ��E���5�endstream +endobj +2825 0 obj << +/Type /Page +/Contents 2826 0 R +/Resources 2824 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2742 0 R >> endobj 2827 0 obj << -/D [2820 0 R /XYZ 71.731 533.833 null] +/D [2825 0 R /XYZ 71.731 729.265 null] >> endobj 2828 0 obj << -/D [2820 0 R /XYZ 71.731 518.889 null] +/D [2825 0 R /XYZ 71.731 718.306 null] >> endobj 2829 0 obj << -/D [2820 0 R /XYZ 126.726 486.077 null] +/D [2825 0 R /XYZ 136.289 708.344 null] >> endobj 2830 0 obj << -/D [2820 0 R /XYZ 71.731 423.611 null] +/D [2825 0 R /XYZ 136.289 696.687 null] >> endobj 2831 0 obj << -/D [2820 0 R /XYZ 71.731 408.503 null] +/D [2825 0 R /XYZ 71.731 657.136 null] +>> endobj +1469 0 obj << +/D [2825 0 R /XYZ 71.731 626.152 null] +>> endobj +318 0 obj << +/D [2825 0 R /XYZ 219.101 590.785 null] >> endobj 2832 0 obj << -/D [2820 0 R /XYZ 91.656 392.727 null] +/D [2825 0 R /XYZ 71.731 584.658 null] >> endobj 2833 0 obj << -/D [2820 0 R /XYZ 71.731 372.638 null] +/D [2825 0 R /XYZ 71.731 553.823 null] >> endobj 2834 0 obj << -/D [2820 0 R /XYZ 71.731 320.996 null] +/D [2825 0 R /XYZ 71.731 543.861 null] >> endobj 2835 0 obj << -/D [2820 0 R /XYZ 71.731 305.888 null] +/D [2825 0 R /XYZ 71.731 294.595 null] >> endobj 2836 0 obj << -/D [2820 0 R /XYZ 91.656 290.112 null] +/D [2825 0 R /XYZ 389.403 281.644 null] >> endobj 2837 0 obj << -/D [2820 0 R /XYZ 409.936 277.161 null] +/D [2825 0 R /XYZ 410.125 281.644 null] >> endobj 2838 0 obj << -/D [2820 0 R /XYZ 71.731 252.807 null] +/D [2825 0 R /XYZ 430.846 281.644 null] >> endobj 2839 0 obj << -/D [2820 0 R /XYZ 71.731 239.138 null] +/D [2825 0 R /XYZ 494.944 281.644 null] >> endobj 2840 0 obj << -/D [2820 0 R /XYZ 91.656 223.362 null] +/D [2825 0 R /XYZ 71.731 235.651 null] >> endobj 2841 0 obj << -/D [2820 0 R /XYZ 71.731 198.292 null] +/D [2825 0 R /XYZ 71.731 217.719 null] >> endobj 2842 0 obj << -/D [2820 0 R /XYZ 71.731 187.397 null] +/D [2825 0 R /XYZ 71.731 207.756 null] >> endobj 2843 0 obj << -/D [2820 0 R /XYZ 91.656 169.564 null] +/D [2825 0 R /XYZ 136.289 198.257 null] >> endobj -2819 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F44 1994 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +2844 0 obj << +/D [2825 0 R /XYZ 136.289 186.6 null] +>> endobj +2845 0 obj << +/D [2825 0 R /XYZ 71.731 147.049 null] >> endobj 2846 0 obj << -/Length 2431 +/D [2825 0 R /XYZ 71.731 116.065 null] +>> endobj +2824 0 obj << +/Font << /F33 1306 0 R /F35 1567 0 R /F60 2527 0 R /F27 1208 0 R /F23 1201 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2849 0 obj << +/Length 1904 /Filter /FlateDecode >> stream -xڭɒ۸��P�2�KbH����l���TŞ�{ʩ�s�HP☋�e����m���4'W<<�}:\�.��O5�����x�կ��N��*����g8o�^�����M��XDA��v�j�ob�x����;��`��ZŁ�}�}��eS��/�=�ގ������*�����_��x�:�����9�+�Tz�ϩl|E$��llnN�K���l? -�[<�mq=;z�{�^�+���+鶡������l�N���C��j� ��X^4c�#��a[0��թ��y�i=�R1���[�����^��F�:f��E+����/�?�����`+m�vN�v(���G�+��C�ocVل�w�d���;B,C�fh��`s�6v�bP�6N��������Q��da��2 ��H�>bmX�cgW����X���6gz���xtT��+��k��vwaΗ��YW�HGH���21��!I��萓��3�+Fj%�X&��4�ў`3S�B�t�߇��_�8`ò�� ��>ɼ!lU�X+�<�T�ں�����\R�O��KgrwsIPP�7U���r4,���U���ں�J]��w�N�ze�d�쭐�(�`q4�����Ў����M��ف����@�"7����z�։��I ��-|>��`�s����g��b�͊�F�tg���@����+A{�����À��|���mź\��NR�{ǿ0]���e�H�I��CR����\����Q���P �ݵ�˯����9g��v:Y[`���##E>eǠ��u���^�҉�'{ˁ���Xv.?FR�n{Y�@M�R�e�p���!��+#%�j�w,{T<��5tN��S��:���{����O�#�$qi;6�G���/�ul�2��Ğ�Ǐ��o���2�̭�Z>��@�2����-��ġ�KtZ_�峃Fe�z� �/ʲ��*�7���,���R�e��fU3��c;ؿ0$��} �, �G���,�R�ap���:��5$�K ێqwv����,���0,���[����,�#1(S@�IrDs��E�TA�����R���,�@�"��g��h��h��sM���5M�Tx|�!�,<���`v���\) -CQ�� -��" ���� +f��� ~�v���o�=`�Nj������K&<��J'���fEP뚁k-R9�W}�S�iz�Wff�4�sG�n|<��#�cB�� ���𬳮�f{hÉ�Si��x<���#��Zwo��`^�a�F��{#�CA9�����0��G#� -�x���V���9���Z���%���-������:�N��jSV�9��\W���2���g_�6�(Ea�����2�� -Z؎�}���G83�%E�e1h��0���'��8y?���4@���c.��ן��W����&�E;��`� -�9h9�~�h�a�p���u��n����W�E���T�VlD��JiVE�HP$�(�m�)$%:�Ռ8��w�.n3��݊`G�۱ʝ��5���[�)�ݵ���r���|o���[f�`S�Um� E���:R~�?*�g���C�\���*�RZ+�W���%�j2�]�P��ͬ����9�3����_x F|H+�����I��5@+�6gpn���m2�>�>Q,9����\@���0幺f$׳��R9~u����T��di�����UR��un -��b��@#q\�s�L��V3���NA�/�w��də1������~�C��1��j���&�a lF�^P;���bA��v`5�X����gшwm���������Z�r�c05�`��o$f�{}�Z���9,�M&�݉��g\G��^���N�n���z�/�0Jу�@�11}^��ԘW�AexTV��Q�T���е��ؘ�,�~ ��� �:��y�ټ�y,�E����N-xy�������V{o����xN��I)�/p��!o�p�3�qGn�:@_�s�k�F0A�4�<D�5�OKQ�_S��tu���;UA�]ƽgM��.��,�Q��@���<)�[�p���,���5Xa�(��!|���h_�<"��s�ޜ_G�X���]���u�'�y7�aze�f��ma�j�1����� - ��yAHc�Z����\�G9�Q%���x��L!W����CB�L�T`V�!%�a���������1�23��\g�nS['8�O��j����9Tyr�k-C�V���c�������hX=�%���<?��*1���'��)�?a ����Q�w���Y�/���5�C���3|A��oT����-���9�fv�O8��8����;35= I���οwg���0�� -�Q��'��(G�� ���kN��M�.endstream +xڝk��4����~A�����f? �-�=tW� �&nm��aU~=3�q�nt�����x^�W-B���H�X�B�y�(�g���'�=��b�$����g�_%ɢE�,��EmD�^��Xl�x��~ ^eoհ\�YĂֻ�X�4uw����i����Ͼ�NB�d-�M�zy�kŲ�F�k�+Jro��:܈$M�be/��P��Wy�E�#i�XE�ȳ�#�I��*Qˮj��-i�\Ei��U�>�`��"�6�X,�0ql�hc��< ��4�GE@��QP� oY�����F?�RC��Ǧ���f\��=6�e���^�e� +������ ��p�#���D��\�!Sґ�-k�w�j �j{$�v�����(�J�'��bQd�3�ǣB#��E&q�kƃs`�����SD ����e�cb� k��%bz#D�����s��#�~�H��V�#�t�7�ם ���߬ a*�L��2�v����lI�'-���s�PJ�ޑ����KZJ��u�vj4�-D�<(��UL?hyO�N�9�@,L!������o})�,zڶ��65�Ǡ*�(H��7���q���ǐ�3�_�,����{�ҽ} +*�8L��ӄ��ҳ�)� �Fi����Ǩ�{Cb#"��tF��MG.�I��\�PZ��D�wy�0�$=k�1�����չױ���!l/�Q�.��X>�AI�;�s�*%��a�]ᗟ��7����������$�ᔘ��u�Pј�2cO}K%nVM}��s��ѧӜ^TSTJ/��ֿ�'�ҟ�f�HJ���/�֝�Z�; -�fC����*�d�k��6>Kĺ@�����t�/,��+��}翳�>;X�MҨ��O�o��|{{�^�E��,�Z����>Y���]c��Sb� ^o�� ��Ά��s�3{lP Eg��]�@�kj�E�p���\�Te�X��Nў-pI[�wh��qeQcG��. +J}82�*k�{P;p��DV�z�\ ��J�]ͤR��ecbv���79A�l���vG� +W�`�B���@,�kx>ZSW�X�7V���a�s�����ty�����&�d�*yZAU5P��u��ZX��X���8ډ5��F����W�iD����A�ʗ_�j�T�2�U��SlG 7�LR��gAqX����,�Q�q`�L����V0� +w����qUþ.y����?�l&�@�t�6 Fs1��p�y��Zz��G:?`61O�;�6�^��+�� ��1 �0Nyp��N�2{�}}�g� a!6!��苣�=O+��k��8��8O䳩�f�����<21h���6A�1�C�3 �N56_��$_iA�d���Ҷ�=���v�)�� �� +��ԜK�6�p�lU�l��~��|�w��?�?i���9C����q�< �E?��i���Qf�#��?tn�����u�ϣ?|�%ԥ_�hI�mB���� +p&w1�GO�`w.H�'^AT��>\���A�V��{~�PU���|毕��H�5����v��T�#}�`U�J#j�Ͳ�@Ez~���wx�X`�u�9Np�<k\\�Ivಂxvv� �������4Ҏ��!�O�����,;�OT_e��#�Ć��Jw����G/�Z���Ll�l��b�T1�8�1��!��/W@l�2�J��}���e,5��/�?�})��-���ai�/Y�ؓ���^ +ߎm�A�\C�z��RVդ^;���v�糉y��{�P L���!��+IB������� �Q+b_��G7(_�_�˦$|�3���U���'>����0?<��u�Ԡ.�˩�-��S��ge|pU�ǿ��U�Fl�����u&��A+�a��=7l��G�kI?��endstream endobj -2845 0 obj << +2848 0 obj << /Type /Page -/Contents 2846 0 R -/Resources 2844 0 R +/Contents 2849 0 R +/Resources 2847 0 R /MediaBox [0 0 609.714 789.041] -/Parent 2818 0 R ->> endobj -2847 0 obj << -/D [2845 0 R /XYZ 71.731 729.265 null] ->> endobj -2848 0 obj << -/D [2845 0 R /XYZ 71.731 741.22 null] ->> endobj -2849 0 obj << -/D [2845 0 R /XYZ 71.731 718.306 null] +/Parent 2742 0 R >> endobj 2850 0 obj << -/D [2845 0 R /XYZ 71.731 706.187 null] +/D [2848 0 R /XYZ 71.731 729.265 null] >> endobj 2851 0 obj << -/D [2845 0 R /XYZ 91.656 690.411 null] +/D [2848 0 R /XYZ 71.731 718.306 null] >> endobj 2852 0 obj << -/D [2845 0 R /XYZ 71.731 652.762 null] +/D [2848 0 R /XYZ 136.289 708.344 null] >> endobj 2853 0 obj << -/D [2845 0 R /XYZ 71.731 641.494 null] +/D [2848 0 R /XYZ 136.289 696.687 null] >> endobj 2854 0 obj << -/D [2845 0 R /XYZ 91.656 623.661 null] +/D [2848 0 R /XYZ 71.731 657.136 null] >> endobj 2855 0 obj << -/D [2845 0 R /XYZ 71.731 577.669 null] +/D [2848 0 R /XYZ 71.731 585.24 null] >> endobj 2856 0 obj << -/D [2845 0 R /XYZ 71.731 551.766 null] +/D [2848 0 R /XYZ 71.731 575.278 null] >> endobj 2857 0 obj << -/D [2845 0 R /XYZ 71.731 536.822 null] +/D [2848 0 R /XYZ 136.289 565.778 null] >> endobj 2858 0 obj << -/D [2845 0 R /XYZ 71.731 453.201 null] +/D [2848 0 R /XYZ 136.289 554.122 null] >> endobj 2859 0 obj << -/D [2845 0 R /XYZ 71.731 438.092 null] +/D [2848 0 R /XYZ 71.731 514.57 null] >> endobj 2860 0 obj << -/D [2845 0 R /XYZ 91.656 422.316 null] +/D [2848 0 R /XYZ 71.731 489.499 null] >> endobj 2861 0 obj << -/D [2845 0 R /XYZ 233.106 396.413 null] +/D [2848 0 R /XYZ 125.529 480 null] >> endobj 2862 0 obj << -/D [2845 0 R /XYZ 71.731 373.4 null] +/D [2848 0 R /XYZ 125.529 468.344 null] >> endobj 2863 0 obj << -/D [2845 0 R /XYZ 71.731 358.391 null] +/D [2848 0 R /XYZ 125.529 456.687 null] >> endobj 2864 0 obj << -/D [2845 0 R /XYZ 91.656 342.615 null] +/D [2848 0 R /XYZ 125.529 445.031 null] >> endobj 2865 0 obj << -/D [2845 0 R /XYZ 71.731 304.593 null] +/D [2848 0 R /XYZ 125.529 433.375 null] >> endobj 2866 0 obj << -/D [2845 0 R /XYZ 71.731 293.699 null] +/D [2848 0 R /XYZ 125.529 421.719 null] >> endobj -2867 0 obj << -/D [2845 0 R /XYZ 91.656 275.866 null] +1470 0 obj << +/D [2848 0 R /XYZ 71.731 390.137 null] >> endobj -1445 0 obj << -/D [2845 0 R /XYZ 71.731 229.873 null] +322 0 obj << +/D [2848 0 R /XYZ 197.861 350.765 null] >> endobj -326 0 obj << -/D [2845 0 R /XYZ 269.758 186.776 null] +2867 0 obj << +/D [2848 0 R /XYZ 71.731 343.412 null] >> endobj -1446 0 obj << -/D [2845 0 R /XYZ 71.731 186.56 null] +1471 0 obj << +/D [2848 0 R /XYZ 71.731 302.58 null] >> endobj -330 0 obj << -/D [2845 0 R /XYZ 283.793 147.403 null] +326 0 obj << +/D [2848 0 R /XYZ 284.184 270.267 null] >> endobj 2868 0 obj << -/D [2845 0 R /XYZ 71.731 137.038 null] +/D [2848 0 R /XYZ 71.731 261.629 null] >> endobj 2869 0 obj << -/D [2845 0 R /XYZ 71.731 99.219 null] +/D [2848 0 R /XYZ 481.532 251.338 null] >> endobj -2844 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F44 1994 0 R >> -/ProcSet [ /PDF /Text ] +2870 0 obj << +/D [2848 0 R /XYZ 71.731 218.297 null] +>> endobj +2871 0 obj << +/D [2848 0 R /XYZ 71.731 181.499 null] >> endobj 2872 0 obj << -/Length 2467 +/D [2848 0 R /XYZ 71.731 166.556 null] +>> endobj +2873 0 obj << +/D [2848 0 R /XYZ 76.712 115.049 null] +>> endobj +2847 0 obj << +/Font << /F33 1306 0 R /F35 1567 0 R /F60 2527 0 R /F27 1208 0 R /F23 1201 0 R /F32 1215 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2876 0 obj << +/Length 1804 /Filter /FlateDecode >> stream -xڅَ��}����@���ط�I&���}�,�l�m#QZ�u�>uQ�e��Zd�XU����q���$�J�����h��?��#����';A�-p>�~��sl2������ ]W%n�I_���y-��|:�����Ώ\'P�})�Ҕ=�Ksd��q�9���U�o����{�xGA��4x(�Ź��6)��|���(�$n��0$�^��g���g�L�^��i#�/��.p#��]�yr.�����yQ� v����춞��C�c�G�������9�Wہ�I�K�1B�D�xrD�]3���B�i��1yU]�õ�uQ�{F:��C lvrꝇjJ��mβ�V�t��@���s�%|��|Г\�-��n��0/x(���5��߅Dk�����6�4E����F�<��e��*h��X�O��Yc:�pj�P~�:�3��w7rϧr�i)`⊃}nw���<.�a�#j�������)�|�� ����f'�)�(���?s��<G��� -�;~7Bu�3aOeQ���xA��dA��_5M��O�����H�Op�iy\1K��GUB���2~�9��-��n����q���I��+1H~��?jR��s�5���#���}���O�{�r3<fp����vz�3���Y�o�BW��.B�-�����|0�BtFLuL*B� ��(rԄiR*�&�S�>����'=D�0<�pB�Ղ�Ή�\���{JU ��f(���j���dx`C�G ٞ ���Q�x����ټ��`�W7�%-R�A�¦d7F��\�˓�D=����_�i�@��d�Z�n�V5ǒ���yc�TZ�Lh����RhA�t��u�Gw��+��%�U�<�7X�"J)�<��;m�������s�5J�[�0����i`��8vm`s�20�.�����V|���@��M��.v���ˁ��4`��;N�����(�itґs���q8Vy����%��6��N,圂��G��(���m�� ��T�z}��liR�c)̵&�HM���!Ũ)z�uR*ۖ{�dϼ�9E���_~݆����;�>���e�A`[��+{��=K�W���|?�t2 �)��-�ίW;��~�.;���N�0����D��;yo�q,�C�S� ��� $ 3�r����q0�(�m�E�7������qo��%�q�sH�@zlO?^��U]���I�*����^0��PMX��/T_��I��~�)��&E�e/�F�cOCv��bi��]� w�,�"xU�g��a���hK��S�_Y]������kZ� �����$tUf��Ķ<�����C�v�ۃ��U�*H�+�s�Sv�>������^fvG�{�E+�#DԎC.{�+�v� �hQ8r̼�G����M��6�>����2�(D��n��!���~ �CS�<�����������x��c����yx!����փ����6G��0F�!���mp���z���p�L�t���p�4��� -�a��U�JF�O� ���\�V�*&�H� -xx7����uZ�.@�q(��\���c�W'��ށ�h~�2f�g�-�;����]u3�̖����ҫ&�� ��F>�;�]WY$��1��#�O(ax��H.�^_ڽ�n?P�j�]�-�n�ė�E4� �\_�M����>D>��G�-�C�kB�\�f���*��$*�ҫd����tek����\_ɑ�{�~���Q��6�3t�<�wӢ�l�7g�Y{�{ٜ�Iâ��G���R�d�|�0�V-�������zI��]K���_�e����݊���K^i��8��k��x˖��Wd���az�97Y�yQ�W7�'����~#(�p�2y�L��ԉ��vjlA����=��U�a���C�=��L�{*����t3λ�T����ny��=�"��?�U%�oՎwj( �"hϑw�WN��u�wos&�#����`\]�qd��6����y�"O_Ƿ�����������NJ��/�w:�Hő���废��A<][[YatF�s|ٺ0��cs�,���$���i�;Ϭ�r={e���0]��#�4���)ĩ'1�ci��C�㚄|�pr�������ڷF��!� s"��Fإ�WO�@�0�h��L��d?5�AM�X�S��/[=�ћ"�:vn$j�0�O�0pc�9� -�S�Ԍ$R½�J"����k�� ���]>��S�����X�Z�p�w�����8���K�ָ���)�Wp~���A�B�$,*����'Ō�@��rWJ�=ɀ�dzF>3�+/uj�H|@Í�Xݾ ����{?����s -��4�wm����>/�v�ǧ�?Ʋ�^��e��������ˊ�D�/ =@N �&���}����Io�a����0U��<��hF���(�S���uI�{?��r���ߺendstream +xڭ˒�6�_�����ER��Ҧm�䐤���t�d�����%�nܯ/@P~n�i�������$h��ǃ��\�G�LdiPw7q���_n��<Kt����f�Lʠde&��e����y�K��Twͻ��u���E"�C�����cն�_�t��K�m5�p���绽�T�,��s%"aI\�L9��q��C4���?��� r'p.��ge)���͛����� � +&yM��|""�%K�$%�s�w��O�L2���9�id%8 +��z;K�2=:�0�$x3s"^�g,�X&��a%2_�w��<��p��RS�n�-!�!�a\+C$��|�Ե��z��8f" �mz\ۑ��q,Pkh=���vt�E|7 v�UG+U��^���8 �`�B�1��,�����f��*�� &qeA��Y���t��[�4j�N萅��{���C[�z���%�� �;��)ױkie9�A�媟��v���U�Z��D^�h��a��5�^=!��}�?�ē2J$$Rp��_��3&������Ԏ�$�C��9iQ�,�� +����mv�F1�"u{�CHD��;�2 �UC�q ���D���x��m��<�%bEh��ad�a$��E9��i|62RpnJ-梕M<�9�ȴsAh�US��v�Pr�^&���I���x��?���^N�C� �&�<�7�ih�ѐ�<��ص��D�I��P��Jb�E��t����Qs�����K��6z3:و�q�_4#������!�P�JGk�D�O �|J|K9'�C�Ɯ��t��8�,��h�=��P��,}�S�b�wm ���z|�e��)�_ �~��p���z��|9s<��$>y��|S�� ���3C]�MG���Pm��+�쮯-���,.�/�l(�Lc���iR�vŎ����yu ����<��U�!vڡ�Z�(n�0S�!��5�$�n��!#��3Ω�"VW�i�E�h�^{�7�km=mT����� ڥ/SKQ����hk�9����QP1�O�N�e������<��i��b.��>�0BIR�v�0����& +�8�8-a���l^�U}e��0Ȑ��d)KO�rk��Q��]>�,.��c��06,����� ��8l��둾�k��j;�:��*)�Us�����̾��0wY�N��o�-���w#Ms����pQ����5M#��a�hU�\Iw@�"�tA����K3tg{~|=+E��Kb�k�[�[BGf�U�jT������{�^\��IH.��j M30��#�P��V3�A5����4 ������<��S������%Rf�L���,%�W࿙ީ��Q��hl�H�zV��a(fE�H�K� y�9�"H��j=��p��z�`�CZ�p�E +���8�2N�~��]-�x# q�f�9]��4W[�=9��'�Pv[�e�� �)$��]�ܶ�s.̀#�{�����$��] +�Ux�`����ڻp���,O�V��Y���>�h�_覡J�`��A���-D����������j�O'� a�鉁�B`���xÅ���'� ���E�ln8sA,�� �2��qD`|��o�#��O�!�ڏ�{�Q�f��x�Φ)ڪzK�3=��Q{ψ�Wrݔ(��4���~�GPhj�\O��$�h������N�n>�\��n1�NBhy���g8��P0�*�N#���3À�7�p2z�yE��3��w�K��L��K�{}a#��^z�^(�I��&c\W[�j��GZJԲ<�{ ����� f��7���endstream endobj -2871 0 obj << +2875 0 obj << /Type /Page -/Contents 2872 0 R -/Resources 2870 0 R +/Contents 2876 0 R +/Resources 2874 0 R /MediaBox [0 0 609.714 789.041] -/Parent 2818 0 R -/Annots [ 2885 0 R ] +/Parent 2892 0 R +/Annots [ 2880 0 R ] >> endobj -2885 0 obj << +2880 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [177.424 321.011 222.255 329.923] +/Rect [288.837 566.386 341.583 575.298] /Subtype /Link -/A << /S /GoTo /D (parameters) >> ->> endobj -2873 0 obj << -/D [2871 0 R /XYZ 71.731 729.265 null] ->> endobj -1447 0 obj << -/D [2871 0 R /XYZ 71.731 657.136 null] ->> endobj -334 0 obj << -/D [2871 0 R /XYZ 264.312 617.763 null] ->> endobj -1448 0 obj << -/D [2871 0 R /XYZ 71.731 614.571 null] ->> endobj -338 0 obj << -/D [2871 0 R /XYZ 274.763 583.293 null] ->> endobj -2874 0 obj << -/D [2871 0 R /XYZ 71.731 574.655 null] ->> endobj -2875 0 obj << -/D [2871 0 R /XYZ 119.865 564.364 null] ->> endobj -2876 0 obj << -/D [2871 0 R /XYZ 455.128 564.364 null] +/A << /S /GoTo /D (install-perlmodules-nonroot) >> >> endobj 2877 0 obj << -/D [2871 0 R /XYZ 71.731 546.331 null] +/D [2875 0 R /XYZ 71.731 729.265 null] >> endobj 2878 0 obj << -/D [2871 0 R /XYZ 79.19 494.625 null] ->> endobj -2879 0 obj << -/D [2871 0 R /XYZ 71.731 474.536 null] +/D [2875 0 R /XYZ 118.555 684.724 null] >> endobj -1449 0 obj << -/D [2871 0 R /XYZ 71.731 443.651 null] ->> endobj -342 0 obj << -/D [2871 0 R /XYZ 224.863 410.341 null] +1472 0 obj << +/D [2875 0 R /XYZ 71.731 621.171 null] >> endobj -2880 0 obj << -/D [2871 0 R /XYZ 71.731 407.681 null] +330 0 obj << +/D [2875 0 R /XYZ 166.615 588.668 null] >> endobj -346 0 obj << -/D [2871 0 R /XYZ 185.702 379.955 null] +2879 0 obj << +/D [2875 0 R /XYZ 71.731 578.303 null] >> endobj 2881 0 obj << -/D [2871 0 R /XYZ 71.731 372.757 null] +/D [2875 0 R /XYZ 71.731 548.454 null] >> endobj 2882 0 obj << -/D [2871 0 R /XYZ 359.607 362.022 null] +/D [2875 0 R /XYZ 71.731 538.491 null] >> endobj 2883 0 obj << -/D [2871 0 R /XYZ 388.183 336.12 null] +/D [2875 0 R /XYZ 105.494 482.765 null] >> endobj 2884 0 obj << -/D [2871 0 R /XYZ 71.731 323.168 null] +/D [2875 0 R /XYZ 71.731 462.675 null] >> endobj -2886 0 obj << -/D [2871 0 R /XYZ 71.731 316.03 null] +2885 0 obj << +/D [2875 0 R /XYZ 131.133 451.881 null] >> endobj -350 0 obj << -/D [2871 0 R /XYZ 280.196 285.31 null] +2886 0 obj << +/D [2875 0 R /XYZ 247.791 451.881 null] >> endobj 2887 0 obj << -/D [2871 0 R /XYZ 71.731 278.232 null] +/D [2875 0 R /XYZ 431.073 438.929 null] >> endobj 2888 0 obj << -/D [2871 0 R /XYZ 117.11 267.377 null] +/D [2875 0 R /XYZ 71.731 423.821 null] >> endobj 2889 0 obj << -/D [2871 0 R /XYZ 71.731 265.22 null] +/D [2875 0 R /XYZ 118.555 385.257 null] >> endobj 2890 0 obj << -/D [2871 0 R /XYZ 71.731 260.239 null] +/D [2875 0 R /XYZ 189.395 376.793 null] >> endobj 2891 0 obj << -/D [2871 0 R /XYZ 89.664 239.482 null] ->> endobj -2892 0 obj << -/D [2871 0 R /XYZ 71.731 237.325 null] ->> endobj -2893 0 obj << -/D [2871 0 R /XYZ 89.664 221.549 null] +/D [2875 0 R /XYZ 194.423 365.136 null] >> endobj -2894 0 obj << -/D [2871 0 R /XYZ 71.731 219.392 null] ->> endobj -2895 0 obj << -/D [2871 0 R /XYZ 71.731 204.448 null] ->> endobj -2896 0 obj << -/D [2871 0 R /XYZ 244.012 194.949 null] ->> endobj -2897 0 obj << -/D [2871 0 R /XYZ 441.891 171.636 null] ->> endobj -2870 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F44 1994 0 R /F27 1180 0 R /F48 2006 0 R >> +2874 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F44 2037 0 R /F27 1208 0 R /F35 1567 0 R /F32 1215 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2900 0 obj << -/Length 3310 +2895 0 obj << +/Length 2388 /Filter /FlateDecode >> stream -xڝk����� -w��v�ע@�^��5m�P�|�Z���-9�|{�_�y��,�.�Þ��C�{�������A��$^�w�b#���QP�����k.r�'��i��<O�^�H�@eq�x*^~�+��nW�A�-C�ϯ�CUW��zˠ�O+��o���_���{�di�a��,��=�3�_.|_�q�4��2F�/T������Ǧ�6��)�|����x��`�t8��x�3�9���z���͉_v�*�p�m�S]Z,a� ID������uQ3d�+���R�}� -��e�����ޜ�O�$�����pf^������C�b���Yb�ρ8O�w5+�U�G#�?4+�[n+`S�E�w�AO�{*�o�f�a̧]��[��g���Z��~��`�2�Q6_�b�? lN�=��CQ�X�e�;P�N1�[���Y�F�8��0 c=�[K��;�0=$��i�P�������~�:�ӱ�E��5�X�D��P�2��S�3�Y$���� ��3�����x�ˬ~W�v>�2�5'2���Us������fD��;;tz�L�/��������9@{e+��$�}%v(r�W�c��� ��J�� 8�LH0n�Д�m:#>gB��B?o=Q�r�b�1��)|�v1��.k�.PRr����l��Q7�Y�S�ک���|�'1����z ���$�8�U -qMv�����!vSv��gd�R�i�����iWa�,��3y��� ��g��$דJ�A�1>|gO�#�G��>�iK��t��%Rvg���9}�� - ��F?C�_kq�D�5���|���qݮ9�����]ҺkMٜ�S��A+u-����,��N��?[������I����}Z��r�}�%��]&3 ���7�T��w�����qK{��nk��9�u�[����<����Q�2,w�f����A^�ף,&�dL� �! �}x{n>?����T�,6�AZ�ݱX���P���W�5����u���9�D���'Y���m<���GN�0%�1>�ZQ������ȿӶ�OU�/�3�G�yB�k7��kr�0�d��}��~c���<ӬY `$�T��B������ٍ0�hK;]��5�2b��{}8�Y�Nд�!)����㺯��{0�)>��}��㾨�v_v+KϦ�bЮ#�\�G�Q*�05�yܿq�<mYA�q%��0�܊�K�nM�W�IT �RH\�jP1�4+V�q%�G;�p��д�"3�Ǥ)���h٦�ҳ܊eJ <�C֍<�ff0FR�1���C�`�~5�A�6U���x�%#]�T��A��� -��_�T�� ��$ ` �� [)�(�˘ ��g�$s��-�P66��j:~�`�3�:.��zN ����W�ٙcvm, ��΅���$AOd��&�+����nH��N7W~� ���pX�1<�{Ph�JS�7� ��@4�����[�XBN ;~}�5d��=���(�":Ĉi�a���,��=i4º���e��#�}dh/�Q�x�b�� ��]���(��2�,)��(��v�K���}�1s�=-d5���Ѣ�Z��l`���ʋ�|�h'|�c�&�`<���1�l�i?R��S+�U�����L�l�����O�?U�P:*H������_�E �����+���!r���"#\�z�����?�J`_P�Qrm �+x�%�n e���v�"FĪ��Ug�������X,m��<�-x�@A ���g4M�E�r��^����k�a�FF��0m�a)�-�s�N�D���yCx�_>�P'g^+z*����h�ɕ��`�HM��������Lj�R�Ӷ]E1��#��?���L���T�~�O%�U�� ��l-yJ��m�e,��j�|O�X���QuF�DV�`�~G�f�wz��1va��:�ǣ.Z٘&�%3HaZ������(o�!jl<3>��$�5��� ��r����0_y���do̊KUPN-���6�\R5���jSb�U����9�!^A���r�i�%RY��Ybz�A�v/�yL��6�:�O���Ub���(8*$��)x�? ��=!0�'lv��Η�x�z>f���(��6� ��Y�ܮJ�{C[\tţ8o3cԾ����qu���L0��Cv�&*ݰ�wܼp0�ȧ�]� �TdW�������������g�إ��5�"�`�3w&1�����h�1GL6��b߅b���J��ߗ[��J !�� ^]����3�ȋ�J ���o��K��[��-�3�s�r��ꭅL���1�� #���z����)gN����+dD���� 7�8M 1�E=|�Ë8,@�]T)�Q��,�w�z7�4]�0C:�ն�0�X�V�/Hb��\'�Vz;�=�I3��_� ��D%���$lZ�fj7����As1䨺��E� c���[��%��[ -;%v[aψ�)�CU8q�Zy1Q�$�$�mtG��䋰���b�P�Ld�`���q��7A�П��c۔�5�lp���a{��`�hj�8�]1��G#GE�'g���.BL��j-�tn|{cu���v���f]qR~H�)ZN�Rg�'3�O9.����x^��nJ4A˻@�B�����\�t�]9��$5̧A�� ��e�u�z��4n�jEg���s�TcҐ����mԑ��g,�ϡ�J�����;C�Ş��X�:Z,{<jf�;��� s/��X���S1��@���Sq��*����N��C��+�$Uu6p!>X=�@��u�V�ʹ2�aȐz$&�H�-'u-zf��#/Y~�&��U5p_��5��-��(V" -7�+�.t���l��\T���6ϰ�6����vZ$ -�Q��6bDy�36����b�v���E��hqQ���M�咽1�-s�P�mmc�s�6�F[#I����9���{��&�7�}��aΙ�M�C���g)���GH�p`�X�6.�Z��v���ɇO[�<�����(�T`��*��ݩ��$��Dj���f}����1|�Ġ�쀇�����;�J�OF����#��p�����v�hJ��z½Y���p�,g������~��Q]�����-ݟ���g��ߡ��㱠����r��FE�5�כt�D©5����*�8(��0?�~Zܑ��Ϲ��2���Ĕ�h�N����8i� �273t4/h���ʄ�q�)/0��%�K�˜R�'visendstream +xڭ�n�6��|��'H��,k�N�v�v��(mQ�mq�,��RS��wn����S����I'���U�DE +UFj����xu���J�"�l"�+�oL>�i��t�����맗�U�Rq�����~�%N#�nV����o}L�����:����>��z�����o�ß�}L֭~�����8)"���8 T�L�$Z��%4��u�ı:����O�*�r� +�D9 +l��tm=~պ����gvg�V��,0������=O�t���䟘BW��>p������&x�������hm���lw�i�(̡z�|�y�<�#���@�f HJ�Z{w��3�#��c��c���<3I�xF�Z�vh��&b���F٩qc[�L?v����m�b�/�<���e���G9��ԻSo�`ZS�a1J�T�"���m�jy<�|R�*�m��Q�n�f�����ů��7��QQV&����;�R�EJ)�����S�bj3�⽒��b)'��b%Qaȗ��]ִ��u݃[��]�����&F�N��v� +���/%`��F�%D$�1�������|,0�,:Cq��� {B$}V�59"[[_�Z�W���%xN@�*�IFr�}����3}�A�I>��3���֑��I��`����GJ�g}A+HtZ;���}�U�����1�M�;����I����{vc�P7n4~��PFҔ�=rF�Jʒ���xj�c잿�CR.�=⿎�?3� �yN�i�ڂ>7��L�ݖ�;����o//ooo��rǗ�^�����������A�01)C-�,(�oJp��ӥE����~���q�2�������7�̡?^~G�������8�C>��j8�n<�;��%Y���G����=�$��_�j��/��ƀˋ��]� ��0��%"�����܁aCuJ��5$DTJJ��_�oL7�gڥ6{Ը��"������=-�e;�nÑ�t���h���d�y�1��(Y����UX�k�z��8p�������JL8����)��]G5�s;�f<��aq�t]o�-��L�?��j��I&�B�(��bcF��'& +\���p�Fxuv��e�(����?q���"4��HG�[���[�T�F�sju�[o�2�L,�gn���#*�eɷOM��H����,_{.'��i��H���GSK;��6�����\~�h#���iE��A^?���A�HZ��sq�e���9����BE�v�����n��d�����=��h�a��~��N��ڴ�$����c��;I��6���t��^�$srN�d�#]z��_2��c�B�k��V���t��C�|bs:M��;\�2�÷m#�K��$��C��j�ם�E g�v���� @ �J��p��~|}���g��� +�pJ�hx��������Lr��j�_)��kj�qԥ��5��B���=^kd�3*bX��Y9��6����/Ҿx������ɒ�,CS�A�����P�=@7h|�m!k���C�g�Y�͒-`�s��[��t��C -�L��`�)�p<*���" }���Z�� �"���pfw7���o�*����r��ܤgk=c�� �0����<z������69�b�5��0�]DT˓t-�)Ȯ�����W�5;L�V�x�Ͽ` +?�N�n�w.� +�p@?�֛��0��[j��l]���C%%�y�4�8h���hC��a���~ �K�����@���h&Ќ��"AB��*�$�Mxn!�m����Ѐ<m�uFe��ew\r�r;S;��� ������uk��D�� +�G��љ�n�iCh�"z��Cj�n�b�>e�z���:���!uJ� +�������M�9?��dMy� ����2(%����w�K��d?z�w韅�����d��D��_��tmN߲8��Ҙr~ ��\��Z�������D��m�������0L��Ɗ?�t]������>��N��2��Z�c�!�0���ʷ�V� �r��Ah���JQK� J�a�`��6��y�O�C���K�>�RP���X��,^�Y}:�,ao��1����qk�`����S@<Y��<#����_�ʓ��l�/W/��'RA� +�v,�=2����CR:�����Qo#���{ �P�n��$7u���hy�!�O�mE���Z�`ĄI��1XAo&��E��THEΦ)6�;q�!� ��Ō=���`��/B% S��=���5_�6r���&,����vVt�6�������N��?�xM84�V��6����,�3 u�S7��m�UGY���F����n�w�?��|endstream endobj -2899 0 obj << +2894 0 obj << /Type /Page -/Contents 2900 0 R -/Resources 2898 0 R +/Contents 2895 0 R +/Resources 2893 0 R /MediaBox [0 0 609.714 789.041] -/Parent 2818 0 R +/Parent 2892 0 R >> endobj -2901 0 obj << -/D [2899 0 R /XYZ 71.731 729.265 null] +2896 0 obj << +/D [2894 0 R /XYZ 71.731 729.265 null] >> endobj -1451 0 obj << -/D [2899 0 R /XYZ 71.731 741.22 null] +1473 0 obj << +/D [2894 0 R /XYZ 71.731 718.306 null] >> endobj -1450 0 obj << -/D [2899 0 R /XYZ 71.731 718.306 null] +334 0 obj << +/D [2894 0 R /XYZ 402.325 703.236 null] >> endobj -354 0 obj << -/D [2899 0 R /XYZ 207.755 708.344 null] +1474 0 obj << +/D [2894 0 R /XYZ 71.731 692.184 null] +>> endobj +338 0 obj << +/D [2894 0 R /XYZ 288.867 651.159 null] +>> endobj +2897 0 obj << +/D [2894 0 R /XYZ 71.731 638.721 null] +>> endobj +2898 0 obj << +/D [2894 0 R /XYZ 71.731 601.54 null] +>> endobj +2899 0 obj << +/D [2894 0 R /XYZ 71.731 601.54 null] +>> endobj +2900 0 obj << +/D [2894 0 R /XYZ 71.731 586.596 null] +>> endobj +2901 0 obj << +/D [2894 0 R /XYZ 71.731 575.702 null] >> endobj 2902 0 obj << -/D [2899 0 R /XYZ 71.731 699.706 null] +/D [2894 0 R /XYZ 91.656 557.869 null] >> endobj 2903 0 obj << -/D [2899 0 R /XYZ 71.731 687.258 null] +/D [2894 0 R /XYZ 71.731 532.798 null] >> endobj 2904 0 obj << -/D [2899 0 R /XYZ 71.731 682.277 null] +/D [2894 0 R /XYZ 71.731 521.904 null] >> endobj 2905 0 obj << -/D [2899 0 R /XYZ 81.694 661.519 null] +/D [2894 0 R /XYZ 91.656 504.071 null] >> endobj 2906 0 obj << -/D [2899 0 R /XYZ 81.694 661.519 null] +/D [2894 0 R /XYZ 71.731 496.933 null] >> endobj 2907 0 obj << -/D [2899 0 R /XYZ 484.554 661.519 null] +/D [2894 0 R /XYZ 263.545 486.138 null] >> endobj 2908 0 obj << -/D [2899 0 R /XYZ 71.731 633.46 null] +/D [2894 0 R /XYZ 500.364 486.138 null] >> endobj 2909 0 obj << -/D [2899 0 R /XYZ 81.694 617.684 null] +/D [2894 0 R /XYZ 101.898 473.187 null] >> endobj 2910 0 obj << -/D [2899 0 R /XYZ 81.694 617.684 null] +/D [2894 0 R /XYZ 71.731 445.291 null] >> endobj 2911 0 obj << -/D [2899 0 R /XYZ 71.731 615.527 null] +/D [2894 0 R /XYZ 71.731 430.183 null] >> endobj 2912 0 obj << -/D [2899 0 R /XYZ 81.694 599.751 null] +/D [2894 0 R /XYZ 91.656 414.407 null] >> endobj 2913 0 obj << -/D [2899 0 R /XYZ 81.694 599.751 null] +/D [2894 0 R /XYZ 71.731 402.288 null] >> endobj 2914 0 obj << -/D [2899 0 R /XYZ 71.731 584.643 null] +/D [2894 0 R /XYZ 71.731 389.336 null] >> endobj 2915 0 obj << -/D [2899 0 R /XYZ 81.694 568.867 null] +/D [2894 0 R /XYZ 91.656 373.56 null] >> endobj 2916 0 obj << -/D [2899 0 R /XYZ 81.694 568.867 null] +/D [2894 0 R /XYZ 250.874 360.609 null] >> endobj 2917 0 obj << -/D [2899 0 R /XYZ 71.731 535.826 null] +/D [2894 0 R /XYZ 71.731 322.587 null] >> endobj 2918 0 obj << -/D [2899 0 R /XYZ 362.548 499.128 null] +/D [2894 0 R /XYZ 71.731 309.635 null] >> endobj 2919 0 obj << -/D [2899 0 R /XYZ 71.731 496.971 null] +/D [2894 0 R /XYZ 91.656 293.859 null] >> endobj 2920 0 obj << -/D [2899 0 R /XYZ 71.731 482.027 null] +/D [2894 0 R /XYZ 133.648 267.956 null] >> endobj 2921 0 obj << -/D [2899 0 R /XYZ 210.667 460.872 null] +/D [2894 0 R /XYZ 71.731 255.837 null] >> endobj 2922 0 obj << -/D [2899 0 R /XYZ 76.712 444.234 null] +/D [2894 0 R /XYZ 71.731 244.943 null] >> endobj 2923 0 obj << -/D [2899 0 R /XYZ 128.518 400.689 null] +/D [2894 0 R /XYZ 91.656 227.109 null] >> endobj 2924 0 obj << -/D [2899 0 R /XYZ 76.712 364.329 null] +/D [2894 0 R /XYZ 71.731 142.263 null] >> endobj 2925 0 obj << -/D [2899 0 R /XYZ 81.694 346.396 null] +/D [2894 0 R /XYZ 110.407 131.468 null] >> endobj 2926 0 obj << -/D [2899 0 R /XYZ 81.694 346.396 null] ->> endobj -2927 0 obj << -/D [2899 0 R /XYZ 71.731 331.288 null] +/D [2894 0 R /XYZ 71.731 48.817 null] >> endobj -2928 0 obj << -/D [2899 0 R /XYZ 81.694 315.512 null] +2893 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F33 1306 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 2929 0 obj << -/D [2899 0 R /XYZ 81.694 315.512 null] +/Length 2620 +/Filter /FlateDecode +>> +stream +xڭɲ��>_���R�Ds_r�/�S���y.W*�DB�`@���ק7��6�)�h��F� +~�*�,�OXxa������:��_��b'Kv�5߾����Q�*�"�V��U��^��, +�< W�տ�ߝT?j�م���<���ں���ݑQ�N�`}��n������^�N��+���5w����_xi��2?��8&��fޢ"ZWjT{5h ��K��� ��Foy�d�IUf&�G�J�9`r8F�k �:c[3 ��=@�Vu�f\��p���M��u���'�N�CQ��vA�"pX��*]�dM�_��-L6gF��#�vڍV��|?,�>D4rw�ˉ �O|���9�#��ǩ�HD�³g�L��x0ᛊ'N�Vo��_+��������������q���`Y�uEփ�Oa�MfUT{@�<I�"h<�"�$|�_�IW¿5SW=i�o}�$P�|��:A�f`�Յ�T�H�[��k:�M��ʓ�ZȪN6��E� +�w.U��&M��z�����P�� +𣚉�`F�'A�ʪV����hq���#����@�hF� j��$�A i�1���u�(��!iT�7��x����b���;^i. ���o���5-CL* ��2ݫ#� �L7u�0���꾩K5��V0Q˗# Bs�` +�M�2��8ԅ4���Y�[Q�P�m�so�mm-xJ�&@�醩y L%WL�Ta� �]�#�[c�B=��a��I�d��}/�S�iE��il���-i#I//�G�;������wNB��!D��ܳ � �?��FJ���EbdQ@��9w�/���j�Ӷ偒dfѾQ�[�c�Bݐ� u=����z"� ϼ쓟�P�R��U�X����|`��B�b]��zC�aS�C-�w����B{�����B%�FMB���z[k��Hp~`��.uW6��k@�Ȇ� ɱ�Y]�+��r��>���F�/��� B"S�_�`MY9��������8Dgng�$��v��;`r�ƴ���ȋ�X�Uƚ���G�+pr�����xT(�ua��Y +�|ی'3�8�t�� +���(��uG��T���M=b4JLd�(@7dU0���d2r��]��kx+ٿ�J�\}� ��*Ea� ?���u��+��W��W����u��.R��;2?L�j�A�S����I1H6�@c +���4H��,�;�,˜�z<����a�%X|RH�����3J�L[[�`�#�Y�֙-^6�˞4�9J@�~F�x��������+���Md���&��H!t$��g�@������#,�b e&�I5�j������"�4.�}��������d�@�m?2,B�ņ��Sč����剗W�!�Bɩ��WÀ�@壱O�J"ǒ���,u��0����" n�B��}^��A��qY*phq��4�QK�9pI�3<ɇQz��B�pA�Y>tK�0���3���P�dժ�X�J�u�j���a\�Al�����:� �����&G���|�BR|�*�F�OU�����}Z��1�'� �T��"�Hϓ�v��FB'�/���KJ�d:"AY �ǣ���E.�fg���sq�����`0^��[[z!�ռ��%�+@�|K����8p7��h��������h���LS)����V�.��ԇ!p ��� ����d�"˿�/����,Y�B��bs��K���}�,���[(�UA7�v..�� h�zӁCmy\w�}����8i��v+%�'ꙹ�G +�P�L��b�/%:b��zO����]'P��v(��j�� +�¥�r1�����C�H�Vc�V���,��Rf� ��ܒ��8�2���w�>��^��<��Xh� !)k�/kٙ�IH�86"S�Rv�)U��C�w&\l�n?6�����x�G��P�%W��Űv�hѿ�@�$�<�� +A�H��|�����h��s# #���U�9`~��V��h�B=LB�� �0���k~�-_Z�Ya����no� ���ԟ�f�d���G�7P�>�f��/���Ԟ�2�XF���!�o0��0'� ��pb|�C�_�Ӝ�'�9v��Jɿ�w��t�#�:<�G�F��O��ե�����[�\�L��y���+�]�d���u��Q�Ѕ��#)���Ϊ�1�9����/7��ʱ��5Z +ǂ '[S��9�� H��[���\UZ��shCݜw�V�%���{��T+�X��a�]7�$�ߨ��y�h�%�w�{����@�+u~V�Q�_,��Ԟy��@�>R��/}I��m��D���=�L����nC{Lq��=����Rր>�4�u�}x��#'���^>�|/z��E���oo�"���k��צo=��1������3u������$��9�Ӑ^�������J���w�0�� �����[ ���yI/���k.�NhiNƗ�Ai���X�����~Wۻ�ug�L��vi#����N�0H&p��<]=%-���|�����Lv�w{y%���Ĺ��g�q����ᖄ�燎�! +��{v��"R�endstream +endobj +2928 0 obj << +/Type /Page +/Contents 2929 0 R +/Resources 2927 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2892 0 R >> endobj 2930 0 obj << -/D [2899 0 R /XYZ 71.731 300.404 null] +/D [2928 0 R /XYZ 71.731 729.265 null] >> endobj 2931 0 obj << -/D [2899 0 R /XYZ 81.694 284.628 null] +/D [2928 0 R /XYZ 71.731 657.37 null] >> endobj 2932 0 obj << -/D [2899 0 R /XYZ 81.694 284.628 null] +/D [2928 0 R /XYZ 71.731 592.777 null] >> endobj 2933 0 obj << -/D [2899 0 R /XYZ 71.731 282.471 null] +/D [2928 0 R /XYZ 71.731 579.726 null] >> endobj 2934 0 obj << -/D [2899 0 R /XYZ 81.694 266.695 null] +/D [2928 0 R /XYZ 91.656 561.893 null] >> endobj 2935 0 obj << -/D [2899 0 R /XYZ 81.694 266.695 null] +/D [2928 0 R /XYZ 71.731 533.833 null] >> endobj 2936 0 obj << -/D [2899 0 R /XYZ 71.731 251.587 null] +/D [2928 0 R /XYZ 71.731 518.889 null] >> endobj 2937 0 obj << -/D [2899 0 R /XYZ 81.694 235.811 null] +/D [2928 0 R /XYZ 126.726 486.077 null] >> endobj 2938 0 obj << -/D [2899 0 R /XYZ 81.694 235.811 null] +/D [2928 0 R /XYZ 71.731 423.611 null] >> endobj 2939 0 obj << -/D [2899 0 R /XYZ 71.731 207.751 null] +/D [2928 0 R /XYZ 71.731 408.503 null] >> endobj 2940 0 obj << -/D [2899 0 R /XYZ 81.694 191.975 null] +/D [2928 0 R /XYZ 91.656 392.727 null] >> endobj 2941 0 obj << -/D [2899 0 R /XYZ 81.694 191.975 null] +/D [2928 0 R /XYZ 409.936 379.776 null] >> endobj 2942 0 obj << -/D [2899 0 R /XYZ 71.731 163.916 null] +/D [2928 0 R /XYZ 71.731 355.422 null] >> endobj 2943 0 obj << -/D [2899 0 R /XYZ 81.694 148.14 null] +/D [2928 0 R /XYZ 71.731 341.754 null] >> endobj 2944 0 obj << -/D [2899 0 R /XYZ 81.694 148.14 null] +/D [2928 0 R /XYZ 91.656 325.978 null] >> endobj 2945 0 obj << -/D [2899 0 R /XYZ 71.731 133.031 null] +/D [2928 0 R /XYZ 71.731 300.907 null] >> endobj 2946 0 obj << -/D [2899 0 R /XYZ 81.694 117.256 null] +/D [2928 0 R /XYZ 71.731 287.955 null] >> endobj 2947 0 obj << -/D [2899 0 R /XYZ 81.694 117.256 null] +/D [2928 0 R /XYZ 91.656 272.179 null] >> endobj 2948 0 obj << -/D [2899 0 R /XYZ 374.742 117.256 null] +/D [2928 0 R /XYZ 71.731 234.157 null] >> endobj 2949 0 obj << -/D [2899 0 R /XYZ 71.731 115.099 null] +/D [2928 0 R /XYZ 71.731 223.263 null] >> endobj -2898 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F44 1994 0 R /F48 2006 0 R >> -/ProcSet [ /PDF /Text ] +2950 0 obj << +/D [2928 0 R /XYZ 91.656 205.43 null] >> endobj -2952 0 obj << -/Length 2522 -/Filter /FlateDecode ->> -stream -xڝY�� �>E��`�ڒ_�v�w�އ;;EQ� -'V2�:v�������(R���)�LQI�J��.�P��Q:���C�8`�o�P��d=�y�����Yl�&1���" -��Ej��b�x*~Y��O�mWkK����8�u�_�F�V���{YU�귧�e�&U�̼�^�$JC�Zj��d�DѸ�. ��� -���Z������D6v��������B�l��>��(^6Ű���h�B�8��UI���@ -���L���s�.� -�Z5+/_<�f�\���}�2�o��ܟ�ly�uzt�.���s�{�LG���1�yq��lW:X�Ny]�� k��q�z��b-�[�Zmģ�N�N��ϫ0^Zư���آ콤7�;��J'��eei���i�K+��x�6ʼ;�9�I(1�Y�!��k��: -TeNe�4�"�p�-�j+۳�c��5��n-`��y�|�c��o�<��ؖ�p�����N��C��bhk[.����d�+?Zi\��$*��<O���k5����ݑ�,ܨ�Z�11P�*�Ӽ*�� �R87��+0y�5�s�C'��ݮ�1�?5����{ubT�⾡�ܻ�i��Yq]8�4{�tVv@y�<U7����v#�9��;�h�eSWg&�� -������y�l�l�w���˥�Eٝ�CP�"ݝ腖�-ǵt6������1J�ͣ��|�c8�H�à���Z��Cc�]W� ]���H�GF�Ձc��=7C%�?������=3�E Fg ���@�W�T� -�d��zI+ -��'`�?���4�EZ�����2�|�9b�e#ж�ǫ��H�-�>��}�����cd��p���/�������(["I�\�a7x~yw/h:guӧ�ͧ<Mo�/K��BJ&�꜏M���̶'� 0��k�{��'�R�����`�Z��Z+���-�p'�wB{,����$Ѽ��o��ȅ-�c��1?3����v`@ΖnW�.�9ѭ�ccX��ay�3:��|���È��y �\:?��H1���vd�,�&�2Y&I7��ͮ5 ��m����mCd���d�J���s������,)�`��䅐�c -�*q�(Z�t��F:�Oz=�B�ES�p��L��5�ng���~ep���0�B�39����1� -o�'��tδJ"_�m�7 �mw�u��mb!<���N+��D�ߝ�[X�j>T�#cr�D�-���:\�9��u2���+Qg-��k������ko \�,J��&�����\d�9e���3Q�A�D�Wl؝�t}���8�q���V� _�,������>��S~�B?"����{w��˓A -�ŝ�����'�a����e+�9��b�<��){��l�9������R/��s���>C�˾�����mk)�y>@��7��{���6DΊ�쓺��i�̘ QN�c��Hҵ�dl8�gY)tN�RR$�x����vmy�J4�̉x�)<Ѫ�`��qOW���lo�C'� -�z���=��)H�ͭpt q`���=Ű+�'W�Fe@��'��*��;A�H�%�zLn!���O�6wEPw�b��B�s&�����(S�tf���d���z��x^!��q��O�.�p��;9ݣ/ -_ql�iH�] }�ԓá�7,�-�7M�)(���t�J�T����C#K7�#V{���,tI�����~k�Lm/5(�W�_,��l} *x��>[�v��`B۹=���l�X�u�=x�ڨM�Z��>��[�(Џ������偈#��I7�J�h�b�����#���4e��k<x-ѥ��^�UȎA25|(�PwD.!� T&�Ǝ�!�T�Jq�@הk���P ���b�����SJ�F�]؋�c�0@\�|+�}�"5�|���S���f"�$�y�b���(]�C+�b�u�Y� �w��T�O�����c���Y���y�S��J୕���Gl.�|�6G���EgG�ݔ}��3�$R_�I��G3[Ye���ҷ�h���6���~��6GgTY}�N���Eq'����dd�F��?~�gG&@ٜ@QG���l~G���⎤J���3ܤ*J�e��1��ѯA�w9��{��Us�r��c���Z̭D���1}�ڴ�*��WHr�9��5nm����쁒�fa⢫4��+@vҝR��K�8Of�������W��A~o�IB��$<�U� ��;���O����B���1>�ve }[�Av��r�ﰴƫ�+u�-OLo��œ -���9sٚNI������V���be���|d���������AL���8�d-L/2��R�S��]��f �v���-S1 M7u�6i4s��t -��}Ѯv��� -��3�s��#�p��Ȓ�� @��-q��4^&�*���g���{��Np�.�J � -�:>4p��k+��X|�l�& J`�2���?�L$7?��:S��L\p����Э��2y�endstream -endobj 2951 0 obj << -/Type /Page -/Contents 2952 0 R -/Resources 2950 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 2818 0 R -/Annots [ 2958 0 R ] +/D [2928 0 R /XYZ 71.731 167.407 null] >> endobj -2958 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [290.209 633.858 335.442 642.77] -/Subtype /Link -/A << /S /GoTo /D (parameters) >> +2952 0 obj << +/D [2928 0 R /XYZ 71.731 154.456 null] >> endobj 2953 0 obj << -/D [2951 0 R /XYZ 71.731 729.265 null] ->> endobj -2954 0 obj << -/D [2951 0 R /XYZ 81.694 708.344 null] +/D [2928 0 R /XYZ 91.656 138.68 null] >> endobj -2955 0 obj << -/D [2951 0 R /XYZ 81.694 708.344 null] ->> endobj -358 0 obj << -/D [2951 0 R /XYZ 198.466 654.944 null] +2927 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F44 2037 0 R /F35 1567 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 2956 0 obj << -/D [2951 0 R /XYZ 71.731 646.306 null] +/Length 2385 +/Filter /FlateDecode +>> +stream +xڭˎ��>_��e偭H�d[�ivv'����^L�ll����DG��8_�z����9 |Y,֛UE:^D���8�&�Qy�6٢h�E����],kAY�p~|z��OI���|�,���4��m�/�� +w�Z<�� +>�i0�r��(HB�~(���z�W�A?��88���k����_����yg�6�w�7�s87��$�S3څI��x�m��}��� o�(L��S�9�gK�����P)�X��݈���&�x�(އ��lw�p4���oQ�L]�<�um�*�<��Q6X��U1�A���`d=�8��`�L�[�t/�s5���N+aږ�`Uy،���RE���8���"����c���l�\'��� N��m�����e.P����Ӯ�%�:=خGl� ��co� <4ب,�4Moj�� +/v����G���tu�]�D���h��Ћ!m�`�˻����q�8�˱@.�luW��gJ�|��������~[�Su�[���� ,��|1�ؙ��Ug�,G�15���j�DY綑���(�k��_O�n�P�6���C�A֟A�u�l�!I<�S��+��ƫHE��Gl�C|�(���t<�Ah�l](�e�ɂ��^�=����0�*��,�y!й�L���Ѵ<‼g��J��4贾:�2��ۓ�h�Y��)�����³� d`HK�bii�i)��6��ڄ�����̟��TY�@*��"/%�m`x�AAGx +/�/�v��l�0�0Mg�ؚa��]�c�35�+[f��I��N�G:7 +P�X��!�>!u�hg���{k�ݳm�1�mԹ����P�Z�r� �)`E�3�ԃ~ֽlr�(�E,D�l*tb�5�93V̀K �<�r�a�7��|%5��t����B�V�Yie +�IoWl�GW\$wp��*�HS��E.��Ti�vG��lX����1!m���c �Ym]'9�$P�7I��p���d��L9G9xw��t����wjf��j +���LA�V*��� .��0;2�w�&QE,�t�r �La*��6�!���8{��@B��j�|��\Z����2��k_�;6�(Ea����DXV{to:f4�O8L�kh*H�\�2N��YC�~� Ik?���@�-�eN�i�_�gm���mS�ؠza�e0������1h�a��SF�F�w�ҭ7�]�Rv���綕�[�7�VE�HP*�����-�)$%:Oj�x�˭ی��Q5�!8#�v�K�.�D�k�����j��?�a64��RI�lLU*���c����SѴ-����/(�7�z�C^Ͼ�Y�Ƚy���:�D��H'*q�+@O���)�d�����7pϬ�����i�~z���?1>+M~��u/O�Z���A[2�4`�Ҵ䋐A�P,9���-�9�����a*pyM�Y/SJ��ե3��SN���(��:���ZRٔ�|@\%����r�Kd�50��_�ݢz�e���&K�̈���8\7po9��Oc+���A��*���-�g�� +j��2~�V,��/W|����a��B�8�E#�ٺ$�G���܅�Z�p��1�1�D$�A���ޜ:����ѭs���-�|�/���y��靋,�4�n���|_]�$=8�;�#f����=�1��Zs����)L�RM)%�+� �k��0�$�a �U������wdl��s,�E��8x��y85�y��i�'�^!A��$�c/1@���������N�,h�đ�^�{|�x��&hC' q�yN��JT���<��Nr����U�)@��0��\鯴Ĭ�QX�@#q� +��E*�+{lp�k\�����(T ��I�Bn�� +F��4�'��IJ���d�<�X�|�;���|�����f�n�o��"�᫄���{UF-|�/HpYeZ������j�\!�[��p�D��'��`A9�0K6��sy�p�r��/�5,��n���w����Ô%dyr�'�4e���6n��E�X�$q ����� ��!�)K̷����$��[XC���6�q���E¢�������!I���!�W�w��y�^sj�)�p0�`|�Fp���0D}�LM�BR%�{��"�z�x�Nw,�1��������V�'�?���Fv<��]��Y��M�r�r\���gu��B��Sv�W�x �<9 Q�����J�쨚�Q��c^]2��ⲵh=���4��8QS)��a���f��z�����Z�i!f�9��0��\�{^=,s�IS�~�h@����G!^m0�x�7V�7�;�G��g:�G�ٓvտJt�v;�1�ׇ��#�H�0���w�]���,���+�څ�rD(9���,������endstream +endobj +2955 0 obj << +/Type /Page +/Contents 2956 0 R +/Resources 2954 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2892 0 R >> endobj 2957 0 obj << -/D [2951 0 R /XYZ 96.324 636.015 null] +/D [2955 0 R /XYZ 71.731 729.265 null] >> endobj -1452 0 obj << -/D [2951 0 R /XYZ 71.731 577.071 null] ->> endobj -362 0 obj << -/D [2951 0 R /XYZ 233.494 543.761 null] +2958 0 obj << +/D [2955 0 R /XYZ 71.731 718.306 null] >> endobj 2959 0 obj << -/D [2951 0 R /XYZ 71.731 535.123 null] +/D [2955 0 R /XYZ 71.731 708.244 null] >> endobj 2960 0 obj << -/D [2951 0 R /XYZ 436.119 524.832 null] +/D [2955 0 R /XYZ 91.656 690.411 null] >> endobj 2961 0 obj << -/D [2951 0 R /XYZ 71.731 511.781 null] +/D [2955 0 R /XYZ 71.731 644.419 null] >> endobj 2962 0 obj << -/D [2951 0 R /XYZ 71.731 496.837 null] +/D [2955 0 R /XYZ 71.731 618.516 null] >> endobj 2963 0 obj << -/D [2951 0 R /XYZ 300.596 485.28 null] +/D [2955 0 R /XYZ 71.731 603.572 null] >> endobj 2964 0 obj << -/D [2951 0 R /XYZ 71.731 445.729 null] +/D [2955 0 R /XYZ 71.731 519.95 null] >> endobj 2965 0 obj << -/D [2951 0 R /XYZ 71.731 373.833 null] +/D [2955 0 R /XYZ 71.731 504.842 null] >> endobj 2966 0 obj << -/D [2951 0 R /XYZ 71.731 347.93 null] +/D [2955 0 R /XYZ 91.656 489.066 null] >> endobj 2967 0 obj << -/D [2951 0 R /XYZ 118.555 309.366 null] ->> endobj -1453 0 obj << -/D [2951 0 R /XYZ 71.731 235.744 null] ->> endobj -366 0 obj << -/D [2951 0 R /XYZ 226.737 197.466 null] +/D [2955 0 R /XYZ 233.106 463.163 null] >> endobj 2968 0 obj << -/D [2951 0 R /XYZ 71.731 188.643 null] +/D [2955 0 R /XYZ 71.731 440.15 null] >> endobj 2969 0 obj << -/D [2951 0 R /XYZ 71.731 168.769 null] +/D [2955 0 R /XYZ 71.731 425.141 null] >> endobj 2970 0 obj << -/D [2951 0 R /XYZ 71.731 145.022 null] +/D [2955 0 R /XYZ 91.656 409.365 null] >> endobj 2971 0 obj << -/D [2951 0 R /XYZ 71.731 137.884 null] +/D [2955 0 R /XYZ 71.731 371.343 null] >> endobj 2972 0 obj << -/D [2951 0 R /XYZ 349.696 127.09 null] +/D [2955 0 R /XYZ 71.731 360.448 null] >> endobj -2950 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F32 1187 0 R /F44 1994 0 R /F48 2006 0 R >> -/ProcSet [ /PDF /Text ] +2973 0 obj << +/D [2955 0 R /XYZ 91.656 342.615 null] >> endobj -2975 0 obj << -/Length 2425 -/Filter /FlateDecode ->> -stream -xڭ˒۸���T�çDfOc{��֎㬵�!�1j� -�V�>��II�\�J�����n4�I�w�»u�c�V�ݮz��a�/�B�x`�� Λͫ?�����W����. �w�8�4�����Dkd�|����}�J�J\�{�闡���*K����WO��w��<�o��p.�֣|�A��Ib��r�5�����R��2Zy����Rh���N����� $%U��)��d:5!��P�/ n��с'R-K�ll�Q��{�6Ӡ��ڡ0�`�y����r�� -�<����3 �Iۢ.hbp(����K!B����@��P��A�/���D��LSK��4i��Gy�%�p�Ga�Oҥ�ũ�.���u�}�P�N��퀟o�~��oZ���J� i6�A��5I�p C�3����\�Z_�p������!���i3��m'�� �;)ʇo�tҕ����m�nr��Ht��O��'b� Ǧ��r���'@���@��'���~ o[I}O����A ���$����-��:|Ư��$������ K�ֲ� ��g�A�д%hX�mP֪�|vJ쌎��2|�y���ݡn�fdm-v�1�X��Qm�N���kƮ� �[y�^t_��.����r���{"Z�kYf��Ʒ4��40v֭}�G��A�CF~���]�7=���4�4�"pFc�P4a�N�d�� ��}'�%�0�X$:�o��0���B+�3�o|��->�(K�-�ZG6R/Uk*T92E���c!�(�L$;�J<�iTvL9<�Ɇsk0�Ѳ���UgmO6���`�ȃ�҄-zc��k'��HЗ�y����o�����ߞ��@az���D�K����-��g�a���{1ø�LC=�KVܟ/�kq�-d��b�lx%�� �e�=%�҅�9�,�W�d���8��#7y��Eޟ%dDC7_8/\���3 �,�!�4��U����M�Lp��ơ�x�5�����jn�>#{��!�/�����sIԴm�q����`�il�ᵊ�ilĹ�1F�Z��.y�Xc7x��E�O�P� -�!U�̆���DsVu�[R�:��PO��;�n�r)#�d��+��q#����VϿR|pсF -����2̬8y�qY�i)�M�;t�<��[6����M9��� �V����g�]U}E��/�(w�֔��R��j�!��3+<� ���'Q:��K4���<i��s�1l��<��ȴ�X��\|�1�s��8Wd��b�hMr�������P�����`8�����4e���dtz�8 8���SH����K�fJglx���ӊj'4�ֵ2�8J��G5 �|���z��$��hy�J����6��`�N�r�U^�bM���G(��4��rĴe��m�N��VC`�+-�u|Zq��u��I<���E�/���-h~��5��C� ��*8j��?,FV�\��z�)��,~����Zа�������fu �a����~�j}] -j���'6�%ڈ����O�s��Ȏz�Զ'�-���L+�3���q�}�31���M2��I{;�YӋ�gPA��*~b������ *v��+��&�� -�PC����}�B�U����;6 ܴڪR�#�}S�{Ps�����&�%;�mc��B�\V{O�* ��^�L��4� �|A� ho��R��58����H�}m�>����X�F�̆I+:����2�R����dE~Ѝ;:+$~B9/�Ǎ'D�=I#�b�U�� .U��ۡ� ���5�?���,Eah6�ا���ׂ��E���� ��\��kL�}'�����(� -�z�F9Kx�P`=^�� �������iIO�]0���H��&ۦ��+�S������]�����N4���m�Rά�pbJo#��6�L�v�]j6/��C�i���K��wh|���'���ߝi�K'�o��i�9�E���i�-c������i���zw�;�WXfN�+h5�)���5��i(K]Φ�)eE�� �����!�VJc��?�Wb(n'K1�m�j3[*0}���Z���+_��r�p�ύ����fk2��֚8��}���&�x�����=ʌi����;�O�r�̧Z��Wtf�f��Lp��ԡ�l�gx�P��x���7��5��V>������f�<���*����,�~oC�����9TY>� ���{Z B��>0����2ܜ�d�r������d��ϐ1~���{� -!�|��e�_-�o�h���dRp�8�䤋G�1A�mp2������ןn����N���ܫz��l%5�X�f�,w��!J�r���w� w7��@�0b+����_�<o�]3�\�[�F�D��5�������_Jtendstream -endobj -2974 0 obj << -/Type /Page -/Contents 2975 0 R -/Resources 2973 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3001 0 R -/Annots [ 2979 0 R ] +1475 0 obj << +/D [2955 0 R /XYZ 71.731 296.623 null] >> endobj -2979 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.731 621.441 110.234 630.352] -/Subtype /Link -/A << /S /GoTo /D (gloss-product) >> +342 0 obj << +/D [2955 0 R /XYZ 269.758 253.525 null] >> endobj -2976 0 obj << -/D [2974 0 R /XYZ 71.731 729.265 null] +1476 0 obj << +/D [2955 0 R /XYZ 71.731 253.31 null] >> endobj -2977 0 obj << -/D [2974 0 R /XYZ 71.731 718.306 null] +346 0 obj << +/D [2955 0 R /XYZ 283.793 214.153 null] >> endobj -1454 0 obj << -/D [2974 0 R /XYZ 71.731 688.254 null] +2974 0 obj << +/D [2955 0 R /XYZ 71.731 203.788 null] >> endobj -370 0 obj << -/D [2974 0 R /XYZ 179.498 645.157 null] +2975 0 obj << +/D [2955 0 R /XYZ 71.731 165.969 null] +>> endobj +2976 0 obj << +/D [2955 0 R /XYZ 71.731 151.025 null] >> endobj +2954 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +2979 0 obj << +/Length 2293 +/Filter /FlateDecode +>> +stream +xڍM��6�>�"x�:@�����7���:s�����l%1ƑS˞��_R�l��K9X�(��7�`��/Xe��"x���dU�������]�[F��p�����K� +Q��j�_ž/2�XeQ(�$\��{��ܫn� ߋ=��S�k�Z�~X��u���v����n�D�(��x�F�0Z���t��g"�+_$B��Y��.�\�w ���?Z�a���*H<���@I�t��6�E��IL����:��)G�{��L[!�@!����MZfA.����~�����-�r�w���5#U�=�4�� |��u�x��Ʋ?(�p'T��Kʲc��$�iZ���*��-=���c{���'�n���l�t> ��Z���X��ȂPVEV+!LPk�*"� ��0I<1��ǀ�"��"?���~ؙ�6���д�z��A1Bm�),]q��;����>�I� l��hmO�˲tom�������ī���b�^�A�X65�1b��J_���<�~����^�dC -O|h�gM{�I/��ο��_%h�4cO�dʹdUu���L�Ԣ�R����oOO븂�'�M�]D�V����U�43x� �3Ix�; ���P���:r/��>{�Y�ǝ�dN>�݅����L�ȉ�����{�;��m��Ҧ�)�\L�^L���Q�:������ �Nq84�#��{�&l��>$��y��D�����:ʈ�wLY>��6gE�xswc.F�'�b�*eC��cM��ՕqWGŠ����y���īZT_��i��nƏn�G��Hֺ� `!6PuۨA�� .HBtW�=mG��&[xR���7M���&�+��B��c��C M�~Ic�y#�ͼ1M��ē�i � BZ�aw����f�8X�(II��@/��e�d9��ݳ*k�cI{H�@z8ھ�гR�o��r&�u��0��i[���R�3��8*}��G��n5�z� Z��{CX��p�f;p�Sv5�6r��t��.'���ԝ3���,N�T�YX]*���sמU��ʈ��I�8�g��y>@���m��n��=H�(O�(N-O��v��ڳA��w{����Q�,�V;.���@��mY�B�����rՔv/�l� �(����G!��u#�M݈��_��m߷'�gOO%�an��Y�RZ�4.�N$@���B;p��:�����6[�a��cq=1�Z̈́Ucx%0xu�� �$>���I�<l�]Y�64�QN2��d��,8[Εhu��bbm������2S���Y�A���x*�eG�k+���w�����et�-��[f*�3���m�͠c[�kW#�2p� +�g�A,��3�;ouH�C�1)�S���\b�Z�GA�8�Wq���ν���lgH4͢qI���\���[�d���f1w8�/ !sq�y�A��&�<�Ni.�=���;����Qc����֑��)�+��r��BwM�{���ή�Y��s(��dr�((�C#����=��ߙ^8.x�ª��+\?-��0����:���?�lg87�[�A�b�+/D���x-�#o����,�~ޏ_0CNM�����bB|�X�>�گE���ɫ�`<�s���"l����J0��sU]5Z͚?4ݓx�tP�S��C�M8o��QP}ᛦ�����{�{Ay�R7 +v�U;��P +�"���OJ;J��u��q9�Nύ�W�u����&��`�����T�O���rx �M)�� !���H}���=~��O�a"�� A`q�3�~���K�j+�^Qj��l�B�WT�ˊ�~.�4aں�o���7���*歉.���R�N��`�!ۆ� ���|�x<x����z����:�v���?��Y�NO���8��DBE�(�- �Q0ܔc������*��fv�X�*�g�V�n*��9}O�M�*�l���9�Z܋��iC�W���K]ZW���~]ݟގ���ocy�D�%Ms����$@�,/�d�&{8��?Mi��� ��d�9VbƲ��a>���3iA!���ۑ�q���}�B2��ڋFeZ>��V��nU�J[���������6���:�=�g���>�ӱk�C����Pw�[0�Y��_[3�&_����eA�#4� G`������7�_������m@_4�s"����@�qv���~2��z=W.:`�lW���־�{��u�_Swr��e�Y�v��J��ې��8y�=�#bB��" sᇎ�U\�֟ +���?�quendstream +endobj 2978 0 obj << -/D [2974 0 R /XYZ 71.731 636.334 null] +/Type /Page +/Contents 2979 0 R +/Resources 2977 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2892 0 R +/Annots [ 2992 0 R ] +>> endobj +2992 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [177.424 411.089 222.255 420] +/Subtype /Link +/A << /S /GoTo /D (parameters) >> >> endobj 2980 0 obj << -/D [2974 0 R /XYZ 71.731 590.556 null] +/D [2978 0 R /XYZ 71.731 729.265 null] +>> endobj +1477 0 obj << +/D [2978 0 R /XYZ 71.731 718.306 null] +>> endobj +350 0 obj << +/D [2978 0 R /XYZ 264.312 707.841 null] +>> endobj +1478 0 obj << +/D [2978 0 R /XYZ 71.731 704.649 null] +>> endobj +354 0 obj << +/D [2978 0 R /XYZ 274.763 673.37 null] >> endobj 2981 0 obj << -/D [2974 0 R /XYZ 71.731 548.778 null] +/D [2978 0 R /XYZ 71.731 664.733 null] >> endobj 2982 0 obj << -/D [2974 0 R /XYZ 71.731 533.769 null] +/D [2978 0 R /XYZ 119.865 654.441 null] >> endobj 2983 0 obj << -/D [2974 0 R /XYZ 71.731 528.788 null] +/D [2978 0 R /XYZ 455.128 654.441 null] >> endobj 2984 0 obj << -/D [2974 0 R /XYZ 89.664 508.031 null] +/D [2978 0 R /XYZ 71.731 636.409 null] >> endobj 2985 0 obj << -/D [2974 0 R /XYZ 71.731 505.874 null] +/D [2978 0 R /XYZ 79.19 584.703 null] >> endobj 2986 0 obj << -/D [2974 0 R /XYZ 89.664 490.098 null] +/D [2978 0 R /XYZ 71.731 564.613 null] +>> endobj +1479 0 obj << +/D [2978 0 R /XYZ 71.731 533.729 null] +>> endobj +358 0 obj << +/D [2978 0 R /XYZ 224.863 500.419 null] >> endobj 2987 0 obj << -/D [2974 0 R /XYZ 71.731 487.941 null] +/D [2978 0 R /XYZ 71.731 497.759 null] +>> endobj +362 0 obj << +/D [2978 0 R /XYZ 185.702 470.033 null] >> endobj 2988 0 obj << -/D [2974 0 R /XYZ 89.664 472.165 null] +/D [2978 0 R /XYZ 71.731 462.835 null] >> endobj 2989 0 obj << -/D [2974 0 R /XYZ 71.731 465.027 null] ->> endobj -1455 0 obj << -/D [2974 0 R /XYZ 71.731 421.192 null] ->> endobj -374 0 obj << -/D [2974 0 R /XYZ 210.434 378.094 null] +/D [2978 0 R /XYZ 359.607 452.1 null] >> endobj 2990 0 obj << -/D [2974 0 R /XYZ 71.731 365.923 null] +/D [2978 0 R /XYZ 388.183 426.197 null] >> endobj 2991 0 obj << -/D [2974 0 R /XYZ 71.731 310.543 null] ->> endobj -2992 0 obj << -/D [2974 0 R /XYZ 510.307 260.894 null] +/D [2978 0 R /XYZ 71.731 413.246 null] >> endobj 2993 0 obj << -/D [2974 0 R /XYZ 71.731 240.804 null] +/D [2978 0 R /XYZ 71.731 406.107 null] +>> endobj +366 0 obj << +/D [2978 0 R /XYZ 280.196 375.388 null] >> endobj 2994 0 obj << -/D [2974 0 R /XYZ 71.731 227.853 null] +/D [2978 0 R /XYZ 71.731 368.309 null] >> endobj 2995 0 obj << -/D [2974 0 R /XYZ 71.731 222.871 null] +/D [2978 0 R /XYZ 117.11 357.455 null] >> endobj 2996 0 obj << -/D [2974 0 R /XYZ 89.664 202.114 null] +/D [2978 0 R /XYZ 71.731 355.298 null] >> endobj 2997 0 obj << -/D [2974 0 R /XYZ 71.731 199.957 null] +/D [2978 0 R /XYZ 71.731 350.317 null] >> endobj 2998 0 obj << -/D [2974 0 R /XYZ 89.664 184.181 null] +/D [2978 0 R /XYZ 89.664 329.559 null] >> endobj 2999 0 obj << -/D [2974 0 R /XYZ 71.731 182.024 null] +/D [2978 0 R /XYZ 71.731 327.403 null] >> endobj 3000 0 obj << -/D [2974 0 R /XYZ 89.664 166.249 null] +/D [2978 0 R /XYZ 89.664 311.627 null] >> endobj -1456 0 obj << -/D [2974 0 R /XYZ 71.731 133.208 null] +3001 0 obj << +/D [2978 0 R /XYZ 71.731 309.47 null] >> endobj -2973 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R >> -/ProcSet [ /PDF /Text ] +3002 0 obj << +/D [2978 0 R /XYZ 71.731 294.526 null] +>> endobj +3003 0 obj << +/D [2978 0 R /XYZ 244.012 285.026 null] >> endobj -3005 0 obj << -/Length 2039 -/Filter /FlateDecode ->> -stream -xڕYY��6~�_a�IF�l�G��$A��Xd�@K���,):�����b�N[j����*�n��� ��M`���;��m��;ss����Y��3d?�|}x���8�HD��9�6�i���6�c�г7��w㛋,U���g��߯�k��5���L��e��I�L��8�������9��Bg�x��|���a[����� ���㡂��mǀ�Z�Q�E^�1`0����mKx^�w���,6X��� ��`{Ƨt*N3LYI7O4�����x��%K�������J�u2O�P�Y�m��4���x�oA[R� 3CM��-[Dl�k�5�V��2�ӴU�|A3�ں� 0�YYɸIc^Ӓ\��]�@�*KU��Oh���@�����|��"wv�� ��ҞE+��b��a�}WJ6��ԉ�IR>�����]6� ��o{ �xPُ0�#����#Zb.+��ﻏd�{ټeU��-�~����:���F؍�l�}N����M5n��h� �u5�E52�b/��^��j\�=c���w7kA�c�B�Ñ�G���"�n�$�/hULs���&7�\t�එ���HTZ���-d�\%�Yg ���Ǚ��WI�%��Ox5�g�c�4x��$aX��Uz�4b��^�/�W <�,��P^_0�YoxM��-�~����\^y���xi��]�s�<\��ș�wɏhVեN�V����ȳ��������M'��6�S"/\��U�ː{���z.�?�d�"Wo��:\-a�m$$��8���'r;��ś���y� -���9� ���v���A5��+EE+�Cy-3�4��:b u(�� ��`9:�{`���4�� x� ^a�m*H��V�F�����)��cW��:=�Yr�̬}�?uB3�<��h7,h{`<_��.�9�\w�Am���N>1/K(�y��k���%�v�v�I���$�/TO��'Z���I�p�Von�3۸�o�Z�s����g��e�b��S$��n��Sh�=�toY��}� �}"J�=q�N��)B7Xm9r�8��d������Y5�N�#t߾�j���q��qBW�u-5�0K�����0d����d�آ��<nCz��68��V��g�T���宫o�,��!���Yo�oE��������3]�N�J�ԕ���r��^_���=RM���0��c�j_�@���[�=c;��5�]_�$���K��Bwq -���۟�i �+Zu�0�u9�f`�Yf:�2Äu]T �h��~Z����*@t���VʢN�T�ww����/��<�;�f�CWXNj���?���w��i��1H -`�b�np�u�5�^/�R���#,��Һ�HiM�RVЄ���ÉA�T�P٪��32R�ľ/�GK�B�"{�gh^�ݢ�0)藞ݸ��R�8���Yy��!U�1�D1h�j`2�j��}i�d���Y(.ax���Sӱ��J}�,ao�0�I�R�R*�#[X���#�R0w��.�Yo����c8�8d`�Fe����'�Pw���T4V��̠&�@����� ��H��yD5�D̡˼ʆ^|��X� -�S;�Թ恁���{r���x*�/� !�^2������g�1�_��3�u,oDөA����A�R�)����u#���;��o푦3��,�`�'ZP)h�?ض���N� y�dA��<���_>5�ħ����W߮p�c�=J(�*U���:���KjH?Gd��#�DL�Ze�'Z���E���Y�\�Og��`���M�X���:�4c�2�U�<W�OE�7a�O���yk�<� @��P�K��Q���o�~�A��OL$G�І�p1�jXӼR���q"uQ��kbN#H��������N4��營�=�Kr��';X�t��B��J���g&h%��{fV������ϝcc�h���v��Vp�����b@v_ �<�E����a������X����/���^���T"�endstream -endobj 3004 0 obj << -/Type /Page -/Contents 3005 0 R -/Resources 3003 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3001 0 R +/D [2978 0 R /XYZ 441.891 261.714 null] >> endobj -3006 0 obj << -/D [3004 0 R /XYZ 71.731 729.265 null] +1480 0 obj << +/D [2978 0 R /XYZ 71.731 182.61 null] >> endobj -3007 0 obj << -/D [3004 0 R /XYZ 71.731 741.22 null] +370 0 obj << +/D [2978 0 R /XYZ 207.755 147.143 null] >> endobj -378 0 obj << -/D [3004 0 R /XYZ 176.83 705.748 null] +3005 0 obj << +/D [2978 0 R /XYZ 71.731 138.506 null] >> endobj -3008 0 obj << -/D [3004 0 R /XYZ 71.731 696.925 null] +3006 0 obj << +/D [2978 0 R /XYZ 71.731 126.058 null] >> endobj -3009 0 obj << -/D [3004 0 R /XYZ 71.731 664.099 null] +3007 0 obj << +/D [2978 0 R /XYZ 71.731 121.076 null] +>> endobj +2977 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F48 2049 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 3010 0 obj << -/D [3004 0 R /XYZ 71.731 653.205 null] +/Length 3508 +/Filter /FlateDecode +>> +stream +xڝZY���~�_�̋%`D�>#��lb��If�8bK�W"e��x��SW7����X̪Y���㫳�\���I��3Ǐ���������pl�ek�|����߂`�9Y�����u���VI�;i䯞��_�K���֏�u���Ź���eu`җ�>��<������>�{6�� q�4�;�0�Dn}��|���� ��,�OV ��\�O��g��N��l���o/��L����zN������]�j� �p�>?+�M��\LJg�z|Ɯ�Dz�V���p}P�j�����Q1�ڪ�M��=���:�剉yQ4��#j&|]o�h�����6^��3���,���V_�p�7�+�2bc�s�MHz{ݣ��\���!.~��o=��g������,�Ї�p�~����~���^�fRL���O5"w�*���{�ם��yg�ËFz�rݑ7���yu0=U�0�T�ff�V�xӄ���]M����=Z?��7V��Pd~*~�s�&�c�x���8���]�xn���XP�a�*4>�B���\?�=a�d��hr>(�1�<7f0 ����� @�I{FOE�d����`�^��t-�=�/��@��Є��]}���g�N�ܷ�ϭ����� +[>�����Ia�m�Z7� Y��R't#��%��?�&��$cMD�V>l�����/.( mn�L9������_���w�NL+��\�z���30�Ĥ�f>��d�da�����z*�O6,@��T1DMQ��T�;@�������l36h&yՍ�)���4�'~j�������I��5�]�|Q'4��q���^/�w��-� +�z��;>�^K:���a��h徑�����-��B���}|��Q3�?'xxA/kKͫ��DzR=}W�/'p�x0oL���X��6��<�ɖq*��q�s$w9�;m�:mT���?�@k@�vL��5�`����.����R�X� +UJ�іue?���������]�Y<7��9�7#lpc�3���=��0�a����s1c�f�݄h�6htoL���j@��y8Є��~�;]<]��q��?���)h�e��XfE(@��܂��`�IF(�@Wi���cP4��DP�vQ���ʜ���P��=Y����Ys}���w�b��#��rO=f)bX$tGW;Z�g&�[GS:�j r���}��w�:_F&�+��s���k��P���;md�d�*(�V�����3�/&��<��p�S��?�`�}/w[�j�C��*=���Ӽ%e3N�UWVW��9 �Se1~)y�� �?˻k�j�uc��x(�">R%�4Z:��aO������T ��}N��9���VL��!���g�/����/L*��� 0V�`ԕ��I�: �$:��L%��X���,���1݈�tL���F�%81�#o�J#�a"ٻ�>T)(���ƭ���8E��#v3X�`7c��XP�2?vb�'���g� Y���Ctl`�QF�p�N*Zn�kR��h��� �O�Dʋ��y��5�4P8����v:��חs�I�ތ���@o4�Vv�L:|�2������sR ���o]�Ȃ.����[^��Ŵl!�5��='�^�a�MM��w3�o+��d�!�Kb_8^����1 �Q��ݵβj;��N� Q8�Nl��̄�8Ba�:�������ǟ�U��[���^�9��Q�� �V�Z����3���^��� +�d����r�M�>|����U��9A��Bc���J�T�p����;i���@������ ��Ʉ�$���ϥ�אM�� h��iZ����د�nI�N���?�m��nŸ�N2,�M�� �� ��D��c!z����DZ��і���ل���m�e&fL� ��Dŋ�Yx�8hP�.�!�Kwi볐 ����98L~$},�7z�G,�=>1Gw$[���֞�ŷ���F&�H�= ��蔤��E^��L��C��(��?����-'�)�XaH�dܔ�x+n%*A�"��P�ynAM8��6����9�Y��_A8�9��ӊX#��Yl�Ϙk���N 3B���a +!���U�C�x\�F���P�4��U��Dp������<��:��0'������R�&c�ʺm�JXiϠ��e��ϛ����a�����Մ����E� +��{.hY������r�N߯,[<�P,K(� +[F�H��-�;*JR�6D ���XN��ɸ�l +t6$%bۅ�b��9%�"�.�y*�X�;z��˰��T�S���j��s�4��y�[<����쌆L+�1A�?#8��I�-�)f������ܡ��7�8EERzi�nxb-��,`�YiVI�A����f�R�Mj�̔may���0��Q���K��D� �z'�A�~R`��i`?�3���BU<Mܦ1h:g���>�'C����,�Y�/ [<��+K�� +[�H�`-� ��B��{1�,oQ`_~���� 1'w���TcL�]�d]p�j���i����4uq�QYǫ +n��{����UQ�â��ܿ ��CE��5���0t����ù�2��j��u�r���w%�ŇT<�����&?=Rs|���� ����M�WϢ� +�Q�nH,�.�h�(�&��vg���K���/f9�2�|:�f5v�j�N�3��.o��>���g0Q�d��7��.(���؞�� +ǒ�N�-k�H���Z�Qc��Q1C�[·�}q�G�LE:����0Es��::�JN���Ď{��h���Qx���t +R��f��s lc�l��L#�j���G�C�d�ѲR�3�K�x�����/�.=��qqc�)����|%���#�p: +�X��ʼ�76�0b6��Z�G%� � �B+1����"'p�e-���"���[uK�8t���Yn�0,��TҢ��$�(�%u�Nvz.���4���2sCK;Gl�d�P;���-���?� ��S~����@��u8v��?����5a_����I �`�b�ʼt����a��H�7`PO/yB3����>)bPxv�EQ�Njwxm�H��DJsP��=��p��������w(��E�}�!_1���/d�S6������w5�-�����?>�~Kz�����y�����u���(�mM�A a嚽{7�M�����������L݀?� Bhgݐ������k�ݡ��L"r �f���n�9~�?���A��AO�-�H��A[�?�pe#���8r���]csԱG�tm�0�*f2�xQ�X4~ۋ�Q�ND.�yV��R��_lČ���q�;-����LN�*��DN�3^��K�>eU��˿G;���Ul����<)��դb�w▽ S'��[ҳLp����z\s��0z*��TE�endstream +endobj +3009 0 obj << +/Type /Page +/Contents 3010 0 R +/Resources 3008 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 2892 0 R >> endobj 3011 0 obj << -/D [3004 0 R /XYZ 71.731 648.224 null] +/D [3009 0 R /XYZ 71.731 729.265 null] >> endobj 3012 0 obj << -/D [3004 0 R /XYZ 89.664 625.409 null] +/D [3009 0 R /XYZ 81.694 708.344 null] >> endobj 3013 0 obj << -/D [3004 0 R /XYZ 71.731 623.252 null] +/D [3009 0 R /XYZ 81.694 708.344 null] >> endobj 3014 0 obj << -/D [3004 0 R /XYZ 89.664 607.476 null] +/D [3009 0 R /XYZ 484.554 708.344 null] >> endobj 3015 0 obj << -/D [3004 0 R /XYZ 71.731 592.368 null] +/D [3009 0 R /XYZ 71.731 680.284 null] >> endobj 3016 0 obj << -/D [3004 0 R /XYZ 89.664 576.592 null] ->> endobj -1457 0 obj << -/D [3004 0 R /XYZ 71.731 569.454 null] ->> endobj -382 0 obj << -/D [3004 0 R /XYZ 194.2 526.356 null] +/D [3009 0 R /XYZ 81.694 664.508 null] >> endobj 3017 0 obj << -/D [3004 0 R /XYZ 71.731 517.534 null] +/D [3009 0 R /XYZ 81.694 664.508 null] >> endobj 3018 0 obj << -/D [3004 0 R /XYZ 71.731 489.689 null] +/D [3009 0 R /XYZ 71.731 662.351 null] >> endobj 3019 0 obj << -/D [3004 0 R /XYZ 71.731 474.745 null] +/D [3009 0 R /XYZ 81.694 646.575 null] >> endobj 3020 0 obj << -/D [3004 0 R /XYZ 71.731 425.694 null] +/D [3009 0 R /XYZ 81.694 646.575 null] >> endobj 3021 0 obj << -/D [3004 0 R /XYZ 71.731 411.303 null] +/D [3009 0 R /XYZ 71.731 631.467 null] >> endobj 3022 0 obj << -/D [3004 0 R /XYZ 71.731 406.322 null] +/D [3009 0 R /XYZ 81.694 615.691 null] >> endobj 3023 0 obj << -/D [3004 0 R /XYZ 89.664 384.847 null] +/D [3009 0 R /XYZ 81.694 615.691 null] >> endobj 3024 0 obj << -/D [3004 0 R /XYZ 71.731 382.69 null] +/D [3009 0 R /XYZ 71.731 600.583 null] >> endobj 3025 0 obj << -/D [3004 0 R /XYZ 89.664 366.914 null] +/D [3009 0 R /XYZ 81.694 584.807 null] >> endobj 3026 0 obj << -/D [3004 0 R /XYZ 71.731 364.758 null] +/D [3009 0 R /XYZ 81.694 584.807 null] >> endobj 3027 0 obj << -/D [3004 0 R /XYZ 89.664 348.982 null] +/D [3009 0 R /XYZ 71.731 551.766 null] >> endobj 3028 0 obj << -/D [3004 0 R /XYZ 71.731 310.028 null] +/D [3009 0 R /XYZ 213.707 515.068 null] >> endobj 3029 0 obj << -/D [3004 0 R /XYZ 89.664 292.195 null] ->> endobj -1458 0 obj << -/D [3004 0 R /XYZ 71.731 272.105 null] ->> endobj -386 0 obj << -/D [3004 0 R /XYZ 150.026 229.007 null] +/D [3009 0 R /XYZ 71.731 512.912 null] >> endobj 3030 0 obj << -/D [3004 0 R /XYZ 71.731 216.569 null] +/D [3009 0 R /XYZ 71.731 497.968 null] >> endobj 3031 0 obj << -/D [3004 0 R /XYZ 366.767 207.448 null] +/D [3009 0 R /XYZ 210.667 476.812 null] >> endobj 3032 0 obj << -/D [3004 0 R /XYZ 395.819 207.448 null] +/D [3009 0 R /XYZ 76.712 460.174 null] >> endobj 3033 0 obj << -/D [3004 0 R /XYZ 396.191 181.545 null] +/D [3009 0 R /XYZ 128.518 416.629 null] >> endobj -1459 0 obj << -/D [3004 0 R /XYZ 71.731 166.437 null] +3034 0 obj << +/D [3009 0 R /XYZ 76.712 380.269 null] >> endobj -3003 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F44 1994 0 R >> -/ProcSet [ /PDF /Text ] +3035 0 obj << +/D [3009 0 R /XYZ 81.694 362.336 null] >> endobj 3036 0 obj << -/Length 1672 -/Filter /FlateDecode ->> -stream -xڭXK��6���-2�b%�K�I��C�^��6�VW�\Iή��;��iy�"�� g�o��W��U�$�AfB��j{��V{��ӝ�.������>�*Y�6����D�e�$�"��j�����N���<'4~��2o`?/��������yQ��_�_�>m:�Q��, n^����'��� ����^"��7�D*|�V�:h��O����ep%���o�V��/#�N~���ZF�9��N�l�>��CK���9��U[Ѩ�'�8��R����s�i�O)�/��\옗�}ϓ/�|���a-=��~�j=>U�B��t�ɫ�6��ރ��V��F��}� -^� �YDh��C���p��H��\�&��ZQ*E_�WT�z?~�3E�H����=-��U��:C�i,�-�Zx�i�Z�c���Ӂ'����B���Y$"x�����:?�֜ɖ�o^���S\�|R�wSgH2p1�d&�]�H� ���� ��/���L�qxM�t�d'lQ��Blqc��8Q+0%�a�قzZ�X2�@�8���s۪�Ќ5z�CQm� �u�q습�*��gf}>ш>!��fc[cݲ�/չ��dw�s��}��0���#��lra��v�!�;�,tIsżВ�����K�3�C�����Lh������@�,�z�I9bk�Ƽ4�X��x��c.�!*�*[��]t�H~E�8����u�����Z;����l��`�֪X�[� ,�����6�Yr0K���KvE֫vK�������(�n�I��T;��C!��6r=�"rLBIz ���ב�!{�v��MȌ��E9,ZA@�M���"���.7Of�3�B�>9q��k,�A�"��z�E=0 �/\��\��z�!{��DNL�abCc2Ї��˧fD�:��'�p�5�.��h_ј�m5a���t���J� Ԩ�U�%�����=--kv���N����l'��het�����Ɔ=k�����d[Mᒵ�P̄��%k�$x�h�Z��z�Znɞ�Eٿrʌ#��e;��Wc�/�b1&�>T�UT�1*�����`�+�q�T���0Ш!�V�XV7Y�Z��x���� -|���:���]���gٱق1�� -�D����)P� �y�#iۣ�����3��)�@�E����m���:�(�_m�|��23�@���ȷ���E���ʟy�0�ج�"�ț��\������$W�K)B�q|��&�; f�v3�� �Gq'�[HSt66��^�����ڮS��Ue�P�Ӟ�qo�@�Ly�\�>�����H�5��c����Uо�ڟ��⻠5v%X�Oy�]@]B��e��P�[Bݒ��;��!xPݛuف��)}�k0�6�C -(��`�A��z��*�g];��2����}�o����o�n^&�_�&G\c[�~OP/���D"El���:�����0`���:��9���O�" �]�Q��s�p2�cH��L�<����[�)���oYԠw�%��8��� -�o`�$���!�ݿ�MK��V%6�e�B���]&PSx�u�X�m��Nзc�^��������Ssԕ��E��w4rMDitI8=�4A�ӧX<boжj{8�^B����$��A��O踘<�,��9��u)fendstream -endobj -3035 0 obj << -/Type /Page -/Contents 3036 0 R -/Resources 3034 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3001 0 R +/D [3009 0 R /XYZ 81.694 362.336 null] >> endobj 3037 0 obj << -/D [3035 0 R /XYZ 71.731 729.265 null] +/D [3009 0 R /XYZ 71.731 347.228 null] >> endobj 3038 0 obj << -/D [3035 0 R /XYZ 71.731 741.22 null] ->> endobj -390 0 obj << -/D [3035 0 R /XYZ 235.992 707.841 null] +/D [3009 0 R /XYZ 81.694 331.452 null] >> endobj 3039 0 obj << -/D [3035 0 R /XYZ 71.731 697.698 null] +/D [3009 0 R /XYZ 81.694 331.452 null] >> endobj 3040 0 obj << -/D [3035 0 R /XYZ 260.965 687.716 null] +/D [3009 0 R /XYZ 71.731 316.344 null] >> endobj 3041 0 obj << -/D [3035 0 R /XYZ 154.091 674.765 null] +/D [3009 0 R /XYZ 81.694 300.568 null] >> endobj 3042 0 obj << -/D [3035 0 R /XYZ 287.74 611.004 null] +/D [3009 0 R /XYZ 81.694 300.568 null] >> endobj 3043 0 obj << -/D [3035 0 R /XYZ 258.748 598.053 null] +/D [3009 0 R /XYZ 71.731 298.411 null] >> endobj 3044 0 obj << -/D [3035 0 R /XYZ 276.999 598.053 null] +/D [3009 0 R /XYZ 81.694 282.635 null] >> endobj 3045 0 obj << -/D [3035 0 R /XYZ 311.022 598.053 null] +/D [3009 0 R /XYZ 81.694 282.635 null] >> endobj 3046 0 obj << -/D [3035 0 R /XYZ 76.712 580.12 null] +/D [3009 0 R /XYZ 71.731 267.527 null] >> endobj 3047 0 obj << -/D [3035 0 R /XYZ 89.664 562.187 null] +/D [3009 0 R /XYZ 81.694 251.751 null] >> endobj 3048 0 obj << -/D [3035 0 R /XYZ 208.796 562.187 null] +/D [3009 0 R /XYZ 81.694 251.751 null] >> endobj 3049 0 obj << -/D [3035 0 R /XYZ 71.731 560.03 null] +/D [3009 0 R /XYZ 71.731 223.691 null] >> endobj 3050 0 obj << -/D [3035 0 R /XYZ 89.664 544.254 null] +/D [3009 0 R /XYZ 81.694 207.916 null] >> endobj 3051 0 obj << -/D [3035 0 R /XYZ 178.191 544.254 null] +/D [3009 0 R /XYZ 81.694 207.916 null] >> endobj 3052 0 obj << -/D [3035 0 R /XYZ 284.412 544.254 null] +/D [3009 0 R /XYZ 71.731 179.856 null] >> endobj 3053 0 obj << -/D [3035 0 R /XYZ 71.731 542.097 null] +/D [3009 0 R /XYZ 81.694 164.08 null] >> endobj 3054 0 obj << -/D [3035 0 R /XYZ 89.664 526.322 null] +/D [3009 0 R /XYZ 81.694 164.08 null] >> endobj 3055 0 obj << -/D [3035 0 R /XYZ 89.664 513.37 null] +/D [3009 0 R /XYZ 71.731 148.972 null] >> endobj 3056 0 obj << -/D [3035 0 R /XYZ 202.639 513.37 null] +/D [3009 0 R /XYZ 81.694 133.196 null] >> endobj 3057 0 obj << -/D [3035 0 R /XYZ 71.731 511.931 null] +/D [3009 0 R /XYZ 81.694 133.196 null] >> endobj 3058 0 obj << -/D [3035 0 R /XYZ 89.664 495.437 null] ->> endobj -1460 0 obj << -/D [3035 0 R /XYZ 71.731 459.572 null] ->> endobj -394 0 obj << -/D [3035 0 R /XYZ 194.361 420.199 null] ->> endobj -1461 0 obj << -/D [3035 0 R /XYZ 71.731 417.008 null] ->> endobj -398 0 obj << -/D [3035 0 R /XYZ 152.762 385.729 null] +/D [3009 0 R /XYZ 374.742 133.196 null] >> endobj 3059 0 obj << -/D [3035 0 R /XYZ 71.731 379.602 null] +/D [3009 0 R /XYZ 71.731 131.039 null] >> endobj 3060 0 obj << -/D [3035 0 R /XYZ 188.442 366.8 null] +/D [3009 0 R /XYZ 81.694 115.263 null] >> endobj 3061 0 obj << -/D [3035 0 R /XYZ 71.731 348.703 null] +/D [3009 0 R /XYZ 81.694 115.263 null] >> endobj -3062 0 obj << -/D [3035 0 R /XYZ 71.731 348.703 null] +3008 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F44 2037 0 R /F48 2049 0 R /F35 1567 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +3064 0 obj << +/Length 2458 +/Filter /FlateDecode +>> +stream +xڥYݏ�߿�͓�UQ�,�}��&��!Eq[E�E��ɒ���s����3��l�������p8�Z-"��E��L�o�x�.v��hq��_��P��d5�y�����^l��Z/^��$��,�,2�y/^���Gs�m�\�i萿�SY��e}`��a��ïeU��//�?}�2�Nunr��z��N�X/� +7iJ +�}Fy����� )���_le{� �tP\�AG�U6m5Z�Tn�c�q��(菖���X��j�q�`S8�M���IΦ5'˦�����ֶ XM�����[��ư�:߄�zlO���Qf;�eD��dw�,ס��u&I��pO��[F$�y��(pi����T]Ð����,�]3�}���Ɠ�G��f`��3=U�`_�t +:�����l��͞'�);�<Y����fnk������QE2�QX6uuaÈץ�6�Z�B��j�b�w�����Eٝq�(�g��,z��w�q-�&�(g���-�1��͓�t�tT���p>:9`X��shL�&FY�2>'�%��:Pݱ*!��o�$ +^���0�o1:��UR����W�$[u�K����le v���mk�4ǭ��DĈC[�F��f[�S� ���H,Lo����<|=��#��� +*k +F���;�N��3�����=�e_ʦ%��n����%�� #�n�|�f +�����e)ST����B�˩i�>����C��`&c״-��_����`��l��[�Q+V�����<��P=�P�YhO%�<�%�7��1�刃��'sa`+ +������Yj�]#p�kM�DtK�c��V�gBX^��B�]�L�a�qn.���lR�.�Hdzp�NB��ؙ�����:��6���AB��mCd��T��p����T<��/E�p<4v�&y +��r�v�(Z��鐣G:�Oz�,\��)�p��L��5�ng��`�*oB%tC{!#w#�~p����p�Vx�.�L�<e����ڶ��:��6�HR��v�D��_�[X�����1�"ik��r�� ���N��;}%����Bә�p��ipw�+�Fy�M�M�2������j;r�<�c�E�=߰aw����y��q���V� _�<���-J�@�Y�����8�;����湗'9���QW����(Y���V�us(���`Oً`k0����3C[[Q�! ��y����IX�e_Y����mk)�y�? ��7�����6DΒ��s� �0�D� �CF���$c�9^�C��@�į%dz�l�iia�][��M��s"�B8�'ZU�5���*XQ����I��>d�ݞ�p�$p݈��]ƙ��S��tv�`T��Qyr9>]9�c�#ș��Ybp����RXSP�t��8sw��R�KY�ab� ��ш2�BUw�<������Ro��%����p�iڅ�cz'�{�B��!� 4 )G;�I���'�C�~�������r +2�aCű�>`�P � +�thd�fq�j/� ��)�����M�����Z�r��ղ*��Cݹ�V�;�ݹϙ�vt7[*��SJ�i�,4�'���?O?�- +�c�����}"�=��6�J�h�b�����#'HEC���X�R&�c��`3�0��;p��ˇ:R�N��"�5WV?R�*}�]]Q��#t� +��|-F�\<�|�ҩQd���|�����`�o��o\�d���=���l&"�D8��w�JW�� +��}G�Fָ"H��(=�ᔹy�'S��9�og];CX�EHO�(��[+q�/��\;��mN�ύ��L�ݔ}��3�$R_�I��G3[Ye���ڷ�d���6�@ف�~��6GgTY}�����Uq'����Q��F��C�>�Nt��y EA��l~I�0R��da���T��a�^K/����PG?GQ�3��5.� +Ţ���m}�an%0�|��צ-�#��?�:�;�y|��qk+3���MR��{&.�J�ػ�c'�)5ٽ4����"�:Aiv�=��ѡe�y�@�A_�љ���ފK�?˒^���HE��:�U%�m��=^{x�5^Uܨ[mybz +�&�T��������t���}{��2I��V��H�0�7������>w�QX.��鍒�9:�dh��HV��*q�V �R0���N� +>i�Y���t�� M7u�6��Y2���Jq�־��]����ɒPž��.]oO,¹�3K�O6����ı��w�4#��y7���PX�7#1��?���.�J ��>�p�˄K+��X{�m�Q]����nг��y-]�g�?:���0��N�� +�� LA� ,w���L�ZU�������L�;�I��H��@'�@~Y���Q�No�Q�n-F�BYX^�xS��������x;L��fꝏm�k.ǣ<��!��I�*{�ו���Ǖ4��(�L\NH뗒{I�{0� endstream +endobj 3063 0 obj << -/D [3035 0 R /XYZ 71.731 337.72 null] +/Type /Page +/Contents 3064 0 R +/Resources 3062 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3084 0 R +/Annots [ 3068 0 R ] >> endobj -3064 0 obj << -/D [3035 0 R /XYZ 91.656 319.975 null] +3068 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [290.209 687.258 335.442 696.169] +/Subtype /Link +/A << /S /GoTo /D (parameters) >> >> endobj 3065 0 obj << -/D [3035 0 R /XYZ 71.731 307.856 null] +/D [3063 0 R /XYZ 71.731 729.265 null] +>> endobj +1481 0 obj << +/D [3063 0 R /XYZ 71.731 718.306 null] +>> endobj +374 0 obj << +/D [3063 0 R /XYZ 198.466 708.344 null] >> endobj 3066 0 obj << -/D [3035 0 R /XYZ 71.731 307.856 null] +/D [3063 0 R /XYZ 71.731 699.706 null] >> endobj 3067 0 obj << -/D [3035 0 R /XYZ 71.731 297.061 null] +/D [3063 0 R /XYZ 96.324 689.415 null] >> endobj -3068 0 obj << -/D [3035 0 R /XYZ 91.656 279.128 null] +1482 0 obj << +/D [3063 0 R /XYZ 71.731 630.471 null] +>> endobj +378 0 obj << +/D [3063 0 R /XYZ 233.494 597.161 null] >> endobj 3069 0 obj << -/D [3035 0 R /XYZ 365.427 279.128 null] +/D [3063 0 R /XYZ 71.731 588.523 null] >> endobj 3070 0 obj << -/D [3035 0 R /XYZ 71.731 267.009 null] +/D [3063 0 R /XYZ 436.119 578.232 null] >> endobj 3071 0 obj << -/D [3035 0 R /XYZ 71.731 267.009 null] +/D [3063 0 R /XYZ 71.731 565.181 null] >> endobj 3072 0 obj << -/D [3035 0 R /XYZ 71.731 256.214 null] +/D [3063 0 R /XYZ 71.731 550.237 null] >> endobj 3073 0 obj << -/D [3035 0 R /XYZ 91.656 238.282 null] +/D [3063 0 R /XYZ 300.596 538.68 null] >> endobj 3074 0 obj << -/D [3035 0 R /XYZ 363.424 238.282 null] +/D [3063 0 R /XYZ 71.731 499.128 null] >> endobj 3075 0 obj << -/D [3035 0 R /XYZ 71.731 215.368 null] +/D [3063 0 R /XYZ 71.731 427.233 null] >> endobj 3076 0 obj << -/D [3035 0 R /XYZ 273.602 202.416 null] +/D [3063 0 R /XYZ 71.731 401.33 null] >> endobj -1462 0 obj << -/D [3035 0 R /XYZ 71.731 172.364 null] +3077 0 obj << +/D [3063 0 R /XYZ 118.555 362.766 null] >> endobj -3034 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +1483 0 obj << +/D [3063 0 R /XYZ 71.731 289.144 null] +>> endobj +382 0 obj << +/D [3063 0 R /XYZ 226.737 250.866 null] >> endobj -3079 0 obj << -/Length 2299 -/Filter /FlateDecode ->> -stream -xڕYݏ����o'#6#R�%�����[E�\����EW�������e{�gj8������U��*�"��G�B����!\a�$sl�e;������/Q��E��V��U�" �U)�%j�X��xҗ�4�J� ��P�˺l�^�G"}��28�QV�^����~zt'Q*�,z�<�se��V2Q�C�>�Td�t�E"ά4�Ւ90���^�0�����7mעm 47��*R%N������? �9�[<S�ta�Aզ�E��q ��Se>nx�.h���u;�NS��x"�)�* ���Y�$8�Y�e ����5L��oieQ�P���Yj�������L�yBGL+ԎOv�h�J�_4���W��O�_,��x*�c�N��.ʽ�_|�3ٳ��aY�-��fY({0��oT�;d�,R����:'rM՚�ոu�d���y�K�%pæ^�4�;��>턼���r�瑚`M�k�ǃ�&�X��g�۸�}��{]�F�W���ࠫs���c%�wR���|��� ��3�Oz��%ܪ�~9��ӌs�,�c�>׳��0'p�r�.�?`��.����,Q�p �^L�ښ�S,�o�%\ݠ$���3p&x��mo�)�H�� -�Y��`���������L#{��`c����\,��iI�������� -�����:�?���^��뤗���1��!q6�*��.nΒE.d��\����2Q�0�M���ZR��2�����ld����"kK�m�0#�-a�ۨ�� ��g��(��2�H�0������"���6!��qlU�!@�0D���h��W"N��&18R�/z]mX����B�;�w�X���miL��п��Gf�?u��Dun�t�Ro������\{��$�_[�/�N��[��6�7|ܑ_#.�t�,l������DCYsY��ІJ��zq�'��J��KEûE0[2�R'�v�j��b��{���s��ο��n���z��O�/��0�E����%��Gs|Hxw�2�ʝ��E,������ -�1+r�< 䌶����'�w������ݣXD���JT�R�D�p=F*���i��c5����H�m e -4�;�v�����tP�:��w�* �`�gp���p�$辯D� -�ma�� S�������eI�?��3cW"�� g�x� �&~R:D N�#Y�铏�>s� B։�l�����b��� -�dk�Rw�-����j&A9S�T�{'�TZ�O� -����`r@��U/��l��PXHԵ���ȏ�'-W)�� -Q������0qy1L���9����t�H�ǎ�=7ei����� �/�Må o�4��������Ũne -3$#7{˩� �_�}��]�C@���`3�_�v�BG{�ք_���3���2͡W�+�b�{^b�Nx���\�BnU���,�]|K��w��K�Խ��q�W> FAU�D$���2�Ktf�_����sr�ޔoNT���l� ͼڞ��ɢ��ǩ ��i8+��1�,R�Z��KV�����B�+B�@r������1��"=n�=�?k�ɶ_���C��d=p���y" -�iɂ]ò>�����i�>()�Of�i���ƛB -�`��H�=�x��<wa�,x��.̯u��7t/Ģ�sĔ��(�j��8���U��h�F�M#��i^���Q;�3��*�Е����tc�c���W.p�̫��W�&P��? �cp��d�3�� �Zl���Z/'�+�W{�T�av�B�;����zl0��P�Rd�|��{8�,T���� ]���-����W�,5��fS邮�Ք3R���.�סU�?zӻG� q�����Hz)�-�~h��������W"z����C�(D���Yn�G^qwe͏d���6��H[2цH�lC� -},�H:j�V����:��ʖ�kנc��G��jr|A�M��ɦ���V�s��� ����m���G��56ʿ(z)Q�&p�&%��C��eך� �c��`!�,'�Wv�n3�LG��E��e|�ha]�|�k1P VL�nn$_����ʧI���[��/�k�s�*�dq4�p���w�&�ع�?b��(r������B>~+��.� -k���ZBGG�ڠ����������|��ϡ��ub�ͪ�!��Q$>�xo��[d�4�������Bq�� -� ��s ����,p��L�Ld2}�OC#��_����B��e���s������endstream -endobj 3078 0 obj << -/Type /Page -/Contents 3079 0 R -/Resources 3077 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3001 0 R +/D [3063 0 R /XYZ 71.731 242.043 null] >> endobj -3080 0 obj << -/D [3078 0 R /XYZ 71.731 729.265 null] +3079 0 obj << +/D [3063 0 R /XYZ 71.731 222.168 null] >> endobj -402 0 obj << -/D [3078 0 R /XYZ 244.6 707.841 null] +3080 0 obj << +/D [3063 0 R /XYZ 71.731 198.422 null] >> endobj 3081 0 obj << -/D [3078 0 R /XYZ 71.731 697.476 null] +/D [3063 0 R /XYZ 71.731 191.284 null] >> endobj 3082 0 obj << -/D [3078 0 R /XYZ 144.965 674.765 null] +/D [3063 0 R /XYZ 349.696 180.489 null] >> endobj 3083 0 obj << -/D [3078 0 R /XYZ 327.322 674.765 null] +/D [3063 0 R /XYZ 71.731 160.4 null] >> endobj -3084 0 obj << -/D [3078 0 R /XYZ 107.148 661.813 null] +1484 0 obj << +/D [3063 0 R /XYZ 71.731 129.516 null] >> endobj -3085 0 obj << -/D [3078 0 R /XYZ 134.893 661.813 null] +3062 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F32 1215 0 R /F44 2037 0 R /F48 2049 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +3087 0 obj << +/Length 2461 +/Filter /FlateDecode +>> +stream +xڭ˒۸��P�b�j��S$ק�=�:��8k��!�$a$��PҶ���F7��HMU*��F����'�/<����w�� s�u�����v���g�{F��ݼ�ˇ0\dn���E�yn�e�$�4��?�wGqjd��b� ]��*��*zۮ|����b����^=n:�q��Y���\��?q?F�=������/t#*I���*�j��})\����M p��D���#���k�p�}� ��&[�s�7Hz��� +��F�{�x�9M�c���TK-ˆ������:�sF�Gx%u:ѳ�T��.-݃K��3A�U[�lW'Q���9��Z�+2��Gi�Z`uXŎ(��#�@� +Q� (kq�n��7c�; +|�o�G~:Ui&���'�&��qd �iKа|W��EU.���sU�ѶT ��il��XVyu83��{�Q%�E�7ꔳ��+#�����[i.��}}s_A��,WA�|��>ɝ9-���O/��X���Ʒl��>Y�FU�뺀�w�������S���G��mK��zǎFX�h�4`(�0D-i���?=/8�����JF���6�����qo+�B;����˶��C����q�Fꥥj,�#T�3E���f!U/���/�Bŭ#Gh�c�A�`eù1;�hY���66�'+�j�3a�A�O��mc��k'��L������O������_��@7�iY���7&g���[�9��P6hLa� f4��l���.Yq?]���"�u�fY0^ �~�s�.Ƞt�{�+���:��u9v���M�d���K$��K�KvWz&��3Eđ +Cߌjb���2�UM�3�FA�Y�\�zY57x_��T )�u��߳zrU~����C5m���������i,]ĸ��gVc�B�Ʈy����/�"�Dz��:���*hf��p�� �+�2I�{�w�:�PO��=��߲)�d��qf_��F���y��~��`��0k����+?5�d��eE}���V-�� ��n^a�2�֔f�a�T+�yyG���������+?�l��5%|�t�@�����OG�Q��(�mt���� +;�������X/�������\~j1�s�H9W��\�XZ���w��9*��ܕ&�.��3��|JYc�2� � VN!�e +I1�qI��DIb�m o���ZQ턦j,����l���&���4��Y� ;믴dž��� +� �X]�cѼf����*��bI���#�L�w���Ӕm���:M�[ ��/;����qi��2։G.�p_��տH�F��9��:�T�y'�/�ࠫe���Y�Kp�+ʉ�\>|6�q6Ƈ��a��j�3��z�b�bك����J=�.��H�� h�6b��s���=�`�ϲ�&6�ɡFK-�'���=C��of�G<��AkD�bО��F��B���W���3|d������ *v���ӫ �����b�6����f��}cU!vl�i�U�jδ�]5pߣ�zMn��=�0�.Y[o�;�5����W����e� .h��gT�����-UJ^c�s؏�^�d�0�ۗ&��\�yy��h`�l��D >>��c�I�:���@7�褐��V7� ��$�$��W�$4\�T��NJ&�G3�L�B9�Ti)��f��]Zo,/s-�Z��-ݔ@ߕ��h�%�ڶ������� +�z�F9sx�P`�_t�˃#c?�!�ђ���`R� 6��U���b"�Xh�Oy@����w��wa�7�H�H���+{�N�@�]�a�7�Ά� ޮ�K��eS��0��Q��V������C������F��x��ƏL�����[�=�� �e�6&��>܅�'k�;���0�,�5�j���t��R��&��+KmΦ�)fE�� �����!�Jc���+������+�O�*��R��ۯ�r<K�_� +�k��倹>7X����7[��\kbQn���^lMn� ;��=�Uӧrp����嶙O��A��4�]? +o�Ǚ�)��l�'x����/���dwNe�ķ5֡�*�0n��^V�<�1Qd����0˨� 3.���qI��w����n����]2SKqs�q�m�n�6�s�@�ȍ#G�N"(��u�%~��ce��>��?}F�R���&���ԀۦE�I��#�ϛ�_�����b��px_@� �^�jf+Y����Wk���CP�s��(�p_�]9~��� +-�����è�[s��� +9�Ȃ*�z�a��"��ObŁI-�5zd�8��ưҭ)��X~��ޛOѸ]y7���v�j�����o��o�-�bje�0���2�N��A0�s��n����r��V;ۦs�m8��&E�+�l����ײ2���ls�� ���&f6�����?���i�oA�R?���`�r��`�,�;*�Z�s��^��/j�endstream +endobj 3086 0 obj << -/D [3078 0 R /XYZ 71.731 610.84 null] +/Type /Page +/Contents 3087 0 R +/Resources 3085 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3084 0 R +/Annots [ 3090 0 R ] >> endobj -3087 0 obj << -/D [3078 0 R /XYZ 120.869 600.045 null] +3090 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.731 682.402 110.234 691.313] +/Subtype /Link +/A << /S /GoTo /D (gloss-product) >> >> endobj 3088 0 obj << -/D [3078 0 R /XYZ 319.55 587.094 null] ->> endobj -3089 0 obj << -/D [3078 0 R /XYZ 448.374 587.094 null] ->> endobj -1463 0 obj << -/D [3078 0 R /XYZ 71.731 567.004 null] ->> endobj -406 0 obj << -/D [3078 0 R /XYZ 242.592 529.789 null] ->> endobj -3090 0 obj << -/D [3078 0 R /XYZ 71.731 519.424 null] +/D [3086 0 R /XYZ 71.731 729.265 null] >> endobj -1464 0 obj << -/D [3078 0 R /XYZ 71.731 507.507 null] +386 0 obj << +/D [3086 0 R /XYZ 179.498 706.118 null] >> endobj -410 0 obj << -/D [3078 0 R /XYZ 215 475.193 null] +3089 0 obj << +/D [3086 0 R /XYZ 71.731 697.295 null] >> endobj 3091 0 obj << -/D [3078 0 R /XYZ 71.731 466.556 null] +/D [3086 0 R /XYZ 71.731 651.518 null] >> endobj 3092 0 obj << -/D [3078 0 R /XYZ 71.731 449.126 null] +/D [3086 0 R /XYZ 71.731 609.739 null] >> endobj 3093 0 obj << -/D [3078 0 R /XYZ 361.806 438.331 null] +/D [3086 0 R /XYZ 71.731 594.731 null] >> endobj 3094 0 obj << -/D [3078 0 R /XYZ 490.942 425.38 null] +/D [3086 0 R /XYZ 71.731 589.749 null] >> endobj 3095 0 obj << -/D [3078 0 R /XYZ 71.731 412.429 null] +/D [3086 0 R /XYZ 89.664 568.992 null] >> endobj 3096 0 obj << -/D [3078 0 R /XYZ 71.731 392.339 null] +/D [3086 0 R /XYZ 71.731 566.835 null] >> endobj 3097 0 obj << -/D [3078 0 R /XYZ 320.794 381.544 null] +/D [3086 0 R /XYZ 89.664 551.059 null] >> endobj 3098 0 obj << -/D [3078 0 R /XYZ 71.731 374.406 null] +/D [3086 0 R /XYZ 71.731 548.903 null] >> endobj 3099 0 obj << -/D [3078 0 R /XYZ 89.664 353.649 null] +/D [3086 0 R /XYZ 89.664 533.127 null] >> endobj 3100 0 obj << -/D [3078 0 R /XYZ 219.624 353.649 null] +/D [3086 0 R /XYZ 71.731 525.988 null] +>> endobj +1485 0 obj << +/D [3086 0 R /XYZ 71.731 482.153 null] +>> endobj +390 0 obj << +/D [3086 0 R /XYZ 210.434 439.055 null] >> endobj 3101 0 obj << -/D [3078 0 R /XYZ 71.731 338.541 null] +/D [3086 0 R /XYZ 71.731 426.884 null] >> endobj 3102 0 obj << -/D [3078 0 R /XYZ 89.664 322.765 null] +/D [3086 0 R /XYZ 71.731 371.504 null] >> endobj 3103 0 obj << -/D [3078 0 R /XYZ 134.39 322.765 null] +/D [3086 0 R /XYZ 510.307 321.855 null] >> endobj 3104 0 obj << -/D [3078 0 R /XYZ 109.868 309.813 null] +/D [3086 0 R /XYZ 71.731 301.765 null] >> endobj 3105 0 obj << -/D [3078 0 R /XYZ 71.731 307.657 null] +/D [3086 0 R /XYZ 71.731 288.814 null] >> endobj 3106 0 obj << -/D [3078 0 R /XYZ 89.664 291.881 null] +/D [3086 0 R /XYZ 71.731 283.833 null] >> endobj 3107 0 obj << -/D [3078 0 R /XYZ 192.792 291.881 null] +/D [3086 0 R /XYZ 89.664 263.075 null] >> endobj 3108 0 obj << -/D [3078 0 R /XYZ 384.02 291.881 null] +/D [3086 0 R /XYZ 71.731 260.918 null] >> endobj 3109 0 obj << -/D [3078 0 R /XYZ 114.012 278.929 null] ->> endobj -1465 0 obj << -/D [3078 0 R /XYZ 71.731 256.015 null] ->> endobj -414 0 obj << -/D [3078 0 R /XYZ 172.607 220.548 null] +/D [3086 0 R /XYZ 89.664 245.143 null] >> endobj 3110 0 obj << -/D [3078 0 R /XYZ 71.731 211.911 null] +/D [3086 0 R /XYZ 71.731 242.986 null] >> endobj 3111 0 obj << -/D [3078 0 R /XYZ 389.41 201.619 null] +/D [3086 0 R /XYZ 89.664 227.21 null] +>> endobj +1486 0 obj << +/D [3086 0 R /XYZ 71.731 194.169 null] +>> endobj +394 0 obj << +/D [3086 0 R /XYZ 176.83 151.071 null] >> endobj 3112 0 obj << -/D [3078 0 R /XYZ 458.937 201.619 null] +/D [3086 0 R /XYZ 71.731 142.249 null] >> endobj 3113 0 obj << -/D [3078 0 R /XYZ 71.731 183.587 null] +/D [3086 0 R /XYZ 71.731 109.423 null] >> endobj 3114 0 obj << -/D [3078 0 R /XYZ 176.467 157.784 null] ->> endobj -1466 0 obj << -/D [3078 0 R /XYZ 71.731 140.683 null] +/D [3086 0 R /XYZ 71.731 98.528 null] >> endobj -3077 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R >> +3085 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R >> /ProcSet [ /PDF /Text ] >> endobj -3117 0 obj << -/Length 2713 +3118 0 obj << +/Length 2341 /Filter /FlateDecode >> stream -xڝko����� -}�<��ع��W#�"(��@�k�=�K���.��3�%����>pvvvvv�7��M�i� w�$ޔ�w��f����+!��hn�߽�17��'���ay��z�& 7���}�O��Pt��WA�9����c������Q7���<��n�b�����}������ͳ�M��J� ���F -h��n�$_�fn�b��J,@�����8�P�-�O�m������||�a���s(���|����xj<(��-BU�c���nU;��x�S���Z��3�O�F��f���5������N'�1@1�Y��V=C]����FƱ�2ⶁɺ��Z���=��P=~��1���ۯ���T �FӉ�3��Q3��<�l�����6�N�$H�\�����n�A�`R�exP�*G����?[��.P��R��W�hD�bO�2�,�}�)����9����ya�ざ )Z �q,��QѾ��ĝX�χ��f�c1N��t���|�ʃփ��\�ẅut�Ҡ!34Cq4K��I}�k�3a��� �> -�F/eW�j��m�\ +R�K\���v|�����)8�e�^Q?s� 'V�Y=7�͝�7f�|�����v���s�-�</�<�G�Cd -,��^�;�R�����z5��Ueƃ�c���.cН"� 5�A�����x5�:'�"o�U��([�0��0K�0��qY��k�ؑR�|e��iq9A�g��S.f�=��BX�C�/�=��1�ńF�A���A�VE/�%��������8N��Igg���E�O�cQ�S�CP�̷m����+���K]!�|�P�E9�<�ʰ�T�h���`� -���0�����g{b��P��a����n�Pl�B�S�BY�H{5�<k�9F�B{���Ը��8 -���o�P��\[�����ā胝~،0o!!���| -"Q�t-5��,@�s�F�=]�3�B�V�7��<�ϔ0�6H�d��3�-�7�b/�l��Ѧ�2�)�7�W̕&�O�2�}\oᣓ��4��;[h�9��GTJ�������8��[B려 ��kIR0��i٥y��Z]1ژaT,.ŴA+�N�]�]��S9B�V���L�����1B -���鰍��g��������/_�-��!�K�Arj���d�����h�%��U��c[6'�&� 2�~v¦)ǃ��|AG�s[�uݫ�- y�n"g�<�XgDX1X���A��&�5�eg46Ydb����#4~E�����-�(PZ�dj�pD�B�8!5�dg�^n'���P4��AZ����,����"��x�w��e6�����g\)L�,1�y?;�)�����}�00�i� 8�Ӕ��]((̢�F~'����t�Dß�^�۞������1P����8����c�UN<�:K�4�~u�YrT&wl��6�B���q4�s�h�ċ<rX��� ��U��8Gv@wl=ٷ/ڡ=2�;�%��ts`����V���Х -�ܽ��IqR1�s�o ��,��-����S�"�2��'�����"ߖ�S��6rHj��4"�6;�� -.�B��ᕨ$��v�Q.���U��bn����V��K�iQ!�Lc@�SgnZg�})O/b\���Z_?�7�3����s�O�~x��3��'@�%j��|�Y���I@T9]Q�ê�-Qc3����!�S��^��� �k���-R�{�\�I��##�x�4ld�:� �;{���e,7���N -����N���-Ϸ��F��<��ƿa��-�ee?X��)�����7E�Z-����$�a���n�EI&$��?q�\��\���e���1>2I+��v��U2T��L�����&!��+�]��� ��^M|�;N�f0][Aς��27�Å]x�$Ga���Z� ������K���'������ |�>D��q��0t�02��v��Ǟ8<yM���s`/dF�^��HjM��}kM�R#���J�K8��|�ZE��;%�e�s�jH�S�A�z��_�x��t�//tf7=@A�J�����.C�5x%��Yu�4ϗ���χ���j7�-G�F��4���������{l���H�3M�+r���H� 5������vR+�#qH 1~��p�k���D���D���^���f�����T� -]�%�tv�,�P#G� ��<�����됈��W���/=�@�k�μ����TK�%�R��`(������q��\c������".8���x.�]�������$?��;� *K����/�+p&i���t���`875`�-R2w������rb=�> �|Dz����]���,�ww_��aD/{Y�� �� ��#G�=��y7�e�����`��qP�OԠ���#�3�D&(�e�-_SGFu��вU�ja�(;��Q�@�N��W�լ�3q#lx�,���r.&$����ٟ -\$,oN�8d=6���kw�$]�.\2�$s���I6މ�q�q�C»��(�y�4��)f�9[�ı�G(�T;(� J��Ȃq�øw��z�8�1���m��Y�,��7�I���/F+��V)�x������[�|`m�U�}�}���,��Xѽ��F��{���h��������L���72�>Ä������]��;�Tendstream +xڕYY��6~�_a��ƶْ�s^�I2��b�2N��Nh����%�$���뷊U��C����bY�WE�]8��."WD>^"�0X��w���3�2ņI6#�o��_�\$" �b�_��#"'YD�q�-��V�U��f��g%}?d���[�� }{^�����P�߶�x�q��d$�X�n�b���b�9"���GH`w�ub!}�?� G`K�'p����D�����l^2+��-�~i��;jj,?fyGͺ��s�-�צ �P�����iw���Y��U�.����G��G4��hI�(�#5ޑ���d_�E���3;������[ު��<�4�Ug[<�������F��B��j'��*��5�Q���X�k���2ӟ�+u�����+��˕��,[�"/y6/��vU��O�[P���DС��p��#�@k�h�IP�|h�[YoxF�[����1��R��U������U%������B�"�U��U�\�Ѫ_9������`ճ�%�R��$t٦�ܭ=gu�Fkp@�p#��p��u8!�7B!Q��1/t+aG�t�p�A��5#J� +�hj,;`��k͎|��0y1���P%OV4�̉��C�}5.���nP��z����ҡ:Յ~��!�֞ˡC#�� �p�`9ڰ�a��yOfho�ys'^�p�6 ��j5è����;��j���{)uve�U�� A�`����\����B:��U�~O�� zJ/���'fu���&��rR�m]kŁ�_K�$��~���'���O*�����ۀj��s����Uz �����a�INk��j���:>��uEPL8h�y��� �ۀ�X����}B��:�}s��w1�N�J�!v�| +ff�|?��{Ԫ��k����?�?�g?�D��8�h��%�-b��z��d_�Eٟ�"�w���B�S��~��|?S'��h��If��;��Vߌ�+�7�2H^^���'R�����USBn��'�ړ�H�p^{�C�1�lepG��ڛ�}�v\Ȑ5%#[����)�6Na��y W�ǰ\-�՚�KMB"�f`� +�0D�0a�VMG���|"��c��Ĕ(�U4SWm��[�1CXv���e#���:��iW�+�dU�O;̈́����H/ +c�c.E�`��aS0`�ִ-ѽu�i�G�,��[��[jժ�2�\��hLR�J[� �-�LVX���#��t� ����P��w�H�fV��<���Ҥ8��L����@Cp]M���4 u t��Y��!e���^(.�����}gY-�ʃz��qǤ7�� +e9ԛ��ͣ`�$(��wd��s��؎�É�! NЪ��:T<Q���ăhD���f`3��L ��U�� �l$B�0 +��x�?�Pg�TGw>d���M���Z�4Xs��}���U9�<b'O����!��K�\o^���1͝A�q�o�`u�1 f��)T͈��u�#4�4�v�;3�a����=��Bц� ,�D:-��gϓ��t opX��� L���k����.���㵗bW���Z��)�#�x-����J8��Ku���ku�� ���LZ���ř�������9 �p�x�J4/��JS]wύ� �V�~�S����9�en� ���F�J.]��UsK�U�pԾ����u~�� 9�!�V��~��{�P;ˉ�E��ɉ%���^sRfKEuhw4�:�_h<�rC�NV�����/����:t�J���1 ͢���?�ѭ��l�{xa� �sx�x-m����E�|!���[&BF���A�}>Y�B�#���(������ �1xMQ����:lf�ܣЗ`�/<pԹ]�J���yO4�f�t$�7�4��֛͞���c��(��U�Ͱؙ���'�o,�HdV:>P�;a1ol���f��J������y� �k��Uw�zW +7q��>&�y�+j���,Jz�Ľ���u� ����O{��Hu� +A��& M��iH?���^��N����cT� S���b�J)�`�b<�yT�X�ً�Yo�3s��ؚw�b�7��u�Q�n��u�[`���-���3=��J�@��p���}`������黎2�H#_�^?-����^����Dt�(��(�]��c��h���lLqGmż:��Q>ff�*��w���L�5U��LH�d����R���5a��Z��x������04�]v*/{t���ū��{���Tw�e�Z�����t��f��SK_3����=?����8����x����I4ѣ_�nE��)endstream endobj -3116 0 obj << +3117 0 obj << /Type /Page -/Contents 3117 0 R -/Resources 3115 0 R +/Contents 3118 0 R +/Resources 3116 0 R /MediaBox [0 0 609.714 789.041] -/Parent 3001 0 R ->> endobj -3118 0 obj << -/D [3116 0 R /XYZ 71.731 729.265 null] ->> endobj -418 0 obj << -/D [3116 0 R /XYZ 249.377 707.841 null] +/Parent 3084 0 R >> endobj 3119 0 obj << -/D [3116 0 R /XYZ 71.731 697.476 null] +/D [3117 0 R /XYZ 71.731 729.265 null] >> endobj 3120 0 obj << -/D [3116 0 R /XYZ 133.174 687.716 null] +/D [3117 0 R /XYZ 71.731 718.306 null] >> endobj 3121 0 obj << -/D [3116 0 R /XYZ 311.772 687.716 null] +/D [3117 0 R /XYZ 89.664 708.344 null] >> endobj 3122 0 obj << -/D [3116 0 R /XYZ 175.111 674.765 null] +/D [3117 0 R /XYZ 71.731 706.187 null] >> endobj 3123 0 obj << -/D [3116 0 R /XYZ 71.731 654.675 null] ->> endobj -1467 0 obj << -/D [3116 0 R /XYZ 71.731 641.724 null] ->> endobj -422 0 obj << -/D [3116 0 R /XYZ 201.18 609.41 null] +/D [3117 0 R /XYZ 89.664 690.411 null] >> endobj 3124 0 obj << -/D [3116 0 R /XYZ 71.731 600.772 null] +/D [3117 0 R /XYZ 71.731 675.303 null] >> endobj 3125 0 obj << -/D [3116 0 R /XYZ 165.864 590.481 null] +/D [3117 0 R /XYZ 89.664 659.527 null] >> endobj -3126 0 obj << -/D [3116 0 R /XYZ 71.731 577.43 null] +1487 0 obj << +/D [3117 0 R /XYZ 71.731 652.389 null] >> endobj -426 0 obj << -/D [3116 0 R /XYZ 142.614 547.143 null] +398 0 obj << +/D [3117 0 R /XYZ 194.2 609.291 null] +>> endobj +3126 0 obj << +/D [3117 0 R /XYZ 71.731 600.468 null] >> endobj 3127 0 obj << -/D [3116 0 R /XYZ 71.731 541.958 null] +/D [3117 0 R /XYZ 71.731 572.624 null] >> endobj 3128 0 obj << -/D [3116 0 R /XYZ 71.731 509.121 null] ->> endobj -430 0 obj << -/D [3116 0 R /XYZ 166.016 478.401 null] +/D [3117 0 R /XYZ 71.731 557.68 null] >> endobj 3129 0 obj << -/D [3116 0 R /XYZ 71.731 471.323 null] +/D [3117 0 R /XYZ 71.731 508.629 null] >> endobj 3130 0 obj << -/D [3116 0 R /XYZ 511.114 460.468 null] +/D [3117 0 R /XYZ 71.731 494.238 null] >> endobj 3131 0 obj << -/D [3116 0 R /XYZ 106.042 447.517 null] +/D [3117 0 R /XYZ 71.731 489.256 null] >> endobj 3132 0 obj << -/D [3116 0 R /XYZ 71.731 440.379 null] ->> endobj -434 0 obj << -/D [3116 0 R /XYZ 156.761 409.659 null] +/D [3117 0 R /XYZ 89.664 467.782 null] >> endobj 3133 0 obj << -/D [3116 0 R /XYZ 71.731 402.461 null] +/D [3117 0 R /XYZ 71.731 465.625 null] >> endobj 3134 0 obj << -/D [3116 0 R /XYZ 71.731 378.775 null] +/D [3117 0 R /XYZ 89.664 449.849 null] >> endobj 3135 0 obj << -/D [3116 0 R /XYZ 266.731 378.775 null] +/D [3117 0 R /XYZ 71.731 447.692 null] >> endobj 3136 0 obj << -/D [3116 0 R /XYZ 71.731 352.872 null] +/D [3117 0 R /XYZ 89.664 431.916 null] >> endobj 3137 0 obj << -/D [3116 0 R /XYZ 71.731 345.734 null] +/D [3117 0 R /XYZ 71.731 392.962 null] >> endobj 3138 0 obj << -/D [3116 0 R /XYZ 244.236 321.988 null] +/D [3117 0 R /XYZ 89.664 375.129 null] +>> endobj +1488 0 obj << +/D [3117 0 R /XYZ 71.731 355.04 null] +>> endobj +402 0 obj << +/D [3117 0 R /XYZ 150.026 311.942 null] >> endobj 3139 0 obj << -/D [3116 0 R /XYZ 397.391 321.988 null] +/D [3117 0 R /XYZ 71.731 299.504 null] >> endobj 3140 0 obj << -/D [3116 0 R /XYZ 111.017 309.036 null] +/D [3117 0 R /XYZ 366.767 290.383 null] >> endobj 3141 0 obj << -/D [3116 0 R /XYZ 279.62 309.036 null] +/D [3117 0 R /XYZ 395.819 290.383 null] >> endobj 3142 0 obj << -/D [3116 0 R /XYZ 71.731 296.085 null] +/D [3117 0 R /XYZ 396.191 264.48 null] +>> endobj +1489 0 obj << +/D [3117 0 R /XYZ 71.731 249.372 null] +>> endobj +406 0 obj << +/D [3117 0 R /XYZ 235.992 212.156 null] >> endobj 3143 0 obj << -/D [3116 0 R /XYZ 345.153 296.085 null] +/D [3117 0 R /XYZ 71.731 202.014 null] >> endobj 3144 0 obj << -/D [3116 0 R /XYZ 71.731 288.947 null] +/D [3117 0 R /XYZ 260.965 192.032 null] >> endobj 3145 0 obj << -/D [3116 0 R /XYZ 226.957 265.201 null] +/D [3117 0 R /XYZ 154.091 179.08 null] >> endobj 3146 0 obj << -/D [3116 0 R /XYZ 485.41 265.201 null] +/D [3117 0 R /XYZ 71.731 171.942 null] >> endobj 3147 0 obj << -/D [3116 0 R /XYZ 71.731 245.111 null] +/D [3117 0 R /XYZ 220.591 161.148 null] >> endobj 3148 0 obj << -/D [3116 0 R /XYZ 109.396 234.317 null] +/D [3117 0 R /XYZ 71.731 154.01 null] >> endobj 3149 0 obj << -/D [3116 0 R /XYZ 143.754 234.317 null] +/D [3117 0 R /XYZ 89.664 133.252 null] >> endobj 3150 0 obj << -/D [3116 0 R /XYZ 388.886 234.317 null] +/D [3117 0 R /XYZ 299.943 133.252 null] >> endobj 3151 0 obj << -/D [3116 0 R /XYZ 134.644 221.365 null] +/D [3117 0 R /XYZ 71.731 126.114 null] >> endobj 3152 0 obj << -/D [3116 0 R /XYZ 226.941 221.365 null] +/D [3117 0 R /XYZ 164.608 115.32 null] >> endobj 3153 0 obj << -/D [3116 0 R /XYZ 71.731 208.414 null] +/D [3117 0 R /XYZ 287.74 115.32 null] >> endobj 3154 0 obj << -/D [3116 0 R /XYZ 146.719 208.414 null] +/D [3117 0 R /XYZ 258.748 102.368 null] >> endobj 3155 0 obj << -/D [3116 0 R /XYZ 71.731 203.313 null] +/D [3117 0 R /XYZ 276.999 102.368 null] >> endobj 3156 0 obj << -/D [3116 0 R /XYZ 71.731 157.44 null] ->> endobj -3157 0 obj << -/D [3116 0 R /XYZ 71.731 157.44 null] +/D [3117 0 R /XYZ 311.022 102.368 null] >> endobj -3158 0 obj << -/D [3116 0 R /XYZ 257.935 146.645 null] +3116 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 3159 0 obj << -/D [3116 0 R /XYZ 439.391 133.694 null] +/Length 1898 +/Filter /FlateDecode +>> +stream +xڭXM��6���-�d͈�V/�M�鴇����� [���,������ @��l'���̚A�@ʅr�J����"H�����/����d�����w�p��< ��"�}���" ���b]��}(N�j�� ��P��Sy���y��I�ἔ��ߪ���_�~X��0yޝ^g"Ȃ�*��ut} 9�~������t\�X\A .'��"I��c����|/̢��AQxJ�b��Rƞ����S}G��j���a�A�!���A���l5v�i �4��Q�f�Xgތ��ח#w����I�ES��x)'^09�p���Nb�d"���������4]���9k�!��������'�Ǣ>���G"����0���V��E7�a����p���Y������Oh��a�U��M42o� +�����uIJ{M�U��çV��mO��-wЩi�J7$�5��Ec��U�*:U>ҧ5����6�9��c!�H�d �N/n�[:sf����KթG��Oqe��{�sjWwOmB��}��:7��*8��&Z澾��;�/̢�_4��e{�$��k_QC��<aΝ�_�D��T�,z�}�f��yO� ���;D}�}�D�T��{v�a=�H��̼$����H�����)l�[�L.d$�Ȑ�JBz�4���2�B:Dԥ����瞚!h����hF��̀�0�t�K���2� gus"�9��e:[���E����*uA��ws:���*���#@%IeB���#�� ��� 6�D@ᘛ!6֏��#����(�#��o�?��~(p�����6��Ϭ��@�L�k$H��;�#�|�S w,�`v�A�=�����r�1DP(#��խ������VQ�:�L�;q��֬�!��h�o����H)��+��$��Z@�X/��E��t3W7ڐ�ׇ����I"b?�V�u�� +�U�_�=�¸&�D��A}U�$�c �Xd M�i۟���B�� �Uo�q�u(���|��-i��g�a�;� �ac�c��Z�:L��@0��Cue�R�-��2�&�<�跘NnSx�̀S��2����]O���XQ�!�y +i�F���6'��U]g�l�Z��Z��P4�����=x��Q�7U՝�v=sr�Ec��:8=�4��Ϙbq��A���Q5��4+��3�c9}��B�l�I���$}=���A4V�Id��6 ��B�!ݥ���Pڏ<��P�B��՛G�o�>(��V4�m�\��� O-XU�)6O�Gd=�@�,@�;ٙ�kfZq'Ս�284��"�A�Ѱ-ґ6��Ld��� �����/�m�+;��&* xC[��B<��m��a:�~բ3�Zf��c�����e;�&�33����a�_q���v����ZYo�P 7bM��5{�Ah�&�X��U��8�m��ۢ�Lg�f|�tl{v�?����Y�tREK�f�L�G�;��-�CGs���6��x%����qu�o0�.�T�Mqļ.H�6�1(/�y��Z7�v�d�-�pt��Nj��@L0�Vm�ܪ���Ա�j���ݫ���:R�����3-��6�B\������a<�黑@�Fl�9y��`r/�;^{S�F*r�7�\�0��;͘U�"Lc��B@k.��_G/�17Y���@��G���Ɇ����^��+�6h3��#a;��O�M��)��&�������%�D,��n��U2�T�g�6U*���>3i&�JBg٦ɑ���Z�m���٠)\n��A��6�#��ݔ��A�DҁGIj�!��Z�n���L�s�m�y3���2eÿp;6喋onXޑo#òIܺ��%�{�ڣ��U;�;�X#���n=Q�=����endstream +endobj +3158 0 obj << +/Type /Page +/Contents 3159 0 R +/Resources 3157 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3084 0 R >> endobj 3160 0 obj << -/D [3116 0 R /XYZ 146.138 120.742 null] +/D [3158 0 R /XYZ 71.731 729.265 null] >> endobj 3161 0 obj << -/D [3116 0 R /XYZ 222.467 120.742 null] +/D [3158 0 R /XYZ 76.712 708.344 null] >> endobj 3162 0 obj << -/D [3116 0 R /XYZ 281.244 107.791 null] +/D [3158 0 R /XYZ 89.664 690.411 null] >> endobj 3163 0 obj << -/D [3116 0 R /XYZ 435.614 107.791 null] +/D [3158 0 R /XYZ 208.796 690.411 null] >> endobj 3164 0 obj << -/D [3116 0 R /XYZ 71.731 100.653 null] +/D [3158 0 R /XYZ 71.731 688.254 null] >> endobj -3115 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F48 2006 0 R >> -/ProcSet [ /PDF /Text ] +3165 0 obj << +/D [3158 0 R /XYZ 89.664 672.478 null] >> endobj -3167 0 obj << -/Length 2266 -/Filter /FlateDecode ->> -stream -xڕYK��6��W��"� (PTrp�L��ح�'��� ���x��Ӎn�!�س�*h4Ѝ~|��+���>��!|����Z%�+�:��O���2�v�s{����0\�C��O���^V�P��������]���T�}�ޤe^����L���:���E������Տ��l��C~Q=dz�o���k��w;�^�Ǿ����c�C ������5��Z -��z�V����j�T�������w�^U��.�G�uY���{�٥����+������y���m -�R��i��D���B[ց�t���Lɣz)p��Q }���L'�w �oh'�D��Kg�М�� �1�@���Q�P�5Jg��h�Z� f!�VW�5:�h��>�Dv��C�3�&BA7t'uu���T�Z4�MctKlGs�[Ct���,?gϋ�@LD��D�>�|�Lc���*���(?�0��t�#uĈ��t��p � �&���p*�nfF-.=q��ɡÉ]OC`q��e/�P ��([ k+�3�x���Z��"�3!�pb��%��;j��|J�)R�S��Ϻl -��2�w�/�{`G�w�ms�Z� :����"8���L����`C˷/���ɶ��C�d�57~x�X����>3�2K�s�s�k1��0�����Fp�dz7[��`.̏�a��q�&���:��6%����t)M��B���+!�z�M,Ά�LCԺHi`��M����-܅�x�5 -���R���k4�.�u}����xj뒈��=�T ls��Je�AK�� �6j��VO����:7�8�^k= ]�$3�'�|�2��L�����?M��Fuv6�6E�qE���F�C����}��J#�Al��͆���+�-}�<w�_��x`�R� -;�,�"%)��&�s� -5�r����Vu�;������;��y��Ȑ���4�w��wjZ�f�52;�cq���J�=}�O�a�����}$n�wCɅ)�(c���v=��} @ mg<�8c���Br�נ~^}�4D �͟�A��������J���0͆FG0�# Ss�`q)z^�,h��¦���FW6YqBC��q����i4嬧f���� � hT���hJ��ߎ) -���\E�8�>oMY�5T�ؿa�Gu*��0��E��y�C��goL��gd�nt2��B?Sp����B,��ťc��H�@w�*����c^��fC����p�u ;�"�EX-5�2�ch� -��wD@�F�n0�Z���yz��Tt�H�;��*G�\#{gE��������r��������HQ���{�DI'2�Sg�ʛ��fРr��5�d�Bf��!�15O��ӂ���i0�� ����O�icX�q��[���|��8�j)��h�*�V�zvD�W�D�c�~ �Oa)Xȿ' -��a����G�2�����tr�G�L��r/gn�у��\�aT��-j(g\����d`JP�BD�~��͛A/L���S��<��-�8� -�09���ܶ&ٝJ�����f�,��1�����7xa�R���h���\�c�po���O�~��Vp�Mk� ���~۟��T�5���P���h���4b�cs�+Q�bh�$��l�+���4-8�H����Z[��9�]���T�sՂ�N� -��i��am��5}��2�z�_hu)�.��mp��G*D ��8.e\�(��~�ͩ���N �h�@̋s���rwG�_��Z/d��$����a���Ĵ��N\/�K�]�`�闞��#o��E#9T�pF��|4���d��^r/�{I��kCN�� �2��{'sr�W�Mk���>����-�h�д� 1��A�u����˸#}p���� ����exI2�b�c�82���S;���5�T����������u�/�g=�Y�r��'�F>�4�9W��!��Z�|�m&��g������ -�`�����U:ҷ����Sׄ -[&��� ���OPh�������� _ZMLAcR?�_Na�m��1�64쌹�7y?�>n��t,�'�<�fah��-��+����ha��{��+���.B�Yd�����7�K+lw����5���&�s�t�d<�c]z �x��$��Z/�NӴ���x��g5x�r�����.��`�ſ,�?�(�B�CЎ;��_T���Yl��endstream -endobj 3166 0 obj << -/Type /Page -/Contents 3167 0 R -/Resources 3165 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3001 0 R +/D [3158 0 R /XYZ 178.191 672.478 null] >> endobj -3168 0 obj << -/D [3166 0 R /XYZ 71.731 729.265 null] +3167 0 obj << +/D [3158 0 R /XYZ 284.412 672.478 null] >> endobj -438 0 obj << -/D [3166 0 R /XYZ 154.051 708.344 null] +3168 0 obj << +/D [3158 0 R /XYZ 71.731 670.321 null] >> endobj 3169 0 obj << -/D [3166 0 R /XYZ 71.731 701.265 null] +/D [3158 0 R /XYZ 89.664 654.545 null] >> endobj 3170 0 obj << -/D [3166 0 R /XYZ 71.731 644.419 null] +/D [3158 0 R /XYZ 89.664 641.594 null] >> endobj 3171 0 obj << -/D [3166 0 R /XYZ 71.731 644.419 null] +/D [3158 0 R /XYZ 202.639 641.594 null] >> endobj 3172 0 obj << -/D [3166 0 R /XYZ 71.731 613.534 null] ->> endobj -442 0 obj << -/D [3166 0 R /XYZ 142.923 582.814 null] +/D [3158 0 R /XYZ 71.731 640.154 null] >> endobj 3173 0 obj << -/D [3166 0 R /XYZ 71.731 577.629 null] +/D [3158 0 R /XYZ 89.664 623.661 null] +>> endobj +1490 0 obj << +/D [3158 0 R /XYZ 71.731 587.796 null] +>> endobj +410 0 obj << +/D [3158 0 R /XYZ 194.361 548.423 null] +>> endobj +1491 0 obj << +/D [3158 0 R /XYZ 71.731 545.232 null] +>> endobj +414 0 obj << +/D [3158 0 R /XYZ 152.762 513.953 null] >> endobj 3174 0 obj << -/D [3166 0 R /XYZ 224.195 551.93 null] +/D [3158 0 R /XYZ 71.731 507.826 null] >> endobj 3175 0 obj << -/D [3166 0 R /XYZ 71.731 518.889 null] ->> endobj -446 0 obj << -/D [3166 0 R /XYZ 171.774 488.169 null] +/D [3158 0 R /XYZ 188.442 495.024 null] >> endobj 3176 0 obj << -/D [3166 0 R /XYZ 71.731 481.091 null] +/D [3158 0 R /XYZ 71.731 476.927 null] >> endobj 3177 0 obj << -/D [3166 0 R /XYZ 181.465 470.237 null] +/D [3158 0 R /XYZ 71.731 476.927 null] >> endobj 3178 0 obj << -/D [3166 0 R /XYZ 380.939 470.237 null] +/D [3158 0 R /XYZ 71.731 465.944 null] >> endobj 3179 0 obj << -/D [3166 0 R /XYZ 473.597 470.237 null] +/D [3158 0 R /XYZ 91.656 448.199 null] >> endobj 3180 0 obj << -/D [3166 0 R /XYZ 509.52 470.237 null] +/D [3158 0 R /XYZ 71.731 436.08 null] >> endobj 3181 0 obj << -/D [3166 0 R /XYZ 191.511 457.285 null] +/D [3158 0 R /XYZ 71.731 436.08 null] >> endobj 3182 0 obj << -/D [3166 0 R /XYZ 71.731 450.147 null] ->> endobj -450 0 obj << -/D [3166 0 R /XYZ 224.367 419.427 null] +/D [3158 0 R /XYZ 71.731 425.285 null] >> endobj 3183 0 obj << -/D [3166 0 R /XYZ 71.731 412.349 null] +/D [3158 0 R /XYZ 91.656 407.352 null] >> endobj 3184 0 obj << -/D [3166 0 R /XYZ 71.731 375.592 null] +/D [3158 0 R /XYZ 365.427 407.352 null] >> endobj 3185 0 obj << -/D [3166 0 R /XYZ 71.731 355.502 null] ->> endobj -454 0 obj << -/D [3166 0 R /XYZ 170.649 324.782 null] +/D [3158 0 R /XYZ 71.731 395.233 null] >> endobj 3186 0 obj << -/D [3166 0 R /XYZ 71.731 317.704 null] +/D [3158 0 R /XYZ 71.731 395.233 null] >> endobj 3187 0 obj << -/D [3166 0 R /XYZ 129.576 306.849 null] +/D [3158 0 R /XYZ 71.731 384.438 null] >> endobj 3188 0 obj << -/D [3166 0 R /XYZ 279.855 293.898 null] +/D [3158 0 R /XYZ 91.656 366.506 null] >> endobj 3189 0 obj << -/D [3166 0 R /XYZ 349.928 293.898 null] +/D [3158 0 R /XYZ 363.424 366.506 null] >> endobj 3190 0 obj << -/D [3166 0 R /XYZ 71.731 273.808 null] ->> endobj -458 0 obj << -/D [3166 0 R /XYZ 148.701 243.088 null] +/D [3158 0 R /XYZ 71.731 343.592 null] >> endobj 3191 0 obj << -/D [3166 0 R /XYZ 71.731 237.903 null] +/D [3158 0 R /XYZ 273.602 330.64 null] >> endobj -3192 0 obj << -/D [3166 0 R /XYZ 71.731 205.066 null] +1492 0 obj << +/D [3158 0 R /XYZ 71.731 300.588 null] >> endobj -462 0 obj << -/D [3166 0 R /XYZ 176.855 174.346 null] +418 0 obj << +/D [3158 0 R /XYZ 244.6 263.372 null] +>> endobj +3192 0 obj << +/D [3158 0 R /XYZ 71.731 253.007 null] >> endobj 3193 0 obj << -/D [3166 0 R /XYZ 71.731 167.268 null] +/D [3158 0 R /XYZ 144.965 230.296 null] >> endobj 3194 0 obj << -/D [3166 0 R /XYZ 412.374 156.413 null] +/D [3158 0 R /XYZ 327.322 230.296 null] >> endobj 3195 0 obj << -/D [3166 0 R /XYZ 446.453 156.413 null] +/D [3158 0 R /XYZ 107.148 217.345 null] >> endobj 3196 0 obj << -/D [3166 0 R /XYZ 306.765 143.462 null] +/D [3158 0 R /XYZ 134.893 217.345 null] >> endobj 3197 0 obj << -/D [3166 0 R /XYZ 71.731 123.372 null] +/D [3158 0 R /XYZ 71.731 212.264 null] >> endobj -3165 0 obj << -/Font << /F33 1278 0 R /F48 2006 0 R /F27 1180 0 R >> -/ProcSet [ /PDF /Text ] +3198 0 obj << +/D [3158 0 R /XYZ 311.294 186.461 null] >> endobj -3200 0 obj << -/Length 2071 -/Filter /FlateDecode ->> -stream -xڥۮ�6��|��*6#��.���I�b��6�)Md���Ȣ#��z�~g8CI���ma$�Ù��)9��'g���!)E������v��ݓd�%�,'8o��^�WjV�2S���,�c���,W�(t2{����W��t�e��H _ou[;���@oNs��W7M5�����w�o�rQ�E�Ν|i1��B��O�Bh!��(Z^D?�/'�zZ|�Y��tD�^�O�T<[J��G*��M'�4���Ù�>�qb� � �F����[�ٮ�':�:�:"b*�u�t\жm��N�ṭ�"x���ovÍ�LG㺂��k�\���ت� Z��loN�?�N�� *�ZID���ʾB, |,�f�WܚuO6��'�a�)IԮ�ڞ��6�Kyw�(�e��p�/�LG����KG�D+RLH�#�4 �T͉Y�A�@y�N��`����t�J��W�$�N����~B��lܕ�V�" .�4�V��K�,M�:L��C ��-�4��#e�; �|5��)�f�ױH��P���iLO1 �����`���(*D���(RZG���iTu� �z8�*e�0��1�x�����8r �t�ΘvA��CGg�94[�:vƁ]�& ��8hj����ƛӎe���X�v��\�����u�W���=*�wqb@Ӎ�[q�7W�@2,h�n��g��6��A��h&�Yb�|�5�����g����Ǿ���M�R*��t��od�`n����o�l������"�P:T^���J5��l�����%�C���%t���,�,˴�D'C�@O�.d�*�B�J����s������{2�p���?��C��Ȁ3��,�;)���w8X�)�M���d��{�)F>(~�+�2�Y�Н,�q�2ʶ��+:Z���b+H��>��륬zn;ۅ����L�9���2�Kn���l����z)U&r��]D�Im��L���s ��h�pA(5�����]u<����[2��D���T���tjg��ȝ4��+����ς@�o<c�p�*���D1�xs'�`C�@�m���G͐N�czmqyY�ͅ��!�T'FZ��$(�_y -�f���[�vgx}긾MN��AN��3I��k23���%ۛ)����||�08}�K:U�ڳI����OU,T��F��d�iIE!�r�P'��LS)YN�����j�J@�E��X��H��̱���٣��ڸ~?��f�@�q_ �D�BB`V�� -� �<� x�^��pU!<�B f�H��� -`*�H?�ﰁ=�eZ�ô&�Lhտ��!d4<D����%�A/*�9��v(����v�d���쪆�瘂��t͚H�5��CM%C�C�ƕ�����\Ь��ͱ�%���::�A���_�����:��[ֱ�zT�c�����ն��shM= �rf|�L|����E�=A��M���T��������� �ڄ��3k�=~Ts�{0U��*<3��!���92��Gоi�U{���JK�3o@��j�t&R0��Ʈ�fm�m� �u �O��_ڎe*������.^�ko�3X��U�hFo���{���Y�)� �4���8��kV�, - -!����Ќ��ɿD��.R��'��k��\��:x�3���Ai�^t��`��h|�]�j[^|�����������§�!�C�\z ������ƿ��^��#�q�{�n_�����Cb�t��O^�%�N�͆'���X�KJ�h��:1L�]���wU%G9N�HnH0G. �n�S[ ��b� , Go�2�<Fa��\���;8���L�ٮ�J.��#��` ���U{�Ja� ��X#�Z�*@�3��6 ����Ha��!N���dp�����Lո/��R0u:�j�o��g�8|P>�L4�{o��B�X$v��fR��SuG���<�㶍�K����1u�� e9���j��2�*y�2�Ȳ���q��G^�}C�7b�'M� ���O�.��T��c��}�1Wi��,��_�d;��}��I!��f�O*����=��GM�-endstream -endobj 3199 0 obj << -/Type /Page -/Contents 3200 0 R -/Resources 3198 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3227 0 R +/D [3158 0 R /XYZ 71.731 166.371 null] +>> endobj +3200 0 obj << +/D [3158 0 R /XYZ 120.869 155.577 null] >> endobj 3201 0 obj << -/D [3199 0 R /XYZ 71.731 729.265 null] +/D [3158 0 R /XYZ 319.55 142.625 null] >> endobj 3202 0 obj << -/D [3199 0 R /XYZ 71.731 741.22 null] ->> endobj -466 0 obj << -/D [3199 0 R /XYZ 189.139 708.344 null] ->> endobj -3203 0 obj << -/D [3199 0 R /XYZ 71.731 701.265 null] ->> endobj -3204 0 obj << -/D [3199 0 R /XYZ 148.158 677.46 null] +/D [3158 0 R /XYZ 448.374 142.625 null] >> endobj -1468 0 obj << -/D [3199 0 R /XYZ 71.731 647.407 null] +1493 0 obj << +/D [3158 0 R /XYZ 71.731 122.536 null] >> endobj -470 0 obj << -/D [3199 0 R /XYZ 199.853 614.097 null] +3157 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F35 1567 0 R /F23 1201 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 3205 0 obj << -/D [3199 0 R /XYZ 71.731 605.46 null] +/Length 2045 +/Filter /FlateDecode +>> +stream +xڕXK��6��W�]�zZV.i�H��Ҡ���hz�e�RW]Q��E|g8C�,����p83�|� ��?��n�_���:^d���3߿�c�,����o߇�"u�u���繉�.�0p7q����p�sqnd�\��.��ٟ���@/�#�K�9�S��X����Żm�;7݄O�gy�� �a�F�>���D��/t7n�f%g�\{�ex��Rӧ:��{�����FKAE���X����GM��DE��������b��ԯ�C��0�],�Fd�IV����*�@;�D{t�@8�M�-#7J��y�oP:Zc4|�^������3�L��ya�{QK�Z�y߸�(u�~��w+uSt�٩���� +d�#y�$�ŀ�,Z�NՏ���*6�@F|��݈�4F�'�&/���@J-��vZ44�*^��� v��BY�3F�?AX�Ta�.@�h��T��ě^�x��cG��L�%��$�9(�j���)�\��M�d��p9EC��ri�q�!��,�OC�VCR$H�';}��jD�U��TDҒ��!�IUV�hz[2<�1\%�4�u�F�"����^[�Q:�%����)��۫�������> ?�װW�ykǮB��BCG��?�؋���1W>]���2� �6Pra�(�������e�a` V���v�3L��ϵB��8E5�$��6`hv.��#�] ln���)�^F�s7�_Lvs�C��x��'�3����I�HR�IXD|�?[ۈe5��1p�Dn�w��6��^Gs����n^��X����?�H��)��T)����4Ag�5� �_���(ZpZgp���<���\�B�Z9�!k��0�nD�t�(pD�p��Q��\`��Q@>��F�I3Jkt ���o&�q�}��Kkm;)��B�+\߁�̶\ +�����c���b k���6�:%#|'�.H�Bm�*Q�{�Ђm��i��<7a�,x��M�_�z�O螈Eݿq�� ��о� gu�͌����<�,�Ӽ������]�S�U!J��A�K��3�;�;��Ƽ��b�H�ji���Tڣz�[��=s�����*l�6��H�uɥ��-�M��J��Z�����2O�p�SS����-��7p8��Y>�{"u��3����&�I�&V�H���!!�}�]!~ie+�ew�y�l��bM$�A Ӆ�"�5�8b���ᑈ�,Ɓ��z`��;�Q��#������ந0Ì�>،�Q���6D�`�Ths)d�^×��wT֙pP��=*��}9U|q�z�c�U-�&\u������ohE�>hQh/6@��M�q�<� ���m.)�-�0��e�(-˃K���f鼲��^6#��Q؋�TzZ�~D�}�7q3��F��"+}7�mw|�nP0�~r�S�X��40��!%Y�J�G����\J���ut)� %m����` �t�<�0^H���.}rޅ�^I]�\�p�#B%1>E]XӋ*+�=[@� 1|��[�s'F��QܥW>��� W�ߋ�$�7 �a�Ρ8�]�2\O��A�t�#+?����*��?���`�n�uo!���#Fop. +����B�q�#�A��]u`��~w���$ ME�]}E���_����S���i�T�4�ԃޥNRpw�p�E�@�2�p�K��\k��\%}��I�m��6�$Е�w M�hv���#��k�8]������5$~y�1d"�5lY.����%�ɨ��t@!R/C�r�&x�~���ֵ(��m���"�e����9A�h�-���(˕Ғ5wu� ��F39j���.լ�"_�[��ju3~d�zr��2�U/xq��w�G�Ŧ��s��� I�cS'+�쁆��Ƣ.5���\����^����"��+�������(N�C��?�R����Jm^�7(���jwaDp��F����R��Qb{�����������~\��hs�����=�ճyl\/�B�S�[o�ך��"��endstream +endobj +3204 0 obj << +/Type /Page +/Contents 3205 0 R +/Resources 3203 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3084 0 R >> endobj 3206 0 obj << -/D [3199 0 R /XYZ 159.666 595.168 null] +/D [3204 0 R /XYZ 71.731 729.265 null] >> endobj 3207 0 obj << -/D [3199 0 R /XYZ 71.731 575.079 null] +/D [3204 0 R /XYZ 71.731 741.22 null] +>> endobj +422 0 obj << +/D [3204 0 R /XYZ 242.592 707.841 null] >> endobj 3208 0 obj << -/D [3199 0 R /XYZ 186.589 564.284 null] +/D [3204 0 R /XYZ 71.731 697.476 null] +>> endobj +1494 0 obj << +/D [3204 0 R /XYZ 71.731 685.559 null] +>> endobj +426 0 obj << +/D [3204 0 R /XYZ 215 653.246 null] >> endobj 3209 0 obj << -/D [3199 0 R /XYZ 71.731 562.127 null] +/D [3204 0 R /XYZ 71.731 644.608 null] >> endobj 3210 0 obj << -/D [3199 0 R /XYZ 118.555 523.563 null] +/D [3204 0 R /XYZ 71.731 627.178 null] >> endobj 3211 0 obj << -/D [3199 0 R /XYZ 232.228 515.099 null] +/D [3204 0 R /XYZ 361.806 616.384 null] >> endobj 3212 0 obj << -/D [3199 0 R /XYZ 378.496 491.786 null] ->> endobj -1569 0 obj << -/D [3199 0 R /XYZ 71.731 469.866 null] ->> endobj -474 0 obj << -/D [3199 0 R /XYZ 193.206 441.219 null] +/D [3204 0 R /XYZ 490.942 603.432 null] >> endobj 3213 0 obj << -/D [3199 0 R /XYZ 71.731 432.582 null] +/D [3204 0 R /XYZ 71.731 590.481 null] >> endobj 3214 0 obj << -/D [3199 0 R /XYZ 247.76 422.29 null] +/D [3204 0 R /XYZ 71.731 570.391 null] >> endobj 3215 0 obj << -/D [3199 0 R /XYZ 159.162 409.339 null] ->> endobj -1570 0 obj << -/D [3199 0 R /XYZ 71.731 382.275 null] ->> endobj -478 0 obj << -/D [3199 0 R /XYZ 209.453 339.178 null] +/D [3204 0 R /XYZ 320.794 559.597 null] >> endobj 3216 0 obj << -/D [3199 0 R /XYZ 71.731 326.74 null] +/D [3204 0 R /XYZ 71.731 552.459 null] >> endobj 3217 0 obj << -/D [3199 0 R /XYZ 428.19 304.667 null] ->> endobj -1571 0 obj << -/D [3199 0 R /XYZ 71.731 302.511 null] ->> endobj -482 0 obj << -/D [3199 0 R /XYZ 303.261 265.295 null] +/D [3204 0 R /XYZ 89.664 531.701 null] >> endobj 3218 0 obj << -/D [3199 0 R /XYZ 71.731 254.93 null] +/D [3204 0 R /XYZ 219.624 531.701 null] >> endobj 3219 0 obj << -/D [3199 0 R /XYZ 188.678 245.17 null] +/D [3204 0 R /XYZ 71.731 516.593 null] >> endobj 3220 0 obj << -/D [3199 0 R /XYZ 365.186 245.17 null] +/D [3204 0 R /XYZ 89.664 500.817 null] >> endobj 3221 0 obj << -/D [3199 0 R /XYZ 71.731 225.081 null] ->> endobj -1572 0 obj << -/D [3199 0 R /XYZ 71.731 194.197 null] ->> endobj -486 0 obj << -/D [3199 0 R /XYZ 253.251 156.981 null] +/D [3204 0 R /XYZ 134.39 500.817 null] >> endobj 3222 0 obj << -/D [3199 0 R /XYZ 71.731 146.616 null] +/D [3204 0 R /XYZ 109.868 487.866 null] >> endobj 3223 0 obj << -/D [3199 0 R /XYZ 71.731 134.7 null] +/D [3204 0 R /XYZ 71.731 485.709 null] >> endobj 3224 0 obj << -/D [3199 0 R /XYZ 71.731 129.718 null] +/D [3204 0 R /XYZ 89.664 469.933 null] >> endobj 3225 0 obj << -/D [3199 0 R /XYZ 89.664 108.961 null] +/D [3204 0 R /XYZ 192.792 469.933 null] >> endobj 3226 0 obj << -/D [3199 0 R /XYZ 71.731 106.804 null] +/D [3204 0 R /XYZ 384.02 469.933 null] >> endobj -3198 0 obj << -/Font << /F33 1278 0 R /F48 2006 0 R /F27 1180 0 R /F23 1173 0 R /F44 1994 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +3227 0 obj << +/D [3204 0 R /XYZ 114.012 456.982 null] +>> endobj +1495 0 obj << +/D [3204 0 R /XYZ 71.731 434.067 null] +>> endobj +430 0 obj << +/D [3204 0 R /XYZ 172.607 398.6 null] +>> endobj +3228 0 obj << +/D [3204 0 R /XYZ 71.731 389.963 null] >> endobj -3230 0 obj << -/Length 2741 -/Filter /FlateDecode ->> -stream -xڅM�۸�_�����ͨ������f��ם�����mq,6���L�__���e{��@ -�W���.�w1Q�G�tu���#���M���r?�y���/?��*��m�z|Z%A��|��#?K��c���R�:�n�4�b��wE�e���#�����;~WU%6�}�����4��y�(^�f~�E��(��(�~���1��8I�#D����P���(���6YM�8^�q��[^� ��4ig���gU)C�o[�tՙ>{3(�+h�Ѿn��U/�9V�!h��Fd��is��'�M�zg�=����F蠛BuJ7���N�Ѥ��`y�dq7P���(?����ޞa��$�� �X2X7��� O���v��%n�y`�D6�������yZ=�R���L�ƎM!@��9��@Q��Z1G6�{e�1�B>ٳ�ozҭ�'���� -kIp�xF���N� �0��Ib?��2�Mx�C�]��MQ�)m�mF9����RUe}F�e!��l -Y�gl7�>*D���#�M'kb���Y��@�)=��P�JW��8�x�(�AX�f!3-t7+�R����#O�ؠ�i�R_P�0�/e}�5P����o&����d�� 9��'�Y�:K �m���Q�J�Fʂf��4 '�v��W�% -�bT4YC ���J�����A�������Yu��;U��l;��rĩ�����3�Ѱ8N� ]����Z����L�Z�rHCyjuM���?=����_>��\�[?|�}}GsvǩtS`2FL�0g�5L�W��t�Х:���V�Vu�k��Z�m�e]g��a�/�o-���ݺ�af�m���\�P�!���E�C�Ouc�o�8rTf��q��j]�'�av�9>�y�Lq��0���l:��J������r�%�WS���Dm"hï����(=�������?�]�C+es+0�Ӣ��i�L9g�ָ��$�� ۽�� �-};���+�^������[�E�o�������ԯ�?8 ��4��)�Rh��H�-m�7��P�Yj��{�� -e�y�J�UgE��5v�����qnZ�Q(+߲�%���}�ޣ5�hn ���[�o����w4��a��������V�A -�f�"`d��Խ��;�{�#��5��ِs��}b��D�+ ��;1U�,�4�O�U��Ӄ��nނ�>}�4��Y�U����4z�5�����h\�F��K�-��7oe�n��V��q,L���H��j�*�B���2��y���Џ��e�qn�?� ���_�z���������s�]N��P�8���a��Ö;0����>��� ����US��GJ����Mx� �0��d�3f��k�;?��x��w�Nh��wj���-�<'C��ù�6+�R��/�&.�`6��f̡���w�!��O�W�s�!u��t�K^�;��d��'���BIU�D���_�k�0� �����������'�J`s� �J���?� -������!H*f���=��^��kOIB�:{��-�3��p����[G�46;�吹��\�g� �t�c�Z� �f>��-͛}�a`��k��w��i� �{�@Y��̓/��GivsC]�U�qԦ$�P(6pē<(��@�?QM>��^�f�p�d h@D�b��ܙ���ʜ*q���a��kES��e�J�L��L- -N|S3���u�'�T&�ӥ(�W�P�}e�:�z�T%t����VWY��3�(���i��殺� F�?��(�s�d� OjQKlM�����X�Ӵ,���DT$�I����=�����O���h�����-ӳQA�@��I2� !U0[?�)�N���yL�&������g�y=ͩ�3G�HV�8�%mYy�<���`�ʏ�ۦ�A������{�G�T��3��V,�p��>�./�(�?9M@C�ET�=���\�a�(K3���J5�V��1'��i�G�p`q�z.l��\\�Vq���vj5����]�j�L5`jx��y�M-��Ck���ͩ+��lt,�l]�ȹ��Q��A fϥ�%�! 9�GɍP�f�M�H�q��8�'�>�4";�Qۏ����:� -�J����j:�-�{Zn�I��g̯�p�e�O��pT������ �NZ��ڔDoz��q��fœm��=9�j� -�l���<�T ��Ԁ�*����9��م� CK�$���|}�s+� �E6 -��� xn���O����Q�n��Rc0�Ø��ī�ή h #�\��U��;��4��}GhY�>�֙E}GBh��0[���q��T`dU��Q��m�=(��^�zV������_cYp�����A�5n`���<�j�P{>�<|�c �� }C�&p�%����՚ 誯�6��`��Y��Фqܱ������+VL'7�g����8�H;�,��`0![�PngE!WN8R�x;����pK�B�D7T��o�-��+}3?��:f� "D<��(.3�� s�"�:ҥ��R�<�2`f�l�|FZ�ך�ZK$O�O���$�j����q�;�����%����� ��C���!05N�v��������� -�W�h��GO��]����L|��L����"��a/�^���9_O��d[���C��3�����K��'������Q.Z i�a�1l�%����%��� )�endstream -endobj 3229 0 obj << -/Type /Page -/Contents 3230 0 R -/Resources 3228 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3227 0 R +/D [3204 0 R /XYZ 389.41 379.671 null] +>> endobj +3230 0 obj << +/D [3204 0 R /XYZ 458.937 379.671 null] >> endobj 3231 0 obj << -/D [3229 0 R /XYZ 71.731 729.265 null] +/D [3204 0 R /XYZ 71.731 361.639 null] >> endobj 3232 0 obj << -/D [3229 0 R /XYZ 89.664 708.344 null] +/D [3204 0 R /XYZ 176.467 335.836 null] >> endobj -1573 0 obj << -/D [3229 0 R /XYZ 71.731 660.359 null] +1496 0 obj << +/D [3204 0 R /XYZ 71.731 318.735 null] >> endobj -490 0 obj << -/D [3229 0 R /XYZ 166.811 617.261 null] +434 0 obj << +/D [3204 0 R /XYZ 249.377 281.52 null] >> endobj 3233 0 obj << -/D [3229 0 R /XYZ 71.731 604.823 null] +/D [3204 0 R /XYZ 71.731 271.155 null] >> endobj 3234 0 obj << -/D [3229 0 R /XYZ 71.731 549.71 null] +/D [3204 0 R /XYZ 133.174 261.395 null] >> endobj 3235 0 obj << -/D [3229 0 R /XYZ 71.731 536.758 null] +/D [3204 0 R /XYZ 311.772 261.395 null] >> endobj 3236 0 obj << -/D [3229 0 R /XYZ 71.731 531.777 null] +/D [3204 0 R /XYZ 175.111 248.444 null] >> endobj 3237 0 obj << -/D [3229 0 R /XYZ 89.664 511.02 null] +/D [3204 0 R /XYZ 71.731 228.354 null] +>> endobj +1597 0 obj << +/D [3204 0 R /XYZ 71.731 215.403 null] +>> endobj +438 0 obj << +/D [3204 0 R /XYZ 201.18 183.089 null] >> endobj 3238 0 obj << -/D [3229 0 R /XYZ 71.731 508.863 null] +/D [3204 0 R /XYZ 71.731 174.451 null] >> endobj 3239 0 obj << -/D [3229 0 R /XYZ 89.664 493.087 null] +/D [3204 0 R /XYZ 165.864 164.16 null] >> endobj 3240 0 obj << -/D [3229 0 R /XYZ 89.664 493.087 null] ->> endobj -3241 0 obj << -/D [3229 0 R /XYZ 71.731 490.93 null] +/D [3204 0 R /XYZ 71.731 151.109 null] >> endobj -3242 0 obj << -/D [3229 0 R /XYZ 89.664 475.154 null] +3203 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 3243 0 obj << -/D [3229 0 R /XYZ 89.664 475.154 null] +/Length 2678 +/Filter /FlateDecode +>> +stream +xڝkoܸ�{~��E�=WR�)v��w�Ը�P�"�W\�I\H����(Q�p�9 g���^�^d���0D��ҋu�&�x�/} +ť�\:4Wwo�}���/V����" ?��,��<�.��y�[�t������}?�M�V=���QW�E�=���k����/o>ݍ��8�<~Q=Ks�_�O��m�' �����!��Y�}Q�F��>Gٴ0���?���m���<;[�@�� 2��ӟA��'�G�1C�BXV��VϺކǫ�X�f�^w��ְ(� �ژ�b��S�(����a?����X��E���N[�vPU��.�ԓ/?Qꩺ*y�G[�M�\��[oU�փl �4�{Z��`�6��-S����Z�>��u*����|��H��Q�k�8�vCeڟ���b�ą�� �u���r�g�1���t#0P�3�f���?�����|����C�c��V��_�^~�?�<��ABu��~���s�"r�}<H�=�\��QD ��HZ�Oe%��0j�mt;L�;`��4���v����k%�ĩ�����2a1�f/���bhy/#�)F!�f1:���Gd�����K�]�A?�Qb�v>�ؒ����k��*^���jA�Tf�!*�6��o��V�_���u�AX�h�b�Ѱ������.�8�:S��C/m�KV"�@�L엌x�V����v��&"��۷l�o��;0�C0�$��T�>�g��@�a��<G��Hቫ��M���=deo�A�4O>C7��V�A�?�����:]���[��4�c�'*�M�< +V���A���մug��A���zr +��U8��$5pYiڷ��!�p��4���ĆK��x^��#Z�D�V���טN��4�ix�D`^[[Pʛ��.5�V�X�z]!�����|c+��:��&�������y�qZ1��1�<�u�׃��p�۽E��-`v���]�\`E�/B�\��=��%1uo� +� {@aq�U�-.D7���0X�z���K +X<lA8�:M\��7���e��N�} v�en� +*B3����d=�1��� �FR +��'���''fx��Q4��=C�چ���, j����>Nfa�|[ƏLٓZ��&}T�iDic%4����A���LVR�B�Ó��B�w�X�-b��jj�m� +�f��w<�pL�Suz��Ʈ@'ʢ�z�/�gQL�Y��0~zr?�M�h!�T2�_{�m�"�M*�����d�ˀ3�8N��Rfy�7&,p��=յ��6<r�ER�1NF��i����(6���i�����b�)0�8�����r�� �Q��-���;�נ�ǻ=��G�T��r�j�7Qh�Vp ��T?�ƀ_�ʅ�v�$\�y!�N�p�e ���j����;mgx�$C��]͞Ӓ�b���4<�`��%wF�K�h�89��um =��2��"�gU��� +T��(�,8Y;I$_���֞�O��~��!���V�c?��(ig�yH�S�tz��.��Bfߋ��)���h��[��=jd�2)s+.�d���$�,�ݨ?(}��2���F���n����oP_`H���tb'y�N�A��*�����?���qsh�4� �}�� +a��xv��]�\b6�D��#8�ʒ���c[�Vp�mj���V'� 6�4�f�R9[�(6ԏ�15�8��`Ń#�())* 5,�Qd!p��f������)�<�K +��w�,�P#�&���>��N���!Q��Qw��Nt p�^�w����Rj�hIǒ��� +�����r7����k����ٖq%4ĉ��_�?=�fW���ћ�~Œ$���-�*�����P�@�<%M����<�a�Ԁ�|��E˷�Z�Z���V�uoQf�C�=��SI����f0��;���e/_q}B-�-��P����.U�w�)�w958����qpD�A-�-%�R=�M�ճ\D�|MݘR�������Qb�z�Z�^����j�-V( +�+q-lXP^LOR&��M��ʧ.�W{*��^ ��Mڭ�YH�r�ܙ�c@����d\c��!�mUTŷ$9��)V��Z��F�#�u�k�@.�X���q�øJ[�z�8�1ɛI����Y�W��?��EK�'��V)�x_�����[�t`k�U�}�}�����Xѽ��F�{�y�K��2(L��������Z=P_��@�ȓ�ܮ8��8�� +u�۪{=Te�16_�>�o6<J��8�:��5�c���'�<�P%�h���Ă�uW��X^LQy +TZ�^%���O~���� �,�pF�O+�B1����m ���D�eH�;��z�I����Rn!3�A̡�ن���qN�����ٲX����h,��R�n3Эc�����=O6$�W=�&T�©&ݖB<�V)v��ȱ�B_��Ն��W\赾���Vr�s�g�!*���덙��p�S�1z'ťG�^�0�wQ��6Z*8��Mb>���w0Rg��=���0�� �7V�|��u!�s�]��edn>�^�\����^��Z� �W��P���Ԑs�Zgz��d\��_��6��<�^�Yz"9�U:�r�,�F����X���(hendstream +endobj +3242 0 obj << +/Type /Page +/Contents 3243 0 R +/Resources 3241 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3084 0 R >> endobj 3244 0 obj << -/D [3229 0 R /XYZ 71.731 449.152 null] +/D [3242 0 R /XYZ 71.731 729.265 null] +>> endobj +442 0 obj << +/D [3242 0 R /XYZ 142.614 708.344 null] >> endobj 3245 0 obj << -/D [3229 0 R /XYZ 89.664 431.319 null] +/D [3242 0 R /XYZ 71.731 703.158 null] +>> endobj +446 0 obj << +/D [3242 0 R /XYZ 166.016 639.601 null] >> endobj 3246 0 obj << -/D [3229 0 R /XYZ 89.664 431.319 null] +/D [3242 0 R /XYZ 71.731 632.523 null] >> endobj 3247 0 obj << -/D [3229 0 R /XYZ 71.731 416.21 null] +/D [3242 0 R /XYZ 511.114 621.669 null] >> endobj 3248 0 obj << -/D [3229 0 R /XYZ 89.664 400.434 null] ->> endobj -1574 0 obj << -/D [3229 0 R /XYZ 71.731 393.296 null] ->> endobj -494 0 obj << -/D [3229 0 R /XYZ 163.591 350.199 null] +/D [3242 0 R /XYZ 106.042 608.717 null] >> endobj 3249 0 obj << -/D [3229 0 R /XYZ 71.731 338.028 null] +/D [3242 0 R /XYZ 71.731 601.579 null] +>> endobj +450 0 obj << +/D [3242 0 R /XYZ 156.761 570.859 null] >> endobj 3250 0 obj << -/D [3229 0 R /XYZ 71.731 295.599 null] +/D [3242 0 R /XYZ 71.731 563.661 null] >> endobj 3251 0 obj << -/D [3229 0 R /XYZ 181.725 284.804 null] +/D [3242 0 R /XYZ 71.731 539.975 null] >> endobj 3252 0 obj << -/D [3229 0 R /XYZ 71.731 251.763 null] +/D [3242 0 R /XYZ 266.731 539.975 null] >> endobj 3253 0 obj << -/D [3229 0 R /XYZ 71.731 182.024 null] +/D [3242 0 R /XYZ 71.731 514.072 null] >> endobj 3254 0 obj << -/D [3229 0 R /XYZ 71.731 138.189 null] +/D [3242 0 R /XYZ 71.731 506.934 null] >> endobj -1575 0 obj << -/D [3229 0 R /XYZ 71.731 120.256 null] +3255 0 obj << +/D [3242 0 R /XYZ 244.236 483.188 null] >> endobj -3228 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R >> -/ProcSet [ /PDF /Text ] +3256 0 obj << +/D [3242 0 R /XYZ 397.391 483.188 null] >> endobj 3257 0 obj << -/Length 2709 -/Filter /FlateDecode ->> -stream -xڝ]���}~E�8``�Z��=uw�w�õEo�=����J�c�,{g����H)���n��%�")��HE���L�Y����4Y�ǻ`���w�)6L��мy���wQ�*�"�V��U~�, -�< W�կ�ۃ< �_o�$�"����c���u�'Лq-��릑���{��d'Q�y��z��B�0Z��E� -�}��Ź�/�E�Ze��}��O�沭��W����3� ����&~����=�2O6M��A1�-�ˡ��ѷ�]#�ۢ㞹Y�S�Uc9h�T4҇nl*�m�g����R-CS�~�5O�;5ʧɣST뮬�P�����������1xs��Ȑ0�[����ڡ�F1ٮ�4";��DU5�Nr�c[�(���;Gb�@÷Fw�} ��. v �q?�T�,X�(?��d���$�_/�4�ڵ�RҼU���۳2��P�іE�q�`���Pe�0�W�|g<���Z$��i�DPh���a�㩯�F��y��R#H�O�M֍�6lb��,?>�Ud_Y�5�z[7x4��4��]J�WL��nP��r��e ��u�j�ɞW�<,�>w# ZE�%�h�x���Q�V�nG�z�����cp�����1S�����$ ���G�����Ot��Ŵ�Acx��6aC2�g����x�i`�Z�>qz_��=x?M��`{��q�v���pv�0_\3U��a�%SYKu;�&Rp:�ix6��vq�L�A�6-�j�U�@sM�bb"cBچmL�k��;lD�A�Ec�bf�I�+e{Nu�`rq"]v��d�i��ݱ��o�� �E�U��r����3KQdk��;Xӟ�8�Ik}���=Z��=E�(�0.������-Q��2���x����W��:����@��6�@kX6�cE_��f�w@���,�g�a�˽�� ��.�E&�;oƱ��G�X�-±�h�W�.��}Kߟ�B`���C�Ŕק��%sl���$u���n���Lـ��h`!ƥ%�� -� �'f�%C���S�p�F�c�ej�r�i��j�n��f��scIġ5�QG43nE�V�KebT�-�`RW:;ʅ�!H��ǒ>p�l�1����@(x�ތrvf��M�h���k�������m��V�P[M贠�=H��&]���8�ԪgD�.8B�������V �R\�nUc��N���(�c�)��m|�b=����-��4iMx�����)�q|?s�=;�4ўQ�3�x����:�9D�G1�9*�#�d~$��^pm�)���ҿZ��46L��Nn\���J���U� -h��*�&$�6RD���P�2�a��mOe�L�k��_'���({�e�7A���0�N�XS�'�?.�仮3 2��[F�0-^��#�i2�@�Û��e��<g�b�^����;B�3�1M�ݜ���������N�������U����j��T���uUMx��z�mQ�Y��� �-�Y:�7<wE�]���[���ea�M7� h"g�B"�/ -l]��Us -e���ٔ�w��}��p�j*��������UT�c��vP�F��Օ�]�mc@ҭB]�nlPEK�b���c#��%{e�4�6�ݲs�j�Z~��E���܌bā��h��z�#S6u�q�h�y�I��3��M+�#��4��WLd��������6؇�m�Χ�FH�e_�-s�����*�v�ȃi���a1�'����5��n3�dc���t;�e{0�;i�ͷ�|g۽R�����u<��m��q�ٯ��m4pLOC8��=�Ը=�����ɤ/N�.9��44 -X��L�hN�������v���;b --���p�ʹ�d�j�rG�х����#� �q-B.92��8�`��ג�Hd���K�fʎ�ܒ�+v=W�Y��ζD�ҖS\g�e����2�4�d٦v��ɉ�g7��;2}8ζ�g]��׃iM���*"䨙�^������@ -��ڊ�L�f � �L1rلP0�&��`n�U�@}(��.F�_]��{��ɾ���u[6ceE����Ώ8�����#*.BC]�dp]��RȉH�I�A{��"�������߂U������C�H�D@ �E���jw����HMs?J�K<h-�]��Xm��#�f? ��! -��Wxc�9E�/��6[��<gmD -�6�����ո��'Uֻg�)p.�S@���:���"�+����+Mh�G\�Ǟ��`����/���E�I�}�_q�߱A{��}�(�s** -َ�y�m��B�,K�c���?��sٙ�x�3��"�}��b��=���pll/j�.\j}��dbݵg�V$h�,���4/�9�Lj2�ߪ�[��EL -Qk�c�������KAvo�p�*��A�{���$pgP�NB�F{T�>T�"��'o v��0�s:7�z4f/���=�*�'|���I����]'N���S,���jib\ Xru�%�y������QUu��)�`�?^5��������L���H_9���;Y��(����٧��m��s�_z����_�f���O�zR�C�o�K9j�1P�O9��hzY5���w�����Գ��p��q�Xү�p��"{���3��o�I��ɲLL�E�~X���?�J�Dendstream -endobj -3256 0 obj << -/Type /Page -/Contents 3257 0 R -/Resources 3255 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3227 0 R +/D [3242 0 R /XYZ 111.017 470.237 null] >> endobj 3258 0 obj << -/D [3256 0 R /XYZ 71.731 729.265 null] ->> endobj -1577 0 obj << -/D [3256 0 R /XYZ 71.731 741.22 null] ->> endobj -498 0 obj << -/D [3256 0 R /XYZ 339.876 705.748 null] +/D [3242 0 R /XYZ 279.62 470.237 null] >> endobj 3259 0 obj << -/D [3256 0 R /XYZ 71.731 693.577 null] +/D [3242 0 R /XYZ 71.731 457.285 null] >> endobj 3260 0 obj << -/D [3256 0 R /XYZ 376.087 671.237 null] +/D [3242 0 R /XYZ 345.153 457.285 null] >> endobj 3261 0 obj << -/D [3256 0 R /XYZ 71.731 664.099 null] +/D [3242 0 R /XYZ 71.731 450.147 null] >> endobj 3262 0 obj << -/D [3256 0 R /XYZ 71.731 633.215 null] +/D [3242 0 R /XYZ 226.957 426.401 null] >> endobj 3263 0 obj << -/D [3256 0 R /XYZ 353.441 622.42 null] +/D [3242 0 R /XYZ 485.41 426.401 null] >> endobj 3264 0 obj << -/D [3256 0 R /XYZ 280.021 609.469 null] +/D [3242 0 R /XYZ 71.731 406.311 null] >> endobj 3265 0 obj << -/D [3256 0 R /XYZ 175.77 596.517 null] +/D [3242 0 R /XYZ 109.396 395.517 null] >> endobj 3266 0 obj << -/D [3256 0 R /XYZ 397.028 596.517 null] +/D [3242 0 R /XYZ 143.754 395.517 null] >> endobj 3267 0 obj << -/D [3256 0 R /XYZ 71.731 594.361 null] +/D [3242 0 R /XYZ 388.886 395.517 null] >> endobj 3268 0 obj << -/D [3256 0 R /XYZ 71.731 579.417 null] +/D [3242 0 R /XYZ 134.644 382.565 null] >> endobj 3269 0 obj << -/D [3256 0 R /XYZ 462.474 546.605 null] ->> endobj -1576 0 obj << -/D [3256 0 R /XYZ 76.712 517.015 null] ->> endobj -502 0 obj << -/D [3256 0 R /XYZ 232.492 477.643 null] +/D [3242 0 R /XYZ 226.941 382.565 null] >> endobj 3270 0 obj << -/D [3256 0 R /XYZ 71.731 467.278 null] +/D [3242 0 R /XYZ 71.731 369.614 null] >> endobj 3271 0 obj << -/D [3256 0 R /XYZ 71.731 455.362 null] +/D [3242 0 R /XYZ 146.719 369.614 null] >> endobj 3272 0 obj << -/D [3256 0 R /XYZ 71.731 450.38 null] +/D [3242 0 R /XYZ 71.731 364.513 null] >> endobj 3273 0 obj << -/D [3256 0 R /XYZ 89.664 429.623 null] +/D [3242 0 R /XYZ 71.731 318.64 null] >> endobj 3274 0 obj << -/D [3256 0 R /XYZ 131.167 429.623 null] +/D [3242 0 R /XYZ 71.731 318.64 null] >> endobj 3275 0 obj << -/D [3256 0 R /XYZ 71.731 427.466 null] +/D [3242 0 R /XYZ 257.935 307.846 null] >> endobj 3276 0 obj << -/D [3256 0 R /XYZ 89.664 411.69 null] +/D [3242 0 R /XYZ 439.391 294.894 null] >> endobj 3277 0 obj << -/D [3256 0 R /XYZ 300.451 411.69 null] +/D [3242 0 R /XYZ 146.138 281.943 null] >> endobj 3278 0 obj << -/D [3256 0 R /XYZ 450.128 411.69 null] +/D [3242 0 R /XYZ 222.467 281.943 null] >> endobj 3279 0 obj << -/D [3256 0 R /XYZ 71.731 409.534 null] +/D [3242 0 R /XYZ 281.244 268.991 null] >> endobj 3280 0 obj << -/D [3256 0 R /XYZ 89.664 393.758 null] +/D [3242 0 R /XYZ 435.614 268.991 null] >> endobj 3281 0 obj << -/D [3256 0 R /XYZ 135.13 393.758 null] +/D [3242 0 R /XYZ 71.731 261.853 null] +>> endobj +454 0 obj << +/D [3242 0 R /XYZ 154.051 231.133 null] >> endobj 3282 0 obj << -/D [3256 0 R /XYZ 174.159 393.758 null] +/D [3242 0 R /XYZ 71.731 224.055 null] >> endobj 3283 0 obj << -/D [3256 0 R /XYZ 250.842 393.758 null] +/D [3242 0 R /XYZ 71.731 167.208 null] >> endobj 3284 0 obj << -/D [3256 0 R /XYZ 341.239 393.758 null] +/D [3242 0 R /XYZ 71.731 167.208 null] >> endobj 3285 0 obj << -/D [3256 0 R /XYZ 467.454 380.806 null] +/D [3242 0 R /XYZ 71.731 136.324 null] >> endobj -3286 0 obj << -/D [3256 0 R /XYZ 71.731 373.668 null] ->> endobj -3287 0 obj << -/D [3256 0 R /XYZ 71.731 347.765 null] +3241 0 obj << +/Font << /F33 1306 0 R /F48 2049 0 R /F27 1208 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 3288 0 obj << -/D [3256 0 R /XYZ 71.731 332.821 null] +/Length 2050 +/Filter /FlateDecode +>> +stream +xڍ]��6�=�b��*{��ݥM��M�䢪j���B�����w��IN�=��c�x�M��/\lB��v�Z'��z,���I(WBr5���}��u-v�n-n��8�M�[l"�o�����^��M��RI�E>��YU�E��>0����EY��߷�<��v��D���+����oG��5���1��[?�C����w��ŗ�J<�R<�6��`q�1��`+���V�3��{D ������_����z��ψ5�a�-3>A�Q <-�m+���mE-�䆁����^��ΈDwKxGa���a��3m��}k+Fv������2L�^� ���AP�. I$��ZG���� U'�����~���e8�-iP�:�M��'���4AQ`b9�'3.�?ݛLv����=h��]?���0ˆII�0g���-��p%��X� +��/?�+ؖ�+�;�O�11�Pil]���c�����'��$8�`(���t-���k۟��u}p���h�8��Y�V8��N� u�zԎk�v&/��EȢ�l2w��VMiz���L��n8�������;����{�敩����2p�@��#�M�K��}�i~�� �l��IjXKjxo�=�"��?�� '��8լ��>0��=%�c��"FA�x��R]S���5�7��)�! ��S/N%�y�9��seG�$����{�4���g�F�B�_I��D��hMe���n6��/y qj��`B�AO��h�nĠ�`�꒜���>��|���f75 �e7^��_�|�#��<�b�K��x6Z�'��)(��j����1��w�;F`�F�nP��Zg�EvĪTv�;~d�p�X'rg���j�����%Ofv_'.�@���?;�>AS]Sf���)��^@!w�U �&1�$��|�&�H�pf&�V�3s�*�sR�UJ"MA#���%`��ީ��I��@�����ىY�ng�Fu�D�;�W�� +�#�k!�r��cN��"�NN.X�_0F� ȰɐK��yJg���J2��: nףH$CM��C.��J��<�ʙT�i��� ,���[��A�MY�� ��S��C�� ���09�sqM��Ip�?I9Ɇ�02�xB� Om�/�Xv[��Y�|*K��k��y�B��y��N���q)�a6��+��熧��U2jC%�*�ӕ@�"2$���W� �д)�%�������,+%��u���r��H]`i�%n�)��=�ł�N����͍� ���D߭��BJ�9h}��'�np�c�x ���8.d�$���R�c�OT��� +�<:Vv+�^��+��~�����䍴F�HM�k����B�ӽ��K��!7��3��}�-]t��j���B�fU <\C���Wg��b�5�!��TL�S��;���F-7�X;*}u�Q:��V^4��P�'Nb*]HV ��:�6��ɿ�;b�����"x89/Iɠ��E��݉g���ƛv|����K��Q2�C��h8呭Ky�}�r�T\�0y7�y��˹Z�a�Ԋ�o3�$6��9gG5zV48�=&��و��<eo/]*�5�F�͓���>EY�U��-,����2�/���d��ߺl���5�̑�7��9�7y?e�6n��|��gLR84P2��$�[�"�+��ĺHi�w%���gL_|P���8���EI���7�b�&����'�^'�&^bd�`ܻc]x ߵ��"�Ǡ:���4��14���9��=:U����uG`zl~��]8Ƨy���tk��c8�f�Mb1b1S�D�,�!�@�'�Ǵ<������Ya��lo��/P+�pϹs�LJW +d�hD��3^ +oH�rh9��0�\���Y5������!�R�8O�:���%��v�ŝ<aJ�]��9v���9'��/w">��B�:}�Lάcq"���4�Ə��A�6���H��`�����߆��~�If�������᷾d�9�}8Tendstream +endobj +3287 0 obj << +/Type /Page +/Contents 3288 0 R +/Resources 3286 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3318 0 R >> endobj 3289 0 obj << -/D [3256 0 R /XYZ 76.712 260.059 null] +/D [3287 0 R /XYZ 71.731 729.265 null] >> endobj 3290 0 obj << -/D [3256 0 R /XYZ 136.488 216.514 null] +/D [3287 0 R /XYZ 71.731 741.22 null] +>> endobj +458 0 obj << +/D [3287 0 R /XYZ 142.923 708.344 null] >> endobj 3291 0 obj << -/D [3256 0 R /XYZ 76.712 156.841 null] +/D [3287 0 R /XYZ 71.731 703.158 null] >> endobj 3292 0 obj << -/D [3256 0 R /XYZ 89.664 138.909 null] +/D [3287 0 R /XYZ 224.195 677.46 null] >> endobj 3293 0 obj << -/D [3256 0 R /XYZ 71.731 123.8 null] +/D [3287 0 R /XYZ 71.731 644.419 null] >> endobj -3255 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F44 1994 0 R >> -/ProcSet [ /PDF /Text ] +462 0 obj << +/D [3287 0 R /XYZ 171.774 613.699 null] +>> endobj +3294 0 obj << +/D [3287 0 R /XYZ 71.731 606.62 null] >> endobj -3296 0 obj << -/Length 2042 -/Filter /FlateDecode ->> -stream -xڍYK��6��Wxz�<�V�~��y��3�tR�iz�%��T�\I����P���3{ ���A�����^����qb� �Uzze����+�96̲�x�l_��ຫ،w�ݯ<�2C+^��cF���fo�ɹ�z�����}�Ny�7@����\ֶq��E��k�۫��N��f���y~d:���8�;��b��Vd���m� �-0�b���AQl����(]��N7/Y�}#u?��w^h\�"#ɲ�R�k�7^�|������"�[bi��HoD�&��T� Ac�>4��A<�- �4�%�Y���J� -T՚)�����X]���;��mlnj9g�2-.��(3��1oh$��0)����ӣ��ܝ:�}Ϣ>�m�T�K˲��(Dˋ.��Y澮@�i�0�.Ywe{��C��!�*H�+w隰e�F�c�䇒���/�jm�FCSi|��crk�C�K���R���V���|Z�x/ }Nⴣ`�F���9YE����/&�`ǯmXsmF(a(�kZv��H�g��7g�!rB�]D.����G-F��@�w.�4o�+g\ ���#w�x ��������O��Jŝ��e9�� ������x悡X�!�\0&t� ƒ���`h���UD���-Py�r��G;���8�����дꋮ�yf]�,T1�\=�u���o���lr�mt)$qJ�PAk�H� -POI+]���RK�.ER�1�������I� ���K0�["%�qi+P���BbP.Nʖ-���t����A��os����a��U�뫼;]�rNӷU������9���B�'��wՁ��Xp!Q�@Grr�s��fxfb�����x�3O5�����8�����.��e_�C�d�I�-��@�`QA�9���*1���2�H�m���.e`X�"ie��DJį�4�`��Z�0��4�1wr��� -�B db/��K�2��\���j���QC -�+Z��+i" }!gY�t��,A��S�7��ɻ�L���c�|�JZ%�e���I��J5��A}�,�u���gU<k��'�0;� 7h��]��6���s��8P�����Ⱥ��v��~�I;n{Ӝ���/Ww�g��+�ŮfB��꾤�F,��?��V��W��d�`@"^ׁo<����roѳ�z�8;������W<���+H��5��sK~e��o�o=���x�������KO�i� �t�ƮZrckB�x5g�n˹����ˁ�.z8���t�^3Q.����E���8QH�4ҫ�B���c^��S�4`*;.Xʕ7�Kt�u/R�B��дOJ�I�KQ�D���w��Xm��Dl�i\@�Z=,bò��z# e�(��"�U��ƏJ�7Wm\?0�(]���3�-Ų�KN躋�%�7b{|��_�#o>H/�rå�~���� -x@�b���o��<�cv��OT$I�I�l�/[�q�tYq�� -YuYO�L����/��ew��w��>ռ_��h��x���>�u�c�Y�PT8DO^ -�A����H�C�I�>)���:��,g�Y��L�t$X6&e+j%tw�L���ߧ.����Ǧ熋��x� �X�o���BzI���q�*^Ug��<�F�5F=�-�|�B���u|ѱ3 -C�H�Iy75����n�1m�f��r�=�����Oc�-�˩������r��iE�{oh&�_�§�V曅xn�:��t��2 g��!h�Tđд����Xq<�/�fHF�c;���=,zD�*y0�i_U?u�%�Vㅆ/K}����T�R]Ȕ�D�]�~'h���7R�&����J{XpB7.��R�٥����W7uI��Ռ��ҩ�D�Y�& ;��Y��W�-~�vD>���P��=m7B,�ϴ=�1�I��U���.g������ο+t��-��F�#~�p]� �\��zX���y����?>>�{�~��u����}����ݯ�Qդ?y����?�z����|'2-G �%ӛ�g�X��>}ƻendstream -endobj 3295 0 obj << -/Type /Page -/Contents 3296 0 R -/Resources 3294 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3227 0 R +/D [3287 0 R /XYZ 181.465 595.766 null] +>> endobj +3296 0 obj << +/D [3287 0 R /XYZ 380.939 595.766 null] >> endobj 3297 0 obj << -/D [3295 0 R /XYZ 71.731 729.265 null] +/D [3287 0 R /XYZ 473.597 595.766 null] >> endobj 3298 0 obj << -/D [3295 0 R /XYZ 71.731 741.22 null] +/D [3287 0 R /XYZ 509.52 595.766 null] >> endobj 3299 0 obj << -/D [3295 0 R /XYZ 89.664 708.344 null] ->> endobj -506 0 obj << -/D [3295 0 R /XYZ 304.825 651.039 null] +/D [3287 0 R /XYZ 191.511 582.814 null] >> endobj 3300 0 obj << -/D [3295 0 R /XYZ 71.731 640.674 null] +/D [3287 0 R /XYZ 71.731 575.676 null] +>> endobj +466 0 obj << +/D [3287 0 R /XYZ 224.367 544.956 null] >> endobj 3301 0 obj << -/D [3295 0 R /XYZ 71.731 628.757 null] +/D [3287 0 R /XYZ 71.731 537.878 null] >> endobj 3302 0 obj << -/D [3295 0 R /XYZ 71.731 623.776 null] +/D [3287 0 R /XYZ 71.731 501.121 null] >> endobj 3303 0 obj << -/D [3295 0 R /XYZ 89.664 603.019 null] +/D [3287 0 R /XYZ 71.731 481.031 null] +>> endobj +470 0 obj << +/D [3287 0 R /XYZ 170.649 450.311 null] >> endobj 3304 0 obj << -/D [3295 0 R /XYZ 71.731 600.862 null] +/D [3287 0 R /XYZ 71.731 443.233 null] >> endobj 3305 0 obj << -/D [3295 0 R /XYZ 89.664 585.086 null] +/D [3287 0 R /XYZ 129.576 432.379 null] >> endobj 3306 0 obj << -/D [3295 0 R /XYZ 71.731 582.929 null] +/D [3287 0 R /XYZ 279.855 419.427 null] >> endobj 3307 0 obj << -/D [3295 0 R /XYZ 89.664 567.153 null] ->> endobj -1578 0 obj << -/D [3295 0 R /XYZ 71.731 547.064 null] ->> endobj -510 0 obj << -/D [3295 0 R /XYZ 381.763 509.848 null] +/D [3287 0 R /XYZ 349.928 419.427 null] >> endobj 3308 0 obj << -/D [3295 0 R /XYZ 71.731 499.483 null] +/D [3287 0 R /XYZ 71.731 399.338 null] +>> endobj +474 0 obj << +/D [3287 0 R /XYZ 148.701 368.618 null] >> endobj 3309 0 obj << -/D [3295 0 R /XYZ 275.93 489.724 null] +/D [3287 0 R /XYZ 71.731 363.432 null] >> endobj 3310 0 obj << -/D [3295 0 R /XYZ 71.731 456.683 null] +/D [3287 0 R /XYZ 71.731 330.595 null] +>> endobj +478 0 obj << +/D [3287 0 R /XYZ 176.855 299.875 null] >> endobj 3311 0 obj << -/D [3295 0 R /XYZ 71.731 443.731 null] +/D [3287 0 R /XYZ 71.731 292.797 null] >> endobj 3312 0 obj << -/D [3295 0 R /XYZ 71.731 438.75 null] +/D [3287 0 R /XYZ 412.374 281.943 null] >> endobj 3313 0 obj << -/D [3295 0 R /XYZ 89.664 417.993 null] +/D [3287 0 R /XYZ 446.453 281.943 null] >> endobj 3314 0 obj << -/D [3295 0 R /XYZ 71.731 415.836 null] +/D [3287 0 R /XYZ 306.765 268.991 null] >> endobj 3315 0 obj << -/D [3295 0 R /XYZ 89.664 400.06 null] +/D [3287 0 R /XYZ 71.731 248.902 null] +>> endobj +482 0 obj << +/D [3287 0 R /XYZ 189.139 218.182 null] >> endobj 3316 0 obj << -/D [3295 0 R /XYZ 71.731 372 null] +/D [3287 0 R /XYZ 71.731 211.103 null] >> endobj 3317 0 obj << -/D [3295 0 R /XYZ 89.664 356.224 null] +/D [3287 0 R /XYZ 148.158 187.298 null] >> endobj -3318 0 obj << -/D [3295 0 R /XYZ 71.731 315.213 null] +1598 0 obj << +/D [3287 0 R /XYZ 71.731 157.245 null] >> endobj -3319 0 obj << -/D [3295 0 R /XYZ 89.664 299.437 null] +3286 0 obj << +/Font << /F33 1306 0 R /F48 2049 0 R /F27 1208 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +3321 0 obj << +/Length 2593 +/Filter /FlateDecode +>> +stream +xڝَ�6��o�7W"Ey�s���`1�!,d����%G��������|t�b0�Y,V�&-B�-�H�>:W:����!\�a���`< +������o��Y�*O�b�[�a��0_�F���ź�5�p(N�떏چ�Q�}W���^5{�?/�`�ߪ���o�>�G�֤*�̫�y���YD�ʭE�9�L�8&��ʔUK�࣫��2����g) +�=������1�T�s"���k�����=� ��1��;�����f�Àמ���Y<�\h1/��ιf����O�3m/�:fp�G��,j`ȣv���{�)M��E覼�/�}�:�岩� C�=�3��ҫd���2R�w<.��2�x����W� ���A�d4�jBp]5��q���<C{��y9@��i��F];`e�x�ı��}돇_%8���;�== r�o�|.��E���/�)���ୌvC����h�H�q~��1�u��i�H�-m),�=�1��kнɓ!�y��~1B�E�JLF;~n��Q:����7�1d2�&�I5ȷ>���ORgA�,t#�6*�bA�u��B��g,��b��d\��D���ί�\f�.1Ѝ��T<���Rۀ�����:��e��������B's˃�e���wÊQ*Ae p����trE��,�D���ɶh�v�]{'�&�\��7 +����b��;�0\�FHR���+�8w�:�pX D:{�m��0���}L� N�7m���b��]b�\E��4�Nж���)E�w2?w���� �bȹa&)�C�f�T��nN�ǟ�J����7���\{1�o��d h�о=͒H����Z��ƪ8If�ҨI�Z,��'�cE�)�k��%�<����亡r������G�B�v��bs!!�+J)�@���^lM��pQ"��X���/(��� +U��{�Sptw�����B���^��9" +�N����T{�K�9U:�b�4T�7p.��� +��KF�\]�wM�#%��s�R%�� +��ǖl���qv=u&����Ь�� �Fr���Tu5<�`)�� �R����0x녇0�&�i�S�|�'w�M�{�ȉ��Ik�W���TE����-��O"gp��=��6��`�,=�+����Q �<�en��~��=:A��S<��c�/��� +<8M�w�����I�g�I�I~r�3����x{Pv�\zl��x���vm+ݿ�|O �����M`:ao�DIj���*���e#iO ���9Ct��TG����i{��ӡ�.������;a[�9��B4��-� &�̬�X�$�ޕ�����}��rB��'r�(yR�k��� ������ȑ0�|{���'�Ǭ�1$��R�@X^��x'6"��`bi�:'�ì��-�_<h/�K(|��g�[��{�Y��?��t��BZ�����\�Ĭ +��ڃ���M�.S����WW3�lh뚅��0@��>�r�0䉗��""kW�~ù�ǣ~ݝH��6���w�w�N��z��G��7�be�]f�߉9o�a>x��*����(���ۘѹʬ\-����[�<�����%�ڊgg*8��z�q�Nl ��5��9�(��/k�mȗ��1|�[��*���cP���/��J{�K� �\�?��H��q�f�'�'(�ڄ�d��)���r�1a��L'�Up� +� g ���5|\��r`96����JV�Ua6�"� +D(�w&��Y�D�\q�(��Nm!<Xw�;A�,[�S��� +����V��>�ミ���Qԫ��( +U�篇ф�R �[at���0�b~/�f�?N=�h�pS��y8�<�䱯�y�u�D8*BvH��8V�s[�� Fc:�so�3߈O\�J3�h D'��u�[�[�D��R�-G��t�[��=��1f�C� ��d�K� n)��/yN��*�^O�3�<�c��9w���9���xΜ�z���~y/ [ ����D�3z�����'��VAX�P���@��� p��6ғ+��vG� +�^�9�;��)�|���h� ΰ�@�B�v�D�Y3[�S�Ә�a!P�k���k��ń��f �+=/ȱa�����6�ڶw��4r�R�eZ I���;nH�j�r�)8"u� 7)��TI��K��+�6��A��-�*�u�$t��`����-^h)EđDQ���ɸ�^�}K�5��C�E<k�:5z�t�H�+������#��{Ń/���u�D�$[D�qD�����8��A;F�<���3s|�V���k�q�=ӯ +�q^� �Z�,��S/*�فv��7-=���o�8T6����L��k�XA#m����yp�y) +�[y���y����<8��*��aGw'׃l��2����G��0(݀W�ƍ�M|�EPە{l�";o��_2�ŗ�S]<s~���� @�l�ÊǮ?�m%# =�]�<�t�A@!�Ǻ�@��E�ar����V�2�r���C���I~ߛu��cřʢ�U��Pn,ku�B��ab������Y1I�endstream +endobj 3320 0 obj << -/D [3295 0 R /XYZ 193.314 299.437 null] +/Type /Page +/Contents 3321 0 R +/Resources 3319 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3318 0 R +/Annots [ 3349 0 R ] >> endobj -3321 0 obj << -/D [3295 0 R /XYZ 332.302 299.437 null] +3349 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [362.68 151.955 419.882 160.867] +/Subtype /Link +/A << /S /GoTo /D (edit-values-list) >> >> endobj 3322 0 obj << -/D [3295 0 R /XYZ 71.731 292.299 null] +/D [3320 0 R /XYZ 71.731 729.265 null] +>> endobj +486 0 obj << +/D [3320 0 R /XYZ 199.853 708.344 null] >> endobj 3323 0 obj << -/D [3295 0 R /XYZ 71.731 243.482 null] +/D [3320 0 R /XYZ 71.731 699.706 null] >> endobj -1579 0 obj << -/D [3295 0 R /XYZ 71.731 200.707 null] +3324 0 obj << +/D [3320 0 R /XYZ 159.666 689.415 null] >> endobj -3294 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +3325 0 obj << +/D [3320 0 R /XYZ 71.731 656.374 null] >> endobj 3326 0 obj << -/Length 1289 -/Filter /FlateDecode ->> -stream -xڥXmo�6��_�����}ߒ^�۰��k�ö��6����ݯ)J�c'��C���)>4���� ��p80��}�H�+�x�'wW\i,��b��Z_]r#b���'õ,X�86=�X��7�xz��=�t�˴�ʬ���|���~����<�g���]w؞�(tκ�u&�َ�]�>:��� -X�r�ø�\�+͛�(����n�gI�fU��J�D�]=�-���������A� �����2������+�;Q�:�i�qB�$�B���[�E����u�a�9�$YdGr=A6���u��$��{�+M����f�T��,;$oj���,+iq�Uf�*�'���Y�9[�i�1�\#�$�����7�j���j�X풡�A� \2B6��s a��������s��R�~O�� �g�G:�:�����÷�k�������2L ����^�����~}��X��X,}~+�-�'��a@����am��I����1D�( ��mF&��L!v��G�pd�1��P�"��n��a�m�S�z'�U�֫}+Sq���VP�ԇ��~U5�W7�P��}��5:��4����,����EQ��?�h���Տ�5�:K0�^|��������)J����:[p���������×�o%�æԔ�6U.����òqyZ���� #�1�Q@'��;.�dI�d �����<9D�'8�&����m��#�x�GL��IJ����t��=�⦍�f�gj�U����@�T�v����d��̸V\-�HE:���n�Q�x��kHe1С�app#3�9gc�0b������r{d�!�����~�Y�/����F�N5��g��rfC�t6l��ɰ)t�>�)���v{d��*-��M��L��V���س*nJb��8*���;̱���uNT�P�:�)��z{d���]]P������ч�2��FO��E*�!(�&���roZ�lY\����V'��͆�ţ7��=UQ��~����dYͰ�aE;�m����/��5��Q�vX�<��� �[U%��]�j��(2��D��2Q�X�ԄЬ�r8�J*�X����EJ%���3��ʵ�o�������j�����liU:�C�C�NT8Ƥ�b�%��iwi��V�M\�.�B~�3�&q�I�J*+J�&���kp���oN�p�=�k��"�H����dL�RwC���������ek#��z�~\�"�/S'endstream -endobj -3325 0 obj << -/Type /Page -/Contents 3326 0 R -/Resources 3324 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3227 0 R +/D [3320 0 R /XYZ 118.555 617.81 null] >> endobj 3327 0 obj << -/D [3325 0 R /XYZ 71.731 729.265 null] ->> endobj -514 0 obj << -/D [3325 0 R /XYZ 398.777 707.841 null] ->> endobj -1580 0 obj << -/D [3325 0 R /XYZ 71.731 704.871 null] ->> endobj -518 0 obj << -/D [3325 0 R /XYZ 359.858 673.37 null] +/D [3320 0 R /XYZ 232.228 609.345 null] >> endobj 3328 0 obj << -/D [3325 0 R /XYZ 71.731 664.918 null] +/D [3320 0 R /XYZ 378.496 586.033 null] >> endobj -1581 0 obj << -/D [3325 0 R /XYZ 71.731 528.314 null] +1599 0 obj << +/D [3320 0 R /XYZ 71.731 564.112 null] >> endobj -522 0 obj << -/D [3325 0 R /XYZ 381.114 492.847 null] +490 0 obj << +/D [3320 0 R /XYZ 193.206 535.466 null] >> endobj 3329 0 obj << -/D [3325 0 R /XYZ 71.731 484.395 null] +/D [3320 0 R /XYZ 71.731 526.828 null] >> endobj 3330 0 obj << -/D [3325 0 R /XYZ 71.731 448.847 null] +/D [3320 0 R /XYZ 247.76 516.537 null] >> endobj -1582 0 obj << -/D [3325 0 R /XYZ 71.731 394.416 null] +3331 0 obj << +/D [3320 0 R /XYZ 159.162 503.585 null] >> endobj -526 0 obj << -/D [3325 0 R /XYZ 342.285 358.949 null] +1600 0 obj << +/D [3320 0 R /XYZ 71.731 476.522 null] >> endobj -3331 0 obj << -/D [3325 0 R /XYZ 71.731 350.497 null] +494 0 obj << +/D [3320 0 R /XYZ 223.845 433.425 null] >> endobj 3332 0 obj << -/D [3325 0 R /XYZ 71.731 324.912 null] +/D [3320 0 R /XYZ 71.731 424.602 null] >> endobj 3333 0 obj << -/D [3325 0 R /XYZ 71.731 319.931 null] +/D [3320 0 R /XYZ 502.556 398.914 null] +>> endobj +1601 0 obj << +/D [3320 0 R /XYZ 71.731 371.228 null] +>> endobj +498 0 obj << +/D [3320 0 R /XYZ 263.709 333.639 null] >> endobj 3334 0 obj << -/D [3325 0 R /XYZ 89.664 299.173 null] +/D [3320 0 R /XYZ 71.731 323.274 null] >> endobj 3335 0 obj << -/D [3325 0 R /XYZ 71.731 297.017 null] +/D [3320 0 R /XYZ 89.773 313.514 null] >> endobj 3336 0 obj << -/D [3325 0 R /XYZ 89.664 281.241 null] +/D [3320 0 R /XYZ 71.731 293.425 null] >> endobj 3337 0 obj << -/D [3325 0 R /XYZ 71.731 279.084 null] +/D [3320 0 R /XYZ 327.818 282.63 null] >> endobj 3338 0 obj << -/D [3325 0 R /XYZ 89.664 263.308 null] +/D [3320 0 R /XYZ 71.731 275.492 null] >> endobj 3339 0 obj << -/D [3325 0 R /XYZ 71.731 256.17 null] +/D [3320 0 R /XYZ 81.694 254.735 null] >> endobj 3340 0 obj << -/D [3325 0 R /XYZ 71.731 233.256 null] +/D [3320 0 R /XYZ 81.694 254.735 null] >> endobj 3341 0 obj << -/D [3325 0 R /XYZ 71.731 167.168 null] +/D [3320 0 R /XYZ 390.418 254.735 null] >> endobj 3342 0 obj << -/D [3325 0 R /XYZ 71.731 116.195 null] +/D [3320 0 R /XYZ 513.923 241.783 null] >> endobj -3324 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +3343 0 obj << +/D [3320 0 R /XYZ 71.731 226.675 null] +>> endobj +3344 0 obj << +/D [3320 0 R /XYZ 81.694 210.899 null] >> endobj 3345 0 obj << -/Length 2453 -/Filter /FlateDecode ->> -stream -xڝْ��}��o-Wl��y�\�����f�����-і2��ұ��� @���=��� ���H�~�"��$�!�� ���8��__�L�f��E�n����0\dn���~��<7�En�]�O�})�Av�uyN�Ҹ-�US�����ލK�9���k�����Ww��(L�, _T��\�-R�/F��gz�n6Z�m�˾߾Y�c�s>����"������n���/_M3�P9��}7����ض��Ƿ���v��~;#�5��;U��@t�\AC -��?��W��k�ޫ�Q5���s��������V��N��~{�����{�)~�~�'���M�Ls]_{F�:���N�0��r�GΉ&_e-E/{曜��E�����a�^zV�8N���xr(�.pN�(D]pZ��#��fZ% +��p���(�4�Yꁗ���@*S$�n�2��D�Rc'{���h�*�N��eY��%�2��~��/p��צ�e>v��D������?)#&`V&�j���h�pl1H��ʦ`��(h�K��^�0T��o�M -��/f�FG7>�}b�����#�+a7 -n -���i�-��+�f&��MW��� �Cˮ��Ռ��z�&���3�Fu3��VU�`���y��0q����4�ٙ)~d�ka?���+;[�g| ���V�� �K�do �*<�M��@��X�e`·0R6�}!��leD�5�37L�sN�9��c���!K>p@~��M5��\�~@u�J^I�U��� �&ٰ�z�S��FZ�$��sn�p�}P-a�ܞ���Zm��f[+Q����d�J�M��J}'��)��B��K�\J������E��$i��H�%�S��\�/w.�w�6%�T��N��f<B���W54�J=q��L�:7V�������}��:1)�aѨ�P�t���y�o��1�F�P -�R�7�7֓�=��2���b(Pt:�B��e�/�%��opU���|��}$�T�2HQ1��dL�䝤BS�!���ȆiH�� �E$,�B�N�OP�����ieW�0�>�(r��v �ϲT�4p����J��}#]:�(�̽ν�W�;�!~Ċ`*������O4��S�����Fk�DmK�] K4\7�-\���sulES����8�Ǽ��lC��y��[ɱjH)�~f��3�0�}�t;�7��XL��eѪ�]h�8ܰTA*���λ�[�Ƅ�>w��B�\i��q��= 4a -��PÄF(�,.����:��݊f�H4�b��u���UOl��\9��Ll8�^��t��q)G��c��鶡ъv�� L���Ӫ^��aƁܹY��L'0��C�R}$�ZhK!֙7k�⡖[g�,Nee� �?]h�8;�q�=�-a�g���� taY L^���3�Y���sC+t��hE?�8�m�n�,@w�"�g'�1 ���L�=&��`�P��87b���In���?�K���t$�ikI�IL����9��m��A�^�#A{Ys�boת��P�v�~ ���U�4�~FM��)�˦�8p �E+1���Y0#����삷�x�Z���-Ѭ�.R��=���X��������,�Z��)\������Bgf*�`+b�4w'Ι�oA����ӽ��V��1�t�e?��,L짇4���7�Za�x���l�L"�������N -���Y~_���<��P=����F:����������[��na �����ڄ��P -x7�oQh�^ilߘS(.c݀�>�e��L*�������d@�G�au��cO����j�]:�RSA�e�f��鱆舅 � @� ��k|��˺@����ϵS ��$��01>�إ0I���>@K[/��k=���c5H� ZpE����i��)�=K.�a9s�:�����0�<�G|c��pQ|������£��c�g9�v�F�CƱ�S��}��-0�kΈ�ke �.� ����;�G�H �C]�= �_���Q`U`!��<5�$��.T9g"n��f�:B!�%թ��d$3r����7�,��n*y$�^ � Qn6gJ���Cj���.��Q���N�j�ߧ�T�j�+��gh� q���,���Vt�4�!� �Db�L_ z4e��9w�!�R�uA{𨌾�Zt�7�Z^��/���l��o�a�-�Z�M���7���W�#�)t�"�^�b@��+ȣ.ͰS����]I�3�*��G�)2cϬ�1Fp~f���(.D��.�W^b����� 疃vv���0���KG�SU��]�"�i�x���ie�wHg��>h��zs��ȏ�?��������#���J�� �Trj�� �T���B�zz~?UCIP��� # -k-�n�'?x�5$W EAkT{?�wе����endstream -endobj -3344 0 obj << -/Type /Page -/Contents 3345 0 R -/Resources 3343 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3227 0 R +/D [3320 0 R /XYZ 81.694 210.899 null] >> endobj 3346 0 obj << -/D [3344 0 R /XYZ 71.731 729.265 null] ->> endobj -1583 0 obj << -/D [3344 0 R /XYZ 71.731 596.862 null] ->> endobj -530 0 obj << -/D [3344 0 R /XYZ 341.27 551.607 null] +/D [3320 0 R /XYZ 71.731 195.791 null] >> endobj 3347 0 obj << -/D [3344 0 R /XYZ 71.731 539.169 null] +/D [3320 0 R /XYZ 81.694 180.015 null] >> endobj 3348 0 obj << -/D [3344 0 R /XYZ 71.731 514.94 null] ->> endobj -3349 0 obj << -/D [3344 0 R /XYZ 71.731 509.959 null] +/D [3320 0 R /XYZ 81.694 180.015 null] >> endobj 3350 0 obj << -/D [3344 0 R /XYZ 81.694 489.202 null] +/D [3320 0 R /XYZ 71.731 139.004 null] >> endobj 3351 0 obj << -/D [3344 0 R /XYZ 71.731 487.045 null] +/D [3320 0 R /XYZ 81.694 123.228 null] >> endobj 3352 0 obj << -/D [3344 0 R /XYZ 81.694 471.269 null] ->> endobj -1584 0 obj << -/D [3344 0 R /XYZ 71.731 469.112 null] ->> endobj -534 0 obj << -/D [3344 0 R /XYZ 249.392 431.896 null] +/D [3320 0 R /XYZ 81.694 123.228 null] >> endobj 3353 0 obj << -/D [3344 0 R /XYZ 71.731 424.544 null] +/D [3320 0 R /XYZ 71.731 108.119 null] >> endobj -3354 0 obj << -/D [3344 0 R /XYZ 71.731 352.828 null] ->> endobj -3355 0 obj << -/D [3344 0 R /XYZ 71.731 270.138 null] ->> endobj -3356 0 obj << -/D [3344 0 R /XYZ 71.731 205.381 null] ->> endobj -3357 0 obj << -/D [3344 0 R /XYZ 71.731 190.437 null] ->> endobj -3358 0 obj << -/D [3344 0 R /XYZ 108.889 169.281 null] ->> endobj -1585 0 obj << -/D [3344 0 R /XYZ 71.731 118.073 null] ->> endobj -3343 0 obj << -/Font << /F33 1278 0 R /F35 1525 0 R /F23 1173 0 R /F27 1180 0 R /F44 1994 0 R /F48 2006 0 R >> +3319 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F44 2037 0 R /F48 2049 0 R >> /ProcSet [ /PDF /Text ] >> endobj -3361 0 obj << -/Length 2986 +3356 0 obj << +/Length 2154 /Filter /FlateDecode >> stream -xڝَ9���꺏��&sa`��bwf0��ʶ&�R��v<_��H��vA�)��H��%u;+�9�ȱ">nb�a�J���3?<8L�c�݈��������J�$�VO��o�Vd'��s�8pWOٯ�oN�j�z�s{�Y�}��e)���H����Y��E!6�?����S/;�"+������~��r|��CT��ӎ��w�~��x��zE��Cu�EF:�pG������������Z�y��9�����j�ږ�Z��)"�Qa��T�f�q���ʖP���W0J�䊾�֑^UǦ�e� -0^+Ui�-%p.�*+v���K$� �o��ܘ��'V��dͿ�l^rW��-������Ϳ���s�߱����36���<E{�֞��Żv`�ItW������j��u^:m�7����=мx�L���O{)�˧}G��-��Va�\�B��`�O��9Q�!^�׆� -��24w��3z�%܅!d+ǿ����`��K.�zV�]b�y�%����K.���e��#{�e������B{�X���g�O��Z�6=A:͛;�� �}�N�殲sF/y��� �����5`����=�;�����G��;����ku�o�mrFU�{C��h+[�pl���S������ptL��� F��6A�ff�<�Z�:��pWG���U^f,BuR&��P�)�-�����y�jB�HY(��.P��E)D����<�Ҹe�6��R��#�r�S�����'��^'�=�3.���:�V��_y֓�����XQ���Q�s�2ou��ꏄ�{�f��!�Xt���B���v��d�mrQ'd/�́�O�T]C3��Y��ƴ"�%�t�r����h�"�A�;Klo�,T* -��������p�p\�,˱��]�L��v6f�݈f���l1Zβ8d�(�+��ܕ>g��!�C� -�`�Ox��炣���#���щ�ğݹ"H�0�}�D5�^D����,>��[&�0A��jf��.�g�-!eKd���Q-��`���^��^�i��rs(�9Н��1��ƍ&�7־U�3 �ዉJ>c�Ը椺"#�vMW�&4.�.�4��,��i��+�]�<n g(���n��rڤ$V�(�l�b��]K�G̡��e�h?v�����ؾ�!`�p�ˇ3�:��쒐{����l�Q��Q��.���9��� {�ӓ(�y3���K(Kf�mr2���0;ʔ�6?W�\uC���y������GT9����eq�dT��*���0-�bK�\�̹�k�B�^�,l���� a�{�ڳ�XTPz?˳h11k� �D�gȍ� ���Fǣ*��7��3vU@별�Pza��o��xa�%x W_�L��\bɦuӧL�7C_'�<[t��RA��س<G��O��n�2ȥ?�ϟ�sy@b߃�+JV��oU�������� -!�e�{��e����f绶e����v,/�W~�C�N>�o<xQ������ -��P/�9�kŶ@h�^DW������9���|�E�w�.hZ���܄WI�(m�?�� -k����^������W��P��^` �.��]M�8x�����5F�c}���S�Л8V�>E��J �'A�� 7��c�H����"�sP�q�M� �?0@;%`Q�ijk�f��R�YD�6h�-[���e�F7s�n�^X2�ť�E�� j��9dz]��d�(�;v��3�3����p1W#'�J�=��b�N���o9PA�л}�7</ -/�F� �x�N?��t�K���3�!9���|��d�P�����k�H-���s�Q��4�`�yMnV�z`��ǻx��L��%��Z��W�nW�ݍ*�o��q�LW��B�p�ԭ:������"K^$�j���70+h8T[�U����\MxŬ 'se>�>j��B���>G,�o-��˶�~S4JQ�� 6���O�Sx��e&�`'Nå�浕`�o5^go/�7\��c�5}|���ry<���q� ���Ã�UI�~���f֊u-UK;�"��1�N�<�n���®e����~�w�ڼ�����:oMa�CF��7�l�6� ��Si��|�9�"��39�2U-����0P>z����p���#�s��kz߉o=Ճ�7�g���� U�E��Fml#9�F��l�WJ�(�ǂk=y�{�v�([q<ꋴ6}��mѬ�x@�nf#-^����(�6h�����F��M[KNNZ��n���h��|}ip�w��~��P�'2��s���7 ��$�� -T���//�w���I�����W��p��ʲ)]^3�Pߢ�߾.���h��=�z� _�$��02���.���!�/4R:DL�R�8}nvgY��+������g)���:m{��T�R\�vX���+��24�7j0z�c�� ��V�i�^�e?;wn��3�S� Y�l�<����3O�����$�l'y<}0�'B��msm��R�^SC��s���.��6m�IV���6���պ��}d�ߛ����y�s�AP;Ԍ�gѽ�QT\i�ZK�Ϊi p ��mijl6�w�X<oaZЧP,A"����d�{����j��i��s���Ѩ�J=���p�4�.Ł��S�S\b��-I��gA��0*�<ӑ�7.>5�V����-̴\�Y�ϖ�لK{�$]�Qk�I�����S �+��m�e��_�=�,pG:������AS�BSLޖ�.�m����.a,e��g��znH���_�K'�N��Hq�n����u���U�Y��*�g�5�r�(o_crz�:�s�.�[��!�\����:�` FZF��#��p��%���j�H���CYjzx�y#����h�Lg�`9_m��'���8V����#���ݛ�����0A���Wyt��c+u����@��K���`=Tԏ^������T���endstream +xڥYI��F����mdҮ�zKЃ�H�i`���l��B˒������!�,��2���"��G�d���'W�i� A�v�7���;?��L�a�͈���~ +�U.�$\=�W����Wi�,V��o��cq�T����o˓���u]h��e-������������s/;S�g���EI"� |�� +~&�(�U�HQg�@�A<?Q�8�F���A8��>�_&E�G����V�Ө���X�w9�d��SE���G<�ծ ���DȻ;j�<��RNR��/�ś/G��a2����U�,�����$̻n:A�O�~���U5��8629ٵ� Y��}-c�$�:���V�"B�G�ѹb�Sk:�Q��uT��Ŷr�Za]��8�3� �a>�A�`�˱�;~��:�����+E79q���Ч9_�CK�l"iMT�X�'���-�P�Q�J�@D�m 9�͈�!i��#<�g�c���X$� D~�=�4����Ȓ|"��6��D[+���mb�� ���gsʈ�NNq���^�)s�7r�X�m�UqU��P����93� +]����;�B@�L�̭���Iz��4B�08g�gܴq��#� +����}*�esl.4μ�|VE۫I��9�Du�L7vD���&�.��:^ɕ��越�k5��1�c�{uCO�G�� +f�� �,L g@B��(�`^�����1]���a(� z�ͽ�f��"{)��Ȟ ��#韬}���N݈�(��O+ �1T@�L* ̇ +���ɮHFLF�J�8��3��ӂ9U%h��f���ӄ7K*Z��Vg\��,�T��M$�����Id�%�T(<ͼ���()�体 㟴����o�-��kϖ{���{�՞|�N>6U�hʸ@�O��1Ú +2�K��g^@���a�X�E�̨��U秛�s:$䦶9�B� 8_X���/�!���45)��>���w���B����M(��9���<[�A,��%ґl�E���YT�PHp�Bx�Y�P8�<>e���͠��8��2�=[�R��:U�[�Rs�x"2�D���I� ����%���}�(�s�'��ӕ]��m�nKg��V@��EC�Rqʀq�1c�#5e Xطn�ŖF/jK�-���,��%�At=&�k���R3���Z��:�p�O��<���+|o;kX =�`p��=8w����ƨ����{`���t��:�=�C���v�vn(�������;z�j�ZUw��6;�Z�Y���JE c�>{�q$�(\���������"�s���w����̷e��dt��}/�hT��(=ٕqF·�Ë�_Ϊ-(�q�� +w�y"*(YP�|te�ɹ� 诉eD)߂+O��6&�QY��s@���B�!��0����"�>��۽u�7K�B��v�"G'(��q�ڋ#ힼ��Y� +{V�"-M[�;�/�����a�E}�� �W��u:rc�2p��+a����yWͮ�vM�ׇ���\��5Ѭ��h�{��P�s9�ˋ��K��A`�"�G~�>��v����Cͺ�J�er�ʁ�K �����3͘�AQ'5@�wݭ<aB�M�6���E�u��äe�D}�}�(�DZe=p��bpeR�aq�A�3�v��e� �%���{ͼ���E�����)>�|���ZJIRƚe~�X/���l�}��綜ۥ��Vz���"h +2W�]V�.ռ�Ga��r��1j!�G��͝.���y����})�AQ�<0�<q��٤�+S� �]k* TysN]8P��8c�/�yHZ�ʥֿ�ݯ~�7��8�+�Q� �ma�j�0>2Ӵ�L���LK���h��=�5���y#{C�o��'Qn��mK��D�5d7{���#�O�T���f#r +�Q�a�c�����\]�ܵ;,f�T5C�g"�ט+�W���~g�:`=�����B��%�n���M�H6#�E�<c����[}��$�nɺ{��Wʞ�E���9̧�E���j{uܻ��Ru�����9�Dę|l�9�U +�s)�us>�=c����<�ƴ���v����>"�V43O���c?���$��-1�~��ࡣ��5KIeЇ�endstream endobj -3360 0 obj << +3355 0 obj << /Type /Page -/Contents 3361 0 R -/Resources 3359 0 R +/Contents 3356 0 R +/Resources 3354 0 R /MediaBox [0 0 609.714 789.041] -/Parent 3390 0 R -/Annots [ 3367 0 R 3370 0 R 3373 0 R 3375 0 R ] +/Parent 3318 0 R +/Annots [ 3360 0 R 3368 0 R ] >> endobj -3367 0 obj << +3360 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [141.14 657.664 205.897 666.575] +/Rect [123.546 680.284 168.378 689.195] /Subtype /Link -/A << /S /GoTo /D (upgrade-cvs) >> +/A << /S /GoTo /D (bugreports) >> >> endobj -3370 0 obj << +3368 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [203.157 639.731 267.914 648.643] +/Rect [202.898 525.211 260.182 532.065] /Subtype /Link -/A << /S /GoTo /D (upgrade-tarball) >> +/A << /S /GoTo /D (edit-values-list) >> >> endobj -3373 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [214.225 621.799 278.982 630.71] -/Subtype /Link -/A << /S /GoTo /D (upgrade-patches) >> +3357 0 obj << +/D [3355 0 R /XYZ 71.731 729.265 null] >> endobj -3375 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [81.972 565.385 134.276 573.923] -/Subtype /Link -/A << /S /GoTo /D (template-method) >> +3358 0 obj << +/D [3355 0 R /XYZ 81.694 708.344 null] >> endobj -3362 0 obj << -/D [3360 0 R /XYZ 71.731 729.265 null] +3359 0 obj << +/D [3355 0 R /XYZ 81.694 708.344 null] >> endobj -538 0 obj << -/D [3360 0 R /XYZ 367.202 707.841 null] +3361 0 obj << +/D [3355 0 R /XYZ 71.731 680.284 null] +>> endobj +3362 0 obj << +/D [3355 0 R /XYZ 81.694 664.508 null] >> endobj 3363 0 obj << -/D [3360 0 R /XYZ 71.731 697.476 null] +/D [3355 0 R /XYZ 81.694 664.508 null] >> endobj 3364 0 obj << -/D [3360 0 R /XYZ 71.731 685.559 null] +/D [3355 0 R /XYZ 71.731 649.4 null] >> endobj 3365 0 obj << -/D [3360 0 R /XYZ 71.731 680.578 null] +/D [3355 0 R /XYZ 81.694 633.624 null] >> endobj 3366 0 obj << -/D [3360 0 R /XYZ 89.664 659.821 null] +/D [3355 0 R /XYZ 81.694 633.624 null] >> endobj -3368 0 obj << -/D [3360 0 R /XYZ 71.731 657.664 null] +1602 0 obj << +/D [3355 0 R /XYZ 71.731 597.758 null] +>> endobj +502 0 obj << +/D [3355 0 R /XYZ 263.064 558.386 null] +>> endobj +3367 0 obj << +/D [3355 0 R /XYZ 71.731 548.021 null] +>> endobj +1603 0 obj << +/D [3355 0 R /XYZ 71.731 520.229 null] +>> endobj +506 0 obj << +/D [3355 0 R /XYZ 271.04 480.956 null] >> endobj 3369 0 obj << -/D [3360 0 R /XYZ 89.664 641.888 null] +/D [3355 0 R /XYZ 71.731 470.591 null] +>> endobj +1604 0 obj << +/D [3355 0 R /XYZ 71.731 430.78 null] +>> endobj +510 0 obj << +/D [3355 0 R /XYZ 219.024 387.682 null] +>> endobj +3370 0 obj << +/D [3355 0 R /XYZ 71.731 375.244 null] >> endobj 3371 0 obj << -/D [3360 0 R /XYZ 71.731 639.731 null] +/D [3355 0 R /XYZ 441.444 353.172 null] +>> endobj +1605 0 obj << +/D [3355 0 R /XYZ 71.731 338.063 null] +>> endobj +514 0 obj << +/D [3355 0 R /XYZ 311.237 300.848 null] >> endobj 3372 0 obj << -/D [3360 0 R /XYZ 89.664 623.955 null] +/D [3355 0 R /XYZ 71.731 290.483 null] +>> endobj +3373 0 obj << +/D [3355 0 R /XYZ 189.454 280.723 null] >> endobj 3374 0 obj << -/D [3360 0 R /XYZ 71.731 616.817 null] +/D [3355 0 R /XYZ 328.748 280.723 null] +>> endobj +3375 0 obj << +/D [3355 0 R /XYZ 71.731 260.634 null] +>> endobj +1606 0 obj << +/D [3355 0 R /XYZ 71.731 229.75 null] +>> endobj +518 0 obj << +/D [3355 0 R /XYZ 261.227 192.534 null] >> endobj 3376 0 obj << -/D [3360 0 R /XYZ 71.731 560.404 null] +/D [3355 0 R /XYZ 71.731 182.169 null] >> endobj 3377 0 obj << -/D [3360 0 R /XYZ 71.731 495.273 null] +/D [3355 0 R /XYZ 71.731 170.253 null] >> endobj 3378 0 obj << -/D [3360 0 R /XYZ 118.555 456.709 null] +/D [3355 0 R /XYZ 71.731 165.271 null] >> endobj 3379 0 obj << -/D [3360 0 R /XYZ 71.731 403.119 null] +/D [3355 0 R /XYZ 89.664 144.514 null] >> endobj 3380 0 obj << -/D [3360 0 R /XYZ 364.919 370.462 null] ->> endobj -1586 0 obj << -/D [3360 0 R /XYZ 71.731 355.354 null] ->> endobj -542 0 obj << -/D [3360 0 R /XYZ 244.469 323.04 null] +/D [3355 0 R /XYZ 71.731 142.357 null] >> endobj 3381 0 obj << -/D [3360 0 R /XYZ 71.731 314.402 null] ->> endobj -3382 0 obj << -/D [3360 0 R /XYZ 71.731 263.1 null] +/D [3355 0 R /XYZ 89.664 126.581 null] >> endobj -3383 0 obj << -/D [3360 0 R /XYZ 71.731 248.156 null] +3354 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F35 1567 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 3384 0 obj << -/D [3360 0 R /XYZ 71.731 199.105 null] +/Length 2688 +/Filter /FlateDecode +>> +stream +xڅɖ���_Qϗ��++Zm�s����Lu2��9dr�-�ʹ�(��_l����@ +�o��7����0D��ӛ]�.�����ޅ�����������7�������$�M��l����������A;�.WQx��㇢2���7��A�e�����T�����ݧ��wo�<�_���mF��1�̏������\�i�z��~�^#�fЮ�ә���d@Z��MǓV�#������@��?.��Se��S�l��� +]j��3�� �.E��ex�E(7�9��3��Nd�p� +������L�V֚}���.�������� +D>8SN%9�sd��7v�p(���/e�C#H�8�#"]�v@v�j|n�(LѬp�u��yF'��0D7�d�o�<�}�wM|6E���9m�mF����D)�e}B�e��[�Z^"�gb7��D|D�ѵ�f�#��ɡ22 +��������Ў��2J�Sd�,棅n�`^�Qy�s��K�6���*��]]p ��3��|3 �7ɗ�5%h�Qesd�%��.����5CQ�<��.xF�'�<Uۙ]_��)��APU�t��an�(�Q?���N�>�_O�;8�S����n;e�rĩW�Ֆ��hX'���/A�G�J�����AU��a 1�m*�-�������Ͽ���'8傡������[��;NE��9���B�\ +�;��x��?���iZӽ\ +d��v�YuYâ\�f����t����e�yr��9�䊇�qɠ3��H���dѵF��?�b?�!<���cUMaD�������i���� �D݀���QV��\3'����)�,������q�-[^�}By�)��!vz�� ��T8�ۦ�wh݅(l�j]_��$t����<y2�0g%6��s���*P�j�1���U��1z[�s�ӲgN���M�W�녡�Ywp⥩��S5�:A)��{��o�Y�zcg�q��E v+��K�mK�_b��!�c?�6�b�s����S\���-Ny_0Ɣ�h�$�[r�b���ͱ��'�2l���R��E�s+��4������'�Q�m[����m*� 9p%��'V|NT��0Y�c|\9!�9}���5�<�u������I��R���.�����0������h�,=g�2\x�VaP7��n��:�J�)m'ҭ�J����륪?�uV�V_��������8W�_P�_r���y���'�/�����s�M���P�8���a������PN�e���yXªM(���I���d����\vZ�@�2 ��l����Z��Əa:^+�������N��v�����d�3:��e�R.�:��l�f��n�J�eyW2�����<�\uHAA�W���� +����T�'�듉.U�j�����K��v�D �2k�t���-v��};=�U�K/IWI�����{OF��Wo����$#A���Z�J�̳\�uT?w�PiK�y�/��E7@�j=�l���F���-)��s<j���w�V[xg[�W>�����n|Ie?J���<��N�6'��C��#�Π�;��j�����'GI�D�-�H���4Րz0{,��^��k�Uu�T.{�z'g�O�`*UHʐ�������)�D��T�b�T�˅�2k�رN��N�*��QB�(ڸk��dC���#�C~7 �a���U�ƨ��eN�L0�I�*�M�4�|f�+}��He�6Q%Kxl�5[�|�i��=�����'�I|$��:h�;�"b~�#*(�<8I��$� +f��G3Es�I��8�Y���' � ��9�p�HY-J@�d�d�-����� H~D(���:�n��Ʀ�<���Ğ���y�����:�x����4 8Q��ڪ��z�DY���!T���w��)�`, m�A}�ѯX��^���Z>����t'�Ad�Ӕ4�%��ą ��pfj� �w����<���Y�!��>I�9wEq�u��s�.k�R�èx�������S�C@rD�Z����M�H��S�q�O6~}iyDv8r�&ԏ���3g�i5=ᩃpM�#��qO+�;-T���h��[f��v{ß_�O�����U�pi�MI�����a�B(�;œ3)�6��Ȧ� +��LBP��\���}g�4;�$cyi�D���^�Jn�����F!����>}Jw���e�?fq��q�x%��ɀ0��Uj���NXӰ"���"�H�3B��BxM�0*Xf�$�"��YM��w�.q[b +-�UV�������>��R��˚@*� ����!d܀�EX%��^���A�m���eH_s� \} �Ň���j!���j�7��`_�9)b��I�c�y��+$�� +�3�r�q�v0Y���`�:&�P�gE�TN8r�x=�׳�p��Bᤩ�B��0;9.@�����t(N�u��1 ��b��"7�ыPs�H�Wf���9H�3��M�k_k�k��<k�>Ea�_˯�u�83���/�c� +vfL��G�J�#�!05N�v)A~(ms;���W�T�4�3�ꦖGO��]z��o&�Ar�.�K���x��!��`�F���G�V��5�I>�J����m��Y�y����}� rD���\�O�����F��endstream +endobj +3383 0 obj << +/Type /Page +/Contents 3384 0 R +/Resources 3382 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3318 0 R >> endobj 3385 0 obj << -/D [3360 0 R /XYZ 71.731 163.14 null] +/D [3383 0 R /XYZ 71.731 729.265 null] >> endobj 3386 0 obj << -/D [3360 0 R /XYZ 104.01 151.583 null] +/D [3383 0 R /XYZ 71.731 718.306 null] +>> endobj +1607 0 obj << +/D [3383 0 R /XYZ 71.731 678.291 null] +>> endobj +522 0 obj << +/D [3383 0 R /XYZ 166.811 635.194 null] >> endobj 3387 0 obj << -/D [3360 0 R /XYZ 104.01 139.926 null] +/D [3383 0 R /XYZ 71.731 622.756 null] >> endobj 3388 0 obj << -/D [3360 0 R /XYZ 147.048 116.614 null] +/D [3383 0 R /XYZ 71.731 567.642 null] >> endobj 3389 0 obj << -/D [3360 0 R /XYZ 104.01 104.958 null] +/D [3383 0 R /XYZ 71.731 554.691 null] >> endobj -3359 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F44 1994 0 R /F35 1525 0 R /F58 2421 0 R /F55 2249 0 R >> -/ProcSet [ /PDF /Text ] +3390 0 obj << +/D [3383 0 R /XYZ 71.731 549.71 null] +>> endobj +3391 0 obj << +/D [3383 0 R /XYZ 89.664 528.952 null] >> endobj -3393 0 obj << -/Length 2192 -/Filter /FlateDecode ->> -stream -xڭko��{~�?8��iQo����^q��W\ڢ� -Z�-�dQ+��f}g8CY~l�� �D�p�p��\��#�y�h#�,]���p���??H�X1�j����a�m/6b�ŋ��" C���EG�H��S�S�V���r�a���:4]3���zw\�`��i[������?=M��8�"~u{�v颀�e�?̰q�����\ea��.�=��oQ>p]I)�4�@3m�K;Ze�k�l��o�V���T�׃n���Ga?���Z}�[e�Zw�J�Ա���J-(q���������@�ߦ�s_��_aj[ -��kUK�4OY��$���?�.*P�����== r�盅�M��b����_'N 35�h����f����ӕF�B&p��lq��;�oL��^mc:R\����,�"�Ldqᐿ�-Wq -? h��h:�ښ�h��%��`�v3�a.$l"t����}ww��41��V N��I�"*g�a�2�)��e��"�x�q:AG�l�,��zԝgǏ�8¨Մ�w�)UKòV�^�3vh��H"��}��ѷ�ഔi�F�;�]Fa�Rpn }���'��}!�A{�����\�$�k�Y�uu�d�W</�4��k8& K���⦴����2���"�z��A��$���]�4FE��j���l��z��};�t��Ha�t!8"�;�t����V{�IsN'�a2����|��%1Xe��Y��G���f\��B�9(�2Ϥ��~������&�]h�Uc���C_��S� �F��|=ʒ���P��� h�-��[��Z!-�U�L��� �F&Sd��k���lz��|�%�Hsp(0��Q/#��:�U xOi�0��l�V5��]`�-#�F��G+��4�L�� �<u�QA~p.��u�Hmm����tB�,A�p���!@a���j�j��c��1�>p���g�!�y$� -�F��;��N�t0��b:�S���)�Q8���fG����+��cM�f*��ĩp��2�f^�ȫ漱3J�Ŭ0����KK~�P'�f�rX��./)��$�q,}��X7����n� �p�l�b>ܦ��v�s)�p�/.P���78�/��I��#�e;�._l�_"w@�x�r��b�������j��;��ʹ����s¥����K$ov����UF�SV�tt`) �������F��/E ���`4 95�e�nG}����ݺ3�ɧ�h'���22����� -�<-nUb��X�Uc����^E1�+����;�3^1�<���'�2(`�b���-��uܮ��`�֘v\o9�"!����&��n�� ��ܿpņ[�+���U���dz�V���O�;�w\�^���*����Ӈ\��1�=��d��B� �G)� �>�'dwh�cW�7T����=~IY��Г�!&kZ�R�teb�k��e��3z/t5� -�6@!T����z;��/��r&�ʮ����)x ʻ�6�k�( ���� +���&�r��x�T�����gZV �w����({�c �:L$���Ha|ѷ>��yр�"��%ް�*;��\Ag�5���H��5��8�Yc<��nJ�.��4V�J�]țjS'�:K�JC�>2�n[B�c�]��e�L�� -�ަS��3k(�3�e��%h\ 6�#��0�;2W�:�/S�q�G��q��Y�W�E3�I3&���l��:�z1�n@m�.��qm�� �=����S�(*�B5S�jM���.w4��^yJW����K&��_�`TM�$i�5�%5^�r$�iރT�u��<��2�7���=j��Y��@|LH�i��k\hVG�'g���O��*)i�r7�1��|�h:�� Lm��5��9��0�{�A/e��6���$#�x���}�2�w�r�٨�ʖ�^f5*0L?4S�G%�x٧�q}7݆{o"�O_�H;���[%��t%�OA���:������3w��� -�P8r���������a�#L�x1e���֑��!=$ dz�9q�Z��/(���ꎡ ���}���}�Ƃ1&�L6쓏S��\JS16��o���M�����s�F�0��ބ8I! -����3��?Ҩa����s�����:,D�endstream -endobj 3392 0 obj << -/Type /Page -/Contents 3393 0 R -/Resources 3391 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3390 0 R +/D [3383 0 R /XYZ 71.731 526.796 null] +>> endobj +3393 0 obj << +/D [3383 0 R /XYZ 89.664 511.02 null] >> endobj 3394 0 obj << -/D [3392 0 R /XYZ 71.731 729.265 null] +/D [3383 0 R /XYZ 89.664 511.02 null] >> endobj 3395 0 obj << -/D [3392 0 R /XYZ 71.731 660.311 null] +/D [3383 0 R /XYZ 71.731 508.863 null] >> endobj 3396 0 obj << -/D [3392 0 R /XYZ 71.731 638.406 null] +/D [3383 0 R /XYZ 89.664 493.087 null] >> endobj 3397 0 obj << -/D [3392 0 R /XYZ 118.555 597.873 null] +/D [3383 0 R /XYZ 89.664 493.087 null] >> endobj 3398 0 obj << -/D [3392 0 R /XYZ 225.689 586.396 null] +/D [3383 0 R /XYZ 71.731 467.085 null] >> endobj 3399 0 obj << -/D [3392 0 R /XYZ 332.317 586.396 null] ->> endobj -1587 0 obj << -/D [3392 0 R /XYZ 71.731 541.163 null] ->> endobj -546 0 obj << -/D [3392 0 R /XYZ 277.022 512.517 null] +/D [3383 0 R /XYZ 89.664 449.251 null] >> endobj 3400 0 obj << -/D [3392 0 R /XYZ 71.731 503.879 null] +/D [3383 0 R /XYZ 89.664 449.251 null] >> endobj 3401 0 obj << -/D [3392 0 R /XYZ 86.396 480.636 null] +/D [3383 0 R /XYZ 71.731 434.143 null] >> endobj 3402 0 obj << -/D [3392 0 R /XYZ 71.731 473.498 null] +/D [3383 0 R /XYZ 89.664 418.367 null] +>> endobj +1608 0 obj << +/D [3383 0 R /XYZ 71.731 411.229 null] +>> endobj +526 0 obj << +/D [3383 0 R /XYZ 163.591 368.131 null] >> endobj 3403 0 obj << -/D [3392 0 R /XYZ 401.148 449.752 null] +/D [3383 0 R /XYZ 71.731 355.96 null] >> endobj 3404 0 obj << -/D [3392 0 R /XYZ 71.731 424.681 null] +/D [3383 0 R /XYZ 71.731 313.531 null] >> endobj 3405 0 obj << -/D [3392 0 R /XYZ 104.01 415.182 null] +/D [3383 0 R /XYZ 181.725 302.737 null] >> endobj 3406 0 obj << -/D [3392 0 R /XYZ 104.01 403.526 null] +/D [3383 0 R /XYZ 71.731 269.696 null] >> endobj 3407 0 obj << -/D [3392 0 R /XYZ 71.731 402.311 null] +/D [3383 0 R /XYZ 71.731 199.957 null] >> endobj 3408 0 obj << -/D [3392 0 R /XYZ 104.01 380.213 null] +/D [3383 0 R /XYZ 71.731 156.122 null] >> endobj -3409 0 obj << -/D [3392 0 R /XYZ 71.731 343.836 null] +1609 0 obj << +/D [3383 0 R /XYZ 71.731 138.189 null] >> endobj -3410 0 obj << -/D [3392 0 R /XYZ 104.01 321.932 null] +3382 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 3411 0 obj << -/D [3392 0 R /XYZ 104.01 310.275 null] +/Length 2710 +/Filter /FlateDecode +>> +stream +xڝ]���}~E�8``�Z��=uw�w�õEo�=����J�c�,{g����H)���n��%�")��HE�|���T�4�O�� �W���_����d� �l&4o���]�r�'��q��|_�~�J�@dq�z�~���Ӡ��&�}/�}]�����=�ތk���[7M����ǻw�Nv�"��ճ4��J�"�1*h���"�2�_(��*ͼ��u�{�x�4/�j���{U�}=<�� =�_m)�87���W�zE�t� ��h:��}1t=�:�ֺk��鶨��gn���w�X�2-�C76Ӷ�3�`^Z��!�)U?5O�;5J���)�uW��P�����������[5<c��D1��!a���12�aٵC�5�b�]�iDv:3���j��=�me��C���� ��Q�@�]@�@�.~��X��ޱ��� �p;��S���H���]�@+����`{V�O�4ڲ�b�#X��`y&T�+�U4����0������gZ>X{ B�0�u<���(_7�3WJc���r+��6lb�mQ~|B�}e=x4��m���0Чz8Шk�wt=(-���oݠ�a08���$�Z�]� V��B��a���i�* +,IG7�� +��qk��vt��y-� o`�1��]|�!~1��i���c>�(���Z��n?��C0h/��&�#Hf��q���O8 �5+X���<ۃ���{ +�W�Gm1���N���k��3�_2��T��j� ��g�Ik��$n�EUͶ�h��RLLdLH۰�i>s�c�����#�_4F g֘$��hϩnL.N +�1G�Ys�zw�l��|v�uaj�m��o2Yj)�C�������g5�g�Z_z�����'�}��ܑ���o�2�ΔA$2��I�7&�e^�v�L26�A&���I��(��h�0C�r�5�=d<�3\���N�v ��-2�y3�9X=�Ċn ��E˼�v���[������.�d�>5G/�c#�H���R$#H$ +���24e�n������* 7<�P����"�O� Oh���hC�.S��������!��)-�ih�%��@�OF=�̸�[�.��P5�8��I]U��0��?�;�[f㌁�m�k �����0�`g���T���� +�f?�~�?X�~�V��QiU�ՄN +�C��Є��p��Z����G�q���#5�ЪY�ۭj���։� AEѼ��MyP%n�#� Pd�Em�}�Ik����4}UM����{� �Y������q�C��5���!#F�:$���@��Џϕ����-RN�I��������<���ܸ;W���e������UMH +^m��d3��Fe� *B۞����D�d-�N6/yQ��-�~o�fq9aҝ�Q��n?NR���w]gd�[F�0�_��#�i2�@�����e��<g�b�^����;B�3�1M�ݜ���������N�������U����j��T���uUMx��z�ma�4�^�ۄ��, ����"닮{I��-���ڲ ��&���L4���!���O�*��8�2 �j�lʈ���־H��D5�_�ƽ(h��z��X���ԩ)���J�^�mc@ҭB]�nlPEK�b���cSp� J��4i6�m��e�N�ֵ�.�RW}��6�/�ZT�@G�l���,��J��6�7fJܛV4TGhsi=*���4Ƀi-Cim�3��=#�O��(��˾@[�D-K3��T��~��4���b�O. �kv��f�������vT��`8wҌ�o�ζ{������x�'2��<���г߂>���1= �(2�Ը=�����ɤ/N�.9��44 +X��L�hN�������v���;b +-���p�ʹ�d�j�pG�҅����C� �q-.9R��8�`��ג�Hd�˒K�fʎLݒ�+v=W�Y�K϶D�ҖS\g�e�����2�4,ȲM�Z'D��n��wd�p�mϺ��Ӛ�K�UD�Q3�4="9KM�����[���@�@(�b� �&`�MB��GT-��$���ua�� �&�r�mٌ�a��:?�d�G��� u���uy�J!'C)b?��<ҏ��������U������C�0OD,��y�z��ݽ����R�L��|��e�� \�Pb���'�9����� +o�$�H�e��f�ޜ笍L��F����̽����z�l2���0G� �5��� +�#��J����gbz/i������,�~�i�y߈+N�;6hO���y`NEE!��A1��-uP�/�"�Ƙ.����G��\v&3����#�W����Ⱦ����E��K��E�Xw�Y� �B?�Q��%>G�IM���5��ZF�5��9� 쨹ٽ�d�� ���^4�s�^���*�I���h�H@�!�?~�6�`g~3����Y�K��0{���$��VY?���e�K�l��:Q�ue�`)PK�j���#,���<�l Ŏ��{h�M)3�'}�|�%e +���@��ɦ��ɪWD��7�ς&�E�3�y�~E����~��=О?�I��}�.�Q���:P~�Y<G�˪��ͽ����_� +=k���_��%�J�H&��>�\��,�Ą_|��KI���Hendstream +endobj +3410 0 obj << +/Type /Page +/Contents 3411 0 R +/Resources 3409 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3318 0 R >> endobj 3412 0 obj << -/D [3392 0 R /XYZ 104.01 298.619 null] +/D [3410 0 R /XYZ 71.731 729.265 null] +>> endobj +1611 0 obj << +/D [3410 0 R /XYZ 71.731 741.22 null] +>> endobj +530 0 obj << +/D [3410 0 R /XYZ 339.876 705.748 null] >> endobj 3413 0 obj << -/D [3392 0 R /XYZ 104.01 286.963 null] +/D [3410 0 R /XYZ 71.731 693.577 null] >> endobj 3414 0 obj << -/D [3392 0 R /XYZ 104.01 275.306 null] +/D [3410 0 R /XYZ 376.087 671.237 null] >> endobj 3415 0 obj << -/D [3392 0 R /XYZ 104.01 263.65 null] +/D [3410 0 R /XYZ 71.731 664.099 null] >> endobj 3416 0 obj << -/D [3392 0 R /XYZ 71.731 251.994 null] +/D [3410 0 R /XYZ 71.731 633.215 null] >> endobj 3417 0 obj << -/D [3392 0 R /XYZ 118.555 208.449 null] +/D [3410 0 R /XYZ 353.441 622.42 null] >> endobj 3418 0 obj << -/D [3392 0 R /XYZ 136.092 199.984 null] +/D [3410 0 R /XYZ 280.021 609.469 null] >> endobj 3419 0 obj << -/D [3392 0 R /XYZ 71.731 166.408 null] +/D [3410 0 R /XYZ 175.77 596.517 null] >> endobj 3420 0 obj << -/D [3392 0 R /XYZ 71.731 126.612 null] +/D [3410 0 R /XYZ 397.028 596.517 null] >> endobj -3391 0 obj << -/Font << /F33 1278 0 R /F35 1525 0 R /F55 2249 0 R /F23 1173 0 R /F44 1994 0 R /F27 1180 0 R /F58 2421 0 R >> -/ProcSet [ /PDF /Text ] +3421 0 obj << +/D [3410 0 R /XYZ 71.731 594.361 null] >> endobj -3423 0 obj << -/Length 2306 -/Filter /FlateDecode ->> -stream -xڭٮ����~��X#�kї�n�(�ķ-�4#�������٨���N`��9s���X/|���V��� SA-�̓����7Z0V��:�y�����1�Le�Y<������ T����Mi��藫 �=���뼩�j�x���zZjo���k����ۇ�<�L��Լ�ތs�_`Z�,���YN?U&�?��Q�"Β��W��m�\��4���K�{e1 �@99I�/V:UY�Ϳ햫�Dޓ�xa���;�G0��,ߛ������L�T\��Z��XڑW���ɹVpe��ҵ��|@n�� '۩٠1qw����P �kyk[�v_�m�7Lے1-���@�l�]�؎C/P:T̟�;�U�k�B�^Y�ae����Ky��q\72o�$��-8����n��~:��F,����u�*��:Tơ9jg�y5��O���?�S ��8vZ���2�<%�%�V�_��ۯs��D�pH+>�XV�L���̛a y�D9@�V����<����b�z˦%�֮k�vd��e���6w�����&muE?��ޱ �*ǦFI��L��B&�I8����u�e# �p[� �"l0�#/��ko(�S_�O&�r��b8�Z���L -�-�EM��ia+K� -v9���EL�^_ԅ -����\�)? ��m˾L�oO���Ce�A0>P���Wd�����D�ۍ@P �pG ���� h%�c�r�V\C�je���G�l>o�o�H6�%��H�ʒlO�D��y}Ɯ\��D�����������<_�s �ݽ���5�8V �:u����+(��b�5g�\Њ�CK�Y ��� �ؾ�23��Zud -J�[d�k���8���@)�(W�K7�b��[�h�Q6�X�3(0͎�,�օ��x�[�4l5خ�������b��UP!�u_�����sb�3B5�:��Эջ�O�2�3��t�]`xIhP\�M����R��b�E|c���'$hm�$\���}�[�=&�5���3�r�Ž��-+����$��O��@>���('ÿ�q��غ~���Z`�}(6�s��,t5�S�F�_��*�v;��(<�kr,���nn��c�S��S�g���ڏUǤϹ�����=4,i o^u���t�o��il�fdȊʷ/a?��5d{��G�?)�ٳ\7<;�q�>�����ml �����\RA��V��>o�54�Q.���Pc���?����o��O�����!�ƀj�1�̢/��w�)��Q��,|��%���j�*]��0�B`���ke�!B��y"������0�&��Qu -������a˼��c�7;P[Hi�$Ҵ�&�����?��z�ith �D��30b� -@�l2���|��Aw�بZ��Q��C7�g��'���@K$����[�Q`��ȫ|�*�T5x�⫸��˶n�s6�=�\�c���T���MYƬ�+$� �P��T�64�]h���Ԑ{Z��^{i�3`/L����:��ߜ����n�\�^�)o"�Ta���3�K�_����|w%<�3�b7�SO����C4g��_��}y䟇�!��a+s� b�^}���)��Þg<z��A��φ����JK"����_b8�0�P{�s �ʊ�4 -N :¡],]�k�p�-��CC�#�Pa���(�y9 �S+Q�RT��j=c�'���`��O��k^C?t�e�H 3(q��!���~��V���z���{����ZaM>��uݫ_��I��V��H�&���"���@�����W��I��._l��9U�Ge���v�J&�b_ɀ�� -���D��hΊG����h ~J�bU�r�s~�D����TW0�5s��pHcq`%r�$��YnT�˂'=��.�`�$A�fdߣ��b[r�a1��M<�]qt=w�8j����S����f��ּl\^Q �X���vy���~�A-�^��@0�т�FX��N����2��`����a�F�&q���?*�m�x&F����Δ��m - �̾E��y\N�h|�:��=��� ���f��W��s0�5վeQw쀚��$D���,<�]�/"P�'�W�����y?W��m��AE��ouP���+�jAF��ȼ�����X��y��a�*�ǧ�F�`����5������}/0wu��@����(����hh�k�^?G _1�7X����-��n;����WGp���4Cϵ�F��0U�N^������D4��Le���+����$���endstream -endobj 3422 0 obj << -/Type /Page -/Contents 3423 0 R -/Resources 3421 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3390 0 R -/Annots [ 3439 0 R ] +/D [3410 0 R /XYZ 71.731 579.417 null] >> endobj -3439 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [271.86 388.635 336.659 397.225] -/Subtype /Link -/A << /S /GoTo /D (upgrade-cvs) >> +3423 0 obj << +/D [3410 0 R /XYZ 462.474 546.605 null] >> endobj -3424 0 obj << -/D [3422 0 R /XYZ 71.731 729.265 null] +1610 0 obj << +/D [3410 0 R /XYZ 76.712 517.015 null] >> endobj -1588 0 obj << -/D [3422 0 R /XYZ 71.731 718.306 null] +534 0 obj << +/D [3410 0 R /XYZ 232.492 477.643 null] >> endobj -550 0 obj << -/D [3422 0 R /XYZ 264.948 708.344 null] +3424 0 obj << +/D [3410 0 R /XYZ 71.731 467.278 null] >> endobj 3425 0 obj << -/D [3422 0 R /XYZ 71.731 699.706 null] +/D [3410 0 R /XYZ 71.731 455.362 null] >> endobj 3426 0 obj << -/D [3422 0 R /XYZ 496.727 676.463 null] +/D [3410 0 R /XYZ 71.731 450.38 null] >> endobj 3427 0 obj << -/D [3422 0 R /XYZ 415.635 663.512 null] +/D [3410 0 R /XYZ 89.664 429.623 null] >> endobj 3428 0 obj << -/D [3422 0 R /XYZ 71.731 604.568 null] +/D [3410 0 R /XYZ 131.167 429.623 null] >> endobj 3429 0 obj << -/D [3422 0 R /XYZ 71.731 570.76 null] +/D [3410 0 R /XYZ 71.731 427.466 null] >> endobj 3430 0 obj << -/D [3422 0 R /XYZ 104.01 559.203 null] +/D [3410 0 R /XYZ 89.664 411.69 null] >> endobj 3431 0 obj << -/D [3422 0 R /XYZ 104.01 547.547 null] +/D [3410 0 R /XYZ 300.451 411.69 null] >> endobj 3432 0 obj << -/D [3422 0 R /XYZ 71.731 546.332 null] +/D [3410 0 R /XYZ 450.128 411.69 null] >> endobj 3433 0 obj << -/D [3422 0 R /XYZ 104.01 524.234 null] +/D [3410 0 R /XYZ 71.731 409.534 null] >> endobj 3434 0 obj << -/D [3422 0 R /XYZ 104.01 512.578 null] +/D [3410 0 R /XYZ 89.664 393.758 null] >> endobj 3435 0 obj << -/D [3422 0 R /XYZ 71.731 476.201 null] +/D [3410 0 R /XYZ 135.13 393.758 null] >> endobj 3436 0 obj << -/D [3422 0 R /XYZ 71.731 454.296 null] +/D [3410 0 R /XYZ 174.159 393.758 null] >> endobj 3437 0 obj << -/D [3422 0 R /XYZ 118.555 410.751 null] +/D [3410 0 R /XYZ 250.842 393.758 null] >> endobj 3438 0 obj << -/D [3422 0 R /XYZ 421.576 402.287 null] ->> endobj -1589 0 obj << -/D [3422 0 R /XYZ 71.731 358.747 null] +/D [3410 0 R /XYZ 341.239 393.758 null] >> endobj -554 0 obj << -/D [3422 0 R /XYZ 295.902 326.351 null] +3439 0 obj << +/D [3410 0 R /XYZ 467.454 380.806 null] >> endobj 3440 0 obj << -/D [3422 0 R /XYZ 71.731 315.986 null] +/D [3410 0 R /XYZ 71.731 373.668 null] >> endobj 3441 0 obj << -/D [3422 0 R /XYZ 355.306 306.227 null] +/D [3410 0 R /XYZ 71.731 347.765 null] >> endobj 3442 0 obj << -/D [3422 0 R /XYZ 71.731 281.156 null] +/D [3410 0 R /XYZ 71.731 332.821 null] >> endobj 3443 0 obj << -/D [3422 0 R /XYZ 104.01 271.657 null] +/D [3410 0 R /XYZ 76.712 260.059 null] >> endobj 3444 0 obj << -/D [3422 0 R /XYZ 104.01 260 null] +/D [3410 0 R /XYZ 136.488 216.514 null] >> endobj 3445 0 obj << -/D [3422 0 R /XYZ 71.731 248.344 null] +/D [3410 0 R /XYZ 76.712 156.841 null] >> endobj 3446 0 obj << -/D [3422 0 R /XYZ 118.555 204.799 null] +/D [3410 0 R /XYZ 89.664 138.909 null] >> endobj 3447 0 obj << -/D [3422 0 R /XYZ 297.118 196.334 null] ->> endobj -3448 0 obj << -/D [3422 0 R /XYZ 71.731 174.414 null] ->> endobj -3449 0 obj << -/D [3422 0 R /XYZ 462.063 141.757 null] +/D [3410 0 R /XYZ 71.731 123.8 null] >> endobj -3421 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F58 2421 0 R /F55 2249 0 R /F44 1994 0 R /F32 1187 0 R >> +3409 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F44 2037 0 R >> /ProcSet [ /PDF /Text ] >> endobj -3452 0 obj << -/Length 2511 +3450 0 obj << +/Length 2042 /Filter /FlateDecode >> stream -x�}Y[��6~ϯ��N�cF������l���t:�>�m��EW��x�~ @Y�4�� ���t��Y���Q:M��U��c�_�B���T�D~0�N�Lm�h��qx����:Z�@��f��Q�x��X~w(N��Vk���X���_�4�>�r������`�-6j�F�/X�!.V��Ƭ��&\�v.�2�;����`�=��QáL��A�ɒ�4�`*ad�"/�d�b��=��s <uي�,B��m��E�y�"�FsL��vf���A����+���U��:#������M�Ɩa��kL ��-��3\x�SgS�� �c�3U1���fLL[;�L[�j��F���Sg��L_�t��� -��:3�Ǻ��q����]91��n�/O{*ʃ������$09��EKr�#�M)R�KNʵ��9�v�mk*��g,�)g |[���z��$[�(�;���&�n����:�m��S:�P�b�h�z��ђx�,���[�x�|0<��vd&#h1�^��'w�u���È���]�?�-,��j���IgT�U��E�'�J�� ����8���<8��Yy-M��⥌Z�Hj�6K.Ȁ���8M�3��߽i���9�B��]�pΜ���|Q���dX��E(1-Kw;����f��pC;�V�} `k�A��8|������9�4�X]��G��)u<�AV%v��,��G�(%D=����U�/�i�� ���g3�����lF��cY�^`�$�pI'��L�����ɘ����ɉ�A!dǑ���'����1J�/Z �t�H���� �U(E��KQqU��ʴ>VQ���h��LO�=���~������+�F����@�:q\8b���"���o�U<S��A�[����v��o�&OA0�dِ嵎q=R?�/H�w��X��LsHi;�R1��;/���x�7�0�S�H���pm���:7�D.&���tA~���]Ƅ;$�v��Ҷ��~���bɺ0�i�=g�JYf�x�A�s p��B:#��;6¸�z`��#���8�t7j��L&��>���FȽ�xF�±W�h�A�1ܻ�4�BOe�����hYQ�rʼn��m��m������*I�������T��̰Kh��?8F���C��Mh�BK)J���y����INqc]$��Dȩ1 R������)_� -��P^�[I��(]�pX.07�}�p\ 7�8��I��M���Y~��*�8���7�ߖ�ۯ����[�t�����Lś|��̳��mAH�3wY�W�6$�*̑NӍ�0��K�&��܉����|�*3�Z�n8�Ý��)�%�"+g�,U98qSq�SuoN\]�,�������^��D� -e�����<`���l#D�������Z�Y���:k|c)�S�Lk��:Ӝ�I�觾��.}���b�s�A��*��M�š���ot ���r���)������vZ�Ph�Sq:�q9�Qo�L< -O�����-#n���5z�;����|U��� ��U$�P�C�l!f!�|�������;Μܫ8]4o]��l�=b'��Z�:�r�m����y'A�ܒ�?�vĥy��di���!;0u�G4EGY31�x��=`0���[�ǻ���u��+��k�cmDM�� -�6C��7�̺tw�4q' -�z�_��z#G, -��d��IX�p�0�ח�pݎ�J��Z�����o��X�F�ހ& -w���k�C��T�.�� -(����w��ί���� �?�t+S���D���ʋ��G(�e7)����$��L\�F*�g��~p���� -����F.G���RY�L⨢_F�S���o;����N'��}�FKKK�!����K7D8~�q�A̬��������l)�n�Y��w -d�ұ�#sKʜ��[�Q�"�Rc�8��z�5IT��Pz����{��N7<�4��c*W��8��PK� -JzK���I��%K�s��pR�C�H�a�҄��I���Ҳ���eP��M�F/?���I���K��W[̽_r�~�7�'�~�� ����檭��b�r�t/���R�"I�[_-�RL�m�j��P=[2lc�H�͟k|�4[�S\8�|�#G����:�vO"t��S�X<`�j -�����C����A4�\��L�k��Qv��( Ǔ�.bTO=�\��y��C�9�"X�ae��T<h0�cP�=?���oq�sE���G��7]� -r���'졘�4Kyx9{�{E�2S��(M�����=�}��|�v0/�hK\�$��x�{D��},��(����}=&��fh�b!|܃ɴnv����|y�ύ��Å-?��jP����A���G��D�����\}�:$�B���LT -O��c3�%��l9�;�e�+-)���r�����أ�m�䏌8G��=l�b}!��*���=�E� -����K�?1��dendstream +xڍYK��6��Wxz�<�V�~��y��3�tR�iz�%��T�\I����P���3>��@��A m�,�٫�6CNl:��JO����<���c�,����������8pW��ʳ,3��U�:f�;�m������[Q�7�o�I��씗y��<��em��yQ$뿶��z��t�nhƑ�h��G�9��c��cOo!��iE��y�����(܁o��fx+M��u��t�E�7bQ��|�Ƶ�� 2�,�(5�J�v|�ȇ���h,��%��(���F�kҋO��H���qN⁈lIh� /i�"��W�V���Li�E5��RdD� t.�hc;f�9��iq�DF����l�yC#)��I�\/hu�5����x'�y�)o[���XZ�݈�D!Z^tiD�2�u�N���t�Ⱥ+ۃ@ڍ )P�x@�]�K״]�A燑��4��$4���Z۾��T�ϧz�X���вǒ�o;������$7�V'�KB��8�(X�Q��4'�42u�E�D���� k��%��rMˎ���!R����9DN躋�%�7bQ���e�������E��mq�+ a�t��b��/A�u�������)7`^I8��s]}�,�3��#ߴ�`1�\0:ęƄ���X�}#v�{]4��(@cY�ԣ*�_�]�h�AV�0��~�6@}��=Ϭ���*Ɯ�Ǻ�zA����ՁM.��.�$NI^�*h-IW���)i�k�Pj��åHj�3fpq^�2�d* @Rq����%���-���(�S]!1('e�a�d:@A��A��os��Ï������Wyw��w圦o��%JqS�'rvIۅ�O +�g�U|7ƚ���t$'��?��قXd�)�)~�����t|s��C��N`@�����T2�$▾�@�`QA�9���*1���2�H�m���.e`X�"ie��DJħ�4�`��Z�0��4�1wr��� +�B db/?���e +u�FI[�,"a�/�(��W6�.%W�D@�Bβp�8oY�����o���w��t943�!�(i�����Z$٦*��R���`���<��YU>Q���O�A�?`���d��=����$�+�ā����'Eֽ^�{l��O�q�Ә�\u���x��k<s�]�,v5��V�%�7bQw-���ʜ��?'�|�a�'p���{��e�#ı�Y���Ǽ�PT�\A2���a��[�)���f|�|�y��#��^�,]z�L��5vՒ�[�ǫ9;u[�t��^$u��I^v����r�m�.�%�ƉB���^�>�r�{0�y�OuҀ��`)Wި/�!HmIJpB�>)�&,E�jE�6�u�b����y��q�k��� ���4���x�lW�z?*uh�\�q���O�"�4�9l)��^rB�]t-���˷���y�AzY�.��B&�o+�e<��e�x�}< ���٥�>Q�$�'ղ� +�l5���em�Y+Ldm�em<>0��_<��h��݊ޙ:�T�|��1��!������gMCQ�d<y(��=��;CW �||��*}RZ��:��,g�Y��Lyu$X6&e+j%tw�L����Sr�Cډc�s�EHk<s�V,h�7� ]w!���F츁P��3u~u����ۖk>X!{��:>��!s�Ǥ<����cuwB�㘶m�h�9�^��t��1�����C{���Q����"ս74���k�U[+��B<7i��d�YT���Պ؇��4o*�Hhڝ�pBm,�8̀�n3$#ٱ����]"M�<�����:c��n��@Ç��Z��q*O�d�L��.\?� 4mw����v�c{�=,8��A�I���Rl|�����I��Ռ��ҩ�D�Y?& ;��Z��W�.�p;"/�_�F��쮶!�t�kڞ���KҩNU꾸�Y)����SR���w��g#�����_E���t ��e� ,�x���������=n?}������n�o�>>���vT5��'/2#;\���g�?�;!��Ț���4V�?/���endstream endobj -3451 0 obj << +3449 0 obj << /Type /Page -/Contents 3452 0 R -/Resources 3450 0 R +/Contents 3450 0 R +/Resources 3448 0 R /MediaBox [0 0 609.714 789.041] -/Parent 3390 0 R -/Annots [ 3459 0 R 3464 0 R ] +/Parent 3318 0 R >> endobj -3459 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [97.498 367.618 132.915 376.529] -/Subtype /Link -/A << /S /GoTo /D (gloss-daemon) >> +3451 0 obj << +/D [3449 0 R /XYZ 71.731 729.265 null] >> endobj -3464 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [258.734 354.666 290.823 363.578] -/Subtype /Link -/A << /S /GoTo /D (gloss-service) >> +3452 0 obj << +/D [3449 0 R /XYZ 71.731 741.22 null] >> endobj 3453 0 obj << -/D [3451 0 R /XYZ 71.731 729.265 null] ->> endobj -1590 0 obj << -/D [3451 0 R /XYZ 71.731 718.306 null] +/D [3449 0 R /XYZ 89.664 708.344 null] >> endobj -558 0 obj << -/D [3451 0 R /XYZ 344.957 703.236 null] +538 0 obj << +/D [3449 0 R /XYZ 304.825 651.039 null] >> endobj 3454 0 obj << -/D [3451 0 R /XYZ 71.731 681.855 null] +/D [3449 0 R /XYZ 71.731 640.674 null] >> endobj 3455 0 obj << -/D [3451 0 R /XYZ 522.288 634.645 null] +/D [3449 0 R /XYZ 71.731 628.757 null] >> endobj 3456 0 obj << -/D [3451 0 R /XYZ 71.731 616.593 null] ->> endobj -1591 0 obj << -/D [3451 0 R /XYZ 71.731 575.701 null] ->> endobj -562 0 obj << -/D [3451 0 R /XYZ 252.56 532.604 null] ->> endobj -1592 0 obj << -/D [3451 0 R /XYZ 71.731 528.774 null] ->> endobj -566 0 obj << -/D [3451 0 R /XYZ 198.219 493.231 null] +/D [3449 0 R /XYZ 71.731 623.776 null] >> endobj 3457 0 obj << -/D [3451 0 R /XYZ 71.731 485.879 null] ->> endobj -1593 0 obj << -/D [3451 0 R /XYZ 71.731 427.115 null] ->> endobj -570 0 obj << -/D [3451 0 R /XYZ 267.87 389.899 null] +/D [3449 0 R /XYZ 89.664 603.019 null] >> endobj 3458 0 obj << -/D [3451 0 R /XYZ 71.731 379.756 null] +/D [3449 0 R /XYZ 71.731 600.862 null] +>> endobj +3459 0 obj << +/D [3449 0 R /XYZ 89.664 585.086 null] >> endobj 3460 0 obj << -/D [3451 0 R /XYZ 209.73 369.774 null] +/D [3449 0 R /XYZ 71.731 582.929 null] >> endobj 3461 0 obj << -/D [3451 0 R /XYZ 291.334 369.774 null] +/D [3449 0 R /XYZ 89.664 567.153 null] +>> endobj +1612 0 obj << +/D [3449 0 R /XYZ 71.731 547.064 null] +>> endobj +542 0 obj << +/D [3449 0 R /XYZ 381.763 509.848 null] >> endobj 3462 0 obj << -/D [3451 0 R /XYZ 381.061 369.774 null] +/D [3449 0 R /XYZ 71.731 499.483 null] >> endobj 3463 0 obj << -/D [3451 0 R /XYZ 419.603 369.774 null] +/D [3449 0 R /XYZ 275.93 489.724 null] +>> endobj +3464 0 obj << +/D [3449 0 R /XYZ 71.731 456.683 null] >> endobj 3465 0 obj << -/D [3451 0 R /XYZ 322.387 356.823 null] +/D [3449 0 R /XYZ 71.731 443.731 null] >> endobj 3466 0 obj << -/D [3451 0 R /XYZ 449.982 356.823 null] +/D [3449 0 R /XYZ 71.731 438.75 null] >> endobj 3467 0 obj << -/D [3451 0 R /XYZ 489.834 356.823 null] +/D [3449 0 R /XYZ 89.664 417.993 null] >> endobj 3468 0 obj << -/D [3451 0 R /XYZ 436.781 343.872 null] +/D [3449 0 R /XYZ 71.731 415.836 null] >> endobj 3469 0 obj << -/D [3451 0 R /XYZ 258.733 330.92 null] +/D [3449 0 R /XYZ 89.664 400.06 null] >> endobj 3470 0 obj << -/D [3451 0 R /XYZ 171.642 317.969 null] +/D [3449 0 R /XYZ 71.731 372 null] >> endobj 3471 0 obj << -/D [3451 0 R /XYZ 71.731 304.918 null] +/D [3449 0 R /XYZ 89.664 356.224 null] >> endobj 3472 0 obj << -/D [3451 0 R /XYZ 71.731 289.974 null] +/D [3449 0 R /XYZ 71.731 315.213 null] >> endobj 3473 0 obj << -/D [3451 0 R /XYZ 210.778 278.417 null] +/D [3449 0 R /XYZ 89.664 299.437 null] >> endobj 3474 0 obj << -/D [3451 0 R /XYZ 317.348 278.417 null] +/D [3449 0 R /XYZ 193.314 299.437 null] >> endobj 3475 0 obj << -/D [3451 0 R /XYZ 129.377 266.761 null] ->> endobj -1594 0 obj << -/D [3451 0 R /XYZ 71.731 238.865 null] ->> endobj -574 0 obj << -/D [3451 0 R /XYZ 215.507 199.493 null] +/D [3449 0 R /XYZ 332.302 299.437 null] >> endobj 3476 0 obj << -/D [3451 0 R /XYZ 71.731 192.062 null] +/D [3449 0 R /XYZ 71.731 292.299 null] >> endobj 3477 0 obj << -/D [3451 0 R /XYZ 401.912 179.368 null] +/D [3449 0 R /XYZ 71.731 243.482 null] >> endobj -1595 0 obj << -/D [3451 0 R /XYZ 71.731 136.365 null] +1613 0 obj << +/D [3449 0 R /XYZ 71.731 200.707 null] >> endobj -3450 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F33 1278 0 R /F35 1525 0 R /F44 1994 0 R /F58 2421 0 R >> +3448 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F35 1567 0 R >> /ProcSet [ /PDF /Text ] >> endobj -3482 0 obj << -/Length 1629 +3480 0 obj << +/Length 1289 /Filter /FlateDecode >> stream -xڭX_o�Fϧ0���誻����n�!ݲ���a�m�"K�%5�>��#%˒����x<�G�xdz9�@�@�GEB��h�>sFK�y{&Y�f�#s5={�F�Q$"_��#W��(�J��M��V�J�c[y�� -�^���,�it���mZ��N>�L[��D�n52���@(�c��Onh�r�Bg��z����m�"Wh��E��֑Ёn�%�����RC���*Y}9�u^��` P�!�kT^� ��:ɫ�ȓ#+������P�<�F��Q :�����>Z'W\أ�� &28m�eN��)B�d�2!��7!�"N֍c媨3�v,�:':��4̋���|:V��%͒���e����:O?� -�K���Y��W�@YoY�*�;/��L:a�J /��c��$7��(�5&6����*p����jWD��5�=�Պ�]Qs%� ܀~(���ee�c2Z��va��A�N���Rz;V�zQ�7���B��uQ�{�{.��|�<���nlk�[��a,+�@_���ڃ�����b�[��ck� �gY�?���� M���-A����F:�km��ž�YY<��b�"|� a��A���s���@����* @-�*�`I*"Ջ r(&H�+IY3�_R��>v f�Q2����N{�G�Т�0m�vC@�3kJ!-�Y�,�Z�%aDx���7�rm�7�eY��<͗M%Tk��$0˰f�ޗ��ķѭ�ag��7 -�4�H��=g6���;2�o�n#/�@eֻ�s6�}�a���fq[�b��/�q�Y��Ւ5�߾��NH5��ɔ�=���0{���;�]|r<�lx2��gɓ���C|WDp���9(�d�w����9���ձ8��u$"��xss����~����f�vr�j&�W�)�i}R�!��@���{�5��_ac��Ÿ1g�&�A��N���貶OZ�#w8���&y�����r���t8�i���ft���Lt�����>�Z��!�0G�֤�[]y_�N��L�}c�N���'A�Z���t�w` ���Y���i��z�~#�����*-�+)�k�<sJ��b�����mT��&4t��l�ċ]�*�J��i y��P62'w�Wt��?���Y��"4~�+�sO��>Û�߿P47g�$Փ�ö��#)��\]?��y͑�$& �45H=%3( J�f62Hm�ن��*rb������H���*�y��`��C '/�V����`SOǴ��.��2�`'I��ta�� -��V&`0F~�� ������p�U|�?��4�ep���0�ܞ�<� � �\&e� -�<�tɕz����C�e��b=E�']`�t���'��)��I�}E��e�U�m���a��yT�#�$�3<x�l�bj3i`P�e���r�6��YZ�ͱ�杧ٷv��x+`�QJDI�;�s�.ao�^�w)X�M$y��H�0|(�����i�ߴKJJ<���z�T�띘�C�HȠ�|9�dì@�-}�s*?��q�g[_�k�;� ��� �|L���K;,_cI�w�����1�ج�}�ruCB�y�n�����Q�V=���NCK����Aendstream +xڥX�n�6}�W�QlFu�7;�M[��b��b��A��X�.�$o�~}g8�Œ�S��p�hx8327,��ϙ/`�Cf{��W��O�Xh��@g����$������p,��Vh��f�k��O�f�Y��k��ѸL�HkXO�gZZ�g�|�7Ͳh������u�� +���8�^�3��w�p<t�}O�g�Õ�q���̛2�˂��n��qԤeQ�J�D�]5�-����MEC+Y��&g��"�e,�����k�;Y�*�h�VqB�8��F��6[�e����u�a��9�$Xh� +r=@69���U�6$GŌ��+M���xf�U��,;�$oj�\�,-h�Q��f�2��M�ѵ�s2���� c�y����\�V��t�Ͷ�OxتGz� +0��R���P�+#x�(��5 z�מ�`��)���{z�XoP�8�\ҩ�)} ��_��_��G����Aj��=��u}fސ��{�<����b��[yl9=a,1 <ЄI1�w<��K`�xcD����4L^�)��?3n�R�(q!�&�ȼ0��2��2.�n��a�nZ��N�=�B���F)&�e�������UV�^U�CEl�E��X`ѐ�|�&g��`��t%�]���d�Z���1�FS�1�ҋ�Y{,����o��o?-����}}�����r����[�-ؔ�j��T=3{X6.Oˡ��dd0�0��D�q�E�,iP����k��N�A� NǬH>45��$���+m�R|��z�ݲj���n����-�JM���@ޔ�v����T�ͨ�\-�Ld2���n�aȸ/��5���P�08�����1V2�s�a��[o9�=2�؏R��zsl?����ZGgz�i����g��pfC�t6l��ɰit�>�)���v{d��*-�������:n=��g��T��qTj%N�LX����:'�U(g� +���=�=2�t�ހ�.(d���{�ч�"���ZO��&�DbCP`MJ�#`�����c{O��й�+�M��N7*��C�TE������s�U5�ʆ���]�Z����gR���F�{�ay���u�&���J(t�':�(��>KP�UDq� +b#m��1�� �Y_�p�T6���w����(*��{g���k��di �_����* �����hhU9��C�3�>�p�H��KfA���(3��R�:�(Y���g�M�:t����V�� L�US����B ߜ>��.� z�Wm/�.��"] +��Kp�1�K� X���?H�*��#\��wV��O��0����Sfendstream endobj -3481 0 obj << +3479 0 obj << /Type /Page -/Contents 3482 0 R -/Resources 3480 0 R +/Contents 3480 0 R +/Resources 3478 0 R /MediaBox [0 0 609.714 789.041] -/Parent 3390 0 R -/Annots [ 3485 0 R 3503 0 R 3505 0 R ] +/Parent 3497 0 R >> endobj -3485 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [141.531 644.094 194.317 653.005] -/Subtype /Link -/A << /S /GoTo /D (security-os-accounts) >> +3481 0 obj << +/D [3479 0 R /XYZ 71.731 729.265 null] >> endobj -3503 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [318.972 337.225 370.159 346.435] -/Subtype /Link -/A << /S /GoTo /D (security-mysql-account-root) >> +546 0 obj << +/D [3479 0 R /XYZ 398.777 707.841 null] >> endobj -3505 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [392.313 236.881 445.082 245.792] -/Subtype /Link -/A << /S /GoTo /D (security-os-ports) >> +1614 0 obj << +/D [3479 0 R /XYZ 71.731 704.871 null] >> endobj -3483 0 obj << -/D [3481 0 R /XYZ 71.731 729.265 null] +550 0 obj << +/D [3479 0 R /XYZ 359.858 673.37 null] >> endobj -578 0 obj << -/D [3481 0 R /XYZ 164.538 705.748 null] +3482 0 obj << +/D [3479 0 R /XYZ 71.731 664.918 null] >> endobj -1596 0 obj << -/D [3481 0 R /XYZ 71.731 702.184 null] +1615 0 obj << +/D [3479 0 R /XYZ 71.731 528.314 null] >> endobj -582 0 obj << -/D [3481 0 R /XYZ 306.92 666.375 null] +554 0 obj << +/D [3479 0 R /XYZ 381.114 492.847 null] +>> endobj +3483 0 obj << +/D [3479 0 R /XYZ 71.731 484.395 null] >> endobj 3484 0 obj << -/D [3481 0 R /XYZ 71.731 656.233 null] +/D [3479 0 R /XYZ 71.731 448.847 null] >> endobj -1597 0 obj << -/D [3481 0 R /XYZ 71.731 626.161 null] +1616 0 obj << +/D [3479 0 R /XYZ 71.731 394.416 null] >> endobj -586 0 obj << -/D [3481 0 R /XYZ 408.16 588.946 null] +558 0 obj << +/D [3479 0 R /XYZ 342.285 358.949 null] +>> endobj +3485 0 obj << +/D [3479 0 R /XYZ 71.731 350.497 null] >> endobj 3486 0 obj << -/D [3481 0 R /XYZ 71.731 578.803 null] +/D [3479 0 R /XYZ 71.731 324.912 null] >> endobj 3487 0 obj << -/D [3481 0 R /XYZ 213.741 568.821 null] +/D [3479 0 R /XYZ 71.731 319.931 null] >> endobj 3488 0 obj << -/D [3481 0 R /XYZ 387.602 568.821 null] +/D [3479 0 R /XYZ 89.664 299.173 null] >> endobj 3489 0 obj << -/D [3481 0 R /XYZ 249.294 555.87 null] ->> endobj -1897 0 obj << -/D [3481 0 R /XYZ 71.731 542.819 null] +/D [3479 0 R /XYZ 71.731 297.017 null] >> endobj 3490 0 obj << -/D [3481 0 R /XYZ 71.731 503.038 null] +/D [3479 0 R /XYZ 89.664 281.241 null] >> endobj 3491 0 obj << -/D [3481 0 R /XYZ 71.731 503.038 null] +/D [3479 0 R /XYZ 71.731 279.084 null] >> endobj 3492 0 obj << -/D [3481 0 R /XYZ 71.731 491.996 null] +/D [3479 0 R /XYZ 89.664 263.308 null] >> endobj 3493 0 obj << -/D [3481 0 R /XYZ 305.215 481.748 null] +/D [3479 0 R /XYZ 71.731 256.17 null] >> endobj 3494 0 obj << -/D [3481 0 R /XYZ 71.731 480.34 null] ->> endobj -1898 0 obj << -/D [3481 0 R /XYZ 71.731 458.435 null] +/D [3479 0 R /XYZ 71.731 233.256 null] >> endobj 3495 0 obj << -/D [3481 0 R /XYZ 71.731 413.573 null] +/D [3479 0 R /XYZ 71.731 167.168 null] >> endobj 3496 0 obj << -/D [3481 0 R /XYZ 71.731 413.573 null] ->> endobj -3497 0 obj << -/D [3481 0 R /XYZ 71.731 402.532 null] ->> endobj -3498 0 obj << -/D [3481 0 R /XYZ 149.738 392.283 null] +/D [3479 0 R /XYZ 71.731 116.195 null] >> endobj -3499 0 obj << -/D [3481 0 R /XYZ 71.731 390.876 null] +3478 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 3500 0 obj << -/D [3481 0 R /XYZ 71.731 379.36 null] +/Length 2305 +/Filter /FlateDecode +>> +stream +xڝ˒��>_�[�U6G�ÒfO�yd;��I�xvk+��,Ѷ2���cݝ�@��d�{�R>A��,g��,�"�`pcᮃYZ�qfX���+&Y�h�o�~�Y,�7��g��Љg��(pg��_��Ǥ�T�X��3����̫�|^u�/���(�ſ��q;��Pđ��z��Z�`�~k��Ӊ���F�M���ݼ[�֎3��������_6�6��J�?��-��B�@�JJ�B��k_��ן?����q3!\�6:�ӎ��7hH���S��_U(�V�.K]��j�q�Շ��6���Zm�:������[������d(\�M��h-�86�=!}�0��M��W���4>���'�|Q�JZ�2����֕"��W,��ؽ�,oqt�.��Twd:w~RD���t�I��̨d�������jJ��%�v��w�R�ꠘu�.�������L7D[��w��5�:*Z���L��p��iLѪ�o��b��q�8�V&L��Lb�ı�Ѫ`_gI��T���itEcB�^�8� �N7������#�\�}5��hLt��C܇��x�?\7����)�r<�-���A���D�ÞMwdcUc�����6�V��f�5��O���X�Lh&k�W��k�%;�����|�y��L�#;_�����_�y$}��eR�aً�&��1���89^��y�$-��k�0;�*�>S�t�C1�eE���Xx�w�i��گ�Y���8��0/�2GH���(ya��m]$�-�`p�+�z�=�a��*nҍ������s��d�:9�ƅՍ|A'�]�*SO"=�ׇ�#�ˈ�8=t���wpv�"��CR���;f��΅(��Ҥ���y LG��I\!�+ωL��x� �a��;A�-������T}�S�'�p���i�oQ[\g����X��.��|'�D�'ӖK�;BnJH��g>¾S�O�7� j�.�=�+�c(�R<�'OG��!�PN)�$m���lI���x����*�����V'�A�@�c��b���jf �8��B�$�"88<V��)<�n9Ɋ��ʖ���l�:N�%ct�Fu�jR ��U��qHȈm�n̮rvp�M}�e�tw���i8PoKp���=�r�]��:S� 2�GI�l�X�����m����U`�B���i���;h�u3f{��Yb�%4ؒ���ɼp���l/��1�4�h�m[6�s�|#1��ق0Kǘ�馢��O̘�mb�M�q�P�[��i�E2L��)��3�2��&��Tp�1ꁟ�Z,�O�vɮP��Y��9-FX®]_gxQ�gZ`��ДՎ�4]%kH3�����?UVBgԥ� +]��"��̇ȇ�F�h�^'m���"�o��o�.��L)d�+7���Pޞt!<JSH�$e��钜'�OLUI'D�1����|�Bu_��a����J��q�JJ����8���*��7|�n����"$� ӠH�\v�A� o5%> +/�p֩Q�V��4ߙ��)1�0�r$�4�"�l�Sx�v���qv�I�U�_ +�Ӎ���L�l�]Pe�f��t�N�vn��QD� ��ʙ�͟��c;��[�쇏h�iK�$<��l����3u�}DޠU�Q2�� A\g�Ư��"m��$^cJ)��ak���0���H�'�_�;�t�īQV�PQ�+SHc~�#!� ��m���T��E~��Ȱ� HSD�퍽ed��"/��� 4���|B��9������!�iMQ��D�4�U>#���u�Z�i_�E2��� ����v�#3��`|����\h�*Q���̛�����|��..(��>�iCh2�%�͗��3��曨Fދ2}��9\-ox¹�)!�Ms�賂���5�>$</���Kk�v����;����;e-� ���oT �P�L�.�vϡ��фb�j- ��ci�)�?c��=�ZUC���1��(c�g�����6СH�7Tx ����7$�/Ah�7|��Rm||R�Y�Ɵ����.��+Y6�~�>���reQ�2��� �j��!����0���ΰA���!o2�tME�,yD�N�I�2k�������q@�&\ x�U$�#SxS�QΎ�Zۯ���j���� + +%�H�+��`6I+'�K�ӹ4���ö���,�5qt@n��{r�)���rZ��*���.�����0�\����j���ӑ���Tw�=Տ06g*)���<��}G�jLJ/~F��ђ\����p\���G/�q-��ps�endstream +endobj +3499 0 obj << +/Type /Page +/Contents 3500 0 R +/Resources 3498 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3497 0 R >> endobj 3501 0 obj << -/D [3481 0 R /XYZ 71.731 357.314 null] +/D [3499 0 R /XYZ 71.731 729.265 null] >> endobj -3502 0 obj << -/D [3481 0 R /XYZ 71.731 357.314 null] +1617 0 obj << +/D [3499 0 R /XYZ 71.731 596.862 null] >> endobj -1598 0 obj << -/D [3481 0 R /XYZ 71.731 311.486 null] +562 0 obj << +/D [3499 0 R /XYZ 341.27 551.607 null] >> endobj -590 0 obj << -/D [3481 0 R /XYZ 222.149 272.114 null] +3502 0 obj << +/D [3499 0 R /XYZ 71.731 539.169 null] +>> endobj +3503 0 obj << +/D [3499 0 R /XYZ 71.731 514.94 null] >> endobj 3504 0 obj << -/D [3481 0 R /XYZ 71.731 264.762 null] +/D [3499 0 R /XYZ 71.731 509.959 null] >> endobj -1899 0 obj << -/D [3481 0 R /XYZ 71.731 223.93 null] +3505 0 obj << +/D [3499 0 R /XYZ 81.694 489.202 null] >> endobj 3506 0 obj << -/D [3481 0 R /XYZ 71.731 186.206 null] +/D [3499 0 R /XYZ 71.731 487.045 null] >> endobj 3507 0 obj << -/D [3481 0 R /XYZ 191.311 175.277 null] +/D [3499 0 R /XYZ 81.694 471.269 null] +>> endobj +1618 0 obj << +/D [3499 0 R /XYZ 71.731 469.112 null] +>> endobj +566 0 obj << +/D [3499 0 R /XYZ 249.392 431.896 null] >> endobj 3508 0 obj << -/D [3481 0 R /XYZ 71.731 168.139 null] +/D [3499 0 R /XYZ 71.731 424.544 null] >> endobj -3480 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F32 1187 0 R /F35 1525 0 R /F55 2249 0 R /F61 2629 0 R >> -/ProcSet [ /PDF /Text ] +3509 0 obj << +/D [3499 0 R /XYZ 356.564 411.772 null] +>> endobj +3510 0 obj << +/D [3499 0 R /XYZ 71.731 365.779 null] >> endobj 3511 0 obj << -/Length 2097 +/D [3499 0 R /XYZ 71.731 283.09 null] +>> endobj +3512 0 obj << +/D [3499 0 R /XYZ 71.731 231.284 null] +>> endobj +3513 0 obj << +/D [3499 0 R /XYZ 71.731 216.34 null] +>> endobj +3514 0 obj << +/D [3499 0 R /XYZ 108.889 195.184 null] +>> endobj +1619 0 obj << +/D [3499 0 R /XYZ 71.731 143.976 null] +>> endobj +3498 0 obj << +/Font << /F33 1306 0 R /F35 1567 0 R /F23 1201 0 R /F27 1208 0 R /F44 2037 0 R /F48 2049 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +3517 0 obj << +/Length 3054 /Filter /FlateDecode >> stream -xڥZϗ����_ѷ�~�2��6�d�6�g�K�4��&KChO�}�T4�z��Т���T�*h�·?�K8K�q�+������������?�.cY�ϻP�,��. K#�{>�����z��"�����史�r��E������=���ߞG�(HX��f �.�x��аa~~�8O�]!И$���"O�CS����`�l�w2$bT�����]~�ÃUY���gymzI�Ǣ�]G㾡_� p�CS�������}��$�TV��v$����3."e��E�H#R/���{�+T���E���V�<Ѹ���i� W���Eߴo��|���4�Jk�-<*G��J_���:#|��}�izY칗�;�~��s�����7g�ű~��9<�F׆�pUv���ʺ�(��M��4��a��*��p�+MF�Ta��'��B�?�Z��?�7��� -��-l���,��{���M����a���^_p�蹿�\)� -6�n�5�Q�R�#�i�D��bT�ˮ���g�ʎ�D� ��Z\��^�I���[m��)�V�F�o�RrO����:�S��#�D�o}�%�|&x�ad'�5W�\�,��e� y������﹩�f/"�MrxCҮ�7eQk:�a��X.F�rp�(,(�}b~.o ��A�};�"Ȁ��w)�/_��B#e]�Aj� -�'I����T���Q�ꥂ:`H��O�4�]z��9i�#��s[��"5������c#�\�y�ӗ�y�^�r�V����=����eS�?�]�oX~;�j-��5Tx�+��-!A>8gqDi&��T+��1F�.���쏷��h\�k�Q��� - -=3_����(�`�]^G 9Lˣ35h�/�����VTp�d�=��)�wȾ�˭�"�S��Ν�`OO�}{@�"��@�!&�A6����%��A��Y���s=� ��z��P��V ���T����M��|&�2� �d�mr00��xbZ>@�����P�l�~ӏ,��~�(L���)�|�w h�����������=%Al!�b��4yU4��|�Ί -�0�'��40+!9 !�@���yH��6vY�>;�}�p�jF\m��q8aV�PC\qh����f���`WqH�6uݗ��]ԗ�d������ۮ��gpO�=�5a��t�N>46�̇k*w�:e���y-��r���h`�H#\ d���&��`�����4�VE�w�ȣ�J!���020k�4@�����yX���6��{�7D�����/���h����r���B���Ewi���XYsW�M�,���K?��>���@�դ�Sug0?�/|�f��������n{����B=��3��,�t ���M����\;�ξ* -�r6HY�l�`f5g5ĕ�6�;gmv+g �����k�I��V� DG��?�1<��j⊈�"�� ��� -Y���6���7%.�צ$��Y�����`���`��^0迾��^��3�ܘ���6��<����߷��W�5�����vs8A� -�F8�M�,6��:ԏ�c�RU85�_�<��y��0+P�VD����[�� f-�#ٰ�ne�I��j�nw�X*��: �J�< M���i^ �7�&��i?�X�P'\o���|'�jjZ�;�,j+�&�o �DP���p10+�2 �@���y����p���V�O��.<��/f-`�#b!��>���4�Q/Kcz�}������[5�ԁ�J�tGK�Wr��Ct��glZ<�_�X�_�SG�����I������Joms�� =��p_�c��?���-o���Wy���{Ր���Yj����{��Ա)��8�Ư����0���iyYw$�C*D��y����]����E�c�54<jT�kAgH��B��h:y�+y*��լE+����q���x�f)&���_�7��a���*w�@��E�?��8�}��l�Q�IR7,�Bi��_��I��[F�O8Y|�B%W�^�ʵ�F)Ky���h�X�[���bP�.���?�L�>銝endstream +xڥk����� +������O�W��-ZܦE��,Ѷr���q�ͯ�(ɒWZ�Ù!9����x}7������Mvy�6'���/;!�Mh�z}z�N����Gz�z�����~k�&�ڼ�?:_��kg��N���]���_��h_T'F}�o}��[Q�����}d�:v��^U��,�Sz��"T��Ӌ�$�I?�´B�����zjҜu���Vw�O����+�E��o<������*$�_�����}��1PT]S�}fZwg�@z(ʢ{l-Ⱦ�/ /K�R�*P�(p*ؤ��w⩜���Ae�*tn��1��������0Y�U��y�"'-��P�g&8�m�`]�*��u�I`�l�W�>�����HقOly`�����\�&�4��s@����37hW�Gq����M��&��P��&#UI8��Bx��q��u�3F(�e�&��7��XB�N�Pp����2y��T���7�ڞ���~�z�������������*��|q�S����w�$��d�*�p����T�a�ơU4q��t�WG���O]/��H��l�O�Uf�T��Աn��)�;���4m˰�n0r�jg٣���*Z�mM���\��I)�-�$|�9Wk���0���U/�Wӝ��AZ�����[g&��gb)�gC��L-Н#`^�@Tɦn[h��j�v)�ouoO�j;�`2Gw���=Dp�a�I�8�0�nB�xA36�1!+ٻQ<�5�d˒U�3�(��v�a_��zs����K^ݽ��j0cs�8Ē%-���>^�oiV�3B `��{��H�o{�y�����wo{)��o{E��-���&OR��}����g��P�搢�z���ƫdiV��3z�$�B�r&?X�@h�5�1�=����3\5���]�����R��Ċ�[���z-�[��ʸ�>��R�P�i�Q�֮Xf�������YUv��=�� b���Z�@h�5�1�Z�w�؏��oS8��#��m�C���9�?�-c�N0�6{mj��` ����$��5������6a��s�S�G � ����\M��ΐA�zȹ1�!��t!�D�s0FԄ葉F�\�3�2mq�^��j�gw�m��2��r����v.�<D��%�D���o��(~���I�;��ElZ����n洕�(_��O�������7�M�#��/�n���B�ڴl�~$V���=5Eݷ<s����F0��(9��+�A�dp\�D�Ivg����X"`��gYCAƠ=�T��HE�0;�6{֢Zx,���jD�M�co,$� ��CݳY����E(�5x�8ZniV��Qy3��H�a�=�W�X�z��"�v��M��_�� #@�+5�z�6�����!�z|&_�F�J�K�S_v�,:&��ǧz��`�xH�i��'=�+��Ȝ��qg[-�ߕ*!�j��JS��d��k�u_�'�Td��� u`|M)��J"�]�<n g؋��+�Ά7Y0�d�M����}dz'������?�~bU��d��XZ)*��r=��4Co���M�+q+��8,�6fwk +q0+�M���9�N�'r{ +Q�8˱�� ��J*9�٩��l:s��{E�KS0]�����_P�$���̏&�hPU3��P��0H;�-�g���eo>r�~�vT��~b�0l`�- N�|���EbO�@-�/�E���EL��R*��[���+��.�w�0���5��^g�1,��w��we,�i�N���v��9��9}_�al4d����?�>�������~�~��'$�r�l�z�7���>>�c���TEj������f��ȍ� ڴ�=��a�ё�;����Ӧ�G��]�ݠ��(7�o����z�j��64dR�FÀ30����dӭ��+H��o�.c���A>yPXk�gi�������zxiH �>Ŧ%�QG ��g�`��Ҋ���HM�A��9�vu3&'�IQ�v�\�?�D���0v7IB�)DW܊�,j�q����@wO � դ���d/0��l���m��s6n����l����@ַ(\���@��A�X�'C��xgr���~���6��=О�HO�N�oo�p�^��O �к�Vc&�B����/)8v.�����LgI�uY����qﴜ��L ����Ա�ڋB>u:���cjd���'I0Pp�.��7�-<3���ܯ �+f� Ha���i���P[w�G�8��H�i��dQ!T��(�o��(���V9WH:Ƌ�f|-��n�M�H�H�"�Хta����9aL�� f�L����P�5�P�F�ؓ��N�Sx�C5 +��J�}U��tJ0s�r�P��|4W?I�I��9m^n��˹��/�~��6�\�@���}�%q:��n�Dת�8��S�<��2�G�,�1�S���� �oTL5�s�p����r����+��33A|�dp�;3gQ�6�c*sm +He&]|�+��O��.����߷���G�z8g��@}y�ow9�jO�³UK�&���T��F�y,�6w�̩�?Oe��NTI���o�g��rRF؍tX�9ckT��T�Sr���ৱB�� =(�gp0��k����uQ�-���~�e��<Nd�S�$���� �p�-@��f)*`Y�o�Z�nU�<���ԃ��E����i��k�2�4����s�s�p��G�ŶU�>:��.�Xj��VsJ���AL���8���.EӀ��or/5ٟ[s������Z7"E�/��~����F�A���!L��'��V!�z�۶>��h���A��@�q�W��}�,�n�-�E��=�sq:��cDK�h=����z��P�VS������έ�������e� d�^�ϥ,2�f�!��0����G� ���SW�������M,��m����%�{��ߥb�<y���Z$�G�ȶ;0n��dϜa�� +���Q�(9X�������H����P%��,�������,r�lendstream endobj -3510 0 obj << +3516 0 obj << /Type /Page -/Contents 3511 0 R -/Resources 3509 0 R +/Contents 3517 0 R +/Resources 3515 0 R /MediaBox [0 0 609.714 789.041] -/Parent 3390 0 R -/Annots [ 3517 0 R 3518 0 R ] +/Parent 3497 0 R +/Annots [ 3521 0 R 3528 0 R 3531 0 R 3534 0 R 3536 0 R ] >> endobj -3517 0 obj << +3521 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [272.131 579.171 315.707 587.761] +/Rect [243.325 672.608 288.784 681.519] /Subtype /Link -/A << /S /GoTo /D (gloss-htaccess) >> +/A << /S /GoTo /D (parameters) >> >> endobj -3518 0 obj << +3528 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [262.114 567.623 321.927 576.105] +/Rect [141.14 554.332 205.897 563.243] /Subtype /Link -/A << /S /GoTo /D (http-apache) >> ->> endobj -3512 0 obj << -/D [3510 0 R /XYZ 71.731 729.265 null] ->> endobj -1599 0 obj << -/D [3510 0 R /XYZ 71.731 718.306 null] ->> endobj -594 0 obj << -/D [3510 0 R /XYZ 197.608 706.118 null] ->> endobj -1600 0 obj << -/D [3510 0 R /XYZ 71.731 705.903 null] +/A << /S /GoTo /D (upgrade-cvs) >> >> endobj -598 0 obj << -/D [3510 0 R /XYZ 498.095 666.746 null] +3531 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [203.157 536.399 267.914 545.31] +/Subtype /Link +/A << /S /GoTo /D (upgrade-tarball) >> >> endobj -3513 0 obj << -/D [3510 0 R /XYZ 71.731 656.381 null] +3534 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [214.225 518.466 278.982 527.377] +/Subtype /Link +/A << /S /GoTo /D (upgrade-patches) >> >> endobj -3514 0 obj << -/D [3510 0 R /XYZ 159.969 620.718 null] +3536 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [81.972 462.053 134.276 470.59] +/Subtype /Link +/A << /S /GoTo /D (template-method) >> >> endobj -3515 0 obj << -/D [3510 0 R /XYZ 71.731 605.61 null] +3518 0 obj << +/D [3516 0 R /XYZ 71.731 729.265 null] >> endobj -3516 0 obj << -/D [3510 0 R /XYZ 71.731 590.666 null] +570 0 obj << +/D [3516 0 R /XYZ 290.952 707.841 null] >> endobj 3519 0 obj << -/D [3510 0 R /XYZ 76.712 551.577 null] +/D [3516 0 R /XYZ 71.731 697.476 null] >> endobj 3520 0 obj << -/D [3510 0 R /XYZ 71.731 541.615 null] ->> endobj -3521 0 obj << -/D [3510 0 R /XYZ 81.694 508.738 null] +/D [3516 0 R /XYZ 71.731 674.765 null] >> endobj 3522 0 obj << -/D [3510 0 R /XYZ 71.731 506.581 null] +/D [3516 0 R /XYZ 87.074 661.813 null] >> endobj 3523 0 obj << -/D [3510 0 R /XYZ 71.731 506.581 null] +/D [3516 0 R /XYZ 146.988 648.862 null] +>> endobj +1620 0 obj << +/D [3516 0 R /XYZ 71.731 641.724 null] +>> endobj +574 0 obj << +/D [3516 0 R /XYZ 367.202 604.508 null] >> endobj 3524 0 obj << -/D [3510 0 R /XYZ 91.656 495.787 null] +/D [3516 0 R /XYZ 71.731 594.143 null] >> endobj 3525 0 obj << -/D [3510 0 R /XYZ 120.717 495.787 null] +/D [3516 0 R /XYZ 71.731 582.227 null] >> endobj 3526 0 obj << -/D [3510 0 R /XYZ 120.717 495.787 null] +/D [3516 0 R /XYZ 71.731 577.246 null] >> endobj 3527 0 obj << -/D [3510 0 R /XYZ 147.218 495.787 null] ->> endobj -3528 0 obj << -/D [3510 0 R /XYZ 147.218 495.787 null] +/D [3516 0 R /XYZ 89.664 556.488 null] >> endobj 3529 0 obj << -/D [3510 0 R /XYZ 76.712 477.854 null] +/D [3516 0 R /XYZ 71.731 554.332 null] >> endobj 3530 0 obj << -/D [3510 0 R /XYZ 81.694 464.902 null] ->> endobj -3531 0 obj << -/D [3510 0 R /XYZ 92.483 464.902 null] +/D [3516 0 R /XYZ 89.664 538.556 null] >> endobj 3532 0 obj << -/D [3510 0 R /XYZ 71.731 464.714 null] +/D [3516 0 R /XYZ 71.731 536.399 null] >> endobj 3533 0 obj << -/D [3510 0 R /XYZ 71.731 464.714 null] ->> endobj -3534 0 obj << -/D [3510 0 R /XYZ 91.656 451.951 null] +/D [3516 0 R /XYZ 89.664 520.623 null] >> endobj 3535 0 obj << -/D [3510 0 R /XYZ 71.731 449.794 null] ->> endobj -3536 0 obj << -/D [3510 0 R /XYZ 91.656 439 null] +/D [3516 0 R /XYZ 71.731 513.485 null] >> endobj 3537 0 obj << -/D [3510 0 R /XYZ 135.691 439 null] +/D [3516 0 R /XYZ 71.731 457.071 null] >> endobj 3538 0 obj << -/D [3510 0 R /XYZ 135.691 439 null] +/D [3516 0 R /XYZ 71.731 391.941 null] >> endobj 3539 0 obj << -/D [3510 0 R /XYZ 76.712 421.067 null] +/D [3516 0 R /XYZ 118.555 353.376 null] >> endobj 3540 0 obj << -/D [3510 0 R /XYZ 81.694 408.115 null] +/D [3516 0 R /XYZ 71.731 299.787 null] >> endobj 3541 0 obj << -/D [3510 0 R /XYZ 92.483 408.115 null] +/D [3516 0 R /XYZ 364.919 267.129 null] +>> endobj +1621 0 obj << +/D [3516 0 R /XYZ 71.731 252.021 null] +>> endobj +578 0 obj << +/D [3516 0 R /XYZ 244.469 219.707 null] >> endobj 3542 0 obj << -/D [3510 0 R /XYZ 71.731 407.407 null] +/D [3516 0 R /XYZ 71.731 211.07 null] >> endobj 3543 0 obj << -/D [3510 0 R /XYZ 71.731 407.407 null] +/D [3516 0 R /XYZ 71.731 159.767 null] >> endobj 3544 0 obj << -/D [3510 0 R /XYZ 91.656 395.164 null] ->> endobj -3545 0 obj << -/D [3510 0 R /XYZ 71.731 393.007 null] +/D [3516 0 R /XYZ 71.731 144.823 null] >> endobj -3546 0 obj << -/D [3510 0 R /XYZ 71.731 393.007 null] +3515 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 3547 0 obj << -/D [3510 0 R /XYZ 101.619 382.213 null] +/Length 2041 +/Filter /FlateDecode +>> +stream +xڵ]�ܶ��~�>����DQ�ח��6H` .|I������Z�ZQ��[�}g8�V�];W��Lr4���,_y���b�b��2? +W���[����+n16e3ù��r�%�*ei$Vw�U�y,��U,|������y��Z-���=G0Z�)US�����@�Ú;�Ǫ���ow�_��n�������x#Ι|~|�o|��0F�������T]��:G @���=5�r��������њ��!k +��HY��^T�m�i{+��v(���j��^gpҕjr_�O/zsm/7ł�~h�<���(v��Q��� �Yj�adew�j�3D��T�����,���f��/�y'$0����89�y���g�{<ݽ>��v�[�7ܱ�\r�X +�����{bV��j�F��*KcR��̊&����ew��ɝ��Q��A �߁��Pu���A�0Օ7~�q���VJOFn1��Oo�r���Qu� I')� �'�����t[u��> �^�W��^ڇXжΚw@�_P����J�u�[�������C�^��f�����"��f�ׄ��e���zhY[/�D����}����n'뷍Ҳg���4Q--��te�r�AL��g!5��:3��4�$�Q꜍��'0��`!�C���_����* �}���� +�Д�Mq��b������տ'J�3����Ѡ���f�f�K���*Ŋ��%<�<ȣ!��D$���`�QE0Sņ'�v�"A��r�s�贑����SܨA��&�]�D���s/f\sŋ�1�� =&�:ao%���p����̓��K^h/�<'�$����� ���L��-dW��~�|����$�Q +i̤m����)e?#�n�8a��,ǀ9�5�����d۵�I�Φ���v�5 .t�dWJ����˚�s:a�Z��)�XG�{x&ms���D�k+�5���̲���Z`^�Wn�r�zp��Q�Q��B��/�.��8qZ�r�R ���� [2�H�&,��li���IsF'�ۏ@��f����$�����Y`�K��a�9����C8p�<�0���?�e�������Y�3ژ�5Sh?��ݏ��xQf4��em���#�W�S���Z'�.��z{�v=H2��t��V�5{D��b .��B +���e���6�U�uܱ2�Neo���VgUc��[)�J`6�V#�0櫩��3'�N��B6�� +��6A[�﨑����*d l�qG!�y�y�n1#�Z�ja�w��K�)���)�<�h�Y� @��C���a�[C�O���W��]0А0�%��F8�M4|�':�N)��--�&�g+� %�l�����U�>�"fu�hת�����][h�4���I̅�cɂ���f�;E�A_�i�T�8e}���ֶ����C_e�$���M�FVTQ|�4-�-_��ܤ�H� +C���0!S��h�ϣ<�d՟p魪{9R4��k�7 !�������R��)�j(��� �<BY6����AB�D��Qֽ����`�n\v�)��� �IGO���ݣ;&�Ƞѓ�T�|��ф2��c�[;�`�6��[w6����Z��������}�d5V~<�r/I����6mfZhY\C�]�S���wv�9I��(�#��P��������(�̪D^ v-Oh��*�����3*et�Gb>�l��&�pM��ޯ�U�_-��3��9s��3��?f����=�#�K�,O�Z����7��D~H�F{,Hӯ�Ca^��'��/�\���?5�B�&����P�����k�6\�E} '�0�L?�O�1E|��3RP����Ƶ��w�T�i���8oUjD?��|��XO����X��J!���4�d�&X!�3��-�jYז 3��{i'�h�-����l��� =�l�pñ�O"�$`���h�]';f�v[ѻ�Mc�#:|�櫙|�C-�+�5�U�a����I?�{x����K?��~�<e1P����߶OdFN�W���endstream +endobj +3546 0 obj << +/Type /Page +/Contents 3547 0 R +/Resources 3545 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3497 0 R >> endobj 3548 0 obj << -/D [3510 0 R /XYZ 71.731 380.056 null] +/D [3546 0 R /XYZ 71.731 729.265 null] >> endobj 3549 0 obj << -/D [3510 0 R /XYZ 101.619 369.261 null] +/D [3546 0 R /XYZ 71.731 718.306 null] >> endobj 3550 0 obj << -/D [3510 0 R /XYZ 142.884 369.261 null] +/D [3546 0 R /XYZ 71.731 685.33 null] >> endobj 3551 0 obj << -/D [3510 0 R /XYZ 142.884 369.261 null] +/D [3546 0 R /XYZ 104.01 673.773 null] >> endobj 3552 0 obj << -/D [3510 0 R /XYZ 76.712 351.328 null] +/D [3546 0 R /XYZ 104.01 662.117 null] >> endobj 3553 0 obj << -/D [3510 0 R /XYZ 91.656 338.377 null] +/D [3546 0 R /XYZ 147.048 638.804 null] >> endobj 3554 0 obj << -/D [3510 0 R /XYZ 71.731 336.22 null] +/D [3546 0 R /XYZ 104.01 627.148 null] >> endobj 3555 0 obj << -/D [3510 0 R /XYZ 71.731 336.22 null] +/D [3546 0 R /XYZ 71.731 579.115 null] >> endobj 3556 0 obj << -/D [3510 0 R /XYZ 101.619 325.426 null] +/D [3546 0 R /XYZ 71.731 557.21 null] >> endobj 3557 0 obj << -/D [3510 0 R /XYZ 71.731 323.269 null] +/D [3546 0 R /XYZ 118.555 516.678 null] >> endobj 3558 0 obj << -/D [3510 0 R /XYZ 101.619 312.474 null] +/D [3546 0 R /XYZ 225.689 505.201 null] >> endobj 3559 0 obj << -/D [3510 0 R /XYZ 145.653 312.474 null] +/D [3546 0 R /XYZ 332.317 505.201 null] +>> endobj +1622 0 obj << +/D [3546 0 R /XYZ 71.731 459.968 null] +>> endobj +582 0 obj << +/D [3546 0 R /XYZ 277.022 431.321 null] >> endobj 3560 0 obj << -/D [3510 0 R /XYZ 145.653 312.474 null] +/D [3546 0 R /XYZ 71.731 422.684 null] >> endobj 3561 0 obj << -/D [3510 0 R /XYZ 177.534 312.474 null] +/D [3546 0 R /XYZ 86.396 399.441 null] >> endobj 3562 0 obj << -/D [3510 0 R /XYZ 177.534 312.474 null] +/D [3546 0 R /XYZ 71.731 392.303 null] >> endobj 3563 0 obj << -/D [3510 0 R /XYZ 209.414 312.474 null] +/D [3546 0 R /XYZ 401.148 368.557 null] >> endobj 3564 0 obj << -/D [3510 0 R /XYZ 209.414 312.474 null] +/D [3546 0 R /XYZ 71.731 343.486 null] >> endobj 3565 0 obj << -/D [3510 0 R /XYZ 241.294 312.474 null] +/D [3546 0 R /XYZ 104.01 333.986 null] >> endobj 3566 0 obj << -/D [3510 0 R /XYZ 241.294 312.474 null] +/D [3546 0 R /XYZ 104.01 322.33 null] >> endobj 3567 0 obj << -/D [3510 0 R /XYZ 76.712 294.541 null] +/D [3546 0 R /XYZ 71.731 321.115 null] >> endobj 3568 0 obj << -/D [3510 0 R /XYZ 91.656 281.59 null] +/D [3546 0 R /XYZ 104.01 299.018 null] >> endobj 3569 0 obj << -/D [3510 0 R /XYZ 71.731 279.433 null] +/D [3546 0 R /XYZ 71.731 274.297 null] >> endobj 3570 0 obj << -/D [3510 0 R /XYZ 71.731 279.433 null] +/D [3546 0 R /XYZ 104.01 252.392 null] >> endobj 3571 0 obj << -/D [3510 0 R /XYZ 101.619 268.638 null] +/D [3546 0 R /XYZ 104.01 240.736 null] >> endobj 3572 0 obj << -/D [3510 0 R /XYZ 76.712 232.773 null] +/D [3546 0 R /XYZ 104.01 229.08 null] >> endobj 3573 0 obj << -/D [3510 0 R /XYZ 81.694 219.822 null] +/D [3546 0 R /XYZ 104.01 217.424 null] >> endobj 3574 0 obj << -/D [3510 0 R /XYZ 92.483 219.822 null] +/D [3546 0 R /XYZ 104.01 205.767 null] >> endobj 3575 0 obj << -/D [3510 0 R /XYZ 71.731 218.414 null] +/D [3546 0 R /XYZ 104.01 194.111 null] >> endobj 3576 0 obj << -/D [3510 0 R /XYZ 71.731 218.414 null] +/D [3546 0 R /XYZ 71.731 182.455 null] >> endobj 3577 0 obj << -/D [3510 0 R /XYZ 91.656 206.87 null] +/D [3546 0 R /XYZ 118.555 138.909 null] >> endobj 3578 0 obj << -/D [3510 0 R /XYZ 76.712 188.937 null] ->> endobj -3579 0 obj << -/D [3510 0 R /XYZ 81.694 175.986 null] ->> endobj -3580 0 obj << -/D [3510 0 R /XYZ 92.483 175.986 null] ->> endobj -3581 0 obj << -/D [3510 0 R /XYZ 71.731 174.578 null] ->> endobj -3582 0 obj << -/D [3510 0 R /XYZ 71.731 174.578 null] ->> endobj -3583 0 obj << -/D [3510 0 R /XYZ 91.656 163.034 null] ->> endobj -3584 0 obj << -/D [3510 0 R /XYZ 71.731 140.12 null] +/D [3546 0 R /XYZ 136.092 130.445 null] >> endobj -3509 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F44 1994 0 R /F55 2249 0 R >> +3545 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F35 1567 0 R /F60 2527 0 R /F54 2322 0 R /F23 1201 0 R /F44 2037 0 R >> /ProcSet [ /PDF /Text ] >> endobj -3588 0 obj << -/Length 2148 +3581 0 obj << +/Length 2338 /Filter /FlateDecode >> stream -xڅXm�� �~�b�~� �h-�=AQ�.IsA���")[3v�o��n~}I�����m����h�"R��M�r�J��0�\�$���`s�����,�e����ݻ���p��< 7��&R��e�IC%�Xmv��އJ�VŁ ������4�d�y������ݭ:�0y�i�"sc�J�v-�2F�3����j[�݃�ͥ�&c����o>WfI��D��Ae����#˸C����HO��/3��8U��b��Ă�8���?�v���-Aލ�;��Ȁ��ИāD��I�R��=zaF�5ug��<��<�E�>���w@e����^O�5�} r�ۡy!z�;T q�7�/A���H��@���d�g3��!�Kg'@��,k�k�uɜ}���{�F�.�Y�6@g�o�*��kW_� �p�@��ս��4�yd��4�)0�_�L��H�l�$�Hsud���Bȁ�ʐW�=�lD����k� -R%�ћ��7իr/H���0pC�u7Y �߳3jbW �� U\;�V���P4{��L�M�� =�����4�'�q=�UF�xW�(��1&�|͜�� -��o�5�ݑ>�� �^*�0E -;Q�۾|���[ۘ;J��%Õ���z6�%���|�?� ���go�����U,�h1lW���=��&��/D�ahj�2�4ӣ+����T�B�ѭ���ST�dxW -t����@�>�� ����V#:ج==��T����B6�^�&A��=����o�ILYj+�c�Tۊ�l��������$>�8�ƾ�a�.��B��9�l�Y�Эy��a���k�c*t%[=[q[�H؈�E�;5:5�!�&S�#���A$4 �/]&EH��_hl�����LbЗ�����0������h\�Ea��yZj��z2$��]�zl���;ރ�#]\49UuQ�r����H�s��"��G����"oj� qm1i�<�d�y�(ȃ*2�2^y��0�� -�VI�N�o���F��i���5P���Ef{!t�ؼ���u�J��D���Dn�],LC�Dٕ6m�.>�]�.�x�C�8t#��TQ4�I0�Lq���6$����p��k�X��10��fH chn��2A��n�������%'ڗ�R��z�4q�}��_�I��u�&��t�(N�y}�����Q"0k/ЋY�@���'�))K��$��o_J��p��%�kz]�܄T�M�tS�L8r�v:��b��h]����uuI������l�w��Y��A�6��?_��빢��sxhB쀱���.Z�[�C[WC��܁��Ҙ��8��3�Cӝ��~t �;��;���3��J.����g�ʫˀb���*���m���p���6�UW��h{�X����ρ��1"�̗'�mM�ۮ> sɿ~"�Z,�ș���W�:�-N[��E�ϼ���N[a^��`o=����q��%�;߅ �x Q��Fι���K��j 2����R4A����0y��(ܸ�-�b@|��b<]�bx�Eks7�Cv{��di�=Bc�j�TM���& ��Y+��*��Jdq�p!L���ɸ�õ�/����E.���f��$�����Cg'���l���"�"��hZ���?��w�,�kl0���}' -̆��jMQ=Y�`�W$=}i����Gnq��ʶ��-�E�0X"LW�y��áܩ#����\]A�|,k�����Úzeo�=�����������E�J�k��:O,Iq2�-�$�H�>� ������~�r���Xĩ�7#<��5��r�q����qԥ�f�Hፆcߔ�CU�e�=�R)��pt�{��܈��{�K�p�;�2-��q\{Q�Q�:f %�Ȭ��F���l�����Մx�y����@��p�, ���~���~a7�v��S~����)i��+��4Ŀ,�0��x�9�9���w�U{��r�z(�h�;�"��w}~BK��M$x�����i�,.OC���w�Yfe��@���Őޥ�m����G��O�Q9��P ���rb�$��>���Ώ��; -z�Pu)�W��f؈��T�6��ǒrn�;���-'AM�x݆��}Q&2hs��1�,r�����Բ �$��学����Xendstream +xڭْ��}�B�2U5��g*/�u��_�x�I�?P$%��+�~}�ɑ��d횚b���n4��7.��M�Ud��%��MV?�����A�NHv+�wO���IT���q㻮��dOŁ�yʿwޟ�n,���\�(�~��eS�/���M[�>�U�nx����O���D*�ͫ�Y���h��nӍ��}R��\�@�:Sw�Ӽ�A]��6GX;Љ��r��ǭ�{n'&Jy�UE�0X6Øڕ���M�ŭ,@��IƳ�Һ�I��e+<��vL�QL�tN�/�A��\�k��<.�}�j;��DN)o�/�:vF JB�L +z�W@��`�̃�͐��Q6 c[���TE�I�:����V�A�-c�lF�d��N#ϑ�ky+��E�� +�9�)�|-#t�����y^^3����94��69�%1���&}��e: +�\��ـ#BP ����0��ݷ=�7�v$�G�m��P6Y�����h�'�� +�O_�gm-T���a�)l9ކ�C\P���]����@^d%�<�kGA��N���Վ��.B��B&ط��w,ۧ��� &}Ÿ�|��c�O$&y.Y�q�\_���gdz(F˕��VX�#�$��t 0[�⾫|?!ōҾ2�2X;ߑf��`8 3إc�'}.a��@h�X%��N�7������q���g������3c�8x d�v�egB��]���/`�`0��Z���l����D��+2��i�伄S̩`i�gSvf�t��Ǿ��\�ya�Y���~h�B!���I�h���"�(���()� �������wf�Ca�9��Yq�=^&�j�H����Nr�;Ꙟ�>c`��q����_.O%gK���)!����E�{X���ŜX�0L�������C%h�w����%���b)qU��fk��F�崾s�o�ъ7Y��ڶ�tjS�y�+�)�+_�9ߥ���Y[UE�njh<f�S�E�K�����A��3 �!��r|f49@!"1�a<ݫk41��@G5q$��8��d�`�ÌV�j��� �B�<&�r��iJ�骴a�&�-O����ThiC�PD�"��Jb�?b�/����� 4B9��^��� �d�f&��")���/��N�.�rIgb$~ ��N �=� ܶgx����q"�4H��,�>wO��s �=>��{y 9�e]H �9ࠕ�&.X�߶(q +�mɂ�T,���]�d�/�����5es������Z����]���2K~N���u�G��!Σ�4;`�^�̧���ֳК�|j0]� �7�ɿ]i�qT��-�H�ΉE����0�=���П�W�*����m*�zKh���(�a(U��*�\��p���Bw /J����eC�u����S���r���K�K);ᰃ�$�7˺���4I�DZSuK�������Þq<���m��u��SH�y���qYVyy<��'����j8W��Mc7�2h���)��Yt��-�<Mͧ�c�+�Q_���ο�y%'��]��ӵ����ݯ).(籤��J�S�!ѫ���� k�d�vL�AV�<E����1S���7r�� +"c�PE�����>|�����f� ����$�a�vmub6}�9>|x��� d�0�_��k�.�e���@p�����yh�}>DW+��߀ +h���b�S!%s�k�ֱ�b���� {�;LF��5v��Md/�0I��w%���%���Մ�(ɝphs(R�-��B�cW+K�?�bj�LE�a�g�oI�ӹ�(����x���:n.AL��=��T�w�N�E���?U9#��'�\�w�NT�/���0ܔj�q�Ap�泩�)�vGז,n.[|s�����R/�*a����l$$� y��Wlpl����fx$Ơ�W�[�W�f$ѩY|)j�K�p�Ʃ���n^�|L7�8�̐���>?����t��~��˝�(��/���-�.���&7�7���^ܽ�{��?~KV;m1�s��P����^�%�j�&�??̯Q�d��G&����B�7*����s���X���cCQ�m������ +�P��.R��%�����ʷ�ǫ�(�M��b�R26w��F�z��J���sݫb:pU�[�!4M��Et�kq�!ʣH�^Ĵ)��������-�/lT<�}��W��P�J�h�Ba=o;{�|���(V8�|�&�am�rൾa�\;ULqu������F4�Z� �ȅ�te����,�2�g�ً,�[���%ƇC +|��{�?g����x�B��P�o[7�C���J�m(�endstream endobj -3587 0 obj << +3580 0 obj << /Type /Page -/Contents 3588 0 R -/Resources 3586 0 R +/Contents 3581 0 R +/Resources 3579 0 R /MediaBox [0 0 609.714 789.041] -/Parent 3610 0 R -/Annots [ 3595 0 R 3599 0 R ] ->> endobj -3595 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [179.678 666.905 232.014 675.387] -/Subtype /Link -/A << /S /GoTo /D (http) >> +/Parent 3497 0 R +/Annots [ 3599 0 R ] >> endobj 3599 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [349.173 505.121 368.62 514.032] +/Rect [271.86 303.056 336.659 311.646] /Subtype /Link -/A << /S /GoTo /D (gloss-dos) >> +/A << /S /GoTo /D (upgrade-cvs) >> +>> endobj +3582 0 obj << +/D [3580 0 R /XYZ 71.731 729.265 null] +>> endobj +3583 0 obj << +/D [3580 0 R /XYZ 71.731 718.306 null] +>> endobj +3584 0 obj << +/D [3580 0 R /XYZ 71.731 675.303 null] +>> endobj +1623 0 obj << +/D [3580 0 R /XYZ 71.731 644.419 null] +>> endobj +586 0 obj << +/D [3580 0 R /XYZ 264.948 611.108 null] +>> endobj +3585 0 obj << +/D [3580 0 R /XYZ 71.731 602.471 null] +>> endobj +3586 0 obj << +/D [3580 0 R /XYZ 496.728 579.228 null] +>> endobj +3587 0 obj << +/D [3580 0 R /XYZ 415.635 566.276 null] +>> endobj +3588 0 obj << +/D [3580 0 R /XYZ 71.731 507.333 null] >> endobj 3589 0 obj << -/D [3587 0 R /XYZ 71.731 729.265 null] +/D [3580 0 R /XYZ 71.731 473.524 null] >> endobj 3590 0 obj << -/D [3587 0 R /XYZ 152.136 708.344 null] +/D [3580 0 R /XYZ 104.01 461.968 null] >> endobj 3591 0 obj << -/D [3587 0 R /XYZ 457.305 708.344 null] +/D [3580 0 R /XYZ 104.01 450.311 null] >> endobj 3592 0 obj << -/D [3587 0 R /XYZ 322.488 695.392 null] +/D [3580 0 R /XYZ 71.731 449.096 null] >> endobj 3593 0 obj << -/D [3587 0 R /XYZ 71.731 693.235 null] +/D [3580 0 R /XYZ 104.01 426.999 null] >> endobj 3594 0 obj << -/D [3587 0 R /XYZ 71.731 678.291 null] ->> endobj -1601 0 obj << -/D [3587 0 R /XYZ 71.731 640.897 null] +/D [3580 0 R /XYZ 104.01 415.342 null] >> endobj -602 0 obj << -/D [3587 0 R /XYZ 369.383 601.524 null] +3595 0 obj << +/D [3580 0 R /XYZ 71.731 390.622 null] >> endobj 3596 0 obj << -/D [3587 0 R /XYZ 71.731 598.332 null] +/D [3580 0 R /XYZ 71.731 368.717 null] >> endobj 3597 0 obj << -/D [3587 0 R /XYZ 71.731 581.197 null] +/D [3580 0 R /XYZ 118.555 325.172 null] >> endobj 3598 0 obj << -/D [3587 0 R /XYZ 71.731 533.181 null] +/D [3580 0 R /XYZ 421.576 316.708 null] +>> endobj +1624 0 obj << +/D [3580 0 R /XYZ 71.731 273.168 null] +>> endobj +590 0 obj << +/D [3580 0 R /XYZ 295.902 240.772 null] >> endobj 3600 0 obj << -/D [3587 0 R /XYZ 348.289 494.326 null] +/D [3580 0 R /XYZ 71.731 230.407 null] >> endobj 3601 0 obj << -/D [3587 0 R /XYZ 301.416 481.375 null] +/D [3580 0 R /XYZ 355.306 220.648 null] >> endobj 3602 0 obj << -/D [3587 0 R /XYZ 370.113 468.423 null] +/D [3580 0 R /XYZ 71.731 195.577 null] >> endobj 3603 0 obj << -/D [3587 0 R /XYZ 478.765 468.423 null] ->> endobj -1602 0 obj << -/D [3587 0 R /XYZ 71.731 438.371 null] ->> endobj -606 0 obj << -/D [3587 0 R /XYZ 171.235 395.274 null] ->> endobj -1603 0 obj << -/D [3587 0 R /XYZ 71.731 391.443 null] ->> endobj -610 0 obj << -/D [3587 0 R /XYZ 413.668 355.901 null] +/D [3580 0 R /XYZ 104.01 186.077 null] >> endobj 3604 0 obj << -/D [3587 0 R /XYZ 71.731 345.536 null] +/D [3580 0 R /XYZ 104.01 174.421 null] >> endobj 3605 0 obj << -/D [3587 0 R /XYZ 401.183 335.777 null] +/D [3580 0 R /XYZ 71.731 162.765 null] >> endobj 3606 0 obj << -/D [3587 0 R /XYZ 457.301 322.825 null] +/D [3580 0 R /XYZ 118.555 119.22 null] >> endobj 3607 0 obj << -/D [3587 0 R /XYZ 239.311 296.923 null] ->> endobj -3608 0 obj << -/D [3587 0 R /XYZ 71.731 289.784 null] ->> endobj -3609 0 obj << -/D [3587 0 R /XYZ 319.244 253.087 null] +/D [3580 0 R /XYZ 297.118 110.755 null] >> endobj -3586 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F35 1525 0 R /F23 1173 0 R /F44 1994 0 R /F58 2421 0 R /F32 1187 0 R >> +3579 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F35 1567 0 R /F60 2527 0 R /F54 2322 0 R /F44 2037 0 R /F32 1215 0 R >> /ProcSet [ /PDF /Text ] >> endobj -3614 0 obj << -/Length 2400 +3610 0 obj << +/Length 586 /Filter /FlateDecode >> stream -xڝko���� -㾜\؊�~�(���v�"�n9E�(h����E��M�͋2%�IQ��Cg�y��,��p��u�h�G�t�����||ʊd��4xbr��k��gKg����}��Y��t;{��\�؏���9���pT�V��e��x���_��:0�Cw�oQ�j����n�ڏ�w�m��5m���P?Vm=���]����l�oW�PF���P@�|,��2 c��L@��T�<�TQ�lQ�M}R�0d@W��kt-��Q/���磮�l%+x!0+�ꦵL�V��u!��X�?� -���A�%�F�6 �l��48�����T���wx=V88D��w���I�l�o�";"��^LǀB����̜d���K�"�E+�Ⱦ��E��<M��g�32�y�g3�R������ނg+� -8"f/��"Co%4*���*"���=��&Fj<�� -��Jg�iT]�/�8*�,��1ʮ�p��^����l�+�--�����6��{����+��+���iK�"����f1����|QS�Gp���*�]~����!�O��'Tӓ���;�,8�MV;��7�4�=�#q҇�K3�F�N��Yf:`��>��[6��&�ʆh4NĂw2�2Y0�n������y@[�l&'�?��3�4ѕ�;�p�T������UK���^�@U��0cʵ.A2 ��a<@L���ֈX�M�f�/??1��0��tur��a�|A��!���w�Z�ǐ���|�·+�b̂l��~~��p��1n2��e�G�rW�*;ޑ9����R뭿0�A�H��<&K��Nc���AQ�+^���Z%S��ߞ����{�-eв��S�5��(��YcI)� ����������c KQS��S~,�!B���Rh�&3�AE! z=������W���Q���[T#������ �8����"��J���x����2���x7�#N��پn�57�C����M�����}��{�-��;��c?8��,�f���P<��u�1���d�+�E�A -�D\c-��}=���"@��p�jK�j�Js���ɠTV���AW�&s[ƫP�YA$CC����=αԶBfm\�x|VM#�1�ŵ#�q'y�f�rsb���l�`�cZ˃�����cr"Ȏ�:`f"�w2<�vI���?i���e��6���P謹e�v J�2� ^o��k�G�:�0�mi���'s��c��0�8�Ⱥ\��1�V�hrg�֜���N��A7;��ޮ�b�bps)pa�D��j}����F�U(��umm����Hl 8�J!wf�Fᔫ��h����H*������/J��y��;�d�P�W�I=��b��}^1�GP'HBɌ�R� �O 8�e�Ӫ&�!xȄq���Ue��z�Q�?�uxC�d�z"��x���&/�1�m䒅/��:��;����\��4�]as��ب�V��R��R����q�0myX���8�`�.��6���NQ�J���j��UEY;���.�k�FR����ȺR�<�:���c�X:$cr!.��`���/�?0A�B>v���Sb�Lxn���E~��# ������9~��ʕ�o6���n]Lֵ��ɛ�m�!;,�?����]8|�2�⓫�sa~2\ E��߲o������[�^�v�l�6���. -!<�.sY�!��#���Y�v��3���u*'��G����L�`�Yq�B@��Gj���>�,�W�g�H-�G��֮��t���Ǘ�ܟ�����:�e��ݭ�z��`���o6��Njul�ˣ�{�^ޔ�3zl�����Ys+��%�67����cސ7���� �d�/y��ByIA����s�S/� (,���=/�{kd�XC��ܫ���#�;��?կ�^�X��^M�I ��+-@�_*���Dr��z^�0�SC���S[[�F֒jm����>tº�q}�����f1����l�Zf�ڱ*y������;���Lb�o��Q��܅���Z���&I"�}yS��5pt�k���Z -�e�a�ρ�#��$]9!�:�7�֊V��2��C/h���G �N;�0�>ۢ��c����RQ��=v��M]��R�)�N+2��}��1dI���p��eK�����T�U -��@�p -�˰//��"Q`;z�ꤤ��+��)�@!�E�g{�n�yyδ��h��.�O~��c��1gW��ۜ2���b6���_7�����/�ljٽLd��|�K�1�q� 1��_���.�st�Y_�^*��4��{[� ��J��)�I��?n�Ѫ�da��Ʊ��fz�RB��5� ��J6�&\O�c^��,�J�i�0��P����ޮ9�I?�endstream +x�}TM��0��W ��F�8Ƅ��5�X�Ro�u{p����`m}��d�M�v�<f��D�$����Ȓ�MU�BDG�<,b,��|����Oi��ܤ�����(�<���d�����F�^�Rf���wuk;;n�#B�)N��m�}Y|�=��Ҝ�E���3�F��/��m�����,��!^�� {rS�d̨X +�+N2�1T��v +��y���T�����QY)o]7�#�z���D075uw'#�L%��a�p� ��N���!�8L�~60��d��4�#���vοh#c�^���e"yI��9�A��%�����L���x��C1��ZDu��'o�s�A��k��P�����&J2�Vӷ�V#�2�xU���϶��Be�h�1�(2�,r��˃d��v7���.A@XSA�����m�h���'�Q5F�O\ӸXf�N�Lf���� �]�S=t�VyF]�:��Y_��Cl�q��;d<�y�����)����ju:�b��p;K�0��v�YV�u�8�O�o�7���ș��>�t�/����B��p2Yp!�IB����q[�<6Dendstream endobj -3613 0 obj << +3609 0 obj << /Type /Page -/Contents 3614 0 R -/Resources 3612 0 R +/Contents 3610 0 R +/Resources 3608 0 R /MediaBox [0 0 609.714 789.041] -/Parent 3610 0 R ->> endobj -3615 0 obj << -/D [3613 0 R /XYZ 71.731 729.265 null] +/Parent 3497 0 R >> endobj -1604 0 obj << -/D [3613 0 R /XYZ 71.731 718.306 null] +3611 0 obj << +/D [3609 0 R /XYZ 71.731 729.265 null] >> endobj -614 0 obj << -/D [3613 0 R /XYZ 320.829 703.236 null] +3612 0 obj << +/D [3609 0 R /XYZ 71.731 718.306 null] >> endobj -1605 0 obj << -/D [3613 0 R /XYZ 71.731 692.184 null] +3613 0 obj << +/D [3609 0 R /XYZ 462.063 682.441 null] >> endobj -618 0 obj << -/D [3613 0 R /XYZ 205.304 651.159 null] +3608 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 3616 0 obj << -/D [3613 0 R /XYZ 71.731 642.336 null] ->> endobj -3617 0 obj << -/D [3613 0 R /XYZ 506.431 629.6 null] ->> endobj -1606 0 obj << -/D [3613 0 R /XYZ 71.731 583.608 null] ->> endobj -622 0 obj << -/D [3613 0 R /XYZ 317.599 540.51 null] ->> endobj -3618 0 obj << -/D [3613 0 R /XYZ 71.731 528.072 null] +/Length 2511 +/Filter /FlateDecode +>> +stream +x�}Y[��6~ϯ��N�cF������l���t:�>�m��EW��x�~ @Y�4�� ���t��Y���Q:M��U��c�_�B���T�D~0�N�Lm�h��qx����:Z�@��f��Q�x��X~w(N��Vk���X���_�4�>�r������`�-6j�F�/X�!.V��Ƭ��&\�v.�2�;����`�=��QáL��A�ɒ�4�`*ad�"/�d�b��=��s <uي�,B��m��E�y�"�FsL��vf���A����+���U��:#������M�Ɩa��kL ��-��3\x�SgS�� �c�3U1���fLL[;�L[�j��F���Sg��L_�t��� +��:3�Ǻ��q����]91��n�/O{*ʃ������$09��EKr�#�M)R�KNʵ��9�v�mk*��g,�)g |[���z��$[�(�;���&�n����:�m��S:�P�b�h�z��ђx�,���[�x�|0<��vd&#h1�^��'w�u���È���]�?�-,��j���IgT�U��E�'�J�� ����8���<8��Yy-M��⥌Z�Hj�6K.Ȁ���8M�3��߽i���9�B��]�pΜ���|Q���dX��E(1-Kw;����f��pC;�V�} `k�A��8|������9�4�X]��G��)u<�AV%v��,��G�(%D=����U�/�i�� ���g3�����lF��cY�^`�$�pI'��L�����ɘ����ɉ�A!dǑ���'����1J�/Z �t�H���� �U(E��KQqU��ʴ>VQ���h��LO�=���~������+�F����@�:q\8b���"���o�U<S��A�[����v��o�&OA0�dِ嵎q=R?�/H�w��X��LsHi;�R1��;/���x�7�0�S�H���pm���:7�D.&���tA~���]Ƅ;$�v��Ҷ��~���bɺ0�i�=g�JYf�x�A�s p��B:#��;6¸�z`��#���8�t7j��L&��>���FȽ�xF�±W�h�A�1ܻ�4�BOe�����hYQ�rʼn��m��m������*I�������T��̰Kh��?8F���C��Mh�BK)J���y����INqc]$��Dȩ1 R������)_� +��P^�[I��(]�pX.07�}�p\ 7�8��I��M���Y~��*�8���7�ߖ�ۯ����[�t�����Lś|��̳��mAH�3wY�W�6$�*̑NӍ�0��K�&��܉����|�*3�Z�n8�Ý��)�%�"+g�,U98qSq�SuoN\]�,�������^��D� +e�����<`���l#D�������Z�Y���:k|c)�S�Lk��:Ӝ�I�觾��.}���b�s�A��*��M�š���ot ���r���)������vZ�Ph�Sq:�q9�Qo�L< +O�����-#n���5z�;����|U��� ��U$�P�C�l!f!�|�������;Μܫ8]4o]��l�=b'��Z�:�r�m����y'A�ܒ�?�vĥy��di���!;0u�G4EGY31�x��=`0���[�ǻ���u��+��k�cmDM�� +�6C��7�̺tw�4q' +�z�_��z#G, +��d��IX�p�0�ח�pݎ�J��Z�����o��X�F�ހ& +w���k�C��T�.�� +(����w��ί���� �?�t+S���D���ʋ��G(�e7)����$��L\�F*�g��~p���� +����F.G���RY�L⨢_F�S���o;����N'��}�FKKK�!����K7D8~�q�A̬��������l)�n�Y��w +d�ұ�#sKʜ��[�Q�"�Rc�8��z�5IT��Pz����{��N7<�4��c*W��8��PK� +JzK���I��%K�s��pR�C�H�a�҄��I���Ҳ���eP��M�F/?���I���K��W[̽_r�~�7�'�~�� ����檭��b�r�t/���R�"I�[_-�RL�m�j��P=[2lc�H�͟k|�4[�S\8�|�#G����2Q��ݓ](}Ĕ*�'����Ǣn���g�r�/�o)���'@�]}/J��䯋���DO@()`^����s�V�BXa=����mϏ��<;�[��\Q���=�MW���?$� {(f(�R^�^�^���TFb:J����jlOt�7��K+�W$ +/�^@��sK�:J�j�s_� �ڡX�`2��]{�b#_�s#��pa�&��}�{Pi��83��0�c/W���P?�;���S����~�`+[��;i��AK +��\�.�;8��9��n�<�##���g[<�X_H��D#+iτl�D����*���Y�`endstream +endobj +3615 0 obj << +/Type /Page +/Contents 3616 0 R +/Resources 3614 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3642 0 R +/Annots [ 3623 0 R 3628 0 R ] +>> endobj +3623 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [97.498 367.618 132.915 376.529] +/Subtype /Link +/A << /S /GoTo /D (gloss-daemon) >> +>> endobj +3628 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [258.734 354.666 290.823 363.578] +/Subtype /Link +/A << /S /GoTo /D (gloss-service) >> +>> endobj +3617 0 obj << +/D [3615 0 R /XYZ 71.731 729.265 null] +>> endobj +1625 0 obj << +/D [3615 0 R /XYZ 71.731 718.306 null] +>> endobj +594 0 obj << +/D [3615 0 R /XYZ 344.957 703.236 null] +>> endobj +3618 0 obj << +/D [3615 0 R /XYZ 71.731 681.855 null] >> endobj 3619 0 obj << -/D [3613 0 R /XYZ 71.731 493.048 null] +/D [3615 0 R /XYZ 522.288 634.645 null] >> endobj 3620 0 obj << -/D [3613 0 R /XYZ 71.731 490.891 null] +/D [3615 0 R /XYZ 71.731 616.593 null] +>> endobj +1626 0 obj << +/D [3615 0 R /XYZ 71.731 575.701 null] +>> endobj +598 0 obj << +/D [3615 0 R /XYZ 252.56 532.604 null] +>> endobj +1627 0 obj << +/D [3615 0 R /XYZ 71.731 528.774 null] +>> endobj +602 0 obj << +/D [3615 0 R /XYZ 198.219 493.231 null] >> endobj 3621 0 obj << -/D [3613 0 R /XYZ 71.731 485.91 null] +/D [3615 0 R /XYZ 71.731 485.879 null] >> endobj -3622 0 obj << -/D [3613 0 R /XYZ 89.664 465.153 null] +1628 0 obj << +/D [3615 0 R /XYZ 71.731 427.115 null] >> endobj -3623 0 obj << -/D [3613 0 R /XYZ 128.486 465.153 null] +606 0 obj << +/D [3615 0 R /XYZ 267.87 389.899 null] +>> endobj +3622 0 obj << +/D [3615 0 R /XYZ 71.731 379.756 null] >> endobj 3624 0 obj << -/D [3613 0 R /XYZ 171.417 452.201 null] +/D [3615 0 R /XYZ 209.73 369.774 null] >> endobj 3625 0 obj << -/D [3613 0 R /XYZ 71.731 450.045 null] +/D [3615 0 R /XYZ 291.334 369.774 null] >> endobj 3626 0 obj << -/D [3613 0 R /XYZ 89.664 434.269 null] +/D [3615 0 R /XYZ 381.061 369.774 null] >> endobj 3627 0 obj << -/D [3613 0 R /XYZ 71.731 406.209 null] ->> endobj -3628 0 obj << -/D [3613 0 R /XYZ 89.664 390.433 null] +/D [3615 0 R /XYZ 419.603 369.774 null] >> endobj 3629 0 obj << -/D [3613 0 R /XYZ 130.164 390.433 null] +/D [3615 0 R /XYZ 322.387 356.823 null] >> endobj 3630 0 obj << -/D [3613 0 R /XYZ 269.817 377.482 null] +/D [3615 0 R /XYZ 449.982 356.823 null] >> endobj 3631 0 obj << -/D [3613 0 R /XYZ 71.731 370.343 null] ->> endobj -1607 0 obj << -/D [3613 0 R /XYZ 71.731 339.459 null] ->> endobj -626 0 obj << -/D [3613 0 R /XYZ 252.009 296.362 null] +/D [3615 0 R /XYZ 489.834 356.823 null] >> endobj 3632 0 obj << -/D [3613 0 R /XYZ 71.731 283.924 null] +/D [3615 0 R /XYZ 436.781 343.872 null] >> endobj 3633 0 obj << -/D [3613 0 R /XYZ 71.731 261.851 null] +/D [3615 0 R /XYZ 258.733 330.92 null] >> endobj 3634 0 obj << -/D [3613 0 R /XYZ 71.731 233.791 null] +/D [3615 0 R /XYZ 171.642 317.969 null] >> endobj 3635 0 obj << -/D [3613 0 R /XYZ 71.731 228.81 null] +/D [3615 0 R /XYZ 71.731 304.918 null] >> endobj 3636 0 obj << -/D [3613 0 R /XYZ 89.664 208.053 null] +/D [3615 0 R /XYZ 71.731 289.974 null] >> endobj 3637 0 obj << -/D [3613 0 R /XYZ 89.664 208.053 null] +/D [3615 0 R /XYZ 210.778 278.417 null] >> endobj 3638 0 obj << -/D [3613 0 R /XYZ 89.664 177.169 null] +/D [3615 0 R /XYZ 317.348 278.417 null] >> endobj 3639 0 obj << -/D [3613 0 R /XYZ 71.731 177.169 null] +/D [3615 0 R /XYZ 129.377 266.761 null] >> endobj -3612 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F33 1278 0 R >> +1629 0 obj << +/D [3615 0 R /XYZ 71.731 238.865 null] +>> endobj +610 0 obj << +/D [3615 0 R /XYZ 215.507 199.493 null] +>> endobj +3640 0 obj << +/D [3615 0 R /XYZ 71.731 192.062 null] +>> endobj +3641 0 obj << +/D [3615 0 R /XYZ 401.912 179.368 null] +>> endobj +1630 0 obj << +/D [3615 0 R /XYZ 71.731 136.365 null] +>> endobj +3614 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F33 1306 0 R /F35 1567 0 R /F44 2037 0 R /F60 2527 0 R >> /ProcSet [ /PDF /Text ] >> endobj -3642 0 obj << -/Length 3673 +3647 0 obj << +/Length 1630 /Filter /FlateDecode >> stream -xڭ[�۸ ���b'3��隧��~��=�d�tz�����Yr����__��%J&�4���H�?@���7��7�/�~�����8��n�����)6L�1h����7ax��$�����P�Ir�������~����C~�e�������ҕ�����U���}��_ߏ�q��m^�I�\dj?�q�L�Q�x�Y��������_��o�t�.�D���_|+�~d�U�w���6Gc&k�4��Ɔ������P��K�sW�P����$~�e>�������L��==�:�O�3t���� f�y��X�^��'w�mw�E_��x��%��|xܴ���lK���[���'�1�����S�uOk�[5�NST�~"(kn�}a�.K��-��} ���&�P$�?.s-ۼbȮ$�@������o�]=���"K�;����}�e_<�o^�Ս^���7u^��3��< -H�.�a72�1�e)}w�� �#��*��-?��ҭH=�&I�y����dc�(K3E��ae[�$� k�;b�'gئ,�E�w}ރ�oB/Y��R0����`�Hآ�H�۔��� ;I��o�ԒF�����E_=S��!��T�R��m�<Þ^ʎz˚�7�CֈJ�INVǴR->RM��G��)�R?c��o6<���-;���6��6KI����p��G��%CE�T|$Q�����g��iPzL/w茺���B9h�׃��G��l��P�tj��|�ЁQ�G��+2KxlZz�kM|�;5o�g��WkO����a�TX>܌�q�������������}e��~�GOZ�o:Yw��C٧�����`�Gh:&(�v;�����ಱN4Nce�O�4�s��ƺ����}+���8���`�X�3E��9mSz�Zٝ��Fj��ɂ�����b��8E�E"��E=�8E�$�z��9�uQ/�m�6�_�tG�~ : ->�&�L���yb������~�?7:a�O�~�%�E�4.�k�Q쒾�����د~���E��&��q���Q�MQ棷1� v��y�oJ�RĸN�S� ��itY��S�L�3H�>Ǻ.��M����x��g���PDa:rSKtн5������p���?:�{"����h��d�5u���8�6qدƽ���6��&o�!����)�&ks�^�b��n -k�t2"��A�����j������)�=�eJ�t�N���y����D6�4Υd�I�\�s��K���-������Ïb����Жr��c�n��0 A�Dz.���{\l*rL�����=�:j��Ǥ�z�eq�G���[$Č�p�����U���I-�M[jj^Î��P���� �W10�ʌ�6T{P��c��r]����K�J��7��k�]�.;(�z��" �x��ƩgL�S�:��뺞-�mzf`� '��q!��Yt- EF�"�]�V{WO ��(¼�m�ԅ����� T.�8�P��&�FY(��Õ+��Ar�,�Ap���Z��eYb[�����:���;{�&"����G����zImh��"|Q9-�*'V/�����J�0�E�H�9��ֺ��E;x<�&jy�*)��VV2�[�^0�I܊r<I�̵���qα��4�5($�u?+i�6`��������*����q���\*"s�ˬ��Ke�B���T�s��*������c[���m�\��Z�,G����)��.�ǎ���c�b����@�?t�^�wy���������O�S_�������0�j��iHU �K�(W�Iwi֦�ds��Y��ز�H��m^T��ĥ"L�T�Y�@]W��ME�wj��(]j�^0U�SH�����vuh�:�D}�Qxk%�Q-(G�U��h��4<TMA�AK -��O� -QUi ?��;t9���Bbl��0[��X�� ���@s3��RV#s�Op�Wo�y=���k���2E7�d -��>S��]�_6�/Ɣ�AU�մs��� ;�k���\u�[�ġ��B魳�e����Kl�ޚ�T��2��R�ޱ!o3K>���~�af����^mr~�z[V AؑX���z�~P�MƶF�X����B�<�M�khU*�JI�C&2�łz8G>i�p:�S�p���f��Y�>� ��$>�I0�����d�i'(fI]��[jD��c(�ɧ���v�kA�Z �-�,�����p|�t�?�2;t[Jқ�����u�ƒ#z�ǒ���\�E�;tq.s�R���m� q�S(srV5-P��i�m3'��tek+��"�K�̧C39�J�ٮׇIx��^L��B��Y��@]���&G��k��vV�4 �%4$����,d�\�S��A0U_ -�)2r�0D�a�]��D�=S(�;+���_`�do�Ö���<�P#�'�->/P$��RO�v������5���u����TS?�m^ ����4��5����~�9:�[j�N�L�Ҕ㚄y�^���l���'�xN�}@*�z(��/&�*0�gs��5�߂ �y���1%ˡ����5�E�ngW6~h�=N�㩯!X�y�H$Y0[��0�㘳[h?���֗0>�`S��c���&���V�c|�`73��c���q|٩��3n�Po�6�yXX������\��%�u��Ei-�2ӂ��|��&3����,Q��U}D��A��_����Dg�Ay���q.72������ǹ��3��~�(����4TL�q-�7_�3�O���/�8�>�*�,���RKN�����7��D2Bs�8���z*p6�hr�����P�@�U��^�w�q}_XscUlbǼ�m^�*~A,�����X,�3�q��q���}L -2�9f� -�n�p�.{�ɘ>�+�*kۚE���M}�ÒʍgR�p��B��KD -6{!n1Hq��Pq���u5nYb[����!B�]�D)~�c��ϐ�,�@��wԁi/%�� M_�T˃W%y :�}q�,�!v�5:h������ ՙ�:fҹ��V��9ݎ_�$z��厏�h�f袮z�c�O�TW���M8ԐS��w��#W��iU��ƘLj��)&~�H�^�c�����k��L�e�2�l�M�nbu��<V� ������]�J�-=��Zѧ���Ζz��~ǣ5�?�A�����0����#���-G\�gz~�T�玾�y�Nm���J�l�|{NGa��G��ۋe*��aۚBٶ���uն���6�_}%O��ɺ(��zr��ɲ�q���C���I/�;���e�pq����s����A/����0�9�k�)�)��05��-���QqO����f �P��37�B_�Է����Ȓ*w#'j?)�q3œ���\�a��4�N�n˥x�V�~tQ�&��1�R<�!���-�m�g���CG��a�C�bL�~5K�g;��<VO��$��D�{Hd�E�N$.�2���<��@]���&Q�n�+�b9F->]���-ďIt�_�W�_G��?M=�,LH�Z�s�O�QR�V����Z4v���R���M�}q� -]�U�ϗ�8�ؕ*y���,�g~z�_]&�3��A&�@��Ʈ�`9G�/P��endstream +xڭXmo�6��_a`"+��^Zl@��m�t�g���l+�Yr�����;�N/�w��x�;�=G�'����̗�!��,�g�d 3o�8I�$b�d��g/�H9 Y����a� +�)N|)X��d��h���vU\Lm��e�����$i��.^�ER���>��[�J�,�I���_BN��Wڱf�b��\&�3~`����v�m�"�I�Ӌ��-C&}��sZ1������ۗU�E�r���"�~ P)ƅkT^� �6Ϊ$���V� �]���� D#c��0=�CE��������G12BL��<ɜ6?P��_��ʄv߄x�(�6����N)@Ŕ[u�tD1�p�噽���T(�K��S��u����:K>�1.�K��R��9P� T9~�yV֩I'lT�O,$�����y W��։�(���u�a'~D��DR�hKbOI�Aj��TIe7�rb&YY������8�]����? !����� +h�Q��#���o��d�up!���E��W��-�g��)w�}��CJ��%r1���c|l���X�n$�H���]T�O�d^�H&k \��6��_k�u,�5J����cU��!� ��. +�:�/p̡ $�PX�"��Vq@H�jU�Ib�AL4c������ �5���gLDd� Jf"[X���a�]�-J���h?X:���2Z��0+�!^|������v��*��t�\�e�ΒlݔQ��֫H3z`�}�\Nt��v��I���3�9����|ߓ =Sgp� Y-�ݗ�ө�9�C�6��+�[��X�t�+9i��}}9��j���fs$L��>���Ӝ��ꓣ�s����C���F���f���e!��(z +9�������32��y��X�:����@����{��o?\�~}3{;�{5�M��)��<)A�zm �UH���5��_ac���q#ή�N0���g��a�.i�$�8pLJ�X o�UM�n)�/��A�㟆!�oF���ͬA�������CLg�����+���)Q�)u���}tO��I���5��X�`Ǭ ��u\2����y�M��|��ԕ��-��ʜ�����s�c�j$� ��,�(-�h�o�A�U�j�7�!�8�F��n����!#�>�'*<m�dN(�Əuex���gx�x�ERs�K\=�>�xl�q�������P5G�&u�t�4�M������X�\72�*t� ���g�0G�&Jӣjj-7IF� ��9���d9~�JcpQ�d����9�E/� +v�����7W�״2>�1�z���48�Vƃs��{�g�>�Y]�Oss1�I�9̓��u\6�*�ȓN��\.'����8�H�� �!6P4x���I7B��*�� O�odN�*j�t:.i�q���y��G��G<��M�:ÃN�a���*�/u�i@�"I�*i��$�=;����[S��k���;���������D����Ç<Msݒ?u�M�=��8�':]R/�j�b�g��a� +�ɗcM6�2t��c��W���]���mX�_`8��cJGt���D�����.��c��I������ X��橻��E���Q��*����Ɩ�q�Hendstream endobj -3641 0 obj << +3646 0 obj << /Type /Page -/Contents 3642 0 R -/Resources 3640 0 R +/Contents 3647 0 R +/Resources 3645 0 R /MediaBox [0 0 609.714 789.041] -/Parent 3610 0 R +/Parent 3642 0 R +/Annots [ 3650 0 R 3668 0 R 3670 0 R ] >> endobj -3643 0 obj << -/D [3641 0 R /XYZ 71.731 729.265 null] +3650 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [141.531 644.094 194.317 653.005] +/Subtype /Link +/A << /S /GoTo /D (security-os-accounts) >> >> endobj -1608 0 obj << -/D [3641 0 R /XYZ 71.731 741.22 null] +3668 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [318.972 337.225 370.159 346.435] +/Subtype /Link +/A << /S /GoTo /D (security-mysql-account-root) >> >> endobj -3644 0 obj << -/D [3641 0 R /XYZ 71.731 683.941 null] +3670 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [392.313 236.881 445.082 245.792] +/Subtype /Link +/A << /S /GoTo /D (security-os-ports) >> >> endobj -3645 0 obj << -/D [3641 0 R /XYZ 89.664 666.008 null] +3648 0 obj << +/D [3646 0 R /XYZ 71.731 729.265 null] >> endobj -3646 0 obj << -/D [3641 0 R /XYZ 89.664 666.008 null] +614 0 obj << +/D [3646 0 R /XYZ 164.538 705.748 null] >> endobj -3647 0 obj << -/D [3641 0 R /XYZ 71.731 637.948 null] +1631 0 obj << +/D [3646 0 R /XYZ 71.731 702.184 null] >> endobj -3648 0 obj << -/D [3641 0 R /XYZ 89.664 622.172 null] +618 0 obj << +/D [3646 0 R /XYZ 306.92 666.375 null] >> endobj 3649 0 obj << -/D [3641 0 R /XYZ 89.664 622.172 null] +/D [3646 0 R /XYZ 71.731 656.233 null] >> endobj -3650 0 obj << -/D [3641 0 R /XYZ 71.731 620.015 null] +1632 0 obj << +/D [3646 0 R /XYZ 71.731 626.161 null] +>> endobj +622 0 obj << +/D [3646 0 R /XYZ 408.16 588.946 null] >> endobj 3651 0 obj << -/D [3641 0 R /XYZ 89.664 604.239 null] +/D [3646 0 R /XYZ 71.731 578.803 null] >> endobj 3652 0 obj << -/D [3641 0 R /XYZ 89.664 604.239 null] +/D [3646 0 R /XYZ 213.741 568.821 null] >> endobj 3653 0 obj << -/D [3641 0 R /XYZ 71.731 602.083 null] +/D [3646 0 R /XYZ 387.602 568.821 null] >> endobj 3654 0 obj << -/D [3641 0 R /XYZ 89.664 586.307 null] +/D [3646 0 R /XYZ 249.294 555.87 null] +>> endobj +1940 0 obj << +/D [3646 0 R /XYZ 71.731 542.819 null] >> endobj 3655 0 obj << -/D [3641 0 R /XYZ 89.664 586.307 null] +/D [3646 0 R /XYZ 71.731 503.038 null] >> endobj 3656 0 obj << -/D [3641 0 R /XYZ 71.731 584.15 null] +/D [3646 0 R /XYZ 71.731 503.038 null] >> endobj 3657 0 obj << -/D [3641 0 R /XYZ 89.664 568.374 null] +/D [3646 0 R /XYZ 71.731 491.996 null] >> endobj 3658 0 obj << -/D [3641 0 R /XYZ 89.664 568.374 null] +/D [3646 0 R /XYZ 305.215 481.748 null] >> endobj 3659 0 obj << -/D [3641 0 R /XYZ 71.731 566.217 null] +/D [3646 0 R /XYZ 71.731 480.34 null] +>> endobj +1941 0 obj << +/D [3646 0 R /XYZ 71.731 458.435 null] >> endobj 3660 0 obj << -/D [3641 0 R /XYZ 89.664 550.441 null] +/D [3646 0 R /XYZ 71.731 413.573 null] >> endobj 3661 0 obj << -/D [3641 0 R /XYZ 89.664 550.441 null] +/D [3646 0 R /XYZ 71.731 413.573 null] >> endobj 3662 0 obj << -/D [3641 0 R /XYZ 71.731 548.284 null] +/D [3646 0 R /XYZ 71.731 402.532 null] >> endobj 3663 0 obj << -/D [3641 0 R /XYZ 89.664 532.508 null] +/D [3646 0 R /XYZ 149.738 392.283 null] >> endobj 3664 0 obj << -/D [3641 0 R /XYZ 89.664 532.508 null] +/D [3646 0 R /XYZ 71.731 390.876 null] >> endobj 3665 0 obj << -/D [3641 0 R /XYZ 71.731 517.4 null] +/D [3646 0 R /XYZ 71.731 379.36 null] >> endobj 3666 0 obj << -/D [3641 0 R /XYZ 89.664 501.624 null] +/D [3646 0 R /XYZ 71.731 357.314 null] >> endobj 3667 0 obj << -/D [3641 0 R /XYZ 89.664 501.624 null] +/D [3646 0 R /XYZ 71.731 357.314 null] >> endobj -3668 0 obj << -/D [3641 0 R /XYZ 71.731 499.467 null] +1633 0 obj << +/D [3646 0 R /XYZ 71.731 311.486 null] +>> endobj +626 0 obj << +/D [3646 0 R /XYZ 222.149 272.114 null] >> endobj 3669 0 obj << -/D [3641 0 R /XYZ 89.664 483.691 null] +/D [3646 0 R /XYZ 71.731 264.762 null] >> endobj -3670 0 obj << -/D [3641 0 R /XYZ 89.664 483.691 null] +1942 0 obj << +/D [3646 0 R /XYZ 71.731 223.93 null] >> endobj 3671 0 obj << -/D [3641 0 R /XYZ 71.731 468.583 null] +/D [3646 0 R /XYZ 71.731 186.206 null] >> endobj 3672 0 obj << -/D [3641 0 R /XYZ 89.664 452.807 null] +/D [3646 0 R /XYZ 191.311 175.277 null] >> endobj 3673 0 obj << -/D [3641 0 R /XYZ 89.664 452.807 null] +/D [3646 0 R /XYZ 71.731 168.139 null] >> endobj -3674 0 obj << -/D [3641 0 R /XYZ 71.731 437.699 null] +3645 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F32 1215 0 R /F35 1567 0 R /F54 2322 0 R /F64 2737 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +3676 0 obj << +/Length 2097 +/Filter /FlateDecode +>> +stream +xڥZϗ����_ѷ�~�2��6�d�6�g�K�4��&KChO�}�T4�z��Т���T�*h�·?�K8K�q�+������������?�.cY�ϻP�,��. K#�{>�����z��"�����史�r��E������=���ߞG�(HX��f �.�x��аa~~�8O�]!И$���"O�CS����`�l�w2$bT�����]~�ÃUY���gymzI�Ǣ�]G㾡_� p�CS�������}��$�TV��v$����3."e��E�H#R/���{�+T���E���V�<Ѹ���i� W���Eߴo��|���4�Jk�-<*G��J_���:#|��}�izY칗�;�~��s�����7g�ű~��9<�F׆�pUv���ʺ�(��M��4��a��*��p�+MF�Ta��'��B�?�Z��?�7��� +��-l���,��{���M����a���^_p�蹿�\)� +6�n�5�Q�R�#�i�D��bT�ˮ���g�ʎ�D� ��Z\��^�I���[m��)�V�F�o�RrO����:�S��#�D�o}�%�|&x�ad'�5W�\�,��e� y������﹩�f/"�MrxCҮ�7eQk:�a��X.F�rp�(,(�}b~.o ��A�};�"Ȁ��w)�/_��B#e]�Aj� +�'I����T���Q�ꥂ:`H� ��w��f��r{N��%��週HM/�&��X�H!�`^��e}��״���ia}��;>�q����u���ߎ�Zad ^� +�bK��E���Y�E� �7���w����+��-/.W�Zx�����B��2���.�3�p��QC���L ���,��G0�Bƭ;�d�`����/��r�����s';��c�jŅ��%�v� f��'rzd�|,ygq�c�\�j�5/륞F�=�9�UByx 1�',#j��8���3ȇ4Yt����6����5��!$�"۪��#K��2����j�/��6?��}���@�aOI�[E��4�M^M}._�����)�� ;$ �JHGH.�9Cr�|�&�煍�C֥��Ny�;ܺ�W��fN��8�W�l�8�٭84�UR�M]�%o�E�%'ٶ�����k��ܓ~�hMX3>�u����B�!��Z�ʝ�Nٱ�t^K ���o�%���W�d��ɭ2ؿ*���n�ͼ�GQ�:�(�R��p3��Z( G8-�9Cj�}V&������� Q����c�:���w|��50��y�`�]r00��fj�ܕAo'Kl��ҏ,����>�Ci5��T�̏���Y�����`���`��^0�킴P����3t�9]C0fgS��x��κ���µ� R$�=��Y�Y q����Y���Y��'���ZvR���+�U3E��Q���}����"b���Cv¬����B�fs���n��A�M���) ��0aV��!./�ln/�����$©�'��27fi���<{)�ߦbz������Uq�o+%B�o��N�����`S9˃M=����ذTNM��=O�~^$�/� +ԯ��,~�Vne��Yˆ�Ȇ6g6,�[�`������]�3����N��4GӼ@�l���M���l���!V��� כ��!G�7� ��Z�p��E�N-��J���[ 'Ԡx3\�J�G�,�9�e�|.&�3\zy�U���7����lŋ�Y�∘6g�,��c�dw h��A�Ҙ^e��6Gi�u�V�"u �<����e��ݽ���W8V�W��Qk�o��DR꯱��{x��[��d;H�j&�W�X��Og�s�۾,�U����^5�h�}և��(��÷>ulJ":���,.8L=��AZ^� � +Q�c��gnyשá�EcQ�Xu� ���Z�R+��{8�N^�J�ʾi5k�J�f�p���ߴ9���YJ��88�ŗ����aG�e� ��8�vQ��(0�jߩ$[i�t�� ���0e��Wfh������NP��״r��Q�R�l6!��D"e���ˢh�l��$���endstream +endobj 3675 0 obj << -/D [3641 0 R /XYZ 89.664 421.923 null] +/Type /Page +/Contents 3676 0 R +/Resources 3674 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3642 0 R +/Annots [ 3682 0 R 3683 0 R ] >> endobj -3676 0 obj << -/D [3641 0 R /XYZ 89.664 421.923 null] +3682 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [272.131 579.171 315.707 587.761] +/Subtype /Link +/A << /S /GoTo /D (gloss-htaccess) >> +>> endobj +3683 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [262.114 567.623 321.927 576.105] +/Subtype /Link +/A << /S /GoTo /D (http-apache) >> >> endobj 3677 0 obj << -/D [3641 0 R /XYZ 71.731 406.815 null] +/D [3675 0 R /XYZ 71.731 729.265 null] +>> endobj +1634 0 obj << +/D [3675 0 R /XYZ 71.731 718.306 null] +>> endobj +630 0 obj << +/D [3675 0 R /XYZ 197.608 706.118 null] +>> endobj +1635 0 obj << +/D [3675 0 R /XYZ 71.731 705.903 null] +>> endobj +634 0 obj << +/D [3675 0 R /XYZ 498.095 666.746 null] >> endobj 3678 0 obj << -/D [3641 0 R /XYZ 89.664 391.039 null] +/D [3675 0 R /XYZ 71.731 656.381 null] >> endobj 3679 0 obj << -/D [3641 0 R /XYZ 89.664 391.039 null] +/D [3675 0 R /XYZ 159.969 620.718 null] >> endobj 3680 0 obj << -/D [3641 0 R /XYZ 71.731 362.979 null] +/D [3675 0 R /XYZ 71.731 605.61 null] >> endobj 3681 0 obj << -/D [3641 0 R /XYZ 89.664 347.203 null] ->> endobj -3682 0 obj << -/D [3641 0 R /XYZ 89.664 347.203 null] ->> endobj -3683 0 obj << -/D [3641 0 R /XYZ 71.731 345.046 null] +/D [3675 0 R /XYZ 71.731 590.666 null] >> endobj 3684 0 obj << -/D [3641 0 R /XYZ 89.664 329.271 null] +/D [3675 0 R /XYZ 76.712 551.577 null] >> endobj 3685 0 obj << -/D [3641 0 R /XYZ 89.664 329.271 null] +/D [3675 0 R /XYZ 71.731 541.615 null] >> endobj 3686 0 obj << -/D [3641 0 R /XYZ 71.731 327.114 null] +/D [3675 0 R /XYZ 81.694 508.738 null] >> endobj 3687 0 obj << -/D [3641 0 R /XYZ 89.664 311.338 null] +/D [3675 0 R /XYZ 71.731 506.581 null] >> endobj 3688 0 obj << -/D [3641 0 R /XYZ 89.664 311.338 null] +/D [3675 0 R /XYZ 71.731 506.581 null] >> endobj 3689 0 obj << -/D [3641 0 R /XYZ 206.435 298.386 null] +/D [3675 0 R /XYZ 91.656 495.787 null] >> endobj 3690 0 obj << -/D [3641 0 R /XYZ 335.639 298.386 null] +/D [3675 0 R /XYZ 120.717 495.787 null] >> endobj 3691 0 obj << -/D [3641 0 R /XYZ 71.731 296.23 null] +/D [3675 0 R /XYZ 120.717 495.787 null] >> endobj 3692 0 obj << -/D [3641 0 R /XYZ 71.731 222.561 null] +/D [3675 0 R /XYZ 147.218 495.787 null] >> endobj 3693 0 obj << -/D [3641 0 R /XYZ 89.664 206.786 null] +/D [3675 0 R /XYZ 147.218 495.787 null] >> endobj 3694 0 obj << -/D [3641 0 R /XYZ 89.664 206.786 null] +/D [3675 0 R /XYZ 76.712 477.854 null] >> endobj 3695 0 obj << -/D [3641 0 R /XYZ 71.731 167.832 null] +/D [3675 0 R /XYZ 81.694 464.902 null] >> endobj 3696 0 obj << -/D [3641 0 R /XYZ 89.664 149.999 null] +/D [3675 0 R /XYZ 92.483 464.902 null] >> endobj 3697 0 obj << -/D [3641 0 R /XYZ 89.664 149.999 null] +/D [3675 0 R /XYZ 71.731 464.714 null] >> endobj 3698 0 obj << -/D [3641 0 R /XYZ 71.731 134.89 null] +/D [3675 0 R /XYZ 71.731 464.714 null] >> endobj 3699 0 obj << -/D [3641 0 R /XYZ 89.664 119.114 null] +/D [3675 0 R /XYZ 91.656 451.951 null] >> endobj 3700 0 obj << -/D [3641 0 R /XYZ 89.664 119.114 null] +/D [3675 0 R /XYZ 71.731 449.794 null] >> endobj 3701 0 obj << -/D [3641 0 R /XYZ 71.731 116.957 null] +/D [3675 0 R /XYZ 91.656 439 null] >> endobj 3702 0 obj << -/D [3641 0 R /XYZ 89.664 101.182 null] +/D [3675 0 R /XYZ 135.691 439 null] >> endobj 3703 0 obj << -/D [3641 0 R /XYZ 89.664 101.182 null] +/D [3675 0 R /XYZ 135.691 439 null] >> endobj -3640 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R >> -/ProcSet [ /PDF /Text ] +3704 0 obj << +/D [3675 0 R /XYZ 76.712 421.067 null] +>> endobj +3705 0 obj << +/D [3675 0 R /XYZ 81.694 408.115 null] >> endobj -3707 0 obj << -/Length 865 -/Filter /FlateDecode ->> -stream -xڍUK��6��W�V X�")RR��4E��P� -$9peYR��#�q��>3����Ma�Γ��H�~���� -�si4+�U�*��}%�F�U�+���j�F)���(�ٱD)��a��<Ӓm��W����FRǁ�t�=5}E���zl�ֆ�6�~ۜj��<S/���$%�KRYIXg\%��i(�dO����`��H��" s�-�1��83��?͂w�.qP��T�2Z�;:-P���T�")�ֹs���43A��<U�B��-�ׁm��n>�C(up쉵�GLh?�1��a�w$t�� �|����8�c����ڎ�bؖ[���>��P�s�y���� 3�p���mݢ])ݴ�#|�7Mu�#�H��6�g�Ob{��c�����.�~�M?]=� �����`�� �e�<��5�mC�7��XN�vn��dؓD&�\cPB@�N�[�{$86SM�ř�y���צ��w�F"��HzS3#М�ګm�u���d�~�a&���tTw����@���f��T�_ׂ���s`��"�"L-zk탛!���|��_B�o���y���^�ڼꇮ�P�Ȃj���b��%^ogbF>�?�#^���_J>Ӕg��@�x{���g�V��X7h�>�� ��r��{�[�^E�O"�}a1��ݟ �/F^�e���y&�D�0i�\��v��V���߬���4pILf<���~�/�=,p�Դ�A�C����-@e��k�\��5��~�B���=]�`1���ɶ�c]��t�ۓ��o�����RDu�a����f�sX����dx�:)%����~���g"}�k{Q���jD�8{q�1?��ކ�o�hendstream -endobj 3706 0 obj << -/Type /Page -/Contents 3707 0 R -/Resources 3705 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3610 0 R -/Annots [ 3711 0 R ] +/D [3675 0 R /XYZ 92.483 408.115 null] >> endobj -3704 0 obj << -/Type /XObject -/Subtype /Image -/Width 496 -/Height 579 -/BitsPerComponent 8 -/ColorSpace /DeviceRGB -/Length 50668 -/Filter /FlateDecode ->> -stream -x��wT���dAT@ńi �YPEE��5�9c��b\eͺ����sVT� s�0g����O�=3�0��~��ӡ������[�U�RR�a�a�`߾}���W�V-� -�a�s�a���a�a=g�aX��aX��a�s�a���a�a=g� ��#G�v�ܹ5�D��w�^�re~�9�h���k�J���z���.9����O�a=g�tI��ٳ'O�,��͛7k���W�J�����'"��W�W�^�8p�� đ�����ݻz��>>>�Ν�(<m�9sgkԨѯ_?�_���occ�_��K�.�}��j?�x�"��ٳ������ݣGlL�:U�w�ȪU�"%�=t�?_���1+=���s� -�K�p��Il\�~�}nҤɧO��֭��q��۷oő888>|��*�sDu��Ql��UY�8u��)l �&�3[�l���o����}�66 -*$��իW�q���ҥK��eX���s�N�4iΜ9��+W.�xyy%''�,Yrǎ�ƍkӦ ԘT]�����I���"�s���$����� !N��6�y֭[�"�ٳg��˰�3���߿�T����+��/_��0������Ѿ|�rl�3F ��#G�`�СCdK,X����8v�Y�U�VU�>6�E�_qCϓ'O�q�� '''~��9cnz"""Hfo߾ݠA������dF{RRҳg�,,,�?.�����|����KJ�(��A�-���*y=G<U�T��S���z�F���K�0����S�Flll� -8C�s�1Q>}�T�N�jժyzz�����a�a=g�aX��aX��a�s�a���a�JXXm���҆�.�t��QH$ð�3�I��L��(]5j���s�1=b�7�����v�$NSD� oݺEW�xV�%~���dɒ+V�����˸���/�H�zAD���b�\x��E���K�Ir@���q��d2�߿���;u��ҥK�]�I�9קO�b#))I�D1E��P@Ƴ��Y�ˏ;��H�B�cbbRDSD�zAT�Ar���E�7U�6ᯩ㤑�d��-Zt���+���Ç���F�������'�={�����[�N�D1���(�N��bg)���,��P�Q1Ʌ2Sd�����:N��GDD���B�.�s(���#vs�ȁ���1B=&&&�����y��Ut��T�TyV�w�%�������)��k�^c�\(�qQ>Ijc2���?�1ӱcGlT�P6�p|����Q�q����y͚5��S�LQt��T�TyV7k֬aÆ�z~��%�/��C�>}JQ�Q1Ʌ2Y��Mt��x�q�0c*&z���U�9��3�d�{��a2����9�0L&0��8g��&:��0��Dg�a&s��l�3���-�gLztT��LfeȐ!��l�3&�N|�D�.��@�����2��8gL��%�ST�9�%]�v��������B$۷o��̙r��!���p����b_�����bo�薄�������`�ʕ+��~�ƹ���-[�O�>���g?�f�RW���)*� -��Ç+�D?�!$��Q����%������LF�<{������K^^^,� �7�nݺ��٢�P�}b� -?���Ϊ"��/��Qt��hQ"�ZztT�i`=��C]]]!>Y�d��[�|����>|��I?O�>EsϞ=�F�*S��z����ucnȻ"ˠ��C�}~��l *I$���+��sE�J-Jn��GG����s}�s�N[[[hNPPЙ3g]�����|C�1cJ/���o߾qy37�] -(�s(6h{��U�zu��\�D?^a�AȮ]� -�(:xTt�(�g�ƣ��VL�қ2���Ԧs��U��h���{Q���}���"�h�۱�:���BgPE*�����J���m����,--�Va�sF��<yb���͛j������ÇS���a�ӭ[7�e�.]b4�sT��r傉N3����dwww���8�s�9hٲ%*����s�cF�<|�ڒ'O t��L�###��hq�cF�P�y�r�X� ��.D�Ӛ��0�b߾}�???V`��z�j�y�Z����Jg�;88�9Rr0::�Z�j�����С�Y��→T���U�V����R������|��x�F��˗߸q#̖-ۀh����U�g͚5����իO�4)))I�/��Ndϊ���Lf�sWW�J�*��^88{��-[ -S�������y��t����s窊!E��F�S>,X��p�nݺ�� u�A2ڷo?~�x5�rz�2���i�96 ��'O�)S���ǒkq�+�b���KUj��ٳgK�*%4hйs�pp����ē���dɒ��ƍ�\�2�v�ډ}'*���y�v��P!�>��⸜����3��簺+T��_:�'OuLY!�b�~����+�)W�����o��G�9rdDDıcǔ�ۜ8qB1%�Ժ���X\�+uIgN�<���ׯCҹ�����3�����4iҜ9s��sU��$5�����&''ÊƆ��9�[���={����!�u�։+uIgs��%Tb���3P�.mw��AiH�4$$��������ͭq��©+V��f� -6�+�_i�_�0HT���-[���͛�����w��=���j�lii�bY�Z5���:T�^�L\X��k����+U�������Y�f���[�hA+M(�AM=OIu�x��e�`�T�췡�� &��&&&�����y��ģ�:R��) ����C�ϝ;'9�c���v��mƌÆ +Y�� �I���T��]A�e��~�?�*��6 -.,��3gb���sTTԐ!CP2� ����I���8�7[E�(/""Bp!���K�[:v�H�[�M���~�%VQ`�1������_�֭�+�o��o�nL�8Q2��y͚5��)S���|'*uIgo߾ݠA���8^��sGGG����Q2����.pj�ҥ��d����'m_�A||����@�!+]|�bŊh3������9�F�z�0L&��{g͚�ҥK�S8�m��#��S�nݢ]�'�iƩfy�ܹ�#>N|` ���,I$�9�0�Rϡ��^(���+��(�sl(��8i��=zT�� �ӧO���2/V�6�Kԏ���1ŷ�K �Z�3����vΜ9%�kWGGG����ӧ��oY�l�bC��Ei���EU��bŊ��l4m�Tf��������U1ϙ3G�a�9�z������2e��Z����v�V�$�w��Yaui:�}�v�{�̙3G�Q�T)��P77�1�`C�{��8��s��E��l٢��J��bw���T�̞=���a=gLW�oܸ��o�A����ۮ];�E,�:tP�ؠA���ťQ�F���i�"6�+*�S}=�R����1G�a���<^�a=gLZ��Oİ�3����61���9�9ð�3����z�zΰ�3���9�zΰ�3����zΨ��'x=h���10�$O�<���s��ԭ[7.~�9�C������-,,���X� ���'a���\��sF��P��=z4���֭[�N���^ -.���_�B���7��v��%cK/ �z��'N�ẹ�)�I�z�[=���ߑۍ5��aA������ʕ+�0H֚a=g=gL���P<߆ >|���\z�m�6;;;��Ν�F�_�|���.>"��{K�*պuk���I�&U�X1((h�֭�e˖mٲe�-N�<���������ʕ+_���#G�͛7���<x�8�jӦ����ܹsSR��gcbb��V�Z)&�a=gt�͛7əy�Νo���s(m�ܹ��}����IQKɒ%�2�y�FQ�k}��=�˅ -R��>>>�^�JI�t">[�@�[�na��~�� "�_�~@@�ņh)�����p;G���$�tU���]c=g�Ν;mmm�������sHٌ3h%��S�j�����6n�X|�z`HNI��^�w9,,2+�υ�Ŋ��V�T �0�i�jժ�`8^\����$�a=g�Ѵ�4�m۶˗/?~��b�O�>�t�l�ѣG�)S�\�Ci�����b� -��66�$~qG�ϩ���>� �_\"QW!���`�V����>�w����yݺu��� �H]%$ )����7�*����P�H�.$��]��7I0+++oo�]�v����f͚��m۶�Htt���g�6mHQ���U�V���f͚���ի�B�z~��9��Q�F�-8P�lYDu��!�$oٲ%n��~q0E=��$5m�Tb�3h���pVdn�O5!!a֬Y0�`�����\�rA�����:�s�̩4���uժUO�>��'cr��⡓�0�#""�]�@hH���H1�lٲEC�~_�~5�dw��Q�"��� - -�O����+\��O?mܸ�8���p.\�@mF� -cC� &�bРAd�i?-E'���kג�����QG�����u�{{{{}2�P��|pV��`"P�Z5��5�������9sP&�-J�G�tLB�Uɸ����ٳg�`3�/�������o�87�P�5�`�}�Z����p�����4�B8"�_��B�;t����ݱcG\8o��Hn-�V��c�B��v�bigg�#G�6h�����F�Ț6m���*U�s��g�`�z��۷osVa�L }ǎ�k�����Q-�/�@IIɆ�����ѣGؠ���+Q���N�1��A�ѤIl�6quu�Fpp�O����!�v�g�c�c@Æ Q�6o��Ya��yJ�'����Jf�(-S�sq�Bx��G�y%�[�9�� -�}��c}Μ9O�:E��Qw���,Y�J�?beee䒮�_��1�@~�ƍ�Ya�z�� &�ϡ�����,�9"1�깸�DUx�y%�\rky���Q �}}}�V�|�2Y�m۶��g7*�֭+�9�/H� �6mRuհaÎ9ooo��\�x�ܹs��������w�ܙ��=����={?~���?`���c��/��c4f](o(��F�ߢ���x�V�x�B2sDWz.?��PukPC�4�ϟ�vi��%KB�a�g˖ �C�1ڧv��Us[[[:I�������۷GFF.Z��^�z���]�v�:��K}�ܳ��WA�����v�ܓ8fQ��2��:Fc>|�`gg���`�ߛ1z�`�Q��7kv�}��(�4�u���F�� G=+IS�!n 6�ԩL�����]�v-uzѢEST�g��R�jկ_��WrJi�����1��]覈^'�d4+G��ϤI�pF�._��y\�r�q��#z������I���7�ZVq�Z���!u�M���K`��Y���;`���Ç����K��S�h^ ���͛sV0�,O�<н�����ׯ�x�Aa��ɓ�Cc�F�/�9���x\^���éo$$$dƌ؈���� -;��4ݳ(��a�ԩSh/\�xQOO� �>}ʕ+��� �c� &�P�)�}��8>b���Nqrr���3�?r��I��Ӵ�F'��ə��) -��ի%�>LI��.X�0\ij�ݻwM�?�%]f��hóg�ЪE�����FB���&U֩<gΜ��A���0G�H�|���h�S߲�p��YA����?.�>�y֕*U2�v��^��5=�`nHrrr�5P�fΜ�4��������y�D�8uk��UX�4,X���F�|��駟~2��ey%38$3>HKef�(�c"���d�H�>a�&����T��utt�����SU�a�����)RDՌ��O����Z[[?�\|�ʕ+NNN�vڴi�Unܸ��C���cm8uꔍ� ��K�.���-J������� Q���t���z��I"i��Q�EBHR%�V���L��ɴ��'���P��={���� Pb��111�U$�߿�$=22��F�DGG�t��ٱ�fݢtY^�Ɍ[�Y!J�ȯ�+�$��OUK�IR%�V�fRSR?� �\�Ν�3�F�*���?p�����h��ûF���� �s����a����B鲼��f|���t���z��I"i��QE, N�8Z�)�I�˗/���j�S�����d���c�)4mhlRkZ�F)��;�߿?�)��6l}2d�F���SHfp���jV��9&���J&���FF�ũG�2�z�{���I���y�b�f�:y�x���Hx�� }�!Q�����lj�3zb����+/�k�8C����ٹs'��-]�4�RT�����___�g�\�B+I>ݚhVЇ]�!�E��9ǎ+^�8ͭ��3��1�O�gϞ�nݚ��~���_�V��O�>A��lT�r!֭[�ha�^�~��2�˗/9s������%��s֬YQƲe����K�F>|�0cƌ\�r�,9;;���h|�r;�йsgӝF���wj��T�\f}�q]i����]���w��!L�fyn߾=l�02>a]���2��d�ҥ��lRUkPG:}�5E -(@�.#�0:�ƍ���B�0om۶���~�'c>��?{���ѣ˕+',���o�]�pA�h�?nee�������'O��� Xll����7�ŋ����G�V� -&,�2e�t��a���111/^��\2��>}���2�s�����/]��_X�<HHH�Sx���Ǐ 6< �1�zݺu0�kժE�&� �1BW�>9�U�T1n�8����U~L��U�R�s[��7h2/Y��M�6����ժUkѢŠA�fΜ�w|����Ν�{�.ޯ�����4=}��{�������;p���m�֬Y�4���?�'O�)8dȐ^�z�f��_�$�_�~�:u�����h��-[fO�b� -,� -6 50�J�,���S�f� �lٲK�.Ç�5k����?�̨5+�WW�\Y�zuddd�n��֭���?~�faa�ί�����S�<y�߽���AAA����{�F��9��6m��ٳ/^�*{�ƍ�S��M�6�8�"2|�С�:u -C�x�t;T���#""`��6OƏ���l��9�19�.b�իG��#G�M�0М�/.X��O�>�����K�K�,Y������ ME��駟 �E��6�P�B��a#Ot��j -(�ѣG50z���*$nAV�0�M{{{d�����lD�!K!�x -�(8 �7�bPY4i�z�o߾w��驼�B������lɞ=;B�X��t_.rL�k�m �t��e}�ȑ���o�ĉ���x�a$�<���K�D���A� �0�!Y0P+U��a~7mڴm۶ݻw0`�LAX���7j��+Wnذ��ݻa�#10��@�|��7�Lx� -6n߾�#W�^���;x��֭[��ϙ3��?��ٳ'��*U�@!%�'�m�Q'[��E"Ѿȗ/�p#�m�f͚�����k��>��Y�5�)HHH�?E&>|xϞ=ȟ�˗�Θ1c �F��-���۵k��~��y�桡��R �A�F�pg���͛�&��5�5ap#�L����-[�<̙3�I���$����1B{��Ǐ�_��[i�u�����!5���؆BBf��^�B0#q0����cǎ͟?�W�Z5��E��*@�c@5�P�i#h8��P����&�RP�!��qN!MqҨ�1c�P�@�Û��at+�[�l��.\�^4�Ç�@~�.@s�"A��2�8�ay���Ԝ����U�q.6�>�(�L�Va&Ͷƞ={Z�lI�������5{�l�رt����U�x��\�|�V�dIu�P]�e*�A{D�ƍ���������Ȃ����r�|xX�4d�С<z!]$''�Ν�����N�Kc�"""L���x$ݤ��2�����E�dV�}��m� -h��G�r�i@�ƍ���֭S'�s笭����2�g�ӧO# -����$0�����c����ӕR�߿�S�M�3���� & ѴQ3���i9���J�C�kՍ=���7`ԨQ4�]��/ M��s��6=�rZ��ÇB� -�ŋg��/^�(<<����Z����E<f����x a\��k#���������ۛ7o�e�}� r�͛7�*���+ ��III����`ӦMqd����?�C~���z�M�������������ϟ�ɓ�-=��5KK˼y���3G{h.|�V��yM֬Y3�DK���⚀������M��믿8[trR��N�^�pU�N�2SV�(Q�$�T�R\0FO|���hѢ/^tss���6_"��Y�fϞ=e܉+",�123Տ|˖-P����t�����heeu����T҄Y�������a��w���_��4�� �9mڴ�#G�[�Ůxdzԏ�֭[��"E��7%��Q�F���������\c��]�+Fn�ǎk�z���W___�̐Y<p��,��Ǐ����� >%\[�\����9r��n������%�˖-۲e�-Z������#aaa~~~+V֧��-ZԣG�'N�L�4 � Y[�n*��Y�ZZZ&&&����!ox�o���a�L�0�@p��{�n#����p~���'O��y�~����۷/�w���ԩS�S hkܻw��Ç�k�NI]��vNE�`K�o-�����իWRկ_?l�����y��U�o�j��3g����̙��3��" ݺu<�?{���>��X����a��+&�7�q�F�ϋ+��������S X��R�J�����Ix!����]���-Z���H���dzo�>d#�]��A�֭��˖-K�����щd�8l�0*o666<m�a�����x��֭+���A����DGG�̙300��|�̙�F� -�o��l��Ç��ڒS��V�Z�-X�����=z�?�4������Ǐ_�| �R[�^=ǃ]l$&&�k�����oذז+W.��`�����Z���0fN͚5�m"U�剝��H�y�L�0��G��?>w�\���kԨAݧN��\�x1%՟����ʖ-u=t�PJj�y˖-===i�X��b�ҠA��ݻC�+V�تU���ˋk�]�v���" B<͚5CR���Y�`r�C����� پ}{�,��-\��7�a43��k��LƬY� -��2���1j�{��ԁ��֭��&2k9ܴi�`<�۷�_L���DWE��C���㑓B�{zIJJ*Y�$b���+�Q���?=0�.]������9�4|��������V�uf.\��Ѱa�L�K'O�$��(�k֬�b�0:4�3��<3A�K4�ǂ!��4�7�҅�����-Y��� ���Dg�\���� K���4�aڴi��u�֙;��^�*��!���0��&:�iҥK�[�����>|ȕ+�.�������r8y�d.i����ƹn!�8����6��zR��ϣG�lmm�(�3���hl�g2�\�E��E�kE�-��*L�j�0mڴ���;w�8 �x�������/_:88899�V���ٳg�Zu��(�hl�g2�\�E��E�kE�����7�R�0� -��Ǐ���4�\-��ر#�?�9�I�_Y�d�2�/)èOժU3�s���;���*,�,J��H%���ݺu���xG�Ԫ���T,�N��/)ä�D�|=�b�-bw.b_+�mU�X$�Y����+I�|ٲe����P��҅����(~O#!!!r���Q�r��c� -���R�l�>}��߿?����>[��\ľV��b�.�¤���J�i�~�&M�/E�2�M�gϞ �G�̙�J�dx���(j��\���啮)�2�_;�rT��G��ݻlٲ��JO�<1.Z��%��(<���J��`V�վs�N���4s`�?�f�i�mo߾��yhz�2�C�Z�;wFl�!4��G� S�V�X��cxv��IMŐ���r�hIRRҒ%K`����o߾�D�O�:�K�h��ӧ�1�S�� �6m�ׁ1$������({}���������imMZo���x�"R[�L]E1G�vs{��n�"/'O��w�1���(x͛7ϔ��d,'N�������<w���ҥK( �����p�̙f2WT�.�\ ;{�` Γ'�9���"##Mŋ������Ǩ��H1�v߮]�H�mmm��0�Q� -�ZN�fd@E��� -Y���f��)?\4<x�<�>����ί�?������aBh��QS�����s0k�,�ٳgO�}�#G�$IG;��F<|��,_�|�z�T&��C�������c��i���I�u��#���ld7nD>���y:ϟ?�tz{{�6ڀ��D��~s.u��!I - -�7�����C#���ѣG��jժ�6ڨ�(DۣG3/^^^$�C�嗂a=�|�+{��ч���++�ܹs�A�� �o����z���?6mڄt6j�H�1�#f䃙����ߓ�KKKTs�j0���zbŊHg˖-u�3s��0�>}��g˖�s���:C RaR!튷F�ٿ���/�M�r� -v]���m�r>�����Ύ;�<�k!�%J�K��c�,(]�4�#ϼy�-Zo�z�%Kj�*���\�xqÆ 8��/���O?Z ������O�2�D���,���ݻ�o(hڴ����s��!!!����c��ٳJ?E��;99 8P��?�Abb"~�!� �l��˗/�SW�^e=W��C�"�&L�G�f���:)R�=�3�O���8I�D��ك�����σ~�����|���/^���o��R�Ja����ժUC�յkW�)����rqq1�d*z�W�]�j��_�|���y�6�&�v�Rlmm���`�BލV�axC���wE=��[�n�`�.]pp����_h�����]�p!~7nl<z����]�6j�H.�Q5[ZZ�ʕ�}2���ggg� F�k���q�96��䤨��q�%h������'O6='K,,,�ҥK�Y`��A"�=���+V���O�:���M� 4��`��^м��s�f�z���`oo/�=�+qaW�P!:r�� ��s� --r�ݶm�۷o[�)V��w��M=�?|�p�3��M1���T\���?� F)�7nY���e���{c�?�����4��A�he7�mݺ5-�j$� ���W�^��~����+���chA$&&��������Sr9cmm���� FLRRҼy�Ŋ2��0y>����v�ܹӮ];Z�,w��˖-3����>}�������+*2�U&��˗��ԭ�y��9���|�Q������nɒ%�t�1���0͂���>��0�6���p�Çs��@+ˀ��h� �oZX<���֭����b��ȑ#i�c=�.��˗�D������Ǐ��5k� M�6��]��뇻L�:�K�"...��%�cܼy��?`��a�BA̽������0��s����ݻw�[�0E��ԹcҤIH�����s� ��> _ԹzƄX�t���#��O?�t��i�8jy����Ѳ���'N�� �ha�9��_r{�ꅻ����z�K||<U[\*�"�`��f����{��M�]�v�>p����'�1�9=�ѣGS������4�:�w���]���s��+�ŋ\0�Bs.�d��YaV@�CBB�����a�+�8q���"�ޜaH�zsG�%�x��>V=�/_>���Ç��Qpp0n�c�.J9~�8Yh�Z���0?~\�\9<tWWWU�^�~- �mһ�۷o۴iC/u˖-������:��?p�1c�p�PE�5h6�=cb^�dI<q��������H�h��j�ʕ4����Ν;zM��VUʖ-[p/4-�`������}�|���h/9'�}�}'$�z�>}:g����^ϧO������xOOO��u���%R+Y(����H�eCZ�\�|�s#����3s�|Q:q�b˛7/����_��͢�o߾mذ!b�����L�!����<�M-hΊLɧO�h�'Za/_��U������f�g2P]����8?w�Ƒ$%% 6�F&w����ׯ:Og͚5��� �-�?�%D�%K����QS��mѢ����n ��7oR?m߾}�7�9�<�+dl�>}��mŊd�խ[�Ç:L���߳e�feee�6�U�&9r��3gE&#""�F ��{�Ν;��_HH�F��C�� -"I��A�N�ʓ'����Ks���D��A <���<4ҕM�Lƞ={�f���ٻw��n�����Md@�~ǎw�����3g�������ӧO���V��mq����+WN��JY�h�G3X^�*�F�z���3gN�E�L<y�'��FϞ='C�t�II^yyymݺU�����4Z�D���>�=z ���(��+W����J��;M6m�D%J��Ɍ�X}?��3�fpp���WR� �f���<<<*W��B����ʕ��ۻO�>�����ÂeN�G���_��el�_�˗/VVV�h=)F���c�3��qyuո6u����͛�ի��^mf!Hk��� ,�E�E����H� ������ՋL�gϞ��ã�S˝�ܤILLDn+V�*�"A�ʐň�ի�^Շ�����/��K۶m ��������;�-����l)ҁ�rX�N9��1c?Duh֬-z�Y�HRR�q�j�|}} ��A�*T��ҥKz#9~�8ZXh�s�s�?^�ti����J�*�ړ'O8�&L�}��OP���E���������Ɔ�>��E=׀ڵk��z�>������b}����������K҇������Srh\�xq� - 0�K&11�F�Æ ;r�H||���=ވŋϝ;g˕+צM///څS�J�59G*[�l˖-[�h��*��AAA�э�:v�(\%Vx�j�������{���.\�������͛7iP+���We�8�m۶������g�&4M�mv$o?C�ъ���D�իW����P�k�T�B�`�������?���ɓ7o�P9,P�� -����K�&�J|G\r��=�ET2)�Z�*���j�猘s�����ɓ'�yI�Ν^�:��ӧqk��d�4��i���笐�ϫW��nذa�N�bccǏ�#tV� ��o�b��@2.�LXXD��s�Ub=��.(��䡥��V�ti��Y��ŦM�,--���ܹ3���=Є���!<x��?~~j����MK�pV��2e��A}�͚5KJJ�VCJ&e�q�� "��)NU)��*��ѣGu��U�<�eȵ�X�3 �ƍ#??i�3����iP�N�A�Jlmm٫g��k�*ʖ��F�~�h|ˀ�fxxx߾}�"|��(3��0�kԨ��EEP�fM�"�2z^�\��-[zzz�߿_��bcc�'O���z��G�V�T)�:�T���=��J�It���|�\2�1b��0ē��9r$��f|���֖mذ���K�h�;�Q�D��\�r�Yz3�=蚄����?~KKKX�W��s��]WWW����߷��(P�@vw ����RfΜI�\8+����aլY����\Kv�������ŋ�g�N��l�ׯ_��I�&Húu��a����ߩ}]�F��=���gb���C�{?}�$9��-��_E���_~R�F��u�Y!!]���1VV�`J5�������Rd=� �q�9�$(>~��]�� -�ر%:t@�,X�x�p���+4T{�왮��Ю�%�~<����e˖�K�6�[�O�8��T�re�j�s]q��{{{��xD:�_8p�ѶF�wmڴi��?=��ˮ]��˅��ҧ/��Oܺu����;��TIf�,.��s��{��*U�u��t������jժ����?�hذa�\4����d�Y����ӧӈa�"���� �߿?�1e��|�����������=~�8N�߿��tall,^����Ӳ�'�E����;::���y��(x�Ύ�����4PY�+����Ai����'4h �.��u�,~z;hY -& P�vm�ڏ�)����<z:U�`A�8�g�g�~.蹁-:�6�����nݺ�4(aJFO#3|�p���?��Ϸ�U��ߝC�Q�Q]O�:%q�A�f���`��� �t��{������#l��D%y��>e�+Y�d���&�����oI`�,��kעؠ�.Z������zwľ$�RR�������TSFc=E�� �pk�rSl�Q�-�ѣlj'�xl�ݾ};k֬VVV���pd�̙33�Q�3)fj�<M�̈́��8y̐���.�T�R��� �=�6�z��2z�T@� -yHΝ;7������s������0���_�|�b )�����`��}.��S4�N��g�Ң��P��s�[t���)��M6DE���ޢ��<hTΜ9���aV�ĉ��A���9�Q�FI�l�R�mOs$����&��� �����<�,U ��^A�B�Y[[� (>�l}�,J̭���/^(>߈��X�Z��qI��?G�z�b_t�iӦµK�,�j۶-?���:��T9aS�s�&[�T{'���-:hu@� �Q���O _CЮ������*e�5h\�Rh��'��<E�Ɇ*=W�̓�26^�����r��v�b�~K��*�5`r���)��,:Uf��`�)m����֫W���ޢ#�#X�r�1<ʹs�"1�;w6�ٖ��O� ꠠ��~�i�ƍiFcOG7�����[tnѩ2��MU�m]���H���-:p���֭[ã�3gc�!ܙR�mmmӻ| c0�7��z� -�&�q�uY�d���T��x�[�4ɝ;7r&g��={v<y��Ƽ~�������q����@�2<IF2��D�V�r��Yal|����g���y�c���d'&&�͛7Ý���c�"#F�ৣ4�!���x4 ��\�|�������Ғ-���Bfl���HT]�ԠA�h�L��S�4�Ԝ�O�'��Dn������q�qr��y<�L�NX�t)2��ϧ��)R���;S�F&N���3A�8u�犁�Jϟ={�C��S�N��F���q��[����k;�o%�-[����z��t� GGG�!^�Q�M%E�����4�&�aÆ9rmd{{{�t�/�k)��m�$r18��˔)C.b�NE\9� -�s�ce���G��hl���32�]�9���'yr���jеkW$`���2V� �o*)*|�H���4 l߾=22rѢE���;|�0�ڵkB�b�\1 1�S�Ů�t���%2p̘1\ȍ�������CF3={\;c�o�m��*L�j�.[�h��!��1���Կ����]ڵk�@H��s�7��S$��&P�� v�� Oy���b_ =WL���E��lj�������!��������x.��`��\l �����7�*o*{O�w;����EG1_�~E��ƻq�F���E�Hۊ+��s�I�J}�H��;M��m֬�,(WM�6�/vۢ���$ �) -��tE�lٌ�6#�&�*U��Bc=Hbg,b�M��ʛ���S��E�N3N�|�ڵJ���_�]�S�NUs���s�L[I0y�I����-$$D�ϧ��n[d�M�֭[�)S�\� 1h*�G�H\9� -d`ٲeY� -{x.�����@;c�o�mU�T��{�.2�Q�j�*7%��.-�x�n C�Ξ=��m�\9��}d`� Y������|"-�\�qE�El���Ŗ��0)*��������x���+y�4-e �Oa�<ypk�\�/��r�>�E��͍e�تo�9���F�3��m oWi�7nܰ��̗/�ߐ�C���������ׯ��4����g��AU�3g8+Xϵ'11���E -y��i��:����ʕ����n�!�7ƣY�f g�fzΈ5jr)$$D���/6�"�.]�1�ZҠAr��Yal�z������Zr��ݬY�Z[[���ݻw�� ����s��1M�6E���qV���ǣiժg빖4k�YԫW/�/iݺ5.�7o���r�Jܱy����4r�<��������t�����⌎��,�Y����N�z������B���d]��F�K�3�[�0:u�<����F�0:���V��IIINNNϟ?��z�߾}��J�������|���ݾ}[�)L���aÐ�q���S�r����ӰաC�.ct�������X�l�]�����g&h� - |������&����t�?�[���������ѣ�q�ر�y�3UИ�V\PY�5�֭[Y�f���$�a�u����&�49������4�}����9u���U�l?s����O\PY�5�� - -Bΐ� ���k��٭��^�xa�Ԣ�Aj߾}��NcȡY��CY�3D�Q���ˇ0�(�z�>�-B��ϟ_���1˗/�wj�߿��ɓ��6�����������1i�$.����;u��ҥKf�KO�<ə3'�e����W --[��w���լY�K�6����3�\��y��-[�l�bŦL���p�֠��~�I|\��%�b���VL���9�s��.��ի�E��?^PuE=?|�pPP��ѣ�6�BCCu2�����%�}/I��?� ��:u�� ������9���ի�����\u�<&&FK=/U�����III�6'�jAYG�.�s(���#vs��a����͛�puu%��ZR�R%5��hC߾}q�������6���Y��W�A�%f̘C�x��f��֭����0a�x[| �p�@�B�8�gH.��O�.�;�a�k��,���.�)9��G8%��u��-R�Ȁ�+I��Lzu��3��YHLta��\�:v�HM��G<�<3��͛�H͆ t����ۨQ���lr<��4�'?~����Lϗ,YR�|�r�ʭZ�j͚5؆<n�,j�X`���(<*}�8�ׯ_�u��*U����W�X! �Y|w=��tJra�ܹ��s�N�8v%��X��z�����楅����j�4ο}��wD�[�lA������.�/_沭1��|z�[�����f3�,Y��ԩSkԨ���V�-X���Q�ti�x�|���@,wB�����wW��t\Q�% -�R���sмys��9s&Z�DϞ=�*=7۞s����|�����|��9�GgggUKiObb������͗/_�lk�0����^��������G�yo+��k�X��p�r��hgacϞ=J����1��.�B��%O�<�h+��%��Koz~��Y�SdW�i��f�s��$�q�cǎ���|��aZ��K�6���Z����Ӌ-�Ǎ�! �F���W�~��ے��:u�.\xڴi�����#$�S�����c�]�<<<�֭KGZ�lY�j���P!��I�%����s�~�����r+o���q���cZ�m�ر:��M�6�y��zJ<ZĈ�[�n\�5�'X�����L��9�0�������^U&�y�߾}�Y�&�~pp�>zE���y�Ν��~X\z�/́S�N!a��|"��sP�^=�1b�^U&�y� �/X���&����!~�X��~4����Hk�������$���իxRY�d�{�.`E�<�� 6�� �����������էO�t9� �?[�l��������������f=7~=}���% 6��h���q~��y�?%�H_'�,Ywч��;w�L-y��% ii2۬�&��/777\�p�B.�Đ!C('��8��i�B�����7}ߋ�[�NO䒬1K�,A�m�v�����9�H=z���̛7�Z�j�طo_�2eV�^-Y�jU��r��y{{7n�x��ݬ�i�~�z\��{\��܌�ϟ?S������u�O�0A�1����W�Z�%Yc��111�ر���F�Uye������۷o�N�T�X����f�:��1<D�t9&$$DEE{xxT�\�W TX/}����Y+V�2�'�'-iB>aڷo��s�����]&�֭[E�A�IL����7n,��`x����={<==Y���������7@+�ٳg���vvvb�b�V_�Ż^^^�Z:�D���h�1!����X��ʕ+��@�,�3b�a��cMSU��o!�Zb�F�nѢ�b����+*<9`=W��G������+W꩜<x��Օ��t��mǎw��1@�>��{�����Ν�6m���0q��ùs������ڲe���˓'O�x47t-�v�ЁK�f�������)?|G���f�yddd� ���֭c�\�z�̙�����t^Nv��I�EHH�Ç��ђ���%K���úu�~��M�x֯_������/P�%��h �UԟM��ٶm2�^�z�+蹼' ��\�T��7N�4 �KS�Ѯo�y��ҥbpss��t�����Έ�o߾���d��?MT�X .?p������&�� ��G��U������h�p�ЌZ�j�� z.�U=�ڵ+$�����������[4x#���in����uUHhpZ���u� �'N��&C�Ν;���F�g�'|��Cg_� -��[Cr�+&��z.�`�ǟ������^�:�)Q���Ǐ�/$'O���y�Q�����T5)�ѣGJ/�x�"}�hѢEF���oD����R�СC�Hh��<o�<ሠ�_�f=7E=OI��6�*R�����nݺ!��ӧ���'PQB�a�+5����� -Zr����4��~���!�]�v���F+����p����]�@q����˗��&��)�N0ha���mȋINNvwwG9Qe(2:��ȓx?>�<r^��ʕ+�788X�S�g���:\�%5������Z�fƌ���`=7r=�߿�[�."tvvm�f�<|�������W���=~{{{K<�\�v�����f������)�V��`��l� �j���=���I�yJ��Qr%�g=f� :Z�� a~e��ƍ�ϡ���W�RyhР�p�u��ұhM�p�h۶my E��Q��=���z��E<�EX���+Vlʔ)�F����@�<==[͚5i�7�]�ڦ2Y�f�U6c�zN&'N�!� 6|��U�.��P�V-~e�b>��}P�bE�;v,gΜ$�=�²eː�֭[k��ϟъ���S4��n�ϟ_qĂ���C#��(�`Q��tp���gUz�`�Б�nݺk ��>�U:��l��ػw���"wwwO�s������xkkka��m۶988`;,,�x��W�X�$���>�͛7#��իsIH/_�~��!��.]��\��_j�0�SF����J�˔)#���z�;vl�&M���j����N���@��/Y����N�:�=����PφQ-�@=�͛7�>*��٢3f�@�U�RE��A�i���z.�`���%K��/_^����K@�w��=k�,��E��naXϩ�eΜ9��A�ܹ�Ν��>��^��ݻG��t����&s��������2�O�>999YZZ�d��Y��ŋ�9s�B;z��L���k�/^\8[�dI��z{{GGG��s\.��Y���Z)�����ܹs�q��t/d����YύJ�{���1k֬}��5��e�o�������� �t��Y�믿ʗ+ �$��z.�`�Z����x�b___y�]���-Z�u�V5jAY�A�s ���\�U�Pa���Jmu}���K�( ���p���˸#���:��B�^�qI�?~�2ggg+X�`�V�$��R�B�~�9R8�1G�� 6�[�a��KUԮ]�H��ݲe�g�2�≊�b}N���(�Y�d���=��'����d�L�20�����,Y�TuqU�T�����o�[1lڴ�.3f��墴��Ƿ��G%K+���f̘!�w�o=�en��� bB�>1��ҥK�,\�o����Al,22�t�Ғr�W��o)���\�xQ8�bŊq�ƑG2T|z��~����G�C�hge���ر��5i�ǏQ�X��'11/,����i�+p��-���1 ='�~� -�CmKw��� ۼy3�֫��BA����0`���e�ܹt�>��9sF^�qq�H����PH'''�����@c�`�Ӈ'��y�5dd��ť@��;wFus�ڵwt�n�:��I�&�G��.���O�Q����7o�d=7='����n݊�i&-vӸqc2���d�n������%�DP�- -�\Ш:.η�Y� -��PU �, ��ȋ/��o,"�����B[�ȟ?�F����7�Ⰻ-B"۵k�M$M�6E$�g�f�V�cǎ�Ecggw��eu��q�����ӧO�N�Z�|yAX�����"_�`��;wh-Yh̙3�~��OZ��«:.�7�Mz.d���`�����=?���8�����C[�h1a]�v�O�6h�\�5��ɓ'h�Y�9z�IID/�����,W� :�s3�s�̝;�\��C�� -+~���?H�)�ݻw�H�s����Fc�ɱիW��̊���899)=��'g���خ\��^��MHXƎ�4�1B�Ps!��;�J�����i�:kZ z~���ss�s}�*��!��+W�E��ᑜ��;w�~��-Y����˖-K��:.η���lٲ������s�ҥtE�NHHj�)��C��"�_�j�9A߲'N����IIIE�A'O�d�V��;wZZZ��ٝ?^�r�{fd��ᨨ(l�!c�.\8&&mI�T���.����t��I<@E�K�=�q/��ͫV�6��2e��vb=7-����C�(��r�|hӦ -49K�,5k�����|�z�j˖-!�VVVٳg�R� -u�KB����?^~�z��g�ѵkWm��w�څ�˗/�*�&�=rssC�M�2%]� -�/@)���i����`___��������W�^��Bl@��� -�hѢ;v�8�L.�6l�022�o߾B��z�:c��b>���+Vhv9}�6�2�&����i�VHH��3�=�_�FF�.\� Th����;w�YN� `� >�`&���@�7n�X2�L��(�9� ���F�5�����hg9::�{����:DDD �(��ŋ��+m�� �սi�&�����!CPO�6M"ˤ�8�fLt(�*=�[�O�.�w�-Zp�9����o��*��o�0��ѫY<������:�A���W� -��~��F��e.�Ͻ��q�Jz����� �.]zݺu��3��n�����|��U�ki�}\\?�4y��-J���EUz.?�V^�[�n �{���خT�9��b������q��#|�b����={� �ƍ'M�T�^=�s��sCr��}j�kp-���i�����S�ʕi�A f�d�9�#Y�f�,��� 6��(͚5��-͛7���Vw�����E}=GK�j���7g��s��s�����+P����ڵk��s�'99�U�V4!:]��z.�0�?g=g�9�5^l����m��?c��|+''�4�����o߾e=g=��� ��|��q��!����{z/���.\�=�^)KKK++�t-�J��לe=7=��!��/_>~��Jtt4-Bd* �媕�Y)C\\���E�4��jV\�p���x��D�嗝e=7=ONNvww�;(��,�%;v�Θ�`��"�O���qՌ3��ː��P�padT۶muҏ��겞����H�����E�?~tssC���ӧ��`kk�,Y���J�ƍVVV����m3��۷�pX�j��juػw�:��+�-4W�x��#F�_ٱc���7���'M�U�ľ\Ԍ�U�V�8I�J�)�FƩ�'N�@��]䄖�9��r�Q�F��`*�u5٩S'\5v�X~⪀�"�J�(!Y)L3v�ލ�о�X���E��z�g�Z$Ƿoߎ� 6H�.�!��|���|Ra5j#\c�8����"ah,���h���=��s�ΙJ�5�������������9s&))�V�ȗ/������C9��<��[H�i�(�o@@��A�hWM�:�lo��!����-N�$�lg=W��7o��}���af:���������>}��P��t�^WZ�۷��_����G�Ȣ9r\�pAWqn۶����X��必:="##�8�w����ڝ?>�|�4i�ė��"��>�)S�z.DU�~}�s��R<���kkkr����C~��-�:ٲe�����pȳ��~�!P�X'}��ѣG��W���:�v˖-�o��z����ٳg][�߈���{� -�Y��t�����L�����X�����d�\M����4h �_�r%�_F��;2�Ν;��1+ ��lrX#����0�<LLL���˚5��ɮW��f�ḠY�f��nܸQ�1�r��J^��yz���*U��]�V<���������)��+BX����\X�0ФB�(Y��x����C8.��&��B&k3U$��.ٟ�Y��4d�n4�X�����HE�UW�X�̷���F�5��2|�pg��:��.S�L���nj#��F(���[� -���jѢEΜ9Ui6������"88��Ã�1j�y�\��������m��ӵ��#Z�<!Ts��%1������E���Pcm��1=?x𠟟������<��0*��^)_�<��̙3�����%"?��<��dii 1���9s� �Y���>�����?��\�K�癒/^@���Pg���ϟi��m�8�-g�$2g�ԩ���̙3q��ٳ���U�9^Ϙ���m�:88(��{Y��f��mӦM� ����%K���O�4I�7B�4�����B��߲���֘s�s�A�����������laaq��i�71,����H}���?�č\\\X��Mϓ���v�d˖-k֬���1´��s�U����a���_~�O�M�6�ob�L��:93a�V�vss�Fυ!%�:u�$X���&�P��������͛7o�r��q�ƻw�f=�!�{��O�111aaa����7o��3)�Y�hǎ�3gNS�0f�C*�Y�f�C�k��E�)Z�(��!=�ٳ��N -ƢE���v����@�4�\�@<���빮�Ah����v�JI��N��lA1��L �\d�̙3�%&&��G�y��q� M�^�zѤ�e˖�t�����Dϱ�2�V���0�˖-���۷/^\�5v��&M�,\�PM=߳g���'��[[�-[�P�ˣG�(1����z������e�������Q�{o#�}�F��^ڴi�!oM~�=<<t���`��ܹS������nݺ�����J�*�w�FD8������z�%�p�<�q4����Lh�9�^9x� r�f͚��.^�hcc�@�%/3�>}"�����111�;}ŀ�J�ib>��x߾}���������Z)�������<y2�_[�r���ުU+S|�X��AϞ=������}}}5[W4S��ŋ�ի#Cr��u�� �'���%J�P�a���(V�\�v-�X�N���N=�i�yxxx�v�Xϵ����x�bųǏG��z�P�A�<yЈKHH� 6{�l�<�tvՒ�:SzE#~/]��!i - -BJ�.�C=]�tqqqxyy ]+�im�3���͛�|*H���-P~ߢ 6l�Y=�;���2QW��:g����Ұ�0�0w��%'�x19ǎ=���܀�=~�8�����4@0��s���<666K�,�u�/�s�S�Ny����{͚5M�5��X�f �_!!!�J#�_r�z�Y���ŋ9r���z��)�&�s�r��u���F��2~�x�y�B�^�~m��5y�d�ˏ�+ý��(Q)�T��y���{���ϟ�\pd֕�X�uK�����S�LQ�ԩS666VVV4����+�=c5���U��z����ŋ�J��-2�B��:��Ǐ9s�̒%�˗/�����Æ 3�z��y`` �f�#I-h��(S�sݲu�V}�ybb"�i�_�l�7o�d�7��\�̝;�ٮ];Uhm�+�:5�\:{������TYU}���7��� ���O���G�!>"^��յU�V�ݶm[���%��oY�v-L �ԓ��Ɇ���L����znZ��+VLf��7⬃������6����?�2���'?���<{��$EK=���!�t~�ڗ/_��}||hyPy�/���?��ӧO��y�3*Msx�T�y� ��D�IWwS� -��T�: ��Hrr�ҥ����@�g�]4$��B脤��aÆ� ܹs�/_�U�^��C=߰a����*=Ǒ���ũ���**���3���N��Q2C�x�\��iӦ�9���J�*F��߿��q�Lų_�~����Y���)�o�_�>r����������:�s�]��DFFJ�[��2�j�ʔ)S�깢�s��R�N>SԪ����1�9�����1�8������8��0`���)�����r�ʡQy�ȑ�ԑ�͛7�QA�:��F���wtttǎaɐwAIT֦M��;w.v��-Z�PL�I�*V��u���FZ�F�Jϒ�� -<��<;̋/N�ōvT��͛uh�Ϟ=�v��2�9�;�X��{�*�sE�/�`�?y�9���;��:����j�f��jժ?��3����C������<u���pa@@��{�>|�R�]H�"0v,�ݏ?:;;?z�d{K�*T�.�Y�|U�9��ūW�RR�]fHO�%d�R�hS��@��9�b�w�n��\�h���'�]�V���7$$�^�zJ{T��~1�-x�`����_ڼˏ?�� B؍f���i��P������q�"���X`�r��[�RRW���ʕ+��R$Q �謌��_������|ժU��-C�I� ���߿d�[��Z<T�z>|�p��d|�D�U������oy����A�4���BCO���^�gΜ9jԨ��`Z=��g��(��PrJb�S�0��߿S�nݺ���� �Q g�Nܣ0��*111���:����0���۷o���!#�W�^�&�.]��NNN�3�\���D��'�={��;w��am�hт��a�f��[z���:w�\���kԨA��0;���.^��m�)�� ����]uXU���ѥ" *b*�#�X02���-�:�c��X�b� ���1�(&�:������������npϹ���>�{ξ;�~�Z;�:}�f����h�O��L��5((�m۶Æ ���.]� �xW�����ܹseΜsk�Ș��6������hw�D`�L ����P&˔)�����S�"��E����?z8�������R�x��E� /_�,�E��~�WQA������G}s������B�9���s<�O'����e```llL�@�3>��� qݺu��;������Ӊ�B� -mٲEX��m���eȐ!����#\�t�֪�@\o�\��x�"4�"E��&+411ѫ5М���ӧC/B�4h �9>ȍ*�s������Q�F)0uSSSɉ�X�2>�(rss)���o���D:Ϯ?Q�>|HUadd4y��/_������]��[8Ԯ]�HD],--�B��i0��9>|X��ׯ_[�nMN$��3��|c�ʕ�7t:���;w�С�����Nx�cÆ �PP���˟9sF��x���P�dI����;<<<�ԩ#s�����|0��9=z�$1�9e�j�gϞ�9/���q��5i��B)2Rf�\ɓ��>��$��)zh�� -200@��n>��Fqv����o�ڵ+uC�>|nY(r���< `ƌ�:uZ�~}������9 m(K�b�Wj���������t���L��WUx5O�X���C��w7lF��`5����^lv��Eڬ��Ͷmۄ^hѴ�T�|�=r�Ȋ+�) >���"���L�} 1-|,\����<>oy� ����<)�M��)x�\��c|�,����={Jpopp�ٳg�߿onn������Hz��m�H����k֬I�k{��KF�^�T�}�M -C�i��h�[�j�RSS�-0)))ݻw�� -z�� -�h�" -C�^>�������������|0��e�UӧO'�@]�tѓ��|��V���7�or|�H<�w�ΧC� C�<x�HDDD�6mΜ9ƾ}�6�>_?�� 1|��A�"U����4��mp��ɡ�h������U�xqR�1슦\tX`Ĉ��s$8m�4������+��|0��e�O�>x�R�J�?E(>���M�����.Y8�8��o߾���O�:5{�l������y� �"��6�����y���|4��ӣG:�v��5�ɫW��Q�Cc�l�C�(3��/��w@{�L�ٳ��C��\dηH{w�<�0>�8��x�fU�F���PF�y�s�C�2}�H<�w�%���H+����_�"'0{���ݶH灃��8���NNN��?y�D�_+�ɓ'���ʹ|��f�)Bn�Ŋ�[�+V%���ݴi�� -:E�(\ ���|~��e333�������a�J�|.�;E�1�K��]sj6���@��ۮ]��K����mQ�箮��z��Y�&��Af���������={�[??x� -���|vv6�����Ν�xܿ�v���t*B�� -�.��\���������߹sʛ^��V��E�ۇ~�M�� ������wzdsg�fk+�S3gδ��@1K�.-������i\V�/0>/X>''0��}�bD^�|9�s��9�1OO�*U������ݬ����듂�qRԱcGZk��'N��[##��~�M�{���(����s�����hrt��]y�@݂��g@���U��a��((9�9�����J�TRRR���KQ��]�tI��K�,hV��:��=����JKKk۶mϞ=�3H`�ڵ�KK�k���CN�����ʕ+"+�ׯ_YC�JE�Y�lYNN�>4qHH�<j�(%�4�R�J��NB-`�Ν}IA�C�nԨ�G��3m�3����C���D��^�jР��+]d%=s�L�z�HG�ҥ�^��:t(J�d_ {��ܼ��@~n%B�H��?��3*TP~��t���纙�&p��� �r Hw�ޥ�r�;w��?��� ggg�!�� ���d_x��]����90�Z`ddԭ[����˫s��x������Ը���^E{d|.o� y�:{�,��vssS�����?�������._�\?��P0I��>~�x�AMPQ.55:<�f����n���y�Fd�eL������7������_ݾ};��k߾��O�DSF��\�r(��#F���Z�mC,77��6� ί�ׯ_�����U�&����o�V�X����2|��OOOhn�)<���M�4� l���344��=�,&$$4mڔ���T����ŋ���٪���[�����������w2^��|�ӌ������,8ͦ:::<P��Ν+��ݺu��LJ��+U��k�.F�7oFm��6�纆/^І���(u�ٵk���`UT}]Sѹe�ՀpQ�^=���}�&z(<iii�n�T�R�����A=AѠ�`x�%�%J����yX.�g����u���h�Ν;�1͔��>}��{�N|*�L@�C�dN�+]�4]�:uJ��BSN�8�=a|M�6 %eD���P3���NaӦMh{{{ mB8r��͛7š��1+��Ù�?Ҝ���-tr\����B߃����h�"ڙcjj ��9ꂳ�3�V���EI��4�8h˖-,nݺ%b]g�1�Qx�B� -Q% -z:LB�-amu�������"dV������m�d|�;hڂ��iw���������t�<]ߔ���DR˭��}��d���}||�w�U��ona|�;���� ϔ�M��]�C�Bw:'���r�����=���R�����Z���̥K�rLޱcǫW�2fP�5k֠���\w���rG���W0�a��q����W�9��V �` ������tȑ�\|��4����T�1��.���KI�[���)h�Tt�R�/^L�h�e��B����:}�t{{{brooo��y-��>}�� **�6���K�.�)S�6; ]E�r���zff&�7!����drr�ȑ#���h���Ϗ͓���)�q��8e|^�x��]ɒ%�;v�(�<<����tGDPP1�h�s�s�ƍe�t���jժQy��O�0A:d����ߟ��ZZZ�HdT�<x��frw�,���o۶m��� �j��0R�E��C�.Z�hժUe�r�f���={VX��cǼ��贾��ݔ)S^�~�H �عs'j�S�N��u�ϟ���ѣG�������+WJ���Ehhh�֭�����ܘ�c%Q�N�bŊ����9������%����5j�ofeeu�ޝKy��B����DK�.��ǂ����Q����c|^���勫��Ds�`�oܸ�H�S`` ml&@odD�$$� -����'L�@����M'ڔ@u?t�P����ѣi�ЬY����tQ� �{�K���E�QYkpx�������'O����:t��{?!!�� -T����صk1�r���i���������"� -D��ڵ+w�[�n�p�e ..�]�v����b���l�S��l�bMLL222�,���*i��)������כ��B65j���K�.1�V/^���ッ�)�D˖-�u���T��P�^�;v��_:h��I�e<}�t�̙�prr� ��*��h�a�^*�s태(4Hg�d��}}}AD|�b|�?>'�[���!�5J��+U�ğ��<��;Vǝ3@WܵkW۶m�[�I���{�n�D��A,Y�U=r�H������ŋ��BÍ����3>W�ρ��0>0������2g�k���]�[�n�7���/]���I���,-�[�n����h����� -z�i�&]��lmm:$MG��U�s���oߞ�)��4\\\tV-���e�5jDs�&&&>>>���g -����舚ONNf|^��>}:U�Ξ�:t(r ������(�- -�իW< WZ2������cݑ����GDD�lْ�s�j��ϟzg][�x��)YC��k�������t��6Fp��;v0>���'<<��*�Q�<t�ԉ;�T�D������!:��mۆV�ڵ+��D�Q�P�u|�/V��<"b|�>=z4�L�2Jne/���w��mٲ��m�����۷��Ç��M٭^�Z|^�|yww�f͚�1"O���ի��챆OLL��C[��8��9�h����3gҸ٨Q�:u�ԭ[��ťf͚5jԨZ�j�J���/nhhe���~ܸqڑ����e˖�hт\��r__ߝ;wfff2.�T�P����A�9ǜ!!!S�N�4��W�4h� >�Y���?��-Z��rB���al�Q,^�X����F�iӦ���K�=z�����Ǐ�Bu�n������٠A(��Y�<q�4�����'t�1c���^<uꔫ�+t:��k،���'O��xJ���?�L��͛㎏�O�ƍ�駸�8~�"""�e�Kg��x���S�i�[�R�����\���������-7�� 00�رc��@*b���L�� 6lժ�˗/߿���u��i:�1d�h������a3>}�6#��-[�������I�f��sr���&M�p� - =z4����}�Mʱ���t��y�:.*��E�穩�111�>d�s�w����r� -[��qt��M�}�v���*Uj� l`x����긟�AG�:��U�74H<�=)��;v�����*V�Hw�~ٞ�tP�P�A����?����믿꾨0>�����͛k֬�߿��չ��١��ّ|���igg��Wf���e˖M�6�u�֯^�����>nj3q��I�&�Z�' ��������Ϟ=kٲ������!Ԯ];##r��ru�ԩ6m��>?�%\zt��=6������� �j��9&111��b� -���>}��fdd$rbfffdddoo�f��Y�`�i����J��Ok֬�;�f���j"���W�pa�3f��_�~}��(Tν!l���j�*��4��ŋш0��_���2|�𬬬���&M�4mڔ&�Q"tp�G����O�8�n* F���~~~����G2��#((�m۶Æ �2e -*�gϞu���2����F�t`� ��&]��}���Q���LX4gΜQ�/�v�|��ɰhhÞ�}����9��{pp0��͍#s�)���W�ҥ� -��/�������x��K7������S��2���\�zuÆ cǎ��R�T)>�C��Q����Q����M�s��A�N�0A@|���x-v.��y�G166��a��+W��t钼�.��9.0,��ο����p�!���K$B�6��Ξ=�<�������~ǁ�C���[���S�r���ի����q�ƾ}�`��=�cǎ�jnc!�3���+t�C� ��.����y��\k�ԩiw^ ����naaѸq���=::�I;|�6my�V0�B�K��۵k�e�z��k������������㡓/^כ7o����$W/�{xxdff~���͛7�^�z��)��֭[gϞݳg�0�Z��5j��?���CMb���(�?�xO���@?�����·j.\@�+V�}��+�}����(`�C!hg��&r�o�ο��?lݺ7�=:f̘ �W�\9�|>o�<*͙C�W����j����00�"�ݻw�d�k֬�`|W<_��\��K\�#����+�Z+����4�c�pww�� -H|N0"𫱱1�e�ܹ���[��9���+� �o¶R|`V�|N�(K�ڵ����2s�����cǎ���:�&�AE�۟0>�2h��L�2:uD:==�~�� -�̠��s(��!44T�z���M�.]����v�_+V��_��� �\H����ӧO��\<eSS����+X��n������Rs�?~LIIy�������i_�|9!!��hѢI�& >��ϯU�Vnnn�*U�,Ʉ�����+J:mڴ����W���Yg *��q)p���<O�y&K&6lHky��y���~� $)� -���z�Jk로O*�B�9�M[5��C����[���_Z:�Wą�~E�A�z�;�vyK�W=B��F�ߒ���������o߾��0>����g��jԨѻw�e˖a��ǚd�J�fg|��ٳ��{u� �>�2(���%z���)r�<���}�� ��-[�L�����RB�711qqq�݁���Ç�� -d`���C>��l�s��Z�_����{�|�0���P�H���+�X�Z�T8hn�zH���w��-A�F���]���|hNN7"##`3J�[wrr�ׯ�ƍ�ծ|��͛7GO���9��[���)�����*R�����b�s���;����<,�Yd��)W��a�ҡ- -�/��)d�����Ycc�6m�l߾���6l��Wԗ.]*-����%;;��իk֬�۷/�=�P�J���J�#�nnn-�^���}��F�ڵS��X��ﳅ�΅�k�-���o��a����+�J�Z�ЉV�^]�zu��G���^��z�xll�Ly`|�?�]۳g�ҥKs�nkk۫W�������|��7o$����رcQ��4!��K�UTW�ƍ�M��icY���D1�(��P��K��ﳅ�΅�k�-���o��a��i�&�4��-��2dG�Lӌ�2#w0>�+>�����!!!�m.6���9�m۶�i�ͷT�V �#'�|ˑ��|.�ai۶mϝ;G�d�J��,n0<=Z"��Ph�6����9�-|w.|_+�k�_y�|���/�5j�@}�ڵK�k˗/�.�mSA�g2CLLL*W�|��=���\��Cjj� :u�dee��<x�3g����uh�;v�ߡNۑ�_GO�tXZ�vmy�/���[� -�Q��(�R�|^ �Վ;��vfγ����árP�kԨ�ѣG���M:�L�xsj���y{{�r'��g��4ܒ:Hr���0{��z3"R|���[0I?�� ����e:,�~���ȭ�4��Y��G�֥�Q@�F�'$$0>��*dݺuQ��X���EGGs�PXG�$lj��XY<h��9�������>TD� -�o755�ѣǮ2�[`Ղ�I,�.,e�4gOy��L����Aݍ7��� ���Ʋ<�����ח[��gQ�U�VU�a��\]8x� )0�\�T-19��]�v��*�rpp@�����\s|N�]+8n�8q���=�_Æ �����=���2��AP�佟�6�5�f��Nl6�N�)S��&&v�4"��������8CCC�233ׯ_���J�^�t�|��Iym��ӳJ�*�۫$����QINNf|�5�!�e�j(��/_�/_NA{���'M��|��+`G��#X��5��C�A w��A�25e���ې�΅2w1��������r��l�2M$~��e�`�y{{S@���x�����0SSSp`RR�8����뾾��/^��y�Qh^N��r��ե�B��.�YYYP�i?p����}E]�w��D?��t�����u�+��9r��z���ݹsgZ0upp���d��Tĝ;w0J:99)�$��\]��9s�>L8;;��ɓ'kh&G��5��A���0>W��1,����-[ꂣ6M�ڵkm۶%[��͍;Đ�5��s�UY�����pj��q��Ѻg�:u�^��M};0�wyt��I:pjff�1kyQQQ ���ą�����r���r���S�eT8t�P�j��簿��ӧOQ���Bߑ���UD`` *��~SW�`o�P�g̘�m+�R�_�FIQ'T�Z��A��jժU ^} -�ې�����Ʀ_�E���F������8�BV���;>�W�X���ܜ�]�~�����"��|���%��Hq: -�C}�ŋ�X�֭���`D3�V��(0�ȑ#���!������Iu-,�999�˗G�ݾ}���P�l<�UթS'2QG�%=[.��H�/_������#�V�?>���Ɔ �n"..��RXYY-[��9�!v�څ�jӦM^_d|�� -}��bR�Ν�����ٳG�3Ү�d������#�?"���!�͛��\���Ç���������D�Q�N���8��\k �[...*��p�B$դI�Ǐ�{L�U���" �G|D��zC̘1���3��q;v�L�2��Bd"66��%�3��|�iӦ������;����{#CCÉ'*��&��H�m���#�?"���!���h��ɤ�#%%�M�6k�ԩ�vv$D�)�;�3>�.]��z+^�x�����$7��w/��|�������_�~�3g��kѢb�[�u���������W�^�7(�{�ʕ+e˖E -�˗���W4lؐ����f�!�>}���U�\��ݻ�Bh��Y�&�d߾}�K��y>���sX�fff�[։����/͚5����SE��H�"���Š:�={F����j�QQQt�6�)0>��O��J����w,X@����~Q��͛�L��=m�4V!�§O�|||h�#22R��"''�"�:t��6m"�[x�ԩ�j��rghh�jR- E���|� -b�7n��X�h���Æ P ?���*�0>�+0z���<-X`��BNε�nݪ�|*��� :t�FFF0��~ �b�ʕ�qwƌzX�>�*U -�Wq'��Nq�I�����ܹ3��<x���s�߿733���F Ӫ(s�'\DFF����`}+��1c�b`2>�^�x��:fZZ���'`<{�l�������ϯ[�n|�,|7,�N�ruu�[�.����#Ο?��{%�����x -�[ ��ԂիW�b����3g�zҤILJ��m۶��:Ȫ����͛�*���b|�'̙3�ս{w�ɜ�Rq7]ٲeɝ�1� ���{rr�ӧO[�h����ӧG���!C�\�x��.Fz���Q�mS�֏�\����=200prrb~��={��?O��xA�U�*��\y�(*U���B�)�|zz:8ϗ+WNu�r��|�c�����s|�<7l�0;;��B��HYX���f͚qw<<<pG�-��Ν;i�e�ʕ�/����QR�Tj9 ��\y;vuJTF��̤��eʔ������͊���ݰp�9�&�<L'���Z��Ǐ�={��FpmÇd�c�W:>�3k֬��ehh-�b~��<O��Ĩ%A��ʣ{��s���I�%��+Y��;w���?���ݰ�8q����~��i��/^��C�P��bx�^����oݺu�C�E��j�Jb�J�*�/�G%��@n3���N�<)�2B�B===Օ �s%����211y���'���;v�H�\nܸ��N�ؽ{7�7+++��#�sdCA�a%tЮ��G���tP�LMMA)����s-#$$թS'ŏ���k[[[��7��F� Qá��2�����A��]�v�<Vd4�>�]��2>W~�CC��"E�\�x�U��q���p�>}�=s��mKKK(�[�la5&t|���v1u��YL;��M��B9;;�788�sep��-R�{\Y�f ��=|�0�4��ڵkD�-Z����T�dxx8����ԫ��{�zhЅ��D�.]K_�pA�)3>W�'OF- 2D�3qqq��yݺu��Ԏ�{��EȪ2;�F�A��iu�A�@�244455�ٛ��F���8������W�bE�����hR��?�`5�^@5j9��ի����ׯ_�������Y5 -�Ǐ'g�?~tA��뇂���O�p�����8w�� �7}������a��;�n۶��Y���.]�Wh���wb������x�D�A�����~���y��*�0a�<1��q̟�q��yکB��(N�W�.T����*V���>��� -1��n�"+~Æ �����˗�ŋ+�eF`� -ȏ -�����ܴi��?�LL�Z����� -� �i�&!!�ճ@�F�9���{a��!m��ݻ�����b<x�S�vm���yh��b�7���v��=hРbŊ��W�Z�.�'''��+W�oѢŖ-[ؙ#!�e˖h���(Ϲ�����ȶ��+��`|^ �ٳ'�gy�?]�v����FDD���>|�p������{zz���Ӛ�����K�� -��!<<�����U���7oޜ��̚C(x�����@@�Qg͚E�U����<߀�V�P!CCC�����;�xc�h��&������5{��=zT�Z���P�;v�j!@6t�}�����QTn���ᐐ�C��1���v�٪�b�amgg�/_��~n�oߎ����H�?�+nTNӦM�"-nnn�=�%�_��ڵk���&L��t����ݽnݺSJ�(Q�hQPT\�!q���imm]�X��%K�)S�|��+V�V���F���۴iӹsg����Ǝ;y�d�.\�t�ʕ+]�a����;����;v�ةS�N�>�O -��;����ݺu�u�I�3���� ���A�U�^���$P�H�bܸqG��B5J|��g�\5�˫F��"����ϙ3gŊ0�bbb�+�aŧ�@'B͠ 0�6mB%��,Y�z�6m����Q�����֭[���[�hѰa�ڵkW�R-��F���١6,,,���-���؇W�X�'N��f�d��ÇzK��!��p����fEV�2���/�l��'5d�C?\�~�ȑ#��ѝ��|��t�.ݻw�oٲ�����K;>A��F�ժU�r���m-C����mٲ�I�0�fgg�U��H�Z�P�R��L>x���5Zjذa��G������g(�� �nh#�6�0��B<x0�]����L]jE�T��Ǐ_�|�{/_��H���!bH����L��O)))ϟ?�� (�ߺu�ʕ+ h��O7o��z����O��3f�o��!0`���0�x�[������6o����w�*���~~~���G&�rϞ=;<<U�~��?�k�7��7o�Da�Y�h̢#F������z���' -��SU���fP]�t�ի*U����ԩS���n1@GGG�ݻ�{�ܹkݹs-����/^���~��!##��@�Ezz�۷o�+�>�����̙3aL!����occ���`b -B-@m�ఞt3{h8�����(���!..�֣%=� �Y]����������"}���?t�ˠ�x����Ç��R)�&��_�b�Z���80������aLԵ�A�rqqAsԯ__���sy2dj��?��߄�I]ڔ���ؠA�K���W�VK0#}4|n0�Hi�M�l�2���` js6CI���Ն�U�^]����t�R�J�f`s7�\�bjjjdd������-���EL^�fM��菬�T�իW�w�N����!�H��� -�)dys���\1>����TKŊ�;�?vvv�͠� UR��ə<y2mc(]�tddd>�(�2v��F�������ϡY�fH<OI��c'�a�:�/A3��+& 0M�ȑ#��p���� �G1���IKKC�������<�vܘ1c�;t"���E��>|� ��so��'B��x��ٳgݺu�J����Į?|C�z�Q�&���D>��L��M�x��=m�211Q�ڽn��/^�(�w�[��e��3>��ʕ+�ZΜ9C_<x`aaahhx��9U�9rpp�R�@A�X���N;�A�w����ߤ]W������תU+<<����^�S�nݳg�B�y���{x��?���������}||7n��qqq���0ś�?��������<�״S�z��={��U,�8&rD^�6M�Ԅ �ԭ��+]UFa����+�2/�%0�����NJ�(���6mڨh�A�wwwG"U�TQ}JS�6l�O//���,t�)S�H<_�\��O�fdd�{�9INNƝ-ZHk�u��!�b`�z�OR5�S���_[�j���K������Ou���4&�1����8~�8�6�8��������Ü⡍?j������3oe��P����W�Jsx��!i�j��Ջ3f�N D_�(�]��B�.]Z-G�$���.S�L��V��9��:@���~���|��Z��ر��i)A���K�y�J���J��^��Әx���Q�F}�����ŋ�q -7A��_.YC�� �i���� -��L2k4��v�Z����+Wh�$����[�ϥA�����Ksb�r����N011Q�Ѳ�s`| ����;Ç�q�L�"���s�;(]"q���a�S�vm|�^f&��H���4��n�v(�'�?~���3:��+A� ���l�}�8%1B��s�+�������222�u�(�,�t�Z�ji�w��E^� ph���8A���iii����R%M:�4w�\ue�[˫Q�FϞ=��5i҄��s�N �R�d`���v�mۖ���K�.͚5C�aaaHZ��4|�Ô&�aiKJJ���ݺu;v�X���}}}9c�`��1q̘1'N�4i��8%����s�+��v@�j<�k�P�jm��C��ٳ�/Āt$� �s �G���o�����ܹ��O�:Ek�h�����.���Y�uL�m������㔒|�Eb�`i-Z���L�������iR�ʞ���"�h�"ݩ�#G� W���+����K�(�5TtU$?��L�0h�3&°�O�|XVVVE��t���7oB@MZ[[km�LI8p��e�o߷��B�\�r������۷oMLLlllXhQ��ѣG!Ҟ��b-`�5�زeM�����&sؽ{7�ֱcG&�4�B[Yrss)��̙3UI��鈁J"##�����¢���i�=~�����?��0`�F���۶mC��v�ʤ���52�F�^�v��ET�Sׯ_?��~�zV���777dbb�(K���cooodd��}�����?�ƍu�(�1�����ۏQ���U�V�Ś5k�������h���͛��'�:Z�����Ø�^���]��L8P�`kN&�H& -�z�ju%��ӧQ�F�>��͛��\|����Ť<���(���ŋQ'�b�ʿ���ۊ+Ξ=��Ax����;�̙3���>x��S?j�s��U�#�[Mɶ��ə3gB�iץ6eRkP�����ӂ���قt���U�t0�q��رc��AGw����)Shz�z�#:gM�������!zU|��������9f!�{YAq�yn��?r�w��'��w��[$^��#>>�F��.>��I���^��@w���566Vq[�gϺv�JU���~��mAٲe�o�ȧb�� JϓrΩC\�!;;�����y���?^��<xp�ܹmڴA�c���;����#�|w. -�\Z�xQ��&�9��%ޕv��>|xbb�*>�$d�W�^�\�2�;@�O#@�a�*T�j#���n/\�P�1�ނBQȿ<͜�T���U�"�Dڷo?p�@p�.r�%��%<�p�9�s��fnnn��8��(�t��d���J8� =z�7u�4ӎL�P�(W߾}��"$!**�&X���LGz�9s� �&L�s2����u�/�|oEPi�P�,%ؠK�.0���___>�H{Y��X��s�;�+ %<�����If��^�ksD�9�J��?�_�;h�[u�fZ�I����1H�*U*Oz5�\T/� FX~`2���K{X�7��9Y!!!�$%OR�,e`` y�k�ҥK�$#�eE�a�G���\���'gggy��{Q|��Mz���.]����#�j�i���P,椤$e>z�(��#�^�O��4i��fD��S�R�+VL�����!�)B���G4��W���Ç���/^���O3}���~� �������Ktt4���b�U����e���wC�f�6m��I�CbU����I�Y�![�>|X�d l.��*U�lڴ)�tZ�x����ζ���H�j�B(�1圡`�W2���s�T�R�/\�0p�@�V7n�k�.���|���={�賨�?��Wހ��:Ĕs]S�E/��Q�By����\���{R4�Ν;�2�*��0�z����SC���kBb�9���袗I�@7|��m���R;::N�>��ӧb-���+�y��U}�srR�� N?DPPIS�t� ��_�����U�g����w������$W�Z(ؘ�p8 �jߴI�S�tME�L~���ʕ+s��mܸ1�"!���FDD�BE��5�CCx��Ehhh�֭1*��͠�ԩS�X1��#G?~\@Ǚ�L2��kb7o�\�bto;;;.)KK����/]�������F�;--��Ѥ -433������WX��6K�f��L��ee QW�d����'Onժto�++V<x�{�He˖��Ǐ���AX�>y= �C�=t�УG�����(?Ŕ������q{�~�X�.����:t�7o^TTTBB�q�p� ��صk1��R`��g�FDD�3&O�2e$F�����2ݒ�ϱ�G����Pޟ�Y@y���355E�۵k'�ujmN<nذ�v�l��˗/�N�-��5����8�ҥK����ŋ�������`i5�p��AAA�v��a�'�˗/�9��j>>>2(�-�<�5JL�� -]+U�U,���ɤ��/���Q�����u������T�̙3���������x��'���:T(����h�l O�HLL477744Tҋ_&���%Ȝ�|��`��[&:��iݺ������q]�p�-Y��@w��>�Ν�n߾=��<ɤ��-�C��������͟Lb��...z"��dӦM��-��vɒ%�F4����P��ƿ`e�L.b|�:�c�,Z�h�d��u�/�'�شiS��ԩS�����\�gϞ1���X�v-� -�erǎ��5�瀗�W�d��ׯ&&&���ↀ�g>}�Y-]�4��B�%����7o^�z[�l�뻰���y �A2Y�X1yD��\-|>z��|ˤ�lAǘedd��K> h�� �A���E={{{��u -Đ��A���nj�+��LV�V��F�|�̙��I - -|��y�����*TDn���/�"s1�l=��y������cK��ӫW/��tg��?��������@??�nݺ�E�x��N�ruu�[��ٳg�}w.kWgg�'O������kժNT���,���S:K��U�:uk�/ηLv����[�=�"fRlq�����/_�HΦ���H�� I�9䍂fJG��",�}��f�%gh ���{.'�1������{?��p��T������rttd|.2>>|8� }��f{��:U�`���o�^b�cop/T#���Q���D|||@��9�<?�=w�&�~�׆ ��.�& +�_d����|ڴixw�ԩ��#F�@IW�X���A�z��^��_GEE���o���O�3==�ٳgNNN��?y�Df�zn��xE�]�����9��2����H�e˖�Ǥ�����%�%��B�s:R$����AI!����saffj�bTI����Ç7i���;p���I�������䗗]��-�z&���x�W'i��Y�f��|��a�����ߟ���{��)O?�ҥ^G��E�|����Ż?qℋ��:}�4M��V�w �c�|������������5k��͚5��S�B� ��>}��W�IժU���[t�-��>�.\�0j~ƌ:��K�,��#G�=�����ϟ3>�!�C%�>�+W��O�~�:����a��ŗ|.�t7�2 ���L�nbP�s~Aճ4��7o�G�4+et����uAS-u�>3f����k�%���-&�4Ǻ����CN������1`�����C��|ժUxwȐ!�&�w�ޡ�E��:��������������t�lܸ1nr�����W�������G\����K�n)Rd�ر��2��Q�F���}���ӳJ�*����ϕ$��;`��k���ɗ,G���!..�O��%HK����^T�(縆i��|Iƅ���ܹs(fÆ �+��٘�ґ̷��OΝ>��tl��^�xA�2y�W0�2q�D++���T��<&�7s��k ڙ?������C'��G���Y�0�����w���Ó���|�m�6��'nQ\�r%�9l�0��JΟO�<��?�h+���B��9X[[�&/3)�����6M�|�K�3H{��ϛ7���4��5k�Yw�غu����m߾]��|Q��{�����={�n����s�Q�|��K�.d�JO�p��Zp!=��>v�8ڗ�ws̘1E�a|��|�v3ЁGH�4Es��,�9IaJ����|����㱺��4�7��C1�^���\�����tZA>w���В%K.�\H��*Xr�^��=����9�o���nڜ�]`�)��G��CCC����VZ���oii�����癙�&&&` �+p>����*�BW�_Z:�Wą�~E�S:���@``�h�C��T�h V0�Mάh -=|.o����U�Z��O�����a�%11eԐ�$��~r���+2>g`���C��B=+s���9�N��� ��^�D߾}QF�o���Zϊ��3>g�)>'Y-p��E���QƇ2>g�_=����������&?~��-[V�<à�z����������&6mڄ��Ջ�9�g����s�$?m�4� -�A�P@��" �xsځ���� -,ޜ��xs�� -�T�Z�}������Ak*ƃ�+�x���sU�Aw�� ��ܹS����s��T�R��ynn��������g��h�s�2�c����s//�|�d�F��.�@d�#f}��b�1@#�K�,aL�!ddd��v��à�L0>���������[&����@�=���S��۷1�t��EZZcM�������e���������5��C�ɷL277����)>���ζ��611���B���7�ޕ�Πj��CJJJb��W�tww���g|�^>355ͷL�y�Mckk+J���T�-½{��-�R�5���R#�]����'�5$�������\>_�n]�b�T��7n�ugggQ -E!\�p��K�!i�ӧO��X:6l�X�-[������|�d�F�bbb�������):�*2y��Q����)J��V�Jw��-���ɓr->lذC�=z�(++������ -�|ɒ%u��!g,���cu��L���y{{ϛ7/***!!����p�={��T�\Y-2)b�-w��AѪT�"��~�:00��".L���|H��Z�jq1��(�tփAHԕZd���GR�-�����(ڔ)SD�a~��gŊ�[�vrrrssc�By>����]��ȑ#���e&����v��!�}��������[kkk���*t 7Z{҇�V�R��s���u���<kAAA�{w�(�Ȱc�d�ΝE_���t###KK˜��m���h�y��1yֲrN|�Tt��u� ����}Iϟ?��6h�@d����utt400HNNf�5L�2�����a*:�.@���9�Z� -%2d���u��i��I�&L�D9g*:��|.^�X�%%�:aaa"+����I9g*:���Ɗ��?��Jz��E�)� ���&���3�AG���Q�qㆸ����nbbbii���-�r�����&���3�A��,Od,'��Ǐ��41*77�Z�jl�y�+�LEg(p$$$��їt֬Y(�ĉ�T(8T�rN���Tt�� �cǎ}I[�j����ʼn�P���(Ttt4�d�)�u���Q,Z�H�������dz�b(�h�x��1q3++������,==]4������qɒ%?��$Y����ٳ?~����v�̙ �Yt���gmm-z/�����8MӧOg��5�B� -��th�8�X�:�Eg�>���!�� }I���I�M��?nnn&�0I����9&�@�k{ǿ)��b:�z��A�Q�II/]�$��;%7n�E�ƍ��1�2>9��Ze``���(/��ɡ�C?���$�`AK�+V�`U�PP��������l�X�lJ(�M�>%:t(�������]�taU�PP ������s�4<<<P���x�(綶����<`�\�HMM511�����<�Ľ{����DCq����M4a�i���ߟI���M�6h���`�2���j-֘��,��Ç��8���������٣G��0�h�EO"|1�`R�Mggg�>�aÆ(�s��Q�^�z�8cƌa¬;��W�\9� �x�|��͛7�W�ޖ-[��n�ke�#|���s��tN�����P�wU�\Y;[._�lhhhcc���&�:h֯_?�z��,##���My���+�s����N��AzR�ɓ'��%9gX�`�g�|�U��֙:uj��=�����c�cǎU�^����b���駟<==����������ϯ[�n.\@Rx�ĉ�N�ruu�[��ٳg���v� -���ɓ���'�Z�j����+����xd�gϞ���Y�p�СҥKC��?Vp�2e����>}*�⠫����233�H� Ν;a��s��|̷`8��_���cONN��+WN&�שS�� Kءe˖�MP�Z�z��%���^G�!Yz�����1����},$��Ao9::���>~�8d�P�@̦$v�Rw��Ie�����ټy3�j�y+���8x�`^�s��۱cG���!:%ޖ��_�������Ϲ�+U���?p7�ׯ�O����aÆ��p:<X��� K���f͚U�X1���Պ+Ds:RI@����1cƠ,�G�ֈ�C`` Z���t���J6��б�'���3⤟?y�_���j�H�+�r�֭_�z���"������Ǐ#�-[��6��"K��t�ԋk���@��������d����ׯ�*�^���ʕ+0����X"��m d{{{���*9�ҬY3�8mbsvv���'F���={��ϻt�כ4i"�#䤤$�ڴi�nݺ�8q���I�>}���IrP������Ǥ���+e��ח��Ԉ���S�NM�6�F��лw�;w��g�@�Q Б�^��� -c��er.�۷�L�%K.]�T�%�I��N՞U��I5��]@?�Ǐ/^��q�F(����(�kמ3g4�m�`8C������Bឡ��G�����SR�K�.�hѢ|;O{�����g�*Ubcc��iii.\ؾ}��y� ֩S'X%�ʕ���+\�������!� �&&&VVV������NNN+V���ZͶj� -��n2d��ѣ'N�8k֬�Bo\�zudd�֭[w�܉��ȑ#��`�<y��_�u��Q4ߖ-[���ŋ'O�<hР:����)S���v�ԩSoɺ�h=��ᅤ -B[C*X� -�.]j۶-uR##�-Z��'%%�6(z$''�\��o߾��Ψ��)�����)�����=l`��#�CNNT����Y� -�n�ȑ#K�*��_//���ǯ[��ԩS/^�P����{��҄>p���k%&&�%�4<x��8t�tH�7n�x����3g�1��]hD����ҥj$�9>>��ի����ԏ?�����k���իW`$x��=(�/^D����ƍW�Z�}̘1��ӧ����v�����͛7oҤ �����/����ۻG�x�=�����={��i�Gl��<0@����OV�D���˗/0�G����"� B�,Q�D͚5=<<ڷoߵkW��СC� �TCۄ�B�֭���oǎ[�nM��5j�prr*^�8�K=��ʪB� -?��3��bll�ÇQ��/_F�p����#�-""C�L�Z�,v��?���6-R���ׯ]�3g�mB`�Yp�](��o����߿?�80��} - -\�dI(U�T�]�6ԦM�BilӦ �6�ѪU+���1`,�������ݻwQ�*F���`��?Tw5�c��Z���:c�A� -9�b{Z�J{������w��m۶�B���V�\�z��k�Bۄ�}2:::&&f���0�O�< ��y��G�^�z����ʼͧO�<xp��Y�WPPP�����w��#�� �e˖�� 3E��Y��X@����/�7vww''K�0���E�BAPi�CL��Z`k� P��!���#99#Tt:�T�T)**�`�|���U����СC�:��!m۶�\�ҨG�},�_d.�7...h_ӂ.Ⱥu�h��˚�Aw����u�VZ���� -� 5Ȝ�p/^�ȑ#�L����B�ڵ�?}�_�>�E�BAh�6�S�q�`YXX� 0�Y�2�&���G�MLL�z/i�NNN����_"���<11�����a�_d.d�P�HX^gΜt) �#F�`������� �m����צ5g������D4�c�>������z���>�/2 -2�*"�n0j�C)0L�&�)��+�v����G;��P���͍�����/���F},0(@tt4]�E����4��C�����-Z�5�m��њ�#��X`P0Gakk+t��3g�D������֦����� MMM5�l�Ν;��%J|���U�������L���+�R�ڵR -2OAt�ƍ��B���r���ٳY����dɒ)))-'hC�v�UM ==�\�rc�mH���4scc�/_� -.\�`fff``�w�^�!11�p���Çg � hй �Y��|(D�j�!55����]�E���i�W�^�{*�Б��egggjj�LH�|��?��+i��ڴi��mҤIvv��p��ݒ%K�;vd�āA�A����5�x˖-���ÇY=����h�%J<{�L����1���+�:� l߾RݥK�;�Ǐ%n��x�O7n�`�.h`����Ǐb�!�U�TA7n,�px�_A�9����۷o+V�8{�l��322�����̙3g<==���OV��šC����Ѳ�ׯb��߿_�B�nݺ�Ս�AL�(ت�7�2e -y�"V����w��i��� �D��իW�'O�,��_�v�l� hh͈��`ѰaCH��~��s~����F����U�B'��?�U�@q����ŋ�n!��;{�,���@� P#�L���@�w�ڥzR��.L9(n߾M�m�֭?�,��<x��Ғv�P�o߾��Փ��nmm-���̹@q�ҥK�f���)��GEE���"�d�������s�j掎�hA���t�����7((H��DyB�>} 푑�jIM��Δs!����\iS�m�����ѣ2>���d����2�a�u%(��3�\�8x� E�n߾��4����u�\ẗa`�+H�ٴi���Vљr.8�^311�~(+���ɓ��jժ�n�b�ɠ?���qqqjL���3�\X�{�����v'Nܜshh(�D^^^�c ʠW���� ��Wљr. ������/h5333 y��222@;c�����D}�/r��ծ�� �s���/_&/U�K�V�|��q�ʕ�ի#�VVV۶mc�ɠ�x���T{ʤ�3�\�*�x�bsssr����ae~y�üN�:����� �Ӆ���n���������]�X�b...#G�<~�8ۓ��ɓ-Z�4��ѣ�u�399��ݝ6%�?^�gW��_�433�8�jժ����D]ժUk���z+K����դt��G�V�n�Z�hQd���Q��{�'O������:�С,ͨ�������� ���k1bD�ʕ�����on=�ْ��koP�[�g����},BD\\�6j�(&&��K�.1�V/^���ッ�iE�e˖zw,;;{���� -B��lY@���͍��$����ZX�g`�p��}�.}}}AD|�b|�?>'�[����;j�(}��j֬I�C��Z~�ƍf͚�Z��ɓ'� -ooo������3>W�ρ��0>����$��ȐD��ϟ?/����i���tP�|������ \�p�lkk{��!i:b|�"��&_%��G�������,U�/a��ݽ{7�xĘ;iҤ��F��СC!�2����|���hѢP�_�z%�INN�B�t�g���Ļw�b�%��_~a�XD���\�;v0>��^^^���k@f�\�ңG��laa1~�xaM��~��M��,Yr˖-�ā�O�B��+&������G��z�)$\Q������������S�N7 -�� f͚U�H����rҤI>|`$� ��y�j��k��gΜ�z��������ӦMsrr"&�T��ʕ+��<33sɒ%�Ƒ##����C�aݟAd�믿hOcc�b���4O+ ��cGGG�lْ���v�֊gVVVhh(E)500�ԩ����Y�g`|Π5>/@�/�߿߲eK�Ν)�P�\��S�>z�HX����'��e˖%&o߾��˗Y�g`|Π5>?w�\�?~��eIx��ɚ5k����0�0w�����Âs���͛�ӧS|R0y�v�Ygg`|Π5>?y�d����9s������;v�6lߓ���u�=p_pa��}?�<r�� � ���(ȵk�X7g`|�Q�_���ݽhѢFFFvvv-Z���D)��/X��V�Zf߁|�~���D�qI���#Y~R����݄Ά.���2c�]��#G�p��5�4�۷oo�W�n]�'�)Sf����c���xooo*,��C�>x��up����իA�&&&0烃� T�B|������Q:��+ݻwGR={�tss�'5�?`�n��� �QS�N-(>���ݿÆ ��������ʺy��m�ƍ���A[�8`$�ܹ�ʕ+A����߇��b���-[v�ܹ���� h>�W��4((����������iΜ9�u����]�������p��(���'�>�s\W�^]�|=y�ΝА%��|9��̄F��5j���WŊ�$>��U�VŨ�dɒ˗/:fbb"enѶq�����z�ǒ�Aw����<xP�'�|N�ʉ�\PXa�ڴiS�۵k�e˖η�LG;|���E#�4V�X!�F`��/_{�ҥK��ݻwoذaٲe'N�۷o˖-����-l�Q�5jt��u���xW�g�?N�o�l�����$9C��L�_���G��3�A��X�ʕ�I-�[�n�H�2��Z�{--Z�p��P;QK&&&�)n���*T���:thHHȁ�߿/��� -����q�M�6�����v�Z!.�20�o�e y�o�;w.}��|N0�iW����7�N���l����Ea���%J`�B���;v�ػw����Y�fEDD>|����oe����L�#~~~��A^ǎ��������|�j�*n=t�ĉC��X���O�έ�Bw ��[��Cmll�t�ܵkW�[�b����k���---������+W�qEi��ļ{���ǏP;Ae��ق���7222�������-ࢱ�w�~��A�X������4o������аhѢP;eNz�jՊ��-��+₿_�e˖�٠��ڵk#ee�+ZYYAç�B���ꐐh��lڴ�>KcJJJdd�����inn{d�֭iii��20�&���D߾H�7o��p\Ϣ����&%%͝;�Y�f�ܸ��E���7n���200>��Џ?�L����X�͛7���}���mōe(;̨]�v�UN���=����ۀ������Q -�������;z�hWWWnߎ�����KPP�ɓ'��8�s���JII?~|�ΝE#`/_���=v�؟~�����ֶ[�nϟ?gݐ���(�+ -��#r������_�bE�Ҁ��u���QW�^��};����υ����7nDFF6j�����%J����Y�`�ŋ�t -�F��ͩb�7'��oߞ8qb��� jР���`ll���2t�Ѝ7�u1��Ń��7�/���պuk -�Ç�����s�>}�-[����ob*"77������`ǎ��5��^^^���k��$��oݺ�jժ��`???���.J>lll�7o~��y����Aw���ݓ��$ 444|��U�7wZZ�������:nܸ�]�����(QB�{F�dɒ������СC�?f]��Ag���H� d:�e|�:�25ܡC-p�ÇѠ�눈���烱���۶m[�v���9�V2�~U�V�U�V���ٳ�n� -��ݻw��00�����P�8?������aaa���PΓ��$���ׯ���YYY��>�?SSS_�~��ѣ7n�Q���={��]Y y�̙����������֭��V�^=GGG��%��J�Y�&^>|8۶m���/_��=#��{4S���+A��U��u����ؠbA� RKKKr,)6H]�_@ �*��Z�� E�:H�;�j�������5j��\E>ǰEZ������c��"E�`T������wrrrvvnР�/��ҡC??���5jҤI�g�^�lF���h5�Qrr2�X������ɓŋ��=�����͋��JHH`D�$.\��g�0m@@@�ʕ���'�x��ÇЍ��ӳ�������M���ׁ�����Gc�C��jժ�� C����x�Pjendstream -endobj -3711 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [423.666 634.392 465.806 643.304] -/Subtype /Link -/A << /S /GoTo /D (lifecycle-image) >> +3707 0 obj << +/D [3675 0 R /XYZ 71.731 407.407 null] >> endobj 3708 0 obj << -/D [3706 0 R /XYZ 71.731 729.265 null] +/D [3675 0 R /XYZ 71.731 407.407 null] >> endobj 3709 0 obj << -/D [3706 0 R /XYZ 71.731 741.22 null] ->> endobj -630 0 obj << -/D [3706 0 R /XYZ 259.687 658.108 null] +/D [3675 0 R /XYZ 91.656 395.164 null] >> endobj 3710 0 obj << -/D [3706 0 R /XYZ 71.731 645.67 null] +/D [3675 0 R /XYZ 71.731 393.007 null] +>> endobj +3711 0 obj << +/D [3675 0 R /XYZ 71.731 393.007 null] >> endobj 3712 0 obj << -/D [3706 0 R /XYZ 459.262 623.597 null] +/D [3675 0 R /XYZ 101.619 382.213 null] >> endobj 3713 0 obj << -/D [3706 0 R /XYZ 220.262 610.646 null] ->> endobj -1896 0 obj << -/D [3706 0 R /XYZ 71.731 608.489 null] +/D [3675 0 R /XYZ 71.731 380.056 null] >> endobj 3714 0 obj << -/D [3706 0 R /XYZ 71.731 570.766 null] ->> endobj -1609 0 obj << -/D [3706 0 R /XYZ 71.731 173.681 null] ->> endobj -634 0 obj << -/D [3706 0 R /XYZ 263.164 128.426 null] +/D [3675 0 R /XYZ 101.619 369.261 null] >> endobj 3715 0 obj << -/D [3706 0 R /XYZ 71.731 115.988 null] +/D [3675 0 R /XYZ 142.884 369.261 null] >> endobj -3705 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F32 1187 0 R >> -/XObject << /Im1 3704 0 R >> -/ProcSet [ /PDF /Text /ImageC ] +3716 0 obj << +/D [3675 0 R /XYZ 142.884 369.261 null] >> endobj -3718 0 obj << -/Length 2327 -/Filter /FlateDecode ->> -stream -xڥYY��~�_a� ���i{�23�dg�ӝA6�D�Bd�#R�����b%ZR@ЀţX��b������6��D� w"L�Y~~��a���X1�ʣ�����K�vb�F���,�"��l�b�����_�ϧ�bd�\��z���M��������ʪʖ�~���_:�I��m��N�f�T��r���"�c�S'�j����g��� X/TK�<��q�`�D��Ҝ�U��d#?pӘˇ��*����밪�~�,Q�fl�[p�0��}�����G+��e�,D~,���F�N�m�Ž̚�D�Kv��S�����4���A5�в����nQ�a�8� �a^J�r_1��q:�ZPQZ^����n3Щ����8 ��,�]�B"a(n��t/�Λr�2G,�j$����P��"�g�b��B���iQ�}C#�2��yg�5�����[�, �isRZ�%Z���/�i�i��9���{Dǡ5�2�M���2�V�g b����Y;g&?Y����]VՒ�C�~k��z,�H|�%uǤ��ZY�t<�w��i2��p�䄢 =�ҧ����y͓jZZr�kZf�ε=7��; Rd�>w�3}���#dc�}2琐].0���!|H�uPʢ�,8�h,��h��R�[`z�ц�6�pC6��'�*i���Wtw������G�A�X?��S�8g�3 �٨Ӆe�ŅB�X���A��ޱ��TQ��ez������6M-��Hm�<�R�^KAf:8鈡%V�}3���V~eN%/����z�ub5U�̻l{p�Y��'N����j2����/�̔����1�{�O6e�,�a��<C�҆z�v�z�=��;]�v� -�͇9:���y��&H�r��hJ�g:5���J�}`���� JH0�p�`��N$Ꭹp�m, -0�d � -:p{�U�ID���`'�2�ԑNq �톅)�!���H/H/�$����!/2/�E�XF�d�d�������0��?eB�Eh3�X7s��5�x�p]�0 �l��X+X�IJ�cO霨ȋ�?�anEQ�_�mna ؔM|u����A,�Y�U[�`r��]9b�c��¬B�w���U���)�nO�ݩ�sO���L�w���95����q��(�4 -���v|Y���HgI�[NJ�4 |_J�=�ۂ/�u���a2�N -~{�d$�w�m �]|%��2N%��a�գ��V:����8�ϡoE�۾�ZO�jL�jca��6>��'��B��!�;B��b�;F2Ŧ0��"}���h�Ì)^�l,�u�§0����&�S�j���.��ӮF��D� -g�;hw'ui[�A2A�+�I�[��"�^��ҷ_�b�V-�p��^�Ҵ~'s�`+vp?"�{�iLy�R#����jGj)m܂Qkbة{��7��&+k���i�l~��T���?���u�֭E �2��./������4�h��S����+Ќ����'9Q�!�K1�w��J F;H6T��Ƃ�~-A���:���+L��z�&�,��AM���_���V\-�%_{06�?ڬ�s�q�s��q�j=��H*))�<:�음�{���ohO������UL#���Ȭ�� /p��G�ދ9 ?8�!�. �-d�-�o�Ab�m�N�|�"������0��<6c��M_�+p�mwY�S��xYm���c���C_3O�$}3X�z����I�أn ���p�:h��"��0��n���Ci�\�vŚ�.���S$�.5:����9��h�x������t�ӭ�� &�X�E�@r��&��[b�G�kѸ��Xam�v���K�#KեV�[�,.ں�jï߳>�4��t����e��Ojo��b��1��pK0:�u{>g�Ӝ�9r�᫊�|�A�?�xq3Fb�Ҽ��=��uO'�=���4ܔ�������r�Cd�k���/W��b��6b?S~,�jP߫��'k�[�����4�Og�ϰh=�ڝy�Q�K�4���՝G�Ч�C㒌�ܠ�.�eH/�P�ϟ��OQ/��&u��+�_����7��P4��D��Q�# -�!�0�# -D���g_�@�6u�N�����h�����e��A�G����0Թ/�e�5UW�����-Q�>��I9x6"O����E�����b��U|1�Yj_ �k~R�A���V��'���P�����a��}O-x��� -t� s�uvW��CP��k8�m��f�Սy��� ���L-��`�r)ӑ�����4��kk���Ƣ���:�gendstream -endobj 3717 0 obj << -/Type /Page -/Contents 3718 0 R -/Resources 3716 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3610 0 R +/D [3675 0 R /XYZ 76.712 351.328 null] +>> endobj +3718 0 obj << +/D [3675 0 R /XYZ 91.656 338.377 null] >> endobj 3719 0 obj << -/D [3717 0 R /XYZ 71.731 729.265 null] +/D [3675 0 R /XYZ 71.731 336.22 null] >> endobj 3720 0 obj << -/D [3717 0 R /XYZ 71.731 741.22 null] +/D [3675 0 R /XYZ 71.731 336.22 null] >> endobj 3721 0 obj << -/D [3717 0 R /XYZ 245.796 708.344 null] +/D [3675 0 R /XYZ 101.619 325.426 null] >> endobj 3722 0 obj << -/D [3717 0 R /XYZ 71.731 657.37 null] ->> endobj -1610 0 obj << -/D [3717 0 R /XYZ 71.731 644.419 null] ->> endobj -638 0 obj << -/D [3717 0 R /XYZ 217.917 607.203 null] +/D [3675 0 R /XYZ 71.731 323.269 null] >> endobj 3723 0 obj << -/D [3717 0 R /XYZ 71.731 599.851 null] +/D [3675 0 R /XYZ 101.619 312.474 null] >> endobj 3724 0 obj << -/D [3717 0 R /XYZ 71.731 579.94 null] +/D [3675 0 R /XYZ 145.653 312.474 null] >> endobj 3725 0 obj << -/D [3717 0 R /XYZ 71.731 551.113 null] +/D [3675 0 R /XYZ 145.653 312.474 null] >> endobj 3726 0 obj << -/D [3717 0 R /XYZ 427.586 538.262 null] +/D [3675 0 R /XYZ 177.534 312.474 null] >> endobj 3727 0 obj << -/D [3717 0 R /XYZ 113.318 525.31 null] +/D [3675 0 R /XYZ 177.534 312.474 null] >> endobj 3728 0 obj << -/D [3717 0 R /XYZ 205.079 525.31 null] +/D [3675 0 R /XYZ 209.414 312.474 null] >> endobj 3729 0 obj << -/D [3717 0 R /XYZ 71.731 505.221 null] +/D [3675 0 R /XYZ 209.414 312.474 null] >> endobj 3730 0 obj << -/D [3717 0 R /XYZ 71.731 494.326 null] +/D [3675 0 R /XYZ 241.294 312.474 null] >> endobj 3731 0 obj << -/D [3717 0 R /XYZ 71.731 489.345 null] +/D [3675 0 R /XYZ 241.294 312.474 null] >> endobj 3732 0 obj << -/D [3717 0 R /XYZ 81.694 466.531 null] +/D [3675 0 R /XYZ 76.712 294.541 null] >> endobj 3733 0 obj << -/D [3717 0 R /XYZ 81.694 466.531 null] +/D [3675 0 R /XYZ 91.656 281.59 null] >> endobj 3734 0 obj << -/D [3717 0 R /XYZ 71.731 464.374 null] +/D [3675 0 R /XYZ 71.731 279.433 null] >> endobj 3735 0 obj << -/D [3717 0 R /XYZ 81.694 448.598 null] +/D [3675 0 R /XYZ 71.731 279.433 null] >> endobj 3736 0 obj << -/D [3717 0 R /XYZ 81.694 448.598 null] +/D [3675 0 R /XYZ 101.619 268.638 null] >> endobj 3737 0 obj << -/D [3717 0 R /XYZ 71.731 446.441 null] +/D [3675 0 R /XYZ 76.712 232.773 null] >> endobj 3738 0 obj << -/D [3717 0 R /XYZ 81.694 430.665 null] +/D [3675 0 R /XYZ 81.694 219.822 null] >> endobj 3739 0 obj << -/D [3717 0 R /XYZ 81.694 430.665 null] ->> endobj -1611 0 obj << -/D [3717 0 R /XYZ 71.731 428.508 null] ->> endobj -642 0 obj << -/D [3717 0 R /XYZ 236.902 396.194 null] +/D [3675 0 R /XYZ 92.483 219.822 null] >> endobj 3740 0 obj << -/D [3717 0 R /XYZ 71.731 390.067 null] ->> endobj -1612 0 obj << -/D [3717 0 R /XYZ 71.731 318.321 null] ->> endobj -646 0 obj << -/D [3717 0 R /XYZ 166.08 285.011 null] +/D [3675 0 R /XYZ 71.731 218.414 null] >> endobj 3741 0 obj << -/D [3717 0 R /XYZ 71.731 276.374 null] +/D [3675 0 R /XYZ 71.731 218.414 null] >> endobj 3742 0 obj << -/D [3717 0 R /XYZ 344.894 266.082 null] +/D [3675 0 R /XYZ 91.656 206.87 null] >> endobj 3743 0 obj << -/D [3717 0 R /XYZ 71.731 251.97 null] +/D [3675 0 R /XYZ 76.712 188.937 null] >> endobj 3744 0 obj << -/D [3717 0 R /XYZ 155.277 229.519 null] +/D [3675 0 R /XYZ 81.694 175.986 null] >> endobj 3745 0 obj << -/D [3717 0 R /XYZ 71.731 219.457 null] +/D [3675 0 R /XYZ 92.483 175.986 null] >> endobj 3746 0 obj << -/D [3717 0 R /XYZ 154.779 194.949 null] +/D [3675 0 R /XYZ 71.731 174.578 null] >> endobj 3747 0 obj << -/D [3717 0 R /XYZ 71.731 183.547 null] +/D [3675 0 R /XYZ 71.731 174.578 null] >> endobj 3748 0 obj << -/D [3717 0 R /XYZ 426.159 160.379 null] +/D [3675 0 R /XYZ 91.656 163.034 null] >> endobj 3749 0 obj << -/D [3717 0 R /XYZ 71.731 148.259 null] ->> endobj -3750 0 obj << -/D [3717 0 R /XYZ 103.272 99.905 null] +/D [3675 0 R /XYZ 71.731 140.12 null] >> endobj -3716 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R >> +3674 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F44 2037 0 R /F54 2322 0 R >> /ProcSet [ /PDF /Text ] >> endobj 3753 0 obj << -/Length 2900 +/Length 2147 /Filter /FlateDecode >> stream -xڭi�������@` -X1<%ҁ�؎��XǍ�)Z��0"Gk�#sH�7��{�f����6����ݗ�_y����.�O���6^e�ou������F�μ�}��0\�n� W��U�n�ݮva�&q�����:�s˛�&�='v���,�# _v�ߊ�d������[�`��4 �ɜ�!�V �E��ݦ�j�%nE -��߭#Ϲ��{��չy��W���ԱR�Yw�Y˯�O+���W]��z�;�YԼ����u첶���`� -Q˽ �6~চy�0OyA��x�<�;J��'�҈5�5/ړ�xQ�7J��%rh�馉�P���|�?-eBSl�j,�51p�O�@,o��� ��8֜3�=r{��ߟ��E�ע�,�c `�Y�;�i�KC�NL�������c��p'w5�������V��s�(Q��n��n���K��]���� -rN5��A`��V!��I%ix��ƌ>h��>����&�08�u�b�;�䬦9��%miFڊ�˒��e۰�n�����g|�*h5si�G�t/: �<V -�<LJ���Ō��H�Ff%�ޭ}P|m!��p��5�3g��Ԓβ�k<��EkH�^[��K��R �OE�$_x{/���v+��}A��|7�xx�XC0V�~2�����ȉ:������A��������J��G���*,����8ǫG�LbNW"�ρ�o������{ �v�*E�uEF��;F�ܧ�v���oY�֥=���%G�����5�Va���$E���Ѣ��9Z�ׇ�K�CT�Q����D�]�qj �<s^E�]�I���@�?V�N��%o=�+��+�a��݆�\?p���>��a����y��� c� -�M�7�F�;�X�`m��fBId�b�M�q)��j�Jk�R���/]��%���U�����X��k�r_~�@��!�Ņ �4=����������=�iA�hd�2�?Ր*�2��e�$�*���y�QƤ��H���4���,�m���R�&�"�(2\/�n{��)q��9a�[�Ձ�<Z��=k�,��x�������n�KQ!hmh�p�2�:J��J40Z��+ڥ$!�z�wUŔ`N��C��I�4Z�����B~b��;Ũ�6u�m0��,ω]Q��.�g��ó��?�|wƱ8u�]2�X[��9�X�D����=M(ɎM�����ڥ���}��2��S@������m�Q�K}>k{�2Lح�j��H+�*5��`��\�f��4nB 5n�|���#�|����)���,qG� +�k�:H{b4X< -�*A�W���մ=��;�F`F��gv�Q�:L��4l��E��Ĝ���/�v���u���͎������i���*�t�,ꏳ�>�Q��=�l6������$���4y�K%m܀���%�T9�0�6��̤�(���Z�(}��f'�'�b_�[�*E1��'��@�Z��0�I�p����� ���*Ǯa�B�Z��[_����k0ʾ��^� E�"$��t��Aڊ�>�(����3t0ҥ�;���x������r8x��k�e&�1,cYƥ4!�����$좶���N���mE5�ࢄ�\�5��.�ٺ�=��$p�C����-xF�%�b���8��`��3��(�1�fF�j�����墴����D%�/s9���إV[wΈ��hմ�������A��BC��Ϥ@O�64k��X]sa5�^�G?3��Շ���.]�)p�]�x�L�����܉�!ϱ �g#+;.����o�ݣ;v+gp�<q�L�;$��zJ��%�"7����:ca/�,�L�20X|����,تp��{�@�+2�1P,�Wa�f[�#�� Z�fN�f����P����r=9j�+��F�����|������>Vh��&w�Y�Y�7}��Vf����ѩ^bC�ܮ[���b*]��z}f�(LD�� ����= ��_�F������E�%��o�Y����� |��?~�#l��|��T����ӷ��G0F�kk��h�&&���*�u�$�$zI�si�G��@�|�h�+S��vQ��gx�/�̄B��i������|��R'�z4s - " Z$@�t�3����rI;M�u��!Y}Sc<Ec�љ��Tc� +@����$#�nB*l��4**a+���-��s�!~�N"�GN����J����ێD�+���� -�8`r�G�ZM��W ���G�˨�$O��$�H���/�5'����EF�CC���H�N����K6����LĨ��(cL6���'����!�2�^rf�OZ�-j��ҌT���륨,��t -c%� -u�����f��L�J�kc�u.FzC�x����%����R�^�݆�M^?�4[��I�V�̺��j�ˮ����J���D[J�9��tחx�������-���t9!����?��ʢ�� - ��������{t�uFa+H�l|L��coe࠻��t���P��y���f,s��.~�F�Ґ��Y�6*��5����_�D3«h���P��a���x����3���Z�q�h�r��ca�.��v\C�6/���}^�ڤ1�k�j�xio1���N�z�RV��z�8�n ~&�S��Ш�N�Z�a�ih~n�rO:V��+����:ɱ�0��4N��x�O����\�A��H�h����>���:v��۷����{���*�4���3���KK�_�&�S�K�q8!�qY7 �xt��<�8hD���qL�v%�X+��)6�T���r��$�oW��M Q}�[�#�?n����Du�K�2�?v�C�endstream +xڅXm�� �~�b�~� �h-�=AQ�.IsA���")[3v�o��n~}I�����m����h�"R��M�r�J��0�\�$���`s�����,�e����ݻ���p��< 7��&R��e�IC%�Xmv��އJ�VŁ ������4�d�y������ݭ:�0y�i�"sc�J�v-�2F�3����j[�݃�ͥ�&c����o>WfI��D��Ae����#˸C����HO��/3��8U��b��Ă�8���?�v���-Aލ�;��Ȁ��ИāD��I�R��=zaF�5ug��<��<�E�>���w@e����^O�5�} r�ۡy!z�;T q�7�/A���H��@���d�g3��!�Kg'@��,k�k�uɜ}���{�F�.�Y�6@g�o�*��kW_� �p�@��ս��4�yd��4�)0�_�L��H�l�$�Hsud���Bȁ�ʐW�=�lD����k� +R%�ћ��7իr/H���0pC�u7Y �߳3jbW �� U\;�V���P4{��L�M�� =�����4�'�q=�UF�xW�(��1&�|͜�� +��o�5�ݑ>L���{���,)�Dqn���Vcomc�(��,W>�O�3��t���o����d��ߟ���ޚ;�T��Ű]U�_C��z�@������ �8�`L��C�S��F�.�FNQ���])D@�e��Bs��5��r�>Z[��`�����OS�j�b٘{%�Ţn���ҖϾ�R$1e�� ~��Sm+�z�u���+'������� +�%� +\�笲�f�B��^�囪�q��Еl�l�m��J `# +D�����(�$�pLُ�C�0��4̾t�X �����'�?;3�A_���<�ކ?C�qU��&�U�i����ɐH�;t1�ukX��x��tq��T�EE˅��"��=�T�n#���/8���Y6ĵ�P���i�!g� ����x��s��B��@Z%1:�կ�k�B��&��@i�W\���Mc�z#<:+}P{��:��v �0 EeWڴ����w9�����Ѝ�sSE��$��2�q&J�0�PTӫ���f�MW`������!5�=��EG�u��/D�6ZvD�R��h_�K���-�D�q���~�Z$�R���7b�in�8Y��]g���cG����@/f]��ǟp���,Г �})�N�5wTd����uIrR-$6��M�2�����tB���3�u=����%=����?��ah�fM#4=|���|�C��Z&�� �����,,heGl m] �B�s$:Hc�r���s�TMw����5���"�,��&�Я+�|�v|2l�]*�.�1 $Σ� _�˷@�Ñ���t�V]yB��]c���>V�x�t2_���5Io��$�$���_h]�4"gZZ�_8muSu?���:m�}x1փ��8�V`���֖�|b$��%D�9�b�3.���5ȀnNzJ���##��a�[�p�bԶ����V��tY�����l��i<?��%����S5�>��<gP�D(㫴�*�ũW� �0�O '�n�Z��'Z8{��bPlÛMƒ��3r� +-��ȇ:�c�AT�sX���4~�i�÷��|��|����Ǘ;7��t(0���5E�dq�az\��T��y��Z}���+�6�l�K�`�0]I�E��r���R +Zsu��|�M�;6cO`kꕽ��d�[~N����+��i��<�$���Ȓ�"Y/���������cg�9�E���b� +ߌ��tR�Y�Gl�)[�7�Q�n�QZ �7�}S�U�I�@J������RH�y�s#���y/M���0h˴�r>�q�E�G��5��#�z>�kIJ���BT>����v_g���g�Mx�4�s����~\�����0#�YDN� �榤]�h����@����4�����W�-6��ꡔ��f�\������- �Z7=���?�#s�)R��< d��� fU����m��Cz���=?/J1>�F��;C5̮�ˉ�������?;?�V~�(�1Cե_���a#��S���Kʹ���;궜5��u�?�E�Ƞ�}��̳�M�+p�\w���ɗ~��U�?9��endstream endobj 3752 0 obj << /Type /Page /Contents 3753 0 R /Resources 3751 0 R /MediaBox [0 0 609.714 789.041] -/Parent 3610 0 R +/Parent 3642 0 R +/Annots [ 3760 0 R 3764 0 R ] +>> endobj +3760 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [179.678 666.905 232.014 675.387] +/Subtype /Link +/A << /S /GoTo /D (http) >> +>> endobj +3764 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [349.173 505.121 368.62 514.032] +/Subtype /Link +/A << /S /GoTo /D (gloss-dos) >> >> endobj 3754 0 obj << /D [3752 0 R /XYZ 71.731 729.265 null] >> endobj 3755 0 obj << -/D [3752 0 R /XYZ 425.163 695.392 null] +/D [3752 0 R /XYZ 152.136 708.344 null] >> endobj 3756 0 obj << -/D [3752 0 R /XYZ 71.731 683.273 null] ->> endobj -1613 0 obj << -/D [3752 0 R /XYZ 71.731 653.684 null] ->> endobj -650 0 obj << -/D [3752 0 R /XYZ 201.526 620.374 null] +/D [3752 0 R /XYZ 457.305 708.344 null] >> endobj 3757 0 obj << -/D [3752 0 R /XYZ 71.731 611.921 null] +/D [3752 0 R /XYZ 322.488 695.392 null] >> endobj 3758 0 obj << -/D [3752 0 R /XYZ 463.469 588.493 null] +/D [3752 0 R /XYZ 71.731 693.235 null] >> endobj 3759 0 obj << -/D [3752 0 R /XYZ 71.731 574.381 null] +/D [3752 0 R /XYZ 71.731 678.291 null] >> endobj -3760 0 obj << -/D [3752 0 R /XYZ 514.935 538.979 null] +1636 0 obj << +/D [3752 0 R /XYZ 71.731 640.897 null] +>> endobj +638 0 obj << +/D [3752 0 R /XYZ 369.383 601.524 null] >> endobj 3761 0 obj << -/D [3752 0 R /XYZ 71.731 526.859 null] +/D [3752 0 R /XYZ 71.731 598.332 null] >> endobj 3762 0 obj << -/D [3752 0 R /XYZ 71.731 510.437 null] ->> endobj -1614 0 obj << -/D [3752 0 R /XYZ 71.731 470.67 null] ->> endobj -654 0 obj << -/D [3752 0 R /XYZ 197.015 433.455 null] +/D [3752 0 R /XYZ 71.731 581.197 null] >> endobj 3763 0 obj << -/D [3752 0 R /XYZ 71.731 425.536 null] ->> endobj -3764 0 obj << -/D [3752 0 R /XYZ 103.934 400.379 null] +/D [3752 0 R /XYZ 71.731 533.181 null] >> endobj 3765 0 obj << -/D [3752 0 R /XYZ 105.351 387.427 null] +/D [3752 0 R /XYZ 348.289 494.326 null] >> endobj 3766 0 obj << -/D [3752 0 R /XYZ 71.731 380.289 null] +/D [3752 0 R /XYZ 301.416 481.375 null] >> endobj 3767 0 obj << -/D [3752 0 R /XYZ 518.615 369.494 null] +/D [3752 0 R /XYZ 370.113 468.423 null] >> endobj -1615 0 obj << -/D [3752 0 R /XYZ 71.731 349.405 null] +3768 0 obj << +/D [3752 0 R /XYZ 478.765 468.423 null] >> endobj -658 0 obj << -/D [3752 0 R /XYZ 176.973 312.189 null] +1637 0 obj << +/D [3752 0 R /XYZ 71.731 438.371 null] >> endobj -3768 0 obj << -/D [3752 0 R /XYZ 71.731 301.824 null] +642 0 obj << +/D [3752 0 R /XYZ 171.235 395.274 null] +>> endobj +1638 0 obj << +/D [3752 0 R /XYZ 71.731 391.443 null] +>> endobj +646 0 obj << +/D [3752 0 R /XYZ 413.668 355.901 null] >> endobj 3769 0 obj << -/D [3752 0 R /XYZ 71.731 284.927 null] +/D [3752 0 R /XYZ 71.731 345.536 null] >> endobj 3770 0 obj << -/D [3752 0 R /XYZ 71.731 243.248 null] +/D [3752 0 R /XYZ 401.183 335.777 null] >> endobj 3771 0 obj << -/D [3752 0 R /XYZ 71.731 243.248 null] +/D [3752 0 R /XYZ 457.301 322.825 null] >> endobj 3772 0 obj << -/D [3752 0 R /XYZ 71.731 127.035 null] +/D [3752 0 R /XYZ 239.311 296.923 null] +>> endobj +3773 0 obj << +/D [3752 0 R /XYZ 71.731 289.784 null] +>> endobj +3774 0 obj << +/D [3752 0 R /XYZ 319.244 253.087 null] >> endobj 3751 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F35 1525 0 R >> +/Font << /F33 1306 0 R /F27 1208 0 R /F35 1567 0 R /F23 1201 0 R /F44 2037 0 R /F60 2527 0 R /F32 1215 0 R >> /ProcSet [ /PDF /Text ] >> endobj -3775 0 obj << -/Length 2755 +3778 0 obj << +/Length 2448 /Filter /FlateDecode >> stream -xڍk�۸�{~��U�ZI�d;��HrI��%W\��M?�m)+K�����2�X_���g�C���,��p����O���4�e��l+^��q'(wΛ����u�f�Y����t�T��J��C��m���t�( ����?��������*=���O/�=L���+uS&�s!T�< -e��|�$�ӗ��A�4�����Z,f]�19O������;�3��mۦ��y�xO|&u{=-� ����G�ضM7��%�߽���0l�y�}�`?�L�2B�'=�� �4l������#-�5H���÷������������G�z��lj����ސ�0��Q6����_�~�ɑK�o�����M�Y��S� -,�I�H��O��r�Αt��yY���e>��<��y��p��O�xR�=(�Y;��8G�F q��<ă�(z�e���[�Ex2�{#�<� -���#`����-��[���ģf+�r����Eot��_��}H����(R|�zVX&���9��u�L��>��t�1Ó1����4C����^@*!gP�@-{��B�ږ"e2��ΰr�Q�&Ca�N�D�鞥&��<AŐ<E�1�. L7+�%�k��W��&��T������#�?|��������`n�qo:=�U�����{c���ז���dA���Jx��ڒ���.��:���� -mb��KY� (�FA�aE"�����F9�x���$�W�7tD�Kok�0v�~ �A�<>���A�ojKO��x^�I�¤� |�T.,7�>C�ކ?x�[Ӂq� ���7�/ -W~�g�r���j�8w�E�;'�"ac��8.��(����6�3Bȝ��p��i�B��u�����y��%h�f�c�ӧ}"�C�E']<��G�����#/�I��gwCw��݇ǻ_�Ӂi�k!h^nq+]�p��L���f�~0:?�7���;:Wu���R�,�����U5�����_Ġx�}������69g�]�#���"����� י���\cr���;�Gh�oF ��8��གྷйp�-��A��kDߧ��%iq�� b}Й -4`�~B��XC0;��p7� -*> d����*�z*Wfpr�#!��܈�K-�nJa�sN�P�A�̕�C/��SM�q0�)�����"N$�PbL���58Г@:66(~�'e{S[>� �� -TjV��a�6}_R88��'ߧ�2��_>���ᾆ,&r1SM��[��9���<�ف�Ի9�KY;��ҏ�D2�2��Jr�T2��e5e��b���j��������WӒ3�&"�?��Q?M��ωc��k����b�9S���@��� -[M�75��P�^�Q� �8� -��s���c$p:�D�E���Ke�ׁp��U�����o�<F(�*2P�?S�о�����{�*_�G5��I�����'�&�]�G�ݦ�uVܷ`2~�+�Z�?ҝ��/�}������M�E��^Fl ��2�1G;�}j�1H��=e�'P�g$���,1�a�A�_�.{��B:<,?���^��&34�C� ��a��b�7��d!�N��p�A��������O(ɀE������(��ޖ������6��K=�D�$c��M>�$_�����r���%'�2^09z���sw �+��̞����Wc ����p&*E���r�\�9N���y�v���T�u^��O�u;��N2TS�qM�NgوՈ���@{�p���QT<'�?�lǢ��Z�O'cP�?s>%9���q��|:�ă��(�~S4�g�1�����e��:�8���b�;粣tJ����j��i|���w�-[n�>#K����6��7�#�?>s�F -X�(��e�uTVRk�i�uM��6 ��b%%d���Q�#g��E�Y���m�w��f��s�P/���2��T9�J�P���;RyE�'�������Å!M�F~=��kv�X� -N�7�G �<~J�?�J^2^��W� -��.c�@}*� K��D�X���� chY2� 9�-�#�E3���=�r������G�ŅD���S -�F���@DW�2� -Y����<��]�i���y�����_Ayw��dDd�� *O-�+���Xu�����ݢ�1���� -�?��[��Ȟw/�Cv�i"k{!N*�CU��g�S��5H��Ɏ����v�O��ZOcH.o{Y�Y� -�\=��K^����Ȟi=]9E0����r#�1u��S�����n�;P"�=�D~QX{����l"��dF��b�� 7�9R`����;�#�2t;��e�=*�����3�+��ۓF�E?�;��j�����K�?=L�b��`jl�H<��(Wx�#0�4%M�+�]�*=vOD�_N�D0RT��{9*�Z��۩��*kT�t3D�C���!,I&� -��KF�2��G$�`7ֵ��3��Hj�{��*�����]+�զ�����+��`5����N�RX�ֹ��,�F9�e�@��6�vN~%��o��Ş�j��ʫ�짖WB�|B���ؽá�c�C�E�\Xi��`�3�乼��3� ������8N�2�SLHS;yS��c%�*�My�@-�=<s�\��|�e�k��#g����zx�_F㕿 -�7�=�\��D+?�,jP���-������-endstream +xڍ�n��}��oWlE�6k���L�����F�m6��J��M��g�$�K��yx6�g��E��"�,���}�&���!X�`�OB����W����ue~��� �OO���� +�4�O�AJ�*JO�?��{}�M�\�l�%>t�����i�_[Uz�����0�U� ���*?�2b���P��v��)OEo�ZH�E��i$�*�T +(���[��0�:�4)��_������z۴=b���.קδ��l��}?�Mk��`j�0"�Л�wB�^���`nJ?��ʟA�� +7�{��'!��g���?~|x�t-x�3�S6n�����Dq��m����{kN<Ш>^MU4�� ��~�e�)��[�h�_�I�u�r:�0�'n�*����e�x`q�x�nz�[�A��{�a���z}v��b<GPAm"�� ���"kզ0]�[[�1`��X+�h�;J������anj������A ��܂d�.�Ş���/�kO5/; +���)uH4�+W����$�/���=�U��^�tq��/���/����\FeS���LW���t� ' oO|%N����2<�3W�ٯEќ@�;��}-��HcP�tר��8 +���'d�pt���g<j��]�X�j!�ğa����n�T 3v�a�ʃ�m���k`/G��`+��ry��D�y<@H��L����>�����nߜ0�<�3"���;����D�����9�Za�!k]��|���T��\�� +|�x�a�ϸ��=>�~��Ӑ�����`�#��j��������flP��B�&��4�&k�d�]�3�(��T.X���gG�Q�;N�,6�#%�?�7 �m]���bg/,��q��V̻�l�2��S���]�f��OMq���'N 3������ˊ��`$�#��u����#�v�)H��G0��PzfS� ���]T��i��1�~� ;��_1�:m`�ϡ�{���%l�%xw�Ĉ@w�SٸտA![�z�7����:\fץ��ϡ�+h����x�Sr�]���-ט5�i�i��tf�������I;8IHB+G�0Fם���R�1R��ݥO�`�y�å�%�o;�D���T[�x��:����i�n� ) P�1+�9ų�)��1Q!�q̧oy ��.`�p8Ő�Bg��y��6ud�%ù|��վ�B��Ʊ�x]2��sܦS{�#��!�r� �����_X�����;V����� +*�� �[�|��v�t��̔kZ��� jBy�Hj� �J����P)B�7��R4z�������43f�4C�e+�g[��顋�"f�xS�M/̎q&"��H��u�&qA$�0�lLW��;�=�$�O��S9�Y%#�ʢ��<=)��3�43g@�x��bdgd� A�^,��|�˚8�f(5���R�ĔV�$�f}��o���9~ �`�s�p(x�V pEֻ%�=�3�(���g�z8�<� V�r`�MG�V�_IS9&�֎kQ�� ��j �Ջ��P;�kN"]�!YA.6I8�X[r��l 6z���HURk�}9�d[0��kM�PDMm��*Ŵ`oe}`� ���-�m�k- 2A�t��%�@�-\��'L�k^(�գZ����p�em���s��J�ȋ���_�`u�3QSYn�[P)A �a� �>��c��Jx�c�����4 Dsn:>��GDp_����rl'�>��_�p�*ͼm��ׁ'��O�F�)R:���a����8 �$�/l������'�P*�1��������J�;6Sd(�%d��X��s喵#����9�ٳ��Tt�;����<�y���;��F��!OPP��fȻ��~Ȼ#{�eBK��4[2,�W��/6����0��HL� +��Kˣk��R��'�I�#{0���ʭ�������5Ů��l)n�XH�=�ۥ�\�މDo��S��+e!�@�ͦ�y��er$�BX���{�Io���2Z?�<盉�� �Ƒb<����`?����_4g���svM���z��~�?��e�U�o�Y��=�3��q��ܽ��F�F�_�ъ����@^;����)+-X�Kq�F�#��Պ�cLdEs�2�� �C6M��t�먻N���E$<��!�/�ο�VG�uSZ�A�J��.zN%0����i6*��~����4A��[fs)�}��#{Ɩ���Bɫu:�QPQ�G��%�d�O�8>Y<6;�~��˅r�2Ȧ�ьO,P���О�<L� fX�Q댯{vږ�� ? ��8�������!�a���mп�,�M7�-M2�3��j�+�j&�֣�0�zR_{�4d�� �Mx��a���B�E�)%`Ci2p!3���/~���r`P�endstream endobj -3774 0 obj << +3777 0 obj << /Type /Page -/Contents 3775 0 R -/Resources 3773 0 R +/Contents 3778 0 R +/Resources 3776 0 R /MediaBox [0 0 609.714 789.041] -/Parent 3802 0 R -/Annots [ 3780 0 R ] ->> endobj -3780 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [218.529 576.952 268.342 585.863] -/Subtype /Link -/A << /S /GoTo /D (userpreferences) >> +/Parent 3642 0 R >> endobj -3776 0 obj << -/D [3774 0 R /XYZ 71.731 729.265 null] +3779 0 obj << +/D [3777 0 R /XYZ 71.731 729.265 null] >> endobj -1714 0 obj << -/D [3774 0 R /XYZ 71.731 688.254 null] +1639 0 obj << +/D [3777 0 R /XYZ 71.731 718.306 null] >> endobj -662 0 obj << -/D [3774 0 R /XYZ 368.077 651.039 null] +650 0 obj << +/D [3777 0 R /XYZ 320.829 703.236 null] >> endobj -3777 0 obj << -/D [3774 0 R /XYZ 71.731 640.674 null] +1640 0 obj << +/D [3777 0 R /XYZ 71.731 692.184 null] >> endobj -3778 0 obj << -/D [3774 0 R /XYZ 415.981 630.914 null] +654 0 obj << +/D [3777 0 R /XYZ 205.304 651.159 null] >> endobj -3779 0 obj << -/D [3774 0 R /XYZ 441.016 592.06 null] +3780 0 obj << +/D [3777 0 R /XYZ 71.731 642.336 null] >> endobj 3781 0 obj << -/D [3774 0 R /XYZ 71.731 571.97 null] +/D [3777 0 R /XYZ 506.431 629.6 null] +>> endobj +1641 0 obj << +/D [3777 0 R /XYZ 71.731 583.608 null] +>> endobj +658 0 obj << +/D [3777 0 R /XYZ 317.599 540.51 null] >> endobj 3782 0 obj << -/D [3774 0 R /XYZ 513.076 548.224 null] +/D [3777 0 R /XYZ 71.731 528.072 null] >> endobj 3783 0 obj << -/D [3774 0 R /XYZ 250.723 535.273 null] +/D [3777 0 R /XYZ 71.731 493.048 null] >> endobj 3784 0 obj << -/D [3774 0 R /XYZ 340.577 535.273 null] ->> endobj -1715 0 obj << -/D [3774 0 R /XYZ 71.731 492.269 null] ->> endobj -666 0 obj << -/D [3774 0 R /XYZ 198.969 449.172 null] ->> endobj -1716 0 obj << -/D [3774 0 R /XYZ 71.731 445.341 null] ->> endobj -670 0 obj << -/D [3774 0 R /XYZ 256.752 409.799 null] +/D [3777 0 R /XYZ 71.731 490.891 null] >> endobj 3785 0 obj << -/D [3774 0 R /XYZ 71.731 399.434 null] +/D [3777 0 R /XYZ 71.731 485.91 null] >> endobj 3786 0 obj << -/D [3774 0 R /XYZ 434.226 389.675 null] +/D [3777 0 R /XYZ 89.664 465.153 null] >> endobj 3787 0 obj << -/D [3774 0 R /XYZ 71.731 330.731 null] +/D [3777 0 R /XYZ 165.462 465.153 null] >> endobj 3788 0 obj << -/D [3774 0 R /XYZ 71.731 317.779 null] +/D [3777 0 R /XYZ 255.79 465.153 null] >> endobj 3789 0 obj << -/D [3774 0 R /XYZ 71.731 312.798 null] +/D [3777 0 R /XYZ 431.207 465.153 null] >> endobj 3790 0 obj << -/D [3774 0 R /XYZ 89.664 292.041 null] +/D [3777 0 R /XYZ 378.817 452.201 null] >> endobj 3791 0 obj << -/D [3774 0 R /XYZ 128.262 292.041 null] +/D [3777 0 R /XYZ 71.731 450.045 null] >> endobj 3792 0 obj << -/D [3774 0 R /XYZ 328.528 292.041 null] +/D [3777 0 R /XYZ 71.731 435.101 null] >> endobj 3793 0 obj << -/D [3774 0 R /XYZ 71.731 276.933 null] +/D [3777 0 R /XYZ 76.712 385.651 null] >> endobj 3794 0 obj << -/D [3774 0 R /XYZ 71.731 261.989 null] +/D [3777 0 R /XYZ 71.731 365.726 null] >> endobj 3795 0 obj << -/D [3774 0 R /XYZ 109.589 240.833 null] +/D [3777 0 R /XYZ 76.712 289.91 null] >> endobj 3796 0 obj << -/D [3774 0 R /XYZ 76.712 199.986 null] +/D [3777 0 R /XYZ 89.664 271.977 null] >> endobj 3797 0 obj << -/D [3774 0 R /XYZ 89.664 182.053 null] +/D [3777 0 R /XYZ 71.731 218.015 null] >> endobj 3798 0 obj << -/D [3774 0 R /XYZ 71.731 179.896 null] +/D [3777 0 R /XYZ 89.664 202.239 null] >> endobj 3799 0 obj << -/D [3774 0 R /XYZ 89.664 164.121 null] +/D [3777 0 R /XYZ 71.731 174.179 null] >> endobj 3800 0 obj << -/D [3774 0 R /XYZ 259.764 151.169 null] +/D [3777 0 R /XYZ 89.664 158.403 null] >> endobj 3801 0 obj << -/D [3774 0 R /XYZ 71.731 110.158 null] +/D [3777 0 R /XYZ 71.731 143.295 null] >> endobj -3773 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F44 1994 0 R >> +3802 0 obj << +/D [3777 0 R /XYZ 89.664 127.519 null] +>> endobj +3803 0 obj << +/D [3777 0 R /XYZ 241.22 127.519 null] +>> endobj +3804 0 obj << +/D [3777 0 R /XYZ 417.182 114.568 null] +>> endobj +3776 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F44 2037 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -3805 0 obj << -/Length 2882 +3807 0 obj << +/Length 3303 /Filter /FlateDecode >> stream -xڅێۺ�=_a��FF��u�\��6)rpZ'ES\�����G���~}�FI��~9$g�ù;Z��-6Q�I�o�8�e�n�8�ʟ�E��N����|zx��K�,��6O�E�$a��M�E/v��+ut�_���:�B�~��=���p���k������>?��dn��M�Ҭ�"^���pG��ކ�5~�E����w����=~�����0�����u�iˑ7i_�E��XF�:��]�A�-�,x�ITj���,�,м�:^9�6_Q�`��wy�Ãc�N�r�9���pfh՟�T�g���́�'���]��q�����}w�U��2�앭H�Ӻ�PɃ��8܊9�h@���D9a���s�����u=��[��vǃ]�m�~@�������'A��Q����>C=,�,�m�hǷ�i��ZFZ���5�=c 3����M�l�� ���#�>��Q=�H�X������Ov�@Q!��S��G���=��4�tm��JN�o��xf�> -{��\�f�f�i�L����u�| �̽����˛Z@��)ɣ� ND��t��F=ĥ�r�֦1N@�������F��ƴ����r� ��`>����{�*� H���� ���F=-���t+�2�^F$FX������5�w�u�b��d0�f�ڸ��D�.{��ge�Z�#G�D�>i0LL�ˊ�=�е��B�x����y//�(���xT�Cij, �>4Y�Cs��x�8�0����q��s����v�Q -tq��2���o��[��yAҏI��C/#����>&�<q�e�GF,�&j{CXQ��xć��Џ�:��I�5�n]�{��NF�w2�2\yf���-��N�}Ea��t��S��wS�w� a�v�k�H�,��P,��0����J6�v��!W�ġr�ldU��r�;C�e��5�H5��U����y�eo��i�kQ^v��ׂ�5���� |���SbzoX&qAF�C�����0r/���51@�M`�?�qA����y�����;�m$IO�������ԁ�������,�4�:1����}ε�?�S.n{/��~h[����A���'�(�]!������=g���*��n4��"=�L70��O�>���Ny��V�����QX�X3�-���>N,�]�8p���/3&��t$ -���V�0ch�@�m쵀�pH�j0~�J�"'Ad�����w��8 h���`w#bϢ8q�|��iS��L��P��m�Q -s# -��d$�(a9֦4���pe���E��p����{�� -?��1�ӛqm4�m�E����#��`ˡ[]\�VV�Hz5C�O�5�*em�S�C�0N�I��< -�ۍw�o\��G��#^��CF�w�{^����D�G3i�;s�td�'Q�xډ�YH�j�'�G��RI=q���_x�v�k����������z��w1)k��(,:<���U�EV7�Tl^��.�s -��P�j���$R��e��^�G�s_;߆�9�� �-eyb �!�w_��{6B��7 -�?}������u���3�� n��Q �y$���`�ي�"i�Y��y4 -�f�1�e�W)���tG���}&ۉaa��h���s�����)���<W�bO��o���{2�~���O#5T�)W�R(�)�K�0�IA 39���V�|���_�l�8�O F8�.����b�,�9�ˁ$��l|if��`)�����-T$���{��m�Iu�P-�!Dv�f� �����bw=�(�ߐpK!�4Q���l5��< )`nVͦ��gL"�ɝ��ŧq�} �}����nth�8�L &?�u#|~}�s$� -�=�x��i/��}N��*u�Z>@U@De~D�m�����O �v�l( �������M3�'�8�Xl�r��qz�Մ -2�`(zM$"�^��gA��O��9�k/�x���:��S�<4e��k��}���s+��t��!=����L�vƞ�]1��#�"QՃ��(dK�ꆐ���f� y4�0+ɞpPQ�5���WhBZ�K2�&m˴��]k ��3����1w�����6�>:�J�z�%����"(����DO�i�P!Fƶ�^Q(�UW�`$U1���!\"���Riى�š}�<�FT|�v��+S�4H�X�= #�Ѥ���<Ձ}��b�a�s�m��i��O�uw`�,�<{����m�̳@NS`���LXx�;%C�ӓ�B���� -�?�Q�^��#͖4�N�R}+^�t ��w��Qw�Z_-�y��Dƭn� yX� -3���<��"����#����id ��nQy�α�%�z��M����w� ��J -��Y�zN�ǜL$��H|���r�W$�;9Y�Rcܺ��6/\�M���6��طv��E{$�]��Z�s�(Ԝ�����^�Vd&�%�����l�Ãt̽��P����h�s��<��=�y��p���ڙ��8H���`t�o\f�9��:bAI�����/�����`�~��Jߛ�`���dj�O�L����y��>�3�z�h�A����%�.��K>6ɦ���nN�N���55�L{ퟣxFQ.�Q_ -��(�J�<����J!D�n8�I�}��b�1*ˊh���Q�9����GRk�c�����G퉖�ǐ�=�^��c ������DKd�����I�7��@��*�@R���s��e��8L1��d�B�П\��b�а4�b꼨�!Ųr�����Lz:ց�ǾP!�=�C�%��x����d�����i��Ϳ��-W�gq�c����_����������endstream +xڝk�۶�ō���x|J�;���M\�v�ėv:M��#qk>d����뻋]� E�2},��}/��ʃ����}A���*�_xWy��g�-�l-�o�^�|�W���«���(�p��ڇ�����]�/��1;���l��sb���es��o���ʪ�6�������8ܻi>K��9#*؏D�y�F������v@ +"'�~�N�n��y�ު=DA�e��!VuRH����sI���[��D-�{�z�<��m|�1N�P�l�y��R�f�M�9_7~LkLpGNQ���K�rx��7e��R,�w�?+��1yN~̚����b��#�@u;T5����9=o�ý�m�6�{�*����HpT�-��1�W�� ����=7c��� Q&�Ĺm���7!,C��g�2��,���ߍwj��#���5��8�JI�=MH�+a�����2?�TeO<�矲�/��:j�#K�w�7��dʡm�\e9S�X���(�B�lk�w�;�����H멗��W��' k����s�����ij�Ϛ�g�����b�����77�ry3 +��87v�/O7�HF��q����CY�އE}B���ac@m7�O�pi�m/h�?f=��p����E%�^��}������=}�F��S�:�g��#h��ItU�|�����*��J��(D�5�?��'����V-eJ +��ڦ�-�[)Y�%�Fے�+�}�,O����d�� +�Zߗz'���:"�������̸�٤O�DÝ-��6,Fz�'m��@�}�2�2%�ѻsO�Oݽ?I�,�Z0�~~�n�?Õ��n-���<���f�"��&���r��:`)��Om��<sKiB +/����o�WP�裗W�/4����?����Y���~,�#����s'%�6�䏎�kt����r[�.9�e�Y���9m�u���Vp��������,�V���6�P�tdCz$�E1�Li�qVQ�H�k��-�؍�)xw����uٔ��p����Ż�y��x���ML(�έ�='k�����<٩��}+A�U��#7 SMZ�pO��Dhv��[!�oP܁~��J����;Z���%��R���<e �*���X�-�l��M� !.����Le�DS.l�� ���P�t4��J�Ʀ2#��Z*�y� ��a����j$6�l�*d>����3P��Ƶ��i(��W&��B,ja������%���{�=�6������(s���AD�!�i!Z��c�De��,�X 3� ��<�U���M&<.�*5��ͭ��7�� +�{I�0�K~פȺ���r[�V�Ԙ��L@��)�7��8���+����$r#_���� �NMg +:��G9��_f.�g�����6��at�G���ev���z�ltl����h2B3������F�'ʓ��l��'�Xb}U)M�����#����#F�I���\�+JPj� �|Q�ĥe�{��c����}#�f�������pY�A}G���Rӎ�qwT��h k9�ԁ'�L��049�qV���� +���3ԋ��2��t��=�#���z3���������C�\�j��������.��s�i���Ē�Mo�Y��ӗm5`T_v�i䆩��� +�ɁJ=]�fy_=��#�2�~�g(� +��.���Q�0���?�FP��]V.ǰ��X�)�j�5��Vi�q^sNK۲���ص��6�2<1�W���7t�/N���Q'����~��à������eM� t��Ŋ��� :�Ϡr\Y�W|�_"��,�MQ>���N���,�1Em�g6:�*ǥ���7�E���ي�}&]<�"V>EU����� +��su!j�j�1l4�YcaV��A�?᪱��l�3�K�j�I�λM8�R����,��0���=�٨6B3���_�4w�B��:�]bij�aVY� Hz���s\�Y=ý�j��nu]�v���ʼn���oc�4x4 N!���O�R����]/}�0łY�>�Љ���q]����-ܯ~����ꃯ~|oX��ef���m�xo���<t�M�f;k�����J����5�`���\9<ǽ�a������i��Q�F����(�A��h�������]@ij_��3���g���NAZ���<�u��3�K�p�2����#��6Sg�r��� �����f�lv1����bKqP%>Y����:��Sa��]o�|żz�3]P��=�U�'���� 5Ī�r#Y��eN�. �`}��M�)^*=�$��23��=����}<6'{�����}d������kL!G#|���tq�sy��$�PW {�i80j��+�� +��+5�xJ�s��)\��/�_彼+;��ZG���"7��$�{����R_�P����L�:"��.��t+���=�]#̪~1n-]հs\�ul�{I�,���Ӭg��ۧ�ZP�0�Y�E���<��OCo������ڦ6W9�Gщ崎T��mڡ)����*�#7JV�^Al-�s�LQW7ުX�Q]���X,��@"��?�{�\�;7����G��R��Y/���娡�X�$$|�V ��|)i.#p�����������@C;�h�>�{���4~u��敚QR�z�V�#�Mڎ`�m��;�f�/3@�k���&U������9E����}�xη��~���� �����B���u���*;ǽ��6�] ��_J�½���$��b���$��Zt��Z� �B�BZJ�h�[~��W?�u9���S�N|яOa��&���#�+�P�e�o^PA�`�4��nk�I��J�����E��{�G�*���(�e��o�eE��^R�'g��5eI]/� +�k�'��U3u����M�O��)@�U��j[��;踯ڜ��:0 ~��NbU�J8/b�A�pzI�0�R8;�dzh��b�Vڛ}��p�V���~(�Q��=K%[sd=/�-c�����h��ь�o-��:�1~w�� 䪃|���<B�i-(�]=�:�sYg���Tv��JlQ�tPJү�4Y��B?p�6���%�A��e���Ě`�4�0�=��f��L��CVv����W);t*�ĉd�4�)8�y��'��� 7�,��鋦Zo5g�sͷ�~�ۺ�Y�������5�n��g�җOW"�����yn聤�3��P&�̀�#%����:��3=�7��ϾNA�+0��:�J���c�?�}endstream endobj -3804 0 obj << +3806 0 obj << /Type /Page -/Contents 3805 0 R -/Resources 3803 0 R +/Contents 3807 0 R +/Resources 3805 0 R /MediaBox [0 0 609.714 789.041] -/Parent 3802 0 R ->> endobj -3806 0 obj << -/D [3804 0 R /XYZ 71.731 729.265 null] ->> endobj -3807 0 obj << -/D [3804 0 R /XYZ 89.664 708.344 null] +/Parent 3642 0 R >> endobj 3808 0 obj << -/D [3804 0 R /XYZ 407.268 708.344 null] +/D [3806 0 R /XYZ 71.731 729.265 null] >> endobj 3809 0 obj << -/D [3804 0 R /XYZ 71.731 641.43 null] +/D [3806 0 R /XYZ 71.731 718.306 null] +>> endobj +1642 0 obj << +/D [3806 0 R /XYZ 71.731 688.254 null] +>> endobj +662 0 obj << +/D [3806 0 R /XYZ 252.009 645.157 null] >> endobj 3810 0 obj << -/D [3804 0 R /XYZ 71.731 626.486 null] +/D [3806 0 R /XYZ 71.731 632.719 null] >> endobj 3811 0 obj << -/D [3804 0 R /XYZ 76.712 564.483 null] +/D [3806 0 R /XYZ 71.731 610.646 null] >> endobj 3812 0 obj << -/D [3804 0 R /XYZ 89.664 546.55 null] +/D [3806 0 R /XYZ 71.731 582.586 null] >> endobj 3813 0 obj << -/D [3804 0 R /XYZ 220.282 494.745 null] +/D [3806 0 R /XYZ 71.731 577.605 null] >> endobj 3814 0 obj << -/D [3804 0 R /XYZ 71.731 487.607 null] +/D [3806 0 R /XYZ 89.664 556.848 null] >> endobj 3815 0 obj << -/D [3804 0 R /XYZ 71.731 458.78 null] ->> endobj -1717 0 obj << -/D [3804 0 R /XYZ 71.731 425.838 null] ->> endobj -674 0 obj << -/D [3804 0 R /XYZ 263.867 388.623 null] +/D [3806 0 R /XYZ 89.664 556.848 null] >> endobj 3816 0 obj << -/D [3804 0 R /XYZ 71.731 378.258 null] +/D [3806 0 R /XYZ 89.664 525.964 null] >> endobj 3817 0 obj << -/D [3804 0 R /XYZ 300.705 342.595 null] +/D [3806 0 R /XYZ 71.731 525.964 null] >> endobj 3818 0 obj << -/D [3804 0 R /XYZ 96.735 329.644 null] ->> endobj -1718 0 obj << -/D [3804 0 R /XYZ 71.731 301.649 null] ->> endobj -678 0 obj << -/D [3804 0 R /XYZ 209.315 256.494 null] +/D [3806 0 R /XYZ 71.731 414.732 null] >> endobj 3819 0 obj << -/D [3804 0 R /XYZ 71.731 247.671 null] +/D [3806 0 R /XYZ 89.664 396.799 null] >> endobj 3820 0 obj << -/D [3804 0 R /XYZ 71.731 203.951 null] +/D [3806 0 R /XYZ 89.664 396.799 null] >> endobj 3821 0 obj << -/D [3804 0 R /XYZ 71.731 171.01 null] +/D [3806 0 R /XYZ 71.731 368.739 null] >> endobj 3822 0 obj << -/D [3804 0 R /XYZ 71.731 134.312 null] +/D [3806 0 R /XYZ 89.664 352.964 null] >> endobj 3823 0 obj << -/D [3804 0 R /XYZ 71.731 127.923 null] +/D [3806 0 R /XYZ 89.664 352.964 null] >> endobj 3824 0 obj << -/D [3804 0 R /XYZ 213.007 103.428 null] +/D [3806 0 R /XYZ 71.731 350.807 null] >> endobj -3803 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F44 1994 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +3825 0 obj << +/D [3806 0 R /XYZ 89.664 335.031 null] >> endobj -3827 0 obj << -/Length 2437 -/Filter /FlateDecode ->> -stream -xڥ]��6�=�b�O2n�Z��mrIq�ܡh��IP�2m+��D�q��%Jv��� r8��7��n��n��>�:���]q|�����O�"�����y���wIr��Yr���K�$L��n��a����7u������"X����-�=_w�?ʪR�/O�|���g�LV�:O�T&�s%T��rg[�a��$������]Y��Q�Ͱ֚Foy�-]���(�v���Ge�Z����4{�[e�F��A8ղ�P��q��ҳ(��������ik����{R.�k��z2�0����Q��G��<vG�|[��yD��W��s'�"���@$ ��$|k�UE��Y��Y�{gi{���H���9�!Z�<" -���V���m� -,���րj�U�;�O������6 -�*k]S��q�����Pf/�����������qR�:j��tۋ�x@���� �_y/$LY[ -�Z7S������'^���9i�ݩ2j˄a�a0���K��j��;T7�&��o�x��Y�ڛv�¥ջ�1�3+��Y�щe��/�y"]�L-z~S�jt��ήN��,�-M�1���Y��7mi5OL㭭��HV7����ϋE\�'�6�x�u#��~��x���6��k�3�r��Y��Xa��a�����8�8���S4ȵS�f7+�i%>�ul1��H�����"u�y�C�L�e���%�0Y1�e� -#T��ϳò@��X�!���L���@(^�Q�$Bgȩ)ƸdkɊ0hh��t�����5�X��Ń��jvV�<Ƞ����4��[���m�/)���A�O�9Qz����)���<f !��h�k�n |զ�J�A�hێ��Μ�m)���p��2h))�g�D��Z��0��픞��������@� /x���4���&�1NLz�& �م��T�#�h�k�-���U籃ұ���s�)�t G.0��Î��/�����M���р-��M����d���n_����ҕ��VH�Q"da$jp�| ޟ��z}���;��N�QWc�iA��V�7�y߱`� -��U%n.ce��p%;)�h�\�҉+�=I=�,������T���Ժ�F۳�0�ZJ�f��1�H���<�F_9�X��b2�7����0�S?o�P�ٯ��عl>}qٖ -�-����Ƕ�)6��l�����p����ږ���M�Yy���v�X��1�>pR묍��U�7�MӐ-Ӷ�F�g���x��؉��'N�O9I*c���-G�#Y=nB9���K�w.[�%��q��ȋb\<�\��c�_��}5G&Ce��"eˋ9�;�ԺĂ;���da�^�v�UkVʹ��%�����r��:��D}(4_G�:�ȵ�S?�!�!T1Pl�������G�H�6>3��n뤹��X�*�G\�{���W�$�F[���q��Sdf)y[����}���f��% [���!ܚ#kCY;�f�ޒ����5�: ?!Iڑ+q��~R�`�ѻA ʣ0�T�`>��|�$�Ȕo�M*�V`�� -t�o�6�Ka��^�WC�������ܡ���`����'<�e7�c�|���ԥ����/~TO{�o�տ��<��cעn�5u] M�Q����^��)2��T�����a�r���tpRJф���ɖ��Ħ�)t�;LS0r��vZܲ�%�� - -֘C(��+'�2��E�C�| �'���W�v�#)=�͈We�2�'D;1�a>��<{=���pk�k���%�/ѣ'��sER�o�槯���_��DU"Q]����_\�a�f�yy�B�*/��e -�t���H��^*g�,�L���:5����#��;nX�~������o��N��'a�H;�. �4�Fn:�K�x !y$�OcA��?^Ǘ\�����>�g'�]X��љ�*��K�遄!������8�,0��ȗo F�� ��3掭�E�lj�m ����V�|����k� �{�eK���WS��0*�S`�[-{T�=���2ɋ�,$/`�*��"F^�º���O��r�p�c5����"y���(���(�)�5B����ʗy�g�R��խ����^�����L�G7<��_[�D�Ni# ]��[V�>X�0xKw��A.�<#���$���@�!� -�X~ ˱�Y��<�5I�%;]i˹��%_LPi��c��7�BZmZSuV�pp�*wAv��=�"��c�;֥�5o��e*�o�����1�<0��M�{PpEq ���o��^����̽D�f�����ȅ�+ѿ����tza/�}}���xT@��?v��y�e&J�Ii���O�&P��%[�y���H}�߯kN�E�=�endstream -endobj 3826 0 obj << -/Type /Page -/Contents 3827 0 R -/Resources 3825 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3802 0 R +/D [3806 0 R /XYZ 89.664 335.031 null] >> endobj -3828 0 obj << -/D [3826 0 R /XYZ 71.731 729.265 null] +3827 0 obj << +/D [3806 0 R /XYZ 71.731 332.874 null] >> endobj -1724 0 obj << -/D [3826 0 R /XYZ 71.731 741.22 null] +3828 0 obj << +/D [3806 0 R /XYZ 89.664 317.098 null] >> endobj 3829 0 obj << -/D [3826 0 R /XYZ 150.315 695.392 null] +/D [3806 0 R /XYZ 89.664 317.098 null] >> endobj 3830 0 obj << -/D [3826 0 R /XYZ 71.731 688.254 null] +/D [3806 0 R /XYZ 71.731 314.941 null] >> endobj 3831 0 obj << -/D [3826 0 R /XYZ 238.395 677.46 null] ->> endobj -1719 0 obj << -/D [3826 0 R /XYZ 71.731 636.448 null] ->> endobj -682 0 obj << -/D [3826 0 R /XYZ 200.128 599.233 null] +/D [3806 0 R /XYZ 89.664 299.165 null] >> endobj 3832 0 obj << -/D [3826 0 R /XYZ 71.731 591.881 null] +/D [3806 0 R /XYZ 89.664 299.165 null] >> endobj 3833 0 obj << -/D [3826 0 R /XYZ 71.731 546.067 null] +/D [3806 0 R /XYZ 71.731 297.008 null] >> endobj 3834 0 obj << -/D [3826 0 R /XYZ 71.731 517.34 null] +/D [3806 0 R /XYZ 89.664 281.233 null] >> endobj 3835 0 obj << -/D [3826 0 R /XYZ 71.731 517.34 null] ->> endobj -1720 0 obj << -/D [3826 0 R /XYZ 71.731 439.478 null] ->> endobj -686 0 obj << -/D [3826 0 R /XYZ 299.665 405.007 null] +/D [3806 0 R /XYZ 89.664 281.233 null] >> endobj 3836 0 obj << -/D [3826 0 R /XYZ 71.731 396.37 null] ->> endobj -1721 0 obj << -/D [3826 0 R /XYZ 71.731 355.094 null] ->> endobj -690 0 obj << -/D [3826 0 R /XYZ 364.509 319.727 null] +/D [3806 0 R /XYZ 71.731 279.076 null] >> endobj 3837 0 obj << -/D [3826 0 R /XYZ 71.731 311.089 null] ->> endobj -1722 0 obj << -/D [3826 0 R /XYZ 71.731 267.757 null] ->> endobj -694 0 obj << -/D [3826 0 R /XYZ 295.625 234.447 null] +/D [3806 0 R /XYZ 89.664 263.3 null] >> endobj 3838 0 obj << -/D [3826 0 R /XYZ 71.731 225.809 null] ->> endobj -1723 0 obj << -/D [3826 0 R /XYZ 71.731 169.525 null] ->> endobj -698 0 obj << -/D [3826 0 R /XYZ 378.198 136.215 null] +/D [3806 0 R /XYZ 89.664 263.3 null] >> endobj 3839 0 obj << -/D [3826 0 R /XYZ 71.731 127.577 null] +/D [3806 0 R /XYZ 71.731 248.191 null] >> endobj -3825 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R >> -/ProcSet [ /PDF /Text ] +3840 0 obj << +/D [3806 0 R /XYZ 89.664 232.416 null] >> endobj -3842 0 obj << -/Length 1754 -/Filter /FlateDecode ->> -stream -xڥX��6�"�'ȹ~?ð^:l���>(��g[�-7���#E�vw+0p�$������?��ϟ����0�$�_y�����g�f���ܭ^�~���͓p��0t�$��a�fq0[m�t���A�vqĞ�4>te�#���SV�X����ջՠ0S7��m�<F�h�����a� - -�$DU���Jv4Ql�\����A4�^��ف%͞TOD!&��x$R�Y����7U5g�V���D�Bf�����L�V6|{�s;�{�/����<��1��&��(ʍOb7u}�(͜���B�h4�!]��&F۸��"Dۊ��9{�9���37H�j���x04WC*bm!I��n�����B��.���ŋ����S�D}�䒶�-�P�`��F�2錜5�Z��u%O7w�"���(�w:UK����?�ޣ�+<w�ս�i��/�x�G��Y�?��7����J"��8, X�V`n���>����D����M�ܙ$wÙ�S�%� ��Oό���^� u;.\Y�Vv}���sv�!��Z� �GJ�9�9�Ɛ�}'�*��6eW�]�����$����EFߩ�%g�щ�����37Μ���;� -��,�&b]�ZI �L��O���`f6����Tv�\��|y��N�Ơ�3t5�������9�6��}r -�gL�/3������E��ʉ�f��j_v�d�P��<�� -'�-�d���r�n�ʦ�<oh_U����CI<@� ��|Ix� -��1G`Y���� �|��=�3xL���0�aap�Va���Q�1����/ib|��g$�b���A��4&ۮ0�Ӣ�$������}#� �%��c��:a��5Hmz�ĊZaLP���B6�e�-����������k����A��t����`��C���B��CS��$cÏ�v�_��3<�� ��W M���(� ��pz-�=o)*- 쥗g�T�x�o�*�-��~r#�n���趗��O,s��2���^`Ў4c?����_ �E��ӹ�n��(���'>G1�~��vgh�*�Ո����G�q�ș�FCkj����([V��vpk��%����m*9�@��"��f��V�+u�H��� �� _"��0 7��7؆�Z��M\ -a���� 6"&KR������),P�q���[ 5�Zx�$qnh�S��t�n%u�{�Q�},M��Z���tL7�%�����k� |f�i�n�Ҳ�a�o��A6d��ҽ�}��l��vy���\:�p'�v�8��q,�1x��Z0.������l�yO�k&L�ǀ��&��b���:�'S/Ìc -Dǥ���CE|����xvY��և�ׯ��#b��F�sR� ڇ>[�t�!$�i�`��p2��cq�46������A g�o^�����{�S�R�b�@�������Z�+�����E�؏UH�[s�� -%w��α���a�}����2Mx�)� ��/��������qxE��Z��) -�RA-�J�d��&Y�ا�W�?��ykb ��Z����_��E�Q5���>�?~3��v<��^H"��k��j�+�}��^d�S~_���̨{�m��[P�D �8�� |�Z>ݜ�rd�g"��7�&�S�yj�����?gusV.��e�� -6�ihܡE����b -��Sik���?��MS�C��ة�ML:��w��$���O_�ehd��a( ����'�s?�\j�wQهendstream -endobj 3841 0 obj << -/Type /Page -/Contents 3842 0 R -/Resources 3840 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3802 0 R +/D [3806 0 R /XYZ 89.664 232.416 null] >> endobj -3843 0 obj << -/D [3841 0 R /XYZ 71.731 729.265 null] +3842 0 obj << +/D [3806 0 R /XYZ 71.731 230.259 null] >> endobj -702 0 obj << -/D [3841 0 R /XYZ 288.511 667.895 null] +3843 0 obj << +/D [3806 0 R /XYZ 89.664 214.483 null] >> endobj 3844 0 obj << -/D [3841 0 R /XYZ 71.731 659.258 null] ->> endobj -1725 0 obj << -/D [3841 0 R /XYZ 71.731 617.983 null] ->> endobj -706 0 obj << -/D [3841 0 R /XYZ 259.078 582.615 null] +/D [3806 0 R /XYZ 89.664 214.483 null] >> endobj 3845 0 obj << -/D [3841 0 R /XYZ 71.731 573.978 null] +/D [3806 0 R /XYZ 71.731 199.375 null] >> endobj 3846 0 obj << -/D [3841 0 R /XYZ 71.731 532.702 null] ->> endobj -1726 0 obj << -/D [3841 0 R /XYZ 71.731 499.761 null] ->> endobj -710 0 obj << -/D [3841 0 R /XYZ 240.476 466.451 null] +/D [3806 0 R /XYZ 89.664 183.599 null] >> endobj 3847 0 obj << -/D [3841 0 R /XYZ 71.731 457.813 null] ->> endobj -1727 0 obj << -/D [3841 0 R /XYZ 71.731 407.507 null] ->> endobj -714 0 obj << -/D [3841 0 R /XYZ 223.845 364.409 null] +/D [3806 0 R /XYZ 89.664 183.599 null] >> endobj 3848 0 obj << -/D [3841 0 R /XYZ 71.731 352.238 null] ->> endobj -1728 0 obj << -/D [3841 0 R /XYZ 71.731 340.693 null] ->> endobj -718 0 obj << -/D [3841 0 R /XYZ 223.569 303.478 null] +/D [3806 0 R /XYZ 71.731 168.49 null] >> endobj 3849 0 obj << -/D [3841 0 R /XYZ 71.731 296.126 null] +/D [3806 0 R /XYZ 89.664 152.714 null] >> endobj 3850 0 obj << -/D [3841 0 R /XYZ 282.496 257.451 null] +/D [3806 0 R /XYZ 89.664 152.714 null] >> endobj 3851 0 obj << -/D [3841 0 R /XYZ 71.731 224.375 null] +/D [3806 0 R /XYZ 71.731 137.606 null] >> endobj 3852 0 obj << -/D [3841 0 R /XYZ 71.731 224.375 null] +/D [3806 0 R /XYZ 89.664 121.83 null] >> endobj 3853 0 obj << -/D [3841 0 R /XYZ 71.731 136.58 null] ->> endobj -1729 0 obj << -/D [3841 0 R /XYZ 71.731 105.596 null] +/D [3806 0 R /XYZ 89.664 121.83 null] >> endobj -3840 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R >> +3805 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R >> /ProcSet [ /PDF /Text ] >> endobj -3856 0 obj << -/Length 2500 +3857 0 obj << +/Length 2070 /Filter /FlateDecode >> stream -xڍYmo�6���b�/��&^���v�e�����5���A�53j<�ϲ7����l�˶��1ESE�)O��/\������r?�$���.X����߅"q-"�3�O���Nj��7��i�XDZo6�4��,�O�g�v��^w��( ����'k����7SUj�������8��,�S��̙QQ��~�ޠUnsA�g됌J�̏Ж4�n��AE`f:m'X\G�F ���]^Ǜ�{k&T��(���цp���[D�*-�����x���oح���Mt�5<0��6��;Y~�P��e�x��m�ߏ����M=*��Ro�M⹕;6�az�$p�a�� ����L�a+�:�L�3�f��W<&ې8�D�V�ju�V�顮u��U��D������s��Ev���i�����W/�0�4�Q5s5z�X6�`���Xf���`�A��{h�OB-�x��xw��kÙ��6�->��+�v5�N��uG��+8M3�'��2�}��N��Ȃ�+>e;_,�@C����:�,�],<����uo�=!C[]ۙ�ƫ����G��A!�c�j�T�Ի��e��u��-��z|�eY�^����r�U�'�Ը� �K���)�qp�����j\�v�E�.��N��-y��1u_��2����Ir:<�TLQ%����2����]���8��#�טR��h��/s��?,CH�F�@ʀ�fg�25?�m������,�!{5f�'0P�><��J��F4C�W��.��1Q6�B��@B$����+V�1 -k�<�U�R����'Q��kL�� ��<+��p]ejq����Ǐ�Ϯg���MCA��щl a/�`^B`�5�x��T�; �S���}caT��_U�<�d#���oQ�rؠ�(�wk��%L�_p]]�x�5����jJ|��b���B�V�{��t��� ����=]x�{����HI�tZ�o�n(��ӗ������;���^�������a ���$$��u��m+f1ڄ�����C�1%�0i٦��W���}&��UY��h����=װ� -Ty�u��, -qB�wLh,��u����@�� -�y��-����X�hqL>_y��o_������"�"��Du<�Y�i2��"j��Auԇ��y"��-&&O6�B�C��c�< -1�\A������ �.;�m�E��HDܓ���r�az;tܠ���l2gx��Q�l��L�$4y2��#���za���zKŠ;z]��O���^����t`��n�X��I-a�"^�fh�g[]��%3��XF�CB���L4�&3L�\�:�#���I� -�֊Rg �&�q˒ XJ�_�; -\V[5-��^��Zw��V%��amaQ^���,� 7�̃hgW�Nɸ\�5h�W��'����Z���������x�74 aj��t����X��n��%w�2�߂9lKNG���3s��n��&�4���xaA�Նy[���^f�r7̢2�D{�Q���8���2N<��:�y�R!�sh�1<��L]ګ)�qmm:����]����+�o�"��2$� ���DC?�S��c�Q��_����tq�� �C 3?��D ���.�;s�y�C;���Q��5q㛆R�5�I]K>�#c<t��2���'��)�t%F N�ԥ�m[Q;�R��CȔ���&�xSS���R֜��9��3tW�R�PZ�q�Nm�Qz;�c^�W�`/u87�86��)�()��j���������|�^��VG��S�k)�.�4��>B�`��bfP��mu/mCÌo�k|fMU� y���t�r_�ŝ����K~}Z��� '�l��zg��t�����˹A�/-�`k�A��Tc�:�>?.R)Qs������wz�$�x#�BH����d��K������Cۿjj��f�$9'y������H�M�:��Db�}s`�!wc�i��}D/*H����#��������f��$��A'3���6 �o���e�:���]r5�t���x�q�<��p�?^�&ƹ��tT�������=/�'��{b6boF����*��H#�.E,�1��W09}�ʎ�|�8E5ȗ�#����at��j�ցZ˲�"��4�S��j4�p�����G��C���3��`��;ƊGF�[����5�v�x��NI>�"��<ϝ����?�"��W8{k��������8^��4� -&w�8����3��0���NNt�r����_p |�E.�l�4Ϗ���#-G�>n0��@4-��9d~u�L��*����'�i���u�~N�� �"gqD�d$����z��9|6DA}��s��<vF�m�w��k=+�b�v��+6\�7P�W��c�\w���'��ΐ8��Q����������Z�:O)����|��O�3֙����P3���N�D�DN �p�����|���endstream +xڭ�r����_��T@G�{�l���S�J)٤�<���@���-�_����A�WJ����r66�9���?22�7i������7C�d7�y������nb����\W�A� ])"_n�Zyr�T��I߶|A��E}�����{Q���_�����8��Pđ{��fƔG��X�� �H��gx���L�4�iq֊p���m:��o�t��z�Xw|pNs~��7K:�ŵD�'B� b[x���c���̤�D��8ތ��@��w �Of���B����NM�� Y���s��>`G�ǜ{R�nX��yC�/�-K���{��V�E�kz����G�5=2�ѣ���9���xE{I��$sY�nA�W!�K�|7�Ҫ9��mN����Q1T�%߁��^V7GD���u�=�{�Mݏ k�g��`U�sR�������'��>n}�**Ѓ���ňORT�D��IB[H?ܻ�����S����+����l�3G�@�k�� �x�F`Z�2y��0��:��;���M*��<A��"����n��ߗJl�ٶ9�P>�ɴs��} +�JU{ټ8q�;���x��u�'�P�+}��E�z��H=�ӤM���]�j�6�!,�G8�5\��-�(����K�A$/L�gU2��B�ֳ���(u� �|QA�����iN�}8��� -Uw7�m���M�ƀ_a1Z��,G��MI��,M��\�mS�6�csn�m䀒����F[&u��Y:�Z����Fz|��b��-�.p��?���L��b+F��%���:�(��{F"��c��0��G�b4�n�l���fn� &�)����ڂ֍T�WiS�k]+# m.��t��d�Ԭ���uj)�����B�y� �H�9������]���"��Ytlbg�~N�z�q�C7��r`�P��� 2.W��\��$[����$��33� .�z�f�������%�35��{,�{F�.b�V�2Y�[zӷ�k}��W��k�}˔�����b^�������=�?�f6yB�G�PZ b���pM_l�V���`���Dӥk��)��\i�u��6����:W�b´p'�n��!GF�����ǀ0.Ӻ���֥���z&Xi�vESڽ�ЁA���i��,_�U״�_����A����`�K���;ڞk��$��*�*_0�{hx`Y��k�$�@9m��f��F�V��)qk¥hA�;43vA�d�~Z;�s����C���VdN������ �o?���3U��Z +� �>��D�C}w�%�4ez/`��n:���`�|3�vF��qݠ�_��6�g�� ��]f���^w�io���O��`E��FL���S_ګ�̕P�ai_6�81I�h���pN�rFp���z4�+�煾�ؾ�x���!���k��@�Uǻ���xS�o����n��\GS�o��m�P�Xm�g���R_�Y�����p��ߙ& kedUګ��z]�W��4:!�.� +L�f@�zµ�Cx����yP{��N^�s7G5�HE���� ���N!��g�������Uq������h�W:f37S�� O]��T�,�4X;�����m0���{AC"�te���+�a�w�K֦G�g���^̗�����߄~��͵�H:�&_���*�W�1yIK�����SM�]M[���;�]f)�%0�� _��P�������`lj^��C�,m(!T�1�_��=skO����� ��_ +�f7��5"�է�xnYI�Ι�|ٯ�f�۴�|��v���S�z���:��)ߑ��q b�]�Q)����*��Rg��&��8w� ������aMD��s�sZ�Y̓3T��������pi�~\P�"�.:t4�)g��H@��6��0V3!�1��EWE!}��!�F �U%7�����g�V&���k�_W?���+�i�u����k�c I@�W��:ޟ���в�{�~�W�8��А>�����_m�_�慀�e3u�7��3�̒�/#a���"���j��-vj�endstream endobj -3855 0 obj << +3856 0 obj << /Type /Page -/Contents 3856 0 R -/Resources 3854 0 R +/Contents 3857 0 R +/Resources 3855 0 R /MediaBox [0 0 609.714 789.041] -/Parent 3802 0 R ->> endobj -3857 0 obj << -/D [3855 0 R /XYZ 71.731 729.265 null] +/Parent 3887 0 R +/Annots [ 3884 0 R ] >> endobj -722 0 obj << -/D [3855 0 R /XYZ 185.739 707.841 null] +3884 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [423.666 370.438 465.806 379.349] +/Subtype /Link +/A << /S /GoTo /D (lifecycle-image) >> >> endobj 3858 0 obj << -/D [3855 0 R /XYZ 71.731 700.488 null] ->> endobj -3859 0 obj << -/D [3855 0 R /XYZ 71.731 628.772 null] +/D [3856 0 R /XYZ 71.731 729.265 null] >> endobj -1730 0 obj << -/D [3855 0 R /XYZ 71.731 599.946 null] +1742 0 obj << +/D [3856 0 R /XYZ 71.731 741.22 null] >> endobj -726 0 obj << -/D [3855 0 R /XYZ 229.91 560.673 null] +3859 0 obj << +/D [3856 0 R /XYZ 71.731 706.187 null] >> endobj 3860 0 obj << -/D [3855 0 R /XYZ 71.731 550.53 null] +/D [3856 0 R /XYZ 89.664 690.411 null] >> endobj 3861 0 obj << -/D [3855 0 R /XYZ 101.182 540.548 null] +/D [3856 0 R /XYZ 89.664 690.411 null] >> endobj 3862 0 obj << -/D [3855 0 R /XYZ 71.731 522.516 null] ->> endobj -1731 0 obj << -/D [3855 0 R /XYZ 71.731 466.66 null] ->> endobj -730 0 obj << -/D [3855 0 R /XYZ 319.355 423.563 null] +/D [3856 0 R /XYZ 71.731 688.254 null] >> endobj 3863 0 obj << -/D [3855 0 R /XYZ 71.731 411.125 null] +/D [3856 0 R /XYZ 89.664 672.478 null] >> endobj 3864 0 obj << -/D [3855 0 R /XYZ 270.862 402.004 null] +/D [3856 0 R /XYZ 89.664 672.478 null] >> endobj 3865 0 obj << -/D [3855 0 R /XYZ 71.731 381.914 null] +/D [3856 0 R /XYZ 71.731 670.321 null] >> endobj 3866 0 obj << -/D [3855 0 R /XYZ 71.731 358.168 null] +/D [3856 0 R /XYZ 89.664 654.545 null] >> endobj 3867 0 obj << -/D [3855 0 R /XYZ 341.586 358.168 null] +/D [3856 0 R /XYZ 89.664 654.545 null] >> endobj 3868 0 obj << -/D [3855 0 R /XYZ 89.916 345.217 null] +/D [3856 0 R /XYZ 206.435 641.594 null] >> endobj 3869 0 obj << -/D [3855 0 R /XYZ 71.731 325.127 null] ->> endobj -1732 0 obj << -/D [3855 0 R /XYZ 71.731 294.243 null] ->> endobj -734 0 obj << -/D [3855 0 R /XYZ 256.243 251.145 null] +/D [3856 0 R /XYZ 335.639 641.594 null] >> endobj 3870 0 obj << -/D [3855 0 R /XYZ 71.731 242.323 null] ->> endobj -1733 0 obj << -/D [3855 0 R /XYZ 71.731 214.478 null] ->> endobj -738 0 obj << -/D [3855 0 R /XYZ 262.949 177.262 null] +/D [3856 0 R /XYZ 71.731 639.437 null] >> endobj 3871 0 obj << -/D [3855 0 R /XYZ 71.731 169.91 null] +/D [3856 0 R /XYZ 71.731 565.769 null] >> endobj 3872 0 obj << -/D [3855 0 R /XYZ 406.408 144.187 null] +/D [3856 0 R /XYZ 89.664 549.993 null] >> endobj 3873 0 obj << -/D [3855 0 R /XYZ 512.678 144.187 null] +/D [3856 0 R /XYZ 89.664 549.993 null] >> endobj -1734 0 obj << -/D [3855 0 R /XYZ 71.731 111.145 null] +3874 0 obj << +/D [3856 0 R /XYZ 71.731 521.934 null] >> endobj -3854 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +3875 0 obj << +/D [3856 0 R /XYZ 89.664 506.158 null] >> endobj 3876 0 obj << -/Length 2583 -/Filter /FlateDecode ->> -stream -xڕYK��8��W��rU[���[�M���3�5�3SS�=�%�͉^IN���/@�e�v�| � ���x��7��!|�� �xSԯ������g���,�w�^�M��I�y�o�0t�$٤a�fq�y(���?�� ��.�='v��k��'j�;=�OU������><��0u�,��'ó�Tn�� �we�n�zS��{n��I3���NT��W'�[�sd'�B��+X.���mv���A�z8���1�Gj��j�A�<��K{b����A4O�Q��Y�n���=�*ѽGy��s����Ʊ�k�ϗĹ���˳xHO�4�ZZ2x��A/�En� -;�N�iʚ�Q���&y4��Qɪ$��(:1�ݨ�NdT�ý����7j|������}��*�f�ڪ��6tO��=����B@l-���åQ��.�Q��Y�_�����1ǭ;Z -�}GK�;���ݳ�"�j���yD�==�4�����pv��|PŁ����iy��]�F��$��r��芿ÁǏB�N���n�;�s .u����#�hP�~��1�i/+Y��$�3�p��/��|�43G Q����1�q�F�߆!�����f��ay�^�É�2�-;\ -�m�K�;���-Q��w_*���<i8�e5��(����+�ɽ]q�̸c~�hYF��Uw�!c�U�D4E����w��!��b�!Z}��3���y�zIt��-��n8n\������"���m�dC��U�0�<&b� �M&L���j���3Ol��āAdt:k�qHR@��ߟed-:M�(9x�/.8��}�9B}�O���J��:�m�my��r��]�M %D�#��0� `�i�k��{��^9�\�%)��k��'��#Q�Qx�G&�K>��|d)춏,�/|Ē�����-�{RG&�ǭ�=έW��{X 8_��9&�\��3d����~ʾ�r�5���r&�O!�i �j�)k%��Z �Z�C-�_��K���u{Ҧ ���r�/�r*$&��C,)<`��i�`�d�Q�9d�-�bJ-�/��w�h�_{ٝE�g�Cq���%���7���6Ҏ] ��� �u-v��T#�`$C�͜�(`A�A�^F��^�z����v���`��{;���&�FU�g�A} H�\ -ɰ�Wzl��Q�Id�H�d!�T�Ѱ������������HN�� �H���Ό��s;&�r�����ԩC&3 !} �Qv��4T�KD�Ww�#�n���?5����Ee#��J"LKj����M��� ��J����#���0 -��?e�����ک���Z�{h+U��m�v�|T��� -�:�r�����⌢�3�r�o�T�G�:�Rv�� �n@����O��bj[@:�Qͺ��z��6�J/�� 6,@����C����5ק=}_p-���)��%���78�9{�!�ީӮp�/`NJ���ĉV�hJ�D�!!����-:��̮t��F��OjgS:ꉲ�s#" ��vx�Z��3�ynQ�A�m�^���-\aa��/�!4,���n:�=]""�17��~���A�$B#��y�$խ��`d��;����-�xl�LO����Tđ�� ~v��ק�9�:�VtP��qζ^ɒ!а�e�h���5`�:�1�K/��`�ՙWO��/ JkA���O�6wO��s��%�����|���c%�8�o -8��x�)E���d�"X �9��PI�-؇������w4��UV���� "B;�k\�w2%�x��e��T}��j�Q�$۾W���4RT��B#�����4��?��[5��0`J� �X {��1HץD'�7۳N��>�2����"c�wm��;�����Le@ǝ�8�o���"��I;��j��h��"4l��a0�ck�Z4��5���u��$�p�BeG=Rk���� ��H�8� /FhɌ�����'Z#j�l-Q�]7�Ḟ��v|\;��b���fܚ�'��Z'7��k�\%�(u��OIJ�U�8����h ��:a�19���u\�ΎK�%PD.Y�����(�g�xi���aց�*%o��,��֨POnJ��B:���IWئz��H8�#~���Q�M��%u+E9?�(.��#wG���L��ӷ5�vb�O�|h�ܽg�:�?��gk,?���6Hg@;/����,܄�Y� ��ɿal�M0�|�A������$;.5);�n����4'K��w��@L�Rcz�bԢ�!h��9Lco/�FVl��ngVA5Ok��u�q�2Pu?���p��1����~��۳���y_ѓ2{R-Jz����`������^V�K-R+r�թnxC�,g�f� -�U��.V3���a8\Ht|�ͅ�!?��ղ��Cυ�!�q�qhE��ǡ��C��������^qR�w4I��&CI̟-��W�UeOE������CC�# %�Q�K=�'KG\W^c�&�%"����/a����A�A��h�_{3�)����(s3��"���8���EP\]�O{)��(L)endstream -endobj -3875 0 obj << -/Type /Page -/Contents 3876 0 R -/Resources 3874 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3802 0 R +/D [3856 0 R /XYZ 89.664 506.158 null] >> endobj 3877 0 obj << -/D [3875 0 R /XYZ 71.731 729.265 null] ->> endobj -742 0 obj << -/D [3875 0 R /XYZ 258.989 707.841 null] +/D [3856 0 R /XYZ 71.731 491.049 null] >> endobj 3878 0 obj << -/D [3875 0 R /XYZ 71.731 700.488 null] +/D [3856 0 R /XYZ 89.664 475.273 null] >> endobj 3879 0 obj << -/D [3875 0 R /XYZ 71.731 685.559 null] +/D [3856 0 R /XYZ 89.664 475.273 null] >> endobj 3880 0 obj << -/D [3875 0 R /XYZ 71.731 680.578 null] +/D [3856 0 R /XYZ 71.731 473.117 null] >> endobj 3881 0 obj << -/D [3875 0 R /XYZ 81.694 659.821 null] +/D [3856 0 R /XYZ 89.664 457.341 null] >> endobj 3882 0 obj << -/D [3875 0 R /XYZ 71.731 657.664 null] +/D [3856 0 R /XYZ 89.664 457.341 null] >> endobj -3883 0 obj << -/D [3875 0 R /XYZ 81.694 646.869 null] +1643 0 obj << +/D [3856 0 R /XYZ 71.731 437.251 null] >> endobj -3884 0 obj << -/D [3875 0 R /XYZ 71.731 631.761 null] +666 0 obj << +/D [3856 0 R /XYZ 259.687 394.154 null] +>> endobj +3883 0 obj << +/D [3856 0 R /XYZ 71.731 381.716 null] >> endobj 3885 0 obj << -/D [3875 0 R /XYZ 81.694 620.967 null] +/D [3856 0 R /XYZ 459.262 359.643 null] >> endobj 3886 0 obj << -/D [3875 0 R /XYZ 71.731 607.916 null] +/D [3856 0 R /XYZ 220.262 346.692 null] >> endobj -3887 0 obj << -/D [3875 0 R /XYZ 81.694 595.064 null] +1939 0 obj << +/D [3856 0 R /XYZ 71.731 344.535 null] >> endobj -3888 0 obj << -/D [3875 0 R /XYZ 530.108 595.064 null] +3855 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +3890 0 obj << +/Length 1302 +/Filter /FlateDecode +>> +stream +x�}WY��6~���[d���0u�i���b����-і]�#��w�3�����"���o.R���N�8�%HEI'�W�s�o+�-�l�]�|گ��IE������P�Q��a 8����Bu����@z��~��D���_YUj����կ��@�"M�w1Y�[P����KD��L��i��~�j�����Qg�bE{�UY�k�e��5n>.��Q!"���d�3Ar��%/�]*E�&���8&N�����_��_+����fq�IC:~,_.�ȝ����A +S�8q���ׁ�fk�s*��(k{b ����%��� |!%y���0�/e�34�:�M9�:BV����f9" +����=��v"��jH���&'d�t��:�ǘ��k�qC���k�X�C�N�a6�=Tg�,F��c�~ R雈/�bC�a�57��k�@���Ht`�#Ld^˱ �i�h?29��LJ�J59�YU��2'�����a)e�^&ݟבtEv*Ō�v�TGsm��� U����mƾ��;R3D�+���(����*�=jL�j��<T��;�U�������ފALE�:�2Z��F��w�@7��L8�,�\Y_��ܚCg��&��?-�T�n�G�`I�m��"986$�� +�]��Fh��� ��ؔ�\����c��n49��}�^�S߰g�9�CCGP4*D��4-"��@0��\���e.���V$���&2�f\r����[��I9,��|3�l���Ŀ��Q}�[B� +�G��{}���{%%^&��;e��O )-��ͼ������@��܂?�Ü,���_��� ��:����!cJxB�:�-��F�l>3�����P��T����:��~�� +� +�D}4S�ڌy�M����WOz�tk�U�|# +���v���V��7$�u}������ԷSGd��3�A�C;[�hs�Ш^o�L=���U��%H�� p/��)h�I�+����f���/y���z5�~hi5���0����ՙ�Ӡ�zm����R�ѫ2W��E��=�ܩ9=�^�O�����$���]�BF�$�D�$�a���ذ��� ]����@�������v$5�0�ԑHup`���a�� ��lZUms�8%J�'R-�� 1��%s��Xs�E�H��LRs�E� �E��c%��ۂ��12�[窪��6��_��8^ ߃o������.���q�w����q?q�l��[2�b�6v�(6?���%"��w�\Ln~�� �x�<'�~�������mb�endstream +endobj 3889 0 obj << -/D [3875 0 R /XYZ 71.731 592.907 null] +/Type /Page +/Contents 3890 0 R +/Resources 3888 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3887 0 R +/Annots [ 3897 0 R ] >> endobj -3890 0 obj << -/D [3875 0 R /XYZ 71.731 559.537 null] +3854 0 obj << +/Type /XObject +/Subtype /Image +/Width 496 +/Height 579 +/BitsPerComponent 8 +/ColorSpace /DeviceRGB +/Length 49257 +/Filter /FlateDecode +>> +stream +x��wX���i�b�ް+E,(�**��5�5b#�{0�+b��1Ơ��b!��-��n �b���y�g߽�۹�{>�g�������w��Μ��`�a�a��?�����_� 8+�aX��a�s�a���a�a=g�a=g�aX��a�s�a���a���ar"�s�4im)RD�H4>Q`���u����`X�Fc������RRR�Wϋ/.ٓ��Υð�3�ZR�|��y�� ����ؤI��u�^�xqΜ9��-Z�2d6F��m�6q$�����tԨQ#!!A��}�����6lO���˕+~)����#�����}��իth������K�,4h6~��G�� ����H ~��r�2��Y���jժ�_^��g�b�����C�۷o����f͚Af�����kq$�s�>~�86�;������ɓ��/�+��q�ܹs�@<�Mg�<yn߾���leeu��]l�)SFϫW�h�ƍժU��eX���s�Ν;wŊ�]�`A��������W�Re�ӦM�;ԘT]�����IR�P!���5N�%�e�\&lq +V��!�ϳu��F�!�H|�|��|�s���<%%�����ٙ���ׯ�Q����ׯ_F�� �1e�I$0�O�8A� �ҥK�~��!6N�:Eָ���*���!t������x�={��[�n�͛�˗a=g�M�Add$��ݻw���|3 ��8������ϟ[XX�>}Z ��#|͚5���T�\���\�?GHzq(�s�S�n]�:�����hD�*����z�0:!=l���תU�3�a=g�����6mZ�^=WWWy°�3�0���0�9�0�9�0�z�0ð�3�^im���ӆ�.�t��QH$ð�3�Z� �L��.d]5jvk������7oި����h�1*d=bM�6 ����_�^�$N3D� �ܹCg)�HJ�"�;�q��U�Tٸq�����ׯ�+��^ða�����$'^�rE���q��ߚ*N�իW�ʕ�1c���z~��ɓ'sv19B�a�����HKK�8Q�96P�YQ�,��N���Ç%n!ȇ�M��Q6ɉ��^Tnڄ[S�I#czDFF�/Ru��C��7����W���9y29x�`�v��n�*q����� +��<+�j��Y���1K::�zA��Ar���J���oM'��I���� +*?�k�����M.�=z4gc��z8|��~���bŊ�:Q�+k�<+*w�%������ѣ��k�^ec������$��1].l�3F���CX� 6�*Ο?_։�\YS�YQܩS�֭[+��kA~�:hܸ����3xA��Ar�����*&:����{��aL�D�s�a�0��8g�1��s�a�0��8g�1��s�a�0��8g��ь3����s�Q�Z#��Y�C���_�1a��s�Љ�A%��%�h��S�x��x��iTTT```ٲekժ�?F}<<<����q��Q����F(�ա�N ���Q�M�"پ}�8�.xzz"���p%S>%.�� -�:�ld/��/^��lll]�V���H����m���\����%3�:�)Ǐ��$~����.F����Z���Z:u��k��]��cgg{� 6�>}�ѣG��y��9,�C�M�<bN�ާOr�Ę!��e=(f(pu(���(I��B<�>e}-J�UK���w-��s��o�>2�.^�(�%g��\��;qѢE0]��M�6����73D�7B�ʺ:��'N�����/�D?� +!�\�ǣ\_���j��Q��e��z�[i�_�~��Պt��L� �ꨴ�䈈�rf�ro�r]� �!C�4h�@�?"�����AȰ�0!Y�����8u��k�4Ƚ(�1�����l� +빮��ڵ�����Ғ*6è۱�r�E������h��`ܸq��6m�p�cX����ͲTK����Ν;h��D��#�atEzzz���-,,��@Y����kx��^����0:�mA#N]b4��Y�f!��Տar��Yh���'���|͚5�sZ#�aFW���Ж:u��m۶!�4h�Տa�s�s&'"w�{�ܹ'M�$�]�^=???��������عdɒ�u�b���wTT����������?�����Y�����ig�<yF�A�Ç�_�x6o�,�iԨ��ܹs��Ҕܲrlj�V�����1%=wvv���JIIv._��k�k�C�a{ٲe!!!����+W*�!C��F�C�=*]����Y�f�� U�A2z��=c�oYݣ�9�9����y�� ;��ܞ<y"9;!��_l���+�AE=�t�RժU���F�JHH��ѣG�x��y�*U�G�M�=�߫W/��DY�������&M������q��E�'���L��sXݵj��/�,Z��*��L6q?�����v�xzz��ڒ�:z���I�&EFF�:uJn� ��HR"Im���in�����������gϞ���� I�z�]zNn��< +� תU�B� +Y[[.\�m۶¡�7"=v�`%�ˍS�uXQ���ի�ܹS��D�����_�b[Ř---���W�^��~�����X��;w��+V(��Qy��T��Qo;t� �LOO�� �sH�`�l"ٺu�8�\��t�`���+C�)�������{��:`��E��7M6A�!���ə`IW'm/� +�����...�^�x1�"=,c���3fl�Qb=g��B?s�6` �4-%%������Y�������^�t����s�δ̄�T��L��ׯ_v�D�~�?�9s���w�����+VL���H�>�4�v(m�z���і�;�,N�:�B������oLL�8yJ���_�}����ظ{�.Y����k׆��ol�3�lרQ���Q�ŋ�� ���Q,(^dd��?6::�~��4��o߾4��N��!��+�AE=ߴiS�n�d�+�oƷ�]0g���X� 6D +�ϟ�!r�(�o$�#� ��0f=����]�&>�=ؖ���7ݹs��B<� �2N�[ �+W���~��G�V=fI"Y��1I=�~B{���z������cCV���Iۛ�����v��ϟ�e^�Bl��jŌa=gr�S�5��\���N�p���~�v�$����(�߲p�BE�-?��3�ņl��8%oE7�j� +;v���7o6𫨣FQ�+V�P�3���a=g�_��U����el���J�ҥK���bܳg��=t���'N�Z���{h� �d� ��r�TQϩ{�b��?�P�D��C�w����fY�|9�9�z��\=�u�VϞ=!�VVV��ի�Ћ"��>}�ȎW + +�1�*ԦM�xEX�4^���Ʃ���]��W��#�V�^���s&G�9���s�������zΰ���3�9�z�z��S�5���a=gX��s���a=gX�Y�����^ZO�z��9c`hjL�"EX� ��4�i��\��sF����/^�����ŋ���sr��z�j�~�9�[���P��'Of=7��߹s�`������&�������ժU�_~Q�����goe���X��r��in� �:$g=��7�ݦM��J�����:u��>H�'`=g=gr���(�֭[?z��\z�k�.;;;� Z��˗/�/.�#��C��V�ڭ[7a��ܹs�֮]; ���^�z];w�|��YD��G��������Y��'�!!!���ǎ�Cݻwwww_�reF�v���Ç����P�$1��nILL̗/��_�~�+r�s��9d�H�"�䈈m +��[�T�Ҹq���dY=oҤ�����j.S��\=�Q�-����.>Z�T�;w�`�y��Ϟ=C�-[������-����3��.��h8�e!��:�t������3�f߾}666(e<z�o�����9tlѢE�s�e���MI � �m۶�x�����n�=7..�]�v�Y�}.��P���d�������������`�^�ZU�$����hY;;;���aÆӧO���0*���+W`�O�<��͍��Ӓ���r�i�&m�66�$~߽{���-[��sjd)��aBgd��.QW!���@�\���G�>Gs�{``?x���7k�LL�� >�$�YB��B~�X����ŋ!C���NT�V���H� ��{�n(�$���D�������4l�2�832ׂwuu�+����CCC��:u��x�q�\=OHH�Q__�Ν;=z�z�� +"@��]�v��9"&��⣔��;Jlx����7O�>����}{)��@����oDD$Q�.P�����������ϟ��Z0������&����H~в�3gΐ�� +�Hصk� �:t�&��ӯ_?�/�����.��^�B�*Uھ}�q�9��\�z�ڌ����y�fR?���m��IONNVż���Շ3x��y��06��-��F�����su�w�r�J�� +*�\��j�*GH����"���B+�ҥK\�����fmmmii���g� �B߳�ի��n�Cϳ�vʔ)�� +���Ɔ��߿o�EֱcGY%���z���g�`v j�ݻw9+�P�5�-x�Νƍ�������t�i��~h���q��tB +ߧO����}���U�Ve�6IPriq�J���B�r��^�z.\͚5{��1����67�ck�1mڴA�۱cg���h0[0((�ԩS�1,�(��'~������Òq:�;99A��A�U�$(;Q����_Tȸ���/b�=w�\ѢEiJ��w����J��ZYY��k�����;&K&N��*7u�T� +#��3ԟ-[Z�W2 Pv�����#��>�O�\Z�)�h��B��Aol/^��ƍ4% +���dv��9A��~�� ��M�q�ơs��m;;;��֭[�T�v���B��۷/C�{%�U|��i�<r�Ȉ#$�Yd[L�Ӹc4c���Ԙ�0N=Ww� ��3g��6�O2 Pb���s�(��I��\ri%��PK�,Ia�ҷQ�{�/_&_4h�m��CbnccC{ 閖�YJ��={f͚�v��-Z?~�w��Mj���4�gQ�_��?�:thF��d4s$�Yd[L�Ӹc4akk������� c�o�`� �&<�0�5j���$��+=W>I�Pti%���B�:u�$H + t�����8��:s�L�-82�Q.�U$�ֺu�~���$�1c ��-[P���˗�P�E�(�����O��+9$��d<�;Fc�='��ق��ʡV9�x�b쁬�� 6@!��0�[�_�>���"�)�t���3x����^����i_�| �P�=�l� �#F�?~�� dɾa��q�h̦M�PӲx�z�-�-@ʊ+�{�䉰7o^��͛7iϲe˨C�z���'N,XPv��N}#�Z�"W����0_aꓡ��{٦��;wM��W����s�i�1��~�B�����.��`�E�rh���|�ر����@����g��ݯ���0��������L���066V�&�b����УG�tvv�}�v��+W����=��ŋ<y�]v��e� ��\�pW�dI�#�===��[�n�|�������<#%����t���g���%XAL��틶gh�vOQo�`o�����)Z�gɒ%8J��RRR\]]i<�1J�E�.���0������*UB7n熞���F��L�[�z5*����"'-�^�����YK��RgϞ��2�֭[���$�QQQ�h0:�U�\��y0X�E���x��{��J��ɝ0�|qvɌ�,}� 0���$�G������'�SEs32����4�^]�tA�H��ٳ�*��q#I�1c?#���m۶�sC��]c]2O2}�DU�?��/�.��O�)��$U�h�<ˤ��ϟӌ�,;�h��\����8�?~��9�V lmmI�'M�ď �sƏ��������r�X�LǓL�#�U2�O�A勳Kf�e�FѺ��T��Bf�T4Ih�;���7�>899��(���С}}��mΪ�r���O +�sƍG��njî�u��5�%��M�S4�O�A勳Kf�e�FvJ��8U�h�M�eR<x���YŊa�����z�R4�?%%���-'~��S�4h?,��Y�bu��A��1��xr�d:���{���ɝ0�|qvɌ�,}�(�sq�����{j���J��o�>�j^�Z5�'N%�,����)�hbb"xX�pa��x��͛�$�G���0:�ԩS���;=<<�l-Ƅ1�O��ݺu#�jѢ�T4*��!ڳg�vvv���Y|��c俅at�۷oǍG^����3iҤ�/_r��*z� ���hѢ��*˗/נc�w��J��������ȉ�B!��l��0�B2��ɓ'aaa4\���m�ݻw��q�0�p�����Ǔ� ��G�qK-�mۦ�]����#=�~[,Y�$I�dL��[�n���M¢E����c���?�� ��}BB��ɓkԨ!,�гg�+W�hmJJ�m&��b._���xq<x0��^�j�(��V���4cccc[�l)LX���}��Y�p��Ç�C�0�}���Ç�dr���;_IJJz� �*1���nݺuܸq�5rtt����˄ T���S������#L�bŐ9�|���)�p�f��ӧOcbb�w��&Y�����O�.]F��hѢ���ȑ#�.]�w�Z߿�ϟ?C�� ��x����������7˺u�V�X1{��)S��3f����~�m�L��dB�A�ʕ�e��U[N����u�ܹ��П%K�l߾��ɓ����䴴45ns֬Yaaa�#www������/_�"E��6===!ȓv��u��w��w�!�"##q����f�\�y���r���k�"̼y��}��m۶m� h�f1x�W�^Ѣ�t�'�Q��w��J¤��7m��p�9�kѢef����|!lƔ�v��O?��L�QB�ܹ�g˭�<�8��j�X�x)����w�� ��ɇ�:u +/�ƍc�d���C o%�Ѕ�+X� e�x�y}�����h߾��3�L{�捞����۸\��M>y�^�:�>Y�|���h`1�NL��Ǐ���s�΅�����aٲe�{�ZX[[C�� ��Q�lih]`` ��={��=z���s�ҥ+W���d���dX�>}�|&7o�$#)z*=z��]�6m��sڴiC� �W���}J,�Z�Z�`Z:̷s�΅���/gii ��m^�|9��ʕ+H��b!Ϟ=�m�����7nĝ��E�M�<�6l2�/��;���r��^�z!̈#�ېJ����'�Ӑ �#Y�X�#֣G�r��D#vh(����F��}��:x�{G�5�ְ6�RX�j�~���g<�-�nÆ Z���P�GqZXXx{{����k�-��DQUo +�VC��_�eM�ͭ[��0�n���?�:t(��͇�c�����Fu���ڵkS$+V������9���dW�nݲ�������;w��ѷ-�x�g&K���<jcc�g�P�BQQQ*��#�pr������o��8��������i%K�T]�˔)�d�c�`���h�Q.��d�'11�]�vdAyxxܸqCyxX���bee5f���.�ʕC�� 7==�Q�F<r�Ȝ~אqA�y�:��+G��ɉ�s�ޱc��`���4˦D�'O��|Ӏ�={"[�J��7o���Z[[_�t)������i�Q^؈a�Mjjj߾}��q�l�/_���� +*<x��sL3hE�!C��~ҤI_�N���U7y�d��W�����8�!�������Ҙ3gΐ>��Ç�<�ҥKM��� <���蕱c��R������!L���x�"mx��=^�vvv�z8|�������Ӌ/L ī`|��7\%F����Yk۶����E=z4���Zu�ϟW���ݻ�Z����,��$�J|N2�=III���ȑ#��[ZZbON8g$0�y+^�)K<x`oo�>˹�9��ŋ���],�a]�j�*<h͛7�6�BlϞ=��E',[��9p�@��3f��ڵ�)eE�ʕIҫV���a�DZZZ� +,,,�^�Z�pakkk^�OW;v +ְaC��JNN.X� J�ܹs��^^^$�*N�bFfΜI_�����gTisqq����$<X-4�:��dҺ���x�8�{��'6n���jZ@@�I:�]�3�>�����~�M�fTi�s���&Mҷ���~+��U=rZmS�&�\x���ݻw�Xe�ܹ��Ԑ��0��P�D z�8`�z��ӧ����f��?�= +�������^G�!>$����Y�f�'N�/�CBB\]]�;& _�z��]�Bm�KCp�Z��v�����Ԯ]{߾}�T�]�vРAgΜ�;w.�� +ݵk�D�U��Z���/8�����|��gb�ϋ�1��@%k� +�]$~³������n��gϒ��[�l��Ҹ����s�Ή '���߿�ѣGM�4��R�J��晈��dH�`��2 �mР������aÆa[O�5^�z��9�B8��l�2uo1�pG=�,ƍG�-W�\<�a���ݻx��5k&���Q��y�&::�@��52*��B� +~_��A�� >$���ӽ���sWx5H�!e�|˖-x/ X���iO�Lh�#q<qqqx3B���Ǝ�:D>�Mҭ%}# �Z���0fNÆ �YP��S��"��䂋�l��=_�x�?�H}�4�rĈ�Ǐ�0a�%�$�9}[,]�4����Ǹk����+�xxx����|��-�*>>�E��/��:�߽{'�6oތ��ر�f�O�5���&Y ]+�L�1�a43х5���9���A���1��Ʒ4�Ç 4������s�����z�*�%�H��=Z�zu������kWWW�#G�� /f̘1AAA����]�vhhh͚5�o�����={V��S�NH*� +s����"����uM��۷ƃ�+!�a�5�az��bT��ϟ#'���5�b� �Z��$]�g�a�����%�{�MCρ��=�S�y����Zh��tT�͛7��0:4э���d���7o��������+"�S�N�p.]�r��ʊ�_LLW�ѕ�n�֠��e���f�����`�Ψ7n���3�a��l��rA�e��c���c�%P.ׯ_7��Bţ����y��0��&:�пC���!W�/_����ϟ�Hz��i����c��ӧO��0��l����;e�m"IIIqrr���7� �Ga�:-�a��D7=�\�E��E�kE�-��(L�b�0ݻwwww_�r����"c#""���N�`�s�����4.̚5�R�QoooSs.��"v�"��"�V�E�E��2e�`;55�/$��F�v��M��믿�j=���U���R�Q�D7ɞs���;���",�,r��9�Sk�o߮��)�����|��w�DEE�s� O�>E�,[�,��cT�������G�����g�؝��x[�?�o��a��Jb=߷o�����lذQ����σI>��X�����^^�x1d��N�F�P����nnn�.� ��"v�"��"��uQ&C��z�CH��kW_�`A;;���$�y��={&b\�v-K +�]�i�����~��{��w�Z�1ϟ?�|�� !��P���G�<̖9�b.]��4㵢�؆���ϟoVu�-,kkk*}4R��`�d��j� +�}�-IOO_�~}�<y��M�6Uq�l��7n �U�T�Il7o���\��]O&#�{y�1�����壁j&�Av[�x��:h�߿�Ԗ.]ZWj�@ �r��r�7�KgIpp0*^HH���Q���������� f��k֬A��{�6â�~�:͕����7�`��*W�hє�� }0s�L�p�6m�P����?'''ZY��صkI���-?_� �.��������0�il�Y�9 + +2�n䘘�Hϝ;���QF3��Ӌ/���ꕾ}��^�z����u���=�"&L�@��g��F@ƹ����h���P����?[[['''s���'I�V�?��8{�,:<�'t8�^�ܾ}�,_��n�mժ���?̹��c��F�p> c�|���Sp#�+֯_�h�w�n��@�A<n�8~(�s�g�r��q����G�Ѿ~����6o<ݸp��<ψa=�|6�� �:��M�6�yǎf^RSS�����%B`X�9���VOC��yb�����ӠtGGG� ��u�������m�I�&��'�8���DO�_���[�l�v�=8�U�_~A:��������C�\�dI~���E�����rn0�Y�r�u�n߾�������ٳgr��ׯ\�zu۶m�ӥK����ZDD���z� +˖-C:��ȫU��ȯ_��O(�ر#�Un�0ʁ����x��K�.ɝ�f�z�7oޑ#G���_y��~��D�8:j�(l@7�&�Y�&ݸq��\E~��j��#rz��Ld��111��$]��-ZL�6->>����Ư��Ǐϝ;wRR����Z�*��[�^=�����ʕ+���++�B� +��=G:a��#�]�v!� ~< �X�����;�b�Cr���uww��;g���s��sa������ܹs;��˗/����Q'0}�k۶���y�Μ9c�u�S�NHgll�>"��-*ʔG- +@�鋏�����3f��_���ϟ�h�#F�@�BV�%�iU�ʕ+���ŋxF�����3=���r�qV�ƍ#�qqqz��lݡ+�|A�4�97%������*sh��͛�Yϟ>}jgg��{(v���?���ё>�)S���=Lz^�dIZ����咘�hl���ɻv�^ �)�~��T]7m�Ĺ�(�(W�۴i���b���M=����A�R��Y�f��[�n�������g��s��g�"""lmm����z��/^�0����ګW����s��ڵ����;wn���(�ɒ��� &�d��1c�кr<���zN�߿߯_?Zb�P�B�V�2��������|�����u +@���˗\+��ʭ<"��F� ����~ �b=�='nݺռys*�˗/go"iLT����z��M��*�Z!A��G�qss��ѲeK�y +.,Y���<�����-Q���� ����Ʃ�ĉq��S�r���5�����ʹa�}���o�%�X��{3D�����:�F�4|�С��R�T�C�eK"/^,v��'��"��w��F��ʹaΜ9s�B� +�L�̙3� +��$����r ?�sc�s����9�<9r��i�u�����z� +}�/Z�(� +�����ùa����O�>���:u�ܺuK8t��Q��O�sc���υs�Υ�/���vuҲeK\w����� F����9������۷oɱ����ĉ%���̙��5�7g�ꚾt����e��/4h_�SN�t��ڲeW��>}�L���P� ���Ç5jԠi�� ����<^�0��tjj�����+�u������\�������ٳg�F��C���4�/��3���E���vq�Z�ᅘ���R)z�o߾(�իW�u֮]�hy� +*���̙3�_g�܈��õ7n�C_�|���D.լY�s��A�����ݤI-g�S�c������U��G�yyy�+��;w�/�k�Uz��e�A[���;R�Y��P{�7yΟ?_�@^.x��ꬃ��-;=1s�LmF衈i4pƌz�9r$.1w�\�� ���{�.W%�7]�5a�2o۶��\=���0�����O%�8!!A�x�̙cee�b�ܹ�w�t�N{>��h��� 6��.�Șϟ?�A�0�>}���wD�|�mDD7�u��˗a\Q�j۞={ȇ����n������Ƀ����hC���,Y��+�r�%^�X1� +VYݺuQ��չ��o�>DުU+�6�=h�_����6m�T�bp��M�pww����R{��u�Y�Z5���ҥKq���sUQ�t��'�)BC`��#���x�ɱ��0`�������d�m@�&_�p!�#}���m�mK��˗/��I���J8p��t\gT4ѹݔ {&��z]�ŋh��.x}����rss��\ˤ�$�R�D����K�a'#6�1��gZ��L�2�hg y���"�ӹpႭ����Ŷm�p94䣢�˖-[�V-j�� �FDD=zT��yC_0,x��y-c�R�>�IKK�������~��9@�xzzrV�tP�+V���>|8�F��U�֭[�R��,H���YYY!]u�;o�K��B��zQNg�ر4q����\§O�ڷoO�4�۹s'y0p�����͛�U��u�ԉ�"璐��+Z��a=���|@@�2�lٲ>� ��8�|�|̘1��Y��U����pVȒ��6r��z��կ_ԨQ:t]�V-ɞ����Izz:}��8q"�"���ժU�`� Źx�`�\w�С\�� �e�~�eY�p���O���r^���@V�5`�ƍ(�*U��A�s�$''Sw4�,�j�y�ꕥ�e��� ?���_E��t��ŧ"47�R�J�`��}�V0o|}}Ǎw�ĉ۷o��١ �nݺ�+W⨧�g�����߳g���\=z�W�k�Ν;ϝ;�v��h��ڵ���۷�p�X�q($$����رcJR��ӧ���f}�s�ٳg4w800P�/������+�^Յ� XXX�˵�#��!�h�̚59֢E��ǏC�o�����ѣGh�@��y��xp`�l�2#s��F+�9�Qj���W�)����QD�$�4���Ϗ��\E�ݻG�uG���)={�DxX/�O��'�����g�ȑ�J�s�$�u���������1c� ��ah>~a�}�d\06ڵk�'�\r�X�a�ӆ����䡁P�X1��O�:Ņ�z�:hc�t����g8-- ���#_�y��9����̥�:4g�3M���������E�ed��C��m��;Jt���Y��4zP8 +S�^ ���{J�.����Ǐ7k�LQ�bbb�e� �z�j䏝���ӧ��$W�B5<�r�Bt�Y�䁹H_E��Ercذa4��S�N_�[�jE +/�� P__�Ν;���EаaC���V�瞞�]�vuuuU⛔��y)빉��w�!�J�,���#%�`� ؔ)S�+�h�"O�<�"SZ�H0G��%ˡ/ǎCy =9�� +ژ�%X,J����(P�fM$� \d�S�jU�����<444�>Q���III4>j�رr$&&���lL$�j��/�Q.���۷osg"|�eX�5��ٳ666VVV4�V���ӑ��Ǐ��~��7H�/�� �<�(�����B=�`=�Z��t�Ҳ���;�{# k֬�RZ'�Q�F�FNPPJ�=2��Z���???ZuT������ΪU�fo��d,[�L�Q�� <X�)�:�����#�SWZBG��\õ)}��h�7o��ʕ��ёGp����ϟ_�EfҤI���?doڔ�� �Ơ��8�S�����˅��6�[����Z���Z=�FsN�٦omQ�M�6!�`'������+ZXXܺu+{F��gΜ�<�`�ԯ__�jEL��92b��:1>>��ӳf͚'N�Ȑ}��������&��V�ʐq�!q��<D{G�ء�I<~���[�� �Xw��A����*A˩K���k�Gq�}��I�:tM�nݺ�U�U����8*~�iذ0��QK� lΉX)1یA�A�=�i:t��: /�lOՔ)S��g��������M ;w����ǖk4i�$C��F�ҥ�755�������ؠB�D%q�!���r����ޞ��UAAA�t{zx%�K���+h�$�*U!Z'Q\U��C�W�a<���]��墍��ܜS�M��`�ɾ�)�k�4�̙3B<6璒� +*D�"H�cbb��(�s�������s +��~r�!��!<�t���W��� �#G�:u�/eIT�J�\��CߐV)R�AŲ@[LXR�[�l� �r/_�����3.�Z�"9��鹔V|�B�R�un�)r�&k�˾�yTTa�$/t�sয়~�e/�����ݻl/JJ�\��~����{y���&L�P��C(Pr�(�!;�[�C:J���x��7�:kkk��9*ڦ�NR�|����KaR�$����Ç�Bd��� +Q��8��B%�Bщ}�CsN�6Y=�}�W��͛7���:�L�~W��(�-[��8P�Q��6>|����{��ʊ���� ��PX�02~6�"�tt̘1�I�)��ㇾ�w�;rQ��r�6��ύ5BsU�p###af��� +f�$���#�)���С�; +�.\����.��z�ssN��& �mr_����-Z��~q<6�kYXX �bcc��(��g$�[�n{�M �$j`Ȫ�&�2��W�^(��k�r�i���3��l�٦�������g� +�#N�:E"�����X�nӳgO�s ��ݻwgM0�^� +�T����۳���J����o��9?�Y��+X� ~�:0��F9E�A����0Bʖ-�ҹw�g�>�����u�b�V�\I��=I�-BJ���;���D��˗����HOOG���zh�l�s�cԨQȷ�S�~���J�*�ޱcG�&I�xEF9���<��8���Q4��`=�))) +�����S�ݼy3����M<+����dL�8Q��JY�S��Ti[�8s����U���t6l`ǹ��իW���`=��g�F����Ch֮][�eF�������P�e��������r� +�E�����{��IMM-Z�����_�%�<p����|��?ή�QМ9sd���9::�� �Z�b +�uH�rd�g�7�ĉ�o߶������u��\ +&v�"�\!fXe�"F��e���N =7�Oی�l_���܄�i����5���~�-���_��ڻ +�uH�e�g�ٳg֬YkmѢ���ǡ�7o��?��i�����](���h-�ɓ's%g�2��{\;co�m�٦(L�b�.C�h�� �����t��о}���4g6[C�/_���K�id(��! ����oݺu�~�P�3f��k��l$.b�d��E��[[[d`�.]XX�M,��֑���xo+�"1��zwQb�+V�@v�� V�V G�sF�zs�z.;I_��I0�~6Pĝ:uJKKkܸ�Ж���n[d� q���$�oٲe3d��^��8�|�2�E������#�3��&�V�MEb�����H3* t%K�T��k�Q�k�%y���ݻ��s�d[I0�~6����i[�V�����m�=G��[�nnnn�"�Ak�8:E��C'����ի�,w��E����pVh��b�H�El���yS�k�I��(y���9s� ��-��ޘbŊY[[���<d#�w��9s��jy�P���Fȋ/h"6g��z.��"v�"6���b�MQ��]r���z��@�����S%�h�ȑ# ��%J��x�C�U����Т�<o����fR6��zn�W��Fwg���������۷o �B�(��Z���ё���(]�4���ݻ�������C�*5 +M��-z��%.����4m�y�;wn� +�|�<x��B3=g���]]�ܹ��7o⢕*U��Ҙ�͛#���06��郢Y�bg빖���[XX��}���*�?}�T�paKK�G�,�� ���/���om��8+���ӧ�h��Y�z� _�|���D ��T�<N�={����+v�Ё�L�z����~�z�r��@f"K�,�K�46lȵ��\h�777���_�p���#���A�q�iL����r�R%����dJNNF���������kLRR-?t��auϥ��v�$uܸq�{DK���J�*!ؘ1c62:����Ze�`��A��v��I�s�L��sG�a��v���ã���1hݨ��J�*R�ȩS��0:��,E�*�v�$�d�������~GGLJjp:u�T�Z�0������Ο?��1�Y��P����n���<}!"g>�Z������(q?�%���ŋG���k988�Z�_��Ә�]���=��<[���m&���z�4�O�7�,�ׯ�6o�y��.T�hQ.8mh۶-��F����9�l۶����y�F=�~�����ɓ'���������om�A�S�\W������s�iܸ1��Ƭ�QQQ�u�x��U�r�f̘!����?~< �lGJ�}��0(Z�S�N4����ɤ��z����pmpssC6�=�zn�z�B������������u��b=��;::�o�������3���[䀗��NF�R�|��wH�ʡ���s��q�y��9_0`�� +�8a������Ok�&��=�<3���'�LZ��̞=���[�l���ر���Ƽ{������y6�9u-ʮ��&�",,,��8�� ���2�ǎC�����k�+T�����'�9y�$�[[[�s�������U�"d||<WZ�Dϗ/�"=7Ϟs��i�n�>kkk;;��?�)�o߾��������%�a?�1�9���A��͛s���D7۞sZW�X�bIII�����;s挞RNM��"ˌ������=���sٲe�giEmLt�4����o�I\\��#'� .�S��ϟ��q�����F.�Yύ_�3�z�㹢�Mt�4�<x���L~���?��Ȼt颧 ��k�r��Xz�C���_�߿O+���"%&��?~���ƽ�n�Z���JHLLD�h!���/�_��UZc�y�����y��9ظq#�W�X�̕k���q>`���{�r��:C!O�<zr����sĜ7o�4�����l��+���簾|}}qʴiӸ˚�fh�S/����ŋ�z�5j���]�s�ƍ�2k�˗/��� +(�{�n�������4�����\� �$��8?p��*���ņ �}-rܧ�Q��5Ych�[�=��ۧ��+V�z��*T�m��p�jՊ6*U�$�/��%�b����MI�s0r�H�Ƀu�&���]��ɤI�֯�_��ܢEļu�V��ӨQ#Z���ѣ4�Nu='ٌ����h)���9���W�Z�d�s����c0���ӧQQQ���e˖��Ȍ*�qvv�oDD4~�|��9�d��o�� T,s\V�n�E���f+n0�Ν;�r��!3ɗQ��"��r�ʋ-B��X��ҥK�=x�gΜ)����...8Q�������|��M�4��G@������hP ��Dl7k�2b���$^&�fz.^�hcc�Bܾ}�^�ʋ/��k�5��Zu=��[x����ʻw��֭��mÈ �����m� �1�eYc&L� |S�X�cbbj֬������6oތm��Ν;ɢo��p�����K؏���}]��b�C��7J�c_]����s:$9�H�"�od%�76�����q.Z���O������ۻw�{�xh�����˗a���DЧOm���Ǐ� +m����`7���k\4O�<��vΜ9�����f����,Y��Ғ8�9������飝U�T�����Bra֊���1mT�VM�_�D��_˝�8�8f����9��sɉ�_ +)I�q�9�֭ _��w@���,G�������h߱�~�z�״i�/_�h ���{611���@�����a�� +�<��ҢE��M��Ѕ���Ba�۲���-[j-�S�ζm۰q��A�������W�t!��R�hQA����I�%�7Z=G[�z�4h��v7����EDD�`[�V�D�jp��!C�Q�-�&���oܸ��SSS�����b��C /DAϕ�x�� ����C�/^�������}ذa�mI�9��...,��^�!���e�\@�����8��h�f�hO]�������0�N$=�$�����Bk�\u�p�� +q����[�Yq��i�� j�H��h҇�U�ـ;vL�m@x�5aN�8As���K4�s�x��li���С�N֣���ʼ����9s&r�M�6��um͘1�����p%�k�N�}#4��0�-M���@�������ʕ+�=��վ�%,,L������T��a��~�l߾��J����_�>�ݯ_?ݮ��&0"<~�8W @���¢T�R�9� �yF�Q���z}���/^����ꕾ}�J,����u�<�GF(�`���H�ԩSuۓ'Op��C4�4̐S�ŋ�w�������7o�)S��9߽{W�H ���ϋ^�����G�,Yb�b��u��СCu�H�K)����wE����X�MF���G�h�h���5[���ٳ�R�ؾ};�988X�s�� �AAA���@�cbb�!��$�{��:��S�N���1+�{3gΔ��\y�Z��ӈt0h� a�ȪU��ի����8�Lll�8����p���',��m�8p��\KRRR:v�h�����Tw�!Շ �#�Wd�f�ڵk�����0�|m��/��B����۷���/^��ʠ.{��AA�(QB�c�������X�yeiݺ��Y��@�ׯ�"+����ٓ�\{����͛�����o�zn�z~��m*/`ggסCl@�����I�����~�Ŷ4����U�TA���ӫ��QY%��V��tuue=סb�+W�f�ϝ;WůN��٢�4tD�p�U�u���۷GT?���uY�h��N�:r��Dυ^r�%�5jt��Y6���"LN�X�uZ��}�-K3aYύP���=�Q��*�e`�mۆ��m�V�xy�6H�\�^�|�5A-��� +(`aaq��)%�JO���Y������[�ne���zN��ǣ�Z�ڵ�v��Q���A�d}3:88:�ѣGƓfZHH�\���߲eK��2p�@�M$��9��jժ۷oGc�E�Y�yxxx�^�X���熶-G���M�6'N��.=��n\�^����7nL��J�,�|�$�N�> }prrB�ҥK���J�.j�� �����\ʟ?�����V���ɓ'0V�8�mҤɽ{�LI�ɛ�ڵkY�խ3���,(�j��yXX"����b� +��[P�<�E����L�0��ё�[�~� 6���W=5ju)@DŽQ�4U�֯_?~����@���Yw��q4�C��Iյ����\=��+W�^vnܸqڴixA`;66Vz>lذ,����z������ׯ_�f�>���iŊi��,땖z��='�A������Yt��a�`�o=�U�ϝ;��#�Ï!Y�{��IxE��Y���/��/v0N!���;r�H�z��+4�K�z��֭�'=�e)Q�`A4I���w�����.�^C�:u�M$4��U�V,�j1|�p��`�X��Mω�?���O���h�Q2 +(йs�q���U�����u���n��<��������o�V�_�uh�b���}��I�gqH��x�$%%���B��d��I��7�@�R�ڴi�c���c��z�j$�o߾�DBa~���h�9y�$ڳh�(��%��[�n�����ܹsgʔ)�*U����K�.4P�{U�V�6�ˀ�ˊ+Z�l ��8�{G�~q�A�=rU�G0�q)9t�+� +I�o߾ի��ɓ'$$dƌ��:��-}����1ܽ{����Y�c�"OΧO��b�W�\a=7C=��.[��|\�Iϓ��e��}�������!/߂���/κf͚ ��^�ze�ml�1"or)�ɡ�:u���< �/H�?��q��6l������Z�j�� �����`:�r�J3�-�_���¢lٲ���E��cC��իW�S�g�ŋa��ʕk����ׯ��Ȋ�ӧO��������;u�T���~���:i^�`��]|(M��Z�͜}��!�`�(�g�깬�a�N�R�B4���9|�p]]]][Æ i�7��=z��m!��� ,9*;l���u�����L�=^^^T��w����M���G�_�|�(�/ɺ7n��@.������W�n]a�q���p��+"�������YO���G�I���iԨ���<~��p��ȴy��U��\P���zN;Q�gEz�z��M{֬Y�k�.llٲՀf8�F+wX;���LN$'�3y��è��M�4����*|��n�j�J�eu;�\��DϏd�H�����\`Ȑ!h��o� +�z�:�z�-ԯ_iV4M9������M�rk�DFFҐ���$u���%zS�fMEzNR/��,]�T�r��9������������U��c̘1\��geeemm��O6=��+V�V�RE����ъ��K��͛7;;;{e"�5��9�9빾���l[[[����s*dii)L`����#r�1c���x����z.�`����O?acݺuh�)wۥ��|�ڵ�v�~���c'�9�빁�y�&���Bpn��ܳ$55�f #�4xu�d�9Y,(A777����111rUg��$ @��???��aǎtʔ)S�.�oa�a=7x5�䴴4�8�G��]9���P�U� +4[���e=g=�|Β�˗#�aaaꞸu�V�X�^=.�,�9s&�*_�|Y��g=g=W^�0Ȯm�;V��YR�vm��s�N.t��ر������J�EY�Y��<~�I*^�8?_z%::�<`����`rZ�אZg��www ��͊+W��d�9s�h��ʝ�����㹃�[XXh6,�Q��}� +>gr� +��Çj�ոqc���%ϟ?��~{�術~�,U���L����!U.�MO���:;;�q�����x�U�P�Bj�u��i��Rő�ْ�����A��l����l�2** +�}�]�:uh�����Ç;w��I�.]��Q%���'���ˠA��q/�V��W�6������bccY��=�E�%��Ρ�^mڴ�) ?ܬY3��� ���h.qE@�� S�B�8L�^�G�9x�`l֯_��敏�ϐ!C����c/�����ݻW2�P�`r�o�֭g͚5t�P��z���Ґ����������yBBB�z�;V�S._�laa�����\�r���KǎiY��T�K��4��5k�4j�~~~ݻw����0a·�~��t�۷O����z�}��*���2�F�牉����C�"""�}�3S*G�摱9(ٝ:uRw�-Z���s�r�+b���4:QE_��@����5�s�`u�ر�����njӾ}�Hd�;�v����*�s��e� y�Q�F�Ν��\߽��w�nժj�w�o�ڃ�������Ƀ,mڴ��U �� +*+I�¡C����u�1u�Td���C||���^�A�Z�Fg��iӆ,s�}���.��LԵ�g͚T�Z��[������'::�e˖�?�_���ٙ\0`�J�{⥖�,y��9lrX&0E(W��铳��ɓ'H6�,ãAW�fM���;W��,^��cee3X�1�ܹ1�ʕK=�֭L�u��a��ˋpA�������8C�/}�������}�v��Дc=�Uޱc�Ф��V��CѢE3262���F�O��U�䕛�>9N|~��gZ�[��6l�{�:��j��dŊ:�|˖-�|[[[m�|ƌh8�??�֭[�@�N�:�����:*hu���*���������� +X�5*�|�rJ�i�xh�ӧO���˖-����z�~#""�=�C?.����kM���߿/S�£5��-�ʕ+I̗,Y���/�X=gr�����ׯ_ =�B����͛������L�y��!p@@��,?�����&w�]���;wn�s3��o߾����+�s��͍7��U�TQ%�˗/���oiiy���: k֬A� 3��G�]�h\"o��f����W/q!�СC��X�d �vȐ!��E�r�1`bbb�Q���Κ�Wqrrb=7��-s�̑�y�ҥs֗,�s�As<U�q���\�r������?�obV�^Mb>k�,�<� +`=7C=_�|9u���� +z>q�Ĝ����뉔���{�<dzz���Ja���ob�ϟ��K3W���?��iGW�[h�PŊ!��+{�������e���4 �V��rQ1Bgg���Pa�$�J�)�F٫�����۶mK���[�n��3`�ƍ�خ]��b d���y��P�gj�ҥ��"ާ�b� 5�s�����+W�,�����"�EB�Ϟ=�ضm�d좊B�k֬)�'V�6�5F�Q���gj�יU�VQbr�*��� z��IT�ٳgNNNy���4������6l0�u����:��BZM�EI~���G�Eq�lo��!��k�n]&�����v�s��~�MҡG�X�Z��x�����my��͊�2���o��L#>�%D�����|�r����*UJc=W�uz�ΝJB��*)Y���ݻ���իa�c�ܹs%�\T��p�ޙ̟?_�s�o!�nݚ+W.\w�����h�����)f=g22�d���L,���S|����ߓ{RGGǸ�8_�[�n�tٲe5�s ���lҤ� ����^^^�"ܼys�jՔ��J"D6֮]�F����s1�v�����=����:Ҍ�\�j� +��|-�w����:+W������z�)X���3g����|���蹺�[@ݺu�l�"��߲eKllڴ �0�)��!j#�ya=�k��|�ȑ�GO�>�C�?Y�u/PU +*�|�4Ƒ�'?#s�^Ŋi��kײ% ͚5C�u���[ƏO�,�aߧO��nnnȖ)S�HDX�%�a̼���ŋ�Ks��2a=g��ٳ���F�R���5d����c'O�$g��j�z��Iv%�ZժU�F�#����D�l����gJ�����]\\,--�ܹ�(̛7o�$G�O�4�sl������ȍ����]��<��������?���#hڴ��β��<�w�F~�l�RI�^�z�Ƽ��y��1ˠA��}��*U� %�����&�����իW�G/�Y~������ܵk������4~C�o�]Fk�Aύde�%J =�k�f=7==�����&�ݻw�N...�>�<x� ����kךsF�x�Q�F4�|���F�*r�����znHv�ܩo=G�/$$��q4mI��:dذa��ٳg�= +�'C�2�\JHH([�,=\�Ν3��������0��P�B���,qww�ˋ�L�8Qp���!lQ�fh�b�<==�m۶0 1߲eK��gΜ�W=�����ͳg��3��)7�U�R�J�z��ls��~˝;7����9f< ���u���ʕ+_�<��!=<x��N��6 ��5j��Rυ �ӳgO��ϣ��"""�����988�Z&�|)�s�� ���� +s�Z���ڳg����߿�1�$90W4�����666VVV�6O%G�dܸq�/Efl�h��96��aaa���8�^�:6���S�bE���ԩS۷o�f���������&���N�����>V�qz.���Y�?=�[��qf#�;�vvv�?��]��#�y�ر�)������8W�\���F��'N�\����}߾}�D��[�FFF +,��X�t��'K=�����Y�f:,�ӧO�D�h�Ƀ������~����Q����ѣ�ؑW8���]*>$����Y�fM<)��퐐�ǎ��}��A���ݷo_ww�U�V�.� +��w4)�����ϯs�β�;wn�ڵ��-��G�V�ї/_�*E���,�t���,\�0j�q&�����&�A�QC��:L�8,vggg�L�궹�������>|���8h>Ϛ*z����7o�܆�ղeK��j��hN�;wN|H8��������=jҤ ��*U��"0��.]SSS���`�b�loITeʔ�)8J�����t�5jP����|=�<O�<���H����Ç#�K�(��3��+V��B��<x`��Šu��0�a�W�PA��)����sL=�Y�yxxx�^�Lu�bZZZ���gϞ�̓���k�d�g����Q'������c? �,���´;:v;��S���/E���*�v���-`x�|ԨQ4#Fn���:u�ܔ<%%%44��Sإj}�1<���ׇ�����*TH�A�Z�6��=e��_�X����Y'w|��dƷ��ϔ�:�i�G777X�f�Щ��/�Hn]��`Ĉ�Ǐ�0a�%�$�y�ƍ� �yS��Ȅ��� �Q G�� 7���ϻw���a�s�,s(���y��E�[�z����իWi�eyccc�?�Ԍ�^��'����wEIÆ������Se|,OW ���K���Ν����c��9�X|���ѣh7A]q � �ڵ+��)�s�Q Gnj$��0�:uBRq��?���U��d;aʔ)cn�wB���P�9eFr~�znTz�dɒ%J�5��?���?n�ݛ��A/������{E��,e�MBƚ�7P<z䝆%��>���I�&��F8ߟ�:�}�V�B$���\����4���3�r�Sh>Zɒ%�jʌ�9s�9�˓'O�{��V��zn��[����r����۴�َ +����Z�h�"�!��"�G˖Ev��G�N�jmm��S�NN�$�:��Ʃ穩�J�h�{��|'v�����a=����Zv��+�V�2��h�_�}||P�p�'N̉N�?|�@s�XύS�<HX$��jժe�}�� +����7�|#� ��a��e��$֭[�7o^�r�r�h�XN�{�������$i�.^���mݼy��uI���5��+q�"��*]�*�ܧ��n[�Dn�.��7Ҳ�O�>v +���dա�/_�RгgO��Y���zn�z����4==�˗/4�V}ݺu+ۙJ��^�z�ũC=� ��z /P��2m�����q5�����Eɾ$�HT�0F%��-MS���1Jֱg��� �gM&�>�}g� ��l%k~�G���8�{o�ݭ{�}?���s�=�}����|�^���ڼ��y����#����H�-S�̖-[�^��۷�,mڴa|��|NX�n���˥K�( +Ihh(#�B��]�T�{�yR��|��1r�B��]�$%%���HpoXX��;w�~��V<�K��ݶH$�~B���ק6����_*I�]�tA���ٓ�����*U�ষ���gdd���S��ԩ�L���1> +�CE�={6�<�j۶�N�WL?�b��%��|-�w��c|�,�|:4Z�Z5���LJ�����t���رc`l� +�����t8H����s4:���.��Q�\9�������S����X�rضm�8�Z.�K�F�B�ƌ��\(|���9�J�*-Y��1�|.�M�k�S$�d�HX�T>�z�A�RRR�̙��G�ϥ��A�E�mrS�_ˏ���Ӯ6n��ٳg0((��=E��0I�ӡ�d�.|||P.�h��\|�e�:�s��z��-_���yQ�\���L�)��]�@I&/.�J�������/_��ݹ�J��E:$\Ā��%|���%���Ç2�Z���� +�&�!H�KJ��bccmllPR+++Q�����d|1>�~>��N�^i��͛74?@D��\I>��"��%Mb��95�o�^///���n[ +�sgg���@(��"�qpp�ݻ7�B 6VL?<x0*�N�:��c\ S���"~�Ν:P_� &�a���LHH`|��|�쁇���Ͽ��mht�s���|.2��>xX�®Y���|R<�G�����TA�B���ٳg����� |$*д{Yξ���x���͡MI;uٽ{��e�����"�����ڵ�H/^�x�6��TÃj֬��P^�x!ʺ:z�(�3100=z�����QR'''�����������311A�,D��/�sʌ�Ս�/_���q�*�߿O�@�4iBSv"̍�}�R��ƍ�;wN�ML�漽��k9�?y�W���͛7�;w�ֹ�3p���;�����7n� ���*��,_�|Y�jUٲe)�����]�x1mV��/8::�/_~��팄UT&�[�|)��������-3T/\�c3�s�2C�ҪT����ãG�� Pԕ������ 6$���Wd�ǰa�P�+V���ySSӊ*E�E�R���ᴔ#��t��u�nܸ��9Ä h��ʕ+���&&&�ڽ{w��z�����?M�ԫW/11Q���Օ�O���������J��D��&�>}����>|�H�{��Ց#G2>�qDEE�i�����` W��Y�f��������D@=zT����͛�**���~��5�@S��Y���)2�MKK����d����:K����~�z�4��b*�-[�U����1B��.�p�0�FkѧOZ�RF� ���Y�Ǭ�,;;�9s�p�.-�ǎ���>}�n +Obb"�ND xyy���\q�<y�u��d纺�^�vM���ܹs����vb]4�wOɤ(ly� �N�J}�X�/�`�R�J��%q{#) 4�п�&M��lٲ���7nt�֍Z�V�Z;w�dt�a�·�smË/�-�t�^����&��S���2�����!C��:�"�6�A��uv�"��CaJ����hh�EFF~����0e��Ɍ3�k!~��g�HǎU�&���I@NE� ===T����cllLݙx�}��"X@y���I�h�dɒӧO���������Va۶m4W��ݳ����X%��N�dBg�w��IdN^Y����� �"{����A�P��� � S�!��5�s���g��(�u����5�������3��ׯ���t\���]�LASF������1k����-fffF'�k(���Z��������N���r�F�N{�I?oԨ���'t&�X�"1y�n�._��ȡ �={�\��W��ZhΤY�㭫�/�����9i]�������� +�������&_�dI�J��ɻv�Z�:ªU����k�x�`u���ǏG���]d*��(癙�������pC������gr�����DPP*����\@�����5�����߿_*��(�o߮U�W����_�tI�y���`�GL~��F��U���0>��ر��S�J �ܹsU�Tٲe�Tt1)�/_�,觭[�ҙ)R�Ǐ/��bP$�����������?�ɋ���<H��B�J3hh�iӦ��Czz:���eJ�&���ի2�$x{�ȑ�Z^�F �_���ʕ+����!�D�AAA�^�-FܹsuX�fM������ѣ��G���̙3 4��TE�r�.]�t�ڵ%�߾}�v��Đ!C��j�2y�СN�:�nkk�S��-��ݻwg|� 8w��������+�����?y�$22�����ֶq���ױ�ptt����gppprr��D�T�Bǂ�77l�@�ij����s�;������z��K�,�`�� A}Λ7��y����ύ5B�Ϟ=[�2��Çu���@}�9L� �Q� ���_��w��)9Ѣ;���|�4������E��_��A�oӦͶm�t�E�:��O?�V�=����A�T�͟��gϚ6m:f̘���x`bb��� 5 66�رc,V��8{�l\\��ի1&r�>`����/>Ls@Æ qf���/_^(�w�$$$t�ܙ�R��� 8�R�ޅ���ŏ6���X���#Z�揭ڃ��ܘ�R�[�h��{��F���9w���F�l۵k'�8++��n�����ޞe5~�xA��OOO�9s&�blmm��/��6���Ө�f͚�o2>/t�ޝT5��^jj*m�ѣ���Q���stu�.,Q����|4nܘ�|k3>~��kN�:QHJ(*�M��-�����\�سg����Fk�:����*A�ϕ�s **���D__��w���L^�dIr��y�fHH�����'O�.)��kK�(g|����ju��$N�:E�d�����|<5���M������;v쨵>Ӟ>}�t��-ZPV�����߿�)�C���Q���s c�̙��jmW:t(r$���+�� �K�����ٳ�w�R� ������푍W�^�Y��}��4�ԭ[wy�r�Y����CT~�*U$�3>�$=z#}Ak��1ʀC����k���U��@�N����k�a۶m�+��<t����Ą�l3jԨ'N�N],زeZ�W�^�ϋ}��EmC������ٽ����J�|�ر�_ɹ�}������/_nذ��חsciiٿ���y����]�r� ��F����?���ȑ#��k�q��J�5�JM�#e�0��9f2IF4�s����Y�P��� B��6m���ܠA{{�:u��}������~�|�?^32����e˖yxx���@ޣG�;v��(�D�H���N>�s���ӦMS7���,6o�\|���G�G.�f9!y��06V+�.]�U�]�#���Ng� n�n�ʹ�c����[A�Wk���Ǐ-[����fq399��S��:Ÿq��?q/���@ہd?~_qݫW/��G�J<�����������5L�6m��N�n�Z�jդI���~�bbbF�q��i.��1�3�mܸq#�G��3h �߽{��?��ٳ'�S!T�V-(((11Q�eUg�&+h�V��pqq�С�ӧO_�zթS'dx̘1_�a����Ľ��� +��ѣGm۶�תU�����?�� �����sr��O�r�xdd�رcq�O&sVV)�2�����>�zg��� +�s��yff�m��}���8���oڴ)l����3��r�����`7 T?�U�V�o�g��q�_�O�q?q/���"�O�74H<�=)��۷oǸ��8��?�lO~:��2b/H?��%Nq�� �������W�0`���=�"����A����@k��+�ɴ��!� COOO��J.,ƍ7q��I�&�Z�' ����_��������Qe>� ����w�Pi�n.W)));v�}~:�J�����K�(ahhx��U���G&FFF�/_.q�зo_�\�v-j���������-˥�`���$��W����i���ɕ%w���ŋ��_��x�R����fΜ),>������O�A��jmmݳgO���)� p��Y4b�&M +�Z��eĈ�߿�t�rغuk��F�л�%~"~NNNFP�ggg�#���ڹs��ÇO�:�ШQ#�(s��A�3g�p���AV�uŊ�e�=�#G�,�ʄEs��19c�h�ϧL�����I�'�Y��cݟ�9,,mѬY3��i�PP>p���K�9t�:���Q�M�III2��nN�<y���%K����iӴ�ϡT\�paݺu�Ǐ��R�bE>�C��W��s��ƍZ{��A����MAS�s���k�s1�XXXo�ݻw�@�[�.�:22����-ui��q����t��]ߐ����tv2::Z"ҷ�ΝK_�̙�϶4��۷�8����W�}ѧO�����鵷��>�1x�ڵ�{�"��c�v����� Ӳe˶k�:Ɂt$F��@"�4�sM�TPm����fff�Z�!l��Bc|�eXO�̷����w//��7��tP���NГ����pww�͐����?jÆ �/?��U�繹�Y߀��{��[��?�g�X +�8���F�o�h����F�`�bx�?>F�Ǐ3�%�={k���b�k|^\8uꔞ�*_K��v�ҥ�� +�sPDi>Y3��4��u�V���߰i�&�LLL7n\��͉�k�0�ϛ7��DP�����⪉����),m�F�Z�hQ\\�u�GG��_A T�|)�su�Bt:-���ϟ������94OWWW��S ���v~544�Ϸ����W�T,d�8|�0����+��B�ߜ6mZ�gf5��+++GGG��СC1 +�]��СC���cs����)$j!�s5�[�jU�ړ���b��@�43�����Ȃ�C˔)���֫W/�Z�fM�z(hmT>p!�� 3f̠�4mN���+d��9`��%J�o=�?�r���s�Ν>}���ݻcbb�L�<y�ȑ������͚5�U�9� d�������� �`d��|��J�*����"aȐ!�<5�hsժUZ��3g�8P& �Ϟ=��z(疊��e�c�n ��dh��W���W��N�q!�_�C��>���t*�a������ nDВ�-�/_w�+@�}��i۶m����{˹Xu������'N0z. +���\�عs'Y�Z2���ѣ��p� ��[�n���y"A�'��ΆN;u�Th�NNN�<FF�Ę���{�� +2���}��ݹ�}���~] +z�k��az�� ����ijhD���˗/qqq�<�Y�u�~��I���1c��r��"; +i�v��ڵk���\\\$ܭ���0`����U��5j�hӦ z�ƍ�d�طV��=-����-,,`��~�Z��ﳅ�΅�k�]�? �,2�����5�[:���C�(�qq +��h�"�A���ח�[��o�/Y�DZ���Ƌ/���_�)`�:u�=�СCJ��G�$Bϫ:��{��Eyyy��X��ﳅ�΅�k�]�? �,2��pH!-������R�۷o�Wrj�l�2���>}��O���v�)��uǿ��ի*U���<{��۷o��/^ M �%:Őaoo(M�tG��Rd��ݽU�VЦ�u���\�ŝ���D1��(�����[�l�M>��l�s��Z�_�E�7�L�0|q�7��a�={��ۛ�V��� �ӥ�p�������s�s>nݺ�����555�B�u��"���|Kݺu�;H���sX��}` ��s�K;w�|��In"Q��\�ō�@π��f(L�2e�|7�����9�-|w.|_+�k�_����Z����hE}�H5Y����w�҅�6�(QbȐ!�����566��~�ΝB���9����u��u��fBX�)D�;@��ڵ+���p�����ѓ2�:::D�2�o��]�? + �°aþ��X��X���XT&�^c3�/^���!&/U�ԤI��y]�M:�L�xs*�w�͡���a�߳gT.t͚5g̘Q�?��ÄH� Ʋ��-��>�ׂ�s�K��s���, �oq��Z��GA�B��}���� +!��Jp��u�"��%K�+��9��p��Ń����{y4.m��/V�\I�B.�~����u�|�Z�8�d�z K�w���+i�< � �\��Rh���V�Z�����K�Y��={�䖺����V��y��?W�ɠ&�ᇂ\� +/_�=z4��#&W��F�J�*U�0�}�v����s:��m����666D�...�I����kh�v��ĉ�u?�sM�Y�f�ɘ���ŧO�"##˖-K'�Ǎ�7�C�E�AAA����� �K���ק �!77w͚5Њ��+W��`����l9_��������)���AP�U�Qy���s�!11�Ng��@�?��Cǔ�8gjj����ԩS�i->>��:�|����aooo��}rr2D��T�+Wn� 999� T���O�����*0**J��2�ѣ19(];�}||(�ORR�s��9����x��%q�իW}}}��˗/�h�"�%FU����`��5�cǎ�+V��rW�yyy�W��mNg"##5��?��8"A�ϕ�s�&M���\�r�B��111�y����d�j�����ϕ�m������];R����ϟk�P �����-Z��F�+������;����Ϣ��/_&��VK�@ +`ԨQ)@�W�+��ׯS`b�G�ė/_�,YB�9*W��w5�<�wy���B;LLL����͛c���|�<((�v���r��)?���Z�F`` ���^�|Y2�`|�1���o���B��U�V�����b9!���."E�s���D]կ_���2"çO�.\HS��J�Z�b�~)���ꠢ�-��J�,hCCC9w}[�l�.`gg�����"��|�~���GTx:��Փ'O"##aG����uF�r���>���� +:Hh� �����pss���HCN�F���nݺ��\c�?�w#�ȉ��R�i/�Ү�d������t�� +VVVL �v��jժ��s�ҥ�>p'�ڵ��j�E���X�ժUC�)��s��U�իW�|F�U�L_�_�y=��#*<q�9�&�Z�'C���/����X��Xd'$$0>�(���!���iۃ���͛7zL�U���" �G|D��#�1cj��ɤ��СC�+WFcU�P!))�UH!ʹ����3�s���₪[�n��)|��q���4�2r��·�K�*�p[$����t��aaa���ɤ�����;v��XS�L�Me�sgg�"�!b|�<N�<I�&$�_����A�J��oڴ�U���"����B����pr(���N��۶m#�_��-�犁�?͜9S�ׯ\�B�=�T�r��9V�ʀ��Ze�!�����K�ڵo߾�*�k������+��x����Պ�7�%U�dI:zɎZ(��q�Rw���*D@HOO��?+++�]�� +��Lm�� +`ʔ)���*���A�����#�s���k�P�t����g",dggw�֍�?��kZ����g{{{%C�3>/*>}�Dv�S���IN�0�~.\��դJ�|�rT���>%v�3e�a����/���l=�]��вeKea|^TP"���|�ϓ�q�F �S~��t�H����F��J `���ETT�NWxMJ�x��u� +P���D����P�%77��Jss���x%���^�zebbbii���{�B��A{�n�:�hİ�0]+��q�P�Ν;+���"��Ç�*��3��nnn��#O������������w��wÒ�����ܨQ��Ǐs|>r�H��#G�@f��&%%QX�b����\��<�z��ٸ�8q"�R�b���FFFhDZc��N�o�RC3Q~���"a��鴔)�IqE+W�|��5e��jժw������ݰ���>x��ѣGm۶���;f̘��QAϞ=���=_�Z5!�Lr�z��|�w�v[[[��O�ؽ{7��3�@�ޔ)S�O��y��z��.T�<Ͽ}��e˖x�f͚���W�߹��|�,|7,�M�6���������G|J��^"ea�֏0�qw��ݕ��� عs'M��)��Va�֭()t*���c|.?���)��<�u~��'<�!@%�t�Y�c�N?��7n�ĉ'M�$�.�������t�Ppm���\�<x���;�[�f�*t���_�����>:��K>���*I������q��L`K:�I�$*�s�c����d''';���gϞE��z��Ļ�����ٳ��.�4�aÆ�z1<IPu���}��L\���s��~��G����P�PFU%��\N<y�������$33��'߿ߡC�j�J��Afu�z8�7ss���T��6oތ��U�Vvv6�(�#$$��)?]���x�"F+##�B��2>W���)�D�}���vD�+WN�����ʕ+t�_�Ѽ�<3~1b�+����;::����Ǐɏ�jwd1>� 4�g����B��� ����·ݺu��� +�f�m1��^��]L=z��Υ���rppP����rꄤr�����h�d�N����ӂ��G�n�����X�%RRRX� ���eʔA�.X�@%:w�����3gT�2�sy@~W��� +yfǎz�ذa�1�c�4����&��=r�H�,/��Rm���ѳ���Ϟ=+���}��V�i��s ��v^H�P(���TtVc�Żw�ƌC�=�O?�ܧO�bjj���`ň��Pr����A���(H�&M���\$''Ӗ�B�A��:|�pV]*D^^ަM�h�.hyɒ%E�A���N_�~ͪT����Qk�Ogk!��9�F5�|c|�]2U4u�T������"���̹� +q�� ��J�@�=�������.4Aиs玅��±5�7oޤ�+t��Z�����֭[2��_�+(��T �~��V�Z��,R>�x�61;v$eBDLL��x�ꕰr��� +W�V���y�ؽ{7� ��������eu�}�kРAe˖%�utt\�b����|�E��n��m�nڴ��9"ڷo���,�<�������vvvV�����p����~d�M9v옱����^\\�(����#G�̟?�]�v�R011�ݻ7�VM�֪U�jԨA�enn���aÆ��4�B���W�dI�;͙͞3�V�LUy�`|�ᘙ�<y�D�'ܡ�-:�{_1<����ӛ7o�l���/?���Q%��������_���.>��w�^09ͫlmm1�,^�������cNw�h&��,�<��`�֭�[L�X6�ϕ47��r`��i�?A���((�ԩS��.]���������ָqc;;;�2� ����kkk�o�]�6^l9�������f��:bĈ���I�&��cٲe+�~����صkWb>�T���$�_�ܹ�����H�>q�āv���eooO[�%`aa���:~����G{������M�6��F>J�(Q�^=T2~;v�ܹs���֬Y�2&$$�S�.v�_ccc���9���ӧ�VQ�� BUw���ެY�� r-�֡f�/�7˕+����ťcǎ�*��Nݚ�6��I�&�"��g������c|^h�K�O�����e1tN5Y�111������˗����𘟟���7uK��y�tr�\cƌ�]���k9��:t�<y2�]�� +���J�Ha���w23>/���4M���#��˗/������'%%���zr͚5%�mٲe�NC�5jԜ9s@;�w�ƿ�;wJƔ�|HX +�x��!33��7ܾ}/Bm� 8p�*%tTN��5kVh>������o>|||<���u���ݺu�3��?{��U�V����ݸqCpg@rrr�_��J���hѢ &�K���e��ުU+��;~��矩�04��N��ZE�B�FU�ٳ�~���.p-�֡f�X�E���g�0��<y�:2�������b/��h)��l�Em���ƍ���=}��V�Z���t=�TJ �%�\*��+W���ӮHB�5��� }R�ڂA&�� 3g��r��Rv�555566~����իWD��4��0>/@�@�ߤ0�h)�xE�zLQ�i_T\��w��a�Ϡ���p��|�;nٲe�_����ߴ�\6S:�`oo��)Y��E�#����0?r䈾�>�����J�[��ӓ�^�z�/^���V����ŋ~~~4���� +%Vą[�,Y*���8��Φ@�U�TѼ���\&�gKݺu�;o߾��������+9RL�2���+�^�Z�eA�ͤE�-[� ��0RQ���c'�a�:ƏO�T�q�$L�ԍ���6�*UJ����TKTt�y�֭�̥�g1>/.�3�Q��iAc)����͛v��!���ɓ1F(�NDD�۸�][���P���܊�T����c�Q�?�*��2y�6��իW6###T�T�ǏoN^�~͑yq͚2>� :Bȅ��t�2s�� e�W�ƍI-W�)7(�����C�A�qqq�G������ܻw� DGG���;�5:~�8��6m�` �^�`A�&M<<<���[�V�Z�kBB~�?L>��'<�?�~�>��5읤�${{{0LA�4����QԡM�� F��t�V{Tt(HŘ��O�R�YT�K`�ϥq��E��C:>�7������www$R�N�{��)�C Jtqq�g�N��� iW�իW��ѻw�����������i۶���ܰaì�,*8y=�'I�a��a��k� �xy�ӟV�VMZ�Hc�ȑ#ip?r�,5�8��NNN����a��?j���.�5h��ʖ- /��G��D��n��Ŵi���W�\I����F��U�D"�E`�$�i�8�$L_�6m*���Z�l߾��k֬)���K�9���7�P����E��Dt�1c��b�СgϞ�S� ��;��%[��&1��?���Æ k�%7�d~j^���M^�4����<��q���@�3|��� +'x��i��u��9���y�u���۶m�;��]�&���d8�& ++�8)9&@;���� +���y��4�K�����g��<�-������cA����D/��ǏD��qJb�*����H����dɒ�����Zb�ɓ'i#���w�Ν�� ���K 33bojjJLE1�z��$u�6��W�^����(`hA�~ݱc��z)A20�����Bh����Ν;�������OHpŊHz5��4|�Ô&�ai�t�~jݺ���ߡC����{���ŋ����ƍ�8q"�|�S�~A|�Eb�f͚!�ׯ�X{.�m���3g�4hP�8 b|�]P@�v����5��đ�"�ȑ#4��N幽q�,Mmva��(�a000�yu�8%'��_�5h��K�611�,ztt4:����5�_o߾�����A$.\�=�p��A�}����(Z�pM+���^���˄�"L1�1QN6���AD�x��5T/u�)��ԭ[��jl�LN ?��h֯ �+WF�\�r%>>��M+G,add�HK�1]Fbb�L�Ϣ͎�UwڰaCɒ%)Ґ�b:+��{�"o^^^L�XӴSַ��#��.]�L��ׯG"�o���x���;SSS33���\Q�СC�4���_�z��L>:��u�q�Fd�&�v��?�@m���w�ڵ��Y��������C:111�n�͚5�@�>}Z��#�K*�7���D�g-,,��im 0>�C�� �9�ݖ-[�7--MzÒ��ґ�)q��u5城��(p��W�뼅A� -�P,!��V��xR}2�a@2Q��+W�*��o�Sl�6m�ܿ_���f����L�a��E�͞=uҴi�"���ʲ���3g׃�-A[���cǎyxxL�>]��>��>�?Z�>�}���li��]���R�2�1�v�`�իW'w����ת�Z2�����էQ�F�N���S������ҙP�5C�L�2t�^���?~�Ν;���>|�AA'��^V�����q�[8����ݹ��Db띴��%�Ĉ��50�c��ϥe����V&��>}���244Tr[��Ǐig��n�D��s ���;wƧ���g��q1����G�M��M�~HH��Y�������ر#z%��x���%<�p�9�s)�ϥ�~��/�&G4��Ļ�N`о#F�8}��2>�$d�V�~��G�ˤ��u�BmYa;VmbA��^�Z@aA�͛'�U1���M�6)��Ʉ���J!$ҥK�A���wq����\�s��s�;�lFA�d:��X�i'49��%ޕp9v�د��i�����; I@ǧ�3}}��?��b�ܹ��uo߾��f``@����A�����R� `�<www�ٳ'�d���Hs,��9ߝ��HOO�����lA/ +��59��%����!4魼O3�ɤ���A��*��K��(�Ӆ�X��3g��`m�?���z �:J�+HR�,�Q��㟗�ג%K�$#�eE�a�G���\���'X�%[Ћ��s �h��oA��5��<2��f��I����t钜}�<,�G���8��\���U�@� |Ŋ�<)P�:$>EH����&=��.w}��A�3g�(��L�d���8=G&`����R +�ݼy�f����]5O�S�"���5kxx� +G�+B��XtA&�n݊bȖ���ׯ/^L�W���-t&'h�����Ǐfff�+##C���!��3/tJ&?~L���};� ��+@˖-w��!&'��C�v�ڥˢN��U{N��1�A�Tt��$�KMM��� **�Q�FTv�=z�6Q��QQD�m�RRRԡ1�A�Tt��$E�9rd�Ν�����ժU�1cFzz�XK���b^�xQ���)U�\Y�Ɇ���1�AK�2����kגT���i������/������Ey�7&u�"//���iӦ�Cb�9�����I5�����V�Z�)���ULL��(T%J�@���\_�x��Idd���'F%n��w�����������:��d��$_�~����ˡ{[[[sI�Ӻt�A��#{���t�Fp9��� + +266�����������eT�r��]�669!QW��������7eʔ:������� 2dϞ=�vJ�;���tDSSSQ�Z�j +�)))ʑs33�aÆ8p�{�߿g�R�9�˗/C�iذ!u��:T^&MLL����͛{�ر#���ٳqqq�W�Ƙ�q{߾}�?��o����T�"1 +�N������|�%&&��8q�mѢ��@*�����ש5��ׯ���ڵ���3��e]i���G�9s���|�]'%%���ё �*U���u ;w�|��Q��2r�H��|�r�C� �ۭ[7��*88X�K՚t�J�*QŲ�PL&{��"�s�s����]��ʊ�oΞ=���;w�����eQGDqŊ(�aÄ�a:�ԫW/���r�:u��3��ň�/�P%Ȝ�|DEE���(,�@�xzz�(N�<�9s�P��P��۷o���<��ۛUE�djd||�41>W�ρ��+,�𮓓��Hc`` ����"�C�En#""�� �����:DZ�ɠ� �\��\y>OHH(]��b2�W�:�ʕ�i���Q^rש���˫T����[U+ +���P�L��@���ρN�:)&�tT �d7(��̭>��8����hD�PrI�F�mڴiܸ�ƍ���!C���E �A2imm]1>W ��;Va��) �Y��E ]��à�ڵ��������ݻw�M�P릦��9�dݺu����g͚��LB���ӧE�s�K���������Q�6�3���/8KJ"dE� ��POw,XФI�}���urr������Ir��SRR���5jD�OqݫW/��G����z��ݠA���h�b�פ�$d) @:K���dl�V,]�Ta��֭�ݹs��{.zJJ���3(Pϟ>}����|TVwwwr�$��7 +�)������E���_�V� + ����wυ�$1�3��C>�����a8PHe��;�-���E��#F����������l��\��Lӹsg� ����]�v�ߡ�B"�ӓ��N���Ϲ���4j��...��p��I� +��B���\�|��→�u�BX#�s-�g0ytt4�������_���O�3'''==��֖��ʌP�ͽ��H�+�2?�=������������۷o�L�L���,�[�Yb|.t>�#&L}ϥ�III���8����t�� ��N8x� 2i�\�tRzzzVVV���0�J��G���x�tr;;;.�ҫ�4���O?���?ފ+z��M�J���羾�x��2��ҥK\����d'''$E{n���Q��;���1i>��JY�ٳ'��k�ׯ_4{�l����ŋ%��o߾���jdd��?����&�Z��}�\�T)��̙3��ϗ,Y�wG�-z>�X�"J���c����s(�AAA��S�>��իD�����ʕ��.�t����w�ڕ[����Ġ����gi&6lؠ@�4+eXMY�M�ԕ�|ܸq�R�sl���˗�2Fm1�֬Yñ.��j`�*U +�s�/~��ɓ'8�|�A��f>���»Ç7��z� +Ŵ���:����������g|�\nժnr�{������o����qAI�M��~���\&�Ph�:������Q�Nu� +�C����_��g�o�>}8��� |Z�.AZzA|^Ћ�<��$A�����ƻ�����s�y�-^>�n۶�t�B�[��'���$0��I=y�,�5k>�2q�Dss���L��yAL^�̹ή5hf������v�G�ϊ��i5���Y��-�I|�p���7mڄw����-��3C�}��N�>|��?�h+���B��9�8"M^fR���'M��a>�]�vAL� ����y��_ 6$M�~��|�]� �/ *���ukA|.�E9 �Z���bx�s����s���(^>�����KF��� �o��d�Bz��}�С3g�p�/3)��q�,,,��8�>|̬��ys�)�B��9�����E����s�/�����j���\�2v����rΟ���� +�ɓ'_�P�|�Bz=��%W��Я��MMM�|��Ϸp����S�ë́� +�����:`�� +%��롺�繹����` �Y��r���o��h +������i�".��+>�#1N�5J4롌��*���]����&gV4�����_����1c���Wԅ��ӧO��j�$2>�M�R�~E��l=T��L���^��'b|���+j0�PƵk�2>g(j=~ޟ�9;O�aԨQe����3(V���b|ΠU|N�r~3ć��4�jժ��Mֳ��\����&�a�0 ��9�g������ӧ�ݩS��U�R��ś���7�S`��T5ś9r$�]�|�X���~@oݺ%�l�xК���u +,�f�\�x�ݻwǻ;v��>y���P���r���2���C'bL�>��6���������;uꤰL���pg�Ň�k��Q/!f~�С�|DDc5�ݻw666�����AN� + +b|�&>OHH(]���2ikk��w�(ŏ�JmݺU��?u�o߾eL��f�oooVE�I++���x����sZ�SX&MLL������'{?~���422���B���Z�W�^��TBMfffP�.]��j��2��Ꚕ���\�|BVX&)p����(��S��� �����P���`�J��|�r�J��bYm(&�=z���t������ի˖-��L^�v �;88�R�( +� ]���ccc��ˋ��*X:�ׯ�X��ڵ���3��e�E���Q���9�Ű�0���L&&&"QJ]ݺuQ��7o +� )))666�gذa�w�(��ԇ�ϟC'��� O���X*/�&&&�����͋��=v�#j��<..:yPPP�ڵU"���':t������E��ԩ#��ddd��I)"8::�X9rB���ׯ��TbP�Lr���]HԕJd��_ER����M��^�<y���ikk۸qc�)��s(��NNNf��L&E)�^^^Hy��3�4���,--1���`��H|d���o�Y�.^�H1��<k����{w�(�Ȱc�d���E_Ҝ��%J�o����h����3yְrN|�Tt-��իi�Q�%bTMy���W�zu==����3y��N��� �)S���ڀy��A CBBD_ҕ+W��C�Y��G��UΙ�Π= _��-}I� ���X�Bd��ׯ�Ä�X�s��3h���!��w�}I�4i���={Vd������ݻwL��K9g*:���^�z��ׯ���999���%J���铘ʵx�b4ߘ1c�$�r�Ttm@nn.X���Td,'�#G���41*//�nݺzzz"8�/t圩�Ŏ'N��їt���(�ĉ�T(8T�rN���Tt�� ������KڱcG�4>>^L��ի +�y�f&�S�9궶��X�0�<<<����U�A;Ѷm[H�C��]���ߗ(Q���$''G4��s玡�a� +>|��$Y����9sys��mr4���;V�T)6��P\�ԁ�,--E�E�����h���b*E6�1c�d�)�vvv��th�8�X�:�Eg�<���!��}I���H�M�?~ljj +&y��%�d� --�cr�6*���~�������}I5j���?^4%"�-�db\����u�1h3����!(]�*==��U���4��%KB?���$�x1b�����HVŅ/_�8;;C�l�"��.Y�%=z�hJD�+� �$����ի� +��� ����.�ussCa���D��[YY{�Ir�#33��������Ǐ�64���Tsss===�P\!���000([��hF��~� �S`` �d-�(�60��� 4Бm-�%2b�q�������&&&���c¬%�)��Š=���C�.](��۷ou��-Z�@yO�8!��@-GqƍDŽY{��ӧjժ����1��{�� 6���IMMՅ"����ϟ���/S�̋/�<k�-[IkҤ�b~�jԨѦM�ƍoܸ���{|��͛3�0�����9KKK1m�.S�L� Jrΰp�B&�Z��[�3y�d^���ݻwj +��������*W�a��K�t��U�R���0--M�ٷoZ�z�깹�L���N���(��JW�J��w8�<t落�}`` w_���:������urr������;s�������)))��5:~�8��u�^��=��~�ݻw� �����kRR� �%5�͛70����@�ڵ{���}���(u���EP���l[[[gÆ L�����G���u�ͷ@�www'�|������e�yÆ ��������Z�jU��ڡC��O�"�N�:�T�Ԑ,=C_;�{?��p��D0v�[ժUcM�n�~�z���e˖�����GEE��t���m��pI{��u��Q�F������-[&cq� ��ڵ+����o�|����ݺu�J����j�j� �ͦM���7}uqq�?�5�QX��ZH�T�K�.����)Sr��_~���'W�^�U{Px���&&&�n�b�值����E��㓙�Y$>��M<�Ϝ����t�e��?|�_��)z,^�`W.eOO�gϞ}������q +vZZo߾=�1i3��+�DoIg�AI��>%%eڴi����Wg ���t�R�����ƚ�`���kcc�V�X��%K���A�-?���z�����b� +�{���9�� ��������xQ&�C�ï�[����KNNvrrBR�F������w���c�|����ԳgON�gPo9{����=a�T���)-5w�\��:[9�G0��-[V{�#""Ц�8��Q/2@q�;)�U�T��?�q�Ff&���<��^� �9sf�֭���1b��� C̊2�022�ȓ��jv��[�.�n�v�0n2dܸq���|���+W�\�f��|���'&&b��p��C\\\ll,��0L�:u���]�ti֬mV��8X���g���aÆ�C���~ɒ%� 0�X� +�Ν���Nj``жm��˗_�|�����<<<�ԩ�k�.���Ń������������J��i���8:;���� F7� -�z���xf1.]�4f̘�+r���Ҳs��!!!�V�B�}�� +z���ϟ��ǹ|9r$Q +III��ڵk���_vv����{�g���DfTдiS���Ǐ���ܱcJ}��E(KY��;R�8�� `���7o������������7t��{C�1t�Ph������Gǎ1�b�1��C]��g<�믿Bی��g��ӧuj�aQ1p�@qz�1cm8g��а�G�����^BC�Y�|���뻺��-@���͗��t�������������B-�D�H�e˖}�� �- 7A�ϟ����T�jժ ><&&C�.��+�_�nhh����tA�?n��cǎ�f^�z�o߾y��A�hݺu� +�*��055-S���� M�6�� )����'�5j����L �اO�u��ig��۷ow�Ё�Z�\� &@�����1 +�e��`ш��?r:=��6����ӧW�^=r��p��P/W�_��������d�7�������ke�t�K�]�644��LJ�`ff8>>^���H{�ҥ�)hЉ����Y��+����,T��������LE�bǃ��CE���@�Z�6m�T�';��;w����6l�t�nyhV�0����j� +�9ͣ���/2� �ӧONNNh_ӂ.ȪU�P +�����g�ʠ=�6�y�fZ�\\\��?0숖-[��RP��1'O��k�b�a�����BAX�x1��W�a���ԩSd?fmʠ�ػw/�[422Z�|��Y������d��~������cA�O_�6m���O� j���z����*U�@P���i0h�9̹50`�&'�Ν�|59X�~~��inܑ��a�_d�d�&�!W�-��J�����;ضm[ɒ%!�}����t:8�������Z�2����}Pw�V�����u=�w����O�Eo���~���@�����/��J�=� �<y�6:�����~��W tɯjs��P?~lee�&V`��`���tf�ƍ�M����x===cccu;�r���_�|y%�e��:X`(h�ԩ��G��-�&dQ� 00h Ə�nT뿌;�2g�V�DTTm8�i�#G�І�A���ɡ�G�ې���'h憆�O�>e.>�={&4�={���N��3Çg � h�^�Z��rrr2��bU->dffV�^�L�E�r劵�5����1>|�<CŒ3$SQ1i�$t�Y�f���|����������.���� +*PH2v��A4hD����RG��ڵC⊝e�fL�0-[�|���t!���ÇժU��#���� lݺR���d:iii��XH�y�� �&�#t�(̺��d!����ǵk�FZ�l�����A4�~��<\)���,;;�9s�p����K~��g�;u��4<H.�['��߽{���7l�P;�I30(����ɾ�S���/b���T:mGL^�T)�Y�:�pq��� 2a�!�����d36o�\MkF�H8�cP��nmm��:u�@'��� +(nܸAC�@w�?~�͙�}��5(�(ѽ{w��;�O�S�eBOO�)�ſ��K�t===���x��:4ԣG��� b�"�8߀��EА�9(RSSɋl�v��դ��i�&ccc�РAlk"�s�Ut6s.Pܼy�jժhAWWW!� ' >|8;4���\%*:S΅�S�N� �֭[��aJ�l���/X���&�s���L9"���ɯr�.]G�iii�5B�-,,��^�����\ZEgʹ�n�:###����7眒�R�\9�^���3�h?aBB� +���L9>}��믿R�M�4Ips�QQQ4u�ܙ ��:�_�j_Egʹ�������V311���V�߽{k�vƆ��}��5(�����] ;;[�Ɇ���3I(8�<���\�����4��z��!����[�la�ɠ�x���Tyʤ�3�\���[�h��Z��p���>o�<�aްaC���A�@����������mܸ��c����666�NNNf{�>|ضm[��3f����?x�M�6�)1$$���d222���H!!��Oy QW���߿���Җ-[ȫI�*U���M�6�.]��V�ڑ#G30)))��������fll�cǎ0ȇ�g���ŭ^�c"��x���N 4�nݺQ�{�����e>++������/_�d�� 8$$$�ZޢE��۷su��F���9w���fffF�ItĹǧO��ϟ_�dI���� ������kגJcii��s�Djj*m�ѣ���Q���st��eˢb���E/EG��_�>M82���2�ڵ֭[�Z�"--���@���Cn�$Ȝ�|DEE�����.]�$V���>�S�N (����!!!tP�F����c�� \��A���������|<5���->��~߾}1Z��+V�����'�]����xҤIB������СC!�AAA2����|���P�ti�g����F��5�nΜ9*?8��9F///�)���oݺŨ�A���˫T���� ��j��ԩxcժU"���/�D%J� �TyFFƈ#h$�P���m +Azz:��,������ǎ�z6l�pE�˗/�b��-[v�ԩ�F!''g֬Yȿ��٤I�X�O1t ٮ[�.�s��9h����#D!y������i��U�VTT�������FDD@��7x��1��"����?Hx� �K�.E=�����f�n� +���;��;w +˻��"##+W�Ln�u�v��5���3h�ϋ����ׯ7n�أG +[OgާN� +-]X���� ��B�R,���ϳ.����Ac|~���{�y�FÒ��ѣ����cǎ��obb���}�x�bƌt�:���י3gXgg`|Π1>ONN�Q��;w�fZ?33s۶mÇ��#�_~�e��킋� ܹs'88�T�R(���! +r��e����k֬quu-]�������u۶m�>����,@>M�|�~Z�vmÆ qI��� Y~R����݄چ^���4s��b�s���asuD���M�֭[6l��5jԈ&� �+W4hP||�@�>|��LJJ���ݻwYg`|��\��kdd���6x�`;;�B�� ����Q:��+?��3� +h֬?�)߀��9y����iӦ�����۷��Ņ?� c*l_����l�2~�x777ڪ��hϞ=������_� +�W�"##!�T��U����ˣ#�����d���rw8�12��=͝;��Ι3��m:�-�%��$҇r�k{{{ �9�|ǎ�)$,�J�*)|�<77)��+V�;�cǎ5kք��O��?��!/""���y��nDZ�l�aKX�����L���|e7���=�i���d����k�ƍߝo������X�|�t��>}���z�ܹC���ŭ[�nٲe�&MB�<==1�AӖ����q�z�z��5�|���_��Ħ��/\���@KK�#F�Ir�b�����Ǎysz�v����~æM�$�G4��u�ԁz\H��2<��?��*���sww6lآE�0VsG4~�1���:u��YM�6]�j;����%�-&L(�|Kxx8}�?��s�ؼy3ml($)��iӦ~<V�|����� fff�˗�U�*�m۶]�v�ӧOPPЬY�֮]�!��ի���������]�v���s�*0�0v_�r�u^-��?���[�8q�СC%�C�aƌ�z���ը|��� +m���7,,�W�^x�f͚�]��БM��~��!**��+JcǎY� ���*��w��ݻwon�X}���:鉁A@|~$?vO�6m,--���K�.���&sһC��h�_����۷�X�"�r���舔�ٯhnn���x���P�UDD�n� +�!�ʑ��ӭ[7�h������ϦM�ؼ +�6�9;O���N�9$''����]�p���O?qs��ƽ��ׯ_/�\��s>�͛7�`�������effn�_�~�����;;w���T��� /_� + +"Z;q�(� eܳg�رc6l�M�������УG���q���Ǖ��ҳgO�ؓ'O�o�7�iӦ��M���~~~111x�uC����<}�T����˗/GEE��K��ҥˢE�.\� 裩����r���ϟ�]��nݺ���-Z����9�B� +ݺu[�p�3g�t +�Z��ͩb�7'�������e˖ <�y���I�������������o�ᐁA�`�5������Ŋcƌ�С�����C�>}��'N�P؟����˫T������������;u��[�j��Jx��͛���?�������{s�(%�̴i�&(((::�ԩS���`�С�螌���� F}}�gϞ{sggg_�vm�����Ǐ���oK�T�O����²X�x1 +���ƺ��*�����L﵌ϕ���������5�����t߾}111,�������۹sg�������y!^��֭����}Μ9�6mB:/_�d��AX���A���99d|�*>���211�r~�ҥ������Y<�x���ݻW�^E�����w�y�ʕ+�!�iCCCG�5h� �� jww�� V�ZUbcIA��;88xyy�1b���[�no?}���q 55�����G����\>_�zu�2e��:y5����F�P�������r}�ڵP�A����S_dR�ABB���18�E���Q���9�Ű�09uf~$+++;;����7i����������oȐ!cƌA����K�.�믿�Z��>|� ��4������CJJ��� )���y�����;v���|�<((�v��������� 7��Č��A3������N�x�Ố�+(����gB�P�������endstream +endobj +3897 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [477.025 103.778 535.492 112.689] +/Subtype /Link +/A << /S /GoTo /D (groups) >> >> endobj 3891 0 obj << -/D [3875 0 R /XYZ 81.694 548.743 null] ->> endobj -1735 0 obj << -/D [3875 0 R /XYZ 71.731 541.605 null] ->> endobj -746 0 obj << -/D [3875 0 R /XYZ 243.84 504.389 null] +/D [3889 0 R /XYZ 71.731 729.265 null] >> endobj 3892 0 obj << -/D [3875 0 R /XYZ 71.731 497.037 null] +/D [3889 0 R /XYZ 71.731 696.359 null] +>> endobj +670 0 obj << +/D [3889 0 R /XYZ 263.164 254.019 null] >> endobj 3893 0 obj << -/D [3875 0 R /XYZ 71.731 477.126 null] +/D [3889 0 R /XYZ 71.731 241.581 null] >> endobj 3894 0 obj << -/D [3875 0 R /XYZ 219.242 466.332 null] +/D [3889 0 R /XYZ 245.796 219.509 null] >> endobj 3895 0 obj << -/D [3875 0 R /XYZ 71.731 425.321 null] +/D [3889 0 R /XYZ 71.731 212.371 null] >> endobj 3896 0 obj << -/D [3875 0 R /XYZ 71.731 410.377 null] ->> endobj -3897 0 obj << -/D [3875 0 R /XYZ 71.731 361.326 null] +/D [3889 0 R /XYZ 71.731 168.535 null] >> endobj -3898 0 obj << -/D [3875 0 R /XYZ 164.944 348.374 null] +3888 0 obj << +/Font << /F33 1306 0 R /F32 1215 0 R /F23 1201 0 R /F27 1208 0 R >> +/XObject << /Im1 3854 0 R >> +/ProcSet [ /PDF /Text /ImageC ] >> endobj +3900 0 obj << +/Length 2098 +/Filter /FlateDecode +>> +stream +xڥYK��6�ϯ04"�\��lkO;��l&��`��6{�-�& �=f����b%YV?2A->�����"-g!���J�U� +�Lf�ӛpv�����Lq�$w�w�7��!�f�H��l���Q$��r���X'j�����s��ŝJ� ���6做����(���7?����c�D+���ge�4WB�U/��-\�(��L�!�_�1��]�$�J��L_Sҷ9jj*۞�[$IP�@����w;��VW�w��[j���>�7�����-� +���L� �E gwQ*�U�LD"$�Z�-tVR E<A��7�{�PHE��hǂ�g��1+w:��ϭ���0,ln2(Y�vpR��A��)�,%DDbo�(R���cg����j�������� �H�����������+ݴU��8^�����[,�@�������g[�f[0��U��jrYL[����=��mV{����W"M��_��VY����ikʬ1�d|Q7S/Fb�'qTR�9���z�n +%>�z����I������aΖ��; j�ZOmt���N]��;Ӂ���!�ƀ(I��P��-�.�k3��HT�Tx�N7f����X��%/�t��c������^�K��W�̂vQ���^�E%�P�H�U)4ȳ��Q~�#�Ez_����D\sPK�Ԓ } �<��f���o�48�q�nV�&���"��K��tNTd�Mvx˻�A�� +�U&p(���\�nw���ڇ�]��>�\K����rDD��� +��}h�la���Kz��^��ð�-���CUL��Fs�47�T�Kmt�;�:�0Cx�2dɗ�8�qJ�Z�4}6�h|:5V�l�)��)�\1kT���ߞ9-�b>4��4����"N��s�ԣ���A���՝p�ʟBM���x���)Ԙ�%Ԯ���ڈ�j�� 4\�@�+�(,�ڲ�a$�Ql�8U*�g1�<���x� f/b6f>�ِ�� ��#딩��q2F� +����뾣q^=>S9_7��央l�$�}�eh��o,�ՠv����1[ږ+�O��nL�b��,��Z���=�Ɯ��ڊB���Ս�Z���NC�I{�����MfJR��ik]u�-������IX�4��x��>� +J�w�0/i�+j����ǻ���H��8�ʊR<n�tˠjK/���F;HV�eB�[ �D+0{�����dC�`0�Z��9u4�ߣ.G�����b�6��`l�?�YQ�i�S�!�,��ۉ��jbua���R2�oy~~SљT7��XE�z0�9s6�k�1W�®�D�F�ix���:W`�PT�̾�{w�����{V�65q��?J*ʕ +\����^w�x�8ͺ��ލY��hܔ#�"Ys�]`|��=�� շ��^A�GWD�$��p�3g�ˆe��0�Kf"��Y4��?,��Udm�wKWsDž��xp]e����s��Q���l˼g��N��ALD;� E��Nq����kb�ۦ���ߡ��)�]:k8,0E�UV��G�5��2�ʆ>f}y�/��N����y���MRBM,�������ӼnO��z��s���1�O��9Ƌ�k$���l�T[�C�_!4$JɅ�����,)��)���;P�{^B�G*�5��+�Ъ{6��k��������d�D�upp'����5����z*�x�4���o%�=�)Cua�"�ߏo?�ɟSv���6���<�C��1~�i�Y#�߆h��B{�(��B�W#�5�/N�7��:��ڜ�;���h�2�nSK B<�@W�:���YUt��!e[s��Q�>�ᓉ���@U���?��6i�긂�����y�/J0�>P��9� 6S4��(@��0��J�н!���� +�xps�u�E�H������c50uc]��$���}�v��B��]���/��מsv��)�<|��Kw.*� 3B���{�kO0�Ts����U�|4 +�����ыD�Ջ>/�iN��Qo�VOd�|(�qwK�u����4l7���b�h_����O]w�b-W��v;���&>i��o� +/�S?I\s���v�endstream +endobj 3899 0 obj << -/D [3875 0 R /XYZ 368.717 348.374 null] ->> endobj -3900 0 obj << -/D [3875 0 R /XYZ 273.801 335.423 null] +/Type /Page +/Contents 3900 0 R +/Resources 3898 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3887 0 R >> endobj 3901 0 obj << -/D [3875 0 R /XYZ 71.731 328.285 null] +/D [3899 0 R /XYZ 71.731 729.265 null] +>> endobj +1746 0 obj << +/D [3899 0 R /XYZ 71.731 741.22 null] +>> endobj +1743 0 obj << +/D [3899 0 R /XYZ 71.731 706.187 null] +>> endobj +674 0 obj << +/D [3899 0 R /XYZ 217.917 668.971 null] >> endobj 3902 0 obj << -/D [3875 0 R /XYZ 317.393 304.539 null] +/D [3899 0 R /XYZ 71.731 661.619 null] >> endobj 3903 0 obj << -/D [3875 0 R /XYZ 232.347 291.587 null] +/D [3899 0 R /XYZ 71.731 641.709 null] >> endobj 3904 0 obj << -/D [3875 0 R /XYZ 71.731 289.43 null] +/D [3899 0 R /XYZ 71.731 612.882 null] >> endobj 3905 0 obj << -/D [3875 0 R /XYZ 71.731 274.486 null] +/D [3899 0 R /XYZ 427.586 600.03 null] >> endobj 3906 0 obj << -/D [3875 0 R /XYZ 91.656 253.331 null] +/D [3899 0 R /XYZ 113.318 587.078 null] >> endobj 3907 0 obj << -/D [3875 0 R /XYZ 71.731 213.779 null] +/D [3899 0 R /XYZ 205.079 587.078 null] >> endobj 3908 0 obj << -/D [3875 0 R /XYZ 475.448 200.827 null] +/D [3899 0 R /XYZ 71.731 566.989 null] >> endobj 3909 0 obj << -/D [3875 0 R /XYZ 71.731 159.816 null] +/D [3899 0 R /XYZ 71.731 556.095 null] >> endobj 3910 0 obj << -/D [3875 0 R /XYZ 71.731 154.835 null] +/D [3899 0 R /XYZ 71.731 551.113 null] >> endobj 3911 0 obj << -/D [3875 0 R /XYZ 81.694 134.078 null] +/D [3899 0 R /XYZ 81.694 528.299 null] >> endobj 3912 0 obj << -/D [3875 0 R /XYZ 491.507 134.078 null] +/D [3899 0 R /XYZ 81.694 528.299 null] >> endobj 3913 0 obj << -/D [3875 0 R /XYZ 71.731 121.027 null] +/D [3899 0 R /XYZ 71.731 526.142 null] >> endobj -3874 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F44 1994 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +3914 0 obj << +/D [3899 0 R /XYZ 81.694 510.366 null] >> endobj -3916 0 obj << -/Length 2551 -/Filter /FlateDecode ->> -stream -xڝْ�6�}��o��ڊD�N�f�2�lm�t��J�h�5���1�ޯ.J���N�� �q��&�_��B?����J����.`��w�`�e��|xx���(���}m��8��(M7Y��<Q�����\\{�nw* ����O<�0��o������w�<��(��y��Lq�� -��T��U���A�Gq<ʭ� 0�Pl{z�@�U*��(��DMh���Ĝ��1���~��g��w�9�Zow�>�v�Q����ӭ��s3�j� -Z���n��f�ӹ����x�QkY+5r)z] -%�B���2huwm��<V86� ��V�p�y��6��..���p�4CݣbA?�P�{��z�E۱K���D`�HtR2�a�}���łJW��oh��Z����ʏ��]��y��,�.���MZa~�B.���cg�w��}q�qB��0k�!�̍�]fu��=�xh�w%�@��stN`�)p������]:h�O0��g�/}���0�~�w������O��ug�p^r�x����v�%�38�����;�8����t{�*��<"����ac��t�C�&c����~��kkO����5��$�^���]�-�.��m�%�]�?mC��I��7��7�ȏJ��:��VŁi&�B�Ҵ����x�ӣ�mg3�gs�g��3��Ȳz�9�k.z�P��'02a��W�`2�J����0|檦����c��?��L�K��D����Q�:X�~J��l�b4��#�J�8P &�����X�{��.uǓK���'u���QP?H�(F%�#bs��a�#kNW -��PV����\ꫮK.�2Q�bogz����Yk̫'X�9��7wq�G��Ł��윒�wQ�Qj�����x&�8�^ -S�1��S -Y��N\c�A6!��3gT����>H�D�V���-��z�\/�A��_��#��C�R���� �� ��"h�I�� -/��-����8���]���g&�N��;Ʊ�ra�Dg��w�4���Bx�/��h5;Yw6W�f�,|8��rWn��xi.ǃ�s��\5�HX��Y ��,:_$<�ϐ�(���R\�\N�P�I�WpPS�_lC ̠ɴĭ��Қ)�]S�&V%����X����=�̗NWL=;@ B�:����� ��|� ����?`��CM�c8y�Ct�0B+��9�2�і*tq�Iw0q ��y��c���S���2�|����Z���z.���)U�\��å�,�!`F� ���8��jb��+8����PW�#,[{:����F�V� m�p\��Q�"� �o>ЙL�t����{������y̚�^K__,�$ۮ}��ᦞ�JM��{n!"��|�:�r��T�&�J !���O%�(�%�����b�(ˎG�3�t���,��{]@S,"��Y%9�i� -Y$��l�+���A��w<���=n�GI����j _M 5��K4�Nε��K�1.چ��<L�q�\�d����k=����ԖEc�'�p��q#�K��D�=&�(;����;�=P�#�8��(j� ��b� �R��A��(ܠ���:̯��Q�h!P�����VxX�-<��a������T�*���ec�J/Y(�H��>߈��E�$��n� -�E��c�Œޝ���LQaOץ0�s�H`�� -� �� �B�R�Ҧ�b��z��L�e[^Ӓ�I5ˉ��ĵp�*�a��\�D=m�?��:�� ��3F�e��������P��Y�9�{8�ٖ_� -���^y.��n�9$?R̓��vˎ����@�a��/���b[ uiD��˰��� �2�n衂��|��4СF|�X%���?��C��@�37b�:G26C�ZD��s�HVq��".VƸ�R�t�R��}���;c!Aj���#!b�R�yz��eK#�t�[���#eØ -�pH�������B�)�y�#���Ų+C��̈́h5Y6ʾ���N�Ƕ���[&�7��\i���Th��^X^�K�N�[��?��FӢj�Ư�������D�봥-�R39�U7P�a��z�QL�ċa��v⇁��T�s�n/R��"���*�+�'K=#�_������Y�j����mkw-N�Q�M�1E�� -��w���m���K�!}�wն7��6[p�C��BwV�b����6�p��rj�������P7�`��-DOV� -[����sݼl�s��l ��қf�����`l�C/!z�F��c��Wa"�K�~���>�K�7G�0�c\Yu��O���?��e����kr\��_?�b����:!ĉ�0;��Ǻ����(�>[�)�eFs���rb�d�k�M����(�����(5�$���!�8=������*�5�/6�V>J��gM�uvjW���� -bY@uTt�� -�l�F�`�a� -�kE�V��m��-)�����f� -i�E����,�碄S^l�Zjs�> ���~��<�,��LT��A~i�ҿ�KN�����endstream -endobj 3915 0 obj << -/Type /Page -/Contents 3916 0 R -/Resources 3914 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3946 0 R +/D [3899 0 R /XYZ 81.694 510.366 null] +>> endobj +3916 0 obj << +/D [3899 0 R /XYZ 71.731 508.209 null] >> endobj 3917 0 obj << -/D [3915 0 R /XYZ 71.731 729.265 null] +/D [3899 0 R /XYZ 81.694 492.433 null] >> endobj 3918 0 obj << -/D [3915 0 R /XYZ 71.731 741.22 null] +/D [3899 0 R /XYZ 81.694 492.433 null] +>> endobj +1744 0 obj << +/D [3899 0 R /XYZ 71.731 490.277 null] +>> endobj +678 0 obj << +/D [3899 0 R /XYZ 236.902 457.963 null] >> endobj 3919 0 obj << -/D [3915 0 R /XYZ 81.694 708.344 null] +/D [3899 0 R /XYZ 71.731 451.836 null] +>> endobj +1745 0 obj << +/D [3899 0 R /XYZ 71.731 380.09 null] +>> endobj +682 0 obj << +/D [3899 0 R /XYZ 166.08 346.78 null] >> endobj 3920 0 obj << -/D [3915 0 R /XYZ 139.516 695.392 null] +/D [3899 0 R /XYZ 71.731 338.142 null] >> endobj 3921 0 obj << -/D [3915 0 R /XYZ 71.731 693.235 null] +/D [3899 0 R /XYZ 344.894 327.851 null] >> endobj 3922 0 obj << -/D [3915 0 R /XYZ 81.694 682.441 null] +/D [3899 0 R /XYZ 71.731 313.739 null] >> endobj 3923 0 obj << -/D [3915 0 R /XYZ 478.291 682.441 null] +/D [3899 0 R /XYZ 155.277 291.288 null] >> endobj 3924 0 obj << -/D [3915 0 R /XYZ 71.731 667.333 null] +/D [3899 0 R /XYZ 71.731 281.225 null] >> endobj 3925 0 obj << -/D [3915 0 R /XYZ 81.694 656.538 null] +/D [3899 0 R /XYZ 154.779 256.717 null] >> endobj 3926 0 obj << -/D [3915 0 R /XYZ 373.716 656.538 null] +/D [3899 0 R /XYZ 71.731 245.315 null] >> endobj 3927 0 obj << -/D [3915 0 R /XYZ 71.731 654.381 null] +/D [3899 0 R /XYZ 426.159 222.147 null] >> endobj 3928 0 obj << -/D [3915 0 R /XYZ 81.694 643.587 null] +/D [3899 0 R /XYZ 71.731 210.027 null] >> endobj 3929 0 obj << -/D [3915 0 R /XYZ 511.114 643.587 null] +/D [3899 0 R /XYZ 103.272 161.674 null] >> endobj 3930 0 obj << -/D [3915 0 R /XYZ 71.731 628.478 null] +/D [3899 0 R /XYZ 71.731 151.612 null] >> endobj 3931 0 obj << -/D [3915 0 R /XYZ 71.731 613.534 null] +/D [3899 0 R /XYZ 425.163 127.103 null] >> endobj 3932 0 obj << -/D [3915 0 R /XYZ 71.731 576.139 null] ->> endobj -3933 0 obj << -/D [3915 0 R /XYZ 339.03 524.334 null] +/D [3899 0 R /XYZ 71.731 114.984 null] >> endobj -3934 0 obj << -/D [3915 0 R /XYZ 96.637 498.431 null] +3898 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 3935 0 obj << -/D [3915 0 R /XYZ 276.322 498.431 null] +/Length 2929 +/Filter /FlateDecode +>> +stream +xڭk�����ᾘN���DFc;v���4��h������!s�>_�ߙ�����-l�������.�����b��>a���"�m.�������X�#���7�������O�����"�"?�n/vQ����&����$�Z��u�l�ħ�/���4|�/�R��u��W7a��t}�&>3#*��D��6{?�cC�n���MX�4��z�7YW�Z]45-߮�����ջS��h�O�B��XK;; e��U�xWA�1��B,2���@mt~�$H��bo�8N �����!�v{�MW��\J�g ��,���L��Ӑ��"���� � +}*j��TJ{�m��;�4����w۬�)��i�<�j��ւeI����nEQk��y﹐�cͅ> �l���B`deӼ'��ɡip�0#�V�,>�'�w�`�Yɋ�� [�-�es���V�Y�x�i�R�+�v�h6*!�iV�N�ܷ �р�����>p�Ϊ��fE�ك!�"�F����d��n��e�]ҥK�Ѩ�:����|��4�^������wlA=��a}[5��} 7�{G�;�| 9bNW"���{RwmMӦ.�i40�]j���3*��1|���{�,}�Bi�����Y�Ih̋�O�����j�hI5�lj����-����")�D��%YW�NM��2�˒mv}&���w(�p ��K�A @C�]�.Z�L��t�l_���̭����; ��f�jx_��7t�> )3��0��Hv5Fߑ&�2V@�����H"Ve��n;9�K1ͭ ( L���K��J?wE�H�+ ��i1&�?)�5sŸ� � +x����Ņ��=?��m� 7"�C'�{:�A�h�A���ZH���)2}�v��E�u^dBK�n"��A��0։X�f�5Re L�DQQd��.�]}��i�]s���H��Mw�,h��oE;g!$<�$��. �U$t�X� +AkCc�Î�0�Q25Vb��P�/i�����XP���*aD�sr72�N����m#ڜQ0�S�߳�~c�ަ�~�LB�9�+���,�|x�B��ɻL�9��~��8'�'���V[bLNp�&���ys&L>��cX�� {�:���oh�RΘ�X��X�e��0a��[�8�V�Pe!��PW���7��ߥ{�&dǐ��Ù���rt$q8Z��:\�%���d~9c��'A��C�@&��}p%���𧚶�W��6�Q��Y�d̪ ���-,^�L�EI�?��"�{����`��X��ȟ}���U٧3eQ��%�9x������ᥬ��x�&I�<&��/��ap ^���49�0��� ���@���h�O{������H1�/�ɭl�b��� XQhr� +-Lj) +�%\ "p���-���u@ʱk�m �Ƭ;_���/EGJ�-c_x��bPMk"$��tt� m��=YSvUM��`�OӟP��xg�����?H�p��<�8�a��,�Jq�����8 ��mu�d�Ѻ�Ƃ\T���+T݉�RИ��O)�n)�u��=]��M@��7B5h�:}ɪ&���%(ű����i{��XZK�]���X>�މ"�\���`˴���Y��/ZC=���s���0�w?�(gr �����U���%z,�!=/��m��M���%_N��Ok̞�2�2~D1����/�5չi��؟I���\y�NR.?��>��jJ#���~��}���ƞ�a�)!�`��K��y�S�ޣ��n�����ahX[hK�����r��,�������nT.��|��u�B��R�,~4�;���7z�t�� +mѳϽ��Ȝ��~�s+s �zV���/�!gnV{W���b*]��zf�P��|���f�ӊ +=��2���_�^/�/i�P����u.���~��� +���RF�3!'�����R��`�J�κ'���u�p:"��j�s�A�4��K���>�xsG�*ذ�4QU-pl�Iz���2�8BEM+Z�>ē�Y2�fO�.��D��O�L���'@�����:� ]��2��uyA�q��%�:�ZD%� +,W�ddNH��p��j\�~b�r�1G?ǯ�Id��ȉ�_8Q��Pu.Ž�I��r)�4U����{?�����^%0���,�IU��<�֓87�$Ρ_,ZgN@MI�X�C=z'�H�R����OK6���L�U翔1��$�6�C�z@���|~�W��3��S1���^-Ee�?h�S���+��{��b��:3I*���U��R����ū���;�L�Ê$�NK x�o�d�6�7y��l�%MV�3�2��%��rƺ;'���k)��{0_i����ӟm�/�b잷Mw<=���~l�T�d��Of��b_=��C��]�%�������5�ǯs|�t� +�*_����$6��[Y�>��ܦ�K��n|����4d�q��� +�q��*�$ю�*�7���<\�/� �y��Y�5'�6M�ae<��c���� +0c.��}^r�NH�R�٤���B�5&�6�`�,���A���8ap ~&�S��К�N���Á����6G�=�Xa�ls��X��n��8��ѣ���\�A����h���WC�� Mm���7o 6����+�4���Y>C��%ʯ5äzjt�1'D=� 릁���䨳̊�%D !���PW��X$N��d�W�_�ʼ��ȍk߆ܦ���k��Ani8 S�?`3ʫɵCS��|�v}h�\���9�ZF�;SN���^�y����~48��&�c���)��\��x��Ib�Mas��� +L6����2���ixm +����\�������豴����?аW��=�������/F�p�oB��ۆ�%���ʕ�endstream +endobj +3934 0 obj << +/Type /Page +/Contents 3935 0 R +/Resources 3933 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3887 0 R >> endobj 3936 0 obj << -/D [3915 0 R /XYZ 71.731 496.274 null] +/D [3934 0 R /XYZ 71.731 729.265 null] +>> endobj +686 0 obj << +/D [3934 0 R /XYZ 201.526 667.895 null] >> endobj 3937 0 obj << -/D [3915 0 R /XYZ 71.731 481.33 null] +/D [3934 0 R /XYZ 71.731 659.443 null] >> endobj 3938 0 obj << -/D [3915 0 R /XYZ 187.678 471.831 null] +/D [3934 0 R /XYZ 463.469 636.015 null] >> endobj 3939 0 obj << -/D [3915 0 R /XYZ 71.731 420.623 null] +/D [3934 0 R /XYZ 71.731 621.903 null] >> endobj 3940 0 obj << -/D [3915 0 R /XYZ 180.774 407.671 null] +/D [3934 0 R /XYZ 514.935 586.501 null] >> endobj 3941 0 obj << -/D [3915 0 R /XYZ 391.53 407.671 null] +/D [3934 0 R /XYZ 71.731 574.381 null] >> endobj 3942 0 obj << -/D [3915 0 R /XYZ 71.731 374.63 null] +/D [3934 0 R /XYZ 71.731 557.959 null] >> endobj -3943 0 obj << -/D [3915 0 R /XYZ 104 337.933 null] +1747 0 obj << +/D [3934 0 R /XYZ 71.731 518.192 null] >> endobj -1736 0 obj << -/D [3915 0 R /XYZ 71.731 330.795 null] +690 0 obj << +/D [3934 0 R /XYZ 197.015 480.976 null] >> endobj -750 0 obj << -/D [3915 0 R /XYZ 204.474 293.579 null] +3943 0 obj << +/D [3934 0 R /XYZ 71.731 473.057 null] >> endobj 3944 0 obj << -/D [3915 0 R /XYZ 71.731 286.227 null] +/D [3934 0 R /XYZ 103.934 447.9 null] >> endobj -1737 0 obj << -/D [3915 0 R /XYZ 71.731 243.402 null] +3945 0 obj << +/D [3934 0 R /XYZ 105.351 434.949 null] >> endobj -754 0 obj << -/D [3915 0 R /XYZ 275.232 200.305 null] +3946 0 obj << +/D [3934 0 R /XYZ 71.731 427.811 null] >> endobj -3945 0 obj << -/D [3915 0 R /XYZ 71.731 188.134 null] +3947 0 obj << +/D [3934 0 R /XYZ 518.615 417.016 null] >> endobj -1738 0 obj << -/D [3915 0 R /XYZ 71.731 151.06 null] +1748 0 obj << +/D [3934 0 R /XYZ 71.731 396.927 null] >> endobj -3914 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F44 1994 0 R >> -/ProcSet [ /PDF /Text ] +694 0 obj << +/D [3934 0 R /XYZ 176.973 359.711 null] >> endobj -3949 0 obj << -/Length 2639 -/Filter /FlateDecode ->> -stream -xڝ˒۸��P��T�D�/�̞����[���L�Jes�HHb-E*�c���/����M�t ��h4�B+Xl�,��O#���n�Eqz�Y���@(�B��мy|��(Z�~����EE~��.�(��$\<�������n������������oU]��yq��6L��ϳ�e�4τ -�E�Q�E���6��9 ��A�(L�y���E�6^oP -X��g�,��aL_��.�y\�*��^�e�xO<k��폚��uzx��6���whwK�i=��W;e��"�T���R�s�~��<� -�� ���a���g�@%��>���X�z�lKYB[1Ik���Щ�*T��NQ5�չүv�CY��Qu��_�h�W?ҩ��?-QX���}$���j���w�iP�=n��I@�=��F��[�G>q����&l�@���b�g��4C��5B[��a��amS�^.�����{�´)��C0xT)�.tI(�@�S�GV�OZ7�/�ya��T�Z�P��XaWfh�c[`N�a�Y%������Mۣ��v4�0��˙�!�������_�pU����Mr,Yc�6���m�#F�-p����Ru��Ѫ+D⪁�G�S�^15_�oT�Ef,δ'�[�)s�E�cVj\�@Xr��=%n,�p:�]��mz�'�ܔ���`�����m��J ��t��0ccB����+ ]q����t-u�.��n��m���^�~Gw�\���0ԕ�|�ͭ+�4�}u�eV�x.Z�� -Af��Z��m���@#��<��pc�_�<Ȼa�چ�3 �wt+��DB���kM�n�eܰ��2�c���b�ʢsזC�� ���2a 6A0�v����!�;�zѼ:,�%��s%z,��l��`/�h��'���)�#=��f�E �=@{�{6�ig�9�R��ۗW)�LӤ.煯��[���m���(���L�1�:u���1�w@��!?���q�8e}����e -�3�]h���a-�NYx��e���b��V����jd7��%�(;f���&�|h{���T\d�G����BTe��#�{��A2̣e�o����!3N��3��Z��e�����������g���T���J�;�Y�S�3r8������H iF]��εj�������X�,����9/�m��f4�Ua�b\%8az��R���2����'p_�@�J!6Y��%ݍPS��a��{��U)4]{�/��F1L�h��C���J��8���d�Ol+^�[�+|&*�U��f����ϋ��nz�� ��`,C#�l�$�����I����H�w� ȫ��$�|p�vD�w�>s��$���z���{}$·z�s��[N�)��DZ�b2Iǫ�<�8#P�ƕ"�i롯l�o�Uo�J�[�,Ʋ8�^[��>c'�d֢�<w���(oYZ)7�� �ݝ��Vj\wr-%ޓ�)_���dԅc� NpĖ�YH#�vj|T�<�>�V�:� X��`��h��%��v�L(� P���D?�Ps�'���q��\�q"w�0�ワC��oi!'&���.����� �a���?IL���2���k�����e6���T5��;�������$�gAL�3j}P^AK�<5��ν4�I�rA�z� -|�O�% ���X�+R�Zt��P�M����8������m�g_��/<;��\32��������ym�(��lOa ���eE�cU�ԁ}�u`�9�`�K�8�� � �P����{]oA�F�uv;���[%�$"7j����BZ��l6����R��+�\�L�$�{��6��Wo�\E(�з'E�%��3��� �>q�ch�N�W��F�/�N"���7�0�<����3mVs�1��`��d�q#>�h[����b���v[�I "��+�2N� ��>'*��R�S�FͤDi����\@�m=�ÏO�����M-�������`��{v5>5�r�{�=7��^ -��q�f�H��3;Sѕ�����J�qw�"p��â�ޮ7��wxf�3r:G�&�"(r7��`�� լyf��Cerh����t9�J�'��U+N��դ˗͝ -"�.wm�wcg�}g\�+�|R.�mBO��|wL3ۈc�:�D��-�*a)�.q 0t{R��3�K�����S��W����]SIq�}IY�MX�N; ������c �d"E}�qL�%~79ߟ?( ��� IM$bJ�A�q`H���}�.�݄е����Yl�,F{z<���J닩-"S,S�1n��eɃGj�0��ʈp+S.s}ƾknv���q?�~�W��X�8��ؕ`��n�/l�b��}�ણmm �v�N�F:v�)�R̭\F)�Mm*��5�K��u����tS������&#������$����NB7��~��=s�Qb�F���A�Rҧ�~_-/�����?���7)Wx������{�O����S}����w�o�~ ��|`�t��ZNP-����f��k�1�l�ƺ���%y��q"#9]�T����l��5\"��-s�w��Ig~���H����$L縠������|��Ԣ�9endstream -endobj 3948 0 obj << -/Type /Page -/Contents 3949 0 R -/Resources 3947 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3946 0 R +/D [3934 0 R /XYZ 71.731 349.346 null] +>> endobj +3949 0 obj << +/D [3934 0 R /XYZ 71.731 332.448 null] >> endobj 3950 0 obj << -/D [3948 0 R /XYZ 71.731 729.265 null] +/D [3934 0 R /XYZ 71.731 290.77 null] >> endobj 3951 0 obj << -/D [3948 0 R /XYZ 71.731 741.22 null] ->> endobj -758 0 obj << -/D [3948 0 R /XYZ 174.075 708.149 null] +/D [3934 0 R /XYZ 71.731 290.77 null] >> endobj 3952 0 obj << -/D [3948 0 R /XYZ 71.731 698.007 null] +/D [3934 0 R /XYZ 71.731 174.557 null] >> endobj -3953 0 obj << -/D [3948 0 R /XYZ 71.731 639.108 null] +1749 0 obj << +/D [3934 0 R /XYZ 71.731 115.613 null] >> endobj -3954 0 obj << -/D [3948 0 R /XYZ 71.731 593.215 null] +3933 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F35 1567 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 3955 0 obj << -/D [3948 0 R /XYZ 71.731 562.331 null] ->> endobj -1739 0 obj << -/D [3948 0 R /XYZ 71.731 507.601 null] +/Length 3073 +/Filter /FlateDecode +>> +stream +xڍk�۸�{~����Z�%'(�&�K���Ͷ����DۼȒ�G6��(ɲ�9���3���<��R�MC�;7H�U~z�����/[A��p�>�z�!W;w�����* +C7L�Un����λ�jzݮ�A�9���t�:���p��)K����_^}�8����e�]�,�SA��#7���^�K�,�؍�yI3�O����zh��^��^�⡓Y��o�>1� ',�@5�D᭶���AL�����zXo�8rrU�@BGUC�?v���a�B�8ڷH7��0���L1��W-3�>M~�a�{�v�,|�����T����w��$u+`�:S��I�x�jՓ��(�����e]id��û�@ }}���*�<t�[�k�� :E�B")�U����?�Ǻ�<��IFFN�WK�~�4�6h,��t��4>9��h�i������#���Օ�`�,?�E��I�ja��TgF������������|�|x͎���*�Z e�a�e)�pf� .u�2�#��Aw�%�t���C|GW���O��7$��7�HqP�� ��K&�L���F#������`�F�ɞBwyk�,��\��`д�-�:{Pޛ��紂��h& �냮%����.��ڥ��0EU�/d ZԨ��N ��.��Q������`���>��~�55Y"��e�%v"P���Tj̀��pz�-����U��;�(�����1�/ +���a��s�=��N�3����=Y,#� +0�,$�-���S�E�R�]*(����q����z"_��7�z�3�N�g��-�|���*!��9�� �ޒ��p�}-��2�C�.ˠ�`h|tZ/l�xn�����\��nX���!q�����Ax��l"6��ޒz� ���-�]�˃��d��z��xb��RQƅH�,P��$ًo�0s� �xf��Of�Ä�)�*�~(y�|$w�(0x&"U�3R�~F�� o�[���<�v�H�Zr�����i���4��<��T!zw`�.�~��^���hTp��ҽ��-�+D�(2ïo� thd� �R��YdE�08��L��O�{� �X�0`��Um������,(���FQ>BPJ��v.��T��z�kGG��<A�����)�����~��#�3�f��d��:����./�\��2r�*���A�(��5��y������Zؔp�����H$��a�e I9�Ar{�#t�$�Jt��B���,�<6<��,���M��{O����[ԼCR6�\�����(MR�]r��v~28�-�*��X2��`L���Q7t�Nx,S�RD@钺�K���eR�$R��`ʱDy;����;7L�q�/���z,�!�?4 +�y<�w�5x+Na��YJ:f|��!\!_H_(5$���d���C�ς��Isp�>�������#/�K�·A8�H���:��뜟��)ti0W�� }���ޱ��%�$���ҕ�Q��c~�֣|ۛ�Sp7?�?����y���T���,��q)�����X���)荿�\��H��j&�5:Ǜ �����O�@�`�9HL��^�KD1���Ԩ��#��i�b�Ѵ6��)99w�2��u��������*�S,�4,��,��Jh<m�i��i�B�-4��$$��]}�{Ub�dr؇g(����ڂ]&U��7�$^0����� f�\���Bꉷp��$u+�݈���ޜ�V��11����P�W�m�er��UJ\D>��A�+�3*����FB�j ֚15ŷ�Jt����M�A)x �\f�C�L�2�W�V�6��s]�� �)N�� F���[Y���|4ݹ�ii��n7�c;�\増��-|wI(۹I� ����e�=�Rۭ4�8Fᔎa�1R7DXQU�%��h���)���BI�Ƭ.�Z 0���6k-]�y�%M�5���� z���\#��E#��⒡s�z�^{��sPn��ttlB��@�5� +��)0g o +�>HB Dw7��?�H^3^MxA�I| Ώ��#�Lā}�3�D E���R���%� �$�qGL��£��R�u|@��!��#�N"z!��[��4��_��FY�,�n�ε�d��n�$�����3��tWі��m�H»�=�yɶ- +��d�7h}Ӻ��^{�Q����ij.��P�_�~����c�~ �d��l���*n9ܗ���b�� +}ByI悁�_�5�oJ���C�N�YM��f�<V�.ݽ�s������J��g�H�srLQ8?A8�2#��c7��5)�2)� ���?�n�x�$��J�E�u�^7��k�.��z)��r9�,�/�f���Z�0�m e �I%�A�=u&K���`�ø]0�(�X��#R|K@�%��ڦi��p}h�I.�%�p#�p������֜�8��n�?\����OH��v�*9�gz�Q#���ό�w��Moz�Z�6��p��� ��@�hU��2�n�n%�w����߭���Ƶ'H0�<S�9��8���U����x&7x#S(�IMf4b��?75���B�E��Xn�c���<ܰ���}/���Tu�F\���[z|�J1&���H<��KK�]���� ��g'Ps�K�yWSB='�*��#e56n���w�̿�'���������5�o��;��.~j ��Q��tM���ƕ����W/t�=/Bƞ*��G#��4�b+�N'՞y ��f�BϖO2'���:3��p=��nDN1k"�ح�,��P�5�P���8�m�x��V�.j�U�a�C�G]6�4s@e ^��L�S���ǔ���Ü�O�4� +��t��2&�rjzK��Dq#M����5�_ +�0)��O5������{&�4�_Vr�QU@s.SaPq��yN�:��ɗ�6�5{�H�Ԉ>�g��$�8����-.l��"���O��}DŽr��q�a:$(�$|��6�)��ٷendstream +endobj +3954 0 obj << +/Type /Page +/Contents 3955 0 R +/Resources 3953 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 3887 0 R +/Annots [ 3959 0 R ] >> endobj -762 0 obj << -/D [3948 0 R /XYZ 165.31 468.329 null] +3959 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [260.471 607.851 310.284 616.762] +/Subtype /Link +/A << /S /GoTo /D (userpreferences) >> >> endobj 3956 0 obj << -/D [3948 0 R /XYZ 71.731 460.976 null] +/D [3954 0 R /XYZ 71.731 729.265 null] +>> endobj +698 0 obj << +/D [3954 0 R /XYZ 353.573 707.841 null] >> endobj 3957 0 obj << -/D [3948 0 R /XYZ 71.731 441.066 null] +/D [3954 0 R /XYZ 71.731 697.476 null] >> endobj 3958 0 obj << -/D [3948 0 R /XYZ 71.731 391.318 null] ->> endobj -3959 0 obj << -/D [3948 0 R /XYZ 71.731 376.374 null] +/D [3954 0 R /XYZ 86.396 610.008 null] >> endobj 3960 0 obj << -/D [3948 0 R /XYZ 71.731 325.265 null] +/D [3954 0 R /XYZ 71.731 602.87 null] >> endobj 3961 0 obj << -/D [3948 0 R /XYZ 71.731 279.273 null] +/D [3954 0 R /XYZ 512.787 579.124 null] >> endobj -1740 0 obj << -/D [3948 0 R /XYZ 71.731 229.524 null] +3962 0 obj << +/D [3954 0 R /XYZ 112.803 566.172 null] >> endobj -766 0 obj << -/D [3948 0 R /XYZ 211.497 195.153 null] +3963 0 obj << +/D [3954 0 R /XYZ 202.555 566.172 null] >> endobj -3962 0 obj << -/D [3948 0 R /XYZ 71.731 186.516 null] +1750 0 obj << +/D [3954 0 R /XYZ 71.731 523.168 null] >> endobj -3947 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F44 1994 0 R >> -/ProcSet [ /PDF /Text ] +702 0 obj << +/D [3954 0 R /XYZ 198.969 480.071 null] +>> endobj +1751 0 obj << +/D [3954 0 R /XYZ 71.731 476.241 null] +>> endobj +706 0 obj << +/D [3954 0 R /XYZ 256.752 440.699 null] >> endobj -3965 0 obj << -/Length 2697 -/Filter /FlateDecode ->> -stream -xڝM��������gŒl��%�l��m -���"Ɂ�i[x��HT^�_��"�ae[>h8��M:\l�.�0Hc�DY%�E~{�]\`��w�Pl�d3�����W��x�Y/^]q�,�8 -�h�r�y��j���&�oW����l�������EY���/?����o��� ;�_���<��P�l�C�v$��3�ī��� ���p�҈�V�iL�Mזw&R��^�����sRV1}�-��a��jF�Ek�l�C�s!-�ۉ����_��F�J���"e�O�fP`�:���W���g���F��Ao�0 -21��� -h0_i�d��ɞ������e}خ�U��e��Κ��E�JR!��Z�����/�����B�8O&Q���e�����iV��mnAa�}ъ�m��A��B�@3R&�$����/o��`���ù� -v�p|籁���/x.���uHl�*NV7ug@��a(��"�8e/\]ː�JY1��@7V����y��BI��m�w���D�@�ۮ�-6"�U�,���^L��X���h��G��~���6�S���J�ͣ�sT�O:`H��̬�{S0t)�=)m̯�n��Y�e9�'���ڶ��>[�)��0� e�*�X'Rsw�(Se��.�`��z��v�8�|�P���'�>+JL8Y��x��G�$(I��J���0m����47!q�D;�0U�0y�!��Ox����nu�ǻF�+� ��T��^P�3 -�����jը��r#��m+��C��[�����.fy@���?�0���8��FChH0�x��R��T��:݊ -��(�`�q:�V�g���t_'���U���6���r-D��ck��8r�I���"A�{,� �n�v��`&��J����`0����ƃ�pd���a<(�x�C�E�4�[ɀ��e�����$S�@�(^SR_#ZQ<��%���E��3u�`9@�79�A�>#~�9te������a�.���&M2�W���� -��^���MY05��ǙJe.ҼA��CV@Fy�N��n�J�Qhwf�NF%��~�Y�4�J0�;Qt���� xT�˾}EP�}<� -9rjQ1x��4Ði��&G{�)�R h���/��Z}���J;�,�VZ�x���Q�o�T�#*9/4v/H �V�T!�>3R��$ ��r�E4��-�<������#����"�ѧ.�u��>��$W"�9{�J1%v�%~���$�R��C��%T�/BS�4��ʩĺ����Q��S� �$t���O����2�{�0��9�|`z��(�eT0'� ǀ �,�Uk��H< �lu�B�eƸ 4~w��T7pk�7���K#rT�"��3�H���C7�j�%����G��dX��K��c��ɴ42�qdž��<�4�c��:3HT7]���cN���)�)�rz��M� -^::&&:���a�\'���s�~�w�X�gχ9q�NĪ��*�r�q�$î@���#�]ߘ��+u,����-�|7=��C�tz��x�w�� �t�z��Wz5��t������Λ�Y��x��l�p�J{�!|�C�.x{�/�/ib#�s�7KDIrLW��ԛ�wP���x��&Ud�"��M�2�N� [�@I�q�.]-?���/��%�Z�}��]�oZU�Y��a �"��Q|Uv�첾C1�զ�u^PY�7���NV��+c1G��Mq�B\��]Ȣ���!��3�8.��<��eu��]�Bu|&i�Me���+7�'F/�吋�d5�}/j(q)%T4�TDpd�"2U�S� �2�"�Z�-�œ��@i2p��Z��st��N�_}�7��{}%KW���֝�|]�L�5�(��� -�Ÿ�v.�!���G&�i��]�r�cMnx�J�!+�B�� 0��c��W��<��X������敵L��;4#�E2s����ٹ�aq��u����k �qO���] ���[��e��G�b�J�B��"���?3��"{#���z[��Z�^|�3�m"~{X-�Y2 95<��9<�T@��q0��ӣk�4�H�����:q8�y�b�NU�+F.¦�D�i�ݓ_5��9�7#��3/��Y"�d}�@d�>�q���kѵi�Pp&�n�`v�o&4�}l��.ɺ7(������ǣ��ȁ�q��d��^M�Y?j���@иLd�,� �!��L�~L>����s�< ���c����ā��<yƊ��4x}����ͪ���?����L�����D�k�P�(�}a FL�5�Pb�$���P�e=i��0�Ҙ9Z8�H!A����Q�A�zԺ�}x�R7�L��OM��k'�p�{��RK�*���PC�TQ+�J1�_)a0y�:~ٱ������� �Ύ������Yͅ������VT����̹4xfK|�����M�e����T^ylj�ԉ/p\�qS'Y��]�nF�5E�����1�/�~����2��x.7,��1��"=����d{~��Q3�&b�/�q��� ���;�(�\����\a�\}���}v�g�f��̜�ܺ!6��V� -/���>h��"��\���/��������^�^̞6O�@�e�g��Q�R��3�x�JȬ2O�'�������;�$�:�4H���"I����ǭ�=�%�endstream -endobj 3964 0 obj << -/Type /Page -/Contents 3965 0 R -/Resources 3963 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3946 0 R +/D [3954 0 R /XYZ 71.731 430.334 null] +>> endobj +3965 0 obj << +/D [3954 0 R /XYZ 434.226 420.574 null] >> endobj 3966 0 obj << -/D [3964 0 R /XYZ 71.731 729.265 null] +/D [3954 0 R /XYZ 71.731 361.63 null] >> endobj 3967 0 obj << -/D [3964 0 R /XYZ 71.731 718.306 null] +/D [3954 0 R /XYZ 71.731 348.679 null] >> endobj 3968 0 obj << -/D [3964 0 R /XYZ 71.731 644.419 null] +/D [3954 0 R /XYZ 71.731 343.697 null] >> endobj 3969 0 obj << -/D [3964 0 R /XYZ 71.731 613.534 null] ->> endobj -1741 0 obj << -/D [3964 0 R /XYZ 71.731 595.602 null] ->> endobj -770 0 obj << -/D [3964 0 R /XYZ 255.599 562.291 null] +/D [3954 0 R /XYZ 89.664 322.94 null] >> endobj 3970 0 obj << -/D [3964 0 R /XYZ 71.731 553.654 null] +/D [3954 0 R /XYZ 128.262 322.94 null] >> endobj 3971 0 obj << -/D [3964 0 R /XYZ 71.731 510.321 null] ->> endobj -1742 0 obj << -/D [3964 0 R /XYZ 71.731 459.512 null] ->> endobj -774 0 obj << -/D [3964 0 R /XYZ 159.597 416.414 null] +/D [3954 0 R /XYZ 328.528 322.94 null] >> endobj 3972 0 obj << -/D [3964 0 R /XYZ 71.731 403.976 null] +/D [3954 0 R /XYZ 71.731 307.832 null] >> endobj 3973 0 obj << -/D [3964 0 R /XYZ 71.731 374.766 null] +/D [3954 0 R /XYZ 71.731 292.888 null] >> endobj 3974 0 obj << -/D [3964 0 R /XYZ 71.731 343.882 null] +/D [3954 0 R /XYZ 109.589 271.732 null] >> endobj 3975 0 obj << -/D [3964 0 R /XYZ 71.731 287.094 null] +/D [3954 0 R /XYZ 76.712 230.885 null] >> endobj 3976 0 obj << -/D [3964 0 R /XYZ 71.731 256.21 null] +/D [3954 0 R /XYZ 89.664 212.953 null] >> endobj 3977 0 obj << -/D [3964 0 R /XYZ 71.731 225.326 null] +/D [3954 0 R /XYZ 71.731 210.796 null] >> endobj 3978 0 obj << -/D [3964 0 R /XYZ 71.731 194.442 null] +/D [3954 0 R /XYZ 89.664 195.02 null] >> endobj 3979 0 obj << -/D [3964 0 R /XYZ 71.731 150.606 null] +/D [3954 0 R /XYZ 259.764 182.068 null] >> endobj -1743 0 obj << -/D [3964 0 R /XYZ 71.731 106.771 null] +3980 0 obj << +/D [3954 0 R /XYZ 71.731 141.057 null] >> endobj -3963 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R >> -/ProcSet [ /PDF /Text ] +3981 0 obj << +/D [3954 0 R /XYZ 89.664 125.281 null] >> endobj 3982 0 obj << -/Length 2596 +/D [3954 0 R /XYZ 407.268 125.281 null] +>> endobj +3953 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +3985 0 obj << +/Length 2779 /Filter /FlateDecode >> stream -xڥk�۸��� -c?�Ś�Dђ�-w�= m��CQ� -Y�ںȒ�G6�_�yQ�eg[�l4�g���<�`�ÿ`*�� Sn�*?���`�|�FH63��vw|��*U�V�vϫHk���U�C��p�+~��?f��Mh|�(��ԕ�����ײ������w�@�c�&�M�͕R�^� -�Z���F�QBJhT%N����.�6�6a��Ii�#ۄa�3�h��f��Z����E����L�gB���*k�W�W��:�=�m;^ū#�;ۼ���C[��d;Ű�*��G��(��`M��_�?��o�-��*�c�u�{�� -E'��l��G��4�Y�a�cR��_|� AY%��e 0����y�:5��9����ñ~��j/)f�割�����k3�b��k_�RN\=��=lcn���ҠS�= u��v���� Ee���;��R���0��q�Y��3\G���C[��厍0�d�=ee%:,��zF;%��w#z-�{<���<�U�7|o��Rҁ��e��]ޖ羜�̈���W��� 5q���@�a�W���Ͽ���������!q�F��*Pi�W�]=�=��8rB�|Lo��Bw�b�٘B�^D�H�h�!C���&Ym�qs�����)�D�*�C6A�҇l�Vsp��f8� ҉��H��y_����D��[�f]7���iG7�7�ǁ��[Yw����&�8InGܿ�C�'Y�.�a� -��@��Zp��ښ-mL��33�J`���̧�l]�s�M[���r+8��ks���'Ř�8�fXƿ�+9�]�>ⶄ'Y��Lá3�|�|�t��D�`f�K�!r��"�����=n;��?ud��a�_d-�����a|ëH~t����@0�P嶀��[xWu�K�{A�0X���J�\��d\���K���٬o0B �(���hB�Z^-�!-��ά?�5��ǀU��q`CF!D�����v�r �e�����.�aaf��]Jd<�O���OI�'Z��Ͽ�)�����WI:ed�ie���T����Q����/�}��0!3�H����9�]`�%�Ξ+�tǻ^V���X��E��3�G�W:ق ���d�y*0* �`��){Y�F*��+��O��x?�H�~t�ԟ���+ ����s���*�} ��2N%���x\b�sϓ'>�W���84�^>�i��j�+�`@�7�yb�9�䇦����Jd���R�"-��FL3��o�<�ڲ�Љ��� ��&��A8�͌�Ns~FKF�ɓK�(FEW�S��������P��~e�s�4U~J[���m�۪8��v\^�fV^��h�LÅF`�� �-��q\� Ѣ���Np��o>z��'k����H�a -�/R��[�r4�ѕ���.N��i��(H�I�7�;�7�G!��c��}ş�RDT�ܺhi�*�t4��X��k*t��o�zr��$k�W�Xi�L�o ��������r�l�}�F����h����.,6\�li�{��U��B��@��/��O�mK�hoGq�U�2��{��������ði�c���N�`�7��k�P��}_��T��3-C.��gF`�r[x�F�s �q[�C�ؤq�+%]��6��pt��Ѣ�B�E�����yU�GY�&ޱw���5��/<=k���B)S�X/>G��-���:'S����3���K��ȿ�Yq�k��`��}��R�B�6�/��3VD#+���E�a�D�]����^�p�� �FT'��nR�V��Bh/���i�7���3]t��2M��|��"���`k���p/�����.b�R3.+�Rr�Ȃ��� $:>�9�EK'�9J %W��B# -p]@�t�[�J�_�h|�?�$�N�;�˝WKO$$�D�9�ߕ�٣V3�&�벃��%�>����+���t�01@�n��� -U:� 5m=Ơ��6ULZ]{�;V�3��?w{���ˮm�s�RG=�G��Q3_�%a�\|~����ւv|�+zk�^��A����h����pL�DeN���Z{KB����i�Ic.�ږ?r,��H�@��DS��4xʱ,�-��������$WQ.����뚼�ۋ������m���!�H2��NLJ���y�7�D,bB�$�s�͚�q�< �0� �K�`vyj����V uIe��K19#"��b��������C�"-�jX�b�����Ƈ#��s!<٬d�/�u=����,5[,s[�Rx.�`z��{�ۻ['P�1�Q�5ܺ�;�p{���~'�`�K|���e3;N<�y(I���V�p�?Z.�v��w���>�<�!HAz�C.t�a��hl���K��������;6�YD] ���o,�}h��r,L�����-���R&� _�ό�/�R�MK�eܭ -�ZE?_H5S-� @nElxe@��j��3A}�UI��M��L�-�~&B r��1�j��N��/.�k4�I��K�Dr�C� 凎 j�M��ߵ�����P�endstream +xڅ]���}Ep]�x��@����=��6�����Vbul)���M}I�r���CBQIQ����~ɢJ�*����ӲX4û�b3y���^�0[���݇�lQ�u�-��E�eqV��*K�M�.��?��N��i������Z��~��O��X�k�ӻOۉa�Uq��ޔ)��*��Bm�,�E���Y�{�\'�y�G��<�r�A�̑�R7�Ah��4�]fE4�h�B�jP�Q�����Ƀ�\(h8(��#3�����G�M[��dž�^��I�,��q�Z��~�L���k&�^�2;�j�2-�ߖI���hi^ +����u�"����%x����'�+w +��;��'5F[�z��U�s6��e���lJӴ��2-��LQ r7���O����c�ԩ}̋"�q'�J���h* MZ,@�q�)��8�'Z�3���4Ɂ+��.�N���YY�[�ʍ�}�u�X{"�� +��]���a* T\���&h�DeČ� �ψ��h�����:��Ac�AjӚ/h�I�i�-)i /��f��Z~�s?$I\�?��� +筷�=�8�%�� �I�P-t�02�z����J�P3�G�%NͳLM�?1撚�*oF�7��:�Tu\�!�l�8_��h��l�M@�"�Z(nxqԹ�����[��}Eyd?���^��)�?ٽVWk�٩{p&�?pN�alMsD� ,����5�J&y��6�Ӷ%\{g�,ԠT�k8 ����+�8�ҷ/����%����������+���y��%O���Y��ဘ2�G+m���S������%/��N�^P�\�AB�t +��>9oCE&TϬѼ " +�&��HL!)ݔ>�I�@8��j6e?���q���#`��HL��ҵf�/�������R�m�^Du�{���{!��2 +�0��'�h�?G�ww�0��l�-��%�����88�-gE �7�3���hܾ�@��(�S��gk���=�@�2nt��-d+8��(����*�t�4�ˬ|�a�k^uX^���^u�[^��o�"KU@����ܓn|\��ޘ�X���^��<�&�ί�P��ф�/�RT:��/r0xA�$�ҧR������A�P�_��'�s3�"�6�����9�����/}7�j��5�5,}�3�B��ƫ��Q��fl�Q�PE`�c��+��I�M��}KC:,�Si����cu䠌�"�ɏ�`�W��+I�Xr��LV�~�ĠHc< ��)��g��X;��s�5lB-�Z� xȚt4���d�y=Ǡ�PFS��/چ������,b�މW�^�7˅ɚ����ՁO0���;���j>t>pz�(.D�#�b|��q�q���N���7��ɭf���Ч;���ٛ��Aza�vu�î��[�Qz���4���V�|.�sAq��h���#�p�5�x�YSi�@'�x��s�����ek��DK�~�x�p��؈���a����"܈��$C����_~&��\��G���ݴn�����Ut�( kM�&� ��r��B��n01��"*ْ=Ͳ�{x�~�'�R"��+6F�vR�a>��v��J�T�X(ݘq���}L��y$'��a!�����@?~���D�O4�}�ƐG���u�9���`*?��!kD�� �50B����ug���6{>#Z�� �{�a����n���.��xS 0�y�� ��X��=:��thED���4qC�:�$y��ՇC�0(2�����|썖���O�T(�*_�3�Yy��u��Ի}qb� Y�9��FGKwSi��W4wnp��J��>`���Q�Ϊ�h((��j�L�� +Dç���P��eS����� �jfo�H�b-� +d�'����mVWq�2����9�5�؍f��o @��ES��ލ���g ����(0����&(</x1B����э�� ��2n�t� ����r�v���UʗAu +���!�+�01I�b@s�I��|�1��/xu&�H�P>{�Y$���"�O�D�����)��+3Sh��2�����!�t�:���x-G��P�P�O���\0���rz�,8m�)�6��9a�'����$xIN憘Y�+�c�f�F��@���lƾ�ʢ�˸ݳ��ۭ�`*�_U�&���M���Uq����)j��G{?N%qQ�ץ�&=���ě�GR�멭hj�Un�0����Gt�a��N#�/_J�J|%:�gKC������ϟ��AL$4�)7��wiɳ���s��F��qX���ҵ?G�S��gQo����F��G;��ò,"���n����!��^0�uz6�Y/��:��DN k)N<���;Fs��EX�w�9�$��i����HufJ�;�ƭ�x'}���A���x��G��lD����l�;X���s����a�[��h���M�B�>.qg��k��1#�e/��b"�G�,:���Vgr<�4`�S��e�7j�.�?�)l�� +nHL�`�H�@�E�Fc���S�� K���w]\?�+��L�>��(D��zz�����nI�� b]�F ��4����w;LF��J��H��� ��o(����+�����0��w�qT-S �,R���q�F���7$˿��p1�AR��q�(1Ih]X/���Yq��tt�0��g'A����P�6>'i'I�ߠn��km��7I�����ϹE���i ����>��r�?3�endstream endobj -3981 0 obj << +3984 0 obj << /Type /Page -/Contents 3982 0 R -/Resources 3980 0 R +/Contents 3985 0 R +/Resources 3983 0 R /MediaBox [0 0 609.714 789.041] -/Parent 3946 0 R -/Annots [ 3991 0 R 3994 0 R ] ->> endobj -3991 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [138.415 482.569 190.751 489.347] -/Subtype /Link -/A << /S /GoTo /D (installation-whining) >> ->> endobj -3994 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [364.929 432.646 418.584 441.128] -/Subtype /Link -/A << /S /GoTo /D (installation-whining-cron) >> ->> endobj -3983 0 obj << -/D [3981 0 R /XYZ 71.731 729.265 null] ->> endobj -3984 0 obj << -/D [3981 0 R /XYZ 71.731 741.22 null] ->> endobj -778 0 obj << -/D [3981 0 R /XYZ 182.7 705.748 null] ->> endobj -3985 0 obj << -/D [3981 0 R /XYZ 71.731 693.31 null] +/Parent 3887 0 R >> endobj 3986 0 obj << -/D [3981 0 R /XYZ 71.731 643.177 null] +/D [3984 0 R /XYZ 71.731 729.265 null] >> endobj 3987 0 obj << -/D [3981 0 R /XYZ 118.555 604.613 null] +/D [3984 0 R /XYZ 71.731 680.284 null] >> endobj 3988 0 obj << -/D [3981 0 R /XYZ 118.555 565.86 null] +/D [3984 0 R /XYZ 71.731 665.34 null] >> endobj 3989 0 obj << -/D [3981 0 R /XYZ 71.731 520.929 null] +/D [3984 0 R /XYZ 76.712 603.337 null] >> endobj 3990 0 obj << -/D [3981 0 R /XYZ 71.731 501.003 null] +/D [3984 0 R /XYZ 89.664 585.405 null] +>> endobj +3991 0 obj << +/D [3984 0 R /XYZ 71.731 583.248 null] >> endobj 3992 0 obj << -/D [3981 0 R /XYZ 76.712 466.115 null] +/D [3984 0 R /XYZ 89.664 567.472 null] >> endobj 3993 0 obj << -/D [3981 0 R /XYZ 71.731 446.189 null] ->> endobj -1744 0 obj << -/D [3981 0 R /XYZ 76.712 404.944 null] +/D [3984 0 R /XYZ 71.731 539.412 null] >> endobj -782 0 obj << -/D [3981 0 R /XYZ 188.149 365.572 null] +3994 0 obj << +/D [3984 0 R /XYZ 89.664 523.636 null] >> endobj 3995 0 obj << -/D [3981 0 R /XYZ 71.731 358.219 null] +/D [3984 0 R /XYZ 220.282 471.831 null] >> endobj 3996 0 obj << -/D [3981 0 R /XYZ 71.731 325.358 null] +/D [3984 0 R /XYZ 71.731 464.692 null] >> endobj 3997 0 obj << -/D [3981 0 R /XYZ 71.731 268.571 null] +/D [3984 0 R /XYZ 71.731 435.866 null] >> endobj -1745 0 obj << -/D [3981 0 R /XYZ 71.731 238.06 null] +1752 0 obj << +/D [3984 0 R /XYZ 71.731 402.924 null] >> endobj -786 0 obj << -/D [3981 0 R /XYZ 243.797 200.471 null] +710 0 obj << +/D [3984 0 R /XYZ 263.867 365.709 null] >> endobj 3998 0 obj << -/D [3981 0 R /XYZ 71.731 190.106 null] +/D [3984 0 R /XYZ 71.731 355.344 null] >> endobj 3999 0 obj << -/D [3981 0 R /XYZ 71.731 147.305 null] +/D [3984 0 R /XYZ 300.705 319.681 null] >> endobj 4000 0 obj << -/D [3981 0 R /XYZ 71.731 108.451 null] +/D [3984 0 R /XYZ 96.735 306.73 null] >> endobj -3980 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F44 1994 0 R >> -/ProcSet [ /PDF /Text ] +1753 0 obj << +/D [3984 0 R /XYZ 71.731 278.735 null] +>> endobj +714 0 obj << +/D [3984 0 R /XYZ 209.315 233.58 null] +>> endobj +4001 0 obj << +/D [3984 0 R /XYZ 71.731 224.757 null] >> endobj -4003 0 obj << -/Length 2905 -/Filter /FlateDecode ->> -stream -xڥk��6����`>9@����o�C�������aqh�B����;k;�f}���HvZ�a�EQE�")���M�iM��Ao�Ӄ�y���?�B�������Ûwa���< 7O�M�n�$�4�,6O�O��*uu�����.���������/uӨ�/O�?|�d���ͳ�U�� r#/�����ci>?��)��{��~/H�Ha�o|7��M�7LJ�,+o�O|7J��x�\��a���Ѝ�8ő���UQn�� �uz���&�S7>��O��sTߢR@ o�E�&�҄���6���Mf���}fN�z}�4�I����uxN���΅��#��'�m�9�m��ѭ��;���]�رҌ��1.�2����뎫����3���:)�]y��kE������Ĭ��*�'��ʨt�=>�bԥ˨�(h�Y�,X@�Л� �k1��tC3����U�ÍdBi��t"��e���P~݀����=&�0���jIH-���.e�cK�!P��fW�qo<2 -�&73��% -=7�� ���k�.>^c].�n%��XՃ� -5�c[��c�ʇ�8��w�oxꚑI����dr9��~�ً�����N���.��F�2c��ة&g�������v�#"Z�UwiD��CV/2����ŀc}^J�Z�d,/�@f)���|�X5�I>hA>�G���}q��e�Zj�3������/2�db%�t?�ڰd��ě�|biO�� p��1����0������3;h��.Cs�����գ��~��"ʈ-��+BD��6��Z���B�B -�Ձ ���%���P��be�&���[���Y\F-�Z3�8d��� h��Z�2J�r��G�D�Ż�G�!�Rfݢ�j�����;ؑlzǻ�fmf�3�A+�ry�v����N�F�\��(��,_O���d�� �W�����P�� ®��������D.kbV���Õ���:�{�v��~�ƭ&s���RG �F����ÒX���@v2M�#%mJsr+N�UNrIfsR��rǏ,@� �jE� +��U�V惪98�{�bD��M�ܾTh~vk�|]"�����l`���={NQup�.gj���L͇���~7�X�v���6�b7�1�YWO�)���ups�hJw4!1�;u_~E'۸���N1a�[�7r��'<# �'��y��̨�#��岀,t���&A����֝Q��Xw-m��[��!�?���m�.C�$@d���I�<�{��1}'��`i�u�k��C� V�Ϻ���y?�:�rW^mb�ꉴ�"#Y4��L�l�[PXy'cw�}+��?�OAs�#'�3�fZ� ˔����nY -���33i�����%�<�p8�յd������1��O[�kZK��������s#9)�Y�TrJh�r����6���� �� -��%���gjxjUT2�,k�]�L��v3��T���')��\��.����l>Uu�� ���pa2�Y� -�<�F��;*H1{��T�,c7�����]Qcj��;(}�x���]X����(��eķL��+cx �����x%�Z�FⱢ+w6o���x<�^$��6wn�E�d����Q���Pb����T� #�lv �:�(舢��,���Qa`��($��7�"�I�ݓV�`f�����}�����j�۰Ϲ%���2�P{�B4�����@I�h�u?^���Oی<�8���*n�bvL�c�V��㷫I,�ˌãȉFv��r��e�����8h=VĦ�)/M���֤�h�̪[n���4�c�H9,"n�|���j.�>XW⾄���$�R�����uOԹ%2r��ߖ��'�� ���J�"7%;Vn�}��7�N�C��P������<\�)��8u&C;v�"'ob����P���k�~�*vdO��>��=�;P�ifF+�|4w���呧�s��m�N���0a]���aU� -%@c�GZX�+QDփ��*1��a�J������e�z�Mz�sV=��(���;�y�E������hy���i�}w��Jf55=Ey��D��0ɤE -�e~"�ܒ+�d:��2U?� ������9t�H�oa��j�zP�͙zg�lS�Ξ5���Avm#�Uc|���;n���E4�:�j���%V&8e�@��#�=� - ����Hi-�'�XG넄�����q��+ӂj���d��r�*�}qͺ�.l�.l�4в���[0 -V[F��#0iq�`H� ���x��~{k0��̥���2�MO�~3�1�X���y�&a� R����� C���<L���u� ��\��z� ��<zuu!yu��"�NY���� ���?+k!}����� nr`�Ĉ y|�����R^�W�O<�7��X~���9'�畫'a�r��'�����خb�f��M��<��a 0n9��l�\��f!����<��6������%���<��y -����Q�)U���[ ���לf��āR��BEPQ`��O���ll�yn���� 5n��8xJ����&�Moo&D�8�t���Af�ͣ繞=�.װi\��!^�C����vN=6�e��`4'`\�+���lg����;~X�)��) ����Gmr-o��j�!f��?���0!�q�L^`�:.Ϗ���0N��o+X`n~�q��j�b��vwt�u-�n�J���y�÷U�âB8`8������||���3��>�����oLi���Xhu����N��3�=�.?΅f1��3�q�''�@���܂��*By� r����۵����|��������>��7���Y�������"������ .��_������WFendstream -endobj 4002 0 obj << -/Type /Page -/Contents 4003 0 R -/Resources 4001 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3946 0 R -/Annots [ 4012 0 R ] +/D [3984 0 R /XYZ 71.731 181.037 null] >> endobj -4012 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [192.636 269.699 244.94 278.61] -/Subtype /Link -/A << /S /GoTo /D (list) >> +4003 0 obj << +/D [3984 0 R /XYZ 71.731 148.096 null] >> endobj 4004 0 obj << -/D [4002 0 R /XYZ 71.731 729.265 null] ->> endobj -4005 0 obj << -/D [4002 0 R /XYZ 118.555 689.705 null] +/D [3984 0 R /XYZ 71.731 111.398 null] >> endobj -4006 0 obj << -/D [4002 0 R /XYZ 71.731 596.992 null] +3983 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F44 2037 0 R /F35 1567 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 4007 0 obj << -/D [4002 0 R /XYZ 71.731 545.186 null] +/Length 2557 +/Filter /FlateDecode +>> +stream +xڝk��6�{~���l`�ZO����5E��h��I�e+��u�_�D�nRX �Ù�p^���������!|��$�"�^mG���/k!Y;4��_}�6{o����|��&�b�.�ه囓:w�Y��x��=���������,����_��<�í�߅_����(lG���6;/�"��|��������*�,�\��R3F�g�l�*�+�Jլ���h)�N��J��##ZS��Då�Iu<��2TA�Zgu��m%����ln� +bQ�a��M�Q±2m7�g�/A�� FZ�����P���>jv7 ]�a(ZT��1��C!4�]�(S�:�V?��f�R��|�hA�Dş�A��2��D�hI����'[�y�YU�E�5�C��M�49qE�vpȪ+L͘*���աģ���s�����H�`�%A��G`m�oA��p�:�R[l�2�U6մ�'o��( +t�=�g�ۢͿ� @[�%h�%3��`f�Y3�m��i*� q�0�L�3�!��h�&�g��vt�c�<Y��'<&����Y�?`Y��nO�y���\�� +6���h�#�X�ݍ��*�s�.u�����`���t�5EE���n$�R��hR�7>n6A��5;���� +Cv�� �p"��Gt�p�u����G���B����j�:jb湜��$B[� �P�)2�y��iW�G�+η/;�B��z�^D&j�!Ǜ�uo̎RN0w�w8$N�P�@Ყ�5��b��fhɹ3�9�'���~bC1��)�nH1�-�,E�Tq.�溙����w��u7V3[�q '��1��������4*c�0d��~�����Z]�O�E�%���b����%�{bB�W�"��y_�"� ���<]F�����<E������V�d>�EJy�>N(���m����&��� �+#��C�A�?˂k$C�$�0�]�=x�e�PӉ0�:"Q�D[���-�(V��4-���(1��@n#�66^D� .�k�Z���)�SV�a_���:�Ȃ�*\��S 6X ,�{ᖅ����%��� +1�����Q�:��=sr:5`l<?����UzRμp���7dH[4�?��e�d�9�C��X�59l������'�B~d��,�`���إ�%�_> +��ܘ3姄�72c'� }#sK%)y"��C��i�?3u(ʢC��$�=���q�QdTF�6�AC=��S@���H�C�ʘ�F��ʠ�U�?՜H�� Ƕ��t[)o��d�/�����e�1oQ�`���Z�����_�� ���F2A+4�8�����~Xt)��\G`�*dѻ��:[���o���*�F*떶N �B��!+�=q����������}���`MQ[a��h�7���p]��%!�0{ �AXv�ujJ1Y�� v<�����s)H��`>7W�ߴ��J�P�Tp�]4)hGI�L�q���V��4��e�T�P��>�z���<��פ�w��g0��<�js-��{�߁gO�b��tE*m��Y�H�+Gڷ-/�� ���{�5S}8^�L���D�=m̆�NE��PB�4ش1m�n�xF;ۉ�kM7sC�6��Y�)�Ii̘@T7�6���C����C9w�X}]`����-������L���`[�b� +z4������������2���Tc��!��Xnגu��K���ۖo[��4�z���S��o��w�>؏w�Z��z�зM��� rLa�U���E�]��d�Sԡ:,Sh_edug�y����O��8S�N̷X> m��Q����5�z���-���z��c�+sa�sZ�h�è�0F-�����-V3Rg�0��CΌ��\��O֑���"�0�P0�����I;&D4o��xrqu��?`�T�k�&0�@_�k�kúh�E����@�J���Ë(I�ӡ����P}`�������~,|��W;^�t���ŏ�i*h��m�� ��G������=�\ �I�w��N��)2��\ܾ��ê8^z<�[۽�P�f��N2�37�B�7�1Md*�fZܲ�)�� + ֘3c(��3g~>[�<�ߵ0�}p�}y�mf9�|�Ӄ<b���ll&q��!�`'f#�֧�p���g�3���'�4nC���W�@�k�V�=�-�r{�6?C嬧��� �MT흨 +%���ꆰ��x��L:/�Z�{E��P��c�i)�y��^9�ơST#k�hy� Q�W�Ÿ^l��?��E�us"�I��(gprE��D8r� ]�����m� A|�*���Σ_���3�/�N�0!Ѕ^J��1l�d���[Au䫷#��������M������UE���䶢�S D5\�F�P��*���3j��-�!��;��H��Ԃd��F~`$z�&}��J2%�;P��D(�k� xs�yo�O��_`_��m���` GFٌ~�`bS�=_�1�_�JW�FT�����oD��E7��~���!���D����oy�\��v����.�$7?.����� *����᭤��ӧYendstream +endobj +4006 0 obj << +/Type /Page +/Contents 4007 0 R +/Resources 4005 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4022 0 R >> endobj 4008 0 obj << -/D [4002 0 R /XYZ 71.731 530.242 null] ->> endobj -1746 0 obj << -/D [4002 0 R /XYZ 71.731 457.878 null] ->> endobj -790 0 obj << -/D [4002 0 R /XYZ 233.582 418.506 null] +/D [4006 0 R /XYZ 71.731 729.265 null] >> endobj 4009 0 obj << -/D [4002 0 R /XYZ 71.731 408.141 null] +/D [4006 0 R /XYZ 71.731 718.306 null] >> endobj 4010 0 obj << -/D [4002 0 R /XYZ 71.731 365.34 null] +/D [4006 0 R /XYZ 436.472 695.392 null] >> endobj 4011 0 obj << -/D [4002 0 R /XYZ 71.731 334.456 null] +/D [4006 0 R /XYZ 169.318 669.489 null] +>> endobj +4012 0 obj << +/D [4006 0 R /XYZ 176.588 643.587 null] >> endobj 4013 0 obj << -/D [4002 0 R /XYZ 71.731 269.699 null] +/D [4006 0 R /XYZ 71.731 625.554 null] >> endobj 4014 0 obj << -/D [4002 0 R /XYZ 71.731 254.755 null] +/D [4006 0 R /XYZ 238.395 612.702 null] +>> endobj +1754 0 obj << +/D [4006 0 R /XYZ 71.731 571.691 null] +>> endobj +718 0 obj << +/D [4006 0 R /XYZ 200.128 534.476 null] >> endobj 4015 0 obj << -/D [4002 0 R /XYZ 71.731 205.704 null] +/D [4006 0 R /XYZ 71.731 527.123 null] >> endobj 4016 0 obj << -/D [4002 0 R /XYZ 71.731 159.711 null] +/D [4006 0 R /XYZ 71.731 481.31 null] >> endobj 4017 0 obj << -/D [4002 0 R /XYZ 71.731 135.866 null] +/D [4006 0 R /XYZ 71.731 452.583 null] >> endobj -4001 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F44 1994 0 R /F27 1180 0 R >> -/ProcSet [ /PDF /Text ] +4018 0 obj << +/D [4006 0 R /XYZ 71.731 452.583 null] +>> endobj +1755 0 obj << +/D [4006 0 R /XYZ 71.731 374.721 null] +>> endobj +722 0 obj << +/D [4006 0 R /XYZ 299.665 340.25 null] >> endobj -4020 0 obj << -/Length 953 -/Filter /FlateDecode ->> -stream -xڝVK��8��Whs���FO?zl1]l[�6Ţh{Pm9�i�L'����m�AQ�D�I� s���I�i&a�&e�bd��W< ��I����K)IA�T�MM��T�)ɤ��dS��^��~��8�E���vl�-n���5mk⏛W���١�-r�dLJ(�XA.h���|^���H�W���_V� $��Ӣ��`I�z���l��D��|�� �+ ��L�$MM?�HH��*u9��S�s�ͳ���X��z�H��K�HI��C6��MJS���]��lj"*���Ƕ=���ֱd�p�A��e,Xt�3�N�]P�_�a��q4� �]��)w�]ipv)JԸ�f8_k�`����譱�4;7S�i&�m���c���*�9M5�s4}���P��c��<:�/�&�li��X����2B`<��j;Ӵ�oW,T�@�Er(ɨ�Sx���:S�4T�}��vM���A�i -7���1.؆ ��9s9<�]�4�EP!OI�]�j$�B{�����W���k���W��"�*��1�� -EGl�'<���ձ�7�9��'8Ν�����쬙��Q職� -�������^#�=�f^�A^~�@�c'����PDW���}��R3���*5���D=�M�٪��D��?z�qj��� -����P+(O"`d���&��z�M5�Ǹ�E�h�"o2��8��|��E�m��"�����TC���R?� ~�*��8(�P ����٬`N���v����䠽�]�Q�y1MC����++`y/� �P��M��I��r�X���#M)?<�jM�s;}qNQm��|�4=nL��v?����OA>Y�͈�<�,���Њ��aF���\��d=�;4<�ۇ�-G02gQD�P5��K��0�vh�٣r���ɏ���[B��21q�d�G�מ��%�endstream -endobj 4019 0 obj << -/Type /Page -/Contents 4020 0 R -/Resources 4018 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 3946 0 R +/D [4006 0 R /XYZ 71.731 331.612 null] >> endobj -4021 0 obj << -/D [4019 0 R /XYZ 71.731 729.265 null] +1756 0 obj << +/D [4006 0 R /XYZ 71.731 290.337 null] >> endobj -4022 0 obj << -/D [4019 0 R /XYZ 118.555 689.705 null] +726 0 obj << +/D [4006 0 R /XYZ 364.509 254.97 null] >> endobj -1747 0 obj << -/D [4019 0 R /XYZ 71.731 647.664 null] +4020 0 obj << +/D [4006 0 R /XYZ 71.731 246.332 null] >> endobj -794 0 obj << -/D [4019 0 R /XYZ 266.363 615.268 null] +1757 0 obj << +/D [4006 0 R /XYZ 71.731 203 null] >> endobj -4023 0 obj << -/D [4019 0 R /XYZ 71.731 604.903 null] +730 0 obj << +/D [4006 0 R /XYZ 295.625 169.689 null] >> endobj -4024 0 obj << -/D [4019 0 R /XYZ 71.731 580.035 null] +4021 0 obj << +/D [4006 0 R /XYZ 71.731 161.052 null] >> endobj -4025 0 obj << -/D [4019 0 R /XYZ 71.731 565.091 null] +1758 0 obj << +/D [4006 0 R /XYZ 71.731 104.768 null] >> endobj -4018 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F44 1994 0 R /F27 1180 0 R >> +4005 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R >> /ProcSet [ /PDF /Text ] >> endobj -4028 0 obj << -/Length 2484 +4025 0 obj << +/Length 1822 /Filter /FlateDecode >> stream -xڝYK�۸�ϯ�-T�C��)�nRުM%5����8$%1���ʿ>����l�\S�@�я��a� ��$R$~T&Tl6��!����$���X(�`|����Dd���<<�M� -El���~:%�B�x�R��?���;��A,�����T��ލ��u����^~p<e"�4�3�Õ�ı��d/�8�ӹɇj�5j�2�d��,��HIaPR`���T�u?t�`�d*(�:(l��0T�����p��Kc�G"�mI�}U5D�{���2�9�[=�8Ъc�Ua���K�������#J�T=�mG��V�A^�D,� -��pN�����֧���2���4�4ap��48�.��b��'Ƞ� [/4χ./y������VxЛ�=L�ĮG�8B����q���Il�8���/���ڛ�y�;�%p���RU -f*��\�4]���T���n����lAC�M�H�=)=�jN�I�~`j}�할ه�O[c�~͉WZ�e�{�g���M���[���T���a̽�� -"��]��Q�-�W�$��3��*����*o���� ������u�ӽȊ ���/V��@��I�H�c�ί�-�,��*�*f�������������3@EBG1��i�=�Fx+�=�ԗ�껺�{�k��^��<tc�p�B!UD����SO����B�~b�Ӽ�x�1��btJ�i�T3.4wY�� <�I��&���U&E�������E�E�S^�Ȣ��HC��!�[�1'�X����]@b|�6"���D9�U�) n 7n��28�D"5 u����+�����o[p:��s0���g�B�@�$��|���ܬ�'ϝ���o���?�����q�L,mS����ք2JDFl��N�!���v��%@�1�7��?�/���A�i_��ӽc%�lZy��x����-�S�� �wUCw{�N� -C����b������� -�s��>��N@G��l�ؠN)պx�4����U{����m�w���K��c}>��@^�#�x�7���$�&J�СDH��ï���������=��H+��lq��MWm����8��������%�v^�]��Z��3�B�t�ȹj��m��Z,����ha�*�����\%nc��0CL��&�t10�L��Ӭ�s��+��T���X�Eg�"Gt)m\T: -�Z�a���j�7f���G,�r�@1$��sM�3����)X�� I%VZ.(��M��XB�;{�Q��%���4"{��szGpj���hNz&���4>�F�"�D��������j�P\�Ssa1]1��Iȩ�F�F��u-���Ct��`:�)�n��v��Ȏ��G� .aB���W���ud��J���\�*_<8/��� -b� H�����ٔ^�˰7��gq�m�1 ?�NܲoG�e�c�ݏ}n5u -�eSͥ|�y������^��H?VЙ������݂J��q�An����j{���;���=����n���Z6��� -�˝��48�=��Z�P������K_�W�L�TZ�{+���7T�N5%Nj5�$� �&����0��K��l0$�`�% ��\�eO�d=T݅�d���s�=��uqı�Ͷ�Q�ppf&A�Y��ωL� �Ӓ䠧۲�$^���x�[�[X�����Yl��L�?No��c���QG���3���o����{,�Gz���[�2�,Ln˴�/V62TBI_� ��|��M�4ē^���+�;� --�e��\��"B.|Y>�D��0����K�+��X{��*Ül9}�Ktʕ���=����G����/���|0\��;�s�.��ʷ�d -�쁅ъ�Z|�ו�[,#���tdz]<��i &$"��$�Ehr�7z�ස�#�.��4?��c5��sz�!�˛נ~n��B-�D"�a���u�a��Ϸ%�2.E�Lk��\Lg�T�r�=҄������0$آ;�#�/�%���!�H<��kv��*��M8IA�Fx��� w�e�a��v�a�%��i� 1��G�v0�����+"9$�;~$��b�1��\W��Ղs���m��,ŭg�$���.�(�!1N������ᄈHG{�/*~��҃�����k|��5�(���� -�0��9u�弦�:�U|��}vί)8���[���W>q|��,�NfԌL�|��� �U�%�L��۰�H!�QJ�PXXKpd"բ�r�uuY� &�q%���;z��5%y$K�B��|l����"L������K�e����&2V"��M�У��J>�1�Ga�F]�%R�(��� -+��E�wSk�aſs�������(=�7E�V=� -��7\&\&���`�p�!p��"D����+v�W�C�3�(P��LP1��iE���nO�no�*endstream +xڥXmo�6��_a���9�ި�`�v��!Æ�Zl�@۴-D�����yG����@ $�ǻ�s/<9��β��b�R6��W�l;?_��qM,�ϛ�ի�q<+�"�g��,�c?N�YG~�j�����[%��u���8��e���a�oYU|���w�Q!�3���m�<gFE�,��1m��\��q�������hk��{+AK&��7[�����|��)6��M�+�#n�Xā��f�A_��&h��u��ET��Ex�����yG�bS="����e���PH5�a�;�J���\t�k��;��X�����K:�sT���D�u/�A 4n8���`�(�;jxC�*��t��������-P.èiy�0>�M�Қ+\s\��p�p�T4��Ф*7��is��w���K؝kg�PC��U�ؑ)�j@��tR�$䰐����.!)/6��^U@�����f�h��^h�s�oU����kw�4�=9�����o�(]Us<b��Q���X���u�#W�� g��{�Sƹy�$��$���R�4�ym�4e2��7dy�4ɳ��L�R��2zT����1�2%0�O�M��N��u&���bm���ܗ��̣�^�B6�M�w�O���-_�z5ҏ���1�ϣ���x'p�xE^I���s�H�%���c6" +o~�pÙ�c���u���3�#`q|oc��W���P)z� +�C����Z� O���^���C/lE��ږ�f�{�䥐.��N)��g�+^�<j���yb���Q��F{��:�y�`��x-p����L��'��̭�s����+�$���@�'���s�t�j������Os�[���v���ϟ����`cSj��@yb�Y�ȱ:�g3c���{��p2@�c;�$�8io�����M�h�ྫྷH7 +�z*%l,%�T��K\@�����b�Jv�?��P���eGO�L9FE�xZ�8zVq���ң2#��D0X�]�ꋙZ�����D�6>ƚh=�Y04�jh�ii�y�{���<!�����Vjt�XQK���ԙ�h�˰-ǧ��j�z [��u��?���2���v#�:I���=y��r;�����pߔ&A��r����`��VN��x���W�����q��k��y;�Ԃ����y����Q��eR187����nw��H�u�!.��w\;�+�I����� +�-�K�G��b�aJN�Ɂ��I1_�m�a�:(���'�<4 +���4E;)��1j����}[����vnlGI�ف/�`j%�!a�:E��-�)��FK�q��Y4��u6(�17^�p[��a�#fD8K3h���a)0�`�V��S5��i�]#�����R��y�߃�p~,M��%ur;lH,��=0]J���ƽ�L�N���Fj�b�#u���@)��c�vY+�/�l�̻Ex��� �ܝZ�a�����qO�#RkNUɬ�(=�`�����=��hb�9_�@���H���EV���A���5���20��$���A���ի��+��րSP� :�.F7��C6��EW����9������)��Ѕ|TC��;�D���h��{���{�l ���`���۟�$��P|.�@ Z�@�ߘ3���(��ٌ|a'lB6��i܃L�e�!iz.D�H��S�9����R�A=1%q�+�yY)y���щ +������g�/1�/�_�'ar��7iˢ$���J�>U��p�S�@��~f/��6����Ƣ�F)ڤ4}�G�sU�a0�endstream endobj -4027 0 obj << +4024 0 obj << /Type /Page -/Contents 4028 0 R -/Resources 4026 0 R +/Contents 4025 0 R +/Resources 4023 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4055 0 R -/Annots [ 4032 0 R ] +/Parent 4022 0 R >> endobj -4032 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [390.612 583.608 442.915 592.519] -/Subtype /Link -/A << /S /GoTo /D (template-http-accept) >> +4026 0 obj << +/D [4024 0 R /XYZ 71.731 729.265 null] >> endobj -4029 0 obj << -/D [4027 0 R /XYZ 71.731 729.265 null] +734 0 obj << +/D [4024 0 R /XYZ 378.198 708.344 null] >> endobj -1748 0 obj << -/D [4027 0 R /XYZ 71.731 718.306 null] +4027 0 obj << +/D [4024 0 R /XYZ 71.731 699.706 null] >> endobj -798 0 obj << -/D [4027 0 R /XYZ 387.39 703.236 null] +1759 0 obj << +/D [4024 0 R /XYZ 71.731 656.374 null] >> endobj -1749 0 obj << -/D [4027 0 R /XYZ 71.731 692.184 null] +738 0 obj << +/D [4024 0 R /XYZ 288.511 623.064 null] >> endobj -802 0 obj << -/D [4027 0 R /XYZ 303.155 651.159 null] +4028 0 obj << +/D [4024 0 R /XYZ 71.731 614.426 null] +>> endobj +1760 0 obj << +/D [4024 0 R /XYZ 71.731 573.151 null] +>> endobj +742 0 obj << +/D [4024 0 R /XYZ 259.078 537.783 null] +>> endobj +4029 0 obj << +/D [4024 0 R /XYZ 71.731 529.146 null] >> endobj 4030 0 obj << -/D [4027 0 R /XYZ 71.731 638.988 null] +/D [4024 0 R /XYZ 71.731 487.871 null] +>> endobj +1761 0 obj << +/D [4024 0 R /XYZ 71.731 454.929 null] +>> endobj +746 0 obj << +/D [4024 0 R /XYZ 240.476 421.619 null] >> endobj 4031 0 obj << -/D [4027 0 R /XYZ 71.731 609.511 null] +/D [4024 0 R /XYZ 71.731 412.981 null] >> endobj -1750 0 obj << -/D [4027 0 R /XYZ 71.731 583.608 null] +1762 0 obj << +/D [4024 0 R /XYZ 71.731 362.675 null] >> endobj -806 0 obj << -/D [4027 0 R /XYZ 308.598 546.392 null] +750 0 obj << +/D [4024 0 R /XYZ 223.845 319.578 null] +>> endobj +4032 0 obj << +/D [4024 0 R /XYZ 71.731 307.406 null] +>> endobj +1763 0 obj << +/D [4024 0 R /XYZ 71.731 295.862 null] +>> endobj +754 0 obj << +/D [4024 0 R /XYZ 223.569 258.646 null] >> endobj 4033 0 obj << -/D [4027 0 R /XYZ 71.731 536.249 null] +/D [4024 0 R /XYZ 71.731 251.294 null] >> endobj 4034 0 obj << -/D [4027 0 R /XYZ 363.706 526.268 null] +/D [4024 0 R /XYZ 282.496 212.619 null] >> endobj 4035 0 obj << -/D [4027 0 R /XYZ 219.335 500.365 null] +/D [4024 0 R /XYZ 71.731 179.543 null] >> endobj 4036 0 obj << -/D [4027 0 R /XYZ 320.961 500.365 null] ->> endobj -4037 0 obj << -/D [4027 0 R /XYZ 71.731 487.413 null] +/D [4024 0 R /XYZ 71.731 179.543 null] >> endobj -4038 0 obj << -/D [4027 0 R /XYZ 157.2 487.413 null] +4023 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 4039 0 obj << -/D [4027 0 R /XYZ 71.731 485.256 null] +/Length 2257 +/Filter /FlateDecode +>> +stream +xڅX[o��~ϯ�R +�^D�:o��)��X)P�A�&W�6���Q~���R���0`�ggfgg�*�E���q�N�l�d�͊ûhV�����E�VDn'2����%Mg�p�Jg��l��a�Z��i�Y2ۖ����j{��o�, +�����i*&?�wS�j�e��w���`���M���'/s�T�>9���a�\�Ow`z���,X��N#��cN�W=Sf�ϣ�ձ�L)~�̓(*^4��etl�ݼ-�~q����P�L�CϮ�{1�:���v��F�݈q�����Y��g�� ọ�p#w���֦�j�E�.�b@#��m��(�6��@7F7���wv'O��\�F��Y�������YJ&�0̆u�s<�l���I�0N2��l���#���3#Q�USQJ�F��S��W�=<c�\J�e}]� /����uf~�P��9�t�iuכfT�[�R��*����B���Z�(��w���4&��4d� �z5N/x���A�p�:0�j�֚�it��S��E��$���L��t�_!���sp�����<��oT�\��������e`:�X��M��Qv��Z&�.�xw-k���d������f����2Z�������UJH�1��⿃u�,E88]�-��1_����?Y�T�h|'�X�R̢)���lu�&}b1� �/�Bn;Ŝ�L��6�B�d�:8ÎW�=>����_.�{w�`�j�3Mj��5�HgFs�o��r\\����Y��O)Q��p+D*1yy��5M_Ý2�F���A��_pwG�'�Q�YWX?�|[������e8:�'egl�y��;�$H�T�)�xJ�\��gS5,X�!�����(7�J}#��l#��t۫����M�FuL�V^�{\H��^�p�����`���n�k��x��:I����b��G��˫��9 t�Q$�w��?J<�^�I�Uo,%=bG'� ��O��r��t� �S���=2�0������<��d+��.�$�(�APjJ�®�v�i��]gLiE� ԩ�e�I�" +%n8���)����"7��ۛ�����]���� +����P�C���9���c�`B��4�{5�{K �@� +N�IHӰâ�mf1�ľ�Mm����h�EZ��x%q@K{#<�y��Πj'~8��=���Ty%�Nj1��(�y ������pA<y@A�"��7�%<�k�!9��ӆϷ_���"b��Ha?Qo��!�M/�n8p�s!s�/r������Z�@��E�,�x@:uw0�$ѥ�&\�N��LDܓ���r�Waz7t<����n2'x��8Xlr�������� +4��a��5��@�u`�0�6���:�,���?���L 3�����2ϵ�'rd�YF�cB���Mt�63L�\�:�#4��ٸ +�ΉR� �%��f��?��T�%.��mK�%�Wr���i�U�M�C~#MX;0��( ��Ah�� ��4�*���JFsmgїo�O<i��d�=e���^�5���mS#oH�B���E<�Fp���,[�-�þl�j�U^ ��m�[DOx��U)�|�`A����X�ڸ^v��4̢6�d{�S�]�?��v�f�d�|h��)4���� +P�) �Քĸ�����S@M�Z�~n��g�滰(��I�A��+/Ls��O�%�Q�X�G�p^K��^&�4��P�4��y�H���n�M�Ee.�b� �c��e�X��ă�:�6��7�J���s7�1�K��-�eJ1�z9�;�:�|���ڗ�][�8��"����P)k��+���6�����3g�}��N����=���bOcƛ���Ǻ�����z���h}�S�Q�J�ݜ�%~jt�H�������Wx�||X���8��D�H����/d��E��2G#� &E���N�26Xf|ם �u��h���ݕ"- �p���9����"#$�|g�����;l����~>87�s��f���d�� �ƾ�V���H�d���OϏ?��(Lҕ� +q$��'�%��wzGJ;;��c�SC߫���W�u�gAm������Y��sQ"�?Z���+8<�u�� +G�^ԓ��6��^y��� ��cI�dį�^�w�xv�I���Ŷ����y�c[k�݇N>ǖ]�D�O~<���qT��_�������2�x���O"�gg�:\e�ty�������� �endstream +endobj +4038 0 obj << +/Type /Page +/Contents 4039 0 R +/Resources 4037 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4022 0 R >> endobj 4040 0 obj << -/D [4027 0 R /XYZ 118.555 446.692 null] +/D [4038 0 R /XYZ 71.731 729.265 null] >> endobj 4041 0 obj << -/D [4027 0 R /XYZ 165.524 438.228 null] +/D [4038 0 R /XYZ 71.731 718.306 null] >> endobj -4042 0 obj << -/D [4027 0 R /XYZ 341.284 426.572 null] +1764 0 obj << +/D [4038 0 R /XYZ 71.731 690.311 null] >> endobj -1751 0 obj << -/D [4027 0 R /XYZ 71.731 392.995 null] +758 0 obj << +/D [4038 0 R /XYZ 185.739 651.039 null] >> endobj -810 0 obj << -/D [4027 0 R /XYZ 347.534 360.599 null] +4042 0 obj << +/D [4038 0 R /XYZ 71.731 643.686 null] >> endobj 4043 0 obj << -/D [4027 0 R /XYZ 71.731 350.234 null] +/D [4038 0 R /XYZ 71.731 571.97 null] +>> endobj +1765 0 obj << +/D [4038 0 R /XYZ 71.731 543.143 null] +>> endobj +762 0 obj << +/D [4038 0 R /XYZ 229.91 503.87 null] >> endobj 4044 0 obj << -/D [4027 0 R /XYZ 71.731 307.434 null] +/D [4038 0 R /XYZ 71.731 493.728 null] >> endobj 4045 0 obj << -/D [4027 0 R /XYZ 412.638 296.639 null] +/D [4038 0 R /XYZ 101.182 483.746 null] >> endobj 4046 0 obj << -/D [4027 0 R /XYZ 111.263 270.736 null] +/D [4038 0 R /XYZ 71.731 465.714 null] +>> endobj +1766 0 obj << +/D [4038 0 R /XYZ 71.731 409.858 null] +>> endobj +766 0 obj << +/D [4038 0 R /XYZ 319.355 366.761 null] >> endobj 4047 0 obj << -/D [4027 0 R /XYZ 71.731 268.579 null] +/D [4038 0 R /XYZ 71.731 354.323 null] >> endobj 4048 0 obj << -/D [4027 0 R /XYZ 71.731 253.635 null] +/D [4038 0 R /XYZ 270.862 345.201 null] >> endobj 4049 0 obj << -/D [4027 0 R /XYZ 71.731 204.584 null] +/D [4038 0 R /XYZ 71.731 325.112 null] >> endobj 4050 0 obj << -/D [4027 0 R /XYZ 71.731 178.681 null] +/D [4038 0 R /XYZ 71.731 301.366 null] >> endobj 4051 0 obj << -/D [4027 0 R /XYZ 213.956 165.73 null] +/D [4038 0 R /XYZ 341.586 301.366 null] >> endobj 4052 0 obj << -/D [4027 0 R /XYZ 71.731 163.573 null] +/D [4038 0 R /XYZ 89.916 288.414 null] >> endobj 4053 0 obj << -/D [4027 0 R /XYZ 71.731 148.629 null] +/D [4038 0 R /XYZ 71.731 268.325 null] +>> endobj +1767 0 obj << +/D [4038 0 R /XYZ 71.731 237.441 null] +>> endobj +770 0 obj << +/D [4038 0 R /XYZ 256.243 194.343 null] >> endobj 4054 0 obj << -/D [4027 0 R /XYZ 134.999 139.13 null] +/D [4038 0 R /XYZ 71.731 185.52 null] >> endobj -4026 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F44 1994 0 R /F48 2006 0 R /F32 1187 0 R /F33 1278 0 R >> +1768 0 obj << +/D [4038 0 R /XYZ 71.731 157.676 null] +>> endobj +4037 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F35 1567 0 R >> /ProcSet [ /PDF /Text ] >> endobj -4058 0 obj << -/Length 2963 +4057 0 obj << +/Length 2556 /Filter /FlateDecode >> stream -xڝY����~��4���oRI�4n��/ �8(q%ѦH�\F�����c)�$�E`�9;;;;;;�U0��/�e��E��+/L���p��v���.P���,'4_>�=|E���J���v����,�B/O��c����8Z�-�a��SO�/��ꏪ� ��a��"�Wu],~}����q�$ʼU}R8Gs%]���s��s��{����lڦ$؟�ݷ��ۭ�6*pa���%�v�u�Z��QL��S;�S2cݞ�"H���;u�e��ˏ;�+Js/����T`ڝH��@��2�����DQ4��fgz��n�b��0u�[O��}��$�g���œPu� -$ˉ��&)����&�j����c]��߯pg'�VY��8���h�3��a>�E���V����"��ƍ����{�U�Ae���w7]�X�L���u�.� Y�X]�7�ӎEYufc��I�P?�Z� �7�uB8ه��_0/��~�F�H�����A�&�W$�.)ͦ*����!;��.�CU͠$zw�UI�E��O�Кñ.�(�&�hr����]��|�v�������y��͙�T�[<roq?�@]����u�$3�Rz#{�5b��Zj��-$z/�,@U����V�(�L˾`��_�n��=A���`�Ή���(��,��v�|[Rr�1��k��O�.�V\,#��9H�e�0g�������3�)z���Ҟt�4<v�`[�\���9h��+�B%�������Q��4� �����p3:�M~��[��&�I\$T#��0�)jGe��S�m�ȫ�M�U�E �v{�������j�D��Q?�e�tt'�8�U�3M��t����8���G)�� l9��C!)j�K4�M�`9��U;8z�W�zw/ ��J\��g�C��f9�tJI:@��N�|���s�C��0�#��L��]Y���9 �V�=�+�>�c^I��!�3��f߶=��^���̠�����%!���TK��\�)\���_���Æ|tuc��������#����U�V2+I�Xb]"XF�ȋ�6xi�11��(9w�R�� �� =hZ�����ijoD�(�<~�7f��*�=�y(Ͷj{}�U�b]�v@� -|�x�:���d�!6��1я4������|�Ej�ki�1B�%���cR{�jD^�ų$�0�����/�����w�{���Ǩ��l5����l{���_#'�r�_ş�!k�.�f�t�,�4�D���fA�җ��%�,^e^�|֟1rGרm]h'�Q��������"G�H��ēS/wwߙ�Y^��R/��z��O<��{V�{�*���хca�ѱxTȇJ�Jhl�p}����irq�e��2�-I|�A<����sU=t�3��8�zQ=s��2U��{�j�qmPqƐ�A|��jB�#:m��4\�ax@�-v+�| �yW�lbs�|�w��8��y_�:B��ێ�]a$^��|Ó3�u�I����]��*�C`l�:V��Od���V�'sZ�q��0�xR;@5-�>�1s��0P��dC�"�\�\����Ce��u]�+ f�����z�+��r\,�9r��\�v/֪盆�Q,�X�Q���B!)8����GفVLI��ˈ�������%�n�(�_�7��=������������t���� \��v�T�=�3�Koo5X���<9,���>����b?��O�->,�.ᬛ|\d�Q �_[�#�#�=�?��"[K�ǯ�8�H|������B�̾��j�\D�6(�d���QIL�c�y'�p�U�2y6��Vl6�Q�[A�t)"d�Qa+X�M_�$�.�j�&�L'��Y�[���� �l3�.*�>�p�Z�TB��a\w���R��|�t�Hʿ�5.� ��hi�U�V� �h9��?n|���Gro)�����ƚFǢ��f��N�m�Pe��� -ȥm��_�H�èV�td�t�4����z��a-����cU(�}����4N��wp�~m%���w���Q_O��`/_E�ۋ�2 ��HD(y���m֓�[x]�S��l*n�T�4��+68���S�P�����yc9M8q��oV{�I �3ΥǤg #c�~|�q�5O�����\E�:�%/��R��*�$��)t��c����_x2��EhxƄ<��.��B��φA$���I��X)�o��3G�>��N��������V���*�/&��{أ_�.���7��_�:в��������H��I�� -k�ͻ���MI��� C�+�\��>�,{��u�W4p -V�q�C0ms�����xN/T������甝�������x�y��n@�"N<�tZ_�����{?@d4y>5��c xnŊ�:e�j�0_� U������Ze��@,sv�<��"OD�Z/������E#��/T���U�։d�Ԑq��ҭ�uy�.����0Ձ=��Hb�02 �ԩC�[!��=�rb�AR�X�����@E�Z��[;�m��sj��\�nu�.Q����b�3�oo�w�P��wΆ����7%�xK�J�|5�?�x]ݟ�y�g/L�ܫf���fL�ܫ5��!-��Y��j�˛^Mſd�$>W+2��[�g�ʳS���I�D� ��7�d�kބatl��N������K -!D7u�cA� �k:�[���|�^���WJ �e��V���T\`�זj);�Jd?��-��W���6��z`.�}A����4��Yn[��� +�+d.��������B�*�r��}��UIy��ӑrT<��G�C�A��C�6��.I�a&�;ֳ\[�t^�7$T��s���n�a�V�_�� "Z9���~;�*�0]�1"M\�\�4��r)\�.��7�E�5�����Wm��s/�O�n|&���8Ak쇎 �2?�+��N�VT7endstream +xڕْ�6��_�7SU#�(Jyg픷6���$��z !�CP�~�v�<�:��q4�э�/"�ŋ<�>�6L�٢��D�G���M�+Y�`�?�y�1M�p�N��H�0]�y���,Y<��~<�c��r�dQ������摆�O���U%��y���=�,���&�z'3�T�.b�b����Ey���T�Q�e�Mp_���h�Q�eʨ�Po���h�J�l�9D�j��& +���<��;��'�A!�q��� �G���� e��fߚZv�m��JQ�J���QZ��7oMɰ���b�ei��+ʦ��Q��k5x�Z��/�'�6#Y}\� ��6��8ݽ��۶�w4��b���)��qֵ��3c� ���Vچ�,G��vrDT��v�r6 =�X�T��<N���Y�y�@���U���!�B�Ly����$�/������V��a�ݲ�H�=�x0 >GQ���&��/��A{�A��ot G�L�4B����/���ԩ��ѵ�ĝx%���<Eq�3>�6xIV��z���yEn�v�3�Ć�������L2��e��̟5�i�>�n�h���d�t��>/{�$�=�b0:��h���]�>/1)�#��C�/Y<�↬KcW��db�2 {��T��3���2�h�2xJU�N��A�0��W��V;0Ew;^7۩�\&Q�E��gY����E�l���j���7���/���G6#&�,9K��w NG�梁���VL��ʫ�UGidך^�F�@�{��㯿��U�R,��k�]�L[ٛ�I���C�ZO������h�m��o$�B��7`.�C�z�9��o4'>{���=KJ�Vs�;��ӣ��}���'��A�ϥ�`�i�"�F�=��5����N&���e�L��)���.c��ܓZU��{��O��.�Kf>qqP���#ѵbg땲G�P|��q�i[]��8ש����%=d�[z8'v[��gz8�~_�Eo_j�Quyr��FZ3��=9U�$|�*i��b�����h��0{>(�� )`Eq+�{o߾�SAe��@��2�]l�{��G0�C�x�3�n>��}L���jHտhJY��EN��ɻ j�X7�9��%��+C���7H T0k�9T���� 4����������Wq9G�����N�\�T�0��됞#������p(,��B%m7� +�v�w���n7IO ]�B�F�n��EY(n�Hr�B����(ݶ��y��h;�O���#9#�U��2�L����Mf1��sWx���B�*ZN��;������!X6mw��X��� +H�* �*�S��i8S\���j����tgy?�r�PB�ږ�LXQ`p����99^4�CK�x������K�߬2�b�+�eW�fi��������6j��Rk��u-W���Q��S�T�!]U���Ξ�s��,:Y����r��k/�4χj�bڥ6n�g���Ϣp�lӮ�zG��ـ%RR\2�Pz��h[�^�b4���6tt�)�ތ��q����5s���Y�˖��XI/�Q�g���t�@Hh�L�� +$�E�W�s�ٟ*Zٟ����z���;*�����vluF6V#</H+Gem�I�`�/}��i�R���g^� +0�V�؎���m�K��\sM�~6��=kR��a�g۩N�./�l���� �N�D�F�A#Ȝд��_��Vk�L�&�:�"Z�y���p@�S�J,���܁۶lI�v�<;(�t���";̃�m�2e����`�7�;gw�)cA`0^gT�QK(�'��� �';�I��k�a`�J>�vr��L�5���3�c���/:�+��" +7�����H����08pe�Sj~fl�0�8����e�i�JCj :h���A�!�|2��(is��sE#�`R�p���!��Q�w!p���-��4e� +���3�-���w����`�� ��,���ѼϨ��O����b+�^]�e���^�%�i��v����aT$qM_�-e�W����x��0��7�Ր ��>��U�>�BW)�,8����-&�[�;E���Np�:��<�+�� Z�*�E^�1|����U�^���AQ�^�ұ�V�+�������0:z�����}�g&u��Kخ�T�-|b�l��A��uRy�w���E�J��i�s���m�y��W��DǑݿiK��½�H�l���h��j�YC-'8����;B�e#�4�ʼnKt@��u�:.�E'��H0����sbho�q�-�x�%��#v ,Kk��������WO�F�Z1�P�]���f�5O��E��`�ǹm쳖m��u���� �v�:��|������@� �.a�brZ���l��B]��\2 ���R�t'$��K����D����!Qr�E�7�掐���XVC=r�z$����bn����d�/q���% ^b�������y��{endstream endobj -4057 0 obj << +4056 0 obj << /Type /Page -/Contents 4058 0 R -/Resources 4056 0 R +/Contents 4057 0 R +/Resources 4055 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4055 0 R +/Parent 4022 0 R +>> endobj +4058 0 obj << +/D [4056 0 R /XYZ 71.731 729.265 null] +>> endobj +774 0 obj << +/D [4056 0 R /XYZ 262.949 707.841 null] >> endobj 4059 0 obj << -/D [4057 0 R /XYZ 71.731 729.265 null] +/D [4056 0 R /XYZ 71.731 700.488 null] >> endobj 4060 0 obj << -/D [4057 0 R /XYZ 71.731 718.306 null] +/D [4056 0 R /XYZ 406.408 674.765 null] >> endobj 4061 0 obj << -/D [4057 0 R /XYZ 71.731 649.4 null] +/D [4056 0 R /XYZ 512.678 674.765 null] +>> endobj +1769 0 obj << +/D [4056 0 R /XYZ 71.731 641.724 null] +>> endobj +778 0 obj << +/D [4056 0 R /XYZ 258.989 604.508 null] >> endobj 4062 0 obj << -/D [4057 0 R /XYZ 71.731 597.594 null] +/D [4056 0 R /XYZ 71.731 597.156 null] >> endobj 4063 0 obj << -/D [4057 0 R /XYZ 71.731 582.65 null] +/D [4056 0 R /XYZ 71.731 582.227 null] >> endobj 4064 0 obj << -/D [4057 0 R /XYZ 417.328 573.151 null] +/D [4056 0 R /XYZ 71.731 577.246 null] >> endobj 4065 0 obj << -/D [4057 0 R /XYZ 218.704 561.494 null] +/D [4056 0 R /XYZ 81.694 556.488 null] >> endobj 4066 0 obj << -/D [4057 0 R /XYZ 508.932 561.494 null] +/D [4056 0 R /XYZ 71.731 554.332 null] >> endobj 4067 0 obj << -/D [4057 0 R /XYZ 76.712 533.201 null] +/D [4056 0 R /XYZ 81.694 543.537 null] >> endobj 4068 0 obj << -/D [4057 0 R /XYZ 118.555 489.655 null] +/D [4056 0 R /XYZ 71.731 528.429 null] >> endobj 4069 0 obj << -/D [4057 0 R /XYZ 135.395 481.191 null] +/D [4056 0 R /XYZ 81.694 517.634 null] >> endobj 4070 0 obj << -/D [4057 0 R /XYZ 222.231 481.191 null] +/D [4056 0 R /XYZ 71.731 504.583 null] >> endobj 4071 0 obj << -/D [4057 0 R /XYZ 433.177 481.191 null] ->> endobj -1752 0 obj << -/D [4057 0 R /XYZ 71.731 447.614 null] ->> endobj -814 0 obj << -/D [4057 0 R /XYZ 267.224 415.218 null] +/D [4056 0 R /XYZ 81.694 491.731 null] >> endobj 4072 0 obj << -/D [4057 0 R /XYZ 71.731 412.249 null] +/D [4056 0 R /XYZ 530.108 491.731 null] >> endobj 4073 0 obj << -/D [4057 0 R /XYZ 71.731 395.113 null] +/D [4056 0 R /XYZ 71.731 489.574 null] >> endobj 4074 0 obj << -/D [4057 0 R /XYZ 266.919 374.77 null] +/D [4056 0 R /XYZ 71.731 456.205 null] >> endobj 4075 0 obj << -/D [4057 0 R /XYZ 71.731 346.874 null] +/D [4056 0 R /XYZ 81.694 445.41 null] +>> endobj +1770 0 obj << +/D [4056 0 R /XYZ 71.731 438.272 null] +>> endobj +782 0 obj << +/D [4056 0 R /XYZ 243.84 401.057 null] >> endobj 4076 0 obj << -/D [4057 0 R /XYZ 419.408 320.972 null] +/D [4056 0 R /XYZ 71.731 393.704 null] >> endobj 4077 0 obj << -/D [4057 0 R /XYZ 71.731 300.882 null] +/D [4056 0 R /XYZ 71.731 373.794 null] >> endobj 4078 0 obj << -/D [4057 0 R /XYZ 71.731 244.095 null] +/D [4056 0 R /XYZ 219.242 362.999 null] >> endobj 4079 0 obj << -/D [4057 0 R /XYZ 71.731 187.308 null] +/D [4056 0 R /XYZ 71.731 321.988 null] >> endobj 4080 0 obj << -/D [4057 0 R /XYZ 253.921 176.513 null] +/D [4056 0 R /XYZ 71.731 307.044 null] >> endobj 4081 0 obj << -/D [4057 0 R /XYZ 311.687 163.562 null] +/D [4056 0 R /XYZ 71.731 257.993 null] >> endobj -1753 0 obj << -/D [4057 0 R /XYZ 71.731 143.472 null] +4082 0 obj << +/D [4056 0 R /XYZ 164.944 245.042 null] >> endobj -4056 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F44 1994 0 R /F35 1525 0 R /F48 2006 0 R >> -/ProcSet [ /PDF /Text ] +4083 0 obj << +/D [4056 0 R /XYZ 368.717 245.042 null] >> endobj 4084 0 obj << -/Length 3158 -/Filter /FlateDecode ->> -stream -xڍZY���~ׯا��x��@�%k�� � �3C�ǘ���_���lΌ��>��٬�����Y�΅?�.�T��ϔGwE�½;^x�b+K�֚�v/^}��Leqp�;܅n��0�K_���+��;��Q����N���nƮ�~��#O|7�xNU��濻��x��w��Dei�pf͕t~p� S��-�TyaF���S! -���n��n�u>j����M><���Z�t�J -[$�ܻ��*���?�E����(r�U:�|�Η�9�`< ��d���� o���?�[~ٵfJdW<��컞i��7`�s��Y� �KAr���E� Ѡ(�~:��0��X]+��@V,F�t�x�FޭA`ϩ<�^�����u��Y�m�(V �f��*���3>n<��xp�O݁�w?���/n��hH��<�C�Ѱ�������Y ��z�G��}���T�6�*�:��Ʃ&f��u;T��\x�Ѐ�C�ҷ������s���eu�����V�F��h�z���y�x� -�p�Q~�DN^���ч3�T�Z�FdgTmP<� v}��L�t�����D:�,����}9Y��� ����wk���g��49)�o_]vE�8~�/�܇�8��?���Y�����x�½[v�r���F$��5�A�7��m�Hry^��O?*f�p���2��<ե�?MT��u<���>�A�(����W������6�zv�7�yL[Ӫ\VH(qM��_}���oob��^��B��|�IX�3>��%h/6"�����;� �i�Z3Q�{Ǭd��S���u���KJ�p�@��%��D�L{}�Y3^�:�z���G=��92�x)�q���v"�����l��(f<�+��K�^��bv�qoBM�r�f8v�S�K��ʇZ8�:�ϣ|n��:�$���:���,c,iuT��_\�y���j;M>�:��G��@0`��^s旫/�|��`wb҂��}�d���|]L=�SZx{#���^�D��J8j��!�v���y�y��ӇM:o7!X�=O��4�a���GZ��$Z�̎���G�Ɠh��{$ɑ�����*�$/�^�9�àK���� P㼃UH��i\:�����@�4/%��>��9*�D#ֵ����V�m�|yyE�3�������&d!Y�M"���v��U�^�Mp�[��W_ `iK2�L�F�9|��&�?O�u �x�����cߝ�XG}K�o<J1�x|@�� 49P��|�NQ��iP�ce�!�'Ô�Xn���t�G��YY�3�Z��Imϡ� 50�l�t��qaE�~s+o�ai -�W�vA�A�����y�J<��q32{�!�s<�^m�*ML�,��[�8Q~/KI��)�@p,��lڝ�3�BN1$8�=�yY�*�:�t����B��JSoe�ŭN���5(0�Z�s7�GS�� Ց����#-�5h1��3���D��Ht��q]�/®r��x��DSb�`9$���@�X�.��3��ox%tK��58x{`���+K�T���s�1e6��d�����R�u)���a��|�֭��$��S��h!�MH� T��3�����Py�Q����"e0;��D]�ٱ�@�C�)��Sq3rQm�7�E�9o�äv�C)ڳُ?u���4����Qy}y���>��YJ(��9�$u0���Q��PT -?ʝ~f:���2�д>>�>$����I,a+�X��&qW��<:�kO��at� -Xw��'`L���N&��:Ф�r}�s��iO��V�v��o�k+ -�s�Q#V�W2�������E�m���X -Δ���������g���� d-C\ ��*�Ha��T0pU���_����ޙ��[�2i44aa��������\�B�\�}���,r�b������[��Ka��X�~ݻ�U��3C���1UH�?]�F�~2�x t�&�i;��.a:D�C�x���*�W�X�U[����_�V1+5Q�ˀ?~˗����(|�X�� i���.{�u���W'����u���\0/r]R ��XJj)3��2��R�;����$�D���;M�@��ꠅm���ۛz*��2o���VQ�%3J��i�21s6��_��LS���6�Lq%m>M��� _+F\��\ �,)}1#�(�x���ы:83H��X����"\ -0Ȇc�Y݁,��߿��t�BZZ���k�夕S�{ҹ�jqY�ɇ���V���n��ޭ˚��'Z�]0���Q�<�v+���/߆x`AsDdzBx@���qܯ H=�]=��1��ƌ8��F��;��\���Xgm��6��H���@���߈��6.=�е�lZ�7�<0�[�����ȗ�t�!���q&��X���9��0�3��;���I�l�Q�B���L�+#qкVL>����+�G(����{�m�r���i����ʼnvj�計5��r�{y̓]�6����6�1Ϯ���s{>'�~j�9�͗�&]��cC��������@ ?��5�rEPv�p}1�g}�n�n�~�%*�-���9w����|s=��p�hÎ��3�W���R�(�'@���뻋7�~U��`_҂��2׃�q�'Y���ש*>����F��M씐z����:,@4f�ۥ�U5�'��i}!���L�]��cA�Էˈp.#BUF�0�G] 5p@a/��od�DO���C��%xr�U�d!?���I@R ��h� cac�0��J�m����4�߀�)��ʜ},nl�@��!F$6@�q`�p����,�5�U�ȿO���0L��8/�n�L�����BZ@��4RK�}�%?e��捹�����&�ۈ�.������X���e$�D��a�Q��"�}5"0��!���q�bH�Fv�X�]mޝd�3�~�L/�0�-�5?��܂�'~o��xz�/�e%�E �p~��hTϚ/���j��iQ�$x�>�JB�|���km���M�!�{��y�]�oU35<���?���wgn:/dOh��g��i1,�������A�/��J����X�\��F�C��&h�$��?\\��&#�endstream -endobj -4083 0 obj << -/Type /Page -/Contents 4084 0 R -/Resources 4082 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4055 0 R +/D [4056 0 R /XYZ 273.801 232.09 null] >> endobj 4085 0 obj << -/D [4083 0 R /XYZ 71.731 729.265 null] ->> endobj -818 0 obj << -/D [4083 0 R /XYZ 308.397 708.149 null] +/D [4056 0 R /XYZ 71.731 224.952 null] >> endobj 4086 0 obj << -/D [4083 0 R /XYZ 71.731 698.007 null] +/D [4056 0 R /XYZ 317.393 201.206 null] >> endobj 4087 0 obj << -/D [4083 0 R /XYZ 366.772 688.025 null] +/D [4056 0 R /XYZ 232.347 188.255 null] >> endobj 4088 0 obj << -/D [4083 0 R /XYZ 71.731 667.935 null] +/D [4056 0 R /XYZ 71.731 186.098 null] >> endobj 4089 0 obj << -/D [4083 0 R /XYZ 386.497 644.189 null] +/D [4056 0 R /XYZ 71.731 171.154 null] >> endobj 4090 0 obj << -/D [4083 0 R /XYZ 71.731 624.1 null] ->> endobj -4091 0 obj << -/D [4083 0 R /XYZ 380.205 613.305 null] +/D [4056 0 R /XYZ 91.656 149.998 null] >> endobj -4092 0 obj << -/D [4083 0 R /XYZ 71.731 593.215 null] +4055 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F44 2037 0 R /F35 1567 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 4093 0 obj << -/D [4083 0 R /XYZ 71.731 549.38 null] +/Length 2743 +/Filter /FlateDecode +>> +stream +xڝ˒��_��RU����zʓr*e;��N*���H�J��ǎ'_�~��Di&�ҁ@����n� +W��U�YU�*MV��]���ʟޅ�������û�Q�*�"�VO�8��(MWY��<Q�����ݾ< �[oUx��߿������q�_s8��=���w�$��"�^���,�R�,�=[��Q�L�?�Ly/��~ 2�<=�/�0�4φ����a��x��V�79����ۣ�|6�ӽ�uϓ�w��tЃ>�0����l�[(���7,ư�>+�}�?t�2'�=��>P�6T~!��O��9T#嵧��M�c��P>4���C�V������:��-��=���������^�t ����"�ó�(\����m_�a���g<�ʆ�M' \W<��?b�l�� +��M�3��#��I��PV��?��{�⪰\�� O��'U{�6��cY� CY �;u������j_6;��z�|�Z�=��F2�5�R֨���!ā��;}(���Đgj��� &e�����)w*�C?)�Wㅃc�&\�̹�E�L�b?QW�]~g���).䡟��g}j; V���d�o���<��%CR���;�o>�[��n�O;�P�ٚZU�<��:�ce^S�����vl�5(��2�c�C�������S ����&���u��8��+o�w��m�.�/��p���f�h�QX�hްP�o{R���W�N�H��d͋@2/�eϫ�Z�|�R����`!��:ݟ���xj���1p�8b�cT��1�v�$/q.8z��f��:�x�%K ; O(�_ �\(�?��W]����B� ���M���҅\���I8���R�I��a ����B�ˬ�sO�&Z�=C�),�7ZdgN���%P�����ߥ��?�1f�,����a�����!��<��tpn9�`��Kfo;Ò���ww|�-��L���BKC%��@\x� l�:=�!X��q��e��s�e�G�~�^88��*o�u��m�.�/��p�u��k��l!��7�ȏJ�U����lf�K��qlm���OcJޮų�b��Q K.22�<���I��`*�u=�P�+���,u�~���?sUӟ���c�|���n�nF�V9%E��u�j�R? ����##B7!�ď�"�/p^�fn��c���'M;��QP�H�(�A�O��17�]j��9]*����������Z�>Q�booM�foEl0��`�K�"��Ɖ`~gtLI��(ˤ��#�\���iR7����쎃˾ad��|�c{Y�yF��?���DJd�vT���B�o&��R�Y����C.*���_����pl���9H�H�l��j��/��`�NGM�c'B�q,��D�m��G�7�.��<t��J#;.z4��=�?�C�V�;�Km�����Rr��#aa�g%䶷�|��>C�Ql��)��G���ؓ����fS7��!f�lZ���wi��.=��&V%���Y�-_��p�c�L=;@ B�:����� ���a{a������!�1��ˡ�:u���9�2��o|�Ϳ�G\���}~������d�@G�^�/���+z�H��2��E)8\��� ����\9�=&���|b06���>s��fIP�/j�l�FhS���]���b�|��l��s\��l�?'0����ҧ����+e2x�|[�Z���2���k��g�:I�i�]ɢ!��p}#�Fi,Itz��,�W�#�b:�߷m��.�-�`y�˚ ��B�,�E��1Gk���@{<���U��&�y����������K4�Vε ��K�).ږ��<L�q�\�����5�Zk���)5f��� .��h�H���RjF��� ʎ����.�7>�>���p\a��O��A6�=��D����4��%�T{��->?O��j!P*oQ���Z�a����ۇ}D�",S����+�y2�H��>߉��Q�$��n� +�e��g�ђ��,s�1�QiKOӣź��`(ES�D���PHzDF�)�����<t�s�MK�&�YN%'^ǩ��&o�ΥmA��:���C���<�`d:F{�M��� p��CW��~����]� �@�xh�+6�M5��G�y�c��~�Q��+tm �0����N�-�Ʀ��4i×�j?[>�(�ܼa�� +������@�E�J*��"I�FUdnĄu�d4lǁ1��X��摬$b�˻q�����R�?��}��n�ΘF��f�?[��+lcJ�8�����liĝntqcp�lS�=��q���;|�@(��>/�o��� +�v�^ѫ �j�l*�}C�f!���8�ߴFhs���%[˩ЊP����Dz�������&Ӣj��O��� ������ik[ +�vvؓn��� 2g�0����5��$a�L�0�c��ʟ0'��h š+/�:�U�*~��䓥��ί��i��?HZj�3����ݩ�iF�6�{�}+�����f�:��\�O铈�����$P3�ق#�|�����O][��Ĕ]��"xL�t��y����L��V���h��g�\^��9Qw��Sx�M; +VYMc0��!�/M�)�Ѡ@t�-��<�^}m�Q��'*�e�������KN�E�0�endstream +endobj +4092 0 obj << +/Type /Page +/Contents 4093 0 R +/Resources 4091 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4022 0 R >> endobj 4094 0 obj << -/D [4083 0 R /XYZ 71.731 531.447 null] +/D [4092 0 R /XYZ 71.731 729.265 null] >> endobj 4095 0 obj << -/D [4083 0 R /XYZ 71.731 507.701 null] +/D [4092 0 R /XYZ 71.731 718.306 null] >> endobj 4096 0 obj << -/D [4083 0 R /XYZ 228.316 507.701 null] +/D [4092 0 R /XYZ 475.448 708.344 null] >> endobj 4097 0 obj << -/D [4083 0 R /XYZ 71.731 492.593 null] +/D [4092 0 R /XYZ 71.731 667.333 null] >> endobj 4098 0 obj << -/D [4083 0 R /XYZ 71.731 477.649 null] +/D [4092 0 R /XYZ 71.731 662.351 null] >> endobj 4099 0 obj << -/D [4083 0 R /XYZ 351.57 468.149 null] +/D [4092 0 R /XYZ 81.694 641.594 null] >> endobj 4100 0 obj << -/D [4083 0 R /XYZ 71.731 416.941 null] +/D [4092 0 R /XYZ 491.507 641.594 null] >> endobj 4101 0 obj << -/D [4083 0 R /XYZ 154.754 403.99 null] +/D [4092 0 R /XYZ 71.731 628.543 null] >> endobj 4102 0 obj << -/D [4083 0 R /XYZ 102.167 391.038 null] ->> endobj -1754 0 obj << -/D [4083 0 R /XYZ 71.731 384.649 null] ->> endobj -822 0 obj << -/D [4083 0 R /XYZ 251.73 346.685 null] +/D [4092 0 R /XYZ 81.694 615.691 null] >> endobj 4103 0 obj << -/D [4083 0 R /XYZ 71.731 336.542 null] +/D [4092 0 R /XYZ 139.516 602.74 null] >> endobj 4104 0 obj << -/D [4083 0 R /XYZ 71.731 319.422 null] +/D [4092 0 R /XYZ 71.731 600.583 null] >> endobj 4105 0 obj << -/D [4083 0 R /XYZ 71.731 319.422 null] +/D [4092 0 R /XYZ 81.694 589.788 null] >> endobj 4106 0 obj << -/D [4083 0 R /XYZ 71.731 301.489 null] +/D [4092 0 R /XYZ 478.291 589.788 null] >> endobj 4107 0 obj << -/D [4083 0 R /XYZ 71.731 301.489 null] +/D [4092 0 R /XYZ 71.731 574.68 null] >> endobj 4108 0 obj << -/D [4083 0 R /XYZ 71.731 257.654 null] +/D [4092 0 R /XYZ 81.694 563.885 null] >> endobj 4109 0 obj << -/D [4083 0 R /XYZ 71.731 257.654 null] +/D [4092 0 R /XYZ 373.716 563.885 null] >> endobj 4110 0 obj << -/D [4083 0 R /XYZ 253.534 246.859 null] +/D [4092 0 R /XYZ 71.731 561.729 null] >> endobj 4111 0 obj << -/D [4083 0 R /XYZ 71.731 200.867 null] +/D [4092 0 R /XYZ 81.694 550.934 null] >> endobj 4112 0 obj << -/D [4083 0 R /XYZ 71.731 200.867 null] +/D [4092 0 R /XYZ 511.114 550.934 null] >> endobj 4113 0 obj << -/D [4083 0 R /XYZ 71.731 169.983 null] +/D [4092 0 R /XYZ 71.731 535.826 null] >> endobj 4114 0 obj << -/D [4083 0 R /XYZ 71.731 169.983 null] +/D [4092 0 R /XYZ 71.731 520.882 null] >> endobj 4115 0 obj << -/D [4083 0 R /XYZ 439.225 159.188 null] +/D [4092 0 R /XYZ 71.731 483.487 null] >> endobj 4116 0 obj << -/D [4083 0 R /XYZ 191.147 146.236 null] +/D [4092 0 R /XYZ 339.03 431.681 null] >> endobj 4117 0 obj << -/D [4083 0 R /XYZ 307.056 146.236 null] +/D [4092 0 R /XYZ 96.637 405.778 null] >> endobj 4118 0 obj << -/D [4083 0 R /XYZ 71.731 133.285 null] +/D [4092 0 R /XYZ 276.322 405.778 null] >> endobj 4119 0 obj << -/D [4083 0 R /XYZ 71.731 126.147 null] +/D [4092 0 R /XYZ 71.731 403.622 null] >> endobj 4120 0 obj << -/D [4083 0 R /XYZ 71.731 126.147 null] +/D [4092 0 R /XYZ 71.731 388.678 null] >> endobj -4082 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F44 1994 0 R /F32 1187 0 R >> -/ProcSet [ /PDF /Text ] +4121 0 obj << +/D [4092 0 R /XYZ 187.678 379.178 null] >> endobj -4123 0 obj << -/Length 2708 -/Filter /FlateDecode ->> -stream -xڍk����������Z��-����K�\�|�A�-�6�zu��_�yQ�{W��93�������& �$�!�za����7�����M ;V�e5������OQt���qt�Y����7Iz�&�y�[|<����rn�E����km]�/�:���e,LQ����z�Ǟ�&J�m}�9�g�]�ܹK�)1����Q-C������E��q�(j� Wte�[�g?-�͢��n�f�C4��(Lk�;��ft-�f�V�=��\F���Bon���nμ-�}�&dZ���\�P]a��_�Ѹ=�+�'�1Hn��V����f]d5\�. -�����8 �� nQ(��xEU�ۤ,C����`U��������:2G�h� -�!��܈����g�2H��Z��(Y�Jݶ#�f�³�`|c+֩�E|��z�x��FŃ��� ��NZ5���]H��l}��hP|Z�����F��Ʋ��`��YX���k�X���Ͻ��D纻��E�~;`�'Z=֨�g�K����c��'�Xt)���E��Houb�/M��}�Ya��U��/Jґ���� C�0,�Xe��q�i/���Uj٨�S![�nW+�)��T��NhdGU�L���U�`��z�G-�����G���H��w�B]1L�a�ڐ�A������a�n��6�Q$1���p��B��)��Mk���&�cH9�U����X�8�A�̎=��S�n�xύ�$��ԭ�#��}C?Yj��T���@�AԴ��ة*�((&0 -�r��BO�&�\%�B�DB��p�P���/&_)#g2�$�ǒ`�ȵՙ��_n!T��ӞG��\���y�eS�H�C@B���^��l!�ě����j8&���k<��U ���1$;�O�*��h�N>��%D(�(���Z3d1�����Ϛ�"��Wn/�JQj\����0O(�NR�C2ȵ�h��>ԽE���G�S�u!Zb$�,��.5�� [֍l�M�y�y�ھn.��h��P9Jq�%��k�2���$P��Έ�$�e�5ZuIl��5:�����(^�w�mv<+'�����ʳ� ���C=�;3��fDy�T����[Q����04�$� �-�0]�-��U �|�IIv�+g -����&�#3�J䄱TO���Tۑl��� ��#CC��n���Dz��*(yA�+wW�R1�x2:�����MI�bo�A������&u��l�9X�������$�nO:3��5��3��w� �g9{n-g��R��rݚC�UG0�+#%��dW!���Q.�\&�����$\�Qʺ��缠����"^a���_���M���'Xo;hy%__�\"U���|�JRFz���~Y`nj��b4�_D��Hr��d��/b#�T�j_{SЎ�^e� �ꜧ�B"�Bp�XR=N\4��<M�k9&��p(��&�p�^ g����|= ��&�����D(V�89���p䵸AꛐZ�B�v��wU�>� -��}"�I� -�@�p��v�P$/���b˔,�,� *�=^��K��5)8Í��suz� -��X����D��I!d��c�H���p -�z��O1��>M\���[�j�RZ�P�BJ��-xo�Sڏ!���I?ܲ)��(�Z �l&����p���~?� DWw��N�u���LĦ\��r66^/ء��XJ�d�^@����B<��ʚ��WSn=��3d����*�[� -iζ��MGkO���������"u�k�bN��к��+����;2y�ه_�):Q��7���"�m���J?Xs�CD�e�� A,!�H�B�g1�mr/�.�b���a~9�m�fe>�.7�5&�1,��a���b��>Y��0�zDT�"h����{\;���2 ���bj��+�����;�4�����*H����Q�\�ʋ�z�?X�%.Ғ��S��$X�+����+��*3B�GA:Z7��A�E[��Ų���%�U+(�;;� +|�.�J0J�� 7\�7��7S� ���NQ��iX���y���^�q�(�wTx��4)�,�8���}�Z��$m�����L �=�5���"Y�kT71���Q�BR��CLn��Ik� -?�HK���^I�f��❶xX�be4����(Q�0C���æ��+��:GC y5~�2.gH�d7�$Y���u��[�Z�b���v%�� -�)�ɹL�Ghqp���)5�^�ǯTM:wr�4(����Ȱh�e���8��&f�� ی�7��u�Q����H���F�����s�Dh�q�n��4���u�R�Oh�7<�s�w�^��J�J�8u���︐A���{�\x��?��Y)ċx��PY�z�*�&-70�e��5~A�K��K��'�2Am��H����/�^�*�Ӊ�G�û��ݨڒ���0ˠh�߿���Y�@e��WgלmTH��Bڗ���CM�v��6�,UҔ�{r�'�ĵB3c�Q[��j�J��>��0&�\�[��"����]ͮ8y�����.���2���w��Ħ�W��}ݦ�l�]�����N��#?�Y~>�;�s��0��I6�nS�x�?(��uꥐg����e���"$Kف�&��� �S�=���endstream -endobj 4122 0 obj << -/Type /Page -/Contents 4123 0 R -/Resources 4121 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4055 0 R +/D [4092 0 R /XYZ 71.731 327.97 null] +>> endobj +4123 0 obj << +/D [4092 0 R /XYZ 180.774 315.019 null] >> endobj 4124 0 obj << -/D [4122 0 R /XYZ 71.731 729.265 null] +/D [4092 0 R /XYZ 391.53 315.019 null] >> endobj 4125 0 obj << -/D [4122 0 R /XYZ 71.731 688.254 null] +/D [4092 0 R /XYZ 71.731 281.978 null] >> endobj 4126 0 obj << -/D [4122 0 R /XYZ 71.731 688.254 null] +/D [4092 0 R /XYZ 104 245.28 null] +>> endobj +1771 0 obj << +/D [4092 0 R /XYZ 71.731 238.142 null] +>> endobj +786 0 obj << +/D [4092 0 R /XYZ 204.474 200.927 null] >> endobj 4127 0 obj << -/D [4122 0 R /XYZ 71.731 657.37 null] +/D [4092 0 R /XYZ 71.731 193.574 null] >> endobj -4128 0 obj << -/D [4122 0 R /XYZ 71.731 657.37 null] +1772 0 obj << +/D [4092 0 R /XYZ 71.731 150.75 null] >> endobj -4129 0 obj << -/D [4122 0 R /XYZ 71.731 587.631 null] +4091 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 4130 0 obj << -/D [4122 0 R /XYZ 71.731 587.631 null] +/Length 2467 +/Filter /FlateDecode +>> +stream +xڝY����ߧ0�fe���|h��ӴE� �n���lѶYruȿާ��!%�� (|!rf8Ι�����R�MC��$��py�N����/[!��h>��C�r7O���� �d������jW��y9�Au�m{N�����jN~O_��.������w;�a�n���*��y*W~�~�R��y��F�*v}�EI3��ڲt�3�M��n1$�M��z�m�q�k���� r^U]cThH�g@?�+1ۯ��x��~��b�gg��u�{N�턛�7ٶ=���J��CH +�I��;*�w�b�;�^��0����0��{���p��T�f����Q� ։��X����?�N5�H2+�KRD`�F���MĤ�A}��,�b_�$�A�1����s�iz���ӎ�9)!��#��0��XexY�EB�T������r��p$��� �D<)��0 '�\t�E�\?����'�Ƿ��z���s����V>����F�K�rxL�1\{p +�����g��2�C��ɭ�U��B`���-��Ֆٖ�Dl��,���W2sQZk�Wﯕz�'��[�s~m�\���Sh�5��^'ޭ�ơ�;|�����%��|��)�I��Q=���p��G�C��B{hGʓ=�[��� ��v|��g��U +Sє,�I��i#���_�A���W�×��C����Q��� ����iX|��E�����C;�l�L�Px߮��Q,���V"���R�*U!�# �Iɢ��) ��y �����<�NU�D⪡�xԉ��6��ɰ��pn�^2�����E��VU�c(�f!HΠ_I�L�b�tn��K�:�b]�눣��A����5H���"�fp&��{��d$�&Νc�]��%��F�m�O�tw���Z��$���lo��z��L��Xյ����D.{�t+:�K^��es%1ˎ�b柋���Ŀ.1ut'�1H��%��"�VV��m���$�+>�ԭ��3>F]���V]���[P*fl\�)�@2��]u�ݫ��w� �/NkbI�j��\���J>F�L +0��X�iKmI�E�0�������d�l���ڗ��¾�+Y��L�rY�j��:�#ro�<��0�˽ 造n��( +���j�����Q�-�uՇ�B��ip(�8clS3���Lk�v�O_�A�l��@ڊ<G�?T����<��JW�M��vP�Ô��"�:Z�0�(�>��9v���/�q-�wl�A�S��P���g��72���F��1����C�g���8f��#�j��q��0;P�Д�_H9(,�� �W�VC�S��-���.���v�o��h2#AЂߦA_}Q@kG��*NU�U����Y��0Ȫ^���W +_$K"h����Ȓ�A����Ftx�&Tuj��xw��h�z�����0n��y�����M�Ki�u��g��c��K��t�#s��~�+_8oCC�l�f���E����K ^L�&��<����_]�0�Kz���#��0z8�a�Q�1u�j�|35�L��d��Q*��������z*Ӽ[�ǥR�6��-�N��4'��n&Nf<���k���#�S+��3~b.拝�N����ʭ枒_ڋ���m�M.tDy�2�o���1\\'[��Zu����0�vjZ�v1k��qC� �5!jc�IL���5�\0�-d��0EG4剌�]� ��b�:7�Q�4]Mte�(�MfWI�m��Ť8?�Ci�H�=`���X�\f@Q^���Nx�k�xJl�rƫ f��b{*�^IK�=���.�'iZn�h�=V�a�/��w���� +ފ��J�85�������Y���X��o���z����*#��i?�9!o��"��h{�����^�Ũ*G]ԉ}�>����M�sIg9$�p��u�����Zx�@� ̓0���;r�GV�l��pn�:����BJ��m6����xM��1����=kQ�����Cͭ7��"��8��B�B�X��E|�'�:@��"�����e��u��5o���������|;S�f�6f_6@&�L5n$fe�sכ��זv��4G�*@2���\'*�҆�*��Y� �TLJ��@�yz�?]]� +���j�o����^�{��~V�oX�����G)��N�bNsV���p)v�MWnr�33cm�"�w�}{]��S���7�;<9�o�\�#�K�Ȧ��{��A0#e��jV��C�wW�����~��u��;2�_��pvY��f�|�ҩ�AD��V���@�\»!ذ�Bȣ���)�Nb}�L2�{�,03����Ht1��W Ki�s�k��֓�>_8^j��yVO)�_��[X&�J����M�8�� +A��J�� N��ù���k�����W���H�������Ä�K������������endstream +endobj +4129 0 obj << +/Type /Page +/Contents 4130 0 R +/Resources 4128 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4022 0 R >> endobj 4131 0 obj << -/D [4122 0 R /XYZ 210.674 576.837 null] +/D [4129 0 R /XYZ 71.731 729.265 null] +>> endobj +790 0 obj << +/D [4129 0 R /XYZ 275.232 705.748 null] >> endobj 4132 0 obj << -/D [4122 0 R /XYZ 137.035 499.128 null] +/D [4129 0 R /XYZ 71.731 693.577 null] +>> endobj +1773 0 obj << +/D [4129 0 R /XYZ 71.731 656.502 null] +>> endobj +794 0 obj << +/D [4129 0 R /XYZ 174.075 618.913 null] >> endobj 4133 0 obj << -/D [4122 0 R /XYZ 71.731 487.726 null] +/D [4129 0 R /XYZ 71.731 608.771 null] >> endobj 4134 0 obj << -/D [4122 0 R /XYZ 71.731 449.514 null] +/D [4129 0 R /XYZ 71.731 591.651 null] >> endobj 4135 0 obj << -/D [4122 0 R /XYZ 258.006 436.663 null] +/D [4129 0 R /XYZ 71.731 549.872 null] >> endobj 4136 0 obj << -/D [4122 0 R /XYZ 394.451 410.76 null] +/D [4129 0 R /XYZ 71.731 503.979 null] >> endobj 4137 0 obj << -/D [4122 0 R /XYZ 71.731 397.808 null] +/D [4129 0 R /XYZ 71.731 473.095 null] +>> endobj +1774 0 obj << +/D [4129 0 R /XYZ 71.731 418.365 null] +>> endobj +798 0 obj << +/D [4129 0 R /XYZ 165.31 379.093 null] >> endobj 4138 0 obj << -/D [4122 0 R /XYZ 71.731 391.419 null] +/D [4129 0 R /XYZ 71.731 371.74 null] >> endobj 4139 0 obj << -/D [4122 0 R /XYZ 288.129 379.875 null] +/D [4129 0 R /XYZ 71.731 351.83 null] >> endobj 4140 0 obj << -/D [4122 0 R /XYZ 111.088 366.924 null] +/D [4129 0 R /XYZ 71.731 302.082 null] >> endobj 4141 0 obj << -/D [4122 0 R /XYZ 325.619 366.924 null] +/D [4129 0 R /XYZ 71.731 287.138 null] >> endobj 4142 0 obj << -/D [4122 0 R /XYZ 71.731 346.834 null] +/D [4129 0 R /XYZ 71.731 236.029 null] >> endobj 4143 0 obj << -/D [4122 0 R /XYZ 263.437 336.04 null] +/D [4129 0 R /XYZ 71.731 190.037 null] >> endobj -4144 0 obj << -/D [4122 0 R /XYZ 71.731 323.088 null] +1775 0 obj << +/D [4129 0 R /XYZ 71.731 140.288 null] >> endobj -4145 0 obj << -/D [4122 0 R /XYZ 100.413 310.137 null] +4128 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 4146 0 obj << -/D [4122 0 R /XYZ 71.731 290.047 null] +/Length 2669 +/Filter /FlateDecode +>> +stream +xڕˎ�6�>_a��V��$+�Ť�'�`�YL�X$9�m-KZ=��~��,{zw�b�Xo����H|7 ��nG����[`�w�P��d=��������p��i.���M�a/�0p�Q�x�s�u�Z��D.��Ձ��ÿ��T�?�~��l7���M��2�+��p��nE(�9��u�͆��\�\�I��}�U���P\��; +�%����ߺi���|�s�f�F#�8JP��gpw�N�:w�j8�HK@Q���^f; ��_�N[�x�5e��w¯ʙK�ꮳ�|�s�W[��I>�2a[�h�]�}�f�����G͐2P3[�#���'w��n>���˚��3��LU<���=/�4�yK�J�ӥ��^h�F�^��x� +R+�ޟ+?r4#�jƗ���*���H~�U."�(�Z���2S�~NBw���c�Fl�pc��/@�{��݃��'@g�P�> p���6N������O_>�|�s~}�x�T�>|}����)�������� + '�ӀƊ�J��k�7m�Y�QM:��AB�G���� y��(2��9#c1"��m�3f�V�H�Ⱥ @"�*����0B�����cp���ā�۶�t=t噉T������#�z>��܀`�a"�9`��� A:]�u����b4[�e��0�>�(0K����*�����`�}m8����ok#l�V!�#��O-˳�%���\�,5�� rj�<�i�j;�����������M�]e�����w+�_��Aa�}щ�]�h@���l/�)�dW��7�v�p$��^�`� +�g�p���"���y% c��H�(;�u��Ä�p dT�ꪔaZ�!t�+�� ,���}'��b�A6� ڙ4{���8��obg-2q��U>�2����,�c6��6��}L�����V��<�Uv +�+�w�L�g�Y"��f4�d��ؓ�.�u��q����EJ��y��4H E���I�}{�9����j�WS*��~X_�1v��0�� !�s��^��p���[���IP�R���T�~+��8htm�IH�7�����Ug�0y�!��Ox�/p�S��ԗ��+� �:/Dp+(���5 +�Q�T�NzN�>�� +0��V�k�Uf�s����G��d�� ���D����\l�Tk<U,��SQ��[��"���Q�$��d u�9輊#Ge*���r¹���H/����:�g�L=�+-ﴁ�6��٤��9��;�B�}��GۿRC��Ҟd�Ķ_�7i�=������'{�O�xMH}�`hE��hl�a�|M�HF}&F?�,���&ǒ!H2§�f�Hs��8��{��t�Qm�f��)��z���A���V�f�uY05��ǞJe&ҼB��SV@��9�l��q�TOٛ�Q ���9��9@X \&�����&.h�C�d߱"����1M��pjQ16�u; �nح3����(��ƌq��ŕ�������F�zҲ�^�V��Op���������{*:���]�)\L��I�"��u�_qQ�L��fk/:,b[ ������r%��{�^� uI7ZJ�(A}Â%\F���-��}� +�ɱ WF� ֹ��� |����c��'��>������nq������PQ&K�`N��/߫S{;�z���"+�HKȤ�N۫;���-��{��{�N`{ò9���$�L7�����M��qI�h�yQM��b��.���O���y���.X���fCslU\g&��)��qg�=N��n~kˌw��|au��g +/��V������x;?`��O`���P�e��|`�cc�X� +ߡ�(�/���ȵ2���B�I�@�7��B�J�J#"�*f��v7=��U�4z��x*.o�����!�V���j3t�ך�F:o~�:� �^b�U��+5�8~?� ]���_�_2�6�� ��`�(I����u�έ������7�"C/B��X*����5 ����g��Ą|�D,��"�������Uŝ�&��@*r���W�@-�&;D�w�]����ʴ�md���I�Q@wY[��o+�,�k�B�Q��1��RZ��yr[V��3�K�]ȡ��HA��2���c���d���Ks9䢼d,Y g��J\J �9���L��3ɧ���C�Q]�@�z9A��{=��8R���_��7��{m�H�6�F�)���� ��klQj�r1�6&�!��3F&�i�]�rtOcMnx�J�!+�B��� 0��]�����<��V����2q��Ԍ8���-�M��~�7,N��.��S��u��<��Ӱ)�6SZK��|�W�M @��H(��I��7��Y�{C��3��7բ�A��wg�M�����oK$��[4۫� +(1��K�zz4���U��֔I'�ߠ��B���+F��cd�i�͓_u1e_s�oF�}+���Lc%�"��є�~MsGԭn� +��i�m�.�̈́欏-��%Y� +%��Q�|�3�@4�9�<n����#�c=��G���8 +��D}��e�A9���I�:I�痟�y�'�������8P;�f��X���&����7�*�~��{��1��S���lݭ�����Hr��kl]/0LP����T�w��iڷendstream +endobj +4145 0 obj << +/Type /Page +/Contents 4146 0 R +/Resources 4144 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4161 0 R >> endobj 4147 0 obj << -/D [4122 0 R /XYZ 71.731 267.133 null] +/D [4145 0 R /XYZ 71.731 729.265 null] +>> endobj +802 0 obj << +/D [4145 0 R /XYZ 211.497 708.344 null] >> endobj 4148 0 obj << -/D [4122 0 R /XYZ 71.731 222.6 null] +/D [4145 0 R /XYZ 71.731 699.706 null] >> endobj 4149 0 obj << -/D [4122 0 R /XYZ 71.731 178.067 null] +/D [4145 0 R /XYZ 71.731 643.422 null] >> endobj -1755 0 obj << -/D [4122 0 R /XYZ 71.731 138.516 null] +4150 0 obj << +/D [4145 0 R /XYZ 71.731 599.587 null] >> endobj -4121 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F32 1187 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +4151 0 obj << +/D [4145 0 R /XYZ 71.731 568.702 null] >> endobj 4152 0 obj << -/Length 3031 -/Filter /FlateDecode ->> -stream -xڝk����� -#EZإ��� (6�m��K�s�I��J\[9Yt��v��;/�a9W48�i8�3���\��O%|����h����f����FHn&4��6��Vm�`�{\�n��0\%����_������f}�G�+��������zψ���ok�)�*[�����n7��ڦ���4��`��S��Y)��4�Xy��JR煩t]�7���-�F�����y'��f�V7YǮ���uV��l����k�JFu���U�+����9���M�>���":�K��<נ�S� �_�voe�� -�:�*F�k���Q���u�eU%����:-��Bc�����������Y]00����[���=J��z��F�w�(<�hڎ��tj̩)�|A�i -��� ��4M�=��E��X낇B�lz��� �9���!�pHj�]h�w����J��waܘ�LD6�Cם>�l����1����wQ�2����f�G���T&+ԡ;V�L�U�oYW��E���y���9��hP�$v���Xv]���Ukږ �+�a�h��0y����K�n���;{D9�v��cyE��@\��>һ���kR[�/1d��(���?��kdq�*�0k��U�Ԩ>X�1�֞@O.�V)<9r~�� �Szr�}��W�_�����nc�~�P=�Wa�Ȫ�l�������%>���tq��JSo���T�yǠ���a���5�݂��W�� �)k��&u�������Vy0Z}��6Q9�@p-�S0yU�_��bf �tƦ9��:f�r����0_��N�D�٢�x�gT�Ǭ���.��Kӥ"�P [��mС�Q �\3������C�����E�0�_���?���ZFw��"��'���C�yh�$O$fP8%�A�J��E���&�P�M%j��vq���1����y����f�w���~rW�ү��g�{�B�bw�lW��n�U�W�W��1�O<�T|p^�t�r���M�j�\�Ձ� JWk?LH���!(���IQ�j��㥐t��x��^�[{�D?!$��18�_���RFS�/;^ANR7-�&�!|3�� -���wƔ]����%朗��P<�<<e]~P�z�e�D���B��$�l=�m�����Y�9~���@|>�Cvb�U���kY|�{�K��ׁK���S��E�ƫ�b�������4���[��ր$��ăH^F��a/6�dbA@BFv� �P��n������O�k�ϑ�� �;&LS,�c���M�-��s��dmu�5���&I�WR�1}w!K9��||�$��eF�]���_�~Lslu�+ʧ)A��.�z�sp�e{�M�D���a�-[�T��۷�`]0�XrJ��=Q�IJ��҆t2~��Ád5����JЭ>a�Ҍ���'b�&�$A -������lt����9+�v�#A�wB˹6����7ZRe���%��$��L2f���"�E\��%$bզyϣ,oL�2|��U�*�#��f�# G�_k�ײ,{/�U��оɊa���`�Y�T'0jry�`�q�sή�^$i%�u��bRM�?�ɢ_�����%�bnH: -���\yͳ'O��3"y`<�Ֆ���̔��o3�UnO�������.h��\��.���rLڂdX *�ډ(P>������Ó --�$�DkŗZoZ#"���k�VL��C6����=H����]z�2!#��#�`��ʄ|��H�<ŝ�����*��@��\U��a�jv�jŸ�Z6�(y��i��D;��;<��4��P��8M�6�$�_)�:Qi�,�^v�ܻ���ͦl����������ݔx�b ևn.\tn�w�kgEa��_ !m�C��ăo�*���dd?�u+i����"[���4�ܡ��G��D1P�ؼa`�!�;����&���'�X�fZ_C��l��`���@ؽ�lg�˛@D7� -b֍��k��ϥ�=]@��xs�~���S.��8�TN���0-`���'�A�Ig o�U����������s��/o��s�d/��Sx6;F��x&x�c�]*�#E�sC�b���S��1k�h���Pr -9�g[g��yP�Ŷ�����u��ZV�~���Vh���%Ylx*��6�k)��������� ���yib�Ro��N�J��lW4Y~h����L�+���1��%��M�Y��ӡ�@����fkG#%"�;L��Qt����[; 7�Z��H*�rց����Q\3�K��"ܷ#� o�M���ew��G�����5�����A�.c�´�KC���sS�E�����U�.�̶��_-j3�'{6�MskBO*��� l�$��y�CSY���X�a$\Lے�8Qql���) �k/�$���g���0�w�ƤƇȆI Ce��.��6 >܋��|�덶g�6���}w��5*&���[e�9㖒Gtf�q�XATN���n>��GSU����f;ğ,��������^���ܿ��~����_���~���ww�3�����ۯ�6/�;C�9s#~J���<b8��(0��B��`>qF�'�p�`��I�2�ж�Y�1���P\�}���l߈p���A�V_r���D���������Ca�}f��sn��W�g�C�Ǿ� -�',cǕ���xԞt�M 2��n��8t�n���SDcß�n��׳�n0�l.�ʑ��k���d��u� v���@.��J�̱��h�[�d2�@�����?>�fs2m� Y� �Ms$�N��:c�J��� �6o�S�Xo_������Qs���N}(�:�kZ��Հ�gj*kN��4�[\|���B�~=��۪ ���kl�rS�"�[כ�Q5�#ۯ%�֦�ZDs������6Ғ�q�gb+`:2�kq&�Pg��� A(t�⍈�H|֚�M���䃿��$��#�R�n��I����~y��c�endstream -endobj -4151 0 obj << -/Type /Page -/Contents 4152 0 R -/Resources 4150 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4055 0 R +/D [4145 0 R /XYZ 71.731 537.818 null] >> endobj -4153 0 obj << -/D [4151 0 R /XYZ 71.731 729.265 null] +1776 0 obj << +/D [4145 0 R /XYZ 71.731 519.886 null] >> endobj -826 0 obj << -/D [4151 0 R /XYZ 461.484 707.841 null] +806 0 obj << +/D [4145 0 R /XYZ 255.599 486.575 null] +>> endobj +4153 0 obj << +/D [4145 0 R /XYZ 71.731 477.938 null] >> endobj 4154 0 obj << -/D [4151 0 R /XYZ 71.731 697.476 null] +/D [4145 0 R /XYZ 71.731 434.605 null] +>> endobj +1777 0 obj << +/D [4145 0 R /XYZ 71.731 383.796 null] +>> endobj +810 0 obj << +/D [4145 0 R /XYZ 159.597 340.698 null] >> endobj 4155 0 obj << -/D [4151 0 R /XYZ 71.731 661.813 null] +/D [4145 0 R /XYZ 71.731 328.26 null] >> endobj 4156 0 obj << -/D [4151 0 R /XYZ 71.731 643.781 null] +/D [4145 0 R /XYZ 71.731 299.05 null] >> endobj 4157 0 obj << -/D [4151 0 R /XYZ 335.135 630.929 null] +/D [4145 0 R /XYZ 71.731 268.165 null] >> endobj 4158 0 obj << -/D [4151 0 R /XYZ 117.651 617.978 null] +/D [4145 0 R /XYZ 71.731 211.378 null] >> endobj 4159 0 obj << -/D [4151 0 R /XYZ 71.731 605.026 null] +/D [4145 0 R /XYZ 71.731 180.494 null] >> endobj 4160 0 obj << -/D [4151 0 R /XYZ 294.096 605.026 null] ->> endobj -1756 0 obj << -/D [4151 0 R /XYZ 71.731 587.926 null] ->> endobj -830 0 obj << -/D [4151 0 R /XYZ 237.169 544.828 null] ->> endobj -4161 0 obj << -/D [4151 0 R /XYZ 71.731 541.265 null] +/D [4145 0 R /XYZ 71.731 149.61 null] >> endobj -4162 0 obj << -/D [4151 0 R /XYZ 118.555 499.074 null] +4144 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +4164 0 obj << +/Length 2631 +/Filter /FlateDecode +>> +stream +xڥko��{~��/��X�DQ��R��E�k{�(��B�i[Y���ܯH�� ����p83�3�����_ž+h�� "��O7���#��b#$�͏ۛ?�Wj��i�V��*T�UQ��U�&:Xmw����Yӛv� ��h��_��:0��p��(�l�y���a; +�*v�D�����P*�'��ڼ�UaH:��Q���`��찛8��<�x(k��w^���$��0j�hI8x�yl�-�H'��Ӵ�1�n���Ѯ}G����dՒmr�A���Ǟ��О`����l�LC�$���@�X�FK���9=(y��5F�VT7Yk*�ޙ�e��������η�Ԕ�1Ş�Y�,jtϝ��[�[�Y��Z�R��#�XV��>Yb�^��LZ����p#�'n���ghB�0��B���(�� +����=�p_<'�*��:OmM�;�����ڔ�5!�3�q�v2��3�W˞�ٿ2�Gf�Δ&�����G���R�;����d3��k<�Z;.��Vø�+f.;��um7�g/!\"����T��jR�ՠJ;M@?n�{���0��p��ݐ�������x�ő�8w_Q�m��z�]9PMv0�~�0�q����}���2p��c"f��5��ۮ1y���*�*Q �U��;�lzrJ�j^�#",B{n�4-B���Eĉ�8��<eCaF�:� �j���ͰQ��d����C<��>@�f���0�Y[� +� +&]�v���![,P4E�ʼn������hu���X��"��A�`O/���ց�|%*�h0t��Gt쑆����'ĸ���%��1:h���� :��S]�1+�T��p�1�ȬvI1�-#� +N�W?p<gڌ�p�嵯V)+�£ڛ�]j4b��ǡ�e��D�li)*� %s���R��taE�e툮z���f�%z�k +4ݲ&���2��(E�3j ���"�#:-�O������^���v�IN��ty[4}1�Y�<{�y*���q���&��@�����go�����~��� ��y�8]�n��UkV��Ǜ���P;r��-<W�.Xl�6���\�S��Bȱ"���]��U�j7�R�UY;�XK!�&l��F�9?r#�Ќ-�z�U"g9T18�c�q�)d��R�<n��NxJyv���A�����[�w2�'�&䨈$�#��C�'��.�a������Za"b�w#����X4x�*�I~�GV���9KX�;��@N4a �,"u� +7�����C���/� +��pֳg\��$����bص��/1�p��K��`f���pp����+�p���lN����_����%{@{���!�oxɏ�pow�� ݏ����_A���g\Us&�0n��Bp}�YOi�/��e�G�x�A2��b +ui�h����fEx�V�7vP V��+)&"����.����z�ܲ� +Ơ�o��q�3j�.%2���.��2�)����fe9ED����7x'|*�U�N72�iE�����k��7�:��}A���C�x�@2�\� m݀]`��b�����PA�\͢���C�*��@����*��Z�b��1��liǮ�8S�d���+ Ю�`�4�G�I�����#ҞI���=�2n(��J��m ��a:D%���_b��g�w��Y���'M����(G�Zc3+���Q��Xv�}a�c�K�8�c8b[IY��v#������<;�y +�7��_Ev4���bi63"����3BM�]���c��B|�1��o���ş1B�S�3%i�z),%L��I�t�ȍ_�n��E�g�tv�4�h"'�qo����8����.*��M)|���\�<sn.�n�+5����}Y�͌��\����q�Թ�ЇӜ�o��4o���0?�>�?ѡ)�v(��VU,"�,(�_�J1|�t�j�jV��9)�X�BǮ�fկ/���燯Xs\-�=��8%��,:i�f1�3X�q�������������!����[�BPط�e�dFq�U�Gl�ş��)a���X�p��Ƿ=���ck6Tl� .(;�gZ�u�C��i��%��5��e���*��^��ئ���)�Q�-ڝ ��Hԣg0h�ȟGY�&ޱs�n'b��г��w.�<u@���sg��ryA˸�XBg��Q�����,��?{�C�j;!�GVy��'���sGV:�f�>H�T��o �w��_�[y��� y ��F��}p��IT1��:r�Eύ26IƊkσ��R3]T�T�&yО?H��-�a�`*��C�I(D��� +�.����l�+��YP�Rq�d��P4Y.ZZ1��ѕPp�Ba�P,��8�F�6W� +�?$��, =~=KBk�D��<�y9��Db@b�A�f����՚ Vq]���-��є C���H� +�r|pìڱ�P��ZS�6�c��lQ�I�K��۪=�G���n�q���G�-����q�a��)h�kF4=�b���ӑ�M����'!k�H���� ��8�yzFQ��m|�"��\�; ���o�'�[��t�Ga9Zi~��G1H�?~�{�Dr�O��� ʌ��}ƻ��ytN�endstream +endobj 4163 0 obj << -/D [4151 0 R /XYZ 526.195 490.61 null] +/Type /Page +/Contents 4164 0 R +/Resources 4162 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4161 0 R +/Annots [ 4174 0 R 4177 0 R ] >> endobj -4164 0 obj << -/D [4151 0 R /XYZ 71.731 457.033 null] +4174 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [138.415 365.19 190.751 371.969] +/Subtype /Link +/A << /S /GoTo /D (installation-whining) >> +>> endobj +4177 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [364.929 315.268 418.584 323.75] +/Subtype /Link +/A << /S /GoTo /D (installation-whining-cron) >> >> endobj 4165 0 obj << -/D [4151 0 R /XYZ 71.731 393.392 null] +/D [4163 0 R /XYZ 71.731 729.265 null] >> endobj 4166 0 obj << -/D [4151 0 R /XYZ 71.731 321.596 null] +/D [4163 0 R /XYZ 71.731 718.306 null] >> endobj 4167 0 obj << -/D [4151 0 R /XYZ 527.223 297.85 null] +/D [4163 0 R /XYZ 71.731 675.303 null] +>> endobj +1778 0 obj << +/D [4163 0 R /XYZ 71.731 631.467 null] +>> endobj +814 0 obj << +/D [4163 0 R /XYZ 182.7 588.37 null] >> endobj 4168 0 obj << -/D [4151 0 R /XYZ 147.048 284.899 null] +/D [4163 0 R /XYZ 71.731 575.932 null] >> endobj 4169 0 obj << -/D [4151 0 R /XYZ 225.125 284.899 null] +/D [4163 0 R /XYZ 71.731 525.799 null] >> endobj 4170 0 obj << -/D [4151 0 R /XYZ 71.731 277.761 null] +/D [4163 0 R /XYZ 118.555 487.235 null] >> endobj 4171 0 obj << -/D [4151 0 R /XYZ 179.885 254.015 null] +/D [4163 0 R /XYZ 118.555 448.482 null] >> endobj 4172 0 obj << -/D [4151 0 R /XYZ 415.118 254.015 null] +/D [4163 0 R /XYZ 71.731 403.551 null] >> endobj 4173 0 obj << -/D [4151 0 R /XYZ 138.304 241.063 null] ->> endobj -4174 0 obj << -/D [4151 0 R /XYZ 71.731 220.974 null] +/D [4163 0 R /XYZ 71.731 383.625 null] >> endobj 4175 0 obj << -/D [4151 0 R /XYZ 71.731 220.974 null] +/D [4163 0 R /XYZ 76.712 348.737 null] >> endobj 4176 0 obj << -/D [4151 0 R /XYZ 71.731 203.79 null] +/D [4163 0 R /XYZ 71.731 328.811 null] >> endobj -4177 0 obj << -/D [4151 0 R /XYZ 440.089 192.246 null] +1779 0 obj << +/D [4163 0 R /XYZ 76.712 287.566 null] +>> endobj +818 0 obj << +/D [4163 0 R /XYZ 188.149 248.194 null] >> endobj 4178 0 obj << -/D [4151 0 R /XYZ 71.731 161.362 null] +/D [4163 0 R /XYZ 71.731 240.841 null] >> endobj 4179 0 obj << -/D [4151 0 R /XYZ 71.731 161.362 null] +/D [4163 0 R /XYZ 71.731 207.98 null] >> endobj 4180 0 obj << -/D [4151 0 R /XYZ 71.731 111.888 null] +/D [4163 0 R /XYZ 71.731 151.192 null] >> endobj -4150 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F44 1994 0 R /F32 1187 0 R >> +1780 0 obj << +/D [4163 0 R /XYZ 71.731 120.682 null] +>> endobj +4162 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F44 2037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 4183 0 obj << -/Length 2775 +/Length 2982 /Filter /FlateDecode >> stream -xڕi��6�{~��� �z��E7@l�,���-���lӶ�dɐ�:�~�Lv�� �Ù�p.��̅�7K<' ��g�G���;���w/<�X �ʢy����]�2'����n����, |'��������C~ҪY��ȝ�ߞ[]��E�gě���e�/~{��<v�� q�4����i�'W��&ݔ�D�:��\��b���|sP�'��>(*���3|Zx�\5mQW<[�x�#7yTTvU���/�Z2�W[ب�VX��n՞�jK���mѨ���S l�R�]��sg+�w2������>|���?���pUʛ?��A��U��x8���3�M���%0Ef�V����������y}^��ȟ����yY^x"�:���)G����F@`����yσg�<���ͨ��t;Xs���O"m��*�Ԭ؏Ɨ�ܴ��Ɋ�)�`mU,�x� ��w�7o~:55��'t���U^6�5����?����4jȓ>�P *���4�H[�`�4�fe}Wc<[���߫V�`s�+�L�_ë�7�&O�zjo���uު�PUU��6����P/m�"��'�'ڑ1�Rۖ���ښ�,"P��b�]�݅I�6�� -;�K]�0V���;�KF���\8��j�v;F��f�j�8� ��\v2?��� ��N��p\՚� Z݀\��>��ED�-bwhL��ZL5�r,W<��4n�(�W����=�-�����A���oT��Q0aג�[ ��-�w��G` �\��&�C���T�����ۭD���Q)-�M�=�NY�K)�-Dz�bRz�2p{nCl��oD�i���h1��������<�Y�kG�N���yˎ����\����.ұK�4���&+P]�,J�a|dυ>�S� K��D�%��\��QB9(D�it��|S�x��+�p`9/�8�_1�C��4��Kĸ�u�WZ N�7[A_��6u�s����`&��Fj��1�*��)A������#����9�E%8�d�&l'�~�'�7gf��PSr�$�1qb\2�T���$�\za<�4�m�5��Cq��3����[�G�c`�SS�q4��@�48r�8���C��|Oՙ'7�)_e�2�p��K�h�FgW�Y;��Y47�|{,*�F���ܪ�a��F=�N�%�֨m�W�|�l�Ÿ�<'��R�R:����3�@�1�is�����)�g��D��{p�8A�왶�]X���^��sɇ#\�ZcSB){�_+=7�.'�nVZ8�!2�3�^�Vp��k��q���M�y���ya9���'�����y��>�3�R����������)�>��_N���N�r��ݹ\��=��AKG���x�)��v��Բ^u��%c �^��#=��j��e��ˉ>}��eA���ں/D�K]~�Q�Y��@D��pm�a�J(6�D�������вMh怒�v���"%vL]tV�Q�f�T1yP��_;,�)�����>)�AYr��b(���Q�!����+f�r�e�U�Q@4f�z8�*4���9Jf�����6y1�='�2������C�0©_�^�bם�Z������F����%�ֹ�<�͖���O2��!�����8�ǜ0o8��>�Z���jd������]�����{l9��cC��!�����6�}�@#�3v�{�A�(+�pH��K�Q��p�&�Űנ$t��n萕'����Ԓ�Ш�����q�:�����I�z���|�r"E�ʠ�{S�0ޟ;�bD։K�ʪ�tT��i��8F])�T�L}������ˋ�\�����JOD �#����0X���^��qT�8p]눁~�(��=�e���=�2��=��X� -nV+i� �W�.e��#�YWӭ�v L)��o���`�D���9W��k�|F'd.�e�w$c�q%4�vJ$;O5?�Zq��_��I���+�Ec��{b=3 -���HX�D�����*��L �쐂�faO�5�S?嗤��ڵ"c�'�Pb��|aB��� '1#`�NI�Z&�$��b�2��������s����e�]]���`Ib}|��n��2��E��d�Y=J7��K>l���I��y �:_��1^�< =n���,疃z����3�Es�A��K:�e9�%�=���� \ QE�)�[2%TJ�>/���cLu8��N��ױBw��1e HVԢ�Ք�l��Wա>�[#��7p��1�����p`�>ԭ�1R�����?x�\�'�)0D7<�5���D5���Rb?�[�؇"��6!Y�0�{�kq������� -M�pOL;�o*A���ٗ?���Ɩ�� \��y' ��ͽ�� ��{�ц�Țl���2T�� �B���F3��.4�A������ Mm�;a��� ��Y �7}}���"��l���ץIQ�?���뮛:W��ս2�Ci͡�G����>��-�o��ɒ���1ηw�x�����A!�% �I��'�/�������3Y^��r&���_��0�"�O0�k{�;A��>��$AC�ɒ��{A���_���{Ҳ�h�p�I6��wE� �Z����7?�Sח���Hn��+lnF�*�ǿ�v����2�j\�:��?��(nC>�-C���[�C�o돢�)��j����o�q��}���9����j4���-�p����%w;�+���B+�:.�q��,�&@�:endstream +xڥk����� +c?ɀW!E=��R$E�^���4(d�^��%�$g����%Z�m-�����p8�˫W +�ӫL���OT�Q��v��z��?=h�x�'����o�7fU�EjV��UlLh�t��(̓h�\���P�Fۯ��DI�߿u����/uӔ�_�|��y�01YX��M�͍P�Y�84q�R�é,�cMB%�6a��dy�ӡnY|ڭ� +�:7E^�|@�z�T����|W��J���B�]GI��Z'�mG���*�����h+YW����;��z���2fر<C�3���L�[�y`�y0vBw��zq��V��Q�϶���D�Z�"`:�c�(,V��6��5^����e� ��s2�?-)�KEj�~�Iw�h �wB�4�C���� �і�L�������I� �Z.�����x�w��pd_El���#����U�1\V���q�6<<�v�8tE�?~X,��8�x��v��<��މ��D��y�c��vל+�(Ε-���o�( �f�(P��p����14�D������i�͏(��� �p��M��[!cS���WF���ָ��R�����~,kAV�e��=O�ī��n���i�~kձk��F��{�@�ܪ��JM�[Y|o-YЗ2�D�M�;������ �3�<��k�m�����$�.W�SL�x�*�����~~��������� �^�8o�b�â0�ޮ���6qR�Y�^+t7,��4OI{��}�n�M���< cC'�i�{r����x��'�'�ClR3t�&�ߒ��`>�ݟ�p������� �ZgFv�g�=/�k�@��d����<� +���el�2V^@D� �0�8@(=�n�X�,���N��%�.<O^ ���t�&�X��^��E9�tM-�x�D��Q?��Q�dq�`�����'fT܈q��)Ow����*��dA5��D��gU<����y���{L +a�jII-��z������߄�r���ylIl�&W�q���$6 +8� �E�ǣ�_�,���y)�dS �xs����;�r"���V�W̞���YHZA�r;I�~L �Q �/:���O�t�0�(��l5 G �r\�-���m'a�&\��m��*e��H�qf)��,�(�j�|�%H8���X�ρ�õ�3}U�ۆ"$+���:b��N�kR��r�!�>�$��w�a��k 0*^<���7���� +�ߏT�ϐ�����2=+��\�ʊ(����2^'=�!a�VJ +���(�Y�سCT�]�|��;�sw%�-��Y��ޘ� �/��%Ʉ# ���tM��H��!�JHl�(wn�]o�Y���_'�<���5k3���<�xU!�~�C*H���PO����Q)Y�<�E'4y"� H��n�mdl'T�U!�C7���������M��&f�Po��^xj�����>���g�Zz��8^p��^�S6�h8u��%J/d#��8RBxE�5>'<*'�$ޚL2�"��F�3X�"s����t����S���g(N$W�)r-�}=��]RJ�%B��y��E�YA��� �Rk�9S�r���S�����ns�(�h�Qlz�Y6�8(��F�?G���0��Y�bwl����5�����F�l�/H�� lsZ���3j�� �'n a�&A~���E)���ƺk�ؠ>���<~,kd\�k{r D��h�0�G���<��<7XZ�z��5�f����;�ۂ����<��:�»�B\�z"-ľ�I{��i���V�I��9h=Ʉ0��)��y}��f{��L� +d�3�:�'�©��@�4E�ue6.N��K�-xgi$��y����l[M缓��7c}j$'�3K�J���v�� #�����^rj7(j7d؎��_b`�x����.��m�lf��Oh�]TtO��Y��ܯ3w�u���A�v��zvF's���۔RKJ�%�׳�u�����vF�$~�m������B~�-\�@^�Wݮe����)���dQ"H��U�DU��UB~�R4:�n��<Un;��l���V-�;�}g\�S�c�Ť$��ҵ��D��MM�?����Cp<P"���e�֤M�\����K�(�������m����:/�v���u9��w� Iow����"x��z>������5�{,��B��xҊ��Ք֭���\8�/�^es�!��#����9>�����Y�T!~�,���B.���Vd��Lr�:��/���]t}�����^��(OIr���d*���Dzi��z���ΰ8&s�w�t�X���`[�������Ӆ�RN���y�����r}��J�~�"��#�/u�{Y&ɹ����V8��n<S@�=����q!�Ⱥ���c`~h�іr$��n @ڱT6{`�����<R0�9~� 7���1��+F&.��#_w:����Qf����!���D˨0�dE +t��>���B��t���;1���5@L���S掘Y6����at*_� C/H������FV�s�V���4r̬(�EQ�yG'Q���Ţm�K +djP�����(����܂?aĂ]��P�a��Ǐ�����8����J�Ӭ+±�� "��I�'\WuW��ő3���ϯo&-n�X˯(�%�����Lw:��9��x��gs��8^U�9��" +S��tR�������h�<����J���0 u?AC ��>�㰈��]H��|�F�H�)n�� �<�������rq�����w����q Y�)�OW�*�7j���G���:0��؊�:i�ׯ.�N�B�(������ �v��f٨��� +B��@�����TR����:��)b�5�|�|���~i9R���ԥ�P�+�rt����Bo|V㒓��\P&?�P)��a�����& �8s����3��_^$Q��1AUe�kQq���Bs��endstream endobj 4182 0 obj << /Type /Page /Contents 4183 0 R /Resources 4181 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4055 0 R +/Parent 4161 0 R +/Annots [ 4196 0 R ] +>> endobj +4196 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [192.636 157.251 244.94 166.162] +/Subtype /Link +/A << /S /GoTo /D (list) >> >> endobj 4184 0 obj << /D [4182 0 R /XYZ 71.731 729.265 null] >> endobj +822 0 obj << +/D [4182 0 R /XYZ 243.797 707.841 null] +>> endobj 4185 0 obj << -/D [4182 0 R /XYZ 71.731 695.392 null] +/D [4182 0 R /XYZ 71.731 697.476 null] >> endobj 4186 0 obj << -/D [4182 0 R /XYZ 71.731 689.003 null] +/D [4182 0 R /XYZ 71.731 654.675 null] >> endobj 4187 0 obj << -/D [4182 0 R /XYZ 71.731 618.516 null] +/D [4182 0 R /XYZ 71.731 615.821 null] >> endobj 4188 0 obj << -/D [4182 0 R /XYZ 71.731 587.631 null] +/D [4182 0 R /XYZ 118.555 577.257 null] >> endobj 4189 0 obj << -/D [4182 0 R /XYZ 71.731 556.747 null] +/D [4182 0 R /XYZ 71.731 525.452 null] >> endobj 4190 0 obj << -/D [4182 0 R /XYZ 235.228 533.001 null] +/D [4182 0 R /XYZ 71.731 484.544 null] >> endobj 4191 0 obj << -/D [4182 0 R /XYZ 71.731 512.912 null] +/D [4182 0 R /XYZ 71.731 432.738 null] >> endobj 4192 0 obj << -/D [4182 0 R /XYZ 282.395 502.117 null] +/D [4182 0 R /XYZ 71.731 417.794 null] +>> endobj +1781 0 obj << +/D [4182 0 R /XYZ 71.731 345.43 null] +>> endobj +826 0 obj << +/D [4182 0 R /XYZ 243.524 306.058 null] >> endobj 4193 0 obj << -/D [4182 0 R /XYZ 500.324 502.117 null] +/D [4182 0 R /XYZ 71.731 295.693 null] >> endobj 4194 0 obj << -/D [4182 0 R /XYZ 300.306 489.166 null] +/D [4182 0 R /XYZ 71.731 252.892 null] >> endobj 4195 0 obj << -/D [4182 0 R /XYZ 71.731 476.214 null] ->> endobj -4196 0 obj << -/D [4182 0 R /XYZ 71.731 453.201 null] +/D [4182 0 R /XYZ 71.731 222.008 null] >> endobj 4197 0 obj << -/D [4182 0 R /XYZ 71.731 384.868 null] +/D [4182 0 R /XYZ 71.731 157.251 null] >> endobj 4198 0 obj << -/D [4182 0 R /XYZ 246.016 372.105 null] ->> endobj -4199 0 obj << -/D [4182 0 R /XYZ 71.731 364.966 null] +/D [4182 0 R /XYZ 71.731 142.307 null] >> endobj -4200 0 obj << -/D [4182 0 R /XYZ 178.27 354.172 null] +4181 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 4201 0 obj << -/D [4182 0 R /XYZ 71.731 342.052 null] +/Length 1282 +/Filter /FlateDecode +>> +stream +xڝW�o�6�_��IbFE}�E2�+�����D�\dɕ�6�_�;�IV�,� ���x_<�N�A2Ȥ�,q!�T�a;��e!Yc�*��Λ���N��E���6H�*M�L�"�q��>�o��8�n��ujA��5;"ߜv���6�/������P�L�z5�Q�"�8;5��B%���CSZ���c{"bo�q~[J�V�o{�=�Y���*Yӕ{�[ʰ%r�',�>��i��5�wn�'�&_O�{$��Rپ��q�<�� +��{�ϤD~�Ҳ����#��2��C=W2_�=Wc�E�M�'� �P��l����v�l�Iu(�� +Tt ��Pc��>4Llߛ3G�:@l������NH�y yC��z�CL�gKfxfbh�S�ZH�����B��V�*�f0��3�@��%�`�r?�;$ϏaV��+�3�'�z�S�~2V*�&�4J�gݖV�����]�����Fg������h����I�1Pbx�����A��U )�(ڞ|�E����A����y���U<�)��Y��:���]|���{����/P94RYHQ*�l�]|\�6Yo B��l�Yֻ0��Y�<Y^��H2�I�T$��y��RD�����*�5����@T���d@��T�*�'��7�X4�(��� �ij�]������%^ƽo>�p���ڐ�^2��yS�ژk�� �ݖ�G����}u�l�Ђ-�����_��Gq{ZM�.E�)��4����V��G(�&�2#���J�aOY���/����@��{f7��͑�H�<��ޏw�ʹ� �ی�V�H4u�p2��G�� �?�2�v���� o����OS��82~2HcŘ_Rت�_Q7~^�kk��Dmê=�Eu��5�@�����0�-�Z>��f<NF� |:V`��m{8��J�6�јg��l�&��oI��l W~�/��Ĺq��4�\m65kl[6�[9���z�1��F� �3hH��X�5d��m��%��Zh�"�C�9�=�"o��!��_�����=�[Үlmj��!>7��פ?s�B���T-i�-�~2�3;�~��.�G����+� /��m���9[�0�� ��n?��^qe���%]H�xHK�cW�{�>;��*a|�4 �ƴ����*�}����zp=s��ʇ2��ú�LO���y�䬹( ��|o�<�D��C[9|ɥ��� |1�{�\�2{�w�Y��g��s#�50�,������c�1xendstream +endobj +4200 0 obj << +/Type /Page +/Contents 4201 0 R +/Resources 4199 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4161 0 R >> endobj 4202 0 obj << -/D [4182 0 R /XYZ 71.731 321.183 null] +/D [4200 0 R /XYZ 71.731 729.265 null] >> endobj 4203 0 obj << -/D [4182 0 R /XYZ 462.665 309.639 null] +/D [4200 0 R /XYZ 71.731 718.306 null] >> endobj 4204 0 obj << -/D [4182 0 R /XYZ 71.731 289.549 null] +/D [4200 0 R /XYZ 71.731 675.303 null] >> endobj 4205 0 obj << -/D [4182 0 R /XYZ 71.731 278.655 null] +/D [4200 0 R /XYZ 71.731 651.457 null] >> endobj 4206 0 obj << -/D [4182 0 R /XYZ 71.731 273.674 null] +/D [4200 0 R /XYZ 118.555 612.893 null] +>> endobj +1782 0 obj << +/D [4200 0 R /XYZ 71.731 570.852 null] +>> endobj +830 0 obj << +/D [4200 0 R /XYZ 266.363 538.456 null] >> endobj 4207 0 obj << -/D [4182 0 R /XYZ 81.694 250.859 null] +/D [4200 0 R /XYZ 71.731 528.091 null] >> endobj 4208 0 obj << -/D [4182 0 R /XYZ 81.694 237.908 null] +/D [4200 0 R /XYZ 71.731 503.223 null] >> endobj 4209 0 obj << -/D [4182 0 R /XYZ 71.731 235.751 null] +/D [4200 0 R /XYZ 71.731 488.279 null] >> endobj -4210 0 obj << -/D [4182 0 R /XYZ 81.694 219.975 null] +4199 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +4212 0 obj << +/Length 2202 +/Filter /FlateDecode +>> +stream +xڥXY��~�_!�Kd`�I���\Y�l��l�nk[��������d[�$0KE�X�G� ��2)2 U�&Ay���'x��tq� +�(�W^n��"��v����ߕT$Ҥv�i�H��`��5�x4��v����0��8�C{���ybƇ��kU�f���'ZSfB�`s%�,��R!/�`��jz77 +Q��MUR$�L��ت4M]���/=�_��"Zf�FE�62 -sNc=T�ڲ\��!n+x�;��ə��W���M�g�s���c��U�[(G���V'�d����c�G�p�ɣ�EE"��eg̀ +%Qh��X:9&%���@�d{�ŵ��O?�Ui����w�wSĸPH�L�Y�SNd�����lP^��R��f�H��f��ys����?�i_���y��_��v���d ~�"U[gMӀC�L�ǁ��?gף��I��)� S)T�Ai��ߗm3t��m�gJĪp������v��4 ŷ����X��Y�[�q����f�����7�Y�>�G�|̖��p4ShH���������99�܊���^�����T +g��Y�� �M���u^e����ܲX)���A�[=Dэ['Be� \�ЊY"��zP����a�D�)�����Z�\*�`%�`1Y趻z�<��;��O�aԏ���8�&ʣ-�{;�gq��t��3N��=K�fuP��R�l;�N}I�rc�.�m���sn����֗���<ꪒ�+p��Qg�<t��@�4W�I~��KE� +Tl�㙹�wφ��y�چe��j����_6I�I?��v�f�_:{��4P���r�8(��@�c�_1U]M3���Jlc%�Q��M7T�X���xl�Z���D5����?�}� ��0]���J�E�O��=�B�9���U�mV�M3�cC�ƃ>7��å���O&Pd��dD� �^J�Q��6)��t��}ϰ�!o~�ߟ����@�� +� � +�����߰��Mݶ��b��`mͬ����O&4U`@ǖ�Z1�9�;xI>�ݓ[���܊�u=� ����S:��j*l���p2^eP���'�i�,'HE��Onȇ�U9��x�d���0��G���3{|�5E�6����i�}���8�����n�y_{��'HXdSE��Eݖ����={;v�D8�wՄ9 �O�̜�K:J*�V'���/�/˕�d��+�Xx� +���M�����&�M�4墳�7�A��ץE�.k tԃS�������w ��� ���������c=�_Ch�"�*�:Y��'/�]݀��� +P�&հ����1���[�{�7��^hj�\�b�c!���<�S ���H�o��O��o����6tc�ѿ^�"!��< �iM-��i97���3���#� +ӵ��B��$��� +�+$`����I��S�ZD:_�7T�X�G&HF��r���DJ�H�KԊ���kh5%/p]1���b3�P5�sp�Wf���b�7d��$:e"� ��~�AhX<�,��}�j�lO~u����lR�Ǖ*�͌M^��!]�1K���a�T���e��4�8ܮtN�,]�.�y��Vv��6��Ҽ�d4���P�_�0U"+&�cO�?/Oٖ��B�x��u�-��>�0R�Eм�\�R_��p��������N�)�Y��>��>K��z������ho�6�V��J� ��X�Ͼ-pT!5���Rj��)�+�����~�= +�P?����C�X+(tE�y_蠳������J������,v���법���WGR�$T��<�ɨ���`��AhE懓��9,a�HE������I���$�������93����7�d��2@�-����g�7fG�(�PR�oxL�6R-���j����9 �'� +���Zr������{����O�B*eQN@�'�eyYP����/�l��P�}}�Bx4�/ �̨�/g$4��$�`e��v�4R����O-On������U6�BR��4R���FթD�۪�V��/�����0��d0�`���`|�EtD���Gh ��0ಈԣk�uK�1����ó������.�e$ �g��W+Ϯ�+���Pfy��el�61��m,Ec�b�^�?}w�s����Ua*����U��@e7��'�y���/%�endstream +endobj 4211 0 obj << -/D [4182 0 R /XYZ 344.309 207.024 null] +/Type /Page +/Contents 4212 0 R +/Resources 4210 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4161 0 R +/Annots [ 4227 0 R ] >> endobj -4212 0 obj << -/D [4182 0 R /XYZ 140.643 194.072 null] +4227 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [390.612 336.55 442.915 345.462] +/Subtype /Link +/A << /S /GoTo /D (template-http-accept) >> >> endobj 4213 0 obj << -/D [4182 0 R /XYZ 270.568 194.072 null] +/D [4211 0 R /XYZ 71.731 729.265 null] +>> endobj +1783 0 obj << +/D [4211 0 R /XYZ 71.731 718.306 null] +>> endobj +834 0 obj << +/D [4211 0 R /XYZ 388.547 703.236 null] +>> endobj +1784 0 obj << +/D [4211 0 R /XYZ 71.731 692.184 null] +>> endobj +838 0 obj << +/D [4211 0 R /XYZ 220.023 651.159 null] >> endobj 4214 0 obj << -/D [4182 0 R /XYZ 333.642 194.072 null] +/D [4211 0 R /XYZ 71.731 642.336 null] >> endobj 4215 0 obj << -/D [4182 0 R /XYZ 71.731 173.983 null] +/D [4211 0 R /XYZ 269.966 616.649 null] >> endobj 4216 0 obj << -/D [4182 0 R /XYZ 309.019 163.188 null] +/D [4211 0 R /XYZ 71.731 605.884 null] >> endobj 4217 0 obj << -/D [4182 0 R /XYZ 179.902 150.237 null] +/D [4211 0 R /XYZ 81.694 577.874 null] >> endobj 4218 0 obj << -/D [4182 0 R /XYZ 494.944 150.237 null] +/D [4211 0 R /XYZ 242.937 577.874 null] >> endobj -4181 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +4219 0 obj << +/D [4211 0 R /XYZ 71.731 575.717 null] >> endobj -4221 0 obj << -/Length 2831 -/Filter /FlateDecode ->> -stream -xڝk��6��� -W Z`��D�|�pHM�E�\ӽ�-,:�T�9��yQ��`#r8��v<��_<+�P�Ia�g���*�=��wW�`�e>�y�pu�F��"\�j��8K�"Ti:+T�Y2{� ��ն���<ɢ �{7��n��>1�����:L�T>|���xr��pQ��2�qθK�we�`.*�Id�G�k`���~]�8�{g����:S3��������|��6U�oڙ~�w~�u�m/�>��ğ�coY�4�[�h;L��I�c�8��M��:�O{�>uU���A� �y��y��8J`n���$X���,B�r��7K�=��+���o�Wv��m�����`���ǡ]��U�|�{���maVu�����Tl��pֺ=�Y�7[:��&LP�V��sU����J':%ʜ�y�_�� ��(е� -��!I����0K.v�=�[.~����5��f���*Ya�Q/*$��Ի���'�6BA��#����(�v���6��/��+������R����7����K!�<\�p�k{ᩝ�+#PH4��ڀ���3h 0�%���Y "�Qdq�����t^�����ë�}�pK}=���noYr�x�[�4~��I.���Al%��g���]� -���zF�ns.K���^d^�E�x�wE ����g�O@i^�|L��'�qH� ;T� -�F�����7��G��J��;�f�F�ʏ�+�wCٱ�L <���iN�:�l"R}�$n���ı�=ql4��:���Q0�VR�PBc������_T�!+�� ��$p ���%� -�-������Ƞ��g�JI�1�m���@�#���g:�ՀCDw�~q��bŝ�2�q��D��ZN�<t�F6�bF -: -cC=��a��EʬH���;u�l�Iq !�' - �#��7�@0��R>���`}H7�av �+g|4d�Q3P�$��z�lG��$>�PQ�,OR��_[Y��[bJ���sd|5b���Hgi��C���_~�f5�����w��]!r -�*�8\,Ԭӳǫ��~)�Ds�{��k4x�����{n�)>�� �B>E.JEq��r�fEX$���)x���|�� d^�K��%$��s�X��E -��Z�S�C�nm���ť�@����E\��[L�@� �"�/y�L7��l��c����`0��JX��a��$�%�����,3 n�Y��k��Yή�/���h4��,ố$�WV��'���&i!�x����Ɯ���k�S!3;\�:�5��<�w�2��@�37�6`��j�H��!v��j�����H�d$V�5q8^,�[��|�.���G$#�nq�bq�@7���sN6"�C�Z)K�D9�<3�Ḍ�o,����0��7w)k�OrZΤ -�6��?i����ZbD%�?�����T]L7%�U%X)��wv��Zʸ��'���?l��nh<^��T��p�6+�.�$�ྷ�E���x��6`��ʹ�I��Pz��U�A�HU3�S����"ce�kH�'9�\�F�?��c��2p{A=�7xgd'�+��$�rŵSZ/0�8ƪ�3O-$ 5����w�٪g�J䝢����������1���6� -��\��k2z��Q����E��l����@�3��Gc��Y�d�3��:�uZ���'�xm��5��Vh��6�v� ��\`ؐl' 0�]�.��_���A�Ҿ� ����������v��f��!�喦��8g?3��8��b�s,���V���c=��m^��w�5BP�C,�FR:�eRq�1-$�X�T��nT�[,�t)E���w�g��S�y�Xa�H��Sz0D���!��q������/�V�K���� �=�bX� ���������y��������z��7J�����C�EX��WW1��(d� �EC��(Uy���ѣ|��R �;bOw�Ylq��#^���Q�%|�g��#��I -\�gi���q����խo�p�*A�M}Ұq��V�5b�G�$QnX��X�s�H/��fq'Iz3��/�^15�9�d���dx���T �T�SKG���>t�q�d��v�A 2HNs�٤o�S�����Ӛ��{���V����v)���.8����i��yH����3A���D'n�ȧ�Q!9X`<�Cߍq&�����AN�|��|��+\�p��g��ˑk�d���#��;�f�����Px�'@�:�́��/�;qƃ�D;�h|iX��CxX����^�����l��LȢ�i!��1|�����$�x1��7�/��/�j��W��;J�PGQ�f��l�1"�vOiOx!=�Dq��}cw��L����ߐۆR�&OH��%�39*y: �\�8�Ki -�a����;���ܸ�����OG ��|��Z@�������]`�J?����_�ۏI�L��T��`K9��,|�[NHD^�CK�o<}�-P�47��f� -�(n���RV7U-����Y��r���Yآ��\x��s9Ne�<�2+���<�d�9�·ݤ��s��cpT����9���e� �A�?�Y�T�X��,h�e�L2��I XK��f��` ]ͫ�{����^(�a��¢H=�.��*�x��x�iL��[=O V���J�w*].U�@@��*҉Da�ze��'�yZ���1�ޓyɹ�a���9��7<9��������WbS��Mw�,�Mz�@�H�W~w�z�Q��?�eXB���_t(g?`fI�h����s?H��?����endstream -endobj 4220 0 obj << -/Type /Page -/Contents 4221 0 R -/Resources 4219 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4242 0 R +/D [4211 0 R /XYZ 81.694 559.941 null] +>> endobj +4221 0 obj << +/D [4211 0 R /XYZ 346.268 559.941 null] >> endobj 4222 0 obj << -/D [4220 0 R /XYZ 71.731 729.265 null] +/D [4211 0 R /XYZ 81.694 546.99 null] >> endobj 4223 0 obj << -/D [4220 0 R /XYZ 71.731 741.22 null] +/D [4211 0 R /XYZ 71.731 524.076 null] >> endobj 4224 0 obj << -/D [4220 0 R /XYZ 71.731 718.306 null] +/D [4211 0 R /XYZ 71.731 491.035 null] +>> endobj +1785 0 obj << +/D [4211 0 R /XYZ 71.731 447.199 null] +>> endobj +842 0 obj << +/D [4211 0 R /XYZ 303.155 404.102 null] >> endobj 4225 0 obj << -/D [4220 0 R /XYZ 76.712 664.508 null] +/D [4211 0 R /XYZ 71.731 391.931 null] >> endobj 4226 0 obj << -/D [4220 0 R /XYZ 81.694 646.575 null] +/D [4211 0 R /XYZ 71.731 362.453 null] >> endobj -4227 0 obj << -/D [4220 0 R /XYZ 198.595 633.624 null] +1786 0 obj << +/D [4211 0 R /XYZ 71.731 336.55 null] +>> endobj +846 0 obj << +/D [4211 0 R /XYZ 308.598 299.335 null] >> endobj 4228 0 obj << -/D [4220 0 R /XYZ 95.463 620.672 null] +/D [4211 0 R /XYZ 71.731 289.192 null] >> endobj 4229 0 obj << -/D [4220 0 R /XYZ 71.731 600.583 null] ->> endobj -1757 0 obj << -/D [4220 0 R /XYZ 71.731 540.971 null] ->> endobj -834 0 obj << -/D [4220 0 R /XYZ 402.85 495.717 null] +/D [4211 0 R /XYZ 363.706 279.21 null] >> endobj 4230 0 obj << -/D [4220 0 R /XYZ 71.731 491.887 null] +/D [4211 0 R /XYZ 219.335 253.307 null] >> endobj 4231 0 obj << -/D [4220 0 R /XYZ 118.555 449.696 null] +/D [4211 0 R /XYZ 320.961 253.307 null] >> endobj 4232 0 obj << -/D [4220 0 R /XYZ 71.731 395.999 null] +/D [4211 0 R /XYZ 71.731 240.356 null] >> endobj 4233 0 obj << -/D [4220 0 R /XYZ 71.731 345.309 null] +/D [4211 0 R /XYZ 157.2 240.356 null] >> endobj 4234 0 obj << -/D [4220 0 R /XYZ 395.22 319.506 null] +/D [4211 0 R /XYZ 71.731 238.199 null] >> endobj 4235 0 obj << -/D [4220 0 R /XYZ 108.148 306.555 null] +/D [4211 0 R /XYZ 118.555 199.635 null] >> endobj 4236 0 obj << -/D [4220 0 R /XYZ 441.752 306.555 null] +/D [4211 0 R /XYZ 165.524 191.171 null] >> endobj 4237 0 obj << -/D [4220 0 R /XYZ 71.731 286.465 null] ->> endobj -4238 0 obj << -/D [4220 0 R /XYZ 403.654 262.719 null] +/D [4211 0 R /XYZ 341.284 179.514 null] >> endobj -4239 0 obj << -/D [4220 0 R /XYZ 71.731 237.648 null] ->> endobj -4240 0 obj << -/D [4220 0 R /XYZ 71.731 163.128 null] ->> endobj -4241 0 obj << -/D [4220 0 R /XYZ 477.684 139.382 null] +1787 0 obj << +/D [4211 0 R /XYZ 71.731 145.938 null] >> endobj -4219 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F35 1525 0 R /F23 1173 0 R /F44 1994 0 R >> +4210 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F44 2037 0 R /F48 2049 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -4245 0 obj << -/Length 1973 +4240 0 obj << +/Length 2713 /Filter /FlateDecode >> stream -xڭXm��6�>��X,Z�0�X�߲�+��z[����p���$�8VV�w�����H{�Iv�.��@4E�����"��d�K�+ⅈ�4(7gQ����g�%�,2ߓyvyv�J�`!� -.�A�B%I��Xi\V?���z�7��if���C��M�kݮ��lX�:�a�4z���Wg//'˩�ŢP:7�y�wލ�� -�$:��u�ai7���d��vQ��m;��Q��=��\�֮�m�i(��Lwu��f7���x;;�����B��֦�!�ni��l�ի5��6�4[m����Z�G 4��Xp8�����!��D1����8�M���1���b�{E xk=�#X�Ɠ�ƴDu�'�a+��='Ne��g�����=�%�-:r�WW�ޥ�?�~t���^�՚���?�����\����D�{}�;84��ߙ�Q��ǯR�D�8�}=A��vu_�o����s�o�5�Ig��!��C��.J# -m>�]/Y�q��ّҶU dtz7���`آ}=���}5���� 9��4����6~D0$�v��=���/�J<A�P'Ҡ�L�0c)R��0f0�3��,������4}��4>z�a˳9�X��#2���;C�1��ّB�.XZ�_�q�/V+�m�������ݕ���4^�)��� : ���R�b��y�癦3A{�G���'��M��i}0�T/�5dz�;���OE�l�Sxt<�k���<�-�'�A��]�]���}ɗ�m1���.�b�����YҨi��4��*�������t�l�z �M����ɏ�r�j�Xr��=X~��.)*��h6�nhݿP�oD_���*yj~�x9!-��z|1��(��?��mS}��`���[���@~~��߆��c��>�jB���q+��ݎ���q���R �����s��m5I�l�᧫ʙ�;4��:QB~؍�&ǔ���3p֧�h�����\x����ӎ H=���~>N�~s`g����=��p ��|k�Q!�:��,��|?�YZ2wpW��͢�J�y��}����� -�Ư��g��=C��T�/)8,Ͼ?�n��)�%�t�Z�;R1��N/�~[��@�+���Pi(�dA���,�Ss-��c֩T�e�u���D� -�� 涂� ��7�����[��ݤ��(Ge%����d�l `����Z��c�9�Β��@��~o�i=�� �v�(����w�H�<�b�z�� [M,ݓR�=r���V���)��>4�yqP^|s��<�˫�����������%7z+h���6�4����DZ'7p:��3,b���c^�Nq���:4ܜH>��H�n�Z=�� N�&�ձ%�g�%7�����kg��i� n��>� S��r��T��D��=����T�_a�|3K�o�q��]O,Bȁ����B\.�4����i��5�8���,�������_-���ŗ����8���94��p$V��ɓƮ�J�賏��PrLWA&�,ɀ���b��<�#ϳ���_��{�[���.����r����w��#�p����3�˶�n��������ۦ�͢����B��Z����L(!=辆 -�-��)� \�?����}�(Ŷܯ����q$d���oN�_�PZ�G�*���d��� -�_~�OYJ��-���ͱ��qQ�8��q�ʹEJ����5L���5j�@� ��K��s�>�s��-�\�/+Qr�,�;?��ۅ9�@�cK�� ���^�����F���*��h�+����%�J��h+�ᛲ����fj�-�*m'��9��ۚ��E�=��V�7/xʞxA�{�_Q{�ic�"���sc�Ut}U�mm�4�;Tӯ�rش�o6��O��G�Y� -�?��ߝ��~imD<*�#ɋ��~wl�wR1endstream +xڥYK���ϯ��RՈC|����UIU��`�@��D/E�|�x���5�AR���rjk�@���n� +V>��4�R�O�{a��Ӄ�:`���@0���]�|�����R����zޯ"?�T�RzY�������y��f��:���n�s���=0�����&X�MSl~}�������X�^��O2�pn��*��SB�9)�e����<�85F8¬ s�g1Ԧe�?�p4� ��,��چ�������a�~5# ���&��E;0x0��U=�:������6q��<�ӹ)�?�ƣ��/�v�l�tI{{f�96[��^�<��u�Уل1��f�W��e�2�1{������N��H+A��1����4]�Ó�h�%L[1��X�G2c����Y�UϓSQ���W��M��+�Ҝeh��N6��&e��`��IgF&:'��K�p=-s=-Ef`�a�V����CWTz6|�zo� KV������U����0+>�5�V.-�g��l�Y0��N��Ufb���N����{V�A���U��`�ַT�{��B��m��S�������� �-Ӷ�vI�(R�'u��ZD:wfW��x��i֓v놗��g���]�N'�8�I���N��.�ew���Ό�#�x�~z�趗��t���0��ћ ^�A��r�~ +��p֫ʽsVk��wVW�Bno!�� �G���!�<)�E{�B�Y��XlB��2Ð�d�/uC�ȓ�[F +At%g�0��P�EӼ�}�Q<娗L�>���{"��-p�D^��Xq�i�5#")M�a�Ed +�J!�<$M���`8��ш��'60���O�yP�N��r|S�_hX���[+��r_ ��q�����I�_�؟�8���w$�TiGD���ĩԀx� �\`A�=�9$N:���\� #8.`(.��Qk�H�2~`� ��P*�ү�Y9d�N���H�GWޭen�M�*�u:��$��� ��SD$8�}�Qi ���{��0� u��(;�pY�R��S�����L��h�������a�aDO��&n^��2nr�UK�x�J����y�"�OB i�e����i�E�0�ډK��[TK�gԐ���uu���&�q�n��m[�H'�S�E +�Ka�[SΎ�Z���;$�7*"�� k��t+ +"���]%��^0 �Ћ�n��|&�D����"!�H鑋��k]RQ�c~��{r��������ԽL���B��"��`t���`I7Ou���2L.K9�J9�f�Þ��摗���*��7T��܆"�ʫ�����Ȗ���l���xepg.������w(����N{d��� ��鋭T�U�\[*���I��Jq�@���P�>K���M%S�a�hz�#�Nd�Z��������/�5��y�K0�%.5�N�FH,�K��S�v������e�ag��%�P��ȳE�K�K}�c��ⴽ`�},7�-0�!D6p-�K���" �t�K�@|(S����Q�=!T#�?�v[��E%?�M�U�TZ�(��Q� +������H��]4��Ұ��5����]K�cN�\�Mw��������t��S}���n����txA�ծ���ט���U�mu��(K�?b�I�*�$]T^���h4�'�+��Z_�`�i�ψ{��4�3�w�f�윘��X��H<��D �oo���+9r���S>�)}B{ +�q��֟�!�O�h-pJ{�e0�t��^�a�t,]<M����� +(rw�e�)fYcV'C�*�< �x���G�`[2/ɏWA���l� "P���nK�.��^0)+j����H���a�!���fZ=��z��t��l���M�r��8a�x��^v�GwB��Y՝{�i������I���F"��izs` �d�X"�r6�}����^1����f{�˽�ɕ�_P�$����5ʿ���F�d�q�ւ����pJ.q�h��P�S����@��~�4cNP;�2��oq�1��R�yq\��=��G(�?�z��1I�$qoŞ�+q��2�l�U���yI��ݦ����&� +���d�P㱝;Y/��{�c�z~�}�Ye)A��7 +�����S�Չ=Ҳ^s���gZ�R֩���g��m����*�p�]?���4B��yQ�Ћ��?�ꯪ�#�~���!G*�T��/?�^��?�k�g�a�y�)�W�nHl7���G�� +�*�V��=�I��w�N��Z��+�Y�e>���d�E���/�dؐ-|m���N�>֝��� z�&������mϊ}O��_p��WW��s&Dz��?�}/x�I�̺>�Q��5�Hyi�>�i�S;v����m������8�x*Q�+��D��~&�l�P�V�h�� +U#�Fa��n�����3� �8�Xy�1�͓������F +w�% x���K�#����?�KL�X�O��(�%�ﶒy���&� +����Rm�����휖yi~�{Ϧ�kK�p��{��P�PËR+seg��uM��Es1��*�d2�N�0LTw�=�C���[�$�f��xx*Ts�b��j�qz +$��������j� WT��`���)S��eS��ۼE7��+��~��'���0��~zzyy�����Z�t�'��=�1�K�8�z��� 1�(� ��/�3���1�nLTHii����G�pW��endstream endobj -4244 0 obj << +4239 0 obj << /Type /Page -/Contents 4245 0 R -/Resources 4243 0 R +/Contents 4240 0 R +/Resources 4238 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4242 0 R +/Parent 4161 0 R +>> endobj +4241 0 obj << +/D [4239 0 R /XYZ 71.731 729.265 null] +>> endobj +4242 0 obj << +/D [4239 0 R /XYZ 71.731 741.22 null] +>> endobj +850 0 obj << +/D [4239 0 R /XYZ 347.534 707.841 null] +>> endobj +4243 0 obj << +/D [4239 0 R /XYZ 71.731 697.476 null] +>> endobj +4244 0 obj << +/D [4239 0 R /XYZ 71.731 654.675 null] +>> endobj +4245 0 obj << +/D [4239 0 R /XYZ 412.638 643.881 null] >> endobj 4246 0 obj << -/D [4244 0 R /XYZ 71.731 729.265 null] +/D [4239 0 R /XYZ 111.263 617.978 null] >> endobj 4247 0 obj << -/D [4244 0 R /XYZ 71.731 718.306 null] +/D [4239 0 R /XYZ 71.731 615.821 null] >> endobj 4248 0 obj << -/D [4244 0 R /XYZ 71.731 536.224 null] +/D [4239 0 R /XYZ 71.731 600.877 null] >> endobj 4249 0 obj << -/D [4244 0 R /XYZ 71.731 513.31 null] +/D [4239 0 R /XYZ 71.731 551.826 null] >> endobj 4250 0 obj << -/D [4244 0 R /XYZ 71.731 360.882 null] +/D [4239 0 R /XYZ 71.731 525.923 null] >> endobj 4251 0 obj << -/D [4244 0 R /XYZ 118.555 322.318 null] +/D [4239 0 R /XYZ 213.956 512.972 null] >> endobj 4252 0 obj << -/D [4244 0 R /XYZ 211.992 313.853 null] +/D [4239 0 R /XYZ 71.731 510.815 null] >> endobj 4253 0 obj << -/D [4244 0 R /XYZ 71.731 268.728 null] +/D [4239 0 R /XYZ 71.731 495.871 null] >> endobj 4254 0 obj << -/D [4244 0 R /XYZ 242.937 261.974 null] +/D [4239 0 R /XYZ 134.999 486.371 null] >> endobj 4255 0 obj << -/D [4244 0 R /XYZ 410.176 261.974 null] ->> endobj -1758 0 obj << -/D [4244 0 R /XYZ 71.731 246.865 null] ->> endobj -838 0 obj << -/D [4244 0 R /XYZ 313.777 209.65 null] +/D [4239 0 R /XYZ 71.731 458.476 null] >> endobj 4256 0 obj << -/D [4244 0 R /XYZ 71.731 199.507 null] +/D [4239 0 R /XYZ 71.731 386.581 null] >> endobj 4257 0 obj << -/D [4244 0 R /XYZ 89.434 189.525 null] +/D [4239 0 R /XYZ 71.731 334.775 null] >> endobj 4258 0 obj << -/D [4244 0 R /XYZ 221.347 189.525 null] ->> endobj -1759 0 obj << -/D [4244 0 R /XYZ 71.731 146.522 null] +/D [4239 0 R /XYZ 71.731 319.831 null] >> endobj -4243 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F35 1525 0 R /F23 1173 0 R /F44 1994 0 R >> -/ProcSet [ /PDF /Text ] +4259 0 obj << +/D [4239 0 R /XYZ 417.328 310.331 null] >> endobj -4261 0 obj << -/Length 2643 -/Filter /FlateDecode ->> -stream -xڍYY��6~ϯ0��i���6ɴE4w��4EA˴��������9�/I�������Y?��ʇ�`�*���*L�UQ��Wg��U [a�.x�<��}E�\�i�z:�b?SQ��(T�$\=��^t�L�ކ�壘�o�ں��l�Lx3��\^YUz���?^}�4�D����W�y��U��0HP��~��xOҥ*F�����=�������ڡ��OC�Lc^�35� d����6T��4��̽�s%�X���m �R߫���~�,�/�J�EE����G{SiW��������ꅇ���������5��f$0�����G�j�(~�*�38������������ -�@X?�~X� �R��v��[��0u���\E�~� B��c���X�`>^����L��b�ñ�M�zaO���m/l�� *���{��4�+?I@N�'�l����z)�ƍZ��|� �4��n�Br-~3:!��� ������D��1��}�Z��Mf���>T2��A�?t�Uf����l�^7�>�aT�� T�5�B?&u�b��a��=�e�4�^/ޫp4�9u�U]��{b����nxAV/4�Kttl5f܍��oo��'��ci���8�3��Ωo�^���f��.*� �cK��M-� �CD���l���J"�����ȏ?��|-��T�Y4�����sgv6˝g\�m^��=X�H��bzx���Խ�������"�S���q����>�mq6��%H��%;��\s��Z���$�d��� �RV�����:n�e[�.��?���5n� �4-Hg�fr�er����dJgMu��!(YT�����Nl���t��%����_��}y�ȰF�y&�)���,P��٦Вߜ�8���l��J"Dx�<��a"��G�3t�y�B﹄"B��K��������$y�EF�{�Ͷ���1 �T�� �gѴu ���\�����WAs}e�m����W�����C��u �8IB�֍>��n�F ���R�����g�`b��,R7���F$�<��nC�s����� $Mp��7����Ͽ*���UQ� ���JT�;��NB��E~}�˦���!sZ�"�~�^��b���'+�`!�슪e�[+�'������C��5SN��HdD�6T_�� -��.>mMsd^v�p� S�n��l�Gޢ�k�f��}9\�+��2Ϗ�ϥ����)�`��G�L���0��h Ie};�a��dV��)(P� -���͔�1E� ·.�CtF�*N}�߇�]Jx��{��Y������١�c#�2U�'Wz��b�z�N��+ -�)�Ց���͘\�È �f�=�k^�8��g�`�8b�S�6�����(��LJ�����47%���F�0l9&���������+-�!�c��J 3:�7NF;]�&�/�/��]�ˊ�?��a�,Jj -���{���� �d�,�1GH�H��r�M凡<nR��i��JM -�j�mEFZ�JW���!��CoFiH+Вj�aR0�,X���E_v�c���U&�R��sϰ���UI��5��$,B#�Gj�k=M�:�-R��?�X�J�������_���� �r^bi��E�h� N���x@ !i�>�aj�pC[� {�Q��6�|�� ea'�q���v%�LX��i��FN���4�'Eɥ�`wƣH�&$���- 0>�i>^=<|$x�}�� -XvQ���-��;k��M)�`�x\��Q����SpsO�ν�Đ�R�������亾Eo�pO0� � ڶfǔp�cyٮa!�7<�d�3'=��\�\�����v8_(&���v(�ҽ\�hR���$|����k�-7.�u��v��ϔˊϖ�Q�t�Ju�]g7���~�L'c��v�;���1�'��ظ��H� ���B̖��E=� Ҟ.��rs�&ݎ!q�(���E�������bw���QE�m�O=�aY��ѣ�U������'H����9�p����F;��o�;;�c�_-n -n$�.)�?��..�x凷������s�6�"N�� -�}�Ȕ��,� -��g#M�g�2[���Z�kR����[��ܙ���������D�އҍ��������� Ƀ�1�;Zv�7�=_��w�7#"�]l��� �ۀ��*��m���um��ʖ��U9��� p�،� -;V�5j� ���8�������E�p��k�7���t�$.ᔨ�����YoD�u�@d�B`z�SW�z�b~���4䌒.]��A�ٟ6��6#K�t����S��\ʰ������^��)�B��wf����BG/Y�z ��K`�q�a�1�_��@���0�0�#L�p�0�Tt�<P�NM�pjǣ�g<�;A�.�V�|�eK -T����uX���mt5��=R,� \ P����v|�*Wv��(�;�z��k2ާ�ʅP-P������Ζid���$�� ���:�}����\�]��Ā��h��<������4>�����/_�&�S�>��'ޫ}�}�W����G�$�+?��d��~����H�endstream -endobj 4260 0 obj << -/Type /Page -/Contents 4261 0 R -/Resources 4259 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4242 0 R -/Annots [ 4273 0 R 4274 0 R 4275 0 R ] ->> endobj -4273 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [244.528 484.628 410.209 493.539] -/Subtype /Link -/A << /S /GoTo /D (cvs) >> ->> endobj -4274 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [494.336 458.725 537.983 467.637] -/Subtype /Link -/A << /S /GoTo /D (tinderbox) >> +/D [4239 0 R /XYZ 218.704 298.675 null] >> endobj -4275 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.731 445.774 267.724 454.685] -/Subtype /Link -/A << /S /GoTo /D (tinderbox) >> +4261 0 obj << +/D [4239 0 R /XYZ 508.932 298.675 null] >> endobj 4262 0 obj << -/D [4260 0 R /XYZ 71.731 729.265 null] ->> endobj -842 0 obj << -/D [4260 0 R /XYZ 369.417 705.748 null] +/D [4239 0 R /XYZ 76.712 270.381 null] >> endobj 4263 0 obj << -/D [4260 0 R /XYZ 71.731 693.31 null] +/D [4239 0 R /XYZ 118.555 226.836 null] >> endobj 4264 0 obj << -/D [4260 0 R /XYZ 413.928 684.189 null] +/D [4239 0 R /XYZ 135.395 218.372 null] >> endobj 4265 0 obj << -/D [4260 0 R /XYZ 86.396 671.237 null] +/D [4239 0 R /XYZ 222.231 218.372 null] >> endobj 4266 0 obj << -/D [4260 0 R /XYZ 71.731 664.099 null] +/D [4239 0 R /XYZ 433.177 218.372 null] +>> endobj +1788 0 obj << +/D [4239 0 R /XYZ 71.731 184.795 null] +>> endobj +854 0 obj << +/D [4239 0 R /XYZ 267.224 152.399 null] >> endobj 4267 0 obj << -/D [4260 0 R /XYZ 492.055 653.304 null] +/D [4239 0 R /XYZ 71.731 149.429 null] >> endobj 4268 0 obj << -/D [4260 0 R /XYZ 119.931 640.353 null] +/D [4239 0 R /XYZ 71.731 132.294 null] >> endobj 4269 0 obj << -/D [4260 0 R /XYZ 525.26 640.353 null] +/D [4239 0 R /XYZ 266.919 111.951 null] >> endobj -4270 0 obj << -/D [4260 0 R /XYZ 71.731 620.263 null] +4238 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F32 1215 0 R /F44 2037 0 R /F48 2049 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +4272 0 obj << +/Length 3097 +/Filter /FlateDecode +>> +stream +x�}YY���~����x(@�y�^�c{'�l���EFKlI��ВM���>u5I6���ꫪ�ꫪ���ϿK}7 ��n��w���w����|��!�٘7�g/އ�]��Ix���E^�Qt������ݺ������Fw�U{N����Л�.���3�Ͱ�s�;eU����n=����g�w��c���I:� �b7 +I��A/V�:��1�+ґ��gl�z�z����2�����m�XR�f?��L({��?vNmS\��oۣ�܍g��~(�r_ı#=�V}ۨMu�64O<δ�9��G��#�#����\�bC�S�j�G:��Ke�)�%�v�:�X�(��ȝm��<gɝ�v`b�����R�Vp�͠*����|Y��� +��a��0λ<����S����u�ß+���;s��ŋ���E;�Uhep%�9�R~��a��E�l&�l`�ЧK�SC�TG�?�CUH��AhnUg��P���[�I�ڴ�ao����Fk�Z+�t`-^:�~^���>y^P�ka�PF٥�,~P��F�� +��v���-��D �p�{��k2� ��Z���1�R��r4�b��E�ı�����-x])]�QoKU�TV��T�������SJ8/�<G���g<���k�hZ?��0tS��QFg�܍�6 +�d.�n�-���)9j����l�w +YAF����ijwmW��K'�����r��>��F�C/r����?���gz2B,ra"ߺ��3GCx&��[��J��a�_r$v�M��ˋ�Z����n���c$J�MoDS�����h���]y4���H Qƨ�cˍ_W=zT�k��W��D�Z�(z���ӈXOܰ,C��[ˠ���r����)����}T0C� X��8sv5.sd>� ��� ��ߺ����>�1�A��d��h���Ĺs�YfA �YCd�Q������ZY� !��d����@t�� 녅���Ю_rKP�����|)��V$�C5ǶEϾ�~�uYh�.����� �����!�vAK7��t�mox8�ރND1h� +�G3�d�pV��\��C�m��VOA;�ȭ���pա�7���-�o�tK�l�j(�D�eo���!���o�x�ݏ��;msd4�/b6⚶�s�Ղ�@͌'�PW�1zw�M�~W���rM� +7K�*��۶`�W<q��$/Z��=�dΧ �-Z.�j�X%���4V��*z���z��۩� _ȧ�"ݎ��J�Q��:@��&�<iE�l���\���K�����i��jbg��8��]|�ɥ#��ر�^�Zج��cX~Y�"Ww�M��y;ro����ʪ`�C�q������@���Kp�t��h ���Xt��k��f�/,Zn��y�j�afn�=�h%&���[�}k���p ���#����F@�)2��y���E��m\o���<6��VI�(p�;?��+� +!�F�!$n�)ia#�%��yЧ0`a��;u/���'X<�\?����;�C�퇇���+��0c�[V��ġh&V����� l�����=+�yJp.�<��2���%�c�X�"h�Weo����V2��e��#���� +#��U;n.Ð�{��y):2Jp��M� �ۦ�;7��4�m`n������ q��U��Y"�pC����Z�3�}=�SPV�J_Jc�Չ8����E,_@@7���s8f�fi��� "��#���v����\i"ː�I��_:�%7��0��(�(��}έ9�P�O�ZtΨ�>2db�\I�Rw����A�"�U�����k�A P�@^$�J2<���ނi�t �oq�O/��\�`�w�s@�{�vŎ :Q&1�����i�+w0R ��_�4�֯n;D���XH�\^�a7���9�P%̆��n��������:m�r�+�� +p�R ��`zl.k +qS�B��_�����&o��*�F$�|C�P�����/#��Ft2�� g�8$uz���B"��&�@�RuM�s�H����h����GᲘɴ�딂5�j�yEI^��A�,g�1���c�{p]�Ja�BI�ubRϴ�@��c'���-Ԝ�Bӊ��0���ZV8�Ccy� Ӎ����#���jw���n0O��⻗�$��F���§��"6Xa�)��0w���������,p ��%�RB'��=>���� ���� �}g�p����(�r�������P���J��;f��Ԍ�^NG�.�b9��p�ƺ�Th� �����e4P�xؕ�x(�\Y���}���}�(3�0K$Hx�4��07P�� ���h�k[�t�,FT��C��#$��&�S����l��~,9���a��2��_6#j�o)#n���2��yeJW�%��D!b^�z����N;.1U�B�����c��Z���bz���aj�)P���mYh��p��+ � �NvѩJv'CG���;++{*�%�X����L?�9 �䳍�R����[q��,m���m��e d4��:~�~즾 �T_S�%�X��^myn�ڤY42�K�$u�<���<./Oq$��-g<ڝ���@1$8�iU2���������D17�����?XΞ[�ŁfUi3>8e_���r�\�a�GLZ`7h1&�֞�՞��I�k�<ן�=��MDc�6�|�%�pA�'n�ڿn��#�؍<k�w�3�~�<��9N�q�,܌�K�ϯ-��"�u=��)�ΕFQ�[I�I�_*�'K�R�,����w�z���E��Zuؔ3�ģv��H��Vny]�I�zY�I��^ zԋ<:�'cyJ r����A6���?~Qy}4�B$��-��_����&U04x�(���� ���b��s�0����4Z凪�� �r����}x:������W������+��c-p҃%3T 4Y�z���_�f�P=�����+�����^�3�+�(p�<�]i�c�ެ@ +�����<�A���\|�a7��l:�J��gX#��wS��s#hߨ����(�7�(�g�B.ohȤ���s��;���O��g�4���8H��Up�4����[�K��endstream +endobj 4271 0 obj << -/D [4260 0 R /XYZ 71.731 620.263 null] ->> endobj -1760 0 obj << -/D [4260 0 R /XYZ 71.731 589.379 null] ->> endobj -846 0 obj << -/D [4260 0 R /XYZ 449.605 546.282 null] ->> endobj -1842 0 obj << -/D [4260 0 R /XYZ 71.731 542.451 null] ->> endobj -850 0 obj << -/D [4260 0 R /XYZ 159.442 506.909 null] +/Type /Page +/Contents 4272 0 R +/Resources 4270 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4297 0 R >> endobj -4272 0 obj << -/D [4260 0 R /XYZ 71.731 499.557 null] +4273 0 obj << +/D [4271 0 R /XYZ 71.731 729.265 null] >> endobj -1843 0 obj << -/D [4260 0 R /XYZ 71.731 440.792 null] +4274 0 obj << +/D [4271 0 R /XYZ 71.731 741.22 null] >> endobj -854 0 obj << -/D [4260 0 R /XYZ 141.108 403.577 null] +4275 0 obj << +/D [4271 0 R /XYZ 71.731 652.389 null] >> endobj 4276 0 obj << -/D [4260 0 R /XYZ 71.731 396.225 null] +/D [4271 0 R /XYZ 71.731 595.602 null] >> endobj 4277 0 obj << -/D [4260 0 R /XYZ 71.731 376.314 null] +/D [4271 0 R /XYZ 71.731 538.815 null] >> endobj 4278 0 obj << -/D [4260 0 R /XYZ 331.48 352.568 null] +/D [4271 0 R /XYZ 253.921 528.02 null] >> endobj 4279 0 obj << -/D [4260 0 R /XYZ 86.396 326.665 null] +/D [4271 0 R /XYZ 311.687 515.068 null] +>> endobj +1880 0 obj << +/D [4271 0 R /XYZ 71.731 494.979 null] +>> endobj +858 0 obj << +/D [4271 0 R /XYZ 308.397 457.763 null] >> endobj 4280 0 obj << -/D [4260 0 R /XYZ 71.731 319.527 null] +/D [4271 0 R /XYZ 71.731 447.621 null] >> endobj 4281 0 obj << -/D [4260 0 R /XYZ 225.881 295.781 null] +/D [4271 0 R /XYZ 366.772 437.639 null] >> endobj 4282 0 obj << -/D [4260 0 R /XYZ 71.731 288.643 null] +/D [4271 0 R /XYZ 71.731 417.549 null] >> endobj 4283 0 obj << -/D [4260 0 R /XYZ 373.626 264.897 null] ->> endobj -1844 0 obj << -/D [4260 0 R /XYZ 71.731 257.759 null] ->> endobj -858 0 obj << -/D [4260 0 R /XYZ 204.675 220.543 null] +/D [4271 0 R /XYZ 386.497 393.803 null] >> endobj 4284 0 obj << -/D [4260 0 R /XYZ 71.731 213.191 null] +/D [4271 0 R /XYZ 71.731 373.714 null] >> endobj 4285 0 obj << -/D [4260 0 R /XYZ 71.731 187.467 null] +/D [4271 0 R /XYZ 380.205 362.919 null] >> endobj 4286 0 obj << -/D [4260 0 R /XYZ 249.701 187.467 null] +/D [4271 0 R /XYZ 71.731 342.829 null] >> endobj 4287 0 obj << -/D [4260 0 R /XYZ 273.821 174.516 null] +/D [4271 0 R /XYZ 71.731 298.994 null] >> endobj 4288 0 obj << -/D [4260 0 R /XYZ 71.731 167.378 null] +/D [4271 0 R /XYZ 71.731 281.061 null] >> endobj -1845 0 obj << -/D [4260 0 R /XYZ 71.731 110.591 null] +4289 0 obj << +/D [4271 0 R /XYZ 71.731 257.315 null] >> endobj -4259 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F32 1187 0 R >> -/ProcSet [ /PDF /Text ] +4290 0 obj << +/D [4271 0 R /XYZ 228.316 257.315 null] >> endobj 4291 0 obj << -/Length 694 -/Filter /FlateDecode ->> -stream -xڅTM��0��W�H'��U�[��V\��7qSCcW��]��3�HڥeQ��Ǟ�7�b���Q�QM��5"U��*�z8���!" !�E��v�}�4Z�uE��.*�Ѣ�jJPS�h�}�7{v4|LRR�q���LڨA������Ip,���~^��.7��F놾 n��BGh��TYx3K@�ء�P� -�n��1!y�`qk���5�3�<JI�0)]�̀�'��G���5����y�9�ԑ�T�il��]�����*iFu���� ��q-z�;�孺��U�R��1�����a�� ��v����'i��������%� Z��U�ѣ�v��ޢOq��$��;v�n�.�v�ڣ�Z<��&��j������� ���f����ݒ�s�GцKf.#�:���7�㯘�*�=�I?��V�_�d=�4�_H������OP�����$�2'17 q`�n;T�s|�e���qb8@��(��љ^�f(��R�@������ˠUB��9{���|��2�I�+� �����v��@t�G(]����^���nP�sŋ��9ص�-�Brn�՜�k���tJ�2F�r�H���Ľk'��:j��h��;��E _��i�����:q�Ϙ��a�t)xu��+;����Z�ы"t�8(��� - -A����D?��+���͗�r����A9��X8M��w���?��endstream -endobj -4290 0 obj << -/Type /Page -/Contents 4291 0 R -/Resources 4289 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4242 0 R +/D [4271 0 R /XYZ 71.731 242.207 null] >> endobj 4292 0 obj << -/D [4290 0 R /XYZ 71.731 729.265 null] ->> endobj -862 0 obj << -/D [4290 0 R /XYZ 189.239 707.841 null] +/D [4271 0 R /XYZ 71.731 227.263 null] >> endobj 4293 0 obj << -/D [4290 0 R /XYZ 71.731 700.488 null] +/D [4271 0 R /XYZ 351.57 217.763 null] >> endobj 4294 0 obj << -/D [4290 0 R /XYZ 350.294 661.813 null] ->> endobj -1846 0 obj << -/D [4290 0 R /XYZ 71.731 654.675 null] ->> endobj -866 0 obj << -/D [4290 0 R /XYZ 261.414 617.46 null] +/D [4271 0 R /XYZ 71.731 166.555 null] >> endobj 4295 0 obj << -/D [4290 0 R /XYZ 71.731 610.107 null] +/D [4271 0 R /XYZ 154.754 153.604 null] >> endobj 4296 0 obj << -/D [4290 0 R /XYZ 71.731 584.384 null] +/D [4271 0 R /XYZ 102.167 140.653 null] >> endobj -4297 0 obj << -/D [4290 0 R /XYZ 365.641 584.384 null] +1881 0 obj << +/D [4271 0 R /XYZ 71.731 134.264 null] >> endobj -4289 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R >> +4270 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F35 1567 0 R /F44 2037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 4300 0 obj << -/Length 2435 +/Length 3398 /Filter /FlateDecode >> stream -xڕYm�۶��_�|25s��]b�Ml7�{�8��u<��ӁDH�C - Z�}� %�bwn�X�������g��_���r?���f�,������PF$Y�Gi�D�"��~��g���W����D�, -�,�g��a� ��8�=��^�)���h��^��},5��ݧ�����W��r�ޏ��<��/g��g1 -fX{)r˪�Ii��� LJS�D����}����^w�2 6��k�e��������t�f���(��%�4��Ro���>�G��E~��_��h��V���q�fϢF�q䯖�L -�[�C�������j���i)֎� �Ug�j=����ƾ)t� i�ыv7�i�����Io�OW�yg>U��f�ЯAK��cu�-?k�Rh��ZVq����t<�Y��{���o�y��v��~���� wF�s��m��b�����Be����r�&��`Z�߂V�ڻW������Nd���b��m�����q�8�=�SOq��Mf�l��TSQ@S5O� �Q�}��^�"�XV*T��X&v��CH����ȳ�g��h(x=��!�Ѱ�����P��������z�4����� *��;�L�����t�A}�)��3J�a�ڎ��/0{�Ep67о���۵�?0�<v����Y�d�b��ń�:]�-.x`MPE�k}���Gi��a;��"��8��i%9;�_ԍ��g��N�D�5WY<8�Q����a���������j�"O�f��d)�9�����8��IlP�Кz��K9���m�[�/�n���{$!��X��Og���eH˱��ٔ$�y,��fԿ�7���^L_'�"9���ʖLY�>�����n8E�2��f�}2��6X�JVG=8���{<���K� ��;��ς�"����j��q̆���8��B�D�#���e�Q��0�d����tG��� -�Jf��?ly���̸���2.�7:o�*o�p�8�L_K��D��|��VE��qW"��b����vˍ�>�l�D����?7�̂H�ulˉi���g��n?N�՟%��� -"8�N�,�%�w0�ְ��x_e~�\��'@b��~�gW�x�y�0v5PP4ݗ�/�8ȰZ���K�O��rf�P+F�Rm���!�~ ���� ,�H�����<y���u{V�C�5�-F_L�<��eQ��E��M�,�V�� ػ�c27�`��h�W��Z�NwOoҀB���<G[�ǔn@C҂gNZ���<�:����l 8����Bo�����l-�:�>��0&�~mħ�iEJ@�i�S�� -K���X��(��D�)}���"J��!�e��q@��J�MgD�� ƴծj��Bx�mI�1��Ejt�@G�0�ߕw�9rwN�@Ɩ˲<���i5���b[����,�MQ�7K�n�x�Z[����bl�����S�{���n�w�E����;����-��1��`�����YC7'��R -º;ni^*�1�iw-�:2�ϔCCY�_h�`�N;S���9��dj�Qp�Bq.4����ow r+�`�.fQ�7b�͢4����wwS8��Q�6\]�y}����q��M����b�EA�9�D����iZ �x��W��d������ -��jܱVw"�<d������Nׯ���PIJn��� -.��h��nb�NT(Ey��7n�tb|{g���;nR!�n=IS�@U"���D ���$J�M�������zHt��O�a������5����G �ܢ�#���iЍN�8��,�HLy��ᜏ��7�"��?���3��k�9N�H��ۓu�D����˥��F�<��d�uI�IHW�;H;��`������@wC�����JB� Q��'�$�����h&ej��(TbI�Ic������9ٓ�"�B�I�5=E����x_V�L����^4ŧ��*�\���r�^�+��� -���>��ܢ1rWQ� � ܪ[�Pm4�d73�MɼVS� r\��ױ���_�pF5if�ل�#������i���+o���i@��.ԁ�B����F����M�'?.!]��']��XK -<�������N��ds }��P-=y 7�?�y�n�e���U�2����E��] -uG�q�J��<~��d�n���#�<�yƿ�a�Hv�����Z��e, 9+2��7�YMr�H0@T+L/%��f����߿y����oY ̲���k��AD+B��V���5T��"�"q,50>]� ?�8�7K *]���сC[vy%<�� ��c�/��=~���u=̐����e-ş�1�[��>QU$��։k��l<{�8�:#?�$+.'������f�^�F+?��t�*�^�� -t����cWendstream +xڍZY��~�_љ�� ��:�k��`v2�� HA� Y�m�%��1=�_��(Q��g��b���������K#(�����l��w��˛@Fld����㛇���.��$�{��m�ԋ�ۻ4 +�,���>�Ӡ��&��U�q�a���^�n�q<��V���������r�^�E� +g�\IFw�dJP<�K�2�$]�^�B������_(��t9�DC��:�W�9�Šz����;��aL��S��b"�ثu���2L�z6����83������j��-���U�:�%�o���Mg���0� +8�A����D�b;�f�ק�J}�CS{|��$��l�p�����Q˶l9�|�t�,]gځ�:uC���g�"Z�P�]Q?UQ��_�&`�^'��Q��Q�*��깃EB�Kc1�胱M�%�$w���Q�����Fp�%L��J�,�⻢ma��_��`���MB�W�|��/�c��E�8�T�I�`�{e���r�fp���`��&8i�6,Y�JK� +6�q�gCX'�^�L@n���= ����R�����x<_��z���/c�������U������p/�<�XWz�P�/@�*kU-��ε�J \����Σ�{x! +� Ńa-pO�M����[�\��u�G���.�#�%�Y7��y��5#^����������.�g�@G��݀&�d��k���ʭ:!X-�*�'X���=r\D[��TћV�Mc�NN�b�8�Y�@7��p�ì�U�V�쀃�U`Z� +�Xbn)Xg=�tHl��",�1OL�6#�W����4pI��S�i�\ƒf qO�:�3���ƚ(rO�bC;6;8B�����4�ʍ{����J�J�䴆��_+��C�ƶ�\\Y�KwY)p��~������g�Sk�,&�Һ-1"�oS�=�4f���! � ��w��뙰�6$�;�34S����`��)�Y��p�n�Ϫ���N�|Cq!"���7��e����.�@OHqeG����{z���p^\�=��P�*����fq[�iK�U�#iM�^2���,tÈ�F��P-��u�&+d�Dp�01�@Q̇���X�Rխ(�����T�$ Ɋwphh�-ca�(0�و��ݸ�זxi���r)����}���d���[&�<k��x�Y$le5b'�:pI,���q���~T���L�[������B:@��<����.���m�����ꖛ��"�jC,��7���ť%��� )d쳪�"�3<��lHxQ�����ڐm<eQ@gj�w�fv�r�Ё@��i�\&��X����):s�=<��g�BKj�: Fp�M�h��c��xu�c)6����i�Y��<ڊ���+B�|�ة�Z��c�L�S�{�mJ�E7c�u�_ ��+�j��v⦊R�T ̞�f�����8݀�N��gM/�y�ȇu )����������`;(�/����v�{�z���z�<����w��џy�9�J/5�vb�?pÀ�\oQ�7B�IP���k�R6�����t]:�a��qE=�b��T-�]���j�����[�V�n��t�iT�c��F�0~�yA��O�,�6'�B!<m�QH*=�~PiU��͋�����ݬ�6C���M���4�st"<���.EDw�M��S��t���cT]_:���)X;��J���s^��] +���Nto��c}htU�e��˭;c/J3�� ��;��;��.6��ʀpT2h/�ة�@e8+Őz�5�i# ƨg��(kp� �A�˂t�p��zVF1�v�h��V�moO!e,y ��@1�GwL�$����Ϛ/6�q`>ijnO��jq@<a!J;��� +5��k�*�nu��� :c�b��"̎��f��h�xϝ&g�w4����'�>��s}W�OL�H>F>dDu�7j=-Lr/(�4�e��ĉ�\S��a+��U: +ဲ�K(�a��/��Z���<n'b�X����Lu��>���LTGB�'n��JF�S/�.� DD你K"-$U�Oa�ugZH`n|�V^�� P�>泓ν);F����U�/si��Տ��"���oE�⩜�e���0��Ĉ�K�tD���(XCX)�L���/^ܓ�u��}�j�Z#ۘ���t��A�m�buq�_}���fr�S)i�a(P&�q{���F6ɺ�=a��exm����Iբd��u������eHo��Y�@ +�˃q��РF�g�NAY$�0^�0 @��8�W 6a���!���Z� +�!�=���l�y���b9�l +���~$�SX��ĥ����|�8��������;��J���I�R�s� � +H�k��[8��>wřd:�eC�`?�d�� �KB����I����M���L �=B���=�{��R�)%U�ׇ���T>�d��e�X<��ղ[��(�Jo;���������n��� Y�]^���?A{?r��qB -������.��A/�2�'��̗u�8f~V�l�#��":?�$g��A�[��6"/�@a�5�؛��}6f�BI%Vم�Gdj�t�+�p�=G]UJ� 6,zl!&�.��ۂ9/δ *��I?��,X�+5Ͽ�qd��E�}��&6ߡ��8@��Mۡ�[��Q���D=�,&t�@�p�ُd��H��<��!�eqd��h!~��m�/��|:�g�b]_��������T�A|��ɤo� D��}��w� ��W��ࢩ��S��^���y!D���� � ?��4��'`Ȇ�I�{�Pz�Mp�`�hf�H�g<�woQ����q� +�T;���4% ��K���)�(��Ei�{)M��',l��Œ���̘-64�i��7FM�Gz��P���?��Ha�t���5�@�מL^,�07Rv��}zP�i��6.�O�Tc9���:C%����{��w,6�U������BQ)i$gC��%��U~��Av�şn|��4�˞-�Fd����⎰��A�L�%�F��e����G7���w#�o���E�#��_�?PN_E���n�Bp�{�6� +�\���Md��uYl��*���U��g�Tntu���1ii�$_���k���!"���邇�ȌXMV����z�a�xQnS~A,���?$���i+ĕ��:��� r��".�JPJ��$'\(7��73� �t}WP�4�{~�ԷА{Ql%�x�Q�m|��E���2�s�>q�R~�K7�F��.���5��?⊄ėV�����͇�$,a�X�#���ɿ����� ���ir�ϧ8�<?�LP�4{�L�+�h �endstream endobj 4299 0 obj << /Type /Page /Contents 4300 0 R /Resources 4298 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4242 0 R +/Parent 4297 0 R >> endobj 4301 0 obj << /D [4299 0 R /XYZ 71.731 729.265 null] >> endobj -1847 0 obj << -/D [4299 0 R /XYZ 71.731 718.306 null] ->> endobj -870 0 obj << -/D [4299 0 R /XYZ 366.546 703.236 null] ->> endobj 4302 0 obj << -/D [4299 0 R /XYZ 71.731 681.855 null] +/D [4299 0 R /XYZ 71.731 741.22 null] +>> endobj +862 0 obj << +/D [4299 0 R /XYZ 251.73 707.841 null] >> endobj 4303 0 obj << -/D [4299 0 R /XYZ 71.731 671.343 null] +/D [4299 0 R /XYZ 71.731 697.698 null] >> endobj 4304 0 obj << -/D [4299 0 R /XYZ 71.731 666.361 null] +/D [4299 0 R /XYZ 71.731 662.645 null] >> endobj 4305 0 obj << -/D [4299 0 R /XYZ 71.731 661.38 null] +/D [4299 0 R /XYZ 71.731 662.645 null] >> endobj 4306 0 obj << -/D [4299 0 R /XYZ 71.731 638.889 null] +/D [4299 0 R /XYZ 71.731 618.81 null] >> endobj 4307 0 obj << -/D [4299 0 R /XYZ 71.731 615.552 null] +/D [4299 0 R /XYZ 71.731 618.81 null] >> endobj 4308 0 obj << -/D [4299 0 R /XYZ 354.338 599.776 null] +/D [4299 0 R /XYZ 253.534 608.015 null] >> endobj 4309 0 obj << -/D [4299 0 R /XYZ 71.731 597.619 null] +/D [4299 0 R /XYZ 71.731 562.023 null] >> endobj 4310 0 obj << -/D [4299 0 R /XYZ 71.731 574.705 null] +/D [4299 0 R /XYZ 71.731 562.023 null] >> endobj 4311 0 obj << -/D [4299 0 R /XYZ 71.731 569.724 null] +/D [4299 0 R /XYZ 71.731 531.139 null] >> endobj 4312 0 obj << -/D [4299 0 R /XYZ 71.731 538.84 null] +/D [4299 0 R /XYZ 71.731 531.139 null] >> endobj 4313 0 obj << -/D [4299 0 R /XYZ 74.222 497.161 null] +/D [4299 0 R /XYZ 439.225 520.344 null] >> endobj 4314 0 obj << -/D [4299 0 R /XYZ 71.731 472.09 null] +/D [4299 0 R /XYZ 191.147 507.393 null] >> endobj 4315 0 obj << -/D [4299 0 R /XYZ 138.434 456.314 null] +/D [4299 0 R /XYZ 307.056 507.393 null] >> endobj 4316 0 obj << -/D [4299 0 R /XYZ 288.63 443.363 null] +/D [4299 0 R /XYZ 71.731 494.441 null] >> endobj 4317 0 obj << -/D [4299 0 R /XYZ 95.641 417.46 null] +/D [4299 0 R /XYZ 71.731 487.303 null] >> endobj 4318 0 obj << -/D [4299 0 R /XYZ 71.731 416.052 null] +/D [4299 0 R /XYZ 71.731 487.303 null] >> endobj 4319 0 obj << -/D [4299 0 R /XYZ 71.731 392.389 null] +/D [4299 0 R /XYZ 71.731 430.516 null] >> endobj 4320 0 obj << -/D [4299 0 R /XYZ 105.325 376.613 null] +/D [4299 0 R /XYZ 71.731 430.516 null] >> endobj 4321 0 obj << -/D [4299 0 R /XYZ 71.731 374.456 null] +/D [4299 0 R /XYZ 71.731 399.632 null] >> endobj 4322 0 obj << -/D [4299 0 R /XYZ 71.731 351.542 null] +/D [4299 0 R /XYZ 71.731 399.632 null] >> endobj 4323 0 obj << -/D [4299 0 R /XYZ 71.731 276.822 null] +/D [4299 0 R /XYZ 71.731 329.893 null] >> endobj 4324 0 obj << -/D [4299 0 R /XYZ 296.767 253.076 null] +/D [4299 0 R /XYZ 71.731 329.893 null] >> endobj 4325 0 obj << -/D [4299 0 R /XYZ 74.222 222.192 null] +/D [4299 0 R /XYZ 210.674 319.099 null] >> endobj 4326 0 obj << -/D [4299 0 R /XYZ 71.731 197.121 null] +/D [4299 0 R /XYZ 137.035 241.39 null] >> endobj 4327 0 obj << -/D [4299 0 R /XYZ 71.731 148.304 null] +/D [4299 0 R /XYZ 71.731 229.988 null] >> endobj 4328 0 obj << -/D [4299 0 R /XYZ 378.741 137.509 null] +/D [4299 0 R /XYZ 71.731 191.776 null] >> endobj -4298 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F32 1187 0 R /F33 1278 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +4329 0 obj << +/D [4299 0 R /XYZ 258.006 178.924 null] >> endobj -4331 0 obj << -/Length 3229 -/Filter /FlateDecode ->> -stream -xڝk�۶��e��̉�CI{:��������t:���)B����w_�C����s�X��žu������w�>A���j��]�`��G�P̅d>�y~�h�2�R7]�W�۫�� �nW��?�g���r��lD�����}�x�����2��˙�Gγ��s~����/�n�{�0v�$�*���� �L#w�&�� �Kb�rq=�"�^��13`�������dd�k�i��nx��=�hڬ�d�Q[��n��ک\�����8c� �����iG{����j��֥���C��J��,J�l�;U�p�Z)j�n*�C}�Y���v8�ED��������<������9o�ܿ�����w[�o�^�JvRe#P�5<��rA�y�X��2�ŋ<S3EV�M� -��H���Q�>w�Ҭ����fr7���`����_��$@kQ�}V»����-07�����{u��3�N߹��a��rQރ�U��Dzd�ZE?�j�BiCj������3��<W��� -�, ou�:Y��#R��]�mة�Ŀt��̠�� �E�2��T�3��{��Zk�'�q'���f,;>J����T�=P1P��ZZU��QOz�Z�2�Ο���S�n��pPu{���C��o�2�[����'���� -�ƔJ�5�th�.��O������;u�a�a�%���0�Dc��n'B�1�C�ry�;9^^ �r�♇QL�nl���y�m>уE�B���f���A��+������ -UEG+j�+8@d��@����������=���T7��ڭ3ٮ�`����t��ض���f�nE|#�F����l2]��A'����j� 5�6�jk���� 4����!u�C�ÑuF48�Z� �6݉N���bM��y@������L�����N�B�.�h�����x<�V��K'�\p�`En6���.����-�}�~�'+���Ĝ�\�Ԍ��'��WD�2,>��d�2v�`s�`N���s�eL�@�➛�P���h�&l����O��2|w�g�\;���p��(�34Mg�NH�|�Ad�� -�_|xX�r,���m�Y�n>���`���\�~b L�1h��p���o -�P��x�6YG��+��BmEtUV��F� -����yv��'�E�6e���D��R4ǽ -�Y���Z0o >m��%BiW�����8uk�z)@�s� b�&~7]]���In` �3Q�_�m�6�,�,-�7���l#���D��7�O3[;m9֕nu���N/�I���n8���[28�É��!p����:�K��N?���h7��K�f����I��t�V(� �� -p��{��+�YirHuh�-c��0�aU۱�#�=V�ia�����������;����|�]ޚ�{�ma��K�)��"���`k5�p�a\�l,�,|�kH�[M���JΖ�vd�y�D�T�>��V�x������i\��f����kljr�y�����p%བ1�>U��ЕK�U-O���9`�C���`�@~�@�=��2������vu��O d�Sy��蟍ax�a�A�d��$ߵ�>�e�d2X���3�h��ҙ�k5��{θ�i`��0����P�;���ހ��]V���� ��@���#�X� �C:���P�ψA��*"�p�����>�T�AO6��:�ۭ��n�����/z.p���o^��¿nN�),X�1�`�N\��[�5ޓ����L������ƜQ�E�MF���a~�����ď��L�1�����L�{CPE��7�GP8ۙ'��N��I�=��/��5IX� v����Y7P ��-ҠB6 -�Űy&��h�� �${ǚ�0,m�@ڽ�Mb�yn$M!��d!��(p�I}�Ź}��m�E0�i+P��/%��#-����N�m���k��0��!�T��삾o������!���By�J����Jw�~dz˝z@e�ƚ4X�/t�4<+����1�����Eׄl$�8F���<@��*YF}�,@t�#��l����5E��@�>\I��'��mA�݉*� ��$u�0NV��"���&��ZQ�V�r�;cr���,�6��Bb�cU�+xL�M�J��9B�ǔ�����#�_�fS�]���z�S�Tf�iu�S�M����lr�QK��ZSݍ��]��]�_��v�U�+� �k���TM�[c�f���J�9��c¥�L��RO%��:)���G�r�۔M:4S��(��EK�85�7�Zg�``P�ʢ1V�g�����+��/��H� e��IK^ɟ�ұ�$;�!ۋA�jJ�Rt�^PS>�R�WSG� -R�Զ��]'��Ĺ��YK�F�;&dA���4i���;o`�w�2�#w�$�SH��Q]l�p����?���Ē�P[.S����P�V1~(�a -L��������md��+�9�z2Z�f[�LjjS<M�Fچ<�{j� �~���>S���`"ù�2+�BۃD/G�E�/u������A�}MI�Cp�~�$�����[B`>���I}�������� ض���p�-K�m����k�EU�X(mȁ��H�O�I+�D��0O�! -�ᩏ2o�" �&r�`Ce �5�yNV}�Ȯ�Y.9u� -�.~ͅPQ+y7�˅8~y��4���ϱ�����g~?��������<wY�z��� �� YI*�eq�Vޞ+t�r�`pI�������,��5Ɵ�.�ȏ�f��e-��]�ב�0�����+Ig3� ōᜱ�6O�~}��T}qd��T#y�&���9z���2���<dYӏf~���lO���Rg��t$Y�?��g-9[:�O��b[�=C������Z�����B�䆉M.ʊ̅�K�B�;�ƗT(���*�ߚ�h��I�O��%�FŴ�Ae�����q(�q�Ʈ�ؚ�dš��ԃH$,�ZQ������$�Y" -���`����OW�J1�'���"�.��(��r7̓$�Զ=����>Feԩ��0�H�)�h쯷��^����/����:�`�64���앸h<]��!4�ݕ���X�+ԫ�@������_ ��f�a^6r=�L����Aq���|w(O��A��b�@��o3��?͈���� ^% ���'���endstream -endobj 4330 0 obj << -/Type /Page -/Contents 4331 0 R -/Resources 4329 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4242 0 R +/D [4299 0 R /XYZ 394.451 153.021 null] +>> endobj +4331 0 obj << +/D [4299 0 R /XYZ 71.731 140.07 null] >> endobj 4332 0 obj << -/D [4330 0 R /XYZ 71.731 729.265 null] +/D [4299 0 R /XYZ 71.731 133.681 null] >> endobj 4333 0 obj << -/D [4330 0 R /XYZ 71.731 741.22 null] +/D [4299 0 R /XYZ 288.129 122.137 null] >> endobj 4334 0 obj << -/D [4330 0 R /XYZ 71.731 675.303 null] +/D [4299 0 R /XYZ 111.088 109.186 null] >> endobj 4335 0 obj << -/D [4330 0 R /XYZ 429.028 651.557 null] ->> endobj -4336 0 obj << -/D [4330 0 R /XYZ 153.769 612.702 null] +/D [4299 0 R /XYZ 325.619 109.186 null] >> endobj -4337 0 obj << -/D [4330 0 R /XYZ 453.126 612.702 null] +4298 0 obj << +/Font << /F33 1306 0 R /F23 1201 0 R /F27 1208 0 R /F32 1215 0 R /F35 1567 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 4338 0 obj << -/D [4330 0 R /XYZ 74.222 581.818 null] +/Length 2381 +/Filter /FlateDecode +>> +stream +xڥk��6��� +#�"6�抢^��4iS�h�ꢸK��+�6o%�գ����gd��&�l� ���<(g���T�T�O�a���*�m���W�)�L��мX_ݼVj��D�֛Y�BE�,U���p�.��_���3�b��<���o;W���[B�跟rn�R/>��z�>��T�2�U����t�nP2ȼ�(��[ӵ$�Ʊ�F�;Z��� -݆~m�q iS�κ�p����߂���-$�!(wei����%���p���5��.�`�ے�뾺�E����`![�t�����3���oc��+���+Xk)�T�4T�35�����yctg<�,ٙj_�hTX���Y�Mжr� ��|s�ޛ�~{ClorW�ye�Nt������d����� ��+�e�H�] +�Ti$�T6�$Q\��.��w�e��̷�CY�,E��@�,D�J0�mi5��v�z���1��s�ԁ�v���i�>BS�"�;�~�s!�9o!�1랮�g���-YNR�n[{_w�ӥi�L$Y�*��f�LJ<�X�ۅ��|x�$�L��& �l�;D�4�P�n ��s �g���t�k���v��5���_��vV��˘u�����=�l�C��}�T*; ������o=���z�<wMAy)Z���w[��ή]�cï86�l�ѷ���' Ԇ��s ��-b�l�i��m< E�v�8�$i���r�R$r��zj�=j������٣�|���tm�=�ŜdƷ�3�T����`A�t�����l��BEr5�Pq_�����/P�7�=!�NbeE�A�/�����t��xt�L_�y_'�*Pu�yS���n�Bsz�%�k���5��A���ID(|�M��KWc\l��4�^_x=�#~�3T-�y`�[k��L{����ר��t�o d���g�t�s5�BK������͟�Q!4�'��^����.�8� Ŀ�ۓ�\״�u������K��-�88��e�ښ��` +aX�JϹV{��o����FJ��\�� +ܸ}c�~ b�7��=�~��5��'QD\�X����-S���� t���A#>d����L�����-&m�}8�`��h�"��]�����E^���$ ׁ}�7�[�����t���*�V:(���o�Z�9��o�MM�{a|K��d��l Uϖ�.#P7�e눜�+l�<ږ��m�!�v;�yeE�N�:�?���6�Ѽ�9Z7t�����&�� o������$�F��I8����b�(C��������������cɸ�4�]�m�����z��)jV�� +*�X��"�� �}��z��X��vd�݅Lq�d��n�K���}��#rWc�0F}B~������SG�S��:"ڛ�MrL)����|��ݝ�o�/���T_�0z��5*�F�ew���Ȕ�Yvi�i�V�0�aP�����0T�����ƃ�������%J�����Wxz��KK��w�NC�b�9*7�W��E��~P;�\e\��P~N+իO��[�����x&�i��|��R�8�fa��,U8�q��C0+`�����+$�`xU�j&�j�f��m�~��Ǒ\�8�:�5���.,Y��"VjV�%\ +x6�Hd���w�uS���a�� +��,�!X&"Qdė�C*�s� +��|� ���[�,�`���#����9��;�֧QӐ�qg�>����ÛH���>�ε1Xڜ�i��]��@�^w�N�WÒ] ���J�,�_�@��� j{�Jw��2�ȷ��xF�(�"� �w���N��fq�d)��l���-R"�%� ���G�NbN�Dɯ=�HHPYD���4^��k������=�Z����N����x�"� +;4��"�rW�;�p4ru���)q�o�ڠ�uA��i�,�s�bL笡9�nG^��o+��e�B���ȣ�-d�p՚��dnZAHNZ����䜦<84s-��@]km��>�|���7DBOUS��TJ�n���z�@�Sh4_'�pp�Ho0��_�9�7��$�93�@B����F��=���u<��8�@���}��L����Uc�u���i��4�6����y��#�#��~������Z�m���~����2�S�����]sGg�q-�TP-��ѫO3��s ������;�`����?��\��0i� +~�}��|�w������b�&�����}��S�z�}�Q�rbYHwds�Ԏ�� ��f�s+.#�.v*)�>�Û���{O��0Q�&]��k�y��O*����|�s���G��1Հ�j�AO���>�\<��a&�p`�:��/��_��_�/Oendstream +endobj +4337 0 obj << +/Type /Page +/Contents 4338 0 R +/Resources 4336 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4297 0 R >> endobj 4339 0 obj << -/D [4330 0 R /XYZ 71.731 556.747 null] +/D [4337 0 R /XYZ 71.731 729.265 null] >> endobj 4340 0 obj << -/D [4330 0 R /XYZ 71.731 522.939 null] +/D [4337 0 R /XYZ 71.731 741.22 null] >> endobj 4341 0 obj << -/D [4330 0 R /XYZ 105.883 497.136 null] +/D [4337 0 R /XYZ 71.731 677.46 null] >> endobj 4342 0 obj << -/D [4330 0 R /XYZ 71.731 489.998 null] +/D [4337 0 R /XYZ 100.413 664.508 null] >> endobj 4343 0 obj << -/D [4330 0 R /XYZ 132.174 427.397 null] +/D [4337 0 R /XYZ 71.731 644.419 null] >> endobj 4344 0 obj << -/D [4330 0 R /XYZ 71.731 420.259 null] +/D [4337 0 R /XYZ 71.731 621.504 null] >> endobj 4345 0 obj << -/D [4330 0 R /XYZ 71.731 350.894 null] +/D [4337 0 R /XYZ 71.731 576.971 null] >> endobj 4346 0 obj << -/D [4330 0 R /XYZ 71.731 350.894 null] +/D [4337 0 R /XYZ 71.731 532.438 null] +>> endobj +1882 0 obj << +/D [4337 0 R /XYZ 71.731 492.887 null] +>> endobj +866 0 obj << +/D [4337 0 R /XYZ 461.484 455.671 null] >> endobj 4347 0 obj << -/D [4330 0 R /XYZ 74.222 308.842 null] +/D [4337 0 R /XYZ 71.731 445.306 null] >> endobj 4348 0 obj << -/D [4330 0 R /XYZ 148.772 285.928 null] +/D [4337 0 R /XYZ 71.731 409.644 null] >> endobj 4349 0 obj << -/D [4330 0 R /XYZ 71.731 284.52 null] +/D [4337 0 R /XYZ 71.731 391.612 null] >> endobj 4350 0 obj << -/D [4330 0 R /XYZ 368.158 267.995 null] +/D [4337 0 R /XYZ 335.135 378.76 null] >> endobj 4351 0 obj << -/D [4330 0 R /XYZ 95.641 229.141 null] +/D [4337 0 R /XYZ 117.651 365.808 null] >> endobj 4352 0 obj << -/D [4330 0 R /XYZ 71.731 201.081 null] +/D [4337 0 R /XYZ 71.731 352.857 null] >> endobj 4353 0 obj << -/D [4330 0 R /XYZ 202.524 180.324 null] +/D [4337 0 R /XYZ 294.096 352.857 null] +>> endobj +1883 0 obj << +/D [4337 0 R /XYZ 71.731 335.756 null] +>> endobj +870 0 obj << +/D [4337 0 R /XYZ 392.055 292.659 null] >> endobj 4354 0 obj << -/D [4330 0 R /XYZ 340.43 180.324 null] +/D [4337 0 R /XYZ 71.731 288.828 null] >> endobj 4355 0 obj << -/D [4330 0 R /XYZ 71.731 167.273 null] +/D [4337 0 R /XYZ 118.555 246.638 null] >> endobj 4356 0 obj << -/D [4330 0 R /XYZ 385.027 149.44 null] +/D [4337 0 R /XYZ 526.195 238.173 null] >> endobj 4357 0 obj << -/D [4330 0 R /XYZ 71.731 111.417 null] +/D [4337 0 R /XYZ 71.731 204.597 null] >> endobj -4329 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F32 1187 0 R /F35 1525 0 R >> +4336 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F35 1567 0 R /F23 1201 0 R /F44 2037 0 R >> /ProcSet [ /PDF /Text ] >> endobj 4360 0 obj << -/Length 2321 +/Length 3247 /Filter /FlateDecode >> stream -xڅk����� -7)�r����|h���{m��r�A�+�D��ɢ#J�s}g8#[~�&9�=C���~�h�iC4Q���ͳ`���7�B����xz6yǣ��e��i9J�T�H'�D�F���?��v��R�Qx��Ƨ��ɋn�?]U�V��a�z��$�ޏ�����WO�x*fy�U&{�.���Y*�$ey*���8�e�g�wlD���Y8� -��Ⱥ�+]+�ۍ��3��8̽���|"S��BץG�����Օ�<ߛ�0ee ��r��ǠE{��Nׂ��-�����%����q����@+�\�E;ݮQ��#?�Č-�:_�Z6{���T��`�訲,a��X���m%E�C�Ʊ�f)c�ֺX��k���ƶw����9_��r��!��q��@d�̑{x�!�����^��ơaV�,�o��ˤ���&[�T� 8@0F��������w�Xi}'�K9A�(� H玱�V�Ir��Z{\��i�{{4��Zc�X�R����o�L=B, Y��*�YE+�����C�u���r�-Ue�Ivslj\8�g�")��"7�JYF�K�4CS;Sg!��Bi�t��x���jA����E�5�h:T���-�%hI\�0�C�$y2u����q:�h�������ۘR�\����B�mP��{�G��x�ꉴ�F$��3l�.}<�1Kf��v7��)Qk���/OD4�zle[�IZ�@�|l��Z���8KE��!ſ�"�=�V���tx<��j���d\��B��4�rf�$�/��`����~��5��4ؘ�j]CR[�f#[��a��<�M:��ӭ���NVJZF*֪����H��'��P/�����6f�h�b��B0���@/�5)��%��ݫ2 ����7�.� -�n����d��a��{.�¸亚����r���q -�k���T�:3��@3�G�����b���䥩U�5:5N��>�ɤO��֪jy%A'�ٙ�%M �8�����WLZ�g�,��R7�\�������j�5~%�t�2��[C�.�R5�b����8h:�8>����Y�|�i,���p<+����;n�҇���tIHmOk�6O�����bO@�ږ�`����7/�mA�ͶQ�?��E�����á� r�p~J��9) ���̺;���� ��J�n00���p4������Ҷm�7�AC�h��/au�����4�Б�)ǵ^��� ��A���&���14=�����.�ܟ�{ԥj��t� d@��'�iD�8���(����կ~���_�?��.���?a#�M�s`c�*ף���Y<�y��u�@*�@�(J`�֚B�A�S�G-�عi��ڐ��(pq��+�V� -ڸj#�G� ��B�"�j�HV��垠DVS����ZE{�c�LT-��ʮb -٪�fI`��ߖձ��'�p5! �?�?��%V�0���?]��b��+f%��]Nz蝃+� -��}�hɪ�x}���s�ΐ��d��ҍG��1՝�� -c>iީ�F�Q�c�"D�g�Q��2F� -��Y���d|�\�=95�uu Q}Qnf���� A��x����<84,f�e"J�93t����4vr:�/�t�^���OEo�'�:��p�?C84Ԩ �ڔqoU�6S�On �YP����2�_!���q��f�|�(�8%��b�&uz�U�O��C��)�u`���U��N�g %I����v���A&D�5�u� m�{�@[�{���=�&A���e�v�4Ks�4��L��1����6�H����]C�;kJm��Zj�\$�}X�V��JD�Q��a�:�#����J���'y�A�������G�i��FS/�l�1���:�vj�/��-1�E3j���n]W���/ �ښ�;�ToU�ګ��f�R.j��5��l^%�/�m�C�m��q��o g&tXp6�����M��ǾW��:8���7R��v�4�E"�f�@dy~��� p%+����ץBŸ6<����w�&\xt�SC�Ԋ��,�X _���/���ɞ}G�݇,xܷ��l�j6��9�JB I�8�G%p3ͱ�]��J{�xz�Qq�Q�����@�X]�Sڲ(��u$�}3`�4���c��-F^}����9&.��(���0�6�`-0��]�+�M�U M�pC�!�Ⴓ����=i���(�&��%~�9p�?TOS��,7l���Yo�F�G5�h숛������V�ޛ�"�_�"|D�� �F�������]�����endstream +xڅk�ܶ��Հ[-����iaN�"����W:-wW�VRE���_�ΐ�V��N�p8��ኛ���M&�,�OX�a��T�g��F�}&c�(;�����o����4��?��A�Gq|�E��'����'����G9lvax�O��5v�Z����.�_7«����r��go���I��E}�9���.�&��&�\3��ݟ� 7�(��4�Ǎ��:�n��KE��@�S�}RwԮ��n/�&��y�<�M9�>�_��k�n&�#u�F$�G٪�ked�C��yg��w�^�tA� �����A��T/��� +��]ݎ +�!���B9��E��2T��8��jK��S�H��� +�лE��ќ}a�z_�}i�����F�%�6 �'�uG+��](��k�w {���SVҷ�6����r��3:jՊ�AW��-�rOM8Q��FogHj��/�3b�v7�wR�0��#i%�g�Y��G�PH$O��R�#C��;М�aƩ�c�yGɠ~�*�����O�7eu��{0�d�%!W�0H�w�^;���AVc7<Q�$�ҁ"`:�ldv�k��s�����`�)Z}�G"L�x���~���/?�����[����<`"亏0(�\�L +h�A�}�{�N��"�K8f�9;�4'�m< �:N{�*�K'�-TM���b"�E4;iU%4�"F4��/�H:d>и:Cְ �ӭ �a�$ӝ������ؚN0M<�`�8I�X��L�l���� +ϾZ?{�8ɉ�:l%9b�WG�OB�n�Y��}�h.sD����Bp����鴳5ȴ��``!�ݻML��D����jŲ���H� ��S��G�� <Q��������v�'/�=W��w�;^r���H5��L}!X�2��A�y��MN17 уcC�p0m +�/�7�bKø�9��si�!���H��>�k&_҇-,:H2.zP�~��8a�]?�=��I� �k�����n-:9v/r8@�P['#e;RO�A8�]2h�����H���,���xX�.�\��͆���=PS4�����GC}¯Ռ����S��ac��D�����&,��fG�M���^7�����tǚ&ͷ ���1�g ���N� ~���na��k���3(�"%�g��G���Ɛ�A�0���`�ܙd8[D�)O�┻�(�(��9Ʃ���L��0\`TҜ�l�-~%�+Գ��#C^bV���r��c�\e)��x���=�H���U���i4�� +3i�I~��n/�?��Z�:�>�y���E���.�k=$�oC��X9�]�~�3%XO9�[u���o�������^���-���h O������X/vÑg���-8(�:?0�1�3�@CkT�''�σ�#k�*r������Y�P&$`�ݯ�z�k��]2��Mc��Fkïֆ<�!�[���`�R��1f�m +�5�F(��.���US�і���e�PW�h�>'놝%`'����ܵ��.�◕\5��`ܭ=�a�l$ �],<#���0�;%��5j��?��&����q�t�-��y°���!�ĨA�q�Q�Tf�S�D��uR �.��/���t������0�UI��x�m�.�uS>4<�xK(�������U���`�U�L��m3ֻ/��i�)0��x�캆��V�?�|��t|y�{:(Tٯ���y��n�� �:ͪ;V���/��A$�����@)���&����j�k3Kn��cczf�˹"�`LJ�g_�(�0&�q�$i���%b5~��!��WYa�gQj�.C�I�-�!�y*6�م3:�Å�6���N pU�É*��Du6�)�@E����V����5�zd�H�4�4,1�S��]�e�.G�x���Y�1�]`���f�k�?�cw{�Dp7(�s�7�wZ�&�f,Q�/��������#i���?*9���n�-cK+c ���i�d��; P^@r@.Yg��+�70s�_���₭I{�Z�"4I� �/�˘���������!|PHJX�(����^��E�K��AS���*C��s5�S��{�F4uk���� �۾S�ho�v�ڹ�M��6�xpqx� �ݽ��s�索��d��*j�h8�k�٥���\)~e�d�^!�W��[J<���Cw�� qX�is����.00�����N�q�*A%01���Ŭ�8���s?��1ͯ�9�&b�"h<��[�s�0���b�F`�ճ�lЬăA�c���MEf��O� y�IV��N���pmE˦���n��(�Z����FdJO\�JH)�.L���S��K41�Y����yDc� �. r%}6�%J*}��b ���9r�����(�x�A?�`2j u +��hE��P��D5X���D��>�*b�Z�����= +0�)�o�^�+�I��P��Q��T��=JF��Ja���z�Q��6��{(:1��Z�zX{u�C}RT���f�p^��VJ]}`� �Q��)�'^U��r�)�U��q����u�0���˖��<�պ����;�(���@V ��dzA���Y,�+��kF�#*�a��F�P����� +L���X��У��r@��uY��N5q��T6�V�m�_l6�Ej���HR�yi���S\��a|ȁm�G�����jB�ZT}�:K9Z�Vƿ�z���^��6��)g���]dd��I�T�EB��~��>�x�&m�;To�&�C_>'\�`�u�*s����D$rߐ�k�`v��3sba�|}���G(���Mjz�rſr�����־ +�:��;l��;~(�ؽ�!���("�D�<�r"������ڱ�[�S$�RlKm ���b��<�],ߌ�[�m *�|�D +�@;Xq㕰�c�[�Xʒ��X3Z}V�fcD���8�c��������I����&&s�6��y��m��ʯ�H�C��l�G�[���~�R�(+fy����/��`�-<��㜫�e�7+�V.Rz��4(�gP��&�,����Z�5��ז}���c��z�~�dN +���$�"q�/�w�W�rc��9R=Z�b +[��q{�[��7�A@���C�q���8bV��{���W�7�W�p�W���d���e�������X��7��IZ�_�Z���~.�/��gBY��' s? �S���r�+���endstream endobj 4359 0 obj << /Type /Page /Contents 4360 0 R /Resources 4358 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4388 0 R +/Parent 4297 0 R >> endobj 4361 0 obj << /D [4359 0 R /XYZ 71.731 729.265 null] >> endobj 4362 0 obj << -/D [4359 0 R /XYZ 71.731 660.359 null] +/D [4359 0 R /XYZ 71.731 718.306 null] >> endobj 4363 0 obj << -/D [4359 0 R /XYZ 71.731 639.203 null] +/D [4359 0 R /XYZ 71.731 592.613 null] >> endobj 4364 0 obj << -/D [4359 0 R /XYZ 71.731 619.278 null] +/D [4359 0 R /XYZ 71.731 550.834 null] >> endobj 4365 0 obj << -/D [4359 0 R /XYZ 115.567 595.965 null] +/D [4359 0 R /XYZ 127.205 525.031 null] >> endobj 4366 0 obj << -/D [4359 0 R /XYZ 71.731 568.07 null] +/D [4359 0 R /XYZ 261.701 525.031 null] >> endobj 4367 0 obj << -/D [4359 0 R /XYZ 376.59 555.118 null] +/D [4359 0 R /XYZ 468.045 525.031 null] >> endobj 4368 0 obj << -/D [4359 0 R /XYZ 216.969 542.167 null] +/D [4359 0 R /XYZ 237.789 512.08 null] >> endobj 4369 0 obj << -/D [4359 0 R /XYZ 200.218 529.215 null] +/D [4359 0 R /XYZ 71.731 499.128 null] >> endobj 4370 0 obj << -/D [4359 0 R /XYZ 71.731 504.862 null] +/D [4359 0 R /XYZ 71.731 479.039 null] >> endobj 4371 0 obj << -/D [4359 0 R /XYZ 71.731 452.937 null] +/D [4359 0 R /XYZ 527.223 468.244 null] >> endobj 4372 0 obj << -/D [4359 0 R /XYZ 439.725 442.142 null] +/D [4359 0 R /XYZ 147.048 455.293 null] >> endobj 4373 0 obj << -/D [4359 0 R /XYZ 95.641 403.288 null] +/D [4359 0 R /XYZ 225.125 455.293 null] >> endobj 4374 0 obj << -/D [4359 0 R /XYZ 336.678 390.336 null] +/D [4359 0 R /XYZ 71.731 448.155 null] >> endobj 4375 0 obj << -/D [4359 0 R /XYZ 455.543 390.336 null] +/D [4359 0 R /XYZ 153.849 424.408 null] >> endobj 4376 0 obj << -/D [4359 0 R /XYZ 74.222 359.452 null] +/D [4359 0 R /XYZ 385.305 424.408 null] >> endobj 4377 0 obj << -/D [4359 0 R /XYZ 71.731 334.381 null] +/D [4359 0 R /XYZ 132.582 411.457 null] >> endobj 4378 0 obj << -/D [4359 0 R /XYZ 71.731 316.448 null] +/D [4359 0 R /XYZ 71.731 405.068 null] >> endobj 4379 0 obj << -/D [4359 0 R /XYZ 218.849 295.691 null] +/D [4359 0 R /XYZ 488.392 393.524 null] >> endobj 4380 0 obj << -/D [4359 0 R /XYZ 71.731 293.534 null] +/D [4359 0 R /XYZ 71.731 349.689 null] >> endobj 4381 0 obj << -/D [4359 0 R /XYZ 486.265 264.807 null] +/D [4359 0 R /XYZ 71.731 349.689 null] >> endobj 4382 0 obj << -/D [4359 0 R /XYZ 71.731 239.736 null] +/D [4359 0 R /XYZ 71.731 300.215 null] >> endobj 4383 0 obj << -/D [4359 0 R /XYZ 71.731 239.736 null] +/D [4359 0 R /XYZ 71.731 267.174 null] >> endobj 4384 0 obj << -/D [4359 0 R /XYZ 71.731 216.956 null] +/D [4359 0 R /XYZ 71.731 197.435 null] >> endobj 4385 0 obj << -/D [4359 0 R /XYZ 71.731 183.014 null] +/D [4359 0 R /XYZ 71.731 166.551 null] >> endobj 4386 0 obj << -/D [4359 0 R /XYZ 71.731 165.081 null] +/D [4359 0 R /XYZ 71.731 135.667 null] >> endobj 4387 0 obj << -/D [4359 0 R /XYZ 71.731 127.158 null] +/D [4359 0 R /XYZ 235.228 111.921 null] >> endobj 4358 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F32 1187 0 R /F35 1525 0 R /F23 1173 0 R /F44 1994 0 R >> +/Font << /F33 1306 0 R /F27 1208 0 R /F35 1567 0 R /F32 1215 0 R >> /ProcSet [ /PDF /Text ] >> endobj -4391 0 obj << -/Length 2713 +4390 0 obj << +/Length 2629 /Filter /FlateDecode >> stream -xڅi�۸�{~�|*d`���,Xrn�ȶh2�Mp$�FR&�_�wQ�؛�?�||$�}��j?u�W�>�O��A_�����V~~�c+(�Λ�/?��U�gIxuw��T�xN�i\���^w�i���f�;�����������4�>l���כh��}���x7Q�{?K��pΨ�3�Y�'�K�0��H ���]敖�M�ߟ�����y���l�0V;��n�j���2`�m3_�e��pr�em|���y�ȳ\7j7A�=�08�����j�ȡ������qb�a��7���(V�V~&*��.ܳ����i�W/_ ->q��-s�<ĠR��Ҟ��������,~����7�}����h�ў� ��g��v��ZTDy�`)H��gS@(�oea�r��Nv^o��HM�&�Z��/s�)�����̐�0xV��E{�:����3BU ���e:����f�lI[����[}4�U�DU>l�~�?f�¯5F\蕓1i�<O�w��Tx[����$����sO�e�Vyٿʀ9]w҅P���'w6[>�J3�,E˸��JB�n -��B��l�e�a�*ӳ�6Q`z(ۆA��k� ���<�)��~�\% -��bHq(��,�<;��l��W��� Mx������1x5� $�Y�_��-i+��ЬU�9ݤ���K� E�c֔]mN��@u#����N����ɫ�0�V��<���}� �z(��R��Zk��JHZ�����Gc�_���m�����=�:�\��r<�c~��~�?��"�'� {,�G;���woފ��xC'!0}��� ̀���5� �' -��� -=�A��r'�Q�`_Bo���:��(�8�^�}��ap��Fy>����mk��&�rx��%�}���atA����d#�q�!��B:�1�7�d�m��!�S��eBu��,O<�k����a�G�O��.����x����)m��� -���|]�g -FA"��v&Ƒ`j] -���%$bT� �o��^��O(���������6t���ƅ�s-�i�����ak�;Z� �-���^�����u�O�|9�}���5Y)��>��/%D�c]���r�.ogOgL��<o�n��j48����*��Z*(�� <��h���������n�Ϊj]�˖�!*K��Ȓމ�Q�r�I�&O[ �+�80Yj -me>VZR��4v����O�'aJ���n���T�b��n6$��p�L�u�$Mz8E�l�P���E\��k38�W)8Yx���_���b<h&� MM.��w����!J���R\���`�u��aȲ��*B�����'��`������M�t�jy��~Aq��`Q�n�K�$o��7�)���Y\�2�[��$fa�t���R ̶y�*���!�yu� Nj�<�1�C�>|s=J��cdc�K��ؖBSR�K�ޗ Q��+kH>=ԅd�c:c�" H�-y�W�l^p���+ �)`V]��a���������XZˑeP%�^���5��µ��c�r��?���Q.�G��,Ew�j٢�\�F�%Ӭ����'}(�s�N��/�b"��|�U FB����Ȍ�,���~��'�wrE��܈(��)��Pcu!�N�(����$�&��i��>�ɑ������Dj�{)R�4��C��m�8��� �n�@���Ij;cب������.�*�\9%��,]���y����>��;VA�-΄�`��o��iގ����]��v�.�36�BHα�C�(>�`�X���x���b��q���Xf'�eY��r����M��R�����\�,��"��X)������ڥ#�Vl��O��Ъ/�M�d�)t#i4tj����:���F��У�w*������~�����ӻh>���U�<0��0��Bb(v�(#�:�-�w��h υOVJ0q�`��f�� ��L�X>����K }8py����%vt��8�)_G�F�W��^yH�~p]�E;�l�'���Z�Gֿ��;�;�����4<+I1����5/�VBÕR0���oc���7��� �0-4^7{?�G��c%�S_�#h��Q���B^������GXm��`I�=7t ���e��\j�Q���a����⛍��(MI!�WB��=`�)x.^��@@*C(ڈG�"|iL/�MD � �倢+nc3�Ϧ�{9��H�5�K�M�[i�2Vpm�ew.l�V�G���(���Hy�ˆ�;����/3����HS8�հ�+��pQ!�綔�~)1������:��$i8krET$�Q<��:�9���n ��:����7?�+G���OH Z���#L��_�@"�"Q�8\`=��,u����>~��7����%��R�W��F�i1��Z�:)b@1�V^�z��I,�rݗU��� ��J��E�h��ʉb�c��DZw1�͏zT�=p��Z�Nf���3��(�U�2|������b?���ZW Ll�2 -y��]�s���&v���qhΗ����$IVJa5N��q] a��R�A�`w� c7�]˚f-��AS�����֍}�Z��j�L-�E������Q�������d<�~����懏mendstream +xڍk�����zHpp��\>�$hlĮ� +�@%�$�����������K��������y��J/\��E�U���K������]�a��+-+AY�p^�_ݿ��E���_�w�������Tl��:��ysHO���+ϸN����ܴ�1o�rπ���oK��E�.]���O��d�G*��g��p��NH7&&�������v�t�Η|�4N��U��MZ� o��:{[�:mm&��m;:�=� +X��G�� +����"NB��Ӯ +��xG&ݝ�U���uh��j���50nB�u�G<��ạv�j�q�:y9px�G�(�Bp_T����>wx�2 hW{*�6�M��v�V5����:�/����Ӵi��u�`�0���z=�씶�-᱑�^���?���㧿����~د�{[�gv���v�{Ӻӵ�?T�g�=�����^Z� NDf������3V�<Vg$���e�Sq���UEQ-=�<pd�����(mv�ıL"v�{RE�~�4�g�=�vv�K�Q��8 ��06;���k}����U�ֲRD@F�a ��/�.W��:�w��.���ol���Q��Fm����e��}��-���O(�˔�J������(���$R`�oe�t�� ԮNu��M��5.��T���:c1���>�Jbg�s���Vum�SUfdt٥6�Z[6��D�,/�vU̓��q�#���B����F���P<8����uL�>�0�������{���������1HZ(q4��,��Lr���\�h[[N��@0}a� @�-�S�dYO��Q������.��Y�!?�w3�a¿vX��(Q�'�ɉ�>�N_jb=/�߱���6�������d�Z|'�Q�f��}�j�اе�G����ʋ�3�l��P�}50C��>�����=]}��H�쁠? m��݄�u��Na[x������k]*��D�dKʟ-�;��F\���m}�(軶����| f��AM���H�ׇ8A���Fo���t���*�wȽ��"?v{ϐf,���e8��`�xG�@�����2@da�#ږd����y���gۖ���q[Oi� +|D�+�+F�PW�(�# �Q}������"��u9��r��Ė!,1���+�ԏ#=|A��8��j��J�n>���Z�XƢ<Z���E�B�r���r�xbL���<��#/1[��6<Ok�FU����\ ]�5�7��[��3c�b@�M(ND0� }[���85�\��+̐� +��2�Nb��6d�m��+H~� ���Џ�QPጋ�����N�� ���C��O���b��Fd���8w�tk����=��(۶�V���/�#h(? T*����`����3t�_0���.4(��d`�2}A��$�W)L�a�h�a{�P����5�#9$D�I�:��lˋL�%η�oRx�I��ɍ�&��$I���q��+�1It)�Q$W�#L�4kĥ�7�0ф����\f[j��3ܲ�1%�<�ZP�v�2�N���f�&v�c;`{w�l����")q���sA�Fh.�d]Ea4IP��Ҵ�R�[˗���_��>\ۓ@?�61��n�@=]�;<�#��W��x��]~��y���}���I09�=��N�����r#i�y�-��q�(y֛'�/ f.��#s�D���8���"�1�'d�n���P�)h�k�XS�kU�n��+����3�z���x;w{q��3�����e|k�Nz��G�x�����i({���� �y+!V��D2���I[d�"�,��p��5������w�����W�kE��8[͑qU�z��R����Һe?��˂��q�'Қ_�Bz�BM%�s��!���K���v��6� +!8Ʃٖ馰M���2�����+��"$CJq3��C�b�3���E0 +��`6�i����6���=kz�� �v�x:Q�x_a��M�W3n����Dj7�4hNv�#�ێQ�k���z�א��JjW;���'�<5�O<5j�3o��3#f���3��b�yW�{1a��ˌڌ���,�^��dO.�̛ +�<74/�*о��D{cY�x,KW�<z����z�Qٸ>���Z��F��m���B�H�V�xg���ה��&;��]���X����jȟ��k��]G� +���t�<Q�;� +��a/���/��t,��2�$�"��^�q�9W�VUp:��]٦�^����Hڕ�g�^���wpU�̐�pF��b��2�^��|��n�O�KPl|M<�i�ν�k,����+�==��u�s�5Δn�%�_�������0�.}�0�G�bC����b���n<�G��W<����9�����0.s���k���yIv'R�!�"=�P%V|��U a���)�I��/r~m��Eb(m~�t�'?B����[f7����ͼ��z���Oz"�,(�6��K� 0�JLsS���݈��������VPÞyEx����<+ �[`7t�ٌo�I�<?�g+c|���|��O0'�5���E���r5m^�k�XG�&���]�� +�E�@Vc�����'�&Nendstream endobj -4390 0 obj << +4389 0 obj << /Type /Page -/Contents 4391 0 R -/Resources 4389 0 R +/Contents 4390 0 R +/Resources 4388 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4388 0 R -/Annots [ 4398 0 R ] +/Parent 4297 0 R >> endobj -4398 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [240.776 608.553 290.588 617.464] -/Subtype /Link -/A << /S /GoTo /D (reporting) >> +4391 0 obj << +/D [4389 0 R /XYZ 71.731 729.265 null] >> endobj 4392 0 obj << -/D [4390 0 R /XYZ 71.731 729.265 null] +/D [4389 0 R /XYZ 71.731 718.306 null] >> endobj 4393 0 obj << -/D [4390 0 R /XYZ 71.731 718.306 null] +/D [4389 0 R /XYZ 282.395 708.344 null] >> endobj 4394 0 obj << -/D [4390 0 R /XYZ 523.238 708.344 null] +/D [4389 0 R /XYZ 500.324 708.344 null] >> endobj 4395 0 obj << -/D [4390 0 R /XYZ 74.222 677.46 null] +/D [4389 0 R /XYZ 300.306 695.392 null] >> endobj 4396 0 obj << -/D [4390 0 R /XYZ 71.731 639.437 null] +/D [4389 0 R /XYZ 71.731 682.441 null] >> endobj 4397 0 obj << -/D [4390 0 R /XYZ 146.578 623.661 null] +/D [4389 0 R /XYZ 71.731 659.427 null] +>> endobj +4398 0 obj << +/D [4389 0 R /XYZ 71.731 591.094 null] >> endobj 4399 0 obj << -/D [4390 0 R /XYZ 71.731 603.572 null] +/D [4389 0 R /XYZ 262.713 578.331 null] >> endobj 4400 0 obj << -/D [4390 0 R /XYZ 74.222 535.99 null] +/D [4389 0 R /XYZ 71.731 553.26 null] >> endobj 4401 0 obj << -/D [4390 0 R /XYZ 71.731 510.919 null] +/D [4389 0 R /XYZ 71.731 532.391 null] >> endobj 4402 0 obj << -/D [4390 0 R /XYZ 71.731 480.035 null] +/D [4389 0 R /XYZ 462.665 520.847 null] >> endobj 4403 0 obj << -/D [4390 0 R /XYZ 71.731 457.121 null] +/D [4389 0 R /XYZ 71.731 500.757 null] >> endobj 4404 0 obj << -/D [4390 0 R /XYZ 428.12 442.64 null] +/D [4389 0 R /XYZ 86.871 464.06 null] >> endobj 4405 0 obj << -/D [4390 0 R /XYZ 71.731 425.539 null] +/D [4389 0 R /XYZ 71.731 438.157 null] >> endobj 4406 0 obj << -/D [4390 0 R /XYZ 450.21 404.384 null] +/D [4389 0 R /XYZ 71.731 413.086 null] >> endobj 4407 0 obj << -/D [4390 0 R /XYZ 71.731 353.176 null] +/D [4389 0 R /XYZ 71.731 392.216 null] >> endobj 4408 0 obj << -/D [4390 0 R /XYZ 325.465 317.31 null] +/D [4389 0 R /XYZ 71.731 347.631 null] >> endobj 4409 0 obj << -/D [4390 0 R /XYZ 71.731 302.202 null] +/D [4389 0 R /XYZ 71.731 336.737 null] >> endobj 4410 0 obj << -/D [4390 0 R /XYZ 71.731 253.385 null] +/D [4389 0 R /XYZ 71.731 331.756 null] >> endobj 4411 0 obj << -/D [4390 0 R /XYZ 353.315 242.59 null] +/D [4389 0 R /XYZ 81.694 308.941 null] >> endobj 4412 0 obj << -/D [4390 0 R /XYZ 71.731 211.607 null] +/D [4389 0 R /XYZ 186.398 295.99 null] >> endobj 4413 0 obj << -/D [4390 0 R /XYZ 378.982 198.755 null] +/D [4389 0 R /XYZ 134.42 283.039 null] >> endobj 4414 0 obj << -/D [4390 0 R /XYZ 340.628 185.803 null] +/D [4389 0 R /XYZ 197.733 283.039 null] >> endobj 4415 0 obj << -/D [4390 0 R /XYZ 71.731 165.714 null] +/D [4389 0 R /XYZ 71.731 262.949 null] >> endobj 4416 0 obj << -/D [4390 0 R /XYZ 244.777 154.919 null] +/D [4389 0 R /XYZ 301.246 252.154 null] >> endobj 4417 0 obj << -/D [4390 0 R /XYZ 74.222 124.035 null] +/D [4389 0 R /XYZ 172.784 239.203 null] >> endobj -4389 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F32 1187 0 R /F23 1173 0 R /F44 1994 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +4418 0 obj << +/D [4389 0 R /XYZ 494.944 239.203 null] >> endobj -4420 0 obj << -/Length 2756 -/Filter /FlateDecode ->> -stream -xڍk�۸�{~�-��zX�T�Xl�\/E[4�EE�(d��ٕD�(�q~}�E=־\�����I�w�»m�oc�D�m���~�`��oB�X �jB�����q|���&�{�߭��O�O�i�=���O'Ք��b%�������x�?|�U�3��"�q��O��<��͇�A�$��YSHGs-e4J�%�f B���$d�o}����h;�0�6�I~�-˘7��b9Aa��3bU۩rz�E蹳uƭ7�Q�Tys�����N��o�V+���G�Ow�]g^e���_�]��lw+9�*%���T�Z�A�)�f��k4@�V�ڴJ��ٛ��;m�ST}�����"B-D��� -w|�捭rV!T}Br��K<���t��%!Iw�������b�x�w�A�0����-�Me�]^�Ǯ�~�Ύ��ق4�L�d��5iǺ�T�=xy�� �r���vJ53ٿ�4�+�/����$ؓ -P���DB�T@���c��b���F�y��A``;Ђ��G�":#|?4�Jۣ0m�����ʚ對c_�"�α���=i,���<�(�aP�֪�pz��KUTp��g�I�B�3a���HцAԮ���j3w{d���P��A?��O�n�!�_ے�1$�O�7��d�i*��,]I+���%��!�]8� -b¥ {;wC���<u2m��~��z��4��<���H!����Nx}�R�j�����72px��Z�e���,��?�m�@�Z�;������3�[rk^��'�T�U艼�� �g]�����M�vy��W���y;ʼ�w�wY)2#@�W0p�N�U�^j>�n5�0ſ��y��Lez� -2~�aDn7�#_8he_IP*HAd�X��:�*��fA-�R�g�_�CPޘ�����SCZ.������e��0oܰo��4��t���0��I��C�{L��j�5}K�AJ�8h�*1Q��v����]�G���d��e��a -R$�s(!�����>�T��:P�8�.ٯ�T�lz>�f7r�(ٲ�ƾ�S˸�p|m\@m��j-Uf��3ʴaV�P���>2��� -�f�$ܼy�ٹh�;�DM�W"�yAnZ ����ߵ�u�:J���G��c�;�,���P+�m_�Z�J���H?��u�2�2�v����2�e`o�3_���n�~(t�1�~$�َ���ܐJ'838Y۪��.L�oM���m��i�N7��+^���)�Ma��� -$ҍ��1A*Y0;!+��Ͱ�� �ugp+��Ε�I�uK3�M]���(JG��_ل�"Қ}Gn�� pN�q dGc;�h��C?⪀��$�K��F`�Q���̛��aw��6Y�BaH� ܵ2*]��R��Í�x &G&پꤻ�!L��M5���HHy�3�ƫU��D�3t�Pr"ր=�22O>i�^e�h�$��֭l�7��j1���v��JǴ�t�q?�����& -g?��$��طy-Cv�8�0De̋��s�)��,��}BaΆq�bL���X��P��O�r�M&�8eѤ �ng��1.�|șN�K��<�~<��v�/�T��<By���(���"�T��h�\�p��pd�|�x�����Y�a�1��I�Y��v����R� -9�<*��4wٽ����4���Z3*�] -�������Gw��ٍ�& BYMSXE�6�ꊇ[9�f[npP*|߰�� /�JUw\}e���)պ�U����;*�8�W��,�K��r�5z_�8ZQj� 'l�<�n��XLH~4ھing-�! ��k16���rF��qK�H - �ّ`Rڂ�A�4 cz,PԞ!�����{��H*����W;Lz�S���v��80D!���耩�C �G����y�H���֥ �ޙ��킋�Fsa�=p?�J�z�Pm%0�c�d����p٬u�s8х�J��[��9Q���3��b;U߰2��P��� -��V����x���#^�d�Ș�~6�)��z��OY � `!��3f�&?(��%#����ڏk&�����*DA�Jn�<��Q�?I#�L����P�`8^5�X�>�s{%D�����< �9a�w���rZK��q�d�I�y2ׇ����\�"��"���/�\��pS�p�%J��!��Нf���Y.�Y���lv�r�%ψD�����1��������T/��'��%�焒�o���� �H���H �Z�U�d��4��U�X�$ -�`HL��+���uT���9�7�5B5ܷJ�����V��+F�/ -�[0�.�ct�\K����t� �_��,O�8=��2�24B��9�rj�}�z>�����q[��祿RA"Bl����O'c5Mȯ���O�Fg@�����8bq�=q��H�`�:R�G��ٚ���(�Wzp!|�S{ն�E���W���#�$;�����.���f���8<Љx��~��z��^���$�N�.y��>H� -S9�V. -����H��A��ՠt(�%��ӽ� �_&=R;_|:��@�R���n�>G��{���r?��s��~Z�����qW1� �����ߋKmq�zT;y�A�_^���Nb���0 �u������YM��O����f�ZxR�(�����?��R�77g�on=g�߈��:���&�[,�xĿc4�n��yC��VJ���ė�$ש���o�k9�\�i�D�D� ��&�����N�b>�endstream -endobj 4419 0 obj << -/Type /Page -/Contents 4420 0 R -/Resources 4418 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4388 0 R -/Annots [ 4440 0 R ] +/D [4389 0 R /XYZ 76.712 195.367 null] >> endobj -4440 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [453.197 148.279 505.5 157.19] -/Subtype /Link -/A << /S /GoTo /D (template-specific) >> +4420 0 obj << +/D [4389 0 R /XYZ 81.694 177.435 null] >> endobj 4421 0 obj << -/D [4419 0 R /XYZ 71.731 729.265 null] +/D [4389 0 R /XYZ 187.837 164.483 null] >> endobj 4422 0 obj << -/D [4419 0 R /XYZ 71.731 706.187 null] +/D [4389 0 R /XYZ 236.955 138.58 null] >> endobj 4423 0 obj << -/D [4419 0 R /XYZ 95.641 677.46 null] ->> endobj -4424 0 obj << -/D [4419 0 R /XYZ 273.207 651.557 null] +/D [4389 0 R /XYZ 81.694 125.629 null] >> endobj -4425 0 obj << -/D [4419 0 R /XYZ 71.731 638.506 null] +4388 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F35 1567 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 4426 0 obj << -/D [4419 0 R /XYZ 71.731 613.534 null] +/Length 2746 +/Filter /FlateDecode +>> +stream +xڝYy��6��} +# 2`���-�E�,R`��m�m��%G�:�b���EY>�-�����p8��G�_x��/R�MC��$��?x���������g<���z���͓p�]D^�Q�H����`�T��<V�0�n�b�I\�>����Mo�^��ߖ�c�Z-y����Ӵr�n��_T���h�g�2�MrP��HIT���;�6���'�$K��2=�Rg���-��ny�`�c�a�'�i�mXL��z�vjG&�R�m�e��)C%�~PM�:a�۱+d�g�j-��L��C�0��Fˁ=�~��b}Z<�r�PM�ҮT��ܦ�����L?�ֈ �t��w��NȢ;���+ڶ����"�ZI 4k�:�=լ���:d-�z%�aY��J�T(B�AI�E�t�e����r$��(�������±� ����~��P��B6�8ԇ�?�îS����Gۭ������#�p�@L++k�X<��' ~�~�^�f]'��'9�(q#��4�q#��wU+#���a�ki�&��)��8�q��Q�b�||��oQBl}������#��0�����Ӌ���M���ICɗd�\����@�n�����D� &�|7��E��=��,�n��t ڃL q���h��� y`K?q�0�O�a8�e�g1�zmNV�c]��Fh�@�)u���qҧ�3��� ��<ơ��>�d�v�������#p0�� +��8��j��E��A5A䬘�������8�M�� ʦX�6F*~�-e=i���D���R�]:�����[i��Q��T'���[f��i˴���]m�( &��B��=/ҎCm-����p��]�x$�;V�H�i� +�K��3]p��{n���{�F�9늁v_>d4{jM�[#E�i �OL�43�̓�WL����w +�A8�[R��|$��2 +���@��1��f ���x��E7��(���fA1����vP�!s�p,ہw6��� +�n�-�ڀ�p�X���&Զ=��Cݢ�NZ|�g �E������^N��ѱQ�ݑӾxV<7lC�TF��:��d s�lM���|��9���/U� �ٖ[�� +��R �>.���z�Ŧg�R�fרAK��%�[He� ��I���� �-�����o~d��eEm�8��vW���#X�N8EE2-�ɴ�ň��<f`*�������cg=�uL��4��*�,֛fJ����J�F�.�8�jpv�V���Lr��~��T= +�:��;M��'M�$xv��~�sя ����pZ&�e�� +�&���(C�F��4��a+�u(��Sw�d��ͧI�� :Rn��*��� )�Q�^m����n�*�е�b���O��)�@97��r9�������Tx��NR���'R�^� +�L30u�$�V(` ]2 �3 ����<�G���¾��~k4m�,���p8˒>dP�OD�J�#`E����E��vڱ!|�K���f�q*r����v�0���5��r�o|���tgJ�2��Y�V���E� ��/:x��U�w��Zu��y;���A�ㆩ7&EQ`T`�Vl#@�a\��y�Q�pC�B]м8w9gl +�Q(�,�RY����������K�F�6�b��Wr�sXtvNh�Zs��ǁPͧRfmi��*^Q$��X-t�� �Wq������ns���d�R�])]�(���8UG�QT��K&�����Yl�#�����L�J&�e�J�2�@x�'27�q��o ������ �����~�B�f>h̼#���'��BFL��^���t�Ʀ5�j�t~�Q����r�&������V�|����~�X�7������:�<�%�䑛�'l�R��L=���Gs"��ށ���S�����ΔL�����5d��R ��C�P��BZ����0�ϯ�9WJ\���d�i�pz>?����GG �tah��C�}H�bNf�v�,m�n�lu/���� g�,Ȳ������Үe�E���҈��*�|�/�}����u�b�� n�I�K��c#�{U�⿎[>�p��29�p@������6\.l�x|�J�< �BFI�L�ݐ~�f�QT�� +c��cO� ���<� �0OӬL�]����Y��ؽ�̉��`�5�k����0ռ�����>����%��|�H#�u��\Q= �X�"~i^���]k?�I����5�n�z�J!W��4�Y:�AF���̮�dm�o0_,ן;O���ϙ�{bg���]mn��J3%X0��.���I�P�j~@��5Cu��'c������[˵#g\�^+��3��\��А*Xz�z����.D�W�7=*��en���3q5D7�䲙���<�y�U�?�f��,e\��q>��H�L�La����m]<� +e���O��'�ZpD%~�/ +8�S�n���Ly.�7� ,w�Z�G3�f��ᾼ�3ӭ�m;��ad�� �Ԡ6��Gq����}��q�ĆC�a�ΐ�9�x���/��'���lry�����B"3'I���:mS�b�$5:Yr�F-+�V�;�А��p�j�k9���P[�����0�v�%��}�UG�����}��<�mi�}T&��1`�g�?�����,�ov��z}�qTx{~�g��x�I��%P�߁Q&�H�K���L���O�ˢ����?םYn~�����+Ŵ���v�����p]=endstream +endobj +4425 0 obj << +/Type /Page +/Contents 4426 0 R +/Resources 4424 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4297 0 R >> endobj 4427 0 obj << -/D [4419 0 R /XYZ 71.731 595.602 null] +/D [4425 0 R /XYZ 71.731 729.265 null] >> endobj 4428 0 obj << -/D [4419 0 R /XYZ 71.731 572.688 null] +/D [4425 0 R /XYZ 71.731 718.306 null] +>> endobj +1884 0 obj << +/D [4425 0 R /XYZ 71.731 659.527 null] +>> endobj +874 0 obj << +/D [4425 0 R /XYZ 402.85 614.272 null] >> endobj 4429 0 obj << -/D [4419 0 R /XYZ 196.632 543.96 null] +/D [4425 0 R /XYZ 71.731 610.442 null] >> endobj 4430 0 obj << -/D [4419 0 R /XYZ 71.731 541.803 null] +/D [4425 0 R /XYZ 118.555 568.252 null] >> endobj 4431 0 obj << -/D [4419 0 R /XYZ 417.183 495.143 null] +/D [4425 0 R /XYZ 71.731 514.555 null] >> endobj 4432 0 obj << -/D [4419 0 R /XYZ 71.731 492.986 null] +/D [4425 0 R /XYZ 71.731 463.865 null] >> endobj 4433 0 obj << -/D [4419 0 R /XYZ 71.731 457.121 null] +/D [4425 0 R /XYZ 389.061 438.061 null] >> endobj 4434 0 obj << -/D [4419 0 R /XYZ 74.222 402.491 null] +/D [4425 0 R /XYZ 118.688 425.11 null] >> endobj 4435 0 obj << -/D [4419 0 R /XYZ 71.731 351.517 null] +/D [4425 0 R /XYZ 411.769 425.11 null] >> endobj 4436 0 obj << -/D [4419 0 R /XYZ 71.731 283.836 null] +/D [4425 0 R /XYZ 71.731 405.02 null] >> endobj 4437 0 obj << -/D [4419 0 R /XYZ 71.731 247.97 null] +/D [4425 0 R /XYZ 403.654 381.274 null] >> endobj 4438 0 obj << -/D [4419 0 R /XYZ 71.731 202.077 null] +/D [4425 0 R /XYZ 71.731 356.204 null] >> endobj 4439 0 obj << -/D [4419 0 R /XYZ 71.731 179.163 null] +/D [4425 0 R /XYZ 71.731 281.683 null] +>> endobj +4440 0 obj << +/D [4425 0 R /XYZ 477.684 257.937 null] >> endobj 4441 0 obj << -/D [4419 0 R /XYZ 71.731 138.316 null] +/D [4425 0 R /XYZ 71.731 224.896 null] >> endobj 4442 0 obj << -/D [4419 0 R /XYZ 71.731 138.316 null] +/D [4425 0 R /XYZ 71.731 163.128 null] >> endobj -4443 0 obj << -/D [4419 0 R /XYZ 71.731 115.826 null] ->> endobj -4418 0 obj << -/Font << /F33 1278 0 R /F32 1187 0 R /F27 1180 0 R >> +4424 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F44 2037 0 R /F35 1567 0 R >> /ProcSet [ /PDF /Text ] >> endobj -4446 0 obj << -/Length 3030 +4445 0 obj << +/Length 2159 /Filter /FlateDecode >> stream -xڝZY��F~�_����F���5q��l��&�dk7I�(�GbL�2O�_�h��4r6�r���h\ �����YD�y�q� �E���[�|s��ZP��/o�x�y��JBo���������Zq�.��������� ��ſ�;Ń/��EY�<{�r�`y������_�y��� A�EV{W�48�R���I`�>��c��}-�g9�����NbA�ʄ�U�Z�9S�=wyh�d�T�+g�֨�nr�.��CQmy�S�t;�(B�-�}٥������,S�Ȟ����iӽ�ج\{�o_����T��HUNg\��\kǵ���jں�Kت�r)U��\W�K;3����O�,�B�o�n�wW��`�,5��#�_l�U�+-� Qq��:�g��Qy�H�<�{h-�=��xcJt���i��$�˲hVx�Ne]a��^3�yWd;٭�J�*���ʡ��i�9�x%�Őe�ה���X������&4Z�yE&��E����Ј����H�4W��2��ӂaғ�ao�3�9�'��'X����$��d��dβ�ɒ�gu�YA���@j��G�o�ҒGr���ɹ!(�.><uv�q��1~�^��� ��_���6"��q5���N���a�:q�M�}�b3ǀnն��$��=-�`6�R�Z���Y��S:2_k V�k�yڥ���پ'C��l�����+��fl-�k`�^�q�ka��-M�1�����Pdi�f�#�S��ѷ{���^豱р�����"Z4�R�g%4*�ݣ&C?>��;:���'^>�}ãQg4+�P�6+'FP4~ �x�OE�j� �Z6��fWT��~Zv��Ҏ���`������=[@,[�Eq0I[ƚ\4f�:��49�Ct�>Q�4�a���{��ը4_ו���t�4 �4�b���� �-�Ok2���������箳��s��&Xm�)̝�;��9��4e����9_�i�ɍcW��|�<�6X������y�؞:�f\Dz��bcp�$]Ŝ�iF���E� ;dz�ȿ�n�;��=������/��9�&����Ԝ��>M# t\ SuusZ�RL�y��`�[yCQ�nN�>C��qF���LL���겊��.����:1v�wݐRd"��P?N 8��J<7`�L�)[�s<�g����N� K��-y�H/��~�Q�]ߌ7M�$9��J�x�t�_Na�c��i ��-���T�ŦP������ ��tF�XGXZިvXl���6�x^�>� 1��7���U�\��@��͖���@XG��� j������c퇻&3�mD>��)�9�V;V.�G�'�H%F���#\5+��y O�Tm65��\ĩ�ۖB��R�C�r��z� ����}1�]`��v����,�M5�J�F\��0J}Ө��c��?_R�Z���<0AzY���Y�E%���J��~F���ت�؈�6�#?����Z�_g̻���uc��W�O����;������I6��Iy�Aq���si=�J�&.��A�J��=E�oޑ߿��B,�B+p¿v��c��V`�'��=�L?�3 -ʡ���� -���B���e@0�[bV�<�E�U�/��i&@�� ���zA^g����G�[TҰQ�f���/I����÷�ޯ/< �ߜ�`�H����N` *�#1�\����с��-�ؘIE���u_�������;K��-O��`�̩W�s{(+�XGz�F�,�p� ~�q<��O�"��5���ٗ��`��Mz��=Pi�,���F�x��vi#C�m,�'� -��ާ��$��E��س�slT��� -X��B>5ʣp��3����ϐv�v&�������� -�:�u���Os&��&Ԧ�ߧU/�Y����n�=����m+r����b�78��ŀ����U�3º����*ġh[����p��Ua���â�.S�,Q����Tzp��U�U~'l���\�۔�bS9��T��U]��yp��<�~.�e�xcY��56$.;V:{YZ���z��d�����0�}V�2�v|mRө�{B�>��=��A���4k��1�� -W�$��T��B��>������aP���������=?�B�l�JoѨ������J�k�����གwFbm�A������-���eJF`�-���r{�ߔ��f��_�0�a�����^3�z���]�S`��\ -<�z���V��(?���x�o��S:,�=��ӕ�/©�w+�x>kr<��i������F(���ЄʘW\�:kwx���/g��mZ�J��(.�ghΠ���iX�O����%�%��@K�i ��V(gE��{��J��P,pb�<��i/0+��5��7݉�a���P)�\ؐÁ�2����gnYTm��٤^TsE�6���P��Bc=���uJ�Ś|�@�Mmr�w�XJ�k��*�S2��8�(�|ˆ3�ሱɳ����{���`���mW�3�={�Z�� �&���ܬ����w��<���믄l�v�����*��Q>��;���pF+L�w<��{nu�4�� �hyK_�\�S��T{���AM.��R:��@n�]E>n漥v�S�#P�6��i=��;4u�o�l[\x����._�!��掽X�Y��|�L-7�ޙ6W" H�-08e��%]6&C�0�_zIJS�(pƠ�w�)�|��W���69̴��f�����W�]����T��<Kb���� -������\���@/���Ŷ)q���a�E��(65@*���D9�[z��m/}!О�o���O�����F�/�JK�ow�w`ԞYGe:�0yZ3[����l���f�L̢��IY5M�����o�\}��v��N���'�UP�w�3d�{�d�o�? -z^�{SÍ�L�LU���n��]�n�۳�+�,;�տQ��$p#� T��q�ҟu���ά;endstream +xڥX{��6�?�=�a��$?�pE�4٦��-�mH����̸��ďl�E��K���;��� �)��(�Gj����Ĝ��2�NV]��V�.���,�7�yv}q�RJ'ei$���1�A��R�$�u��}�W�^�+O��1�]�TEW�;"<v���[��Z��������9�1K��q#�Һ�I����2b"I��O��h]����W^����OT�x������9��ذ�~Zv!:-\��� �~!X�I����蠝:�Y�W=͚�<�l�tk��ڲ�[��滶4}�aPe�oT� ��3��2e7f{U����N���^@S�*C�A��}�����QѰY 0knj|8;8�u��~���i��;]��?�/s�On����-y�����t[;��?�������n�}\��}fLZ^ +�p�X�>G�z��J%����������п��Pj�����^������'t���)���y��S��E�<0�C�9�?s/'�.;�?H������r +{9�=��YD�4���K#s{��yC���$ �ezM_��'��*�a���]w_�z�C�e��Me��1a�*����V0��?X���v,�giٌ��q%B��f���9���VN`!C������=��v(��Զ|�-�ɭ���v�s(�\�0� �Y�pD�o��N�� ��w�@ �q�p���i���xs��$ �I@j��k�"��/�@荠/���x;��L��P +ߟVx��1�L C5�p�� T/� �X$��&�����g̀ H�D����'i�����2{Qȡm2��� �i�+��c,L�rc@�^l���jaw����5�`��X���$ "����Yh�z�A��M3Թ�����@��܃����y�-������_��zq���l2n;����W e2LM��5��c3��;�hˢ�R�cRۓ�B� n��S�㽴�T�]��������[��vhf2�!���& %��u_��$��d ��̂����@�L&�>��j����SF̀�6r2�Y,(�_�=�Ja +?e��43 $�{h�%�G۔����jU�nm�6ͭfeX�c?�Y����; t�w`�+`P�T3����sШ�����fwP l�nfZM��C����x�#F���q ,��ݭ ���WI6Uw{֡��\k�λnc��l�8���!z��>��(b�I��}U�z��KI��cC_wE����}�{�!(<�p�����)��� A�L!~Ĥ�[�Ϛ�SŲ���3.B��ry2L d�h��. +�?{��f��8�T�v6��Y$�����!@&`�C����͘a}.ȼ=~|����_@�R��\q��vp���H|s�z]��p�8?}�ԑ�QSH�8���H��d��گ�S���#T��`~�[ӌH���܂����ˬl�`�:��%Z�j��8�0���Q��h�DT4)�JZ����k��[O�9�R��q[u�o��U�F^(f;�β�*jU��(}a����XP��u�Q),x���4)�Vґ�TT��"Mm�ɑ�V��@sJ�l�R@6#�bF���>�������?R�Ǜ1-C�L��WKa��M�˚b&��<��{13��q��M�>�7��3s�RLF��d�inL�b,x�����2�-�w�Yf�}1�1K��x����0��NX�D�4�M�1��������;{n�e���K���:�D?�q��~=����y�����}��� +na%"��U�=ǩ��ec3A�� +�}��C���h�T�x2(WC�k�Ru�U]C��5�߫I��Y��{�bD}�/�nh�h�� +̎�UCP��dw��-���wN�wgri:���^�H"�8;���X|8ѧ)� r��Dug�u�� ��5�T�T�0�B� ����H��V ����F�� +��WD1�fx�`����!��R��p0��s�ۦ��T���) O?�/�A7��&�'aᙝ��b�$�~�U�����Qd +� ����o��,�t:P�y�/�B��Y��@E�}?� +Xl.7�76Z�{C�c�r�<�(��q���:HX��G-=�,~,�f��b�����>����/yendstream endobj -4445 0 obj << +4444 0 obj << /Type /Page -/Contents 4446 0 R -/Resources 4444 0 R +/Contents 4445 0 R +/Resources 4443 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4388 0 R -/Annots [ 4471 0 R ] +/Parent 4461 0 R +/Annots [ 4454 0 R 4455 0 R 4456 0 R ] >> endobj -4471 0 obj << +4454 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] -/Rect [204.95 216.02 269.707 222.874] +/Rect [244.528 255.888 410.209 264.799] /Subtype /Link -/A << /S /GoTo /D (upgrade-cvs) >> +/A << /S /GoTo /D (cvs) >> +>> endobj +4455 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [494.336 229.985 537.983 238.896] +/Subtype /Link +/A << /S /GoTo /D (tinderbox) >> +>> endobj +4456 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [71.731 217.033 267.724 225.945] +/Subtype /Link +/A << /S /GoTo /D (tinderbox) >> +>> endobj +4446 0 obj << +/D [4444 0 R /XYZ 71.731 729.265 null] >> endobj 4447 0 obj << -/D [4445 0 R /XYZ 71.731 729.265 null] +/D [4444 0 R /XYZ 71.731 654.979 null] >> endobj 4448 0 obj << -/D [4445 0 R /XYZ 71.731 693.235 null] +/D [4444 0 R /XYZ 71.731 632.065 null] >> endobj 4449 0 obj << -/D [4445 0 R /XYZ 71.731 649.4 null] +/D [4444 0 R /XYZ 71.731 479.636 null] >> endobj 4450 0 obj << -/D [4445 0 R /XYZ 71.731 626.486 null] +/D [4444 0 R /XYZ 118.555 441.072 null] >> endobj 4451 0 obj << -/D [4445 0 R /XYZ 71.731 569.699 null] +/D [4444 0 R /XYZ 211.992 432.608 null] >> endobj 4452 0 obj << -/D [4445 0 R /XYZ 71.731 546.785 null] +/D [4444 0 R /XYZ 71.731 387.483 null] >> endobj -4453 0 obj << -/D [4445 0 R /XYZ 71.731 541.803 null] +1885 0 obj << +/D [4444 0 R /XYZ 71.731 360.639 null] >> endobj -4454 0 obj << -/D [4445 0 R /XYZ 71.731 539.313 null] +878 0 obj << +/D [4444 0 R /XYZ 449.605 317.541 null] >> endobj -4455 0 obj << -/D [4445 0 R /XYZ 113.574 521.046 null] +1886 0 obj << +/D [4444 0 R /XYZ 71.731 313.711 null] >> endobj -4456 0 obj << -/D [4445 0 R /XYZ 149.15 508.095 null] +882 0 obj << +/D [4444 0 R /XYZ 159.442 278.169 null] +>> endobj +4453 0 obj << +/D [4444 0 R /XYZ 71.731 270.817 null] +>> endobj +1887 0 obj << +/D [4444 0 R /XYZ 71.731 212.052 null] +>> endobj +886 0 obj << +/D [4444 0 R /XYZ 141.108 174.836 null] >> endobj 4457 0 obj << -/D [4445 0 R /XYZ 71.731 480.035 null] +/D [4444 0 R /XYZ 71.731 167.484 null] >> endobj 4458 0 obj << -/D [4445 0 R /XYZ 113.574 464.259 null] +/D [4444 0 R /XYZ 71.731 147.574 null] >> endobj 4459 0 obj << -/D [4445 0 R /XYZ 71.731 462.102 null] +/D [4444 0 R /XYZ 331.48 123.828 null] >> endobj 4460 0 obj << -/D [4445 0 R /XYZ 113.574 446.326 null] +/D [4444 0 R /XYZ 86.396 97.925 null] >> endobj -4461 0 obj << -/D [4445 0 R /XYZ 131.461 446.326 null] ->> endobj -4462 0 obj << -/D [4445 0 R /XYZ 349.56 446.326 null] ->> endobj -4463 0 obj << -/D [4445 0 R /XYZ 71.731 413.659 null] +4443 0 obj << +/Font << /F33 1306 0 R /F35 1567 0 R /F27 1208 0 R /F23 1201 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 4464 0 obj << -/D [4445 0 R /XYZ 100.623 358.655 null] +/Length 1512 +/Filter /FlateDecode +>> +stream +xڥWYo�6~ϯ0��2`˺e�[7=���@��-���(�T������{�E��3 �ߜ���<���h�GY�(�`q��_�B'�v"�̻���8^��]/��E�~�$�<��m-�ǿ��R�Vv�u�^��z��keTsfƻ���2�TU������~ޏ7�q���W�d����ɺ����D����$X�o=ep�y�2�9���$���v�Y�Sa���V7�4���(��Ka�svÇN� +}�+>��V�X�S���G��m͑9s-�i�v�?�� �#7�����XT��t����R�}bJY^u�6¾�Mim�v�y~~^f��O���5����4��?6ږq�z��XY��8T���'fҋq3GC!��|V��݄ ^�E}XF�ן}����t~9x�?��t�g��N�n���0��G�w�d�ЯS�|���@�{���Yֲq��\*�N� 7f~�^��:xI蕵�o�ݸ�53B���a��av�c RN��O���`{X�'� ?������{�i�f�( +�0bE,��]��0��� �"Q�p&6��c;s����W���t:NK��9*j�ϝ>���B"W�DB�4h��U� �${��W�� �� 5���i��/t �c>�;6�va�n=�4�>FQ̷EQ�,�M�h4f"TȄh&�U(��z�ӷ��<@w�:$N��Yj@`5hu�/���Cz 9�i���E� N$�C��%;�'�j����:�%r�^jK���Sȸo��#�᧚#���_ںb=�U&&��*Y�E%��r]ɦxZ��n�Vآ�����$�����<���ܱ����1���: �3�T��Ȉ����n8���g�xY �s�;�$�)|/K�ռdb��(�N2�����$P���Ԉ �m���|�w&dHP�^:�[�S����x��s�|@����T�K�7�^1T<�� �\`P�����W��Um%�oNTuH��T-�әs���f�5��(�e�4N�.zt �K��2 h�u�?Tx L�RQ7�|���P����y<w��k��|#�����/u�)���$�<�GO�� �}����M��w�7� +^�mɍne�6C��Հ!���� ��+&��N��������ig�N���Q�ZYB�1(�a�Q���X\0,��F��|s�9��z~C�;�p>��'TQ`m�1�'#�z��I���W��fl�|6،�M� ^rU(�F;��'�����X�j�y{����҅�+=� U�lx��Sf��tR�{l3$����}+����E��3�Y�� �*Y���UMA�fUut"��x.UQ�}!�<���,L�v6!�v�)�=���r�G8�#�vzX�m���Y��2��6�_"��3:��]:*��֔\GG|��]�n���w1+��K����!�l�m����$r�[7��~ JМm�7�s�5�endstream +endobj +4463 0 obj << +/Type /Page +/Contents 4464 0 R +/Resources 4462 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4461 0 R >> endobj 4465 0 obj << -/D [4445 0 R /XYZ 113.574 340.722 null] +/D [4463 0 R /XYZ 71.731 729.265 null] >> endobj 4466 0 obj << -/D [4445 0 R /XYZ 419.902 340.722 null] +/D [4463 0 R /XYZ 71.731 718.306 null] >> endobj 4467 0 obj << -/D [4445 0 R /XYZ 71.731 325.614 null] +/D [4463 0 R /XYZ 225.881 695.392 null] >> endobj 4468 0 obj << -/D [4445 0 R /XYZ 164.384 287.05 null] +/D [4463 0 R /XYZ 71.731 688.254 null] >> endobj 4469 0 obj << -/D [4445 0 R /XYZ 222.306 266.929 null] +/D [4463 0 R /XYZ 373.626 664.508 null] +>> endobj +1888 0 obj << +/D [4463 0 R /XYZ 71.731 657.37 null] +>> endobj +890 0 obj << +/D [4463 0 R /XYZ 204.675 620.154 null] >> endobj 4470 0 obj << -/D [4445 0 R /XYZ 71.731 229.071 null] +/D [4463 0 R /XYZ 71.731 612.802 null] +>> endobj +4471 0 obj << +/D [4463 0 R /XYZ 71.731 587.078 null] >> endobj 4472 0 obj << -/D [4445 0 R /XYZ 74.222 198.187 null] +/D [4463 0 R /XYZ 249.701 587.078 null] >> endobj 4473 0 obj << -/D [4445 0 R /XYZ 71.731 173.116 null] +/D [4463 0 R /XYZ 273.821 574.127 null] >> endobj 4474 0 obj << -/D [4445 0 R /XYZ 421.753 157.34 null] +/D [4463 0 R /XYZ 71.731 566.989 null] +>> endobj +1889 0 obj << +/D [4463 0 R /XYZ 71.731 510.202 null] +>> endobj +894 0 obj << +/D [4463 0 R /XYZ 189.239 472.986 null] >> endobj 4475 0 obj << -/D [4445 0 R /XYZ 95.641 144.389 null] +/D [4463 0 R /XYZ 71.731 465.634 null] >> endobj 4476 0 obj << -/D [4445 0 R /XYZ 252.683 144.389 null] +/D [4463 0 R /XYZ 350.294 426.959 null] +>> endobj +1890 0 obj << +/D [4463 0 R /XYZ 71.731 419.821 null] +>> endobj +898 0 obj << +/D [4463 0 R /XYZ 261.414 382.605 null] >> endobj 4477 0 obj << -/D [4445 0 R /XYZ 185.773 105.535 null] +/D [4463 0 R /XYZ 71.731 375.253 null] >> endobj -4444 0 obj << -/Font << /F33 1278 0 R /F32 1187 0 R /F27 1180 0 R /F23 1173 0 R /F44 1994 0 R /F35 1525 0 R >> +4478 0 obj << +/D [4463 0 R /XYZ 71.731 349.529 null] +>> endobj +4479 0 obj << +/D [4463 0 R /XYZ 365.641 349.529 null] +>> endobj +4462 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R >> /ProcSet [ /PDF /Text ] >> endobj -4480 0 obj << -/Length 2389 +4482 0 obj << +/Length 2248 /Filter /FlateDecode >> stream -xڝ]��6�}��V�\I�d)@�H���.A�-��Y�m]dQ�G6ۇ��7_���v -��p8��V>���6P[ C��0�W���_`�W�Pl�d3�������֫Le�^��WQ���P�q��+?y���4e�m� c�{�x�;�Vu����:b��:���w?_���4��Ve�~VIG��2ܞ��b�D���*E�$�ӁB��e^��z����l�E�;S5Y*m���p��c[O���~}��{�����Q��!���'A���{�c��:-�_�A`�� T��ͻ�dӭ7����u�8���Tk`�&5]_٦�U����^�� ں�(��q�e�英G>�ʛ��������=xܡ��'A�����v���ah�����t�<��;ܢ�#��!Tš��*_2s�(��>�O�E�J�-��*��G�� �"�On�营��-'�6b�2&ʍ+�t� 9 2"��"�!vyq��dQyc���wd���� ��!�P�_�16ڇ��?�rQ��1ȃV�/��\)g�./��B�.:/�E6i��2�]�ŋ�Or��f�l��ԛalox����=��sH��p�����/l���v�6:V�9�x���%r�a�� ��oǾ��Uͭ����� D�7��Ahu �����o]9�o�)x�#!�D��7l]5|����H�� �J�O�̛�����4����)J HJ� -I�)�P�Eo���[�xG��Aޔ!8�NԨ@������n{J�|�����9~Q�%�D�w����o� �Ƀ;� -��A?8y�|S�wU3(���PP�4Z�!�`t�\}��J(?����Bb�±��*PY�W�Y��>^}�8�5�TEI���.�l�>���fE ��D>��@iP%�3��a!̻ JN�jr�M�*�B��hv� U[:�4�cK���?]���=�Tc�$`F���^�7����`�R6�2i��8�<wf6�8!����>;#�u���$k@4@�� �P����ؐ�h�ƽ��Lc�Ñi�#�(�r��Z����-d}����em���ޞ�v�H�81��E������ ��$iۧ,���y3�$��ʶ|������`��� 1/��c�q���)����g5�S��m�+��Ψ|�)�5���|+$�J����f���- -�m�X��[H��h�K�E��L��̑+��^@�-!��{Y[X��%�Їd��Ӕ`?O~ -�-�%Չ�+0/O|"�#�C0t�� -҇|:l�Smr��+�X��t�<v�O�^?�r!�&9����Ǝb. -�9�~�ه98s��j���n��i��; "���|��� -|�ˁ�c�}��G�S��3�1��S������U�,@O8tc1p�K{;�i�5��4�&E���8�͌h��njpG?�. (;\��>:��{N��</:�v����m�\NTpHh�]��V��q����N\�H�����l��S�=g�0�����!Vp��`6��a������(���I.R(�IN�k����b��82y+��."�yH�>P�\AIT�����Y?K�{H�%z����e]Q}|���b"�5OCdS]ӳ�Ӳ�1�a2N�����j�H��Ur<�9��M;wQ��F�J>rD�5�֣r��������ވ6�kɱ��6�ЊB*^�v!���R��nK��'H���i�\ZDS�����4B;0�}=\0U�UC��k��"�Nh�ja/RC����ĉ��е�Tx%��u�Xف����qױ$�g��N��fy� -��S��-�%��갼�%��%�uQ�K�_��2������%�0RA8���#O�r'�|%����6���:�H���e lR�=nfU3Mp7����K�B�=�I��7����]-l�&7���1�P|Nק 7Xj�S�ǂ.��;;��#����Q+�jבGt��8�m���|��)O;#�V��������_���S�fEV�c�L�TPN~!��FN;=��P�����{M>��f��R���R� ��y�9�7y���u��6�$/wXi��Ur}��rF���-��b��c�ǁ6o� ;�7����ۧ��ٛ�{h�Ѻ�C8Jk�W=�.�$Y�Ps!��aH-�WN���#s���0{��ˇRm|w�B���)<�y��B['��2�uc�|�b�ݺPM��T[/�MA�B;�E�E#�s$�sL���B��&���l�ܘ��}�=H��h凵���������0��a��M�U1����#�ԣ�GS�]5<<n����4�>��&Y���[JO\P�t�W/�KQ�1 Jendstream +xڕێ����_�<�V\�)Ej�m1������H�t(R���_�s���^�3�3g��2.�.���c�� +?�����*X��˻W��H�̏�����4��b/V +o�^=�ŋ(�X<��[�؏�l�T��{s<궬�\��|���������_�Q��q��7�$�~]���_@=_~��H<X���\�>U��Ci����)"D�n������A[w-.��k;��m�S�3��{]2R7F/��;U�s���V�x7ԥ���8��/�0%�B_v�V���ů#/pzŰ{��#�gr(���2��[������Vf�D��Jae��2�.B���^ �Uf�c��~'��w�N�0��г��������$(|�ك�/�ĝ�W6֭� +�u�]�7U����ب��-���7�(�D:�����?�5�V�Y���F�E��V�u���9��b!X, I�]�"��z�6}G�3�G���1`��?VJ��[��f��z�eml_���9�Ж�ގ��wtg�}s���ݗ�8��e������_�[ˑR[U7r�Mlw:�����1G�7���/??~�:���Hx�bc��X?t��]���c���]�_k�y��H6�Fh����zhl������8a��)E,����nǿ��Q�5�0XB��2�2ʼ�u9�F�����U +�a�AÁZ�rz p�.�� 5:I�Zk��㏤.�z���]�#�V<-�H��?���u�E~)����ڲ@�aD��/90�EP6/P�ǖs����pd<i슧\3����Ҝ\qX]i+"�nXl�XQ�F�hl��&a��DJ�\OK��K��'����砍Q{!m��(��Y��� xÈ�����Z�����_'�V%ߞ�ꓻp��X�zf��w� 3;%���^���9��Q��47�#��=� +l~>��o�!]���Q��ϋXD)�/�����1($t�b�"9������B��Q2+�Qpej붓'�G�0J� ��J�r#(�@�>/?bK%b^'����~Wn���_���8fAm�\�S!~��M� ��"�7(����)�?���<:mV�>��V�S����� +a`Jc&ב����������@��Ȳ�nj�+��nd��R��O��5���Yi�xQ��1ڌP���7p�ϋNNA+�L f93�W�����q�*n�.���zp�ga!��S��X������� �e�3IbU�~Vd7�p�r�����BCњ�2;��V\ʰZI��-H����,�j�(5�!��D}�6T��X� )����u��F +�����Ou��d��9��[��-��϶H����RZ�� +�%��̭��ݱ��%W!���(���v�B�[�~��J@S���F�%9@G\�l�"�c>�kC�%I��FB(I���R��LD@��v�ǝ^����1��{+:��� �ֵ8� �RakC����2L ;�1l+���G�"Jo�!!�c��}���V�����H���}�R���y�发ވ�(B�!ZiÉa_=�$����4vܖ� 00O��W��<���[��myW����J��3���hk�#��L���A��^�s��@9���pF�]�P����z��1�7` ^)�����Z�<�JK��,�����)1��������B��v� ����2��Q�UPc���A6��{�}QK�~ ��3�W�(�[Ibc��� +� �7��*V;i����5����|���N�3�?Ad� "���#�y�Ϩ���VP[����9��+<w�`�\=a�L�M�?./�ʎ6��^�$-7@��Jn�������?yr( +� �������F��z��&!�����3-�p��I:�����=79����4�ϴa\��ܝ��oQ����j��v$��<��Q刓�Ϣ+��c�̈́s)t�� V��_gr����=ʒ��+�c���cB��Ǝ��.��8I��L�Y����EgGj��^ "?n_y���G�3d�$t$(3>�$�x&���J')R7�P�%��V�xޛ��`On��+�g-��ȳ�����Ǫn����,x������c�)`�T7y�� ����r��>#V�*c�@�T��@�Ռkf�p��zMM��qR��Zӿ�k�Lz*��� ��$~_n���w���?��7y�O�0��������t�N��D�^�No/r[���-ʥendstream endobj -4479 0 obj << +4481 0 obj << /Type /Page -/Contents 4480 0 R -/Resources 4478 0 R +/Contents 4482 0 R +/Resources 4480 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4388 0 R -/Annots [ 4494 0 R ] ->> endobj -4494 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [312.894 353.147 351.505 362.058] -/Subtype /Link -/A << /S /GoTo /D (installing-bugzilla) >> +/Parent 4461 0 R >> endobj -4481 0 obj << -/D [4479 0 R /XYZ 71.731 729.265 null] +4483 0 obj << +/D [4481 0 R /XYZ 71.731 729.265 null] >> endobj -4482 0 obj << -/D [4479 0 R /XYZ 71.731 718.306 null] +1891 0 obj << +/D [4481 0 R /XYZ 71.731 718.306 null] >> endobj -4483 0 obj << -/D [4479 0 R /XYZ 485.041 695.392 null] +902 0 obj << +/D [4481 0 R /XYZ 366.546 703.236 null] >> endobj 4484 0 obj << -/D [4479 0 R /XYZ 74.222 664.508 null] +/D [4481 0 R /XYZ 71.731 681.855 null] >> endobj 4485 0 obj << -/D [4479 0 R /XYZ 71.731 639.437 null] +/D [4481 0 R /XYZ 71.731 671.343 null] >> endobj 4486 0 obj << -/D [4479 0 R /XYZ 71.731 600.648 null] +/D [4481 0 R /XYZ 71.731 666.361 null] >> endobj 4487 0 obj << -/D [4479 0 R /XYZ 128.474 554.521 null] +/D [4481 0 R /XYZ 71.731 661.38 null] >> endobj 4488 0 obj << -/D [4479 0 R /XYZ 71.731 539.412 null] +/D [4481 0 R /XYZ 71.731 638.889 null] >> endobj 4489 0 obj << -/D [4479 0 R /XYZ 142.466 500.848 null] +/D [4481 0 R /XYZ 71.731 615.552 null] >> endobj 4490 0 obj << -/D [4479 0 R /XYZ 142.466 469.071 null] +/D [4481 0 R /XYZ 325.163 599.776 null] >> endobj 4491 0 obj << -/D [4479 0 R /XYZ 180.841 457.415 null] +/D [4481 0 R /XYZ 71.731 584.668 null] >> endobj 4492 0 obj << -/D [4479 0 R /XYZ 142.466 446.185 null] +/D [4481 0 R /XYZ 71.731 561.754 null] >> endobj 4493 0 obj << -/D [4479 0 R /XYZ 71.731 362.058 null] +/D [4481 0 R /XYZ 354.338 545.978 null] +>> endobj +4494 0 obj << +/D [4481 0 R /XYZ 71.731 543.821 null] >> endobj 4495 0 obj << -/D [4479 0 R /XYZ 264.01 303.498 null] +/D [4481 0 R /XYZ 71.731 520.907 null] >> endobj 4496 0 obj << -/D [4479 0 R /XYZ 375.655 303.498 null] +/D [4481 0 R /XYZ 71.731 515.925 null] >> endobj 4497 0 obj << -/D [4479 0 R /XYZ 71.731 288.39 null] +/D [4481 0 R /XYZ 71.731 485.041 null] >> endobj 4498 0 obj << -/D [4479 0 R /XYZ 71.731 273.446 null] +/D [4481 0 R /XYZ 74.222 443.363 null] >> endobj 4499 0 obj << -/D [4479 0 R /XYZ 71.731 224.395 null] +/D [4481 0 R /XYZ 71.731 418.292 null] >> endobj 4500 0 obj << -/D [4479 0 R /XYZ 111.412 198.492 null] +/D [4481 0 R /XYZ 138.434 402.516 null] >> endobj 4501 0 obj << -/D [4479 0 R /XYZ 71.731 170.596 null] +/D [4481 0 R /XYZ 288.63 389.564 null] >> endobj 4502 0 obj << -/D [4479 0 R /XYZ 71.731 170.596 null] +/D [4481 0 R /XYZ 95.641 363.661 null] >> endobj 4503 0 obj << -/D [4479 0 R /XYZ 71.731 145.66 null] +/D [4481 0 R /XYZ 71.731 362.254 null] >> endobj -4478 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F32 1187 0 R /F35 1525 0 R /F23 1173 0 R /F44 1994 0 R >> -/ProcSet [ /PDF /Text ] +4504 0 obj << +/D [4481 0 R /XYZ 71.731 338.59 null] >> endobj -4506 0 obj << -/Length 2390 -/Filter /FlateDecode ->> -stream -xڥY[��6~�_�#cF�DYj� ��$M�Y4�Y�C[�E����Jt&��~��CZ�ef�.��ȣ�s��r⟜-�X�xD��R5[77�l�7�n��X8������Wo�x��<�g�Y"�ȈN�LE����~��mY}�/"���;͋���Tu]���\J�ϓ0�8��7G T�y�(�ǹ�2�̕Hf"N+d"� ~��F�1 -E�mB���G*x���2(;~��Ǻk�2������aTC��5o><}��7^z}�+�*۸���+��V��K�ny�8J���fx��_C�ǹ0�2��Y�4�tu�����Ν����v �g��BF"w&�Z���F�S�D�5�MG*$9�!�CUj!䓖M0M��q�I�+12O���<�!�@/�Էl���\�X�E��ᏺd��b�\�۾h��������1�#w\�ɟk]�e�u�����q"L|<�A9�1!7�?0��b*(���<^����bOffc䑈�c���F���Jwf�_�0�~b<ݱMיL�w3EYޯ -��� -������Pl4k��x�.q�іd�,U�P2�`�����Y��� ���� !�Y"��fR�y<��ls�����CI��/�����K�Py&ry�(�������P�r��Paf/�_�m��uFx�9R���*YN&IE����_����Y��B|�a���n��v'���s���O��Ǫp'@�;�]�r���Cm�͑D�H��)�p�DW��YL��-M�>'D::<�HDt�<]�0�^f�p^f�r�2�3�5�`8f�(�<���*�i���,| -Ʋ�ևF�Ƨ3�6����f���n=t���$Eϕ PH����N�'�7�"�p���4 �2-_*�J!�,��FW���*J]����1��e�ҽ<�/o��j����ŀ���N��k6���E"vQfkV2m�[w��� -[,Up�����K8F�j�:��ӵ�O�|c5��8 �CY�;��.��a��(J�����$�����A��%� �u�~�}튺��c^7E�"u�(� T�t]���ߖ��������z����KJ7�%ˮ��/�u7خ�6�H~-��.��{�7�0�v������W��[֓V��D-9�<[I|rV�N�f���M��w O��������;.��ESt.��r�-���i���j��ɺ�P�5�$9>�T9<��ؒ����K��Tvzho�u ���o�qh�5]�^��1��t�k��]nz[��QO�/�v���8N��t{TN&d˪�ޖ�vN ��}I�0����I�7�k��.#̩�2�qhb���4L���ԃ ��76+<��^�8έ!t_�E����oJ���D�7�-��#�o�#�%<�r�bK��m��c�pM,2�s� �ʽn -���A���Eam��[����\�&4~��pB��ު��}�葟��Zn�"�?��gRE�^B��^����Զ�%�%��2�k�Щ9�&ͭg�t�Uc 1����^ea�Wm�c�4�SD��Oh�#җ��ew���^O�,�E�~O�K2Qҡ��F�^<V�;ۑ۸��S�ʌ*���6���R�z� �]�����r̒c5e��jO*���VڧO�+��az�9 -`�^I��Y��5���� ������+�ñe3)����\�����p��O2�`C!�8���.�����.@���#$��ҝ~�����<#c3�1��Pw^T3���f2��*N�Ne��~o���7�6������}�����.�(��X���\V�D��$*Ę��5]���N7$�N������G�cen�}���ҟ`�W#���.�������늚�k��F7�T�K�*Q��h-��~^�e"��h��3�w�N���:�*�r�����n�H�t�5-��wF{9�F��њ�ܻI��'���zW���`k� -�̌iP�NT��|��srJT��I�A�P7v�¬�o8:�t]�1ą4!����'��/��c�"��zh;����#�h�*�1Ws��k˛��S�ڌ8���Rl��l$�ȁ�6k$�$�ٙ`H�~IY�^rV&Hw0�WT�-d�8����U����O(@�%�rg+�#,�C��eDŽ���U+��;Q��\|���R���ѧF�������JM�0�x��V���|��9l�v�@1�}�O��Zs��B(�dy��Ϛ�c�؎E�b�� ؋O�PF�19��D�6~p�a�}��N����K\e��L�������5�JS�/Q���ݢFa��DN�X��9��E1��kHe���{Ë����i���>�~;�T�~BH�,._��aD���AE�a�'B�e�s?\r�/W7V�endstream -endobj 4505 0 obj << -/Type /Page -/Contents 4506 0 R -/Resources 4504 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4388 0 R -/Annots [ 4513 0 R ] +/D [4481 0 R /XYZ 105.325 322.815 null] >> endobj -4513 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [422.465 613.447 467.048 622.037] -/Subtype /Link -/A << /S /GoTo /D (security-mysql) >> +4506 0 obj << +/D [4481 0 R /XYZ 71.731 320.658 null] >> endobj 4507 0 obj << -/D [4505 0 R /XYZ 71.731 729.265 null] +/D [4481 0 R /XYZ 71.731 297.744 null] >> endobj 4508 0 obj << -/D [4505 0 R /XYZ 71.731 693.235 null] +/D [4481 0 R /XYZ 71.731 223.024 null] >> endobj 4509 0 obj << -/D [4505 0 R /XYZ 184.704 677.46 null] +/D [4481 0 R /XYZ 296.767 199.278 null] >> endobj 4510 0 obj << -/D [4505 0 R /XYZ 387.861 677.46 null] +/D [4481 0 R /XYZ 74.222 168.394 null] >> endobj 4511 0 obj << -/D [4505 0 R /XYZ 71.731 662.471 null] +/D [4481 0 R /XYZ 71.731 143.323 null] >> endobj -4512 0 obj << -/D [4505 0 R /XYZ 142.466 623.907 null] +4480 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F32 1215 0 R /F33 1306 0 R /F35 1567 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 4514 0 obj << -/D [4505 0 R /XYZ 74.222 575.891 null] +/Length 3170 +/Filter /FlateDecode +>> +stream +xڕko�8�{E�EY˒�(i���Ц�$����� K���$�z����7/�R��z���p83���9�瞅���xk�[gI��9���ϯ\�������W��?[����=[��!߳��;{L�a]���J�o�/p�K���L1���'/��{73� ���ұ~����o��{ ?�ב����f"��\�j B:��/�$$��:�kmT��X����d����PBW�WUW�*Ue��kgعVތ99���f��0�����M��Kͭ�gnd�PS��׳ע�?����v��e�xi�b������P��.�i_�K�7�p��;�a�)�jh�j�5���38CU��Phn�:��;�c����=�ς����ڂ�9!&� ��\��Hr��jڸ� ��m�����ǻ����W�f�j�� ӧ�E-L���.��ԉ�9�m6��}����or�bA�>j D���$�Y�95��)��f�vk�!!�^Ս��U��g�f���s��:5��y����p�ɚ[î�Q���d�]� L����h5b:1i�i^���u5�>Wȧ��L9�62��u�T*s4�wןg~h��^����7����)8�&��'�o�"&B�l&��N@/d*!;�t�|�C7�]����뇏�!�8�o�W��f>�=�����q:N�7�EH8C�����2N%��-.����qQj�/��H��)��zD��/ǘ��1���BG4 �Fb~�BS��_�pÝ_������K� ��x=g*vB���w萱5���8�&3�Un�E Xm"S��*��]�5��m �|�-�!b��N�����{���9�s&W(ժ��1��T�Y�5NA<a�;�����~p�\��.��͂�����ЪBōz��B���bX��ʼ��NՕ3�+k��-�� �C͜���fN���#��3�6�m3!Z�x���I&�X�q����6���@h&���oGa$4�.�k�fƷ��2�:���s�!%C-%:UY�|�����N�It�p�sx3���#Y��=���hF����ȝ����Z�~��-�C�d,�b��QK�PݨbkX�®��{�9�ɴ��ض�(��|7!��F��³�=T�h8À�A�́��0A`T����9�}!T�N�f�5ĠMc{��g�u�d�f�ۦ;i��-t�Pʔ;���YZW3>g���<�`A~u8f���Gy�ɯR�4��~����v֖�YdO^��� u��-��d�dA��& GE�+��(Hf*� >�� �Y:v�I�˹�y+q������~y�÷�%�� +q�[�.\h�z���C� ����l�Z�����c��uk��Z,><�G��c?+�D�w|)�h�98&�O2�� �F%qG7�#i�2q[+�V�Ve6�k$� �) +��|e�(��8/ +�u(1&^�`��Nyf-�;���xʀP�Ujm��^�yk�z�<���D�g{Che�%5ܓ� �L�ケMGAa����hpr6#&�x�V�P�)KE&ܝ\Ux�xQ��ˆ0�c���pG��9�t %0�\�DqΏt��8+�tW�ܥd�bY��č"�}+"b��n�}eV(+c�R�K~Q6�����6��t'@��3~�?�|��V�)�ĥb�� +r4ʯQ*Y��s��}��A����BL�X2��{�mX��x�y�Vj�V�x�z\�c_n�&�(����G�_��7~����3Ǜ9#%��;GG��ws�#(����糞���-Ћ85ώ��=����T6�{o-���QIW�n_�P�h9�a��ĵN�Ϸ(��X�ݮ����B�µ�`ν��쓗�y�XazB]���䬆�����U��Q�De�Dz���[���x���Ƙ؈J��u+$����/����U��*d�xu�k�La�P�:�i!т���႟�õ�&jQǜ��݇�m�ST"X �mWcjo�� WҎA�"9�$ o3�t؎y����/A�k�+ A�;.ה�1��e���E5���-*OA5o�����XZ����ѕ�}2uhI/ ѫH-��},%':1�}G���8J��e�ArW��8�)���f.��{�]��V+�w�uU���fz��IFX��������<�UvIH�z����{ �خ%�r����&���X����{��c"ζܾ!V�D?.A�1��Mc�H�0±ɵ��p���O��, w\�U +yOC[.�� �S���V�~`@��B��==z��P�B>g���J NC��x��b������]��"�L'�C��ՏV�`t��O$l�m�K�₱ƒ[�S����(�<�aX +�Z�<�0��^��]�0�/8��0L�"A�R�(cza����&"�H�����R5*l��f��)1�gd�ĝ�w}�{q���+��a~Ӌ�g�,�MsrT��h�Θ�&�<?�V�/FI|�i���6iC��P^q�_���y��e��j��2a��CKhz#;]]K�&/n�$�k�hss��J*�ո�۩�DX?��X��3�F�<]����ț7�.8��t�/LP�B��z��U��E����b�u��8�����k3�'�<��^��礪�0駗��c5��(7��L��G6&�+�X="n2���1�/�A�� +���г7|A���zB���}�l�e��҅SrG�t���]��C���b�:�� 5]됿�P<��:oٜ��`�}�!.�`��W45��GrA�1���<I��'R�g�9���d%�S�}H*h��ݔ������XC&��3���){|���|8�!p�*�t�ڞy���݈Ǥ�et.̶�L^���az�%6��2\��B �>9֕6!r�S&��7���1�a �a�����gYluA�Cp|~��@� +�P^�H ���|y����7��Av;HfZz�I���d۲��Iת|%~�[3��8�BNV9��F�! +������c��*�wU���Gs�S�L>�%��3R�R��p��Ԝ^��s3�x$�˩�������x��u����e1%|�' G��//�������˄�R�A��^endstream +endobj +4513 0 obj << +/Type /Page +/Contents 4514 0 R +/Resources 4512 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4461 0 R >> endobj 4515 0 obj << -/D [4505 0 R /XYZ 71.731 550.82 null] +/D [4513 0 R /XYZ 71.731 729.265 null] >> endobj 4516 0 obj << -/D [4505 0 R /XYZ 71.731 497.021 null] +/D [4513 0 R /XYZ 71.731 718.306 null] >> endobj 4517 0 obj << -/D [4505 0 R /XYZ 71.731 497.021 null] +/D [4513 0 R /XYZ 378.741 708.344 null] >> endobj 4518 0 obj << -/D [4505 0 R /XYZ 71.731 474.242 null] +/D [4513 0 R /XYZ 71.731 623.497 null] >> endobj 4519 0 obj << -/D [4505 0 R /XYZ 71.731 440.299 null] +/D [4513 0 R /XYZ 429.028 599.751 null] >> endobj 4520 0 obj << -/D [4505 0 R /XYZ 204.252 396.563 null] +/D [4513 0 R /XYZ 153.769 560.897 null] >> endobj 4521 0 obj << -/D [4505 0 R /XYZ 71.731 381.455 null] +/D [4513 0 R /XYZ 453.126 560.897 null] >> endobj 4522 0 obj << -/D [4505 0 R /XYZ 71.731 358.541 null] +/D [4513 0 R /XYZ 74.222 530.012 null] >> endobj 4523 0 obj << -/D [4505 0 R /XYZ 194.459 342.765 null] +/D [4513 0 R /XYZ 71.731 504.942 null] >> endobj 4524 0 obj << -/D [4505 0 R /XYZ 357.109 342.765 null] +/D [4513 0 R /XYZ 71.731 471.133 null] >> endobj 4525 0 obj << -/D [4505 0 R /XYZ 71.731 330.645 null] +/D [4513 0 R /XYZ 71.731 412.289 null] >> endobj 4526 0 obj << -/D [4505 0 R /XYZ 197.727 298.232 null] +/D [4513 0 R /XYZ 71.731 381.405 null] >> endobj 4527 0 obj << -/D [4505 0 R /XYZ 328.437 298.232 null] +/D [4513 0 R /XYZ 221.179 344.707 null] >> endobj 4528 0 obj << -/D [4505 0 R /XYZ 71.731 296.075 null] +/D [4513 0 R /XYZ 71.731 337.569 null] >> endobj 4529 0 obj << -/D [4505 0 R /XYZ 71.731 281.131 null] +/D [4513 0 R /XYZ 132.174 274.969 null] >> endobj 4530 0 obj << -/D [4505 0 R /XYZ 71.731 259.674 null] +/D [4513 0 R /XYZ 71.731 267.831 null] >> endobj 4531 0 obj << -/D [4505 0 R /XYZ 115.567 206.247 null] +/D [4513 0 R /XYZ 71.731 267.831 null] >> endobj 4532 0 obj << -/D [4505 0 R /XYZ 71.731 178.351 null] +/D [4513 0 R /XYZ 74.222 226.152 null] >> endobj 4533 0 obj << -/D [4505 0 R /XYZ 71.731 153.281 null] +/D [4513 0 R /XYZ 148.772 203.238 null] >> endobj 4534 0 obj << -/D [4505 0 R /XYZ 187.785 120.867 null] +/D [4513 0 R /XYZ 71.731 201.83 null] >> endobj 4535 0 obj << -/D [4505 0 R /XYZ 71.731 118.71 null] +/D [4513 0 R /XYZ 368.158 185.305 null] >> endobj 4536 0 obj << -/D [4505 0 R /XYZ 71.731 113.729 null] +/D [4513 0 R /XYZ 95.641 146.451 null] >> endobj -4504 0 obj << -/Font << /F33 1278 0 R /F32 1187 0 R /F27 1180 0 R /F23 1173 0 R /F44 1994 0 R /F35 1525 0 R /F48 2006 0 R >> +4537 0 obj << +/D [4513 0 R /XYZ 71.731 118.391 null] +>> endobj +4512 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F32 1215 0 R /F35 1567 0 R >> /ProcSet [ /PDF /Text ] >> endobj -4539 0 obj << -/Length 2690 +4540 0 obj << +/Length 2521 /Filter /FlateDecode >> stream -xڝk�۸�{~�{@Xs%R�;��\�i�4 ��}�)٦mu���Tr�_��P�-��� ��!9��Y��p��"UI<[�/��f~�"d�%�,G4?ܽ�~��,y�fw�Y�"C>J�,����?��lʟK�W��w{M���?eU4z��x�j�?/�u��7w� b��<SO2��P��-e r^��c�Dx� �h��Lg�A��`O���$e|~�<�:��6;�7�%�6��}�l�U�f��Y��"����F��Z��q���[]T�p������䁈§�5�yDX��a]��Ya]�|"���a�^?-(�S�|��I!�RDi����4� �)��t��4�|*����6�B11*B����=�}�Y�EY}F!m6�6�^L���ɒ�e�,J��P�ON�L��H�$��Ѿlta����������H��U������틆 f�A�[R�G�����p��};Z��D�?��T���%�m��@�i�0��hjͣ/8�;S��A�miƇ�+B�_�YiB�ZVP>8Y���WE���v�����"��f�]�ivKG��!� -c��~E+`V�]��9����� -������w�T�H�4�$iN�OA�=|{}���n������I�� -.��]�}�� 26� �j�&ޠy���,_�dv�u��Á�7��"� �!�D��ѷ��uZA���Q{��!�O��3/g5!��X��Ə�M����ta��� -~GFl���Y>A��O��;�rG������v�:� c��>wh�Ɗa�� ^9P���)�s43*�|f�~�_j���@�с>�n�&D뮮�S5�����|Q���P%H�g7�&���x��#��t�t���+��#�h}AFGCϓy��A���N�]�ԉX:�E���*O� -��vE�$f�������m���V�E���-}�f��wo8����ij�q</����,EDϥ�i��/`�y���C=g���� ���n���LL��K{�O���@�/e1by)�+w�@� -^��Icv'�>�t�OQ �;�no^��p#��0����p�k�f�d�6�+Wׄޔ�^۶{�a�0s4�]Gnp1E�r(�ۅI`N����[�n�]���g]�� -��$�X��s -�9��TV�ۏ�7��)rq��5���l����_,�>_�,��ꢎ�t�]�ŻTltI<�:�o{_h�J����A�q�x���K��9�����ai6x�+Z�J�tS�*�"�Ƴ��8i���1�˯oگS�&�ȡ%J�kg��!�Mi!����:�BEzn��9�7��EW���� b������T���$���`�}��$�ݗz$y7�J����J;tu�8g\Y����Z7l��]>z�_��%'�8r=�(�d��U�@�s�X�M�xc����r)>D�l�%@N'�RV��zC�#մ��KD���ӏ�ռ�E���f_@d"�T ��@�-�r%7�&�g�ycΠ:��=d,E6ܣ�p�@�����*�g��z oTUl`y(��ND�oо��-,eNL�thhg����U�9:���G�V�Ɇ�������Y:S������y��h�s����n�0�=e&$��'�d�ɞc��3��Qصe1�L�eC�@{�$`0�,����ہ���|������D"N2^g2R;���F����'�EQr�������b|ITU��$s�d�n;�ל��n(�-� -����N���T7��zZ��I��c��rȌ�f�e.�ua�O�o���%����_lD){�����D�0e��:��]8ǖ(�=��x�x1z��ޢ��\k���u۠+w5��'J���5�-\��([���/��l#��1$�Ҕ�A�|��\��ǖ���<���� ��F��N�hph�`�e�v�\�_��GW��ĭ����7����s��Jc9=t}G��VA�E�K�W� :�/�'��2��w�&�E����h�k�K�r^�X�)v�������les���|sݛ����7�(nӦr: ��B��r �Vu���<ԕ�[(rn|�����HZ��ɗ���rHK�kš�>�<�!�rt)�YM�r�D�忰4UyĔ��!�55���J�}q�����S�#�A��X6-q<^�Ug�6�إ�28���>6���7�-V�!Ӑ -�vX �M�������=[.P6�7a����bVڇ����f����E�x�?[��aU�f����f���5ߛ��ۣ�(*�����{����z�r�h5̹��bƗ�&���r�Y���U�țC@���W�:J���|���P'�� ��a���B�_�;(�۞'� D�%I -�<U'I�k;��K���r�+�~T�Ł��/��"��k��azs������{A���)�:�i3<� �j�V&k�>��/�C���j(�p�atB���5��R��x`�;2?"�0d\�I*�E�e�(��'%qG|��s�Y��u�M&��$Kp�Õ ���i>?l9ƽm���N6���D�o���F��}�[/:������SUlj�v�E:���^��~���#ɤ)��`�� -4���u��Pt�endstream +xڝY{�۶�ߟB�;sT��M��6�ۗ�uc]���EBb�PҲ�黋]R��v۹�#��\,���'����i�`.�$���d ��|�pY��<�0{����'��~5��Xd�'D���_���N֥�4u��sz�o$ �t��UU���b����xy�O�������`A�b��_4����28Z9�E��^&�(�F���N8{�G� ^�j���mL��l*e�2D�t������%=a<�@O�z�H����:���j�T�̪��������O����vpv%c�כ�(�XV��;C�i7������27fN}GӰ����� �w�~"�4��~ ����mͫ�m���</��驠Ď6�4�S��x�Ӕn�KY~o'�`6��f���<�ZI*����O}0�@�V�s-��7������`�O���E#a�i��R�"������By:S��� r�G�������~��>pوk�b�[m_���dA��v��p��l�� +Tf�݉�i;舌��2l@�A�Z�k��tCă�n��%�V���4������[��u�d��l�*��W�0��{"O�9f#�9�Nq3l,��{O�PL���_A $�s;D���.B�qضgQ�� �b��b3h��Bڴy�r�U��7���I(�!�t��6gs��v��{X��J�W�h����G��V�"��v���Ck�x �yc~x���of�3*!�"��o�+�V��|���`C�8%//��-p�`�9��n�.�x6su}3���X!"5H�"P�~���������$��h"�U�==�!X�_�.��I��I�jh����5���'�|[���sys�݆���qQhE}�ip�rW兼�k�`ާ�~��@,r.��>��_��J���HD@G��G��ۃ���؍��M�{���oNZͷ@���6�v$�-�BH�-�a�A�Kга�鶏s�܃$4�d�ֲ4ʜn��z �c���3Gi�bŃ7d� ��(�-_Cv��G�v�^p���0;P�'��8�%�(b�D�O�vg�����f��v����/��a���� b���,�C�jO:v���5���d_�KW`�}�Y�'�(����a<�l�rL�0�V� +K$�$����aHp;R���Q�\-{%��'*_����1d��G=�kg0�Z��&���\Ҡ�$�6�,�Ff���pP� �O�߮�u-|�z[��&�r���],ć$ ����z������H��~j��z�6����i#�,��K�T+oi�����B�FXA�5X��s�yr?�ݮѻF�J!e�8#�E�}��3(� �W�a��/;U�\�mw�f��~�G,1���!�-��Y�3+Gu�*D$�����f\-�a��f{E-��e�/u=B��4l��QX�H�FV�����2k�NK��b�r?�f���Z?��M��s8~��Hg��/�������u{���E;�m댭�Q�����$2�>�:�-I���l��p���*I��u�7��!Dݲ�[X�hd۲s�8tE�v����5�/�pQ�v��2�<|�"�9�87�� oΜ��b��f��8��sP��Q=]5��he:n�ܼ�H_+�6�a��5 <|���8Iw�I���$��ܨ5p���iOP8P��"O�pm������� ��ѝ��@��2&�G�D�5�l@������~�X<_��v�y���� ���q��,Ny����x��_�U&{@���](��kU�����P/}����!�O<0���)�6�(ĸ�M���^U�:FB'3$�N�QI�������<��a�Sb�re��]���U��a���?�:�e C(d�>�Xޟ��ޣ�� +)ւ$P�ÿ_�C1r�'�Jq ���ٿv����c���!�/z=j�o<������e�|���k�B��9u��t[� T�B����n ��O���2��?�X_[�3�߰�[�Y+����Eיg"���'(S�c��ހ1x�~����u&��:�4���_��됌������h�m�\o+����N$5rˈ��#�֕^"�B>Evc�wI`ɝa�?@.3��r�13t�=�W��~#�&Tc >�Բ�S�=�!�^� }�%c}Fp����% +4&IK��3M��h��F���b�c��m�>@G�����K���t�̴է� �h6�E�Y�������}ym�QYX�?˞R��3���N��c����2���g'���]�@'/������aH;\<�����������j(��a�����aPk�V�����'qT }�GX\lI@%���B�>�{C��o_�xɄd8��0,�GR�!k�&b�O�>���vV��M.Y~��Z�&��آ{\B�g�vK�1�3]���h�V�����?AD����?RE.~���Nу\@�~˩����kendstream endobj -4538 0 obj << +4539 0 obj << /Type /Page -/Contents 4539 0 R -/Resources 4537 0 R +/Contents 4540 0 R +/Resources 4538 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4588 0 R -/Annots [ 4569 0 R ] ->> endobj -4569 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [208.787 359.487 228.214 368.398] -/Subtype /Link -/A << /S /GoTo /D (gloss-mta) >> ->> endobj -4540 0 obj << -/D [4538 0 R /XYZ 71.731 729.265 null] +/Parent 4461 0 R >> endobj 4541 0 obj << -/D [4538 0 R /XYZ 105.604 708.344 null] +/D [4539 0 R /XYZ 71.731 729.265 null] >> endobj 4542 0 obj << -/D [4538 0 R /XYZ 140.184 708.344 null] +/D [4539 0 R /XYZ 71.731 741.22 null] >> endobj 4543 0 obj << -/D [4538 0 R /XYZ 184.766 708.344 null] +/D [4539 0 R /XYZ 205.454 708.344 null] >> endobj 4544 0 obj << -/D [4538 0 R /XYZ 71.731 706.187 null] +/D [4539 0 R /XYZ 342.481 708.344 null] >> endobj 4545 0 obj << -/D [4538 0 R /XYZ 105.604 690.411 null] +/D [4539 0 R /XYZ 71.731 695.293 null] >> endobj 4546 0 obj << -/D [4538 0 R /XYZ 140.184 690.411 null] +/D [4539 0 R /XYZ 385.027 677.46 null] >> endobj 4547 0 obj << -/D [4538 0 R /XYZ 185.563 690.411 null] +/D [4539 0 R /XYZ 71.731 639.437 null] >> endobj 4548 0 obj << -/D [4538 0 R /XYZ 71.731 688.254 null] +/D [4539 0 R /XYZ 71.731 608.319 null] >> endobj 4549 0 obj << -/D [4538 0 R /XYZ 105.604 672.478 null] +/D [4539 0 R /XYZ 156.781 582.416 null] >> endobj 4550 0 obj << -/D [4538 0 R /XYZ 132.164 672.478 null] +/D [4539 0 R /XYZ 71.731 570.296 null] >> endobj 4551 0 obj << -/D [4538 0 R /XYZ 74.222 654.545 null] +/D [4539 0 R /XYZ 71.731 549.141 null] >> endobj 4552 0 obj << -/D [4538 0 R /XYZ 71.731 629.475 null] +/D [4539 0 R /XYZ 71.731 529.215 null] >> endobj 4553 0 obj << -/D [4538 0 R /XYZ 433.301 613.699 null] +/D [4539 0 R /XYZ 115.567 505.903 null] >> endobj 4554 0 obj << -/D [4538 0 R /XYZ 159.09 600.747 null] +/D [4539 0 R /XYZ 71.731 478.007 null] >> endobj 4555 0 obj << -/D [4538 0 R /XYZ 71.731 567.706 null] +/D [4539 0 R /XYZ 376.59 465.056 null] >> endobj 4556 0 obj << -/D [4538 0 R /XYZ 95.641 543.96 null] +/D [4539 0 R /XYZ 216.969 452.105 null] >> endobj 4557 0 obj << -/D [4538 0 R /XYZ 74.222 513.076 null] +/D [4539 0 R /XYZ 200.218 439.153 null] >> endobj 4558 0 obj << -/D [4538 0 R /XYZ 71.731 488.005 null] +/D [4539 0 R /XYZ 71.731 414.8 null] >> endobj 4559 0 obj << -/D [4538 0 R /XYZ 71.731 457.121 null] +/D [4539 0 R /XYZ 71.731 362.874 null] >> endobj 4560 0 obj << -/D [4538 0 R /XYZ 71.731 434.207 null] +/D [4539 0 R /XYZ 439.725 352.08 null] >> endobj 4561 0 obj << -/D [4538 0 R /XYZ 162.252 418.431 null] +/D [4539 0 R /XYZ 95.641 313.225 null] >> endobj 4562 0 obj << -/D [4538 0 R /XYZ 254.556 418.431 null] +/D [4539 0 R /XYZ 336.678 300.274 null] >> endobj 4563 0 obj << -/D [4538 0 R /XYZ 327.124 418.431 null] +/D [4539 0 R /XYZ 455.543 300.274 null] >> endobj 4564 0 obj << -/D [4538 0 R /XYZ 499.517 418.431 null] +/D [4539 0 R /XYZ 74.222 269.39 null] >> endobj 4565 0 obj << -/D [4538 0 R /XYZ 207.161 392.528 null] +/D [4539 0 R /XYZ 71.731 244.319 null] >> endobj 4566 0 obj << -/D [4538 0 R /XYZ 270.687 392.528 null] +/D [4539 0 R /XYZ 71.731 226.386 null] >> endobj 4567 0 obj << -/D [4538 0 R /XYZ 476.12 392.528 null] +/D [4539 0 R /XYZ 218.849 205.629 null] >> endobj 4568 0 obj << -/D [4538 0 R /XYZ 71.731 372.438 null] +/D [4539 0 R /XYZ 71.731 203.472 null] +>> endobj +4569 0 obj << +/D [4539 0 R /XYZ 486.265 174.745 null] >> endobj 4570 0 obj << -/D [4538 0 R /XYZ 356.244 361.644 null] +/D [4539 0 R /XYZ 71.731 159.636 null] >> endobj 4571 0 obj << -/D [4538 0 R /XYZ 122.471 348.692 null] +/D [4539 0 R /XYZ 71.731 136.722 null] >> endobj 4572 0 obj << -/D [4538 0 R /XYZ 74.222 330.76 null] +/D [4539 0 R /XYZ 95.641 107.995 null] >> endobj -4573 0 obj << -/D [4538 0 R /XYZ 71.731 305.689 null] +4538 0 obj << +/Font << /F33 1306 0 R /F32 1215 0 R /F27 1208 0 R /F35 1567 0 R /F23 1201 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +4575 0 obj << +/Length 2527 +/Filter /FlateDecode +>> +stream +xڍ]�۸�=�2`k-ɒ���"�f�R\��˶E�+\���H�N������p�2�u�����|�PN�%�]�2�}����^mG���U�kFY8o^��g�b�l�pXl�<.�N��e�.�Fo�A����\��&z���H�N����4�_&I�Yn7�/�=�������<���2�.��%��K/즌���1�2[E/�rT���/�4V�� 3�4��p +���$ƭ��tw� M�mY�G���,�D��'��~F�+��#=�z�i|��X�����" ���;edY��6���>اe���(ϯ��A�ª�H��y�D�ʎ�3o��ǚ]'i��'n'�F���!l`.�4aI���: @�5r� Ūw�a���)\�xå�����d�i��� p&�V/�<z���H�8�%*��4C� pGz�FM"e���$ �1�<����;&��d�m��+� �����uG�YՈ�(�$)Y����j�#�L�>Ј2ɶ6�?�h��~F:��o�]5ZU*9X����T�h!�ν���8&X�`�m��GRl�����v;]�ósL��I��<��k���inms�����uM�#�b�è��4F���k,��Ek���ǤF&+�O�Μ����'�8ʢc�裪X��� F���5w�!0T/T�f��$S����-{M��@���>���)����9.X>$+<bi��'oU�8�]��Y%z�)�p^�᠇N�L���A +;��ę�T�\�8�d���w��������N���0��"ƀ-��i���1���V�r�Pr5�l7q���?��z�]����P�I�%P_T-is��r.6葽 +�X#�a��vT͒<kh����--�삳�=��#F%ǂ=�<HZr�\bΟ��S۸܀7�~='�34TN2��r�+�4�n��R�������>�I�����m�%�M�s���j�T�S�%b�ތ@�iDoD�1�&��+>K:����*`���S�J��ZW*NX�<A����Q�<0q��y �x��P������$��y�!d���N��q�\ޞa#�I�{����헄���wi\�y?�K��+%{6�`p�QZڲ Z�`� svJ�k�z�?�Xuq݅ ����gA�"���Rj������� +�+��M���n���FA�T��}YP�nϜ���3 ��T5 w}��������I)�=3��ܽ}�*�6��I��R���}���!u�|��f��џp�$��h@%�xc�� ��S�6�j}���^��R#̳=�}�����Q�g:� ��%�"zO��"��N0�Y��Q���Z��p^�V�e�u�ko�2�4��$������As�8�i�%�����-�vi+��m����4|�03�yj�!��]�*Fs�����h�,9�,H#��J�Ǒ�Ş�k�L����\3�a�xϬ�v�����-����z\�!�q���i�-�x�/�����fsE�d�:��H���h@3S�a��L˙��0'L�� +�S����[W�[��}C�j_���F*��r{�7-([���?�g���;6<*�I_<������IX/ň6Q�� +�?Sw�(Gs�t�".2*A�(�ӾJ������Т���z`�]]���^�ήV�O�����/�5��^�٢���)H�d�Y[����^�����N<C]���g��d�ZT�p�X��_h$�����!DP��G��E&��KθyXf�N�����<��,��{�̈9H�ǚ��y@�:q�$q�����nZx�O}i�Ҭ�?�9 W�;�'�@ �i�K:�y�JL�b�i��z�m\J#N��/P�%x��i�� q/����P�P�{O@��L�S?�2#�u��� ���(l#���D���}�C���1M�g�n�B���Tz]�$~Ps�Ah���^S��>�ė�� 9+1\�a6�#+��{E�O�np�����G�]D��8��Z�-�S�n�t��t��Q ����7�����55yt��86s^�>��J.��Q�9�Z\O��6?uB��f��^�p����#�)�A١o%�.�(���--}�� �`T=Y�iܔYy���c���uE��⊇x�?�̨?�I� [Ŀ/���� -�M�X ��Z�V��m���y�3��0!+��#�>�����ҊS�4�'�'��YAoe�5�c�h&%�T�?&9>_~J���k��h�݃� +ju ����lW�"���i;oАҵz����霢+��h�͂���g<r��/z��;�,���6w[��`E�>��ɏ4�zw��_<�V��i��1��b�~�(S��{@͜<jk�I�R���UB�}��@F��� �ulmL����0�ҏ0}W����dž��o<�)]�#@hW�] t_�:�};-�Rrm ���+�L|���R�%d��w�5:����(O����w����yy�!�zendstream +endobj 4574 0 obj << -/D [4538 0 R /XYZ 179.919 276.961 null] +/Type /Page +/Contents 4575 0 R +/Resources 4573 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4461 0 R +/Annots [ 4587 0 R ] >> endobj -4575 0 obj << -/D [4538 0 R /XYZ 417.149 276.961 null] +4587 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [258.489 460.11 308.302 469.021] +/Subtype /Link +/A << /S /GoTo /D (reporting) >> >> endobj 4576 0 obj << -/D [4538 0 R /XYZ 71.731 256.872 null] +/D [4574 0 R /XYZ 71.731 729.265 null] >> endobj 4577 0 obj << -/D [4538 0 R /XYZ 71.731 225.988 null] +/D [4574 0 R /XYZ 71.731 718.306 null] >> endobj 4578 0 obj << -/D [4538 0 R /XYZ 236.948 215.193 null] +/D [4574 0 R /XYZ 71.731 696.359 null] >> endobj 4579 0 obj << -/D [4538 0 R /XYZ 289.53 215.193 null] +/D [4574 0 R /XYZ 71.731 662.416 null] >> endobj 4580 0 obj << -/D [4538 0 R /XYZ 434.503 215.193 null] +/D [4574 0 R /XYZ 71.731 644.483 null] >> endobj 4581 0 obj << -/D [4538 0 R /XYZ 71.731 187.298 null] +/D [4574 0 R /XYZ 71.731 606.56 null] >> endobj 4582 0 obj << -/D [4538 0 R /XYZ 71.731 187.298 null] +/D [4574 0 R /XYZ 71.731 570.695 null] >> endobj 4583 0 obj << -/D [4538 0 R /XYZ 71.731 162.361 null] +/D [4574 0 R /XYZ 523.238 559.9 null] >> endobj 4584 0 obj << -/D [4538 0 R /XYZ 71.731 139.313 null] +/D [4574 0 R /XYZ 74.222 529.016 null] >> endobj 4585 0 obj << -/D [4538 0 R /XYZ 131.018 123.537 null] +/D [4574 0 R /XYZ 71.731 490.994 null] >> endobj 4586 0 obj << -/D [4538 0 R /XYZ 223.917 123.537 null] +/D [4574 0 R /XYZ 148.299 475.218 null] >> endobj -4587 0 obj << -/D [4538 0 R /XYZ 145.843 110.585 null] +4588 0 obj << +/D [4574 0 R /XYZ 71.731 455.128 null] >> endobj -4537 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F32 1187 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +4589 0 obj << +/D [4574 0 R /XYZ 74.222 387.547 null] +>> endobj +4590 0 obj << +/D [4574 0 R /XYZ 71.731 362.476 null] >> endobj -4592 0 obj << -/Length 2715 -/Filter /FlateDecode ->> -stream -xڝ]s�6�=��o��bF߲���v��^��z��}��f���H�*R�u��رw{����@�I'��%�*UCZ��,VM�������)6L�9������,[բ.���n�'��"�,�"]=��Do�Q�V\o�"���������$;['I�Y�q���ׇo�}X$(�J���B�)��EʺeB�[����^�֮7Y�G�D�A��8��DR���:�u���4�;(�~^'q$�4q��U�y�q����N>J�M�I�/�栚�[f߹�0���㑥�8�~�I������$���� -*.�p�F�&-�E�k��x?�Le���H�f�y�����GI��-�䴛3� ��Q9eMyk�fB���h�&�t�.&���� �ݜ3���f�vGR�r�z�v�6�&�F��P^z��]���A�X��-Q�0@E�mi�LJ:<���� ���t=n��\u`E����Aۤc��8 ���yWm�\��C���I�[�?�u)�K�J�2ͩ�$��%�"�=��+�5FK��5�4S���v�é�mܤ���6��x.+��T��W��d���gtR�!�Py���ǝ���R��x�����xmˣ;h+�w_��"�Mdg�d�������[�����rr3��k�h�2|0_��m�K�)��]����y����� A� d�#���@ͦut�[h�M�&�la���n ��t�����8�V:ui`i A8۲��G�{wiaiy%�p&��6�}v|�~���F�����(�uU�E�`�U��cT%Eh3���ջ#�v*,��}0�a�C: ,�7 -�pJg ѧa��|��{"n: >aY�o��eD�O���������E��^Y^���#^�NL�J�ɉ �����#0�?�E|pn������s����胴0��E�LP��=������>t<�sB���Wv�"�� �s����yl��M���A��K���=�z��Nj̇��<Z��tN�R�C�n�$�����tI�q0L��'T�b=�&��"{�l��H��(�h�f����r�H�`ѐv - ܯT�B4>9��,����.!�*5B�c)܄խ�m���]�4y���k;���P�U ӽ�R�B���N7�1��pj$@'^�@<��2��b�Ä��$���S�E�"��o��b�W�ܲ�3������tq[�e����Ǝ�0�}X���a����\G��fw���z��x�\r�12�+��l�a�фi6��� "�� r��4��,i�����+���\��n6�I�����GJ{E�I&@�rA+���ٟ�G��:NpCI��a��%#�n9��� �F���EWg���KRRj���)*��>�!8�d�� ����(e�_ �^ -�^�e�Ӕ��Ȓ�s6y4B�^�ʼ*��m��t��mX���8�=����z5ƺ��7�r0��υ� TH��� �6�j�����ǩ �P� -vV��`)%Z -t`"��vC#;��N�Z$�v��W�a�_��Wy^�,:��o~�5^��&����� g�\@����V�Z�n����p�B����s<h-�]��i6t�y~҈f�N����Dd H�nE��'���%'��hhQmm�db[���������ݫjqw(�54I&����\`z��l ��5��14V53�7U�� A��1��tL��d�vyF�����(���xU���\*.��-[�j���GG�aA�ѐ/�!7B�LXߚ��L�a��}2A��J�B�U#��*�X������=d[�%�lO��Բ2���/1��G�עLjN�����B���>�y�Ms���P�y,�f(�}�m;fo�Z�s?wN���B��Am����i�����z�F��lj���ԙ�p./ |�]�WH����g����^˫D�a�3�<���h'����L��|Jd���h��R���vÛ�8;"��yi�������<˺&��J�Wࢄ_5��PvM�*4wr -�#l�{H9�~4Q�q�uG^�H�����t���R�T �%�K\�.��;�祃 ��t��s�$TXT,��¿��<AsH�%~z�h�Y�rȔW�������0PU�^}��� %IȺ���j�8�7�[��i�g o�P�3F�0�q�/<g�A���m� -G�6��O*v�����̿�;>��h���e�¯��������(*�`:l5����J.�K� ��P��e�j�_���W`r -OQ�Y�)�O���R�_����xO2�2����i�c��>�f�#� [/���s�i��Ss�����'�D��58��H�~���6Y�7���H_��<����~)*�}j�a49��:����4%�D�=^B?�GF�ۿ����.�;����������-Y�eݓ���'m揂��ه ��,�E��K�F��o�Z^�^E���`���?�)�2��x�-=��q��-zO���I.�o -��Ħ -�!��R��Zpӊ�`}�I������� -�~�h��� *��"ٲ��0ŕpHmU:3��e���t$����?�!)�\���n��C��A+�E����Y=Z�PtY��H- }������)�~�"�x'�a�5$��G8�}ԡ ^W���Z%}R}�G����� -��40AE��~:���Q\�endstream -endobj 4591 0 obj << -/Type /Page -/Contents 4592 0 R -/Resources 4590 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4588 0 R +/D [4574 0 R /XYZ 71.731 331.592 null] +>> endobj +4592 0 obj << +/D [4574 0 R /XYZ 71.731 308.678 null] >> endobj 4593 0 obj << -/D [4591 0 R /XYZ 71.731 729.265 null] +/D [4574 0 R /XYZ 428.12 294.197 null] >> endobj 4594 0 obj << -/D [4591 0 R /XYZ 71.731 741.22 null] +/D [4574 0 R /XYZ 71.731 277.096 null] >> endobj 4595 0 obj << -/D [4591 0 R /XYZ 71.731 667.333 null] +/D [4574 0 R /XYZ 450.21 255.94 null] >> endobj 4596 0 obj << -/D [4591 0 R /XYZ 71.731 644.419 null] +/D [4574 0 R /XYZ 71.731 204.732 null] >> endobj 4597 0 obj << -/D [4591 0 R /XYZ 394.879 615.691 null] +/D [4574 0 R /XYZ 325.465 168.867 null] >> endobj 4598 0 obj << -/D [4591 0 R /XYZ 236.4 589.788 null] +/D [4574 0 R /XYZ 71.731 153.759 null] >> endobj -4599 0 obj << -/D [4591 0 R /XYZ 441.444 589.788 null] ->> endobj -4600 0 obj << -/D [4591 0 R /XYZ 71.731 569.699 null] +4573 0 obj << +/Font << /F33 1306 0 R /F32 1215 0 R /F27 1208 0 R /F23 1201 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 4601 0 obj << -/D [4591 0 R /XYZ 217.135 545.953 null] +/Length 2726 +/Filter /FlateDecode +>> +stream +xڍk�����- + +8��)�@p�]�u�M�ڴ��`E���\�KZ�}�))�a�����{f����w�8\���$���Ut��/~�\H�#�7ϯ�Mӻu��ӻ���"���I�p�%w���ׇ�nJ�y6O�(x���^3��}1U�x��,����l������W� �t�W� +�i��L�g)�Y�/@�h�� �<[E��E����i�;3O���-c���U�H����̒(�w�q1Bi�6��Ω�$-�وq +��fw+8G��l��������N�M[n�r�Z����z�"�"���u�`�VM7j����<�a�^���$\�SkU�M�l��ժT��V�@�"����cY0F�ʹ��`���^u~�pQs�����ҍ��ӍnU�}h�����BUՉ?8;0n�5K� +����4�DŘT�d�a� .+Ӽ0D���=��#"X@BN ��}��cY"�\�ƣ\њC�X�U_�FQp4ݞ�!&J�Է�����S��S�u7bi�B��"��s]���:�����7ŞO`������,�!n�(L��Ĩ`k�N�����4;Ɠ��j j�k\nNL �I��>0��qv{C����R�q{{�i���bgn��{�M�L!nmaؽ3Vp�'����E�� +�'P+�Y��9Xa�E�$:qYQ{'a�C��ێ!%r<�j����ma|�����,˂[��,遜�r��r�(Liu>����b�i.V,lӵf�pm�Ef�P���Eg�Ӆ��!��2�4� �8%�G��d>���)�zn�'!�n���A'F��X�,(�14*����[���u�$��}{�N�P�� �[D�j�$��p^5(���(n0�l#�S��~��e;�6�1{�f��jv���)��oA2�Z��A�G^����qQ�,q��ʣ��3��Co��9lj��8=d�W�%'!8�Ơ8�p���fI@hI3C|ת�U�h����p䜾�@�]w�����x��uR(�B2�&�PZ<��T�y����%ݢU<�Z�ʚ,�0��v�=R�d!Ƚh�>�FCp^�(ژ/�_�di�1�"�IZi�N.�GPN�b�2dm���j����:ع�(���u`�ox��.m{��p��hµ�z*�(#`����� ��I��GG�v��z� T�U�t'+�yaADp�� +�*��O����$O���/��3�f,�� V�=�OB�M�є� �<g�L��$ô:ޮ, �/���~�����H���8̅��(~n����Mc���`���?���j��e�G��r<� �w�]M�_SL��oV���:iԊ�����g�C�W:�+��-����F=z<8lT���t0y��h-��`̃4�_���������2V!��F9Y�)s�����*�G ��0xs`:^�m7�5ݘ�w� ؗ&|^�|�>FQ�Os����hw!A��,�?`A�{�ZcA�s`��˫�S�8�l0j�'�s��R]<�yPo�U�po��o���j%����4�k�L�k2S +y�ﱚ����-�x\R�D�Ѻ��xM�m<��:�E�l�d�qX��_\S�"�WM����.~���A�÷,0�S�ո(����\d9��^��c\i9�r�PypЭ��mI:�g��p���GF�g +O���Ixx/�L%sS�LS�dM�*�l|ڣ�qލ!���%PJ���.U�M��< +XLg?�n�Z���b��ɯ\ ��X>� +ǭ�4�2_v?&I +v���*p0��π\H�U?4��k�{�n=9Q��������4kq��yl[[���ܶ���x0M/�J��F5��+��|D�15O��iY�������k�xt��[U��7� �<��| +�u�74%M�����j�w_@:��(8���_3R���� �ia�8⮀�� �K��TF����>�"^н~k8���[��`Ha�&��.���Ve +���jB�^���E��:���~�1�!�}��T���A�� �B�Ĺ��� �p��BE�Op����0�I���[9L5�v�K�^{�5_q��[�I<��I +���ŶU���i�i���irY�wS-�ߣ� +�M8[�I�I��Z2b�kN��?��6�ⴗM�>�x��!�=?3A`%'6�( +�_"��D�Õ:,����T�N�ZV��F$�+�#�)��_;.���=j�"l1��3k�ٻ��p?���Ct�f�y4U��W���y\&���h�{� �~�}�{Z �����h/�>7La�x�\p�+'���~�������J��ю(b�� L�PEy��W6�5~aR�MW��Vq�����@��:�\��c4��x�s�Ə;� �0�̈́�G�!��Ms�j���]�q�U�S���㑆�����H0jm�ء��4 c��i�=�O��!#�e"NN�.N;'����ZCOݼ���|nL��졅��Xo_���D"�'K_6�3xc���ܼ�B��\� ����*��n+�G�{^�Q�n�����N�W����I��{����l���u����4��f ��U�ON<M�����g�Ș]>����>e%ă���.��XM�Ә���+��z?�M3�7�7t!z��O�\��w�����u�U������3����dF�g���ֿ�w����Tendstream +endobj +4600 0 obj << +/Type /Page +/Contents 4601 0 R +/Resources 4599 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4626 0 R >> endobj 4602 0 obj << -/D [4591 0 R /XYZ 74.222 528.02 null] +/D [4600 0 R /XYZ 71.731 729.265 null] >> endobj 4603 0 obj << -/D [4591 0 R /XYZ 71.731 502.949 null] +/D [4600 0 R /XYZ 71.731 718.306 null] >> endobj 4604 0 obj << -/D [4591 0 R /XYZ 248.221 487.173 null] +/D [4600 0 R /XYZ 353.315 708.344 null] >> endobj 4605 0 obj << -/D [4591 0 R /XYZ 439.947 461.27 null] +/D [4600 0 R /XYZ 71.731 677.36 null] >> endobj 4606 0 obj << -/D [4591 0 R /XYZ 71.731 459.113 null] +/D [4600 0 R /XYZ 378.982 664.508 null] >> endobj 4607 0 obj << -/D [4591 0 R /XYZ 142.466 420.549 null] +/D [4600 0 R /XYZ 340.628 651.557 null] >> endobj 4608 0 obj << -/D [4591 0 R /XYZ 74.222 372.533 null] +/D [4600 0 R /XYZ 71.731 631.467 null] >> endobj 4609 0 obj << -/D [4591 0 R /XYZ 71.731 347.462 null] +/D [4600 0 R /XYZ 244.777 620.672 null] >> endobj 4610 0 obj << -/D [4591 0 R /XYZ 71.731 311.597 null] +/D [4600 0 R /XYZ 74.222 589.788 null] >> endobj 4611 0 obj << -/D [4591 0 R /XYZ 71.731 269.819 null] +/D [4600 0 R /XYZ 71.731 564.717 null] >> endobj 4612 0 obj << -/D [4591 0 R /XYZ 411.009 256.967 null] +/D [4600 0 R /XYZ 95.641 535.99 null] >> endobj 4613 0 obj << -/D [4591 0 R /XYZ 71.731 216.12 null] +/D [4600 0 R /XYZ 483.137 510.087 null] >> endobj 4614 0 obj << -/D [4591 0 R /XYZ 71.731 216.12 null] +/D [4600 0 R /XYZ 71.731 494.979 null] >> endobj 4615 0 obj << -/D [4591 0 R /XYZ 71.731 191.183 null] +/D [4600 0 R /XYZ 71.731 472.065 null] >> endobj 4616 0 obj << -/D [4591 0 R /XYZ 71.731 168.135 null] +/D [4600 0 R /XYZ 71.731 454.132 null] >> endobj 4617 0 obj << -/D [4591 0 R /XYZ 71.731 145.221 null] +/D [4600 0 R /XYZ 71.731 431.218 null] >> endobj -4590 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F32 1187 0 R /F35 1525 0 R /F23 1173 0 R /F44 1994 0 R >> -/ProcSet [ /PDF /Text ] +4618 0 obj << +/D [4600 0 R /XYZ 196.632 402.491 null] >> endobj -4620 0 obj << -/Length 2512 -/Filter /FlateDecode ->> -stream -xڕko���{~�{@`���Z>D�(�p�&�����h�aM�$"|(|DQ}gvf)���+xw��3��ޕ��ß� -�=ܥp�U���_m�ˇ7�1f�2��{zs���b���W�D�t<WD�{���۹��t��?'37�;w�Ƨ��ɻv��4���O����?w�1����o���Ix�XFދBZ�)��(�2��G��}#��I9qg_�0���\��I�-�,a���(i�ˊ!I���_�s7n����V4+y�5��)��D:���.S��e��ܱ(��� q�(P^��Ŕ1Y�J�e���Q����tŒMB5��C��$V�^�Yv��*���.� -i���,#=Ѻ���Ks�Tm���B�f��9&�Z�Y��{֬g�C:1���Q�Gi\9f�{�pC�"{��"�1!d/��gx% �$8�G_�l���NR�ņ�u9���z"#��庬p�ѼnJ㭎�Ѵl�7�Q4������4�~�:�t�ț6M���ΝY����Ȧ��cWe]���8~N}��<�o�fw{s���'���w�0u�'�Iʸ�����s٣Ķ�3 Ɏ�*m�F}f�|w���/]wyF��iG:B� s�G끰�\D~h� �+�oa 3w����;���9���-�L���;8�/�IoS�����&�*��=���9̲�9�J���۪ -��L� X�����(�W��1���:�\�k���e�![�ϟV�d���yͬWk������8�?��e���|p�јo*���>�6mԳ��<<|d����^�![=e%�'�R"����n�2��8�..}��5��ۇ��$�50u�k�R�+�R��_]�J�n��&�M�'`bE�v�����"�OO�1�46�F>�cU�r�s�|�N���s?Ϝ�^�rnN��0DHA�y�E�+�A�F�&���5К�F��,#�V���A����A�}7��Du�5 ����fM�)f&"`��1i�;�y���Jw z?�V���)��ap�0#���,UB��9a� �&�B��#Xv0��_v����Uz�NW�������o���#��8�m�[���:&�~)��*�<L�{ɏ4�q�c�BrټB�倵�P�n�p� ��}3q7s�X�%���GS�G'@�P}�A� ���?N;��7�Z��Sw$)�� �7М����p�9��w�*�<}9��Bެ i��L�Z��F*`!���E�F���� &y��r����v=����M�0��;��C�-���M�R�謦qa��Ȟ�'�6�O%����}�,��eA�%�"��<6To����!3�����]�*(p��.���5���K�1$iB0.��<`�zI��MO�MUn���"#/�����[��BUl�%%xAd�(�H�k�����d!ljdJ����{��@��ݠ��9�2A�U1���SZ1���Q�m�� -(���~�� ~L}������QS�b2JŲеv�yJh��}Y8�k�3�1L�(�&���2i�sAരTS��Wh了��~d�ۈom���9-���'������OS��K�L˴' ��wᚼ�F���j|��z`*x��4U�>ۦ���V�0�( -�0�IKŸ��ن�k��uG[u�m? M��^WYHa��e�\��4]cuF�\��$��E�+�\�[���]�o�Z2�(���ۨ�{P��RDBB.?w�8���mtL�"� ;� �ϱ�G���e�#���7��u�]� '��ހʊ��f��M���4�P��W�vD��4�A���J;e����a�ns��J�n��n.�R���#�e}0 -�]��)�?���؏#��0�]h�2��}Is_x��]�.�qP��.N��]��~D�?M"P�����n�__:�- �/^>~���-�.��?f��B5"��>�zZ�\�#� ~� �ܿ[���,?��������|)��7��[.�]���5 -Z�L�����H/�ҡ�xA����o���g^�j���O.�*�d� M)��1 ���`���>ԩ�q�a��oj��]u��{���l��o�t�!�����ˉ�f�\3�3�.�Ɗ�<�D��/�kŝ.���w��ڔ��/� 'v�ǚZϥ���t~�Њo7�X�\����&����eZe����I[�|I�`t�\�lFæ���#uO�s2�qٚ�>��8,LH�1�*��ة�"�WS@���@o�Ѓ,L�(洸1!�b�ϥqi��L�K�&���M����Ci_}��^��~`���8�e�i�z��ǎb�bCH�� -��!��k�yH�>A��ðD.� %]4��3��մ�=�&1���5�����D��02�V�!9�����0�vAh�����U�"5�t���z��:C���6%���6g���gVk�m���(*�Z�D*�vx�L~�U ��ҏD$��<������g�Z"(�R^�5����t�_�endstream -endobj 4619 0 obj << -/Type /Page -/Contents 4620 0 R -/Resources 4618 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4588 0 R -/Annots [ 4622 0 R ] +/D [4600 0 R /XYZ 71.731 400.334 null] >> endobj -4622 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [380.968 693.235 433.271 702.147] -/Subtype /Link -/A << /S /GoTo /D (os-win32) >> +4620 0 obj << +/D [4600 0 R /XYZ 417.183 353.674 null] >> endobj 4621 0 obj << -/D [4619 0 R /XYZ 71.731 729.265 null] +/D [4600 0 R /XYZ 71.731 351.517 null] +>> endobj +4622 0 obj << +/D [4600 0 R /XYZ 71.731 315.651 null] >> endobj 4623 0 obj << -/D [4619 0 R /XYZ 74.222 646.575 null] +/D [4600 0 R /XYZ 74.222 261.021 null] >> endobj 4624 0 obj << -/D [4619 0 R /XYZ 71.731 621.504 null] +/D [4600 0 R /XYZ 71.731 210.047 null] >> endobj 4625 0 obj << -/D [4619 0 R /XYZ 71.731 590.62 null] ->> endobj -4626 0 obj << -/D [4619 0 R /XYZ 212.034 569.863 null] +/D [4600 0 R /XYZ 71.731 142.366 null] >> endobj -4627 0 obj << -/D [4619 0 R /XYZ 71.731 567.706 null] +4599 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F35 1567 0 R /F32 1215 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +4629 0 obj << +/Length 3126 +/Filter /FlateDecode +>> +stream +xڥْ�6�}�B�4TՈ& �O��7�:���I�v�T�"�3!�|�v���Ѥv�5&�6���)w��?w�v$��%���p����7.Cld3�y�p����NB�zح|7�c�#<;��C��u<�*/�Xo����mz>�% �t�e�����u�~�;և����|��s��Nbq�Isɥ7p�v��Nl��Lz���H��;/ ��bP#��x�}���Z�0����'�*�LVMQ=һ�d U�7(�cd;�v��&��� �ڍ�m�*{Z��%[Z�T�^Pi���a�[�@����6p�朗2�9]E�г�e�����lr����52Ѐ���^�-�I�;�&�����;z�%��:�c�e�J�zXǎ�T�T�k��i�|Z���4���xTu��kO(��f�p*@D�i��iY(VEX�8T�D��%,oe�An�Z{�u�J�j2���f��]Ki��w����fCo� p!O�t�6<��#��VCo/��e�h���6���L�1���X]K������<6R(v�rV�䤮>)�A�z������Z�]��� +#-�t["���d���A�2�c�B�d�j�Ԡ�����Gik6m�av��6���q<8��۽X�{�N����_���m��۵[L�,z�Y-w��Ɍ�3���)塙Z�-]�cs�N�V2�#ȩz�Ñ_��{drB3�o�i���[�ڽD���|�eaN�ы��'oHi�`���iے��l;����y���9�-����M�3��n~u�פ�J\�l 8k�4������vנU�g��b�~����̺\�7 ����kZu`����Tmp�6-ʆ��9�L{�,-������v�h$��b30��ac�#B)|���kh{vpAp�W��U�S$Hx��6�v&c|�����L�-�ֿ�l�C'} +ע0� ؿ�`B���]0Y7�� `�����U�c����\E��Nk��Hg���J���^Vb">,��+۴��k(�2 �l�E��n�Ф����f�Wπ +` ���u>�Xݏ�n�=?�v�G+�B2w���3i�� �#<��O6z�����qB�)9�f���8d:*��%�8���f���pc�e��"ߤz\eY4���۱`���Ӿ���[�#$T0=��3�� P�˰�pQ�Sľ� [�Zj��`�L���v?F�;A"���3 ����1W&��E�Jט9ߙ�9 �5Blb�� �����L�,{��tyVSPK�(�f�r����Pc��sc���/�fa{�v�x!�y0�{�d+����ޜ�V�����4٦�Swde�(�c-��uo���R�բ��'x�xd�ր� 0��2?�:Tt�K�X�D��mn1�bӀ)Y��-M��۴42����7��c�Ԯ�Ka�9�昡 e�ɱ�I �_Tq��3n�� Q^ׅ�F���Z<�M��;zM�G�l9�,Q��{;�M48��I�j����J=9��,y yPEu +�RFc���پ*>w�q�i)p�=LR.�F �Z�d���ݸR4�4$8 ƪ��j��U�\��A`ٴ�� ��M�fqy��M��s�ᚅ3�fɸ��FPM�J��/�x���1�@����l�ǜ.c�crcؘD��o��6�l���_��%�v�+�v-&Ld3�\dL34x.�`&�� "���9��-WiO�"�7��^�a�|�Y[Ea�5 v4ɧ`��ZU���DX����mZy��D��ж{���}!���ɴ9/�N�P_�z/�P@ ˎ��Q(<�4��G+�ח��!^���(��i��9X=���:��$�헹g�Uw�JޮoF�C/rN�F� c�^B�K�+pm/�X?�V"�Ӥ����<�*�f{-��T�c]&��u��%!\P���Y�I�`l�ޙm�nLL92��J��`<�S�LPT�FC:R7���E�t��2C�w+�).S��9o\8FHL�:���P1M�Y���;&R�l����g!�R5 :[�9��A����=��M��_�^v`W���\�X��^�؋�EM���kY�s�0��b�/Ȱ�y^����s���x��-�����^�E�W� r��g|�C�ŵ���K�cG��ʱ���dI�;J�pY+�?���a�8��Aq�7�</���uv�[��ı���~�=���w_-xqځ�����UE�ف�M\�� Bw�L�KUX@OY��F��[$�;�0��ܥ艩d��"R�'8��!���`��rƓ>Ҡ�&E lf�z�A^~��?���~��Dz���oA�f���ЕС��1S�¨R��E�|R�Q��"1��������iu���b�v�P��4���\�c.�P��P�ZВ��sƥDH-����#�"��[z@aٕ��{�L��� +����� ^�&��v#�<�Դi�C��z����ЭO�h���h�S�9��=I-b�^��Fx}��t��g���yΨ�x���{�PPc?xd���ϧ����I�i�q���_�_������w#�~x���u���?��Ƚ��!��`w��w��lT��RW����g���F�p�T�¯{/cu����GY�\�wL����d� m��&g~��e��ȶ;����9��� �ЧBk�7$@<�f�e�Bw�����,W�}��������I�L����[��;7��Z~� ��gz*9*z�Q���$py�XAb��\?�=ʩ>����A�������t���b�k'�X�r���x��v ��+8h��[@�1�l(��d�X�~�0�/�c?�n�n��J����@oظ���eLh��v�P��� }M@�.��h��oI�0<����;����T��J?]*9F��P7kt4ӱ��hl@�5cf�V��V];�X�Ls����}>�h��{˟<O�W~��-�zB��'}�x�" +���K@J���Q�Yw��R�Yr�6��%w�?j胍�5��?wGv�4ߎ«�fD�-��%�m�C1^E�<������_���endstream +endobj 4628 0 obj << -/D [4619 0 R /XYZ 71.731 520.947 null] +/Type /Page +/Contents 4629 0 R +/Resources 4627 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4626 0 R +/Annots [ 4635 0 R ] >> endobj -4629 0 obj << -/D [4619 0 R /XYZ 297.791 508.095 null] +4635 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [453.197 595.602 505.5 604.513] +/Subtype /Link +/A << /S /GoTo /D (template-specific) >> >> endobj 4630 0 obj << -/D [4619 0 R /XYZ 71.731 496.692 null] +/D [4628 0 R /XYZ 71.731 729.265 null] >> endobj 4631 0 obj << -/D [4619 0 R /XYZ 71.731 496.692 null] +/D [4628 0 R /XYZ 71.731 741.22 null] >> endobj 4632 0 obj << -/D [4619 0 R /XYZ 422.619 439.851 null] +/D [4628 0 R /XYZ 71.731 695.293 null] >> endobj 4633 0 obj << -/D [4619 0 R /XYZ 74.222 421.918 null] +/D [4628 0 R /XYZ 71.731 649.4 null] >> endobj 4634 0 obj << -/D [4619 0 R /XYZ 71.731 396.847 null] ->> endobj -4635 0 obj << -/D [4619 0 R /XYZ 300.601 381.071 null] +/D [4628 0 R /XYZ 71.731 626.486 null] >> endobj 4636 0 obj << -/D [4619 0 R /XYZ 71.731 376.424 null] +/D [4628 0 R /XYZ 71.731 585.639 null] >> endobj 4637 0 obj << -/D [4619 0 R /XYZ 113.574 358.157 null] +/D [4628 0 R /XYZ 71.731 585.639 null] >> endobj 4638 0 obj << -/D [4619 0 R /XYZ 71.731 356 null] +/D [4628 0 R /XYZ 71.731 563.148 null] >> endobj 4639 0 obj << -/D [4619 0 R /XYZ 113.574 340.224 null] +/D [4628 0 R /XYZ 71.731 526.859 null] >> endobj 4640 0 obj << -/D [4619 0 R /XYZ 71.731 340.125 null] +/D [4628 0 R /XYZ 71.731 483.024 null] >> endobj 4641 0 obj << -/D [4619 0 R /XYZ 113.574 322.291 null] +/D [4628 0 R /XYZ 71.731 460.11 null] >> endobj 4642 0 obj << -/D [4619 0 R /XYZ 71.731 320.135 null] +/D [4628 0 R /XYZ 71.731 403.323 null] >> endobj 4643 0 obj << -/D [4619 0 R /XYZ 113.574 304.359 null] +/D [4628 0 R /XYZ 71.731 380.409 null] >> endobj 4644 0 obj << -/D [4619 0 R /XYZ 71.731 302.202 null] +/D [4628 0 R /XYZ 71.731 375.427 null] >> endobj 4645 0 obj << -/D [4619 0 R /XYZ 113.574 286.426 null] +/D [4628 0 R /XYZ 71.731 372.937 null] >> endobj 4646 0 obj << -/D [4619 0 R /XYZ 113.574 286.426 null] +/D [4628 0 R /XYZ 113.574 354.67 null] >> endobj 4647 0 obj << -/D [4619 0 R /XYZ 137.584 286.426 null] +/D [4628 0 R /XYZ 149.15 341.719 null] >> endobj 4648 0 obj << -/D [4619 0 R /XYZ 214.923 255.542 null] +/D [4628 0 R /XYZ 71.731 313.659 null] >> endobj 4649 0 obj << -/D [4619 0 R /XYZ 71.731 243.422 null] +/D [4628 0 R /XYZ 113.574 297.883 null] >> endobj 4650 0 obj << -/D [4619 0 R /XYZ 71.731 243.422 null] +/D [4628 0 R /XYZ 71.731 295.726 null] >> endobj 4651 0 obj << -/D [4619 0 R /XYZ 71.731 220.643 null] +/D [4628 0 R /XYZ 113.574 279.95 null] >> endobj 4652 0 obj << -/D [4619 0 R /XYZ 71.731 197.594 null] +/D [4628 0 R /XYZ 131.461 279.95 null] >> endobj 4653 0 obj << -/D [4619 0 R /XYZ 71.731 168.767 null] +/D [4628 0 R /XYZ 349.56 279.95 null] >> endobj 4654 0 obj << -/D [4619 0 R /XYZ 71.731 143.796 null] +/D [4628 0 R /XYZ 71.731 247.283 null] >> endobj -4618 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F32 1187 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +4655 0 obj << +/D [4628 0 R /XYZ 100.623 192.279 null] >> endobj -4657 0 obj << -/Length 3090 -/Filter /FlateDecode ->> -stream -xڭ]sܶ�ݿBo�����>ҞN�N�V��n#5y�;���0"������b����<t�@`,�{{ -��������~��We�*�:��__��c�[v�=��^���W�_d����U�~�x����������t�m��nvQx�|��% ���U]�}܄a��$�����~|��n� ��~���$����2�OT��%@d��q���f�����"?̷2G�mBO�L�FQ���<���&M�^5�p�ewM�^��<Z����&J=�jq_K���3�n�|��'�A�[�����I*:w�iD�ޫU�ؿ���Q���Jd�#�`M�Z1�#Q�=�^hd�#��;��{��5-q0x�]�Q�C��ޝ4^��R�^[H��t�U�g�:rc�̧�ݑ�E>��"����I��sD%���&������ -2��Ik� �xE�PЧ���ہ�O��RV��j�E��%��+E��T�H �x�t5��a-c�0CO��Ahp�mY�^V[ڡ;Z���;B����ր�0��6B��z���04��G�Vպ �p�Mw8�2�P�Q����(��� xwT=���-)VZ�;���vh�=_3m(�^7 0�p����+J�3R:i���1G�Z��F�^�e�z���3����㐅eGr�ܓ2dz �vW��_7G�ۭ���X���}���G!��W9���X-ʮvQ�g��h#��>k�(��=FH�����}JJ�'|�H�hN�3AXO0�6��;4�k:�\�s' ���[�*��LZ����ٵ�Vw=��V�;�f�~��-O�Z�V]��|8ZQH�{�����ݎ�rs\�|F=�WЧ�ȏ�v��:�z��.���= ���3�V(�fg�,�ҭ��,u�ғ��R��A� �^��A��֏J��lX�d#�{���l܅�dSv=�N;m� �5q��]�"R�2C���2-��;�z�HZv���A��#E�'6c�CUz��]�ˋJRNj<�|+.=�nDkӓ���:�O}y�x0�C��t�D%1@�g~� -HuH�8�N��8�t�Vɨ�6Y�?��;_��n��T�>uE��g�%�����P�'���7튨F(Ky2�C�Ik�ƠA�ܚnM�o�ډf��:H�� ��q�zLQ�%F��z�� -���{u8G���:?�?�a�[��V�e�5d�� -E(]�>�ʡ�MfY�"��k�����- x�H���7��p8=�N�������'�����0K��$�&zw=%X-H�z-/���-�c�,>g�\b{/�Z�r�/O�4�p�R?�!6'~.(��8 �t�1�7�_/E�)o!��=�o��/�;U��b�<����9��U�tS4j���z@ �I��r�|˷,���%�q��o8�ܸ/)�gI�2�1��V-�*�f�Q�B��AT����-�F�Y�Z��7%b�$I{�Lݩ�jE]?�$�d�b���ȹ|���)�:/T�\��}t���-��K`A�!y�����"�}��l�����L|��������<4�%u���*����-��!)���f�j�K}�Elz��/����ML�%FșM��d�R��m�m�c���FCU������\XqMG&Sc3pl�}�������(�������G$i�P���svÖM/��6t-,��Ն��� އt6�*�A1��î -�k�ǐ��0*([�ؼ]lf+��0��BhS������Ƚ��~�AG�w9��jŏ�B�A����JY���N� ;�z���.;#�c�`騵�>J�a˦��1j[���P@�=Ͼ(qfm�0���[Vc��rv8��:� -EC���ӑ��N�����V����$.\Y��Z���g�X�١mA�WЇ���uE��nl������nq�m6�ݡZ�Ԁ��b!�j��������??��m��毘�tu;�o� �w�"DS�Z�,��{n����SNs� -T����A�����l�?2ۿ�νX�-�1�Fȱ�b{W9S&���n�_���F�����d��/̚-RV���2������B�ZxBw��|�a-�������9�u��1��~�è�����`�g����| �kE#v�q�H����,�!�OI5�w,q6 - �Rq��E8���^Tl �E���7��&��0��lO�h�y��)�֗e0�y��wtկN�+f ����ugd����22;���]>t����3����� �1i��4}?�L���/[��˫6_�O�{{�6��ވ1PR�*i�-jG�ظu���Z�����gF�����/0Q�ʂ4}+id�7]@=t[�����x;ʲ��L�H�t[3%��W\��<!v�Z�麧ڠf�Gn�me:3،Df�Ξ%��v�_��,���ԅ�+3 ���D�*'v}d�}�9֘n�-��x&]]���;��t�"��d��L-�eW�`�^��v���p�Ffi{�"|:jj8T�y��{��.)<+:�Vs���, �ՆQ -�E�cl)�u���t?�Yx��az. ax��:�(���S�}�\v3ݦ���{8�ު1�M�w�/b��w�株۞��o������N���A[���К�����7(���Di�:8�+���--1[���x�T�2��I�� �Ft�<j�(�e�<�b���������[�_2�4kd�N�:2%�B"� -��X�0!uIN���R��`?���(8�~��-k^����7o�� ~Z=��=���ՕP��z}%�O��{��ddr�1�"M1�j�C���fRLr�c��+W�\��x6{m-�ni��?Jj) KPj��m����`��0�_q��v����t�{K[dԑ�Uf��m\�%��@ӊ5 &�ƒ�x�FOf�m2��3y97�My�5 -jtq_�F� ��s�Bq�H(��{����`b}%�����F����A�I �V˳�,qT?����2�j�2x�q���� @�\A/�م�P��?�G�O�$��p����\��F�~9$x���7�-���endstream -endobj 4656 0 obj << -/Type /Page -/Contents 4657 0 R -/Resources 4655 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4588 0 R +/D [4628 0 R /XYZ 113.574 174.346 null] +>> endobj +4657 0 obj << +/D [4628 0 R /XYZ 419.902 174.346 null] >> endobj 4658 0 obj << -/D [4656 0 R /XYZ 71.731 729.265 null] +/D [4628 0 R /XYZ 71.731 159.238 null] >> endobj 4659 0 obj << -/D [4656 0 R /XYZ 71.731 741.22 null] +/D [4628 0 R /XYZ 164.384 120.674 null] >> endobj 4660 0 obj << -/D [4656 0 R /XYZ 71.731 718.306 null] +/D [4628 0 R /XYZ 222.306 100.553 null] >> endobj -4661 0 obj << -/D [4656 0 R /XYZ 493.42 708.344 null] +4627 0 obj << +/Font << /F33 1306 0 R /F32 1215 0 R /F27 1208 0 R /F23 1201 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +4663 0 obj << +/Length 2710 +/Filter /FlateDecode +>> +stream +xڥ]o�F�ݿBo��kMrI��+�6��h���pH�ER/��Gl��~���R�������������|�������Sk ��(? +���]�`��W�`�e5�������D%�^�o���h_š���?9������q��C�y�x��<�q�}+�*�՛��Ϋe�:��z}?J�Jb���g&��>J��* +�E�*�$�B�I����uC֗��,�\4� TZ����e&�)��2W��@�3�Q����Y��,�S2�^!+�`����ցr�h� +\k��*�)Af~ �/f���$���~Yz�c���x��T ���:�n�9rY*�٧��u �c�Qv>����������g!ۧ������aXD8�J4��~���������l^tFv�"`�����y��Ag����[;�CW�j�"�����ME_��� +!�����] ��7��f��SͰ�eW�r��"����\P��"�����`���v����\�/�Iwx��G�{N�s&|��#�t76t<��-�F-08e��xZ�5����c�H��(r�����ЛCڗYZUO��+�=���5�����m$X'gW����@ �7�Sj +�Wߊ��O����pCwr���!���lDz�ō�C4��iT�ٞAG�&��G�K뾣ӟ�<�}-�& +�(�N3:�f(8���o�<��$r����4�� + ���+�ȶ턱|���>�da7����U�F�1r����"J�e��O�/ + G���*fqf�h�����M�����3�� �0�`c�Ļk�Z��a�b� s���I⠜0�Y���"�MQ�;��Mm�Qe+234�����;�b�MW,��|��B�ku�b�E�d�<P�����8��.:!��LP�|����lZAɃ���� ]G�Ai��nt��PGU�8F\x��F��@7��}ӽ���/X����������Y�"����%Gw��]ݳ��_iՠ�N�⥊|����!�c����32��پ����4k@�����G�!څϟ�?�|�V��!H�v��L)e�&;���A��6�� �<��M��7�2Z^���S�џa���d����n��y�"3�Y�Y�������"�2E^\̲��"/��o���ݔ�����x�3��a8��q8��^��&�����ʪ��R������:������~n_ �T��������#?q&�"<7�p��*ƣ�`t�\�B��>T��[���{[L��=ϊ��)D��`Z��xHW���h�v:��'q�7�����UC�($ک/Y�P�s\@J���o����ϛ��+�G�����݃�%���^G���_����gw�C�+����Y�p/a��T��E[,�W�ޏ�PA����lgDVV���UMz�J逌X��� �)fS�'6mi[�Bɪ��h�+/�U��0�T�9��\PgH�|m��N���X��R���tL2t�"�GgA���מk(R�,��(�@w$6�8 �h�{>#�u�G���������2A��5��v*<��Ȫ�Ͱ�3.�l�� ���vm�>���¢��eU��9�q!�b�pPЧ�.�L��/�ԋ%-I���6��"�Q�̋��*Y�#��c��r��O`�7��t�I4v������L�q��nF1�R�T�0U!�Q��T�k|�� +�YǶ7�!�~5m���FG��^�����BTY���/����2�bn�d +����B|O�s[�ȋ�A!g�Oc��<�)�&4Q�/)Q��l�yyx����*�A9�WP҇|;���X:���2�걽�������T��-`�j���������Y�lC����p1�x5z��X�_��8B6~��w��%_��^LUn �Mkޘ�nxk;)�q��gO^v���6���!�I0 +r� ��&H�����O~���5��!��s��y�!��g�S{x�8��p�9uK� 6�%f +�:q��ײ55�K�e�`|H�I�O�~!���L�p�y(�=Ϡ���0� ��4R��Q��VE'������G�l��3CBTbyrC%�/x{R���"�}IqpƲ{^�倔A��km[L�q���ؔ�����mxLy�Nm:�j��2�����ÔW�E3"�<���HM%_93����Q8���2��:,doD��BC���ՕIѵ�rW��A����=n����*@�*������:4�6����6���j(�x��k�d��2�-S-䅫<��8��__�qT�V�(�O^�7������,���9�t�䶂t�mӋ � �2��P!l�ݼ�<��-&�u�3��X�Z'�1DztN���x�h�HSZ��f�H�'���bp��%P>Ƶ��+2�'ۦ@cV��O��I[��X�v|q�7<zۤ�J�rJ���� o�=���R��>����w�/^�H�-�����-��H����'�z�TR�csHٯO������7S٩m�"��>�w�x��Oz�V:=��P�cۉ��&G� +&��.zS�E��<�������{i��(��(�&Z���R)ٲ�:��6��-nv��J�1�aG��T���QJ���x�/U�s!�J��~��#����Ї�ַD����������a�endstream +endobj 4662 0 obj << -/D [4656 0 R /XYZ 429.405 695.392 null] +/Type /Page +/Contents 4663 0 R +/Resources 4661 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4626 0 R +/Annots [ 4666 0 R 4685 0 R ] >> endobj -4663 0 obj << -/D [4656 0 R /XYZ 71.731 654.381 null] +4666 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [204.95 685.33 269.707 692.184] +/Subtype /Link +/A << /S /GoTo /D (upgrade-cvs) >> +>> endobj +4685 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [312.894 201.715 351.505 210.626] +/Subtype /Link +/A << /S /GoTo /D (installing-bugzilla) >> >> endobj 4664 0 obj << -/D [4656 0 R /XYZ 71.731 639.437 null] +/D [4662 0 R /XYZ 71.731 729.265 null] >> endobj 4665 0 obj << -/D [4656 0 R /XYZ 71.731 590.386 null] ->> endobj -4666 0 obj << -/D [4656 0 R /XYZ 74.222 546.55 null] +/D [4662 0 R /XYZ 71.731 741.22 null] >> endobj 4667 0 obj << -/D [4656 0 R /XYZ 259.97 523.636 null] +/D [4662 0 R /XYZ 74.222 667.497 null] >> endobj 4668 0 obj << -/D [4656 0 R /XYZ 71.731 508.528 null] +/D [4662 0 R /XYZ 71.731 642.426 null] >> endobj 4669 0 obj << -/D [4656 0 R /XYZ 95.641 464.359 null] +/D [4662 0 R /XYZ 421.753 626.65 null] >> endobj 4670 0 obj << -/D [4656 0 R /XYZ 71.731 464.359 null] +/D [4662 0 R /XYZ 95.641 613.699 null] >> endobj 4671 0 obj << -/D [4656 0 R /XYZ 71.731 414.053 null] +/D [4662 0 R /XYZ 252.683 613.699 null] >> endobj 4672 0 obj << -/D [4656 0 R /XYZ 309.199 393.295 null] +/D [4662 0 R /XYZ 185.773 574.844 null] >> endobj 4673 0 obj << -/D [4656 0 R /XYZ 71.731 391.139 null] +/D [4662 0 R /XYZ 71.731 567.706 null] >> endobj 4674 0 obj << -/D [4656 0 R /XYZ 71.731 360.254 null] +/D [4662 0 R /XYZ 485.041 543.96 null] >> endobj 4675 0 obj << -/D [4656 0 R /XYZ 71.731 337.34 null] +/D [4662 0 R /XYZ 74.222 513.076 null] >> endobj 4676 0 obj << -/D [4656 0 R /XYZ 336.008 308.613 null] +/D [4662 0 R /XYZ 71.731 488.005 null] >> endobj 4677 0 obj << -/D [4656 0 R /XYZ 71.731 306.456 null] +/D [4662 0 R /XYZ 71.731 449.216 null] >> endobj 4678 0 obj << -/D [4656 0 R /XYZ 246.006 285.699 null] +/D [4662 0 R /XYZ 128.474 403.088 null] >> endobj 4679 0 obj << -/D [4656 0 R /XYZ 71.731 283.542 null] +/D [4662 0 R /XYZ 71.731 387.98 null] >> endobj 4680 0 obj << -/D [4656 0 R /XYZ 71.731 260.628 null] +/D [4662 0 R /XYZ 142.466 349.416 null] >> endobj 4681 0 obj << -/D [4656 0 R /XYZ 279.615 236.882 null] +/D [4662 0 R /XYZ 142.466 317.639 null] >> endobj 4682 0 obj << -/D [4656 0 R /XYZ 521.375 223.93 null] +/D [4662 0 R /XYZ 180.841 305.983 null] >> endobj 4683 0 obj << -/D [4656 0 R /XYZ 71.731 203.841 null] +/D [4662 0 R /XYZ 142.466 294.753 null] >> endobj 4684 0 obj << -/D [4656 0 R /XYZ 71.731 160.005 null] +/D [4662 0 R /XYZ 71.731 210.626 null] >> endobj -4655 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F44 1994 0 R /F32 1187 0 R >> -/ProcSet [ /PDF /Text ] +4686 0 obj << +/D [4662 0 R /XYZ 264.01 152.066 null] >> endobj 4687 0 obj << -/Length 2110 -/Filter /FlateDecode ->> -stream -xڕXms�6��_���55i$E�M�qS9�M^�Ľ�M��@$,��H �V~}��HI���8\,�ž<X(��/%����SOL�Q�z�0��I`$\#��d~�~rz���7����Q�^����Kc1���p��kU������{��^*&~�_���<�A윏#��u����̮��a�M��A#�̡�bg�=��za��S�5�2�\T4d$Bo - -�`Ib�N�^�d�y����5(��Rj� -�ə�o���Mi|�.�4ӿ�'�:]k�n� �V�R��+����mn�dž@��W���{��$�Q��|fN�-��̕�n���bX�*}�3��^2[��*��8p̎Y�+���О��u�\�TEcXc;��_�:��v,�X}�N+�\�EKn����q@�|]|�c���E�=#�G)c���%"�&���<�iT��v/��'4��ӱ;������k&��Iҁ�%��c�|.��v�x�~v��w�y�XY� ����y���l�S�t�[�?̪������n�4�iwOnU�������D�=S�aV�p�R�~�Ȳ��jTV�V�.-�7uDŽ� -���9W�g�^^�{s��°5�\\�N���)5#a��� �e8���yY�( ���Q����׃�e@4iY�U��T��fÌ�e���.屲y�U�$�B(���X�������Ъ ��r�l'K�� �~�6��5����F�ݲ0����~�#0f(���h�vG�ɖ%����+-k�5"ܡs�u����i`9�"��Q��3�(p�2��]�ej��T?ح�b9����I�Egpd����&G��F��~�1(��Z�X�����@S,�f]�0z?�_����< -S�`J�����~�/�^zj� M� -�V3 WM�:;_B\�lQ���VKݵ/��~��:�M>|�������S�g�f�_7u�e��=#v,4<� -�GY���:�^����[˾�ޛ�Z�*S����5dXk���A#���.��"bg�vv�h%��r�$B�g���1�!S�#�y$2�Sس��gZ��ҟVE �+�������{��W��Rh~��`UMbhը&�B�HE��Y����{��.3 �H4�D�X���!Z!G�����hP�b��;��F�ɖ*��EE����~0�1z<�`W�5 b1�G`_55���r�xd����ގA�7���!�=-2�dVZe��m��E5��LnKm�5��;t�7�a��:M�ѽIE& �E�!�v��P<Nn -Rɦ���q���f��6/��'B�qeM��3 �\�`H�$�����H�������/�K��:�<Eh(r��=���X ��^@"��G��u]�D; ��[|G/��f� ��Jຳ#�ej5N�=6qnUY�y�u�Tqb��I?��MӉ`������5i��,��͢����� -��r��qb���DZcL��l�rE�%4 �ԑy^�9�p��=�C�&I��8 ��蕅�jfB�7L�u&K�[�V� �ǒd�M�{A5����:a�F� �v�v�J��V�n��˓#��mr@��B�pޡߴ3�Z�=j��0�Úm8J�퍺�<l�%*"��Q`�O�^�F�Z��a�N�1�F�H�]p�q4h�^�-��.1zG���;er�9�m�[]Q��H no�x���]�+|v�ǟ��#�e�����!�(����џ!�����!G��Oο(��'�1u�ߝz��a�{��YE�n�H���_�=v��٢�^D�6Jtw�����T4�9�QR����� �>͝���42�T��Cu�͇��m��[ó�:�£���TL��)]�0쪂p2g�}1�$Ŋo>F%��W�р��˧��,F=�1ܮx����E��C�D��A�ۛq��#�`��ls�(��Tإ�N���#kC��@���X�a��B�\pW 썹 �7ZH���� ��� i�Ny �6R�v�Z�l��3�y�lC���iqp��"���)�z��ރxu�n��l�Ox�k���&���Ƀ���D~��E���nB`��+�O�Ͼendstream -endobj -4686 0 obj << -/Type /Page -/Contents 4687 0 R -/Resources 4685 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4588 0 R +/D [4662 0 R /XYZ 375.655 152.066 null] >> endobj 4688 0 obj << -/D [4686 0 R /XYZ 71.731 729.265 null] +/D [4662 0 R /XYZ 71.731 136.957 null] >> endobj 4689 0 obj << -/D [4686 0 R /XYZ 71.731 718.306 null] +/D [4662 0 R /XYZ 71.731 122.014 null] >> endobj -4690 0 obj << -/D [4686 0 R /XYZ 71.731 696.359 null] +4661 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F32 1215 0 R /F35 1567 0 R /F23 1201 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +4692 0 obj << +/Length 2458 +/Filter /FlateDecode +>> +stream +xڝk����� +`X�DJ�#z�4w� rm��E?$A@۴��^�������pHI~�{"G��2_���/R��"g"��mu.��� wk����|�x��}-r�'��q���d҉ˤX<�~ ��V��j-d�1z>5-��-�R����sܭ�0�����Ǜw�#2JY�E�2�q.���e.Y�E�IG���[`' +��hqT+_V��}%�UG��Ρ5=�Rm�-�U���n$���Q�kO���F��w�7M���}�T�2Gwf����v䅀�:g�7���E�b�\�ܙ�j���Ĥ0[��c{��Ͻ6C�ڒp�ړ)�b�pGk=������Cg�� �WN�"���P�Şֵ��W�3��{��-1��(��ޡj�e��I>��yj���5�{�ۡ+̳U��X���&�g��!K���������`���[�(O�F����զԴ�����'Z���+���-�r%e���P�m_��@��Qj��V�[ڢ������"K�}S��-��YO��Խ醭)����X;!玄�f��#O)�%#�1m!����a(v�1��=�7���'x���+��IP�W<D������Y���{h��������u��h����Y�|iO2�y498����6v��NW�����ca�s,HG�$F�J�=Q��r��( �enT�f&c� �����a�ҜY��0�������ؾi�F����4jW�7��U,���<��ӫ�&��e����m)9�⅄��Aѐ�����p����#����n9�b&e��,tz��y��4R���%a� :��.H�=7��$|*т�,�4_r#R��cQR]����}/2��=��2cY�FIXe��ˊ1�����$|A�A���P]7������ Et��`OJ�c��I!��y'�7���Ci� �P��2�b-��u��gHVMs�� ��c�1�')������'T��S��kͦ��H$,�s������j�b��0��O°�5ۡҵ� @�U���f���n�7�@h��JHH��\���Ozp� &Ak����4���ʦ�N\4Kq�(�\W� ��H\ʻ�����"<���W8�ق�-A5��xZ�ߒ�-�:A�dϋ9�IÕm�D&�� �t+��Ԛ����ij( +��|ek5��9+̭[[���e�T�{̈j��r���}����F�`�h�v?�tu��a3��!wDP�+���5�6���w��n�m�`�� ��ζ��U-��N۲�mc��$���@%!��]U���,�}ݝ�h5��^=�N�P>=[L|rV�N�&�����Fw <�������9�m=���̖��2*����*U�}b�N��'r I�-��φ�����/Y�ӱ!Ю�}�D�5x�n���xơ��t1y��̪�X[!�� |��d�b�h-��؇��%@�x�tYt��"�� a�o$QsO@Y�^���t �SF�c%��@3��܉��N�|�z`�]8� ���{��n��V�=�ǀ�́E�w;+?�D������ґ�j��*w��eD���-��v�wxcSQ�`<�u� ��{M B VQ��b�[b�j<R��T�X~?�!��Ί�����ѳ#�1MMݺC��ǃZى&��~���)x����Zj;��G�=HM�t�`��ֳ��P�ʩ �a���/.�ԍ����L B}}�nX��H���4�ZVf|`�����E�"O�tP������֠۸��vJGa&�������8���ގ�5QS5�����"k�}���V>��a������,�ߚ�t�c�S������n(�l&�RԞ��kf).��8��4�`��'��K�T�q�!v +�.����̋�Ν�?���c��� �#�ԭg�Lv�p�f���N��e��������L��Rf�\�:غ�pq�����5��J�,�c��&���F�ť�}��$q�5�����cyn�}����`��W#���.��e�<-��&�Zj�A~�x�x)k�+��&��Dj��$��B�1?�AG���^�D��d~~֛��'�+%:�u�u�������o/�R6���֍: =�[�l��>���*L�2���;���v������S,O�b �woG)� E������Fdh(@�;�#��l$�ȥ��so��N`�tx�#��rs���xhST-6/�R� Gد(�0��i�<#���H�}vF$A�Ĭ�/)+#���~��������n@-4�#�E��hy�艾�E!ediDŽ�j㪕m�����}���R��0�ύ>���+~��97<Sa����7X�ں�{j�`�����mz}u�v?[Ęb�WؘP.~א�Ax"�}.^�y���w�u[endstream +endobj 4691 0 obj << -/D [4686 0 R /XYZ 71.731 673.31 null] +/Type /Page +/Contents 4692 0 R +/Resources 4690 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4626 0 R +/Annots [ 4703 0 R ] >> endobj -4692 0 obj << -/D [4686 0 R /XYZ 71.731 634.521 null] +4703 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [422.465 503.858 467.048 512.448] +/Subtype /Link +/A << /S /GoTo /D (security-mysql) >> >> endobj 4693 0 obj << -/D [4686 0 R /XYZ 71.731 484.074 null] +/D [4691 0 R /XYZ 71.731 729.265 null] >> endobj 4694 0 obj << -/D [4686 0 R /XYZ 71.731 451.741 null] +/D [4691 0 R /XYZ 71.731 741.22 null] >> endobj 4695 0 obj << -/D [4686 0 R /XYZ 74.222 410.062 null] +/D [4691 0 R /XYZ 71.731 644.583 null] >> endobj 4696 0 obj << -/D [4686 0 R /XYZ 71.731 384.991 null] +/D [4691 0 R /XYZ 71.731 644.583 null] >> endobj 4697 0 obj << -/D [4686 0 R /XYZ 111.572 369.215 null] +/D [4691 0 R /XYZ 71.731 619.646 null] >> endobj 4698 0 obj << -/D [4686 0 R /XYZ 71.731 349.126 null] +/D [4691 0 R /XYZ 71.731 583.646 null] >> endobj 4699 0 obj << -/D [4686 0 R /XYZ 259.914 338.331 null] +/D [4691 0 R /XYZ 184.704 567.87 null] >> endobj 4700 0 obj << -/D [4686 0 R /XYZ 141.778 312.428 null] +/D [4691 0 R /XYZ 387.861 567.87 null] >> endobj 4701 0 obj << -/D [4686 0 R /XYZ 74.222 281.544 null] +/D [4691 0 R /XYZ 71.731 552.882 null] >> endobj 4702 0 obj << -/D [4686 0 R /XYZ 488.744 258.63 null] ->> endobj -4703 0 obj << -/D [4686 0 R /XYZ 106.431 245.679 null] +/D [4691 0 R /XYZ 142.466 514.318 null] >> endobj 4704 0 obj << -/D [4686 0 R /XYZ 71.731 245.579 null] +/D [4691 0 R /XYZ 74.222 466.302 null] >> endobj 4705 0 obj << -/D [4686 0 R /XYZ 207.151 227.746 null] +/D [4691 0 R /XYZ 71.731 441.231 null] >> endobj 4706 0 obj << -/D [4686 0 R /XYZ 171.988 214.795 null] +/D [4691 0 R /XYZ 71.731 387.432 null] >> endobj 4707 0 obj << -/D [4686 0 R /XYZ 337.682 201.843 null] +/D [4691 0 R /XYZ 71.731 387.432 null] >> endobj 4708 0 obj << -/D [4686 0 R /XYZ 71.731 199.686 null] +/D [4691 0 R /XYZ 71.731 364.653 null] >> endobj 4709 0 obj << -/D [4686 0 R /XYZ 71.731 176.772 null] +/D [4691 0 R /XYZ 71.731 330.71 null] >> endobj 4710 0 obj << -/D [4686 0 R /XYZ 71.731 171.791 null] +/D [4691 0 R /XYZ 204.252 286.974 null] >> endobj 4711 0 obj << -/D [4686 0 R /XYZ 71.731 169.3 null] +/D [4691 0 R /XYZ 71.731 271.866 null] >> endobj 4712 0 obj << -/D [4686 0 R /XYZ 113.574 151.034 null] +/D [4691 0 R /XYZ 71.731 248.952 null] >> endobj 4713 0 obj << -/D [4686 0 R /XYZ 286.733 151.034 null] +/D [4691 0 R /XYZ 194.459 233.176 null] >> endobj 4714 0 obj << -/D [4686 0 R /XYZ 291.157 151.034 null] +/D [4691 0 R /XYZ 357.109 233.176 null] >> endobj 4715 0 obj << -/D [4686 0 R /XYZ 71.731 135.925 null] +/D [4691 0 R /XYZ 71.731 221.056 null] >> endobj 4716 0 obj << -/D [4686 0 R /XYZ 113.574 120.149 null] +/D [4691 0 R /XYZ 197.727 188.643 null] >> endobj 4717 0 obj << -/D [4686 0 R /XYZ 307.174 120.149 null] +/D [4691 0 R /XYZ 328.437 188.643 null] >> endobj 4718 0 obj << -/D [4686 0 R /XYZ 388.314 120.149 null] +/D [4691 0 R /XYZ 71.731 186.486 null] >> endobj 4719 0 obj << -/D [4686 0 R /XYZ 239.479 107.198 null] +/D [4691 0 R /XYZ 71.731 171.542 null] >> endobj -4685 0 obj << -/Font << /F33 1278 0 R /F32 1187 0 R /F27 1180 0 R /F35 1525 0 R >> +4720 0 obj << +/D [4691 0 R /XYZ 71.731 150.085 null] +>> endobj +4721 0 obj << +/D [4691 0 R /XYZ 115.567 96.658 null] +>> endobj +4690 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F32 1215 0 R /F23 1201 0 R /F44 2037 0 R /F35 1567 0 R /F48 2049 0 R >> /ProcSet [ /PDF /Text ] >> endobj -4722 0 obj << -/Length 1000 +4724 0 obj << +/Length 2414 /Filter /FlateDecode >> stream -xڍVێ�6}��pч��Dc��8�L�-��C/iѢS����ؖaɝ����"�d�Mv�IGI���x�?V��R7$k�,�@t7qP��n8I,Hdq${������i���Yz҄yl����a�}��G�$��{�㦑8y���mK\��8���(��_�6?�|��{��+�.ҫN�2g^&�����,_e�*.X�e�KՋv���e�}�x�EV҈Q V�����Ni�m��HDS��$�=!ڕ/�t�S��P�"�z�q�6�`%q8Ո���D�����VV���`+D��� �s!Y���)f)�e_�D�J<��� yL��g��Ҋ�-2u�<O[M��λQ����5p:�[\�7�����k�ah�Lq��l�y�\�X��h�g��A�<���@dRvf�(rn�t<ئ#Wm�V�ˣ����N!N#���>]0����1Z(��ҳ��� '�q7�o��N��X�?� ��1�EXߙFGI>�K�L��U}���9EU�܁s>Uʈ�W�|ܳ9{鵛z�1�G�3 �-;�l2�˵�8��WP3m�`--�(�,ۖʫֺ���Δj��T��J!I�z~�Q����=�U7��o*���GN�3_]`]�nq��(H��*�9P�5��V���<��4ӿ'���J��2ٶ�Q -y��:v7[S"���%��dK*uc�}��B���d ���:7�eu���b0�Υ)u�R�� �f�w�k�#Ο�mU��ʖ.��R�q�`�o�����h��Ԥ��݉ؾ�{_ȾsE�=$ϣ��pˎr�f>8>�mK�� -��*�]u�a�%���Ӻv.�6��6>S��?~�L�8a�O�d/s�&(�_fə�� �ۯՂ����W�ػ��w�I�B��o��n��vJ F�.-�x�9����C���QYy��ӆ�I�Z��M-�s/��q�E�4�ha�R<a~��Y_�p��SD��4h�^҅��w����/+X�WW���7`�,Nf%��:���;��?RE��endstream +xڕko����� +���d �H��.�Cn/i��ۢ��n�P䱭F�j�ͥ���#˖����p8�T���*�D�ÏL���U^�qW{����)6L���|�����W�H#u�[^(��K��ru���sն��?�72t�+A�wE�����EYf��Y{^�\�����_w?���%�X������f&���R���o%�|#��:q��D8dk�:_� �x��a_eEI��n�f��M]>�ӭ=�"�����{�'z��(jݫ���1��v�����hU�����ۦ2���*�*��F�^w�����Լ�W���K� x~��z�\��yV6�zw"'_���A֘���k����T��ޫ-� 6"i�.�T�:Zf��]S��9�ߞ�����z�vg�̈́ƚ"�Z�)�m U8�,�X����x9Y�|T����npr��j�,������QY�E8n�}s�����.++�_7J^Tք�eY�W��p٫�Z�|����3e��_V��������t�yNIL�旽����s%M���r��fNE�_��;H;��Q����vJ��Z5A��K6mW$Al��/�I�HF =�|`��=���$�x(j����h��l�� H�|J7�,�������I'� b�|�e�ǦM�͚���ɑ-J�V�mc�w��Ն߶���>�L� H�{p���e�NM����;��]ڤ�W�a�!�,��i���ͬm�'B�Tf��T�g�o�a�h�m�>?��D�#�2��=� ~A'`N�[!�{��CJP��p���w�F��v�K�(�S��D���o//�ļ]T ��d^��/��L�D�/�+�� 7��h�$p���W��p��I�+��?� Դ���:y#�'��t���~��I�«��d�,eŐ�����9���K��j�Ij�Fv +��Ҵ�N@��H�z��"A��`��A��p�!٢�Z-�t[�9��>��1�:1�>���}gh�5;���J�S �a���?��4�$�$l�ּ��7�0���{��ʢ"��;��A`4�y�Je��`�������+�t��Ւ�������n���� �/�~�g[H�n���-t>hT��p��VM��M�l�*`F�fsw֛�{���;ߢ��4���W ��`��y:�_N�Z�C{�m�cG�~�mr�3B�6��=�WE��~����k�MX.�}R�?`<�0G��!��]W�Ǒcq� ������27 +�3��.����M�w��%�izh�'Z6��8A�5�S�S8�&[s2\��|a4{�a8�8�bh� >B�f���lFeS������Be�T��,���ji��ll��5���䜾S��Ӛ�yc�w;ضc_�T�b��>쨼����:.�����`��tA�ޘ�3�!�lf�B����e����\��'RhH][��\���ff0��f�-��γ��9v;F�+ŋ�f1����Fs���$6���Ci�$��=j�y���J��S/ t-��]��&�WTm��1:[�����+��;�@S���$�4�(�"g���L9��D;f�Ŭ�P/�摇1ĵ\����Ÿ�,����)����b,�Q �8}*z�w�d� ����"�D��7�]-�p�K���������;�|�d|G��Wġ}��ʴe�l�d^T��`�'���d���S��cűۂF�ą�(������ݘ@�#t�(����s���,Ys����MD��+E��c���L�f���������mv�L�����L3�sj�sF�<>�0c_+=X�P��д=' XL�+kl1q�}��~`��%���J�Ւ�"�>�}g41;J�3$��I��' +�Yr��@8V�1`��h����0��X�M���~��Ɔ�!�R���W����MyS���2�m(ӛvHOghNv�Ύ}a��/�?4L� �q� "�l1G�g�U�������9=0I���}�M"�F���P۩ +Z�\� ��C����(���W63�l�-���G��ѡ��Z�G�m�|3s��a��~������ ��#8if|��\,�6��.?/��a��O�ݥ�[��A��x9����p�5g� *l�Ǚ�������i��c��]��� ��� HԴ�2t���s7�nK����L�!�o +��`nD�Bĩ�!F_��B��3�\��,����� ���䴹�NC9y�������L`��~�J3�P��9�䋲,kZJ;�K�J9�%�Մ��C��o� �r�)�[ͳr�$I����O�4�h���e��ˈ��'�M_j��M�F���n���9�[8��?eL�%��+HD��K�;���s��KZ&(W�?���M�f��endstream endobj -4721 0 obj << +4723 0 obj << /Type /Page -/Contents 4722 0 R -/Resources 4720 0 R +/Contents 4724 0 R +/Resources 4722 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4588 0 R +/Parent 4626 0 R +/Annots [ 4758 0 R ] >> endobj -4723 0 obj << -/D [4721 0 R /XYZ 71.731 729.265 null] ->> endobj -4724 0 obj << -/D [4721 0 R /XYZ 186.062 695.392 null] +4758 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [208.787 264.145 228.214 273.056] +/Subtype /Link +/A << /S /GoTo /D (gloss-mta) >> >> endobj 4725 0 obj << -/D [4721 0 R /XYZ 71.731 693.235 null] +/D [4723 0 R /XYZ 71.731 729.265 null] >> endobj 4726 0 obj << -/D [4721 0 R /XYZ 113.574 677.46 null] +/D [4723 0 R /XYZ 71.731 741.22 null] >> endobj 4727 0 obj << -/D [4721 0 R /XYZ 71.731 649.4 null] +/D [4723 0 R /XYZ 187.785 640.897 null] >> endobj 4728 0 obj << -/D [4721 0 R /XYZ 113.574 633.624 null] +/D [4723 0 R /XYZ 71.731 638.74 null] >> endobj 4729 0 obj << -/D [4721 0 R /XYZ 71.731 618.516 null] +/D [4723 0 R /XYZ 71.731 633.758 null] >> endobj 4730 0 obj << -/D [4721 0 R /XYZ 113.574 602.74 null] +/D [4723 0 R /XYZ 105.604 613.001 null] >> endobj -4720 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R >> -/ProcSet [ /PDF /Text ] +4731 0 obj << +/D [4723 0 R /XYZ 140.184 613.001 null] >> endobj -4733 0 obj << -/Length 2462 -/Filter /FlateDecode ->> -stream -xڝk�۸�{~�X�"�N?�� m�w[E�(d�k�DA�l���3��,���P���pf8��ʍ��&�" �GeB�Ѧh���#�||##�c�"���(HD��݂�����*�(_�Q�y|����PA�y,���w�n���v���{���M}��*�3�a+}���ɘ�j��?� �&�Ldq�T���&L��T @D�ޠ��2-n�XmU�}�������"�v4�[��q�������j�1����z]o�nA蟞ܚV��0d<�P[�9 -'���Yd v)N��X����T�Df�������wr�Ѯ��"��8�V�y �0���kUh��62JF��03�����l���u�ܗ�E$q�RDhn �����E��o��8��H$�h���:I(2�%�P�t�e��ԉ��f���Yʸ�1��O--�,���vG�����o�Uҫ_��eߺ:��+�|�Ƿ�(�ܾ7��v��%-N}����o���Y��d�b/mW����W�#_�����l���M��vVr�6�xG�� ө����++.,�={j��wt�33�>�����j�:l� 1L]g�Q0X!Z@�6`��*��#�55����R8J�x�q���2�|�Q8��c��(f��j��#!z75y��5�pZا��������7���HDa���L�Yv3G:���r�£ׄ���D�(!���>�י3������h�O��G����_ID�H {�&��yU�5�jPk�/���n��*����Օ���}u���&�?Gr��(��Ho��p��DJ���E�Q���/�E��z�S�\*�#\J�@����Ɠ�k����la\�mr�#.%�|ևA�#����js�1c�w9��%`F��<��u��6��FA�o���O8���X�A�aǮ܃d�(����˃Bf1_�������Yk�0�Gl����������v'���U��m>���tkS�]��-�6� -M0�o A"���~QV��5�8����� -,C�?�����&�[�%!��8�ڕ*�>Y��`Ơ�~�i�S;�^3c�<���H$�g����;�O���� ��Bc;��\^��j@ TO�X=�kM�x6��c���@��B��}�x��/Lߔ�������� -}����x2��TRc��/Lb��I���a��!�t1 +�6�W���!|�"��z��.�� -�G����q��{��"�Z��U��h�f��P�_�v������u3��@�3S�Z'�^It��>��$���|̯9����9�U%�:�<N{��`>��C)e���>�g�i>��4�@M�X8�r�����A�n�z��]Je�K� ;Y,����Lv>�����e�$�a�á�.R����a<`�p�Z(�ɼ��Ÿ�ʊ�(�9�gv�|2|�W�"�U�ʌ��i�1�YOk+�C�ِJ�$�VФ7���*?`���?�� �ɰaYm��,���s��ӡ�F�dw��e]ˮ��.���CF�a{Ê����DХ���H�8�a���G���0�h�F���g��2�E*G@B�:�h� n���0��'��' ��rS�� -N��>��ݞz��`Kۄ��� �l#-fʢ�����`��H�hq���`T���j��3..�);Z���bMD��o`�}�� ��0C����Q{�<��a�7K+Z��=dC�BG��k�A���n�\,ܦ4 L����ߐN�1�N.�i$\P�K^;W�HQ�H�m�$/�c�H�Ss�/�FZ���d'q -��*� -��l�X��&�~��h��(u�*��D�*��Hzۡ�j�:O�LS��n���S$�I`%���ï�����H������->m�:��uXLm�pl{��%����ӳ#�ꁐ{|��#F.�]U���x�;�k��Mܴ ���O��K�Cr�� -Iz����3�]bb�msm�|m�=�5��Su���-�*�L8 ��>q��!�z$l9�|�j��1儙WR���,�(��&��z^���kya)�T����@�u^5�W��A���[h{�iq~�~���K��ǩ./�O�O���$}Ռ�<XWF�H]A����Sy��ė�"��͡�Qv���|E�b�+�D��x�g�|�U�+����[�/�B٪P���i�9���Q�x��z����A! ��Uk�K����&0[�Ɛ�dtp��qԱ� ��U�x�d;�K�ͷ&=v7�b"�%Å�U�_��C~~�@{�y�)������h����h'~gfĮr�%��Z����� -��x�CC��]��M��8���-�������� 9d���[�&�ɿغM�a�y���OV�z�ٰ�l��%tק�Kj��G��p�?��+��oF#a��(6 ����HA V��a��ggњ����5��V�9endstream -endobj 4732 0 obj << -/Type /Page -/Contents 4733 0 R -/Resources 4731 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4758 0 R -/Annots [ 4740 0 R 4741 0 R ] ->> endobj -4740 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [235.548 547.742 280.892 556.654] -/Subtype /Link -/A << /S /GoTo /D (installation) >> +/D [4723 0 R /XYZ 184.766 613.001 null] >> endobj -4741 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [355.754 547.742 401.098 556.654] -/Subtype /Link -/A << /S /GoTo /D (configuration) >> +4733 0 obj << +/D [4723 0 R /XYZ 71.731 610.844 null] >> endobj 4734 0 obj << -/D [4732 0 R /XYZ 71.731 729.265 null] ->> endobj -1848 0 obj << -/D [4732 0 R /XYZ 71.731 718.306 null] ->> endobj -874 0 obj << -/D [4732 0 R /XYZ 358.696 703.236 null] +/D [4723 0 R /XYZ 105.604 595.068 null] >> endobj 4735 0 obj << -/D [4732 0 R /XYZ 71.731 681.855 null] ->> endobj -1849 0 obj << -/D [4732 0 R /XYZ 71.731 658.391 null] ->> endobj -878 0 obj << -/D [4732 0 R /XYZ 233.175 615.294 null] +/D [4723 0 R /XYZ 140.184 595.068 null] >> endobj 4736 0 obj << -/D [4732 0 R /XYZ 71.731 606.471 null] +/D [4723 0 R /XYZ 185.563 595.068 null] >> endobj 4737 0 obj << -/D [4732 0 R /XYZ 146.66 593.735 null] +/D [4723 0 R /XYZ 71.731 592.912 null] >> endobj 4738 0 obj << -/D [4732 0 R /XYZ 441.326 580.783 null] +/D [4723 0 R /XYZ 105.604 577.136 null] >> endobj 4739 0 obj << -/D [4732 0 R /XYZ 71.731 560.694 null] +/D [4723 0 R /XYZ 132.164 577.136 null] +>> endobj +4740 0 obj << +/D [4723 0 R /XYZ 74.222 559.203 null] +>> endobj +4741 0 obj << +/D [4723 0 R /XYZ 71.731 534.132 null] >> endobj 4742 0 obj << -/D [4732 0 R /XYZ 82.138 523.996 null] +/D [4723 0 R /XYZ 433.301 518.356 null] >> endobj 4743 0 obj << -/D [4732 0 R /XYZ 71.731 490.955 null] +/D [4723 0 R /XYZ 161.15 505.405 null] >> endobj 4744 0 obj << -/D [4732 0 R /XYZ 430.969 467.209 null] +/D [4723 0 R /XYZ 71.731 472.364 null] >> endobj 4745 0 obj << -/D [4732 0 R /XYZ 71.731 454.258 null] +/D [4723 0 R /XYZ 95.641 448.618 null] >> endobj 4746 0 obj << -/D [4732 0 R /XYZ 468.549 428.355 null] ->> endobj -1850 0 obj << -/D [4732 0 R /XYZ 71.731 421.217 null] ->> endobj -882 0 obj << -/D [4732 0 R /XYZ 537.833 378.119 null] +/D [4723 0 R /XYZ 74.222 417.734 null] >> endobj 4747 0 obj << -/D [4732 0 R /XYZ 71.731 365.681 null] +/D [4723 0 R /XYZ 71.731 392.663 null] >> endobj 4748 0 obj << -/D [4732 0 R /XYZ 149.514 356.56 null] +/D [4723 0 R /XYZ 71.731 361.778 null] >> endobj 4749 0 obj << -/D [4732 0 R /XYZ 252.264 356.56 null] +/D [4723 0 R /XYZ 71.731 338.864 null] >> endobj 4750 0 obj << -/D [4732 0 R /XYZ 71.731 331.489 null] +/D [4723 0 R /XYZ 162.252 323.088 null] >> endobj 4751 0 obj << -/D [4732 0 R /XYZ 71.731 331.489 null] ->> endobj -1851 0 obj << -/D [4732 0 R /XYZ 71.731 263.994 null] ->> endobj -886 0 obj << -/D [4732 0 R /XYZ 207.49 197.767 null] +/D [4723 0 R /XYZ 254.556 323.088 null] >> endobj 4752 0 obj << -/D [4732 0 R /XYZ 71.731 188.945 null] +/D [4723 0 R /XYZ 327.124 323.088 null] >> endobj 4753 0 obj << -/D [4732 0 R /XYZ 71.731 174.051 null] +/D [4723 0 R /XYZ 499.517 323.088 null] >> endobj 4754 0 obj << -/D [4732 0 R /XYZ 71.731 169.07 null] +/D [4723 0 R /XYZ 207.161 297.186 null] >> endobj 4755 0 obj << -/D [4732 0 R /XYZ 89.664 148.313 null] +/D [4723 0 R /XYZ 270.687 297.186 null] >> endobj 4756 0 obj << -/D [4732 0 R /XYZ 89.664 122.41 null] +/D [4723 0 R /XYZ 476.12 297.186 null] >> endobj 4757 0 obj << -/D [4732 0 R /XYZ 71.731 120.253 null] +/D [4723 0 R /XYZ 71.731 277.096 null] >> endobj -1852 0 obj << -/D [4732 0 R /XYZ 71.731 48.817 null] +4759 0 obj << +/D [4723 0 R /XYZ 356.244 266.301 null] >> endobj -4731 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F32 1187 0 R /F58 2421 0 R /F33 1278 0 R >> -/ProcSet [ /PDF /Text ] +4760 0 obj << +/D [4723 0 R /XYZ 122.471 253.35 null] >> endobj 4761 0 obj << -/Length 1531 -/Filter /FlateDecode ->> -stream -x��WYo�6~��؇��Wu�mP;���t7���Z�"*����� ��C�h��&�cwx �}3�����, � 2�|�WG��V^�$ᒈ�#s�8�]��$cYNד(�Y�g�$Xʃ�b��s�4�^���p�9e�.��;�4���� -�{U�L�\�rt��h�a²4|��,H��x,����X��KYE�dk<Ɍ"����7(�XG��Q��v���<���ѽ(�� ��id[������u�s��v��{��e+�5�W��y�[%i�h-^�t��U�5R�zs����sg���������}2rrTXJ�]�D+�J�{i�${�0�Y ���Q���e'[��8�����i��P��U��A���\W��\�B_�~썟eF�@��N}�\��h�u;x(�� |n\�B7�`w�ǂ�[�OYd,IR�����x�ha ���j�+M+˽\U�m���������ȹ�e��wn�р�xi-�Zɮ7$Z�b�}'N��j �^#���r��78P5�ُ������{�ӆ��K`��Py�������oU��KcM��BU��3��6�u߂�.A�����)�V8SKL짖�-�Dp�yD0�n���|����u�����Y�I�����^|�xu~y6�)a`H��x�F��S���j9�3�k*)7XA�ڠ!�}��'����(�Ө������y�I-����ژ�GQ�9 #��W�=<���˓��=)���������gо~gu�!�.Kb�ΤO��4�����w�qR�3:�� -v��8ai��<�c#����7Z��(5_{6�O �6�I�� � UP����-Pw�� �&)Q�Ƌ�)E. t�0�OQ�Y�I{RՅ���a�d����R�D�}������S�*�YYO�l�����v]�յ���m�7�h�����/��v̓���ż�?#����W��ͺYA��,��[�����;�;��1�f��ಔیi;s:L�mZ�#5 �1��\'�9ӻ�-9e˜.e�7)��r�h�}2�B��B���8�A>|WQ��$���0��^0�����[�fP3�� -���Vf��R�·�9�T�p��V[l;]I\�@M�TghsiO�H����!KBr�V+�G�%�56�kR��ݤR�U�a���S��:�ol'/d��xC -XCwc���!�JPtm��dI���z�V$fo��;)6�z�hBqϓ���`Uk�j�͵�Jey�D*�L��D���)5sE"Nڬp`��@�Od4lcԡ��z ɏ��U�WzE��������#T{{��ߡN�$KI�!�ͽ�fL[�V�����;�Q��;9.�9�L^�q�3 @�h��v�ڞ[��;�ڱ(0S�X�7�^��b8���¬,�'�ꖆ�X�G�j�9Է�t�k�� �5�T����� Q�0�!U�~��My��^u�wyi�a��3��x^�p���x���R��w�h�҃8�o�{�Nz}C���ɣ�����P���5����>T�/&�endstream -endobj -4760 0 obj << -/Type /Page -/Contents 4761 0 R -/Resources 4759 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4758 0 R +/D [4723 0 R /XYZ 74.222 235.417 null] >> endobj 4762 0 obj << -/D [4760 0 R /XYZ 71.731 729.265 null] +/D [4723 0 R /XYZ 71.731 210.346 null] >> endobj 4763 0 obj << -/D [4760 0 R /XYZ 89.664 708.344 null] ->> endobj -890 0 obj << -/D [4760 0 R /XYZ 370.33 645.157 null] +/D [4723 0 R /XYZ 179.919 181.619 null] >> endobj 4764 0 obj << -/D [4760 0 R /XYZ 71.731 632.719 null] +/D [4723 0 R /XYZ 417.149 181.619 null] >> endobj 4765 0 obj << -/D [4760 0 R /XYZ 71.731 611.478 null] +/D [4723 0 R /XYZ 71.731 161.529 null] >> endobj 4766 0 obj << -/D [4760 0 R /XYZ 71.731 555.998 null] +/D [4723 0 R /XYZ 71.731 130.645 null] >> endobj 4767 0 obj << -/D [4760 0 R /XYZ 139.576 544.096 null] +/D [4723 0 R /XYZ 236.948 119.851 null] >> endobj 4768 0 obj << -/D [4760 0 R /XYZ 71.731 531.976 null] +/D [4723 0 R /XYZ 289.53 119.851 null] >> endobj 4769 0 obj << -/D [4760 0 R /XYZ 71.731 464.84 null] ->> endobj -4770 0 obj << -/D [4760 0 R /XYZ 71.731 442.875 null] ->> endobj -4771 0 obj << -/D [4760 0 R /XYZ 71.731 373.682 null] ->> endobj -1853 0 obj << -/D [4760 0 R /XYZ 71.731 355.015 null] +/D [4723 0 R /XYZ 434.503 119.851 null] >> endobj -894 0 obj << -/D [4760 0 R /XYZ 374.461 311.544 null] ->> endobj -4772 0 obj << -/D [4760 0 R /XYZ 71.731 299.373 null] +4722 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F35 1567 0 R /F32 1215 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 4773 0 obj << -/D [4760 0 R /XYZ 402.991 289.985 null] +/Length 2762 +/Filter /FlateDecode +>> +stream +xڥY�� ����)�̚+Q��L;�k�4�^o3�N��D������}��憐��#� �?�r� +�_��#����R�,]U�]����7wKlXd��������8^������n�D�(PO,E���S�K��x�}�|\od��OMė��_M�*�}���4x�N��������z�-H�\�E�Y#�̵��l��lX�8I����e�_�U[e4Z���(a�Y��H����2?k�����"�����=�݉���&n�?X �2�2��q:Z]�S=����-����L�651uo�F���eyɁ�G����؆-�D�;8M���,�X���U�ب��'�W]�f��0�l��c��iH���U�ɜcd!d�=C��Q�k?��ʜ�AcD�w��u���g�%b;�g��̓v��h��w�6֛ʾ1mX]c�ă�F���<%!d��+��L#g�8��es��5xvԼ���HC!C��9��$ ��ڶ��Dž(��E�^�r�:g�s8>m�/�Q0�:M�VU���{l3w"�ЬJ�k�e'ꌺ&����Ѡ�y?p�#�T���H�GM�7D�W�y�(EX��(�J�,�+��T��;��N +�|�2kb�Wd/���O��y�Ov،�rq�A�<���Q�8Q2q��� ��H,4֝̇V���./���]��Q��2���Ev��Um��������?QDž5��U�y2��<����7x��Y}���?�ږ[�Ra������Muk�p%���Ԓ52��X�����G�)K���ߞH���i����L[�ᶱ�e�;�@����R��F<`x@������ԅ�w�� M���&�0 �'lI�ui@���a���C^<Zb9�gI���5P!} ޓRt܆:ը�a<h^n�Yԥ�q"�%��;�n0l�&mC2 �Vw���P�̑�l ��e��y�E>���0]��{N[��D�W��7����}sv��s93~K���Y����ܝ��[��'=�p(�,����vG��5��gF�hfҀQ�a����H�F�.��5�S���al�Z����B��(����q#�)RUe��e<S5��_`�zV��Y����!�X�m�{��{���_Ȼ\��&����0YB�=��#L�P�y�a��6=k����@kwW���X�?�� >s<}� +��g�h1 ��nv'�0l����s`$��Q�r +,�i����J�52��o~z$�m�N6�� ��EI� g�U{�S��q@��IX�쨥�E�#[��(*�8�?�^���X��=�zxx~~�\ @�;9���\�%�H$~8A��j�qh���Ty�7Vq�" ����lb��ܢbV���u���\1De�J��h���>�K�Y��<�����4�,۩��b�::�MȁI����Q��Q�}S� +X�\�8�h�` �4���-+�Q��̖�ژ�`��d�A����p��5�Q&�W�5��H�dy]�;^_�Y˝�E=�~�c�T�2��p�k�K�|jm���*i!b����2'���]@D$"���& E���`�߿���s��ޱ�r�#yIJy��0���H����� bL�փꍶ��_�=(�΅�8 Fį�Ʃ��m��&I<R BN�5M��ӫ����^@wMS7�9n�#T����g�XD�?�|:�R�g�O\#�m9�9%r�-�����;�@�+�~Y*�0�� +�@θd%�fC��P�rI�ᜉG�#F(G��\5�;D�(*x �"˔��Ȗ�K5Ip�=3u��,�{v��O��.��7r&����$�f)~},�@����,.��Wc�c�۲|���ݯB���g�8���K��j�K�fvJ��S/�?Eq.�"Y�i�P���>���[�����w��O�{�C�HD +����W�^���ݽ�5�_!��Q�94��Tl�5��E4��*�'��01��OK���1}���!:I���Di!�R���&���=�����/2)Đw.�����#?���E]!B�������ʛ��N���HlY�з,�e�z�<cP�ȍD�f�~zx兿.\r.�����ࣥ�� rlȗ���^&�{�a�J�arЋw2B��N+�x��*�R�����?�C\��f�� '���\FVF���Z\�2Y�$�RX�jp��s�ɧX3���Ih�������FR��NU+�\1��� +����F��3��DDDP%��*0�\��vB<�XI�2�ȲC��%����/�X���sP�K$���=͇��:�,�m� F4��]���<��ق~4�vh]�$W��z.��9�<�=0�ګd���-j���D)kuw��~?'�����t��7��9t���p��`�L��g�9�������W�T���?G��Q{�m��[�B$q��A ��UKPy�!����K��$�t<bY��xb�;��F�a�����Z8'=��:�\tc������68��ݗy�l�}�W@4��+�2�3�SF�/E�/�������8W����s����]A�a^�L�(������Xd����@�/��K�W����b�����lϋӔ[���W@�,L.���_K���% �>�%�\1�f��po�x����ζَP��/����g��(��O�g��_S �Oz%��2��{�+�ٻuxendstream +endobj +4772 0 obj << +/Type /Page +/Contents 4773 0 R +/Resources 4771 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4626 0 R >> endobj 4774 0 obj << -/D [4760 0 R /XYZ 71.731 264.914 null] +/D [4772 0 R /XYZ 71.731 729.265 null] >> endobj 4775 0 obj << -/D [4760 0 R /XYZ 71.731 227.519 null] +/D [4772 0 R /XYZ 71.731 718.306 null] >> endobj 4776 0 obj << -/D [4760 0 R /XYZ 175.682 214.567 null] +/D [4772 0 R /XYZ 71.731 696.359 null] >> endobj 4777 0 obj << -/D [4760 0 R /XYZ 395.942 214.567 null] +/D [4772 0 R /XYZ 71.731 673.31 null] >> endobj 4778 0 obj << -/D [4760 0 R /XYZ 486.807 214.567 null] +/D [4772 0 R /XYZ 131.018 657.534 null] >> endobj 4779 0 obj << -/D [4760 0 R /XYZ 71.731 201.616 null] +/D [4772 0 R /XYZ 223.917 657.534 null] >> endobj 4780 0 obj << -/D [4760 0 R /XYZ 71.731 188.665 null] +/D [4772 0 R /XYZ 145.843 644.583 null] >> endobj 4781 0 obj << -/D [4760 0 R /XYZ 107.048 188.665 null] +/D [4772 0 R /XYZ 71.731 577.669 null] >> endobj -1854 0 obj << -/D [4760 0 R /XYZ 71.731 181.526 null] +4782 0 obj << +/D [4772 0 R /XYZ 71.731 554.755 null] >> endobj -4759 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R /F35 1525 0 R /F32 1187 0 R /F58 2421 0 R >> -/ProcSet [ /PDF /Text ] +4783 0 obj << +/D [4772 0 R /XYZ 394.879 526.027 null] >> endobj 4784 0 obj << -/Length 1786 -/Filter /FlateDecode ->> -stream -x��]o�6����E^cY�,��0�I����f�t�:��XDdѠ��^���;iˉ�u@W`�����e���z)���p�I�˖���v�1{b`�:g�g��Ϣ�7�'Iԛ]�F!�'l�K���ao����V����� ��اu֏cO�G���y)�B�FV�������6R�(�'�蓊�3�4�K��Ũ�{a��hl4;��&{o�,@M�;PXY��5�j��� +��,����%�t?F�Pn�~D�.�^]��z~zy>�MP.ݚ O2?N��Y!����}�Y0�mMo�5��Q@h��$�x�"bS"�������k�x&K1���@˕���NJ�e�hI"����)Z 䒐����U�%N٥�Ȩ���[�7�W��X�&�&d�?������0��)8�C/#�\�� -VJ7"�����7C'[C'���qx�wG�8�pr��ki\��r������b|��r����;lk=,�|,�a-#� -ѡ��]4��w�Ւ.��Aa0�7�����W�����䗯�$|�'�N_�zqyt���*���I��FFԫv)�j1�2J�0��w�(.�K]��]-4ϱ��Qt`��*�4)g -�(�&Z�J��[>�����VP��D�Vz��u}h��n_idr+#�ʱ���XXm�0�V�X�jU�-��9��Ra)�� �ƛ�8$���Y�ː��cIV�R$K>/-W�Z�Ȏ@Tϝzā��/�!��l���a���T�� �N��JKxZAk�9�B�"�d&� p� �v�75��<yr�0��a��kʌ�Oi{���`��Ka�'����������|:=�z�GH�2n���o�g��~:?���H�p��� ����=6������+˄��>������{��������1���i.EG�=��p~<��Υo_�U�!����]�8���&;��dx4y�ka��Z�~!��_�k���k��Z�Y^�3�n|�@J�Кڡ���kx�ʱ���.����\�pl�۽��J ൩�f^��,k�m���T(�M��Ď�`�(��W�͠�70F{�t�4��>��+5*��z�Q�ԍP8�Ft`�5_����`z=ޫ��)�ET�lv���dYrw��r�h�<}����p�w�W;���c��W�:��&�myM�Z�}3��4�����x�0NռQC�v3��w��ecQ��B�~�x'�;���v<���m7cD�$ -;�b#���֢8v�J&�`1�@��"-�D -|��eN7�b����Y�b�!�K��kB� ��c"�6�BO&1zC7�V��Ԍ�b@3��t�Ư��bn�����T�<���>@��DC`N����?X8�C�a�Ӎ��^��*��4�r]�V�V�%���FI�u�}�+{��/��I��{��d7�Ӆj��zw���h��f8� frVẗa(��!� XI����;l�I��ul�e{0<8�}�%��R͖�b��Pe�ǭ�_��]��AgQ��܁Z-�hV��d���� -�a&��ȥ�9-f�ԍ��F|i������2�ł�:|ǖ�o|B_[��n�@i&���X���1o�t�U�6�*��x[ ��w{��\Ӽ\�I�6j�^�6n��# -.[��<�!HUF��d3�[��A��&��%��잓:����Qn��v���R���U�%3��?P�D&��g��)���4/�w^z[(7��ޏw����%������,���_Y���7\�����������endstream -endobj -4783 0 obj << -/Type /Page -/Contents 4784 0 R -/Resources 4782 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4758 0 R +/D [4772 0 R /XYZ 236.4 500.125 null] >> endobj 4785 0 obj << -/D [4783 0 R /XYZ 71.731 729.265 null] ->> endobj -898 0 obj << -/D [4783 0 R /XYZ 189.38 683.368 null] +/D [4772 0 R /XYZ 441.444 500.125 null] >> endobj 4786 0 obj << -/D [4783 0 R /XYZ 71.731 672.694 null] +/D [4772 0 R /XYZ 71.731 480.035 null] >> endobj 4787 0 obj << -/D [4783 0 R /XYZ 236.591 661.808 null] +/D [4772 0 R /XYZ 217.135 456.289 null] >> endobj 4788 0 obj << -/D [4783 0 R /XYZ 71.731 636.738 null] +/D [4772 0 R /XYZ 74.222 438.356 null] >> endobj 4789 0 obj << -/D [4783 0 R /XYZ 71.731 534.274 null] +/D [4772 0 R /XYZ 71.731 413.285 null] >> endobj 4790 0 obj << -/D [4783 0 R /XYZ 321.183 509.779 null] +/D [4772 0 R /XYZ 248.221 397.509 null] >> endobj 4791 0 obj << -/D [4783 0 R /XYZ 71.731 497.659 null] ->> endobj -1855 0 obj << -/D [4783 0 R /XYZ 71.731 278.991 null] ->> endobj -902 0 obj << -/D [4783 0 R /XYZ 496.414 234.786 null] +/D [4772 0 R /XYZ 439.947 371.606 null] >> endobj 4792 0 obj << -/D [4783 0 R /XYZ 71.731 222.348 null] +/D [4772 0 R /XYZ 71.731 369.45 null] >> endobj 4793 0 obj << -/D [4783 0 R /XYZ 206.804 213.227 null] +/D [4772 0 R /XYZ 142.466 330.886 null] >> endobj 4794 0 obj << -/D [4783 0 R /XYZ 71.731 193.137 null] +/D [4772 0 R /XYZ 71.731 288.845 null] >> endobj 4795 0 obj << -/D [4783 0 R /XYZ 508.292 182.343 null] +/D [4772 0 R /XYZ 71.731 274.952 null] >> endobj 4796 0 obj << -/D [4783 0 R /XYZ 71.731 123.399 null] +/D [4772 0 R /XYZ 71.731 231.116 null] >> endobj -4782 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +4797 0 obj << +/D [4772 0 R /XYZ 71.731 221.154 null] >> endobj -4799 0 obj << -/Length 2188 -/Filter /FlateDecode ->> -stream -xڭYK��6�ϯ0r���zX���6�,f/��-�-�61����L{�z��`4�$�dU�X�UQ�W�ū]�Rh�"L�lU6��� f��)�Y���yy���K��������q�MⰈ��.M�}��^�߂�u�n+��$Y��ܾ��,���,��C����δ���_�����Qj���b�~��_s�Y��4���a�ݒb����6�v��:��?�qh��f�����k�Z1���-���ѝ5�3O8q<�j+��Z�^���u���+F�&��.]W�R9c��=�� z�������8 ��oƝכ4��q{�$� -�{�b�;O8K�����~���Ά�Ɯ�#On+;�vg#�P{��]������-���I�Y{Z���2;�^�e��1�a8�M�&����։���f�ދ85~b.�Ȅ댂��q|Áj����s�[�S^ڠs�{x�A��~�U���r\'�D��pZ'���3�ϣ?���{g�L�Kg�+G�CSQOс�c�~JsǴ����l ��T�l뺁{�j�C�� �>�-���\��EF�������M/�X`E��R�z}}P�~^��:ezYM�";�f�n0��ɴ�X=��=���z��&�Ü4��D1��8;����|@�넍�DC쟞ǫ��<��[�=�qm��i�|W�����1��Z(��b�S�t��'�Er�V�r�l�-�0\x�3/�v6�y�6���wч��75y�cd�yp�-�L��6�65�����G&0bap��h�'^�H�-� �`�M��[�⨄7��L��N�������,��j���Y#�:m9L`qe��������x�51���x ��}����A�)ַP@�ͧ[a��ť�|����1�m���?Xa�H��<��P�)��V��%Y4O�)Ho��A��L��Ð.�d���L�ZN<P�|�Y�#�J��";CK���s7�z^�&�0��kN�8�a�/1�;y�` r�_�`��q�9��-����� ��b -��q�p���"S�qLU��>^8��'I����W�4� �ڕ�W���h;�0ΩA��EG�$$�z ��L��S��d�3���*������O*6�P���-�@\J��2)�,T=`gPG��9���t�I�� r-f-��?� ���,�Z�ZSaHLp�QdC�R+�&��p��؈^�%�=���m�B@#L:ى��_���T��BdJ}�$#p��YX�U����+@����8�ʢ0I��_�=��n|��I��6��x�2t�FAI�+��&�����I�4B-h��Nw���YV�6��ܹ'>E��b-�?\�e�(F 궀쁏�j,N�Ȉ'��[��/��9]��1�����aJ+iA���_�����h�xdde��L8�[���@�7F5���˯��F�n�⦷N�˰�+o�t<�%g�^�@�p'C�˿�O-y�&�X��WnUUAbx��/����Xf����g�zƝ�K=�L���0 ϗ���%{�H9�����Gn�VPl��+9��_U���R��f�(�0�Z����ti�u��fO<�j4�i��T�<���}����ȁ"�/���.���'�!d�Ȧ}T�� Դ�O�kc谉 -�2�0BYQ���s������?�*��^r_d�M�z�I�F�K�d)���ծQ�W�6�O<��!�3���,�r�O���i/��K�"��4Á*5^Mω�������R���Xr��#��GW���X�˧�h�bd�I��,[�_0��!��:W��e)���~��>T���&h�]�?��<��,C������>�\�*^�.��dr����k*�I�ᔍ_ϒRs�)���w��葴+&�gL���������*�Z�t��'v�b�m��⪐g�BvTV�)v�z�������Sf����x�A���'�DO)�P -�qe*�L��xvVmѦ�ɠ~���=��[X�K�ͳ�I�,�܅\��h0��F��q���>�38�<� a��e�S��=����D���e9\��1i0�l��wT�q�Y��=���k�UfOC����#�}Sɻ���>○����������������{�о݇�x�� Ӓ���dF�g��)���4p/��I�Cendstream -endobj 4798 0 obj << -/Type /Page -/Contents 4799 0 R -/Resources 4797 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4758 0 R +/D [4772 0 R /XYZ 71.731 221.154 null] +>> endobj +4799 0 obj << +/D [4772 0 R /XYZ 71.731 148.79 null] >> endobj 4800 0 obj << -/D [4798 0 R /XYZ 71.731 729.265 null] +/D [4772 0 R /XYZ 71.731 128.7 null] >> endobj 4801 0 obj << -/D [4798 0 R /XYZ 71.731 718.306 null] ->> endobj -1900 0 obj << -/D [4798 0 R /XYZ 71.731 667.333 null] +/D [4772 0 R /XYZ 71.731 128.7 null] >> endobj 4802 0 obj << -/D [4798 0 R /XYZ 71.731 634.59 null] +/D [4772 0 R /XYZ 71.731 123.719 null] >> endobj 4803 0 obj << -/D [4798 0 R /XYZ 71.731 624.628 null] +/D [4772 0 R /XYZ 105.604 102.962 null] >> endobj 4804 0 obj << -/D [4798 0 R /XYZ 135.985 614.994 null] +/D [4772 0 R /XYZ 71.731 100.805 null] >> endobj -4805 0 obj << -/D [4798 0 R /XYZ 135.985 580.025 null] +4771 0 obj << +/Font << /F33 1306 0 R /F32 1215 0 R /F27 1208 0 R /F35 1567 0 R /F23 1201 0 R /F44 2037 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +4807 0 obj << +/Length 2415 +/Filter /FlateDecode +>> +stream +xڅks۸�{~�z3�H��%>��Z��\}��\��;Ӵ��D�)�G�Qt�����C����X,v��N�s'�+"/^��d��d;?�pc�(����˷�?ID���z�#��,W��^U�,W��l�-�镠q�K��n7���Hi�v溋��,p�?�������^���$��2<��d�9"�ܳ8�B�^ĉ7�/�E`�=���k|��űDI,@1;�t��^������].���_��L���Unh�h�i�E����hQִީ&'���U-�p�\�d�tzS���n L�s�e�%\d��)Ӏ�h���Q �9�M�/$j�0w=��oT�1���Lu�'�%#�Q$��IK(�����)�g�x��Ċ#ޟ���4/`ky��@if�T�fg)\��鵮 &�,'X�ad��R�u�F���:_� ��v��2��tτV�<g��XŠn�X��aI���ě^�����?|zCP�7O�%!����#�r|���p��%�u[Bt�� +�i1���E"�HB3�[1�{�k��5 C��k`�"Y�C�F�V^\�����2�0w].���3���$zFo��#._�m����\��h����`�¢�2x���j����?��� �+�d2��'��P�0�f^��Cϼ�tG_i�ٌ�2�k]���f�3ϙ���\k0s�M�Hl��|e��� +>�Rk䳖u���b�6�}j���u�99w!@a��s;SY�ռ0��uKrd���\�su�1�Rv%��Z�����pg�\{�Q�?'��2�|���Y-!N�lz|��3l������ +��J��b�S"�ú&�Ф��G!��x�^hZ>VKn�"�; � +�H>�6�+4X���ia8xk�Ŵ��mSU�)�V�����В��N(n���,�\�EA�m-�l��f��fMs&T�-0q^�B�� Z^3�,�+&�'7h2��� �)k��'AI��4�����$8��1�^�Q(?��v�'+Y��\V�$CRjY�Ⴧ�}�6�ͦ�mE{�5�.��%�)$^��S��q� ��:�y����>udU�&�-��9g�k���minԶ"�m $��%@�:-���E��/�����_G)'d:�X�±U���,��Y�a���!v�8y���P@�&�U�'����d��rV�4����ę���"���q�S�8�H������g�ql���\q���7G�FQ��bHv��]揶<'bW-�P�VB�ĂǠ$������O,v�W�O�(�DW�݆utM�G�w�l� �N���O�{Q���p)���A帘YyT�2Ȩ��n����8(I��Z��X��Ѓt���5���B���r�X��"ؓX��"2��HE��6�z����u��m����0�h�����De4O�1� +� (ΤCz�#�{1h5�Ơ��� ��Vp�l���� "T�gL����56 ����=�(��>�`�f9��uŇd� jCY6��9����� P�K�V���L���?�ž���\r(i,5�[]3�}��x4Z��BI3�#��ʶ���.9+�@m N]ۧ@�Xv����A�`L���`%h��U���!��`6\�E�R�M]H���[�8TciH���� ��C��$�'���so�g>B:y���i<��1�����O��p�dL�S|�}?��2䓻\�>��7=�`j�E+_b�hh�ORXm$�m������RYĽ���ߧ�=�l��-�v�~�H�]�Aԧ�^�Q:C6%�7*���k�s?�>�I o�����n���������;��r�3s�=!�(�7�bx��j�4��z�^�z_wv� r���EZ>��1�;��i-w�ʸ�\��o�7�v��u[� +������}��ז{8ۗ��.��0.�� +,)��C����a��$�k2@e � +0��6Na�� zt`gX�rĖ��_���4���[ìm��о�F��/|E�뢅'JW�nO��נO�*x��יd�������}L��/����w\� +r���8����s~���_����9���rU�n8���6֠����Mdu�镺98�n�Vg�,�_��,Tf��5���um� +�s�Ϡ�<�߽�����ELE���8�O��i1�\�hTobnpb?e]��]KG�ᘟ0fpp�M�Q�:���0�k�H��GSs�S��B������.y������N����̇3�Y8�+R$�Y���4��*�܀���o�c�?Wi����l�e|V���������x��gZ�q)��.���������a?At^�M!�O=�x1B�R�:���KI�؍��-e@9�)e����:"x�d��/"���ҭendstream +endobj 4806 0 obj << -/D [4798 0 R /XYZ 71.731 523.437 null] ->> endobj -1901 0 obj << -/D [4798 0 R /XYZ 71.731 484.483 null] +/Type /Page +/Contents 4807 0 R +/Resources 4805 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4836 0 R +/Annots [ 4826 0 R ] >> endobj -4807 0 obj << -/D [4798 0 R /XYZ 71.731 449.684 null] +4826 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [380.968 299.612 433.271 308.523] +/Subtype /Link +/A << /S /GoTo /D (os-win32) >> >> endobj 4808 0 obj << -/D [4798 0 R /XYZ 71.731 439.721 null] +/D [4806 0 R /XYZ 71.731 729.265 null] >> endobj 4809 0 obj << -/D [4798 0 R /XYZ 135.985 430.087 null] +/D [4806 0 R /XYZ 105.604 708.344 null] >> endobj 4810 0 obj << -/D [4798 0 R /XYZ 135.985 395.118 null] +/D [4806 0 R /XYZ 71.731 693.235 null] >> endobj 4811 0 obj << -/D [4798 0 R /XYZ 71.731 361.843 null] +/D [4806 0 R /XYZ 105.604 677.46 null] >> endobj 4812 0 obj << -/D [4798 0 R /XYZ 181.691 348.892 null] +/D [4806 0 R /XYZ 71.731 657.37 null] >> endobj 4813 0 obj << -/D [4798 0 R /XYZ 485.889 348.892 null] ->> endobj -1856 0 obj << -/D [4798 0 R /XYZ 71.731 315.851 null] ->> endobj -906 0 obj << -/D [4798 0 R /XYZ 517.296 272.753 null] +/D [4806 0 R /XYZ 213.2 647.87 null] >> endobj 4814 0 obj << -/D [4798 0 R /XYZ 71.731 260.315 null] +/D [4806 0 R /XYZ 213.2 636.214 null] >> endobj 4815 0 obj << -/D [4798 0 R /XYZ 71.731 244.773 null] +/D [4806 0 R /XYZ 71.731 596.663 null] >> endobj 4816 0 obj << -/D [4798 0 R /XYZ 71.731 187.269 null] +/D [4806 0 R /XYZ 74.222 578.73 null] >> endobj 4817 0 obj << -/D [4798 0 R /XYZ 310.001 176.474 null] +/D [4806 0 R /XYZ 71.731 553.659 null] >> endobj 4818 0 obj << -/D [4798 0 R /XYZ 278.636 150.571 null] ->> endobj -1857 0 obj << -/D [4798 0 R /XYZ 71.731 104.579 null] +/D [4806 0 R /XYZ 71.731 517.793 null] >> endobj -4797 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F32 1187 0 R /F23 1173 0 R >> -/ProcSet [ /PDF /Text ] +4819 0 obj << +/D [4806 0 R /XYZ 71.731 476.015 null] >> endobj -4821 0 obj << -/Length 1278 -/Filter /FlateDecode ->> -stream -xڍV�n�6}�Wy�x�"%�ⷸi� �6[ESZ��U�%]l��w��w[職ùp�̈1|<�9�D�D&�zw8��bA���fu�|�$A��, V�A*8+y�`����3|��J7�c�2o��H�p�R�yݩqk���M����W�2�YY$��1�,I�s&���yc��p�ݰ�Y�����di�Zd��6b�iu�Y�ix"�(X*6F��r��"w".�\�=� ѫ���B5��j�����)+8�'K���~�Hf�Oo�3�9��1<)>r?�u��������dpՄg!�{��!,n��6�[w8S��\oqVэ�W�n�V$�����3����F�}|q��6t^�4�3<a�"j�T&H��p.�s&pP�3��tn�m_�[uu��am�k�7�iێxg�ǝ�i���2( 6�����R�.Q�,�9ᦃ�j p�����TY��3��T=�a��*}�0ϙ#�k5�GE�픞Z��0��I�1)-'YIi $8��r?A�Ĭ鋩J��3�Ȳ31V�p�� &X���v�r�د���W�������,��- v����Uu�y�6����hP���q�j�懮�Dž�$8��ד�?\��~*�|�x������L�6��f5N�ެ������s�a��1��?�� -S �Eap���o����+�µ��Ȧ��5��0a���y��#U����/fhpS�z�����|́��)2硝�8�����G����x�v�,��UL��X7ﮯw��[�Bg,��jg�� .*�֞2�������j�K�z�h�e:[�\-���=��p�i ����U:8�7� �ЊB��kI\2��^��];��гR eY����Rr���]���UTѿ�2v<J��y$�YO��6��b���>��r�{JK�1����>�;�Ġ|����x���cg�dx�`���rϿ4�I{��0������l���� -���$����16��SQ��q�\���r+�a$(a���0�Zn������#�]�Z!�������/#0�"�g@���4;B��Zᢥ�'���y}$�f���;{�T�+�vZ����~\Q�:rE��.Qq��3k�j)�'GX�w�GE��.�O������5N���_/����c����1���K��K����������v�y�۴�����?�'ȳw) -/�^�����_���endstream -endobj 4820 0 obj << -/Type /Page -/Contents 4821 0 R -/Resources 4819 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4758 0 R -/Annots [ 4827 0 R ] +/D [4806 0 R /XYZ 411.009 463.163 null] >> endobj -4827 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [81.972 630.825 141.748 637.679] -/Subtype /Link -/A << /S /GoTo /D (http-apache) >> +4821 0 obj << +/D [4806 0 R /XYZ 71.731 422.316 null] >> endobj 4822 0 obj << -/D [4820 0 R /XYZ 71.731 729.265 null] ->> endobj -910 0 obj << -/D [4820 0 R /XYZ 107.109 683.368 null] +/D [4806 0 R /XYZ 71.731 422.316 null] >> endobj 4823 0 obj << -/D [4820 0 R /XYZ 71.731 674.545 null] +/D [4806 0 R /XYZ 71.731 397.38 null] >> endobj 4824 0 obj << -/D [4820 0 R /XYZ 71.731 654.67 null] +/D [4806 0 R /XYZ 71.731 374.331 null] >> endobj 4825 0 obj << -/D [4820 0 R /XYZ 274.373 643.876 null] ->> endobj -4826 0 obj << -/D [4820 0 R /XYZ 390.766 643.876 null] +/D [4806 0 R /XYZ 71.731 351.417 null] >> endobj -1858 0 obj << -/D [4820 0 R /XYZ 71.731 625.843 null] ->> endobj -914 0 obj << -/D [4820 0 R /XYZ 452.394 558.309 null] +4827 0 obj << +/D [4806 0 R /XYZ 71.731 294.63 null] >> endobj 4828 0 obj << -/D [4820 0 R /XYZ 71.731 546.137 null] +/D [4806 0 R /XYZ 368.08 283.836 null] >> endobj 4829 0 obj << -/D [4820 0 R /XYZ 71.731 523.798 null] +/D [4806 0 R /XYZ 74.222 252.951 null] >> endobj 4830 0 obj << -/D [4820 0 R /XYZ 437.99 523.798 null] +/D [4806 0 R /XYZ 71.731 227.881 null] >> endobj 4831 0 obj << -/D [4820 0 R /XYZ 71.731 503.708 null] +/D [4806 0 R /XYZ 71.731 196.996 null] >> endobj 4832 0 obj << -/D [4820 0 R /XYZ 130.401 467.011 null] +/D [4806 0 R /XYZ 212.034 176.239 null] >> endobj -4819 0 obj << -/Font << /F33 1278 0 R /F23 1173 0 R /F58 2421 0 R /F27 1180 0 R /F35 1525 0 R >> -/ProcSet [ /PDF /Text ] +4833 0 obj << +/D [4806 0 R /XYZ 71.731 174.082 null] +>> endobj +4834 0 obj << +/D [4806 0 R /XYZ 71.731 127.323 null] >> endobj 4835 0 obj << -/Length 3012 +/D [4806 0 R /XYZ 297.791 114.471 null] +>> endobj +4805 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F35 1567 0 R /F32 1215 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +4839 0 obj << +/Length 2452 /Filter /FlateDecode >> stream -xڝY{�����>����x|SL`��&8M�Q�I�+�9��GΗ�߽�ٙ�����q�������sG���?o�xN�㧎G���rW�|q� Eǎ��/Ln� q�]��.8|~wu�7?X��G��n?���ī�������M^~�l�d�~�ȷmƾ���x�X$��I�8��-6Hd�]�{�a�V$k��f��u�p�穩�x4����g��x����kYU�T���m� ��XZh(�V;�@��k�F}���/�u��ͫ���曻���l�5�rs~K�ԓ�y��ll��M����(E�se+��m6m��jD�F�����!N�nFZ��е#;+/q|/�k#�34^;�|�u��|[��f�[���﮳����6���*ӗ��9�{�� ���a*G����]c���i,�r,���}��"�es��BmDշ5C85�t&�Aȵ���� ���0��(��4�"0�el�7Y��K;����_��L�Е�,��c�k�b+���n�%�|r�T${?��Ɂ|�s���Iҝ^�s -����t��a<g������剝]��<�X|�0�z�9�x^�DI��z�ģ������U����~������I��4 V�^���^};s�Y�3L���3[+�6��&��q^�![��92 -ws���&$�6d����xI[o�;;��;�8�8 �}�A��m�F�b;'@�]���W%A��M�&��U?0&o�S+����l#�#.���3��J��x͵�0~�P~!�eM+�i�����T�.b���?��0p�`� �7���C��z^��d�������[�D^���$_6��:�h�����#�Z▾�1 -]�lT�e�(��D>(���§N��N-T��~Χל_D�e�����C���s�!�75!�tͣ��o9ʸh�*g�^�����(�:/�d�ȩ;��JP���T���y<��(��Ʋ6I���#�ډ�zd�Z=P�����k+��bjR�D`���ܑ+��V����,Z����|��{��q��s���9��{�v8�k��n.��l�P��*�Y_v#�#n�o�&���O�-2,���e�x?({�������x�9U����o��A�R�w�x��itxp;��S��)x���+�u��*�Yg!3��<�)+x�=��ʷ��m+�K����w��]�4+��>/H�� ��1 ��*��v�o���<4:ۗ�u��1t��~��g����y�T$�щK�E��^�z������u6A����ez4Z# -�~-ゐ�^��v� ��)��\� ]�h�Gʪ�r,�ms�&�NM8l5��͝��d��͈�ʃ_US-�G0X�,N,R҄]���7����۷wLR�_ʾm(�0��f���#Pw�渍�����D_��is��:��B5+����ùJg5Ŕ"��o���rUY���~,��A�� (�"@����03*�P�D�d���Y6����V��-�O<��^@&b�*+u��q@t�2R�y�a��6���8��|�rӃ��Id��d�����L�)@���{�rEɗ��p�ۙ��C�(Q�iF��Khz�~,J-��TU ������*< -�En؛J��H�`�]�1%g,?�Ez�%1sDZ�WyN>���nn"����e��f(Ʊ���F�7iũ[��0�����7��/2���_J��8�&�z�H�-���=�ecL��G�1D�?�9m� �{�������#T��ZvܷS�;�nMwa���A/x,��)�����> .%RdQ��x�ӡK���0u����i����&H���� o/����d�dٿ��<�%����O?xA���/.<v�(K�y��%gԙ�ԓ\�`O[،rhۜ�|��J'e7?�N</�����x����ذ�W�勍='����r�>F�a�)ƺt>�݅V<$�k�G-��EI���h���[m�V�`�m�h�B�hm[}���xv"�R4 t3��tkN��.�N�aˡ7No�����8N�V��P�9"��_h��)�EZ`^2�ȥM�3�����~\L�?�B�O�at{NG��7�x�ɲ�Ge8I인2"q�k�*+������\�Ɯ���Ħ�I��5fB�ɳ�8������`@ҙ��JVͯ-���vl��DǶE8��%h�q!o*d��q�F_r�[Y���:Q��Rt�o Ok<w�VB�A�V)�\�/�@jx�в�\<�]�㊿�t�uR���P��-������uuS����<%��x����OY��G �\�]�Gjc6�1�r;|'LN��C�L -��A�����ը�� ���)n�����.sFR��L�:oe���e^��B�Ł�a(pe�l�ѲQ��z�+�D�z4M���q���y�&���Ѩ�s�����eȬ�`0�Z9�c�����<_�4��i��"0^���L���^�?������ݲe���4R5GO����M�-�m �k<�j�#����� H�k똹���|8}�����{�2\�S -��B��hÆ�M^f�u�\v�i�c���K��*���1$4�6��T�Y&�Bg��� �T� �?����@"��%�����P�_x�e��̥ɯ�C͠^4~"#���}#S65D+�ɥ�-?.l"��Y5�ڔ�Qd��-�ɜ��'�k𰵞!���,#�D�VZ��0/��RO�Q:%0����v��hsz�ez��ɡ��K��ך�܂r�5Ms��\.�mz!G�l��98)��nP���}��'�Df�ç܀�[��cB���8Y��p�wٱ�n8���ɑɎ��0t��5/Ѝ�%1_ -��v���d�4�P��a(��Z�`�����Í��T��,�y�M�4`���ȵIOo$�P -���������Z�� ��N��JD����i��;g�%��푄;��|j٧���sݳ�%������&`endstream +xڕ�n��}�"/��u��-�"�4{r�]���C��#3�ݎ.'�~}g8CY��$E���ʹ��W.�ɫH�ȇ�[o^%�'�j+_?I�X2�r��e�������b��6�W�E�t|Oġw���۹�*]lӟ���q��4�����f�������s3\���l~��M/A�Gb�o +iqN�����\��� �� �"7~)x���[��uUUY��6-���/���F螗Z��-z�њt������I>���@��i��p]/�?��E� L$c��]D��k�S��ӗ#�i�꺪5����#��`���bF�"wH���rc�L/z(;���n�������TyX�\�K�{8����g)Mt�3`Z�������D�Z�k�deL�r�����?�,����+�A�ٔk8� +'{1vuj�Й�*���F�4e�*�tK�״ݳ�����f���@���M����r�L#;���� ��^;}�~[�(J�0r�gZ��i��p�@��_�H��F��;��A;2�%0,!$}�|^^�s��M�5-}��em�P���O���c��GϘ�V 9�nfL�Y��M�B���S�v_�����������K<}����RMY�>\3��,��/#���D��?� G���~ +�������h�����Ǵ �=��*,�:��+��K$�S�Q%̼S���T�j�Ο�K�n벣�����f�`m�G���v�n�������ɓ�i���q#�*{�@l��*�B���B���L��ʈj�j��>#R�Vˮ�&��(�PI�հf+���>|��I��b%�\Ʈp��e��,H�L}1!��Hq�N�"��s��=�y���0��5m��S���>__����W���('CxK�����8]�}�h+O�k���.�qPj��N�}�ho��F���,�R��?�B��w�qD�l�A����8e�{��~B�-��|�C���j�%[x+��mqD�l�Aa�˶8e�[��~B�o�1���3��|vQ}薽u���G���3�/����O���PM#���o=�W^��kPZ4�����~����e~h�`����J��X������:y1�FA�&�����6 ��L��)�7�QՁ�8әRM��0���=2�8���B���K�T*yQ;+Pf�P?f�&O�C�}"T��f0��@ֆ�ݴ6k? �Y_�3m��5x�����s���ŝ,���i��^�+�O���4� �>��r.�]�9�@g��}`�s��֍�ٙ?��o��� +H��'�fKv%���;׃LIRv����F'|ӅӡxPXr�?��]S�"������(�;;� �0��mq���>��HÌ�`�|�тIRx�s�<w�@�3����=��ot�f�Uʺ3��N�]ɞ;l���a�BS��.}sX3 >M��8� �m�%�p��$h$�"I��AD���)Eә �yF����ƭn�]ad���#:D��w]��0�nA�vo&;�a]���L9ݓ`A#��W�၃�� �6�]{Ʊ�z`�rd�F�}K����f�{{0�Ëb�L�� zj�@��Xe�z����ǯ�U�>/���� Xv���ѪN�D��-('^,�ܴ�N7UdZV!�b� ��|6 ��n�K��fi�����=�fK�!j�#kS_�hH�+dD�4�8k��O�Ó|qFpɣ&t�4KU͐.˖����|�뫌n����yF-A�͞y��w)^��hx�tBg��!S�G��)R�]9�B���ҋWJ�*�.������\8z�J!�\��b�ES�(�vI˰��a��b}(+],��l�vAx�qs&� +���\���@r^0��mC�vo0��5��bTSB����"tGPz'���HrY��RYl7�`�`# +U�&�k���<W�aƲ������1�0�8!�6�3'��@���b�|���bJ[�k��)����1NY\����x������-�}�6j��btekB��I���_*[��A��EZwz��^��i'�x^(�����z"~$��c*���x��ClZ?�l��l�W3ږ�� +1��������a`����Y3`�Q��l L)dmFoq�J���`�W��E��z�����rI�����5�I�iT4d���Ӯ�eM��ڱ���RP���5��uF��j拻�3�J� ^͎����#�6Ƀ2��U�|I5�M�v���I�}ݧ&�ztFLS|\M��d���R� l�#SM�` +�=��#�%�ZZ��@� ��F�L��� ����n�Q��2�)i����}3�4�ة7������F��d�U�Zm��[o&qk�(u3+$V#���?���e��mG����B/��� +o�����)��Ѹ mendstream endobj -4834 0 obj << +4838 0 obj << /Type /Page -/Contents 4835 0 R -/Resources 4833 0 R +/Contents 4839 0 R +/Resources 4837 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4758 0 R ->> endobj -4836 0 obj << -/D [4834 0 R /XYZ 71.731 729.265 null] ->> endobj -1859 0 obj << -/D [4834 0 R /XYZ 71.731 718.306 null] ->> endobj -918 0 obj << -/D [4834 0 R /XYZ 271.435 703.236 null] ->> endobj -4837 0 obj << -/D [4834 0 R /XYZ 71.731 682.175 null] ->> endobj -4838 0 obj << -/D [4834 0 R /XYZ 297.998 673.5 null] ->> endobj -1860 0 obj << -/D [4834 0 R /XYZ 71.731 660.449 null] ->> endobj -922 0 obj << -/D [4834 0 R /XYZ 365.87 615.294 null] ->> endobj -4839 0 obj << -/D [4834 0 R /XYZ 71.731 606.471 null] +/Parent 4836 0 R >> endobj 4840 0 obj << -/D [4834 0 R /XYZ 457.285 593.735 null] +/D [4838 0 R /XYZ 71.731 729.265 null] >> endobj 4841 0 obj << -/D [4834 0 R /XYZ 199.72 580.783 null] +/D [4838 0 R /XYZ 71.731 718.306 null] >> endobj 4842 0 obj << -/D [4834 0 R /XYZ 258.499 580.783 null] +/D [4838 0 R /XYZ 71.731 718.306 null] >> endobj 4843 0 obj << -/D [4834 0 R /XYZ 315.525 580.783 null] +/D [4838 0 R /XYZ 422.619 661.719 null] >> endobj 4844 0 obj << -/D [4834 0 R /XYZ 71.731 578.626 null] +/D [4838 0 R /XYZ 74.222 643.786 null] >> endobj 4845 0 obj << -/D [4834 0 R /XYZ 118.555 540.062 null] +/D [4838 0 R /XYZ 71.731 618.715 null] >> endobj 4846 0 obj << -/D [4834 0 R /XYZ 71.731 509.785 null] +/D [4838 0 R /XYZ 300.601 602.939 null] >> endobj 4847 0 obj << -/D [4834 0 R /XYZ 71.731 509.785 null] +/D [4838 0 R /XYZ 71.731 598.292 null] >> endobj 4848 0 obj << -/D [4834 0 R /XYZ 71.731 490.079 null] +/D [4838 0 R /XYZ 113.574 580.025 null] >> endobj 4849 0 obj << -/D [4834 0 R /XYZ 165.11 477.128 null] +/D [4838 0 R /XYZ 71.731 577.868 null] >> endobj 4850 0 obj << -/D [4834 0 R /XYZ 71.731 469.99 null] +/D [4838 0 R /XYZ 113.574 562.092 null] >> endobj 4851 0 obj << -/D [4834 0 R /XYZ 71.731 469.99 null] +/D [4838 0 R /XYZ 71.731 561.993 null] >> endobj 4852 0 obj << -/D [4834 0 R /XYZ 164.065 446.244 null] +/D [4838 0 R /XYZ 113.574 544.159 null] >> endobj 4853 0 obj << -/D [4834 0 R /XYZ 210.352 446.244 null] +/D [4838 0 R /XYZ 71.731 542.003 null] >> endobj 4854 0 obj << -/D [4834 0 R /XYZ 352.569 446.244 null] +/D [4838 0 R /XYZ 113.574 526.227 null] >> endobj 4855 0 obj << -/D [4834 0 R /XYZ 442.661 446.244 null] +/D [4838 0 R /XYZ 71.731 524.07 null] >> endobj 4856 0 obj << -/D [4834 0 R /XYZ 203.715 433.292 null] +/D [4838 0 R /XYZ 113.574 508.294 null] >> endobj 4857 0 obj << -/D [4834 0 R /XYZ 372.061 433.292 null] +/D [4838 0 R /XYZ 113.574 508.294 null] >> endobj 4858 0 obj << -/D [4834 0 R /XYZ 71.731 426.154 null] +/D [4838 0 R /XYZ 137.584 508.294 null] >> endobj 4859 0 obj << -/D [4834 0 R /XYZ 460.217 415.36 null] +/D [4838 0 R /XYZ 154.042 477.41 null] >> endobj 4860 0 obj << -/D [4834 0 R /XYZ 71.731 382.318 null] +/D [4838 0 R /XYZ 71.731 465.29 null] >> endobj 4861 0 obj << -/D [4834 0 R /XYZ 71.731 382.318 null] +/D [4838 0 R /XYZ 71.731 465.29 null] >> endobj 4862 0 obj << -/D [4834 0 R /XYZ 237.451 371.524 null] +/D [4838 0 R /XYZ 71.731 442.511 null] >> endobj 4863 0 obj << -/D [4834 0 R /XYZ 71.731 358.572 null] +/D [4838 0 R /XYZ 71.731 419.462 null] >> endobj 4864 0 obj << -/D [4834 0 R /XYZ 220.87 345.621 null] +/D [4838 0 R /XYZ 71.731 390.635 null] >> endobj 4865 0 obj << -/D [4834 0 R /XYZ 71.731 338.483 null] +/D [4838 0 R /XYZ 71.731 365.664 null] >> endobj 4866 0 obj << -/D [4834 0 R /XYZ 257.124 327.688 null] +/D [4838 0 R /XYZ 71.731 329.798 null] >> endobj 4867 0 obj << -/D [4834 0 R /XYZ 358.713 327.688 null] ->> endobj -1861 0 obj << -/D [4834 0 R /XYZ 71.731 320.55 null] ->> endobj -926 0 obj << -/D [4834 0 R /XYZ 462 277.453 null] +/D [4838 0 R /XYZ 493.42 319.004 null] >> endobj 4868 0 obj << -/D [4834 0 R /XYZ 71.731 265.015 null] +/D [4838 0 R /XYZ 429.405 306.052 null] >> endobj 4869 0 obj << -/D [4834 0 R /XYZ 117.29 255.893 null] +/D [4838 0 R /XYZ 71.731 265.041 null] >> endobj 4870 0 obj << -/D [4834 0 R /XYZ 427.895 255.893 null] +/D [4838 0 R /XYZ 71.731 250.097 null] >> endobj 4871 0 obj << -/D [4834 0 R /XYZ 71.731 224.91 null] +/D [4838 0 R /XYZ 71.731 201.046 null] >> endobj 4872 0 obj << -/D [4834 0 R /XYZ 173.632 212.058 null] ->> endobj -4873 0 obj << -/D [4834 0 R /XYZ 420.183 212.058 null] ->> endobj -4874 0 obj << -/D [4834 0 R /XYZ 71.731 166.065 null] +/D [4838 0 R /XYZ 74.222 157.21 null] >> endobj -4875 0 obj << -/D [4834 0 R /XYZ 71.731 122.23 null] ->> endobj -4876 0 obj << -/D [4834 0 R /XYZ 71.731 122.23 null] ->> endobj -4833 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F44 1994 0 R /F32 1187 0 R /F33 1278 0 R >> +4837 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F32 1215 0 R /F35 1567 0 R /F23 1201 0 R /F44 2037 0 R >> /ProcSet [ /PDF /Text ] >> endobj -4879 0 obj << -/Length 1514 +4875 0 obj << +/Length 2573 /Filter /FlateDecode >> stream -xڵَ�6�}��@"!+�H�A`�m�-��� �ざh[�L�:��C��3ʖw�HR���p.�%��㋌�,�EL�ɢܟ��-��t�E��L$�g�$�X�G�`������G-D�ҤX�6)a�D�.V���e�*]��~ �ܻ��c�H���eC�k��i�P���3:Y�-�5����A�@�,O�����F�xbu�<A]�.,�2KG�9;���%MW�E��4r7g �7�Q��{f$@+U4\�W��\���;�h#5X�<�i�j�:��Oϑ�/�6�0?��V��+�ҍ��vj.�౯�֩9�7��DжF&�>O<��@}�v~�����~��$�ze}wN;�+�v��S��=m�r[�ֺ�z�s>��3fxE�%��pz��ѫ�e��nFQ�)�@h&y�H3���0��Ϸ�'�f���ul�����q 8���zyeu*�1nm@!��Im�F��/pϾ��x~3U-3����`;eڔ���`i/�8����}o��(�g��G��| ���3]�:1�#�y�ٷ5f"{3v��KS9h�A��c�+�ir�����e7w5V�4ޱE�(TX�v�HZ^�����Ui��j�"�$��z�(͡��F}|�"�"1yx⌉��"�'��vֲۺ�z��� ��n�3��t�k�ۚ�Go_�$�^b~ �Z�:��}��eO��tG6> -* e�+��B�D6`�$�z�I���+!^@�NJ -������t穣��V Y7r���)��̞�!���$��.}ė������rG �E@��`Y=TA���QA�֥�`'�� #�ʖw���/3�q�lM����'s�\�X�UC�맡�P��9�i勂��ɁBv��텰�� -\�T�q������rt�����cµNzm�:�!Xb� ��7�*�@Dw|����k�۶&{���uߏ�c�tɽ F�i�g�`��v=W:�)�Q�H��1dԉ�TN;�ʭ�`4��¡gyE�a(5�I8�lY����)�V�(���N<1Um,i��z9�|����E�T��)<#��f��O�Z�xq�U���PSKĦ��^���^?3�Yƒ�K&0���M���j�+¼3��Op���0ˉ�1dBd_�)Ϝ���Z�7ƺ�f�~��-ig4��5��{�D�5iV��ō+n�T�>���OҙPНwW;Zw�vGI� -�c��2�'�BU�锬\1w�3N�c��~ ?N�q���t���U�+�4�����]4����jI�6S���ST���P��1�W��tZ5<��� �3̔����0����'1��8��W��Y���r�%�0��z^W���9`�(��mw�о���M<%�r��Vj����+/.�|�� ��#�h�����3s9��Y-ށSO5�`�ߗʦ|��E)��@� -m���RӔ�^�����h"�yd�?r}��&���:�x�?J(D9D�s��"8����(:�s""F��9�sk�cQ�/�SY��2�3endstream +xڭY[o�~���"6�L<W���E�M�9�"{��݇�b1��m��1������"5_Z� @F�$�"����f���7�d^�ģb�b6Z�ȯ/|�q�S.{s~y|qu���˒p��E~��'�4F��_���Vԥ�:����ڣ��JP���z�ߏ�דh6�������yl5�ù���w�ts��:-��K"Pr�zaY%�塼��`�M�3o�"o�rw��p\�z��b�K"<��k자 V0�O����T �b0+��(��@+╸fg���/k�۲~X�I���ƣ�j6��\M�1kT*�A��b�c�,��k-���I�M1���_����3�"?m�{�+QS�>����yk̀�%$���l\�F�87��d}{���4BYp�j���(��b��f�uIS7J"����nA����y��"ӓ�j��l�t�WV1h T�������k�v�Ք�A����&�j�U��,�jC��܀�J�VF�E���E�Ԋ�8��a�g15?���ʘ�~yuշp:4ו���'z�R������R���t���%780�=�#�G� �;�,����Z�'�uȼ���;��;�,���NS���H��A��@(�\�y�� � ��Y�}�v�ph�C���i9ZR�0$���HsYO�ȥ���{�F#r��^��R�L�!��8�����pO �ܶ��=!����}I=��ݶ��A��h��m,iO���B|����1đ]����.����8k|&;]�%@o.km�yq��Z�;J��x���Y��.Y^�ꭑ +�}�L^���@�ΨMnd�ơ������4e�0[�̭��(CA�����5���a+� S1�-E+�!�Unh�� +4k�$O�A�CE^����1�n+Ik�q)Q؟[��JܣO������=E�5�6OWD����}�ov�r���u��( +wN�xM��i��&��Βs��Is�@j!J��L���P�wOt��ɂ�<��m�`��T�a>ZRb͡"��a/.�@��)���"�hÜ��b�-�t�������2�����Z�V��F�˷m���"$슐0s��*I' O���<�D\�oNF2����O�MH� 6��nJ;n�V�2d]� �i�<K�����,pT���d���?<N���;��Itݹ���w�u�T�f�[ش@%��t�l��PD�.I�ꌛ�j������9l�����+ՠ:�Zn)(���qL�ޔ.�i���NݹvՙE�>Z��}��\�S�H5� +J�;B "�3�F�R�&76g&XM���SM�gqzWI�'Y��YZD�V%��uj�a[�8�m��XW��c�Z��� �O�ʐۻ�+$X9�B;=t�2���곎-�&|��oW�\ͼ0�s<鼖foT���/I���l�xT�:ߟ��p6��0>���G�����x��ɸ\4��5�ޙx��aȫ6i�%5}��tȼ͗�<�>��j�~ͫ��l�;wOA�J-eAM�rI`l7��p��IS���=3pu v��8U�&$)��_'��!e��(���E�іzJ���*�RuŚ�zT�8 +�4���S�iT��GJ��l��Db��lF�&�E�v-�`��OC/�GYv__�RG7��w�3�o�/��&����hXc����g�Yuy���ok��L`.�A!��D���J�y�0:p��no�2vyKS��JSE�U�BhM}&��llDv\S�Aʫ��ݔ�-�Hqj�a�M��Oy�v��n�J?rg��<t��#O^�I�psr~d��L[iI=�W�*Š�v�:���0K�bȥw@k�p��B�@w{�9��N�eya�:��p����x[�2$��xBK��2��I���N��YskWIȖ�}��'+���x�p�~���{�K��,��j�� �̾{�xeB������B��h�n�?��g�?n�Ӱ�?n>���C�i�Es䂨��Q���}E�DX)k����d�c�D�b"Ĉ�E����zV�Rwƀ�"Oܹ�[�7��� ���+��8C-j唚B~��ڈ��0�QZY���Ww~Ӎ#'6d��2�����4J��F��0�k��`�6���bu,�t���=�U�Q�r�&��x#�FϟܫP�ìv�zk`B���G#tAǞ��s((�b+gH�Q�$�R$wWj��vT�i���3(�8}8��8 +�k-�\�� �����ȕ>���K��]�y�.��b�;Ci��'���q��0w-���=k�w��6ϻ��I[!�/kF@������"�W�|A�~����k���rI��ȷ���Ro�b�4� {J#�@�'Q���$�����裉N�`� &�U���/>�ɈD'�f ��M��� ���4�����x��3w���ħ�F�?��#�����O��P������v�?�� � ߿~ʛ!�d����������J�7�c�?ş4zm�=��P�)>���u��� ���I�G9�U0J�ԟ�w�n��φq0)-{P��~�;�_�@�\endstream endobj -4878 0 obj << +4874 0 obj << /Type /Page -/Contents 4879 0 R -/Resources 4877 0 R +/Contents 4875 0 R +/Resources 4873 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4905 0 R +/Parent 4836 0 R >> endobj -4880 0 obj << -/D [4878 0 R /XYZ 71.731 729.265 null] +4876 0 obj << +/D [4874 0 R /XYZ 71.731 729.265 null] >> endobj -1862 0 obj << -/D [4878 0 R /XYZ 71.731 718.306 null] +4877 0 obj << +/D [4874 0 R /XYZ 259.97 708.344 null] >> endobj -930 0 obj << -/D [4878 0 R /XYZ 155.521 676.38 null] +4878 0 obj << +/D [4874 0 R /XYZ 71.731 693.235 null] >> endobj -1863 0 obj << -/D [4878 0 R /XYZ 71.731 669.666 null] +4879 0 obj << +/D [4874 0 R /XYZ 95.641 649.066 null] >> endobj -934 0 obj << -/D [4878 0 R /XYZ 206.096 624.303 null] +4880 0 obj << +/D [4874 0 R /XYZ 71.731 649.066 null] >> endobj 4881 0 obj << -/D [4878 0 R /XYZ 71.731 615.48 null] +/D [4874 0 R /XYZ 71.731 598.76 null] >> endobj 4882 0 obj << -/D [4878 0 R /XYZ 71.731 582.654 null] +/D [4874 0 R /XYZ 309.199 578.003 null] >> endobj 4883 0 obj << -/D [4878 0 R /XYZ 71.731 572.692 null] +/D [4874 0 R /XYZ 71.731 575.846 null] >> endobj 4884 0 obj << -/D [4878 0 R /XYZ 71.731 572.692 null] +/D [4874 0 R /XYZ 71.731 544.962 null] >> endobj 4885 0 obj << -/D [4878 0 R /XYZ 71.731 561.784 null] +/D [4874 0 R /XYZ 71.731 522.048 null] >> endobj 4886 0 obj << -/D [4878 0 R /XYZ 71.731 551.348 null] +/D [4874 0 R /XYZ 336.008 493.32 null] >> endobj 4887 0 obj << -/D [4878 0 R /XYZ 71.731 538.472 null] +/D [4874 0 R /XYZ 71.731 491.163 null] >> endobj 4888 0 obj << -/D [4878 0 R /XYZ 71.731 528.035 null] +/D [4874 0 R /XYZ 246.006 470.406 null] >> endobj 4889 0 obj << -/D [4878 0 R /XYZ 71.731 516.379 null] +/D [4874 0 R /XYZ 71.731 468.249 null] >> endobj 4890 0 obj << -/D [4878 0 R /XYZ 76.712 483.292 null] +/D [4874 0 R /XYZ 71.731 445.335 null] >> endobj 4891 0 obj << -/D [4878 0 R /XYZ 71.731 468.348 null] +/D [4874 0 R /XYZ 279.615 421.589 null] >> endobj 4892 0 obj << -/D [4878 0 R /XYZ 486.228 456.692 null] +/D [4874 0 R /XYZ 521.375 408.638 null] >> endobj 4893 0 obj << -/D [4878 0 R /XYZ 451.424 445.035 null] +/D [4874 0 R /XYZ 71.731 388.548 null] >> endobj 4894 0 obj << -/D [4878 0 R /XYZ 71.731 403.09 null] +/D [4874 0 R /XYZ 71.731 344.713 null] >> endobj 4895 0 obj << -/D [4878 0 R /XYZ 71.731 393.127 null] +/D [4874 0 R /XYZ 71.731 280.12 null] >> endobj 4896 0 obj << -/D [4878 0 R /XYZ 140.075 384.632 null] ->> endobj -1864 0 obj << -/D [4878 0 R /XYZ 71.731 324.627 null] ->> endobj -938 0 obj << -/D [4878 0 R /XYZ 275.663 279.373 null] +/D [4874 0 R /XYZ 71.731 280.12 null] >> endobj 4897 0 obj << -/D [4878 0 R /XYZ 71.731 279.157 null] +/D [4874 0 R /XYZ 71.731 255.183 null] >> endobj 4898 0 obj << -/D [4878 0 R /XYZ 71.731 260.587 null] +/D [4874 0 R /XYZ 71.731 232.135 null] >> endobj 4899 0 obj << -/D [4878 0 R /XYZ 71.731 209.594 null] +/D [4874 0 R /XYZ 71.731 193.345 null] >> endobj -4900 0 obj << -/D [4878 0 R /XYZ 71.731 184.523 null] ->> endobj -4901 0 obj << -/D [4878 0 R /XYZ 188.024 173.729 null] +4873 0 obj << +/Font << /F33 1306 0 R /F32 1215 0 R /F27 1208 0 R /F35 1567 0 R >> +/ProcSet [ /PDF /Text ] >> endobj 4902 0 obj << -/D [4878 0 R /XYZ 181.907 160.777 null] +/Length 2569 +/Filter /FlateDecode +>> +stream +xڝk�۶��2�8����S���7~�cgb�j��v�"qc�d Ҳ����έo�\,�ž�y#����s�|���ϢQ�y��V0���PL ɴG������ -��,�ލB/rb�'�8�G�����e)�4�<���;~���v-xҬ�dJ =�x^4~< ��?'������� +��"� +ii��F1H9C)=o�x3�ҍ� I����p4�\g>���̢9����d:s����g|��!��,�;����)�|��;���;�ez��8��|,�.�dRl6�O��]�0P7U�P<.r�ܼ����ů�nx�t��'@nJ%ji��:*�"���P�e%'~4�4�ȼf�R@��xT�1���~i'1>���5��s�H�E�c�v��R�"�N�l��%�F}o�$���D��Q���b�,'S���~'+���Z�ڌr�ef0�Y�)���G"O-�C���3]�;ZMj�$M��lZ�ˢ��*gYX�[�NIE<��NIG�oʕ��I"�Z,���nm�e��J�/;���3�L�A�3CC��-��{=���"�od#�v�FiVV��r�@�W�jm���n{eb�7�;��$���GAlu�-ܱ���w#w]ץ����H�����)t�j��㕝W`X'YeWf�Aעn���=�C�.�߾}����g�So���F|Yi�ԏ�!a����#^������Q�my�4`���"c�J����֬�;���Z�ܴ����a�$� ��� �/��"� +G�8ڈ��ɔ�������{c�8o�� t�u@��g_��a-�X�6���lg��p�e:P�G�9�k������,�+� d�PN��&��3�X��p�@@�� +u@` + +��)1BUR�;�Aʜ����&��E�3�Z&����L�=��[s�H�@*lIc�D���7U�)�P��<��Ӂ ����9[Z���"�)Hϲ��<(r���(Q�_>$�mL�@M�H�Cc�pF(��OjtyR� �����yS�A��3��D���}s����`����Հ���`�Ҍ!�I������;������P�p7�A�J����lD���P����x*2�2�����=!���>82ӿ����)|�{��Q}��ʂo|\wu$o�X��̼p��JM�"i0Rd�dΓlJPϊ��"��L��)I?�`�(/e�p��v6����T�m�@P;��#K��$��F\���&�,�o>�i��c��l��Y�0?T�|��>N��J��E#��+�T����V� +%yim>︉�/p����.���� +�<t=+%Ů�uS:��8�m�L$�����e�eT��>�Q{e�9�mņҶHj4n|�~�;n��iV����=�t8^`��LP�����~�_S7���?�Rjs�-����� P�n(ލ^D j�W<ꊱU��*$i�/n���K[((�+��-�����FtW�Yx��4��`�#�m�'��v^�D����o�ެ9�~ocd i�T.bP���/�����i�^D��ZB��V���o;� �A��+-����?�/C�2����y|ޚ�Ic�蟴�!��My��p[�����]:X@cɁ(&�|�t°�3J�)cm�ȓd&��8!tr���O���I��g5���8�Co�T�{5��G����f̹��%X� ���,��}�tPw���$B� �N�� ����ނ��>��\����,���n@�r��De�G�a�Jy +wBm�/�(�Z$k��Y]��� !��CS���6[R���yȖ��p6�n��dH/x�f/YS�ۢ�<'`�u~Reeͯ8MJ��5������Pq] � %i�l��bX��]����}�lo#L�Y]��?3=TN%c�f��'�^tc����%{��0TbQuqb|��b�q���������4K��oS��j��n�ρ�fo,z��7'�T�9�EpO��Ng*C�� N��Cv_��α�ۘ�G�hr +��3UB&Y�oޠ���`#���/3���/L�^)�_��߉g +n�B̑:i���Bg��n�� v����dJg��MYU=hm���!�;�jUBj����Vj�+Lv�:=�P��U<�m6Pб�����k��}�P}�[���R�ϛ��H�O¶ތ�r�ݮ3�r�������\�Aa����B�Xx�;R�T +�tmqd��J&��A:7�Ed>!m�����<Yxq��nt>�zD'�� ��d�aw��e��1�yg�ik��L��v7��5a��7e�fT.�\އa?Y��U�0{���Yw�����d�\���dw���B�uău ��-��{��RvS� ���yxXCD��E��N9J:����(�iG14x�责�� +G9�~ocd�Dh�!c�l�����Ǖ�(tӁ�>�`Fhj���w!��R��`@n�w�{l +m�&I�I�5ʰ+e>��RW�֕05�,�j��c�~E��J��\�����W��0������#9��0�c���&�ǧ~�;���e\?endstream +endobj +4901 0 obj << +/Type /Page +/Contents 4902 0 R +/Resources 4900 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 4836 0 R >> endobj 4903 0 obj << -/D [4878 0 R /XYZ 158.345 147.826 null] +/D [4901 0 R /XYZ 71.731 729.265 null] >> endobj 4904 0 obj << -/D [4878 0 R /XYZ 71.731 48.817 null] +/D [4901 0 R /XYZ 71.731 662.704 null] >> endobj -4877 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F44 1994 0 R /F33 1278 0 R >> -/ProcSet [ /PDF /Text ] +4905 0 obj << +/D [4901 0 R /XYZ 71.731 630.371 null] +>> endobj +4906 0 obj << +/D [4901 0 R /XYZ 74.222 588.692 null] >> endobj -4908 0 obj << -/Length 624 -/Filter /FlateDecode ->> -stream -xڽ�Ks�0������e��4�t�ܒd �)��8��]@ظv�q�x|�d-�����#��Q͢��00��ЂlB�v�&TY������y˹�`g�5�I�S�9�Y�a[0��MYFy�lu� �<�od����i*���៩���~g��E��[�&�j���m���E&���� ~�9��Y�����t�����my+&4�1�P����n~�� -� ������@2��~�n��5�Z�(�U��A)s\T:�Ql�Iݘ@�efv@�XJ��r��{��r�Ī�W��A�@Q�h9U��A�Vo|���+�M�MW���K(FX�����]�m��&K;o� ���r�ާl��m2�ꄠ�Q���Q�/��+[�9������� ��A��uoۨ�*�*�G"Hy���s��,�������}a�F'_�R �<|$��)�k�&�[v�.ؘ��2<q��Y��l�dev�}N�L]��5{ Ю%7�.W9\%�b���˄EP�g��\7{��W��3:�����b*���k1�<�S;�L��뽌�,�2���ͺe��V��s��I{��q [�ksk�7�o������シ�z�LmlS��Clor��c�K*%쭇�1�j�endstream -endobj 4907 0 obj << -/Type /Page -/Contents 4908 0 R -/Resources 4906 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4905 0 R +/D [4901 0 R /XYZ 71.731 563.622 null] +>> endobj +4908 0 obj << +/D [4901 0 R /XYZ 111.572 547.846 null] >> endobj 4909 0 obj << -/D [4907 0 R /XYZ 71.731 729.265 null] +/D [4901 0 R /XYZ 71.731 527.756 null] >> endobj 4910 0 obj << -/D [4907 0 R /XYZ 71.731 741.22 null] +/D [4901 0 R /XYZ 259.914 516.961 null] >> endobj 4911 0 obj << -/D [4907 0 R /XYZ 71.731 718.306 null] +/D [4901 0 R /XYZ 141.778 491.059 null] >> endobj 4912 0 obj << -/D [4907 0 R /XYZ 158.345 659.527 null] +/D [4901 0 R /XYZ 74.222 460.174 null] >> endobj 4913 0 obj << -/D [4907 0 R /XYZ 71.731 618.68 null] +/D [4901 0 R /XYZ 488.744 437.26 null] >> endobj 4914 0 obj << -/D [4907 0 R /XYZ 71.731 593.609 null] +/D [4901 0 R /XYZ 106.431 424.309 null] >> endobj 4915 0 obj << -/D [4907 0 R /XYZ 188.024 582.814 null] +/D [4901 0 R /XYZ 71.731 424.209 null] >> endobj 4916 0 obj << -/D [4907 0 R /XYZ 158.345 556.912 null] +/D [4901 0 R /XYZ 205.428 406.376 null] >> endobj 4917 0 obj << -/D [4907 0 R /XYZ 71.731 516.065 null] +/D [4901 0 R /XYZ 171.988 393.425 null] >> endobj 4918 0 obj << -/D [4907 0 R /XYZ 71.731 490.994 null] +/D [4901 0 R /XYZ 337.682 380.473 null] >> endobj 4919 0 obj << -/D [4907 0 R /XYZ 188.024 480.199 null] +/D [4901 0 R /XYZ 71.731 378.316 null] >> endobj 4920 0 obj << -/D [4907 0 R /XYZ 181.907 467.248 null] +/D [4901 0 R /XYZ 71.731 355.402 null] >> endobj 4921 0 obj << -/D [4907 0 R /XYZ 158.345 454.296 null] +/D [4901 0 R /XYZ 71.731 350.421 null] >> endobj 4922 0 obj << -/D [4907 0 R /XYZ 71.731 413.45 null] +/D [4901 0 R /XYZ 71.731 347.93 null] >> endobj 4923 0 obj << -/D [4907 0 R /XYZ 71.731 390.436 null] +/D [4901 0 R /XYZ 113.574 329.664 null] >> endobj 4924 0 obj << -/D [4907 0 R /XYZ 188.024 377.584 null] +/D [4901 0 R /XYZ 286.733 329.664 null] >> endobj 4925 0 obj << -/D [4907 0 R /XYZ 181.907 364.633 null] +/D [4901 0 R /XYZ 291.157 329.664 null] >> endobj 4926 0 obj << -/D [4907 0 R /XYZ 158.345 351.681 null] +/D [4901 0 R /XYZ 71.731 314.556 null] >> endobj 4927 0 obj << -/D [4907 0 R /XYZ 71.731 310.834 null] +/D [4901 0 R /XYZ 113.574 298.78 null] >> endobj 4928 0 obj << -/D [4907 0 R /XYZ 71.731 285.763 null] +/D [4901 0 R /XYZ 307.174 298.78 null] >> endobj 4929 0 obj << -/D [4907 0 R /XYZ 188.024 274.969 null] +/D [4901 0 R /XYZ 388.314 298.78 null] >> endobj 4930 0 obj << -/D [4907 0 R /XYZ 181.907 262.017 null] +/D [4901 0 R /XYZ 239.479 285.828 null] >> endobj 4931 0 obj << -/D [4907 0 R /XYZ 158.345 249.066 null] +/D [4901 0 R /XYZ 186.062 259.925 null] >> endobj 4932 0 obj << -/D [4907 0 R /XYZ 71.731 208.219 null] +/D [4901 0 R /XYZ 71.731 257.768 null] >> endobj 4933 0 obj << -/D [4907 0 R /XYZ 71.731 183.148 null] +/D [4901 0 R /XYZ 113.574 241.993 null] >> endobj 4934 0 obj << -/D [4907 0 R /XYZ 188.024 172.354 null] +/D [4901 0 R /XYZ 71.731 203.039 null] >> endobj 4935 0 obj << -/D [4907 0 R /XYZ 181.907 159.402 null] +/D [4901 0 R /XYZ 113.574 185.205 null] >> endobj 4936 0 obj << -/D [4907 0 R /XYZ 158.345 146.451 null] +/D [4901 0 R /XYZ 71.731 170.097 null] >> endobj -4906 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R >> +4937 0 obj << +/D [4901 0 R /XYZ 113.574 154.321 null] +>> endobj +4900 0 obj << +/Font << /F33 1306 0 R /F35 1567 0 R /F27 1208 0 R /F32 1215 0 R >> /ProcSet [ /PDF /Text ] >> endobj -4939 0 obj << -/Length 678 +4940 0 obj << +/Length 2463 /Filter /FlateDecode >> stream -x��V�n�0��+t�P��-��n�Ma�zhz�%�&B-�(��ח%ǁcgk����h7����BCf4��{i1��ڜ�'d��`���r�.�b�1oy�)�̜��So�}�u������c0��y%�N(��T�Z(%��J�f��Ɲ,���쮪�Sy��X^N>.w�q�8b'�m���]��8�l:탿�*O��u�&�#Ƙr/��ę|X�1�_~�O9ؖ��ȁp �y�����' M��i-JX5>��e��Ȃ������\,���䶍v�Q��B��m,\#W>Š���{���UiW���s�DmR�U�] -�r��@����B�>�Q9�`G{�.��丨��K�G\����I��v�q`6.��)L��מ�b���)>2:�z�C�V�ެ���J�J���X�L�gY��U ��5�T)�$_��������(>��쁒{Br�e;8ԃ��*mO�����K'ɷF�o������ ���xuUпR�Ԑet: ���>�=������g��Ѧ�ڰ��#�[��#��UC�,T��e��� ᔽ^]���Rs��5���k��K��T�ձ.�N�V�k�ԛ���ϛ.�r���*W��1P� 泡��>H���'$���Į���a�F0"��A���`�A��ы�A0;6�b��ۏendstream +xڝk�۸�{~�X�"���~� rAڢ �(�^Q��"���l}g8CY��͡����pޣ����U*E��GeB%�hބ��||##J�b���X�"���fF�����g�W*I���&.�J'���_���dڲ��ިt<�}\� [�0��~-à6��ڡj�?� Ȧ�Ld�F��jLS&�x�z "wAo���-n��P�U|]�80���#"�v��[ئ�������j�!����N��צ��z"pk[C+ː�hfB�e�)M^«&��إ8 �Cq�w�S����b�����qG�hҊ���`Z��5l�,�˯UakR�d*��Y�Qf��!��밹/Q�H�-����@��� +J�"o߮�q�=��H�x��s�Hd*JH�8��Ko��$N�5���v��C��������ڠ��P1��v �J���۩�+� +�<���:���,��[�mI��E�z�d�[�o�h�B��s�U�6�(��#��u�gt�}�����8��v|�t����ݛʉ˱E�۪�>�];ٞ:����:��L�]6������v��c�B��2]�̽U���!�j�������!����;�d$���p�,����֓�i�Z Bs$D念&/ ��fN�T�-��x(p;�h|��qJ�J�"�v�8��.�n�H���!Q��y����W��P�%��]��u��:��9���,��������8)d��$�8�J�$tC j�< +���m�q^e�����R�{|}�c����@�T�.�4�KZ+�Sy��T��_�����R�|*�#\J�@��������,����\a��]r�#.%�|6��t#r���j{�1,cܟr v7I����}L� 9<m0卂��(2Q�r�ߚ���8�r��7���?��.RG"���k������YkL��l������q����'���W��m>؎�L�R�[���6� +M0��A"����(����M�h�5���ˈ�0���v� ���b�@�{.���� +�O�|��ۆ1���_6����3̘��4u>���Y��h���B���}�q�]t.�dy� ��'k��-��5�¥v<��1d7����Eg!`��>i��`��oKs}��҅FlQ@LEapG��j8�q�*���l��0��$�T�0���U����k�ݫ���>W�\\=@i������bt�8Oȿ.\�d�Kh�*}�L�ŀo(�/c[�0,h߿9�n�q�E8�1ժ�"��DWl �C�H���ʇ����0H�̩�:(9�Ip�����q�J)����<N������jP��1��mL�L2u[�#���S*3^Nr�ż +�Y�d��O��OYvH��|1ڼ�"�*�;���:�[�BAL�U�.�e0RN$D��)�8s��峮���W&Թ�M[.��z4X[ �RφTZ$�&�1�0��U�;}������H� ���=f�w������M5@%�[�,�Zn�t~�d�2� �V��`�7�&z�)m��F�Uϡ ̰�`>�4�������1:��<�t�Y"v�w$4�ӌF ��8��"hx"�|p��A(?�;��D �*�����tM�\/���6�b ,�_�9 v�IT����Т8-qy��帠b�FKR�� ��Hw�� �I(t����3��I����[��f�DB���a�lHZ�ށwm�/��������ߔ���v:�ҩ0���<��j{�k� ++j���%"����X6���\䋩�6���r�8 +��F3o�~p2`"ɀP��?]{��D��*��D�*��Hz۠�j�:O�L�=S��~���H"���>N�Ӈ_7�3��=��[|6��^ul[�������K�m���gOn�!���G�\�-/NU1��������n��7Spӂ��?��/����WH��'�����d�k���k�lq�������w>n�T�d�iHs�� ��\瑰�,�y�1���Wc�3��*?�9v ̘1L�������\8�b�L=N�T�jz��<N��A���kh{�iqz�~���K��DZ./�O����=�$}Ռ�<XW�H}A���Sy��4�+턖��P�(���L� ��K���D�D�x-'�|�U�����k�/�B�lQ("� +�5�ǜ{�Ǩ@<��<�AZ�� ��Fꪅ�u�9Cp�����b�]r����z�Xg��*\<@�����[#���1�ܒ��ªï������?�^�����Tp�W�� R������D����33���%��Z���v� +��p�CK��]��l��8��[\U��Y�G5V:=dp��[�&�ɿ��M�~�x��FHV�z�ɰ�d��%t�ǁKj��G��p�?��+� ތF�Q\@h}~q���U�(ڹggْ����5�����6endstream endobj -4938 0 obj << +4939 0 obj << /Type /Page -/Contents 4939 0 R -/Resources 4937 0 R +/Contents 4940 0 R +/Resources 4938 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4905 0 R +/Parent 4836 0 R +/Annots [ 4947 0 R 4948 0 R ] >> endobj -4940 0 obj << -/D [4938 0 R /XYZ 71.731 729.265 null] +4947 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [235.548 547.742 280.892 556.654] +/Subtype /Link +/A << /S /GoTo /D (installation) >> +>> endobj +4948 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [355.754 547.742 401.098 556.654] +/Subtype /Link +/A << /S /GoTo /D (configuration) >> >> endobj 4941 0 obj << -/D [4938 0 R /XYZ 71.731 741.22 null] +/D [4939 0 R /XYZ 71.731 729.265 null] +>> endobj +1892 0 obj << +/D [4939 0 R /XYZ 71.731 718.306 null] +>> endobj +906 0 obj << +/D [4939 0 R /XYZ 358.696 703.236 null] >> endobj 4942 0 obj << -/D [4938 0 R /XYZ 71.731 718.306 null] +/D [4939 0 R /XYZ 71.731 681.855 null] +>> endobj +1893 0 obj << +/D [4939 0 R /XYZ 71.731 658.391 null] +>> endobj +910 0 obj << +/D [4939 0 R /XYZ 233.175 615.294 null] >> endobj 4943 0 obj << -/D [4938 0 R /XYZ 158.345 659.527 null] +/D [4939 0 R /XYZ 71.731 606.471 null] >> endobj 4944 0 obj << -/D [4938 0 R /XYZ 71.731 618.68 null] +/D [4939 0 R /XYZ 146.66 593.735 null] >> endobj 4945 0 obj << -/D [4938 0 R /XYZ 71.731 593.609 null] +/D [4939 0 R /XYZ 441.326 580.783 null] >> endobj 4946 0 obj << -/D [4938 0 R /XYZ 188.024 582.814 null] ->> endobj -4947 0 obj << -/D [4938 0 R /XYZ 158.345 556.912 null] ->> endobj -4948 0 obj << -/D [4938 0 R /XYZ 71.731 516.065 null] +/D [4939 0 R /XYZ 71.731 560.694 null] >> endobj 4949 0 obj << -/D [4938 0 R /XYZ 71.731 490.994 null] +/D [4939 0 R /XYZ 82.138 523.996 null] >> endobj 4950 0 obj << -/D [4938 0 R /XYZ 188.024 480.199 null] +/D [4939 0 R /XYZ 71.731 490.955 null] >> endobj 4951 0 obj << -/D [4938 0 R /XYZ 181.907 467.248 null] +/D [4939 0 R /XYZ 430.969 467.209 null] >> endobj 4952 0 obj << -/D [4938 0 R /XYZ 158.345 454.296 null] +/D [4939 0 R /XYZ 71.731 454.258 null] >> endobj 4953 0 obj << -/D [4938 0 R /XYZ 71.731 413.45 null] +/D [4939 0 R /XYZ 468.549 428.355 null] +>> endobj +1894 0 obj << +/D [4939 0 R /XYZ 71.731 421.217 null] +>> endobj +914 0 obj << +/D [4939 0 R /XYZ 537.833 378.119 null] >> endobj 4954 0 obj << -/D [4938 0 R /XYZ 71.731 388.379 null] +/D [4939 0 R /XYZ 71.731 365.681 null] >> endobj 4955 0 obj << -/D [4938 0 R /XYZ 188.024 377.584 null] +/D [4939 0 R /XYZ 149.514 356.56 null] >> endobj 4956 0 obj << -/D [4938 0 R /XYZ 158.345 351.681 null] +/D [4939 0 R /XYZ 252.264 356.56 null] >> endobj 4957 0 obj << -/D [4938 0 R /XYZ 71.731 310.834 null] +/D [4939 0 R /XYZ 71.731 331.489 null] >> endobj 4958 0 obj << -/D [4938 0 R /XYZ 71.731 287.821 null] +/D [4939 0 R /XYZ 71.731 331.489 null] +>> endobj +1895 0 obj << +/D [4939 0 R /XYZ 71.731 263.994 null] +>> endobj +918 0 obj << +/D [4939 0 R /XYZ 207.49 197.767 null] >> endobj 4959 0 obj << -/D [4938 0 R /XYZ 188.024 274.969 null] +/D [4939 0 R /XYZ 71.731 188.945 null] >> endobj 4960 0 obj << -/D [4938 0 R /XYZ 181.907 262.017 null] +/D [4939 0 R /XYZ 71.731 174.051 null] >> endobj 4961 0 obj << -/D [4938 0 R /XYZ 158.345 249.066 null] +/D [4939 0 R /XYZ 71.731 169.07 null] >> endobj 4962 0 obj << -/D [4938 0 R /XYZ 71.731 208.219 null] +/D [4939 0 R /XYZ 89.664 148.313 null] >> endobj 4963 0 obj << -/D [4938 0 R /XYZ 71.731 183.148 null] +/D [4939 0 R /XYZ 89.664 122.41 null] >> endobj 4964 0 obj << -/D [4938 0 R /XYZ 185.534 172.354 null] +/D [4939 0 R /XYZ 71.731 120.253 null] >> endobj -4965 0 obj << -/D [4938 0 R /XYZ 155.855 146.451 null] +1896 0 obj << +/D [4939 0 R /XYZ 71.731 48.817 null] >> endobj -4937 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R >> +4938 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F32 1215 0 R /F60 2527 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -4968 0 obj << -/Length 725 +4967 0 obj << +/Length 1756 /Filter /FlateDecode >> stream -x��VMs�0��Wp } �qK�ԓN���N;���������n���.w2�3 X�}O+�Y.fy�xn< |*�h;����'���]Ĝ�&�G!��Sa��-�R"��'8�%�V�tRI�{sIь��Be;���yV�JkU�yo��������)J�.n��;�T��է��ꎙ |q�|3bϽ{���'�u[���Y��*��al1������K;���s�ans�n3���ςI��Ih���.Bǩl�UF*#yi3��8�j����iQ�K<�[�j��r��16o.��&4�XQl���N��_ �T��[�2$��Y9Ңr��_ٜ�]�� -���|�]��,6�Ր(�S3[�C���;ˣ�6����GR4:��Ianri5魐�x�?���RVIi`.���*k3�7����\W0X��� �;��%qSG2�H�ӫv��u�C� -�y�7�\���O ��&f������|��h������ò��5#R�� lS�oX�-�� -t�^���d�%�\kb�]�I�x�C��b�IQ�0�k�49t��5:���T�� ���Z�*����������}��ۃ�l���N{��':]g��B���f}�S�̹x<����(��#��e7|�6r��⢱���t����.�a�wC2d�U�ְc�=�'>�6��!�^WrA��Uu�kN�X,�Mendstream +x��XYo�F~ϯ�C�H@��}��v��I�J-4E����"$��[ ��;�3�a)i�>6�����s�M\��&�'��?~M��;����O<�p��9��\>���$YL�w���D�e�$�E�������Q�Z?�?r�����,���,��fX��+��u��������r'5 +���g�T��?q|Wd�w^�L$.�n*�0�)�'{�f$A�}�X�4qN����;�|峲�E��B͜�M��j+�u3o�M�ў�iܚ��Y��`��vK�nUޛV+�"[�/�v��]�E�r;����]��E�-WC�?c|�/��{�S��R��)Z%��˻Lك������ʽZu�e��'C7���� {ы�F ����MU���5�����Y�Bq��yȹd�Q_kv�P0��{�ȁi��D����*|)B�$I�W�W�ƀ;�R]\�WtҴ�����N�t#�� t�xoy��w�,�̏����.�N+�urä`*�4�q����HZ�f>�������~D���(i���Qۛv��t�5�6�d�Bm*ZEک ����(M ��B�M�Q�D�Z`b/���Qf�c�e�v��-��umz��U��T3ݫ�_�����7/�o��%� S_]�_���w�W�R�� }n�ME$厗��iXgt������zz{���.~5�e���ޡ +y���A^�?]�|�jy��;Cvs����J|�����śg0�|ce��!��Hb�b��44K!B(<��0���q@�)x؉�D�a�!���No�h�7)~�ռ�6E\Ot�P�;�UA%>���8�]/� {m�J��114��թ������2+��h_�Cu�U��<�����~!��ի����S�*�,������`a���C��e�md����w�I/���t_��'�D��_^����@���� +~$�y��4ˎ\�^��g���h���/���X�c��N�,վb�ɂ�i�/��fA�J��trX3�G�2�j�sR�s,��+(}���l1!�r^�1�A��U\2#r��k�E�pr�;�lŵ-UPul�� �K���t�V���3>mi�L����0�����Ҟ�3���m �B���$k��0��ʇu�,���Y�� t5�=Rc�Nۖ괿���P�;����sc���a�Jrt��C��^�j}��vg +�{��A����$+�+Y���k�jm���\�OtF�E$��[�$L�4b��Khi�V�m=7��<� �b;�Nefp�M�~l��$��,XҺ2kn�Έ��(Y����w*3 +D��L(�����f,[������(A7�("��=�q� ��#������K�a���ظ���0�Mnc#fU���J�ƒ�Rp�����[^�c�b�lr�oY�P��#�5��� d^�F�tP$Q�{H����zמ�W��C\�Y�L�p +</cB£/�4t*q�/���鉟ٷع?�)�ƜScΩ��1+A@oW� �dB�b��DX����J��2�$���m�O��0��4��&�c��R����J~�q���h��E3~#b�̍y�6��2���h���1�w�?j�3�'-֏�_*D]��n��v��v��<|����<��ި}3<vȑ��[ԧ3����ɿ�����$�B"��T�mrnM�8�uo��D�Ѵ��Q��Z҃��{z�ӓ1��x��^��{�$'��D~ � � &��~��SY�=�Wendstream endobj -4967 0 obj << +4966 0 obj << /Type /Page -/Contents 4968 0 R -/Resources 4966 0 R +/Contents 4967 0 R +/Resources 4965 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4905 0 R +/Parent 4836 0 R +>> endobj +4968 0 obj << +/D [4966 0 R /XYZ 71.731 729.265 null] >> endobj 4969 0 obj << -/D [4967 0 R /XYZ 71.731 729.265 null] +/D [4966 0 R /XYZ 89.664 708.344 null] +>> endobj +922 0 obj << +/D [4966 0 R /XYZ 370.33 645.157 null] >> endobj 4970 0 obj << -/D [4967 0 R /XYZ 71.731 718.306 null] +/D [4966 0 R /XYZ 71.731 632.719 null] >> endobj 4971 0 obj << -/D [4967 0 R /XYZ 175.332 672.478 null] +/D [4966 0 R /XYZ 71.731 611.478 null] >> endobj 4972 0 obj << -/D [4967 0 R /XYZ 158.345 659.527 null] +/D [4966 0 R /XYZ 71.731 555.998 null] >> endobj 4973 0 obj << -/D [4967 0 R /XYZ 71.731 618.68 null] +/D [4966 0 R /XYZ 139.576 544.096 null] >> endobj 4974 0 obj << -/D [4967 0 R /XYZ 71.731 593.609 null] +/D [4966 0 R /XYZ 71.731 531.976 null] >> endobj 4975 0 obj << -/D [4967 0 R /XYZ 188.024 582.814 null] +/D [4966 0 R /XYZ 71.731 464.84 null] >> endobj 4976 0 obj << -/D [4967 0 R /XYZ 175.332 569.863 null] +/D [4966 0 R /XYZ 71.731 442.875 null] >> endobj 4977 0 obj << -/D [4967 0 R /XYZ 158.345 556.912 null] +/D [4966 0 R /XYZ 71.731 373.682 null] >> endobj -1865 0 obj << -/D [4967 0 R /XYZ 71.731 516.065 null] +1897 0 obj << +/D [4966 0 R /XYZ 71.731 355.015 null] >> endobj -942 0 obj << -/D [4967 0 R /XYZ 252.009 470.81 null] +926 0 obj << +/D [4966 0 R /XYZ 374.461 311.544 null] >> endobj 4978 0 obj << -/D [4967 0 R /XYZ 71.731 458.639 null] +/D [4966 0 R /XYZ 71.731 299.373 null] >> endobj 4979 0 obj << -/D [4967 0 R /XYZ 71.731 439.189 null] +/D [4966 0 R /XYZ 402.991 289.985 null] >> endobj 4980 0 obj << -/D [4967 0 R /XYZ 188.024 426.337 null] +/D [4966 0 R /XYZ 71.731 264.914 null] >> endobj 4981 0 obj << -/D [4967 0 R /XYZ 182.306 413.386 null] +/D [4966 0 R /XYZ 71.731 227.519 null] >> endobj 4982 0 obj << -/D [4967 0 R /XYZ 158.345 400.434 null] +/D [4966 0 R /XYZ 175.682 214.567 null] >> endobj 4983 0 obj << -/D [4967 0 R /XYZ 71.731 359.588 null] +/D [4966 0 R /XYZ 395.942 214.567 null] >> endobj 4984 0 obj << -/D [4967 0 R /XYZ 71.731 334.517 null] +/D [4966 0 R /XYZ 486.807 214.567 null] >> endobj 4985 0 obj << -/D [4967 0 R /XYZ 188.024 323.722 null] +/D [4966 0 R /XYZ 71.731 201.616 null] >> endobj 4986 0 obj << -/D [4967 0 R /XYZ 181.907 310.771 null] +/D [4966 0 R /XYZ 71.731 188.665 null] >> endobj 4987 0 obj << -/D [4967 0 R /XYZ 158.345 297.819 null] +/D [4966 0 R /XYZ 107.048 188.665 null] +>> endobj +1898 0 obj << +/D [4966 0 R /XYZ 71.731 181.526 null] +>> endobj +930 0 obj << +/D [4966 0 R /XYZ 496.414 138.429 null] >> endobj 4988 0 obj << -/D [4967 0 R /XYZ 71.731 256.972 null] +/D [4966 0 R /XYZ 71.731 125.991 null] >> endobj 4989 0 obj << -/D [4967 0 R /XYZ 71.731 231.901 null] +/D [4966 0 R /XYZ 206.804 116.87 null] >> endobj -4990 0 obj << -/D [4967 0 R /XYZ 188.024 221.107 null] +4965 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F35 1567 0 R /F32 1215 0 R /F60 2527 0 R >> +/ProcSet [ /PDF /Text ] >> endobj +4992 0 obj << +/Length 2160 +/Filter /FlateDecode +>> +stream +xڭX[�� ~�_��q���r�K��i�(���E��b+�0���vg�__���NfhDE�E~�-6���(�%�ć0�f����Y�a揟"�X �j����i�K�,�a�,^O�4��CtX�8�g���G����ua�-Wq� ^Bn_�Y�e��?���Xۙ�����?��:h͒]x�'�5���Y�n�� n�a��d��E/WI��^�Y��^���m��Y�[�f�Q��]��(�*$u�1vЗ�<ꉄ4Py���q:כּ�0�u�L�{�����{/��?�,�L�v +F���3�i��df[� nM���պF���ϯ�8<���l��Q8�U�j��L7A˴w}�ΑO��Y�ؽQ���n+�C^�� +���.D�S��m�ڋ]ʉ!p+��6������ D����eM�Z���~��F��Yo����o:{&� ��(�����/<2-�x0i����I:в09:C O�F��M�i{/V�ا��3ϋ�8p�# ` +��Q��^��X�yZF�@�ghmn���$��8$���x��]��.��R�V����)��oW��-a�:�%Bޗx�#�{!�����;����C��Q +�W��go+�N��39 :<8pn@Ypts�b��B������"~�H��;\-�*㞭���@��+hOл�?�������������3��[=�6��4�R�ݍ�m�s�u��sA�!,�f��l��[J�5����?�1vWJ{�_�2���"�0�♱{p �\2���q��d"[����t�R�<K肳� ��8ze�c0��$;��4�� bۏ��J�n5�כr5�`g�����������Q�&m��B�Hg0 Vprà2�� �[L��`dZ����5�N�li�s�u�V�'�v������!�@�?Ȟ�z���� ����Lc7a�%��3���{�%�L����,���K��3�pL�J�kZ�$Z)FR3�� ӏ���Iy]]�,x㡶=�qu�b7HP�!̺�,���R�lȖ �wUȲ�䡋�RS��J�߮k0.ޅ�CF���MU���U$%��۩}�*�Q�z=q)L5�8�&Oy ��gSO�W{0o��m���,�Y�8Ft\����z}DI脕�TC���QD�6ۑ���^��'a�?��Y[�au������ �ڙ��A�,n���oK'��Q��M��6;u�8;�.�p��nञ\\������u�3�=�lǀ�W�|j"#x'苺xf��e?���h��/$Q�l�\�3���v����n��/�J45�r��3��Юx�] +�d3�x�%lA�,٘�w\?�K��Ҡ֔� P�j*b�?9K1��"J�"x�~kE8CQ��;_(��'�ਸ਼E��d+L��5�g̩o� �8O�U�%ڀ��s�wU�͓Iu����@+� @�l�RJ� ���O��F8�1�_c�3 ���An��sS�K~[c4/����Su~�� �gB~*X�Fy�E,F +��5�궎�x��~��d )�U2�߉4h���xC���=�hi-j9}oJ"�8�`�����AFd�3�94U�4��>��d�'�p���a!m���`&����Xި����aI��R�-H]K�H8����C|U U�(@��JC�؈��##+�R8��SD���L"/�6�>א�N��hd%���L��K"��o����K��%]��6�� ���uG�@U� �c�%�!:���KW ��gx�-�D��( ��D��݀����sBu�l�����t�/��Q�e�����wQ�7����w�l<hu�ϖb(O��8y[�xtX���.�����|���w��@��7ϥ��8vT�<2�Y�+�z.UV�F���L }����{�������NIȰ�oW^8�h{4�J���\���N?����Z.�Y�����WnUQ�����_J���Pf���Igӂƍv�i&APw���s[I��VR�d�\���YҌ-��į6��_�Sj�����u� �O���0������|���3���b*=s���>a�_ޫ�:H�[��wÏ�쮾�Y)�N6��Au^�RS�����9;݇�h����7��������ॠ�h}� �^��|�endstream +endobj 4991 0 obj << -/D [4967 0 R /XYZ 182.306 208.155 null] +/Type /Page +/Contents 4992 0 R +/Resources 4990 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 5012 0 R >> endobj -4992 0 obj << -/D [4967 0 R /XYZ 158.345 195.204 null] +4993 0 obj << +/D [4991 0 R /XYZ 71.731 729.265 null] +>> endobj +4994 0 obj << +/D [4991 0 R /XYZ 71.731 718.306 null] +>> endobj +4995 0 obj << +/D [4991 0 R /XYZ 508.292 708.344 null] +>> endobj +4996 0 obj << +/D [4991 0 R /XYZ 71.731 649.4 null] +>> endobj +4997 0 obj << +/D [4991 0 R /XYZ 71.731 631.467 null] +>> endobj +1943 0 obj << +/D [4991 0 R /XYZ 71.731 579.661 null] +>> endobj +4998 0 obj << +/D [4991 0 R /XYZ 71.731 546.919 null] +>> endobj +4999 0 obj << +/D [4991 0 R /XYZ 71.731 536.956 null] +>> endobj +5000 0 obj << +/D [4991 0 R /XYZ 135.985 527.323 null] +>> endobj +5001 0 obj << +/D [4991 0 R /XYZ 135.985 492.354 null] +>> endobj +5002 0 obj << +/D [4991 0 R /XYZ 71.731 435.766 null] +>> endobj +1944 0 obj << +/D [4991 0 R /XYZ 71.731 396.812 null] +>> endobj +5003 0 obj << +/D [4991 0 R /XYZ 71.731 362.013 null] +>> endobj +5004 0 obj << +/D [4991 0 R /XYZ 71.731 352.05 null] +>> endobj +5005 0 obj << +/D [4991 0 R /XYZ 135.985 342.416 null] +>> endobj +5006 0 obj << +/D [4991 0 R /XYZ 135.985 307.447 null] +>> endobj +5007 0 obj << +/D [4991 0 R /XYZ 71.731 274.172 null] +>> endobj +5008 0 obj << +/D [4991 0 R /XYZ 181.691 261.22 null] +>> endobj +5009 0 obj << +/D [4991 0 R /XYZ 485.889 261.22 null] +>> endobj +1899 0 obj << +/D [4991 0 R /XYZ 71.731 228.179 null] +>> endobj +934 0 obj << +/D [4991 0 R /XYZ 517.296 185.082 null] +>> endobj +5010 0 obj << +/D [4991 0 R /XYZ 71.731 172.644 null] +>> endobj +5011 0 obj << +/D [4991 0 R /XYZ 71.731 157.102 null] +>> endobj +4990 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F32 1215 0 R /F23 1201 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +5015 0 obj << +/Length 1812 +/Filter /FlateDecode +>> +stream +xڍ�n�6�=_a���@BKԝ�M�-���n����,�6YTtl�~}g8CE�������p�>��E�4��̅L�E���[8��"`�+F�����^���E.�$\�n�D�4�"�����{�����Jƾw#�{��c�[F�g�u���1�n��?o���v���ȳ�U�Ιd2}��)�g"�"+؇ �������(:E��GQ�B���2~�c�t���Au�.i?씻�{&F��芽lږE]�� J�f��F ����}��v�ܑ��eࡀ�.�� ��C�^ �$�h���q5�+X�*�"g������>�/݅��ޢ�����-��S=-�0�:u?�Ń�����ʝU6;�0�x5�.��c�1wZ��y�p�%X����>�7{���"x5�A���U�Yc��J�zjm� �h :|�H��͚��z)c��2�=w� к�[�Gnl��}�I�C���1�@��� ��w�#��O>�`!�i&� 0#җ�R ���|l\��B�6���RۘHCf�x�*A'�!��@��ժXJ�M�`����%An��?��B�_����z�(=A�@�JW�>�\]�)E(�^jl���������IL&�/H�;ZZw$ ��={k78�Ծ�| ��9�k�&��h:3���!MGv��@���>�%���@�^W|�l^=�e3l����syb�`XL�%��_�%�KSX��*�,���K�<��A洦ꈵ�@��)9��3�d\XO�%��'P (��"H�b���R�&V��1R $Q!R��0��qtS�GQB��S�2�!#VF��ہ�mgЙ\<Z�65�1�,O6����>�>Y�}MJf�ǯ�~d1f t�nǹE�}@^9㷝Yk �1��H5VDv�r�<��C�(�c����H�7l�88�L]��zN�$��6��I��-���(�|G[%���q�����ˀ�� �x�p�Gػ����<�<^� ֕�/w��>r����E�I�9җ"���4�"�e��7L|���� 6Ѥ��Y�4M��{���`��dz�0MEaLȵn�+�Ƕl�a�@���!-��/��8�D,�gg4F��ᜍh'd��gPE��RD"8�D0�E٫�Ϋ�O ������>�츤���T�����llE[�Q�Z;������`p�`%�Uc\=��鱗0�����C�f0���ޏ0q�z������q��7�=!ě��3��)�����s S�c�mM�,�����<�BX�,L]�D���@bck�m}1]E@Ք�˃S;q5��f�X�=�h�����i t��;]3O��;ϫ��������������D�2�ڛj����}D(Z�y��1d�K�x������Z;��=i +h���G|�V���� �c��z�g9�����C����j�2OM+��̳�:��@� ��� [���ӊ+����r��g|��_�.f����c��f.�89XG<�<<���b`�w�kk_�ʩ����b����`�Ű�v����a������$LKL����D=J�<&E�P�����)-��Wb+��}M���(&;6�t�ed������v�m��W�{fD�L�v��T醁�w���ů.JE͇O���j=��~L����{�K#��N~W�q0�G!�o�P�(�]��rWtfl�*��X:�������t6�&��<�f_�����v��ժR�nĨ��Z�����ueq���Ou�Wi�� �����_Q�b��_6O(g���2~�;*(y�˗��9��/P-�endstream +endobj +5014 0 obj << +/Type /Page +/Contents 5015 0 R +/Resources 5013 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 5012 0 R +/Annots [ 5024 0 R ] +>> endobj +5024 0 obj << +/Type /Annot +/Border[0 0 0]/H/I/C[1 0 0] +/Rect [81.972 518.428 141.748 525.282] +/Subtype /Link +/A << /S /GoTo /D (http-apache) >> +>> endobj +5016 0 obj << +/D [5014 0 R /XYZ 71.731 729.265 null] +>> endobj +5017 0 obj << +/D [5014 0 R /XYZ 71.731 718.306 null] +>> endobj +5018 0 obj << +/D [5014 0 R /XYZ 310.001 708.344 null] +>> endobj +5019 0 obj << +/D [5014 0 R /XYZ 278.636 682.441 null] +>> endobj +1900 0 obj << +/D [5014 0 R /XYZ 71.731 636.448 null] +>> endobj +938 0 obj << +/D [5014 0 R /XYZ 107.109 570.971 null] +>> endobj +5020 0 obj << +/D [5014 0 R /XYZ 71.731 562.148 null] +>> endobj +5021 0 obj << +/D [5014 0 R /XYZ 71.731 542.274 null] +>> endobj +5022 0 obj << +/D [5014 0 R /XYZ 274.373 531.479 null] +>> endobj +5023 0 obj << +/D [5014 0 R /XYZ 390.766 531.479 null] +>> endobj +1901 0 obj << +/D [5014 0 R /XYZ 71.731 513.447 null] +>> endobj +942 0 obj << +/D [5014 0 R /XYZ 452.394 445.912 null] +>> endobj +5025 0 obj << +/D [5014 0 R /XYZ 71.731 433.741 null] +>> endobj +5026 0 obj << +/D [5014 0 R /XYZ 71.731 411.401 null] +>> endobj +5027 0 obj << +/D [5014 0 R /XYZ 437.99 411.401 null] +>> endobj +5028 0 obj << +/D [5014 0 R /XYZ 71.731 391.312 null] +>> endobj +5029 0 obj << +/D [5014 0 R /XYZ 130.401 354.614 null] +>> endobj +5013 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R /F60 2527 0 R /F35 1567 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +5032 0 obj << +/Length 3010 +/Filter /FlateDecode +>> +stream +xڝk��6��� +�W 6�֊zZ-��6�k�H/�f��- +Z�-u��He����7�����E��p89O��ʇb� +/ �d^�ī���WG���J0E�$^�_���a�e�p��q�����A� +|/����a��� LV�ŏ�۾WmQ}�l�t�~��k�P�7?�,�U�eI���6Hy�}�+�d- Hג�����@pw������'��J�4��x�WUTŶk5 ��H,- ƫ��@A�ג� +��W�����������M��l��r�<���"�����nx�$�ڣ��ˊ��0Wu,K������axQ�[mE�e��Ԩ���_�R5��D�"�k�bPgd���t�M#�b[W�"�[%�M����%��Z�����e�/Fu��Ƭ���0ƪ'L��Zk�MUW�R���n�E L^V푆3�!��5�� ��84�3y�\���Z���:�t��\�x����-'K�ɛ�^��F��~����AW���0�D��A�5�v��L�K�~TÓ��Bš�f;&�^r���3��x�+m�L"�k""��<��K����0�5ԫ��OQE�Ћ�hC�IR�1��Տ?��з��+�=^!q^�f+�eY���p������e{F�o�L�`�u�lc��4�!ND^�u���!�h7Ÿl"�i��ko �N������:Ẓp�G���5 �Amix�����4��$������7`��):��ұ�ނl����|O$ �VR[��f֯�(%Ƈ�C����^)�f�Q�b��8 +�"V�+��ډB�w ܢ���2�sBe���͙,�L�����[��"��Ya� Ӑ.�F�� m8�`�PףNq�����B��Q<o���D>Pn���§^i����T1��3(�/,�<v��qP���#�ofC4�5�tG����ƺ x����D�ajUT�x���9�GLP���T�� �4t�ȁ0�cm��bx�F�Q�|��+�8(' �bfSG`��#�o���l�3k�z�� ���ۨ�I:�w)��2������1��n����ʶA +PuM�Uo6pct�81�ʜ��eX@Z�y��@�8@�"`��X���T �o�{MP/���Z��Ʀ�F���ΰ�c�w�gߙ�:�����\�윳�&dz�K��A�p���Cױ��a6��d�βi��H�� P�c"z�U�[��Vj][U���w݂G�1��r?�[���h���+����%�E����̍-~ah�:� �����2;�w�f3#�zdPr�]���pN�8�1��P���#y�ce��f�|�N�p�ڼ�ͽ�h��ˈ�J�_�c��[G�Xl��� �&� ��՛����뻷�D��>TC�bd!"�� ~�=E@ݗ��6�ޏ\<"}=���M�7!�J��x +`�jkK�NjJ0EHk���SʕU�B���B�o��+h�k���� �d^~�<�%s��yhEj�������FTe-� ��� ��`��aD]�M�z�Ja�a�i��d^\�lV��мV��*W(��hnw;6w�<*���\�E���~,+-��˺���*� �UxF�2ܲ���G��@�.d�0�',=�Yz��91�b3`o�}�=>#���F��O���y�P�qs��۴�5}�0�n}�7���<��*^r�J36�s���UkMDPg@`a����}`�SN���W�*f������:�]0\�?3��Y4�%�����Wga��D +Y��4<��X���FB�y"t�>�"햙��Z�\��������p@�φ����Г[����$¨��/.<v�(s��}x���3���k��נ�iK�Q�]WЙO���'ԙ��;�Z�w�W#wKd��+���&�k=� _+��>���45����/�Z�CxMPK��"���|����rO�w���0�m���Ѻ��d�e��l��4�?�͈bۭ9kf\��T��N�eK�n��u3DS�p�����DQD<��VS苸��drC�N�3���Å~\�b0�B[���*����qnN�����y+�I襉8se*D�dݏC�i�*+Iܳ�)�\QE�Pb�>��pO� �1S�M�=�!p�B���x&���U�k��y;qor�#�Bo�%���L>ڔ�8�i[u!�A=�]e� ���ݕ���ƣ@q���J�m�e��G.iLk!�.���z_|Z�.|/\���5R�4�@�����t���(�����L�[�2��0�-��E���f�%q��axQz��չ�)0<%(����p!��Kͣ�)j�f����s��L(�e봕�2$P�y#ut-A��sU;�F������գm����pw4H�m������� ��ap��bMM/K�����y�:�0`���k� v��U!���yF��[�n/ILJ�|�vwl���;���)Z\r��v�+���������G�*��9f����8�_����R�L!. +@zvڲ�o[T�$�ϗ�n֑���s�h\���0(4�6�tL�N<�Å6�c� +.\�♤�Ybi%-��X�*�����>{i�+|K��v��?�T����m�E��or�UG�����p^���%i�,z�d�V����`kA��CP:F��٭jZaQ龖O�#wJ�x��j��JlC�+�y��)L&�ص[*��Q�f����p��_�SQ��:B���óif���uG��-�x���_P���O �u˓t�s��]ޱd�z��ᴂ�&'&;<RK��oD״@�ܗ�������D&`%�G�B�������`��;1��w�`�?������m����S����Hn!���J�_���ZN� ��^`�����n�G;o'ҋ?C3��DB������3�O)�p������D&\endstream +endobj +5031 0 obj << +/Type /Page +/Contents 5032 0 R +/Resources 5030 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 5012 0 R +>> endobj +5033 0 obj << +/D [5031 0 R /XYZ 71.731 729.265 null] +>> endobj +1902 0 obj << +/D [5031 0 R /XYZ 71.731 718.306 null] +>> endobj +946 0 obj << +/D [5031 0 R /XYZ 271.435 703.236 null] +>> endobj +5034 0 obj << +/D [5031 0 R /XYZ 71.731 682.175 null] +>> endobj +5035 0 obj << +/D [5031 0 R /XYZ 297.998 673.5 null] +>> endobj +1903 0 obj << +/D [5031 0 R /XYZ 71.731 660.449 null] +>> endobj +950 0 obj << +/D [5031 0 R /XYZ 365.87 615.294 null] +>> endobj +5036 0 obj << +/D [5031 0 R /XYZ 71.731 606.471 null] +>> endobj +5037 0 obj << +/D [5031 0 R /XYZ 457.285 593.735 null] +>> endobj +5038 0 obj << +/D [5031 0 R /XYZ 199.72 580.783 null] +>> endobj +5039 0 obj << +/D [5031 0 R /XYZ 258.499 580.783 null] +>> endobj +5040 0 obj << +/D [5031 0 R /XYZ 315.525 580.783 null] +>> endobj +5041 0 obj << +/D [5031 0 R /XYZ 71.731 578.626 null] +>> endobj +5042 0 obj << +/D [5031 0 R /XYZ 118.555 540.062 null] +>> endobj +5043 0 obj << +/D [5031 0 R /XYZ 71.731 509.785 null] +>> endobj +5044 0 obj << +/D [5031 0 R /XYZ 71.731 509.785 null] +>> endobj +5045 0 obj << +/D [5031 0 R /XYZ 71.731 490.079 null] +>> endobj +5046 0 obj << +/D [5031 0 R /XYZ 165.11 477.128 null] +>> endobj +5047 0 obj << +/D [5031 0 R /XYZ 71.731 469.99 null] +>> endobj +5048 0 obj << +/D [5031 0 R /XYZ 71.731 469.99 null] +>> endobj +5049 0 obj << +/D [5031 0 R /XYZ 164.065 446.244 null] +>> endobj +5050 0 obj << +/D [5031 0 R /XYZ 210.352 446.244 null] +>> endobj +5051 0 obj << +/D [5031 0 R /XYZ 352.569 446.244 null] +>> endobj +5052 0 obj << +/D [5031 0 R /XYZ 442.661 446.244 null] +>> endobj +5053 0 obj << +/D [5031 0 R /XYZ 203.715 433.292 null] +>> endobj +5054 0 obj << +/D [5031 0 R /XYZ 372.061 433.292 null] +>> endobj +5055 0 obj << +/D [5031 0 R /XYZ 71.731 426.154 null] +>> endobj +5056 0 obj << +/D [5031 0 R /XYZ 460.217 415.36 null] +>> endobj +5057 0 obj << +/D [5031 0 R /XYZ 71.731 382.318 null] +>> endobj +5058 0 obj << +/D [5031 0 R /XYZ 71.731 382.318 null] +>> endobj +5059 0 obj << +/D [5031 0 R /XYZ 237.451 371.524 null] +>> endobj +5060 0 obj << +/D [5031 0 R /XYZ 71.731 358.572 null] +>> endobj +5061 0 obj << +/D [5031 0 R /XYZ 220.87 345.621 null] +>> endobj +5062 0 obj << +/D [5031 0 R /XYZ 71.731 338.483 null] +>> endobj +5063 0 obj << +/D [5031 0 R /XYZ 257.124 327.688 null] +>> endobj +5064 0 obj << +/D [5031 0 R /XYZ 358.713 327.688 null] +>> endobj +1904 0 obj << +/D [5031 0 R /XYZ 71.731 320.55 null] +>> endobj +954 0 obj << +/D [5031 0 R /XYZ 462 277.453 null] +>> endobj +5065 0 obj << +/D [5031 0 R /XYZ 71.731 265.015 null] +>> endobj +5066 0 obj << +/D [5031 0 R /XYZ 117.29 255.893 null] +>> endobj +5067 0 obj << +/D [5031 0 R /XYZ 427.895 255.893 null] +>> endobj +5068 0 obj << +/D [5031 0 R /XYZ 71.731 224.91 null] +>> endobj +5069 0 obj << +/D [5031 0 R /XYZ 173.632 212.058 null] +>> endobj +5070 0 obj << +/D [5031 0 R /XYZ 420.183 212.058 null] +>> endobj +5071 0 obj << +/D [5031 0 R /XYZ 71.731 166.065 null] +>> endobj +5072 0 obj << +/D [5031 0 R /XYZ 71.731 122.23 null] +>> endobj +5073 0 obj << +/D [5031 0 R /XYZ 71.731 122.23 null] +>> endobj +5030 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F44 2037 0 R /F32 1215 0 R /F33 1306 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +5076 0 obj << +/Length 1499 +/Filter /FlateDecode +>> +stream +xڵWK��6�����H������d�`�l0h-��Ack�nl��c��%EyƓ�"9���)�")����+~|�p��q�ʛ�����J�q�D$�~bӋ��ei��^o..�J�,���fw��L�jS���:�����D�:�n�;��[�]�;��i}��Qֵ�V#'q�����k���;p�1K#R�S��1��� �/ �'��#ÜM�S����*cYؓ���'oЉ�;��D�V� jl�+��<'�5Tc}���p��э#��Jիgn9V�l]9�����V�jň�&)]�� �c�����Jﭛ�~]�OD�+Tr���Q��Gig.X�Q� +eF��|gP&v/h%uAՖ�upU�tA�@�F�J�R�r�� +�m;^ѳ�*�7�_%f��[9�?,$�8FH�(�@eFٻ^������nG���l��ǝ��?����sH�o���6����$����Ԯ�[����䛵7��j�WG5���ڹ��r?�{��p�)�?�vT6��p�9biZ�7������/TO$u 'o���jB��N}n�-,5i� �h�[����~ ƣ+|a�"R�9�����;�>���P¸4�U]����DQdS��`q +8��;��/�p�9³f,|/�e>?I��77�� +��}����m�����F�����֛�ω�H�G�n}����`�|5�Wj:#��JL�!bzAb#�'IV�IZη1��|>R��$��T�g�8���ķ0nȪ�[\�ց]�6� �Y��'9�f�r~�/#����K" ����U�H*��ǪW����k7�Nh�kF���w �w;��L����ksoCjUoUM��ƾ�P�+-ڴrEF���AB�V����z���)�c s�5��t1�r�s¶Nzm�ڠ!�c� �5'�� �[�}R��*�۴&s����0L�c.|I�fm[���ႍ�zd.��S�����1e��թ��w���h�hB/�C����?}_�j�#NX� +[#�9����'��ub��Z�����R;��ǖ3MB��!�)<#3���1�zUל5�DlZZ6�u]��Y�K�0]r?�!4[�llX�}�����m����}&D�n��z�ˤ�ycč���3@��U��{�����?�p�����;n�aa豛'�L,�N�ۣ=}�j_R�Y��ؚ<6J�I� +ֽ��s{�e�)�C5��93����� +��bje�g��0����{!k0^��9�o���):3���N���rޝ�u�q�f�^���7�0��}oΓ0;�<y��Ƥ�!��<�q<��/q����-�q�./�G�>/Y�I��U9��c{ �X�\>1pSl�4��u���۱��އ��>����؉1N���S��4~�=N���Nΐ<����ccF���6���/ G +i��_I+�E�� 8>L$�� +�%S�"��/M��I�m��!��endstream +endobj +5075 0 obj << +/Type /Page +/Contents 5076 0 R +/Resources 5074 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 5012 0 R +>> endobj +5077 0 obj << +/D [5075 0 R /XYZ 71.731 729.265 null] +>> endobj +1905 0 obj << +/D [5075 0 R /XYZ 71.731 718.306 null] +>> endobj +958 0 obj << +/D [5075 0 R /XYZ 155.521 676.38 null] +>> endobj +1906 0 obj << +/D [5075 0 R /XYZ 71.731 669.666 null] +>> endobj +962 0 obj << +/D [5075 0 R /XYZ 206.096 624.303 null] +>> endobj +5078 0 obj << +/D [5075 0 R /XYZ 71.731 615.48 null] +>> endobj +5079 0 obj << +/D [5075 0 R /XYZ 71.731 582.654 null] +>> endobj +5080 0 obj << +/D [5075 0 R /XYZ 71.731 572.692 null] +>> endobj +5081 0 obj << +/D [5075 0 R /XYZ 71.731 572.692 null] +>> endobj +5082 0 obj << +/D [5075 0 R /XYZ 71.731 561.784 null] +>> endobj +5083 0 obj << +/D [5075 0 R /XYZ 71.731 551.348 null] +>> endobj +5084 0 obj << +/D [5075 0 R /XYZ 71.731 538.472 null] +>> endobj +5085 0 obj << +/D [5075 0 R /XYZ 71.731 528.035 null] +>> endobj +5086 0 obj << +/D [5075 0 R /XYZ 71.731 516.379 null] +>> endobj +5087 0 obj << +/D [5075 0 R /XYZ 76.712 483.292 null] +>> endobj +5088 0 obj << +/D [5075 0 R /XYZ 71.731 468.348 null] +>> endobj +5089 0 obj << +/D [5075 0 R /XYZ 486.228 456.692 null] +>> endobj +5090 0 obj << +/D [5075 0 R /XYZ 451.424 445.035 null] +>> endobj +5091 0 obj << +/D [5075 0 R /XYZ 71.731 403.09 null] +>> endobj +5092 0 obj << +/D [5075 0 R /XYZ 71.731 393.127 null] +>> endobj +5093 0 obj << +/D [5075 0 R /XYZ 140.075 384.632 null] +>> endobj +1907 0 obj << +/D [5075 0 R /XYZ 71.731 324.627 null] +>> endobj +966 0 obj << +/D [5075 0 R /XYZ 275.663 279.373 null] +>> endobj +5094 0 obj << +/D [5075 0 R /XYZ 71.731 279.157 null] +>> endobj +5095 0 obj << +/D [5075 0 R /XYZ 71.731 260.587 null] +>> endobj +5096 0 obj << +/D [5075 0 R /XYZ 71.731 209.594 null] +>> endobj +5097 0 obj << +/D [5075 0 R /XYZ 71.731 186.581 null] +>> endobj +5098 0 obj << +/D [5075 0 R /XYZ 188.024 173.729 null] +>> endobj +5099 0 obj << +/D [5075 0 R /XYZ 158.345 147.826 null] +>> endobj +5100 0 obj << +/D [5075 0 R /XYZ 71.731 48.817 null] +>> endobj +5074 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F44 2037 0 R /F33 1306 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +5103 0 obj << +/Length 626 +/Filter /FlateDecode +>> +stream +x�͖Mo�0�����8�ܚ�L��)Rs[wp�45����!i�4]�.�r�?�����1�R?lyzT5$�d¬�!+S3_F��p��Y�t5rg�Z&�Z�[t� Us%�g�Z%?���i��;�!��v��-�?/���ۼ*�?��T�ffi��u����H������j��|z1�!�${��L@>��q�|�[�D�B�u��VфY!0�&�������l��C)*�"0<KC3ܴ�]��1Hyo`,y ���>��$oZ�����r���.���d�aݚ��j�a 5 ��M���# 6.T�H˶��Z�Z�-��P��dz�?؝��Lg]���C�+�2�i���1�ϔ����� +ힱ�B����c���T&w!��E���Wb��8bB)���ԑ��ݮs����9�_�ίe�B��L�r9Y�P�j�Z���}}�O�0,���6FNǼ��=���^<b�:�];��R\�{�]��e�Γ���v�U��cp���e�7����qw�������6{�����P�_�w�u���4����h����T�@�Tj���^��jp��� ����}�c����rr7c�BD�a�(F���)�|4�5endstream +endobj +5102 0 obj << +/Type /Page +/Contents 5103 0 R +/Resources 5101 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 5012 0 R +>> endobj +5104 0 obj << +/D [5102 0 R /XYZ 71.731 729.265 null] +>> endobj +5105 0 obj << +/D [5102 0 R /XYZ 71.731 741.22 null] +>> endobj +5106 0 obj << +/D [5102 0 R /XYZ 71.731 718.306 null] +>> endobj +5107 0 obj << +/D [5102 0 R /XYZ 158.345 659.527 null] +>> endobj +5108 0 obj << +/D [5102 0 R /XYZ 71.731 618.68 null] +>> endobj +5109 0 obj << +/D [5102 0 R /XYZ 71.731 593.609 null] +>> endobj +5110 0 obj << +/D [5102 0 R /XYZ 188.024 582.814 null] +>> endobj +5111 0 obj << +/D [5102 0 R /XYZ 181.907 569.863 null] +>> endobj +5112 0 obj << +/D [5102 0 R /XYZ 158.345 556.912 null] +>> endobj +5113 0 obj << +/D [5102 0 R /XYZ 71.731 516.065 null] +>> endobj +5114 0 obj << +/D [5102 0 R /XYZ 71.731 493.051 null] +>> endobj +5115 0 obj << +/D [5102 0 R /XYZ 188.024 480.199 null] +>> endobj +5116 0 obj << +/D [5102 0 R /XYZ 181.907 467.248 null] +>> endobj +5117 0 obj << +/D [5102 0 R /XYZ 158.345 454.296 null] +>> endobj +5118 0 obj << +/D [5102 0 R /XYZ 71.731 413.45 null] +>> endobj +5119 0 obj << +/D [5102 0 R /XYZ 71.731 388.379 null] +>> endobj +5120 0 obj << +/D [5102 0 R /XYZ 188.024 377.584 null] +>> endobj +5121 0 obj << +/D [5102 0 R /XYZ 181.907 364.633 null] +>> endobj +5122 0 obj << +/D [5102 0 R /XYZ 158.345 351.681 null] +>> endobj +5123 0 obj << +/D [5102 0 R /XYZ 71.731 310.834 null] +>> endobj +5124 0 obj << +/D [5102 0 R /XYZ 71.731 285.763 null] +>> endobj +5125 0 obj << +/D [5102 0 R /XYZ 188.024 274.969 null] +>> endobj +5126 0 obj << +/D [5102 0 R /XYZ 181.907 262.017 null] +>> endobj +5127 0 obj << +/D [5102 0 R /XYZ 158.345 249.066 null] +>> endobj +5128 0 obj << +/D [5102 0 R /XYZ 71.731 208.219 null] +>> endobj +5129 0 obj << +/D [5102 0 R /XYZ 71.731 183.148 null] +>> endobj +5130 0 obj << +/D [5102 0 R /XYZ 188.024 172.354 null] +>> endobj +5131 0 obj << +/D [5102 0 R /XYZ 158.345 146.451 null] +>> endobj +5101 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +5134 0 obj << +/Length 783 +/Filter /FlateDecode +>> +stream +xڽV�r�0��+X�! d�$N=�ԭ���Bb3�@�n��WH�q�h�4/��s�}H���#�O��� 2#^�1���h[��=������F�¡k̞��ȅ5ߥ(`Ԙ%_ͫ�J�$[[6e�!�?�E�s�|W���9o���/^h�Ojej�Lkm7)�6O��mv?��m�1�Ga��%��9`O���8@��u�g���K�dS��s�D��A`+e�M) +��p3�Bj^}�іe��K�l""���4R����"�1S^�W�@em���;I&���� ����z:�������9�"y���9z�(6��K�����I|TU��Q�q�L����>�j����D��V;l��m�e,ТY�k{�0s��xtD|�N�GΑ�C����� +I��`.].���vM�v�Q�U�G����r��K�_�f����V4jzdj�(�S�V[�s��,R� ��m,���c�+t�ȑ�;[��MW���w���;z�9Y��R�u�tRz�0���B�:�k�� +Y�Q�Z���`Ln;p!���<�ʲ�!?���&��x�N�|�X�2��8�I���RH{���\:�Kq����p^�J8�zm����D�e��t�X��' +R�x�y�p[;�}��-�ٓ"��W��@u��N'W6"���i�������b��P��s%�t�*�����s*�Ę�7(�(��"�`=t��<���|����U1h�er�Ċ�5��w<�/uI�p}��3}�����rgrp�d V@Í��S7�C�_����endstream +endobj +5133 0 obj << +/Type /Page +/Contents 5134 0 R +/Resources 5132 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 5012 0 R +>> endobj +5135 0 obj << +/D [5133 0 R /XYZ 71.731 729.265 null] +>> endobj +5136 0 obj << +/D [5133 0 R /XYZ 71.731 718.306 null] +>> endobj +5137 0 obj << +/D [5133 0 R /XYZ 181.907 672.478 null] +>> endobj +5138 0 obj << +/D [5133 0 R /XYZ 158.345 659.527 null] +>> endobj +5139 0 obj << +/D [5133 0 R /XYZ 71.731 618.68 null] +>> endobj +5140 0 obj << +/D [5133 0 R /XYZ 71.731 595.666 null] +>> endobj +5141 0 obj << +/D [5133 0 R /XYZ 188.024 582.814 null] +>> endobj +5142 0 obj << +/D [5133 0 R /XYZ 181.907 569.863 null] +>> endobj +5143 0 obj << +/D [5133 0 R /XYZ 158.345 556.912 null] +>> endobj +5144 0 obj << +/D [5133 0 R /XYZ 71.731 516.065 null] +>> endobj +5145 0 obj << +/D [5133 0 R /XYZ 71.731 490.994 null] +>> endobj +5146 0 obj << +/D [5133 0 R /XYZ 185.534 480.199 null] +>> endobj +5147 0 obj << +/D [5133 0 R /XYZ 155.855 454.296 null] +>> endobj +5148 0 obj << +/D [5133 0 R /XYZ 71.731 413.45 null] +>> endobj +5149 0 obj << +/D [5133 0 R /XYZ 71.731 388.379 null] +>> endobj +5150 0 obj << +/D [5133 0 R /XYZ 188.024 377.584 null] +>> endobj +5151 0 obj << +/D [5133 0 R /XYZ 175.332 364.633 null] +>> endobj +5152 0 obj << +/D [5133 0 R /XYZ 158.345 351.681 null] +>> endobj +1908 0 obj << +/D [5133 0 R /XYZ 71.731 310.834 null] +>> endobj +970 0 obj << +/D [5133 0 R /XYZ 252.009 265.58 null] +>> endobj +5153 0 obj << +/D [5133 0 R /XYZ 71.731 253.409 null] +>> endobj +5154 0 obj << +/D [5133 0 R /XYZ 71.731 233.959 null] +>> endobj +5155 0 obj << +/D [5133 0 R /XYZ 188.024 221.107 null] +>> endobj +5156 0 obj << +/D [5133 0 R /XYZ 182.306 208.155 null] +>> endobj +5157 0 obj << +/D [5133 0 R /XYZ 158.345 195.204 null] +>> endobj +5158 0 obj << +/D [5133 0 R /XYZ 71.731 154.357 null] +>> endobj +5159 0 obj << +/D [5133 0 R /XYZ 71.731 129.286 null] +>> endobj +5160 0 obj << +/D [5133 0 R /XYZ 188.024 118.492 null] +>> endobj +5161 0 obj << +/D [5133 0 R /XYZ 181.907 105.54 null] +>> endobj +5132 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R >> +/ProcSet [ /PDF /Text ] +>> endobj +5164 0 obj << +/Length 746 +/Filter /FlateDecode +>> +stream +xڽ�[o�0���yLb� !��nt�nL�ci�*7q�G.Vb���q.F�*�`�c����sH����A�_n�܁o$E�1�2�.��B콘7�~�yF���g� �� ��E�����y%+S��l�w�!��Z.i��㲑4ϩ�U 3�Ȭ��� +��]ܤJ�9k�����l�����Y�#�n�S4�F�����[��*Y����X�Ȥ1� �ub3C��%�j������x4�Td��"Q(ɆM���J +��=4��@��͵�㫜�K �s|G�Z�_������,y�$nI�뢈�D�N��5�>v.T�뛫2�h��4�D�� G �4O�/A �-܁D�듖;�N.C��ez�8n���u��������Q��#!�������'pk�9g�M>(k��]��+�\{�Ն�}��+$:$���\�z�Ѡ��C4�\�R�t�d(� +gi���6����뵭��y��U�?�V���L5��C��!� +lm�v_tQ�2��N�c�zԬ��u�A��F�KUu��}9Cl�E~��P���M&�-�)�_�I��YU����O�@Å}�9zy�`-�7���E{V��5��?Ye��"�D��S7PQ�����5pL��D���G�B6��9O��kSx4i(>Q��d\&�2e�W��!����.z~�c�;]����C�TيV�6�&�����A"���M���g�v!G� +>836�(�� ��h?F��]�endstream +endobj +5163 0 obj << +/Type /Page +/Contents 5164 0 R +/Resources 5162 0 R +/MediaBox [0 0 609.714 789.041] +/Parent 5186 0 R +>> endobj +5165 0 obj << +/D [5163 0 R /XYZ 71.731 729.265 null] +>> endobj +5166 0 obj << +/D [5163 0 R /XYZ 158.345 708.344 null] +>> endobj +5167 0 obj << +/D [5163 0 R /XYZ 71.731 667.497 null] +>> endobj +5168 0 obj << +/D [5163 0 R /XYZ 71.731 642.426 null] >> endobj -4993 0 obj << -/D [4967 0 R /XYZ 71.731 154.357 null] +5169 0 obj << +/D [5163 0 R /XYZ 188.024 631.631 null] >> endobj -4994 0 obj << -/D [4967 0 R /XYZ 71.731 129.286 null] +5170 0 obj << +/D [5163 0 R /XYZ 182.306 618.68 null] >> endobj -4995 0 obj << -/D [4967 0 R /XYZ 188.024 118.492 null] +5171 0 obj << +/D [5163 0 R /XYZ 158.345 605.729 null] >> endobj -4996 0 obj << -/D [4967 0 R /XYZ 175.332 105.54 null] +5172 0 obj << +/D [5163 0 R /XYZ 71.731 564.882 null] >> endobj -4966 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R >> -/ProcSet [ /PDF /Text ] +5173 0 obj << +/D [5163 0 R /XYZ 71.731 539.811 null] >> endobj -4999 0 obj << -/Length 552 -/Filter /FlateDecode ->> -stream -xڽ�ˎ�0��}�,�E_�&�n` -�@Q5T��4rcOb�8V��O�si˴L�X�H������sbc�{�u I �1/-'��\�����(���y��o(��̨�y�h� u��3�m��������!���C�mË�7��n$L��q��A�|Y��U%�BZ�ms7Yl�d�F0��U��悞D'���y�! ���J�R�g�yӘy8f-��y-,TRJX���~��Vm�JX��md4{���7o[H���MYt���1�a�(Iz�5���M��K.d=�!0���5H��aLo�����8��['�g��]�:�aj�>��ɫ:�{�X~\�gAπ��gx�\�^r~���k���_"E�� ��~*W�#�1�-`̇ƈ?�_)�~�37r���Iʎ˥U�Uo}�{�f�W���(̯�hYv���x������P� ��H��^��N�V�1����� t�Z��0�U��OC��t�p�3k��蜺��=�q_6��iNG�ܜ�� -c���u�\\Q�P�hrX��ƈ�t�\z���b�endstream -endobj -4998 0 obj << -/Type /Page -/Contents 4999 0 R -/Resources 4997 0 R -/MediaBox [0 0 609.714 789.041] -/Parent 4905 0 R +5174 0 obj << +/D [5163 0 R /XYZ 188.024 529.016 null] >> endobj -5000 0 obj << -/D [4998 0 R /XYZ 71.731 729.265 null] +5175 0 obj << +/D [5163 0 R /XYZ 175.332 516.065 null] >> endobj -5001 0 obj << -/D [4998 0 R /XYZ 158.345 708.344 null] +5176 0 obj << +/D [5163 0 R /XYZ 158.345 503.113 null] >> endobj -5002 0 obj << -/D [4998 0 R /XYZ 71.731 667.497 null] +5177 0 obj << +/D [5163 0 R /XYZ 71.731 462.267 null] >> endobj -5003 0 obj << -/D [4998 0 R /XYZ 71.731 644.483 null] +5178 0 obj << +/D [5163 0 R /XYZ 71.731 439.253 null] >> endobj -5004 0 obj << -/D [4998 0 R /XYZ 188.024 631.631 null] +5179 0 obj << +/D [5163 0 R /XYZ 188.024 426.401 null] >> endobj -5005 0 obj << -/D [4998 0 R /XYZ 181.907 618.68 null] +5180 0 obj << +/D [5163 0 R /XYZ 181.907 413.45 null] >> endobj -5006 0 obj << -/D [4998 0 R /XYZ 158.345 605.729 null] +5181 0 obj << +/D [5163 0 R /XYZ 158.345 400.498 null] >> endobj -5007 0 obj << -/D [4998 0 R /XYZ 71.731 564.882 null] +5182 0 obj << +/D [5163 0 R /XYZ 71.731 359.651 null] >> endobj -5008 0 obj << -/D [4998 0 R /XYZ 71.731 539.811 null] +5183 0 obj << +/D [5163 0 R /XYZ 71.731 334.58 null] >> endobj -5009 0 obj << -/D [4998 0 R /XYZ 188.024 529.016 null] +5184 0 obj << +/D [5163 0 R /XYZ 188.024 323.786 null] >> endobj -5010 0 obj << -/D [4998 0 R /XYZ 158.345 503.113 null] +5185 0 obj << +/D [5163 0 R /XYZ 158.345 297.883 null] >> endobj -4997 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R >> +5162 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R >> /ProcSet [ /PDF /Text ] >> endobj -5013 0 obj << +5189 0 obj << /Length 2688 /Filter /FlateDecode >> stream -xڭˎ�8�0|�5z�={J�� ��"@��v�@Kt�=QN��~�EJ�V'�E-��X,�Iǫ��U�e -�d&E���7��0����"+�0�/ wyZ���t��qx����I�J��������%J�$-V������j��f��w�������w|��������n�āM�1�7S�����{��}�/R�*Z�@�Rv�c�q���(��xˣ�j�N<L�(��U����.��"����yG�u0���Y�g�G��_�S�D#9�������� ���8�KWӉ���U��" �=C6e���Ȳ/���P�_�(�4��������-�t��Ө������� ��õ���a��K:�Y�G]��ƞ���g�tm�8��&�� 0����m�b�8�<���d��3S��9�.�N�{4�#ό@���j�~�����C��t�a�x�;��,c��ܑ��A���gm^��8�s6��I���p�-ج����?`�-����͂V}� �٪�0ҨԿ�C��2�d��e�4t�Qw<w����6��Ŧsj�I:'<����o�v��{xv�=�e��U~kf��=}D�QW��E{�h.i�Y�l7"����_X@ ���x�iH =Lھ6�+[д��A9�`�iշ�*�q�i�7 -�I�=5u}爉�ȃ�1�������-C�&p�m'�A[=�Nt[�q�.p�>h���KF�����C�U��}�#*T�x� ^Z�K�����4����wK8�55�$P���=�uG�߈.��(J*���ȭ��� !��܆^6HDi*^H -��Ba����ӯ��#�oD��}5�8�����a��a�U'�Ǔy�J�7)0C� �NQv�W,7���%A1�0l/v�4���d�;�a�?��8E�!�`�V��A��!C?�;����u�pLɘ�Ӄjx�4����-c���a��b�\����ѵ��C�@[���˳�t�t����Q�L�48) �:�2�f�z�,ㄴXbD�ɉJ����x���,n�³���/aњ' :Fc'��i�R��q"�H;��AT�3ʗ�q!���p�}J d�x'{�-��Z[��M�c0�#��@�bȓ��bT�7S��S���K���e ��O�me���6��;�YFn,��X8 4����_ޢJ���m~�IP���.I��B,�PW�Fr�|�L�A��7�����Vd�� �]��l� -�e��wr��I�>�s�N�N\����,�p���IR�`<h�d�X��3��*s�dGt>O̓I��5T i/�R(��~�F_���0�tW�Bx�t9�n"�:�ƌWq�� ��d����Ujq9+�b��ᮌ�<�z��u ��O�4@�5:m J1��9*��Ί�`� ����<>\�r�V�6-�:�M�6�JjXc܆h��l)��[�m����Lr��t��F%$�X���!ùp���{�s�R�KńDd�2)�;���uw���ԍ�"bzm�AȐ��zX��������IΒ筇�id��A!���(��!�*#%������2�oi�֟�P���t�k��ؒ����4�]E�)�|�DD���������s��=�}q�D����5���z�zA���q{ -$I=+1ʻ���gG=p�F�V�_�|�7 �E=�WT�di�v��������R�ts�]�t�k�@���J>����I��z�*��D`�4tA0�^,s� zʳ0�5�l���T5;+P�^�(\_:��.�O�WW�]�W,��Z+�?��E��,��Pɉz ���ǃ�6 -�9�>s�e��%�<&�a��,=ݼ�9y�M��G3a7 !�舨�B�#�N��@)-&���OT]ެ_8Q�NNG�g#9ߨ��}���t+59@��g5F-(`���n�������>hM�&*�e����[���#�['�39�/#$S�g�O(oly>=���%��"y�3�Hdz�{2H������������{�g?��to��3��vnH'���I -���w"4S�� V`4�9A`gh�{�ç�0('����u��aJZ�5SuuS��Ɲ�W��]6��B0��m2�\kŢ����f�������W^�7F��f!��U#��fl�Ȃ�0ˤ�C%o#��ĸ�yP��kR���ݒK�I�.u<��|9F@%O P\Q���`~�,rϊ��|-�ʪ��Q_:�v)E��σ -��=����`�&]ή&�#��ZH��g�<��� 3>ܜd���ꏔ�~$��$�w����%��9�}��n`�+¦��wK��" -(�6�z E �b,y|7�,����T̋.�I��@T)F��jůk�~b*U4�MO��"V��1�.�U���Aڳ����?�,4o(Sx~A3�:`�C�W"a P=�W&�rA�e��������fJrK�c��f����b��|x�Ny��t$��(�0j��噠vdR&�E��J��3'�}D�R����"J�G71��W�{\�f�ɯ"�=C�H���$�����@p\�O^v^�0jl�r|��8�i��=1��R ��"�0���B50/ -�o><��W��.����_�b7��o��|��'Ix��j���V�gȗ{�����endstream +xڭˎ�8�0|�5zZ��S�MYL�g���Z����a�rz��^��D�\ �Ȫb�X�'���KWUW9|�C���UݽJV����U*�~ge��̫�p��v3o^��>�WY�����vI�8���������E���k�˪��]��_��;�[�y����v�7i�F3���Ժwz��^���9n��v I%���I�4����2��8��裲���Y�$����#+���x�����I��ٚ��K�E�gR&o�_�S�D#9��������MZFõo�D[~�k��>��C6U���ʲO���P�_�(�<O�fpc���5�t�K������x����y腓q��a +�.+:�E�Ό�nXW���Zt�3��1n��ɒ�JL�9�i����2�χ�0?��r��Tl@nN����M��3#PϦ��v�de���X�:_�U��%��N.�(��:w"6��j������e��p&���r�����ʜX���� 쁬�"��g�P����ꯪ� +#�J�k<��-�+{�g-�'k�qF���+�g�������&��H�����%�I 8��I����sW2tkT�����@� �']�f"d�5�����zfs�������j�\`�d�3�HCȀ`� �9=�M���6(gY��C�i[�Cm�|�����sPS?���(�e3�^�8�5�2�mG�&pr��i�:��oAā��IH����ckA��A��`��yP�Ǜm�Ђ�]8,q�gqɧ�i�W.w��-���4 ��@�� ��ם�~��?�$�):�#w����2s� �x!)�Hg +� 3�L?��о�����Ӹ�2N�i��V�0�j�Ep*1�l�jnȈ��r�R�A\O. ��awuc��n'��Q�������9z�sv��"���ad�)d�ί㘅cJ�4н��奟иjF�z����v�1s�2"�wD7ڙ� Ql},�������ksG�3���0$����l/���U�p��b��!'�82��hF������ +��Dk������[�=�Z���#��r@tQ��(�U���<���rJ �;;`l��� � �� 4�$jq�!O�&�Q�_L��}�%�#/��K��5dW�2<�Է�@�A���o @/d��l~cY�|p�(Z���py�*������fQ�ze�$a(���GU<�6����+U6�8���@�M���L!A�����˨�wr��Y�!�s��#�N|����,�p��=�IR�`l5e2N,�˙����P�#��������*�tx)�AN��c(�}~�����k�T��2�.�$��p�m@�QGӚ�A\=`��1��6�a}G�ZZ�ʷx{�+�ϩ^�`v�S: ��j �^[R�!{�����b4X:���6 ���~���o������:%��1~C�|b��cn�-ܶ(#hf�c!�a`�����A��"䎘�\8x��=̿�9j)ܥbB"�� w����� �ܕ�;�S`�VD1���(f��i=��xa�e���$I���C�42z롐雯(��!�+#%���p]/e8�����?J�ę3��v�LC�%I�i��S$�d���#3y��e��s,��8��P���T`˚RJ=a���y��� ���*1�����gO=Z8m�B+�o�T�i������ϊ<Z�J�������R�ts�]����@���J>���HOT��E}"pX� XH/V����=�Y�4�s6Pqf�۫���H/Z��:��-��gs����.�+�PM-��_�O@ hQ��&Tq�^B���v��ꃍr]Ȝ0�G/�gI� O� i+3GO7���R�<��Pߣ����j�DT@!ʼnj/Uc ���3��`�g�.o�/�h�OOG�g#9ߨ��}���t+59@��e�0_@�(Q���CP�&`��2D���-��n�ϯ���)��3H�'�7���Yn�Qr�<�d$2=�����"$��B��7P`w��Z|��'8��͛r�9�� �dwE5Iᶷ�^�v*[!� +�='��������$����.�?LCIkpf��n��и���n�˦Z��M�]V�k��XT�1�a���2��ڎ|�U~c4�l«P5"�hƖ�,�BZ:T�V0B� *���EP��$5��-��d�S�W@(��� �+ +��,,�E�Y1���U�|Yu�6J��.e_E���0~Of��+��IW�+� ��v��E9���_dƇ���l �PY���ۏ$���F՟�D���/���^� l~Eؔ��n)U� +�� �^BQ�K^��_9���Ad�ϋ.�I��@T )F�V���ab*U4���'Fn����A�)��� �E�\j��d�7�)<�����V� +��+�����+B���2�opL��ZE3%�%�1�~1Z��y1�y><����LBz�ktI����L�x2)�`��b��%�˙�>�]��� W{ %NܫH�=n`�*�W�^�Z�z�I,D[�r 8��'/;/o�F �N +9>A|��t������)onK�V� +y����W���_qߥ�⯇B��H�C�e��.�<N��BM}r��V�g�o������endstream endobj -5012 0 obj << +5188 0 obj << /Type /Page -/Contents 5013 0 R -/Resources 5011 0 R +/Contents 5189 0 R +/Resources 5187 0 R /MediaBox [0 0 609.714 789.041] -/Parent 4905 0 R +/Parent 5186 0 R >> endobj -5014 0 obj << -/D [5012 0 R /XYZ 71.731 729.265 null] +5190 0 obj << +/D [5188 0 R /XYZ 71.731 729.265 null] >> endobj -1866 0 obj << -/D [5012 0 R /XYZ 71.731 718.306 null] +1909 0 obj << +/D [5188 0 R /XYZ 71.731 718.306 null] >> endobj -946 0 obj << -/D [5012 0 R /XYZ 530.903 703.236 null] +974 0 obj << +/D [5188 0 R /XYZ 530.903 703.236 null] >> endobj -5015 0 obj << -/D [5012 0 R /XYZ 71.731 682.175 null] +5191 0 obj << +/D [5188 0 R /XYZ 71.731 682.175 null] >> endobj -5016 0 obj << -/D [5012 0 R /XYZ 71.731 672.06 null] +5192 0 obj << +/D [5188 0 R /XYZ 71.731 672.06 null] >> endobj -5017 0 obj << -/D [5012 0 R /XYZ 71.731 662.097 null] +5193 0 obj << +/D [5188 0 R /XYZ 71.731 662.097 null] >> endobj -1867 0 obj << -/D [5012 0 R /XYZ 71.731 638.283 null] +1910 0 obj << +/D [5188 0 R /XYZ 71.731 638.283 null] >> endobj -950 0 obj << -/D [5012 0 R /XYZ 168.205 594.97 null] +978 0 obj << +/D [5188 0 R /XYZ 168.205 594.97 null] >> endobj -5018 0 obj << -/D [5012 0 R /XYZ 71.731 586.147 null] +5194 0 obj << +/D [5188 0 R /XYZ 71.731 586.147 null] >> endobj -5019 0 obj << -/D [5012 0 R /XYZ 71.731 527.418 null] +5195 0 obj << +/D [5188 0 R /XYZ 71.731 527.418 null] >> endobj -5020 0 obj << -/D [5012 0 R /XYZ 71.731 485.64 null] +5196 0 obj << +/D [5188 0 R /XYZ 71.731 485.64 null] >> endobj -1868 0 obj << -/D [5012 0 R /XYZ 71.731 415.902 null] +1911 0 obj << +/D [5188 0 R /XYZ 71.731 415.902 null] >> endobj -954 0 obj << -/D [5012 0 R /XYZ 312.796 370.747 null] +982 0 obj << +/D [5188 0 R /XYZ 312.796 370.747 null] >> endobj -5021 0 obj << -/D [5012 0 R /XYZ 71.731 358.576 null] +5197 0 obj << +/D [5188 0 R /XYZ 71.731 358.576 null] >> endobj -5022 0 obj << -/D [5012 0 R /XYZ 71.731 316.147 null] +5198 0 obj << +/D [5188 0 R /XYZ 71.731 316.147 null] >> endobj -5023 0 obj << -/D [5012 0 R /XYZ 71.731 285.262 null] +5199 0 obj << +/D [5188 0 R /XYZ 71.731 285.262 null] >> endobj -5024 0 obj << -/D [5012 0 R /XYZ 71.731 202.573 null] +5200 0 obj << +/D [5188 0 R /XYZ 71.731 202.573 null] >> endobj -5025 0 obj << -/D [5012 0 R /XYZ 71.731 171.688 null] +5201 0 obj << +/D [5188 0 R /XYZ 71.731 171.688 null] >> endobj -5026 0 obj << -/D [5012 0 R /XYZ 71.731 140.804 null] +5202 0 obj << +/D [5188 0 R /XYZ 71.731 140.804 null] >> endobj -5011 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F33 1278 0 R >> +5187 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -5029 0 obj << -/Length 3081 +5205 0 obj << +/Length 3082 /Filter /FlateDecode >> stream @@ -18947,56 +19508,56 @@ G& �1�g���+�dž1f^H z��v���D���hO��s����**n\�$Ł_Ô ��5֝Q��P]7F?�אѐ*�ī�`���r]�$8j�ߣ�̰wx��k���Τ��x6���+��1����\^�?���fFd��{�<8�٥k2�[;�6>T�=MZN���r���>˹'Qb�tZ��m3Ή�LB~2�EҌsTY��c��8yt焫��_�~�n�v���TI!C���n��vFb<�.ZflOj�����$N]J���.rZ�.�锤��I�X��2�I�熅��(e��r�����{B�"q�8RJS�7��cړ� ��-T�Rq�ո�F"�g$�n,�d���0�To-�H�L\$�1����ʉ)P���nb���fH��2��g��E�\I��E�8�G^ Fۥ��2�Ѿ'w-6���Kd�*����/�1I4�bVc����-�nl�If��f�ƞ�Piҟ����yJ̴820��+�P�Lu�EK1�G�Tִ h�k���'��4�8=,�b?�l�j}�d�;��dI���*$���`��H������.w@(�-�&�~[acA��1��c�Tl`wc{?��i���;º����6q��O8�閪�w-;�*�U��g�C|_q�K���jU���oq}<8�Ův�<�/Ǔqi�5���� $!,���f��YPWT~(���."��iu�,��6�(;V1U��Ɂ -�R�^p�y�|bw�U�9%݅�pw �N�����B��z��B�0k��K�̫�ci��<�^��j��j�~.��| �ȭ��p�ڨҵ ��|���Dx�t LM5�gWo@1(�n��p+'n���05Ճ0'o_�vy���ׇ�,�~)�V����9�:4��yD�2r_�~�2���x����L���h�Oo���\��6B�]eϞ%���$�a��H���D~X��b o������������幢d+�I�w"2�e�71\�.�+-���w�f����@U�SV�<���X&)�_3�*=V�u�&N�)���پj&�H�]D����k��/�`�+!�=����[;i&�-��'N���;�7�(t����9�)�V����h�ֳ���ς4������Z1m��gE����!A�p����_�?��3�endstream +�R�^p�y�|bw�U�9%݅�pw �N�����B��z��B�0k��K�̫�ci��<�^��j��j�~.��| �ȭ��p�ڨҵ ��|���Dx�t LM5�gWo@1(�n��p+'n���05Ճ0'o_�vy���ׇ�,�~)�V����9�:4��yD�2r_�~�2���x����L���h�Oo���\��6B�]eϞ%���$�a��H���D~X��b o������������幢d+�I�w"2�e�71\�.�+-���w�f����@U�SV�<���X&)�_3�*=V�u�&N�)���پj&�H�]D����k��/�`�+!�=����[;i&�-��'N���;�7�(t����9�)�V����h�ֳ���ς4������Z1m��gE'�098,H^������r4/endstream endobj -5028 0 obj << +5204 0 obj << /Type /Page -/Contents 5029 0 R -/Resources 5027 0 R +/Contents 5205 0 R +/Resources 5203 0 R /MediaBox [0 0 609.714 789.041] -/Parent 5038 0 R +/Parent 5186 0 R >> endobj -5030 0 obj << -/D [5028 0 R /XYZ 71.731 729.265 null] +5206 0 obj << +/D [5204 0 R /XYZ 71.731 729.265 null] >> endobj -5031 0 obj << -/D [5028 0 R /XYZ 71.731 662.351 null] +5207 0 obj << +/D [5204 0 R /XYZ 71.731 662.351 null] >> endobj -5032 0 obj << -/D [5028 0 R /XYZ 71.731 592.613 null] +5208 0 obj << +/D [5204 0 R /XYZ 71.731 592.613 null] >> endobj -1869 0 obj << -/D [5028 0 R /XYZ 71.731 535.826 null] +1912 0 obj << +/D [5204 0 R /XYZ 71.731 535.826 null] >> endobj -958 0 obj << -/D [5028 0 R /XYZ 237.066 492.728 null] +986 0 obj << +/D [5204 0 R /XYZ 237.066 492.728 null] >> endobj -5033 0 obj << -/D [5028 0 R /XYZ 71.731 480.29 null] +5209 0 obj << +/D [5204 0 R /XYZ 71.731 480.29 null] >> endobj -5034 0 obj << -/D [5028 0 R /XYZ 71.731 401.331 null] +5210 0 obj << +/D [5204 0 R /XYZ 71.731 401.331 null] >> endobj -1870 0 obj << -/D [5028 0 R /XYZ 71.731 381.341 null] +1913 0 obj << +/D [5204 0 R /XYZ 71.731 381.341 null] >> endobj -962 0 obj << -/D [5028 0 R /XYZ 254.178 338.244 null] +990 0 obj << +/D [5204 0 R /XYZ 254.178 338.244 null] >> endobj -5035 0 obj << -/D [5028 0 R /XYZ 71.731 325.806 null] +5211 0 obj << +/D [5204 0 R /XYZ 71.731 325.806 null] >> endobj -5036 0 obj << -/D [5028 0 R /XYZ 71.731 231.838 null] +5212 0 obj << +/D [5204 0 R /XYZ 71.731 231.838 null] >> endobj -5037 0 obj << -/D [5028 0 R /XYZ 71.731 200.953 null] +5213 0 obj << +/D [5204 0 R /XYZ 71.731 200.953 null] >> endobj -5027 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R >> +5203 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R >> /ProcSet [ /PDF /Text ] >> endobj -5041 0 obj << +5216 0 obj << /Length 3186 /Filter /FlateDecode >> @@ -19009,129 +19570,129 @@ V �o'���k������r.����Ea���Ѓ,�A �%aB� ,v�ZhT�TTф'Ve�(&x�n���-_⍔�X�do�L��ѫ^dה�c~��v��)Nd$��šW�B%Ir����FY�c�B﨓G#,pQ���С#z a�c�ue�x[� z@T6yL`*#r�*kPOym�"cHh8��\ ���!o���!�Y�ƨ'�D����)�"����ӡ���!�jBKk�CC bN���?,��k���4���L`hN��a�RJ���?�'>l[��0CF'���n�ђ ����fl[�48��ޑ�ԓ+�2(�q�{��W��v1�a]bɾ5W��)�I,��˒ 7B���'�����G�Dv��M�9�Y�D�dj$ȉ��є�Cs�F�A:5F�h*������f�n�����H}G��� pnGƒ��3va�t����M����t��=��>��r�dU{˚�uu�Z���!���Jw8���� �aE�g�Z;����)��շR�3f��ʰ��E,�qW qȭk\��ed����������X�����Eн6t�8�[��p?�O�c��a[���>}Y%a��%aݮ�TET�.���}q�p�qŰw�0V-gJ�\x�^L"�;�%��l��\B��V� ��Щ�!�N����~�U����l|��@��h�י�dz2k��01)T�mؐc���#C_r5�`�"N����͚�zl�Vh��R� r �M@G��_o�9�QQ�}/ O�}KcZ����E`��(oh���[��ذ�׀����RW�-J$����a�b���b�b�ޟ����P۪ܔL�QYQe��B�q����B����x�������g��e�*��2�H��t�Lf�,�����X��Z�r���\�16gg�F�RZ<:�w��?l��&g��O�/���M������L�(��x%� -$�m��2P&{�;�c��&��L�J/O�|���ʾ��5CV�K�~%�i"��nANu0�KT���Fҭy�"��3�( n��E���z,Q+�Ghu��J� �5Y� K��B��"�r�����X�l�=+0�>��)�%$�Џ�p�Y0K�Ȁ �~Y<�)�ǧ�B{��b��e_p��F:��"��A8�6�-�1��n�0j��ũ��@�y����!��������|/?���ծ���b2I�G`0��a��"D������܀�_�Nש���Ƶ�ߌa�+��g0��=+��+��0l�����O�D�©�Eo�ы��|)#ЌN�UYI�aN@�H��1r��X/&��Xo)~&y�ڐ�/�����W~Y3pV�:�Ǖ-�X�C�v�|�@4��O$�/d���8�~ S�'��ң�)������endstream +$�m��2P&{�;�c��&��L�J/O�|���ʾ��5CV�K�~%�i"��nANu0�KT���Fҭy�"��3�( n��E���z,Q+�Ghu��J� �5Y� K��B��"�r�����X�l�=+0�>��)�%$�Џ�p�Y0K�Ȁ �~Y<�)�ǧ�B{��b��e_p��F:��"��A8�6�-�1��n�0j��ũ��@�y����!��������|/?���ծ���b2I�G`0��a��"D������܀�_�Nש���Ƶ�ߌa�+��g0��=+��+��0l�����O�D�©�Eo�ы��|)#ЌN�UYI�aN@�H��1r��X/&��Xo)~&y�ڐ�/�����W~Y3pV�:�Ǖ-�X�C�v�|�@4��O$�/d���8�~ S���ң�)��Ø��endstream endobj -5040 0 obj << +5215 0 obj << /Type /Page -/Contents 5041 0 R -/Resources 5039 0 R +/Contents 5216 0 R +/Resources 5214 0 R /MediaBox [0 0 609.714 789.041] -/Parent 5038 0 R +/Parent 5186 0 R >> endobj -5042 0 obj << -/D [5040 0 R /XYZ 71.731 729.265 null] +5217 0 obj << +/D [5215 0 R /XYZ 71.731 729.265 null] >> endobj -5043 0 obj << -/D [5040 0 R /XYZ 71.731 741.22 null] +5218 0 obj << +/D [5215 0 R /XYZ 71.731 741.22 null] >> endobj -5044 0 obj << -/D [5040 0 R /XYZ 71.731 718.306 null] +5219 0 obj << +/D [5215 0 R /XYZ 71.731 718.306 null] >> endobj -1871 0 obj << -/D [5040 0 R /XYZ 71.731 688.254 null] +1914 0 obj << +/D [5215 0 R /XYZ 71.731 688.254 null] >> endobj -966 0 obj << -/D [5040 0 R /XYZ 201.827 645.157 null] +994 0 obj << +/D [5215 0 R /XYZ 201.827 645.157 null] >> endobj -5045 0 obj << -/D [5040 0 R /XYZ 71.731 636.334 null] +5220 0 obj << +/D [5215 0 R /XYZ 71.731 636.334 null] >> endobj -5046 0 obj << -/D [5040 0 R /XYZ 71.731 582.586 null] +5221 0 obj << +/D [5215 0 R /XYZ 71.731 582.586 null] >> endobj -5047 0 obj << -/D [5040 0 R /XYZ 71.731 577.605 null] +5222 0 obj << +/D [5215 0 R /XYZ 71.731 577.605 null] >> endobj -5048 0 obj << -/D [5040 0 R /XYZ 89.664 556.848 null] +5223 0 obj << +/D [5215 0 R /XYZ 89.664 556.848 null] >> endobj -5049 0 obj << -/D [5040 0 R /XYZ 71.731 528.788 null] +5224 0 obj << +/D [5215 0 R /XYZ 71.731 528.788 null] >> endobj -5050 0 obj << -/D [5040 0 R /XYZ 89.664 513.012 null] +5225 0 obj << +/D [5215 0 R /XYZ 89.664 513.012 null] >> endobj -5051 0 obj << -/D [5040 0 R /XYZ 71.731 485.326 null] +5226 0 obj << +/D [5215 0 R /XYZ 71.731 485.326 null] >> endobj -5052 0 obj << -/D [5040 0 R /XYZ 89.664 469.177 null] +5227 0 obj << +/D [5215 0 R /XYZ 89.664 469.177 null] >> endobj -5053 0 obj << -/D [5040 0 R /XYZ 71.731 467.02 null] +5228 0 obj << +/D [5215 0 R /XYZ 71.731 467.02 null] >> endobj -5054 0 obj << -/D [5040 0 R /XYZ 89.664 451.244 null] +5229 0 obj << +/D [5215 0 R /XYZ 89.664 451.244 null] >> endobj -5055 0 obj << -/D [5040 0 R /XYZ 71.731 449.087 null] +5230 0 obj << +/D [5215 0 R /XYZ 71.731 449.087 null] >> endobj -5056 0 obj << -/D [5040 0 R /XYZ 89.664 433.311 null] +5231 0 obj << +/D [5215 0 R /XYZ 89.664 433.311 null] >> endobj -5057 0 obj << -/D [5040 0 R /XYZ 71.731 431.154 null] +5232 0 obj << +/D [5215 0 R /XYZ 71.731 431.154 null] >> endobj -5058 0 obj << -/D [5040 0 R /XYZ 89.664 415.378 null] +5233 0 obj << +/D [5215 0 R /XYZ 89.664 415.378 null] >> endobj -5059 0 obj << -/D [5040 0 R /XYZ 71.731 400.987 null] +5234 0 obj << +/D [5215 0 R /XYZ 71.731 400.987 null] >> endobj -5060 0 obj << -/D [5040 0 R /XYZ 89.664 384.494 null] +5235 0 obj << +/D [5215 0 R /XYZ 89.664 384.494 null] >> endobj -5061 0 obj << -/D [5040 0 R /XYZ 71.731 371.443 null] +5236 0 obj << +/D [5215 0 R /XYZ 71.731 371.443 null] >> endobj -5062 0 obj << -/D [5040 0 R /XYZ 89.664 353.61 null] +5237 0 obj << +/D [5215 0 R /XYZ 89.664 353.61 null] >> endobj -5063 0 obj << -/D [5040 0 R /XYZ 71.731 351.453 null] +5238 0 obj << +/D [5215 0 R /XYZ 71.731 351.453 null] >> endobj -5064 0 obj << -/D [5040 0 R /XYZ 89.664 335.677 null] +5239 0 obj << +/D [5215 0 R /XYZ 89.664 335.677 null] >> endobj -5065 0 obj << -/D [5040 0 R /XYZ 71.731 294.666 null] +5240 0 obj << +/D [5215 0 R /XYZ 71.731 294.666 null] >> endobj -5066 0 obj << -/D [5040 0 R /XYZ 89.664 278.89 null] +5241 0 obj << +/D [5215 0 R /XYZ 89.664 278.89 null] >> endobj -5067 0 obj << -/D [5040 0 R /XYZ 71.731 237.879 null] +5242 0 obj << +/D [5215 0 R /XYZ 71.731 237.879 null] >> endobj -5068 0 obj << -/D [5040 0 R /XYZ 89.664 222.103 null] +5243 0 obj << +/D [5215 0 R /XYZ 89.664 222.103 null] >> endobj -5069 0 obj << -/D [5040 0 R /XYZ 71.731 206.995 null] +5244 0 obj << +/D [5215 0 R /XYZ 71.731 206.995 null] >> endobj -5070 0 obj << -/D [5040 0 R /XYZ 89.664 191.219 null] +5245 0 obj << +/D [5215 0 R /XYZ 89.664 191.219 null] >> endobj -5071 0 obj << -/D [5040 0 R /XYZ 71.731 176.111 null] +5246 0 obj << +/D [5215 0 R /XYZ 71.731 176.111 null] >> endobj -5072 0 obj << -/D [5040 0 R /XYZ 89.664 160.335 null] +5247 0 obj << +/D [5215 0 R /XYZ 89.664 160.335 null] >> endobj -5073 0 obj << -/D [5040 0 R /XYZ 71.731 158.178 null] +5248 0 obj << +/D [5215 0 R /XYZ 71.731 158.178 null] >> endobj -5074 0 obj << -/D [5040 0 R /XYZ 89.664 142.402 null] +5249 0 obj << +/D [5215 0 R /XYZ 89.664 142.402 null] >> endobj -5075 0 obj << -/D [5040 0 R /XYZ 71.731 135.264 null] +5250 0 obj << +/D [5215 0 R /XYZ 71.731 135.264 null] >> endobj -5039 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R >> +5214 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R >> /ProcSet [ /PDF /Text ] >> endobj -5078 0 obj << -/Length 2664 +5253 0 obj << +/Length 2663 /Filter /FlateDecode >> stream @@ -19144,65 +19705,65 @@ xڝYݏ۸ �� ���p`mF�"��P|Y���x(�P*w��Fw^2A�d��-��ʋa��b(�k�j���H.���n���5��-t³�l����hS��Fѷ����0��TAU�ұCc3mo�e}�~{\�$���;Ё��S��PXC�;&O����3H�<��>q��Re�L I�bg\X��j��uR��C�������78�^�=���KA�t�NB�0�v� ;������1L��ap�D���q��Eh{3E4��a�f��,ⷎ{ Dip����7.��.�F��) �:qW�0��uk`�C�A[1�s���s���/�)@%�g��Gh3��y.��9����3��n7Q��z�k��eo�{����7���M��Lˑ��@�S�{�|�䯶?3]A&�qc���U����ah*e'Q��f�Ȓ���~f�,0��d��� �D��^sZF�i@����D6�>t�#|�,���Y��������DL�w-Ԫ�yF���z�J���ꭄ���E�D��3�˝@�Z �zl�㡹HD�蝹���'�����k=��S��]�? ڡG�A�gAp�g9]�/m�TM0�K�7�X�Ds�H���1L!Re�%t-Q�(�+���Ls@#e h�3n�e�{�&CAQ;�p������'J ���=�J�!����Cƙ�q�Sm�?~�$}<r�����N�'͉�{��i<�n�A$!�:PE�^S^-�`*�0��EA �n��.�g������tɔ�3��0���A㡱�D�h�rRfEYe/�uF��.��y© [�8��x�w��z��a���" ����JZP ���{X����\J�b�P�wa�����MK��f-�:����J�S� �.{�*���ɟ�)4�$�Ie����R@2�%e��.�?��6��&�[�kV��R�f�n��<_��R$��ޛ�G��T=��~X��e��$�E��fܔҘ�1������0����G��� �� �����P#���coF ���S �H%��;�V"�P�:*|̑{ f�,�܊{� ��{q���k<��g@�oW���� M��<�z�i�6Wѩ1�YF7;O}��6��B�l�|u=��>��?�/��C|����,�O?U=ݐɐ����}+�[=�|F`���#Yc2F��1��#�*$�VX~"Į�q�����t �u�\,3����(�CļW;>��R��l�����x�@� +<4�C���+�ъ,�+�V�FN7$TY}c{v��������I��z/��n�e�we7p>���P�{I�*z��1�_)3���<Q���;)iCˇkL�qWF���ƴ���,ҕ���/�'�$/R� �s�1��%���:肞�;+������O�zz�Bm��kSZ�p@.��~�r��#W�<el�G�8��W�܋}^��zU�3�~�?��_�F��!Ʀ�˳q�t� ��f�U7����;���� �U�B�_��E��~,�*����7P��_��璘ߞP�3'��Q�p`�2�#���"��*#��j�~�����Uv!�BOt��#:�E"�& @,�K -�,�U_DY-F/����e/[�;Q*ޞe�dvbG�"�/�n��߽�c��s���˱��8�i���g����Qc��(��e-,-�������I�z��hxth��Ź�e�7{����3W�s6t�Mѵ^��*��&Ŧ����xb���8���6ީ4g��}�W�۽���B�endstream +�,�U_DY-F/����e/[�;Q*ޞe�dvbG�"�/�n��߽�c��s���˱��8�i���g����Qc��(��e-,-�������I�z��hxth��Ź�e�7{����3W�s6t�Mѵ^��*��&Ŧ����xb���8���6ީ4'(��_uo��/��B�endstream endobj -5077 0 obj << +5252 0 obj << /Type /Page -/Contents 5078 0 R -/Resources 5076 0 R +/Contents 5253 0 R +/Resources 5251 0 R /MediaBox [0 0 609.714 789.041] -/Parent 5038 0 R +/Parent 5186 0 R >> endobj -5079 0 obj << -/D [5077 0 R /XYZ 71.731 729.265 null] +5254 0 obj << +/D [5252 0 R /XYZ 71.731 729.265 null] >> endobj -5080 0 obj << -/D [5077 0 R /XYZ 71.731 646.476 null] +5255 0 obj << +/D [5252 0 R /XYZ 71.731 646.476 null] >> endobj -5081 0 obj << -/D [5077 0 R /XYZ 71.731 561.729 null] +5256 0 obj << +/D [5252 0 R /XYZ 71.731 561.729 null] >> endobj -1872 0 obj << -/D [5077 0 R /XYZ 71.731 530.844 null] +1915 0 obj << +/D [5252 0 R /XYZ 71.731 530.844 null] >> endobj -970 0 obj << -/D [5077 0 R /XYZ 279.296 487.747 null] +998 0 obj << +/D [5252 0 R /XYZ 279.296 487.747 null] >> endobj -5082 0 obj << -/D [5077 0 R /XYZ 71.731 475.309 null] +5257 0 obj << +/D [5252 0 R /XYZ 71.731 475.309 null] >> endobj -5083 0 obj << -/D [5077 0 R /XYZ 71.731 433.147 null] +5258 0 obj << +/D [5252 0 R /XYZ 71.731 433.147 null] >> endobj -5084 0 obj << -/D [5077 0 R /XYZ 71.731 365.466 null] +5259 0 obj << +/D [5252 0 R /XYZ 71.731 365.466 null] >> endobj -1873 0 obj << -/D [5077 0 R /XYZ 71.731 321.63 null] +1916 0 obj << +/D [5252 0 R /XYZ 71.731 321.63 null] >> endobj -974 0 obj << -/D [5077 0 R /XYZ 303.224 276.475 null] +1002 0 obj << +/D [5252 0 R /XYZ 303.224 276.475 null] >> endobj -5085 0 obj << -/D [5077 0 R /XYZ 71.731 267.652 null] +5260 0 obj << +/D [5252 0 R /XYZ 71.731 267.652 null] >> endobj -5086 0 obj << -/D [5077 0 R /XYZ 71.731 221.875 null] +5261 0 obj << +/D [5252 0 R /XYZ 71.731 221.875 null] >> endobj -1874 0 obj << -/D [5077 0 R /XYZ 71.731 178.039 null] +1917 0 obj << +/D [5252 0 R /XYZ 71.731 178.039 null] >> endobj -978 0 obj << -/D [5077 0 R /XYZ 394.793 134.942 null] +1006 0 obj << +/D [5252 0 R /XYZ 394.793 134.942 null] >> endobj -5087 0 obj << -/D [5077 0 R /XYZ 71.731 122.504 null] +5262 0 obj << +/D [5252 0 R /XYZ 71.731 122.504 null] >> endobj -5076 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R >> +5251 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R >> /ProcSet [ /PDF /Text ] >> endobj -5090 0 obj << +5265 0 obj << /Length 2503 /Filter /FlateDecode >> @@ -19213,74 +19774,74 @@ xڍY[ �Ɇ�c���3��жRϔ%�1���%���Uf�{���-\����� ��l�a ���9��������+�����^��l��e���^�^���EiD�Tn"8�<N�$��ã.���`h��D�ꩇ��M�τ�K�XÌZe�R����Qr��k̀A���H#�~�-z�1q��&o�H`]�J�Thz��2����� �ۧ���*��F�.��}eSU\ �b��#j��ˇ+�2�'n��i�i3=@�sPj[�l��\��N�f���X��y��U����u�@�%. �Y��I �i;�r+�)ZU�����6{`KG4�w�Z�%�bʅ{~B�n'���^�� O~�}�9��+�b����@�����fNt��e�{�{��i�hr�� ��[�E*�Z.���a:��)�J��C}�-�.�P \�]LO�s�^u�*~G=�U�[Rh��k5�&%�S#iyír'���,cJ�j5N��������^H�䀢��2�F<�c��<͑� -���TiH�\�p��cl����l�,?��Y-�G9����x�3c�0T��� ��O�օ�(3�������*���+�E���dp*;<><�]�'���$�h�%"���~�z�>�l�?}b�����?�o*0�q���[7��r� D����|�m���+���#0�Wu��t��3Pl��F�#t{D���8�ܦ�@�F�6-u�����/���N ���y`mw�]4�hY=�~��p[�7���\#P@_X`�/�C��W�G�m�ga�ſ�M,wtK��⽕B�}����{]��0�endstream +���TiH�\�p��cl����l�,?��Y-�G9����x�3c�0T��� ��O�օ�(3�������*���+�E���dp*;<><�]�'���$�h�%"���~�z�>�l�?}b�����?�o*0�q���[7��r� D����|�m���+���#0�Wu��t��3Pl��F�#t{D���8�ܦ�@�F�6-u�����/���N ���y`mw�]4�hY=�~��p[�7���\#P@_X`�/�C��W�G�m�ga�ſ�M,wtK��⽕B�}����{]�؆�endstream endobj -5089 0 obj << +5264 0 obj << /Type /Page -/Contents 5090 0 R -/Resources 5088 0 R +/Contents 5265 0 R +/Resources 5263 0 R /MediaBox [0 0 609.714 789.041] -/Parent 5038 0 R +/Parent 5186 0 R >> endobj -5091 0 obj << -/D [5089 0 R /XYZ 71.731 729.265 null] +5266 0 obj << +/D [5264 0 R /XYZ 71.731 729.265 null] >> endobj -5092 0 obj << -/D [5089 0 R /XYZ 71.731 675.303 null] +5267 0 obj << +/D [5264 0 R /XYZ 71.731 675.303 null] >> endobj -1875 0 obj << -/D [5089 0 R /XYZ 71.731 631.467 null] +1918 0 obj << +/D [5264 0 R /XYZ 71.731 631.467 null] >> endobj -982 0 obj << -/D [5089 0 R /XYZ 182.287 588.37 null] +1010 0 obj << +/D [5264 0 R /XYZ 182.287 588.37 null] >> endobj -5093 0 obj << -/D [5089 0 R /XYZ 71.731 579.547 null] +5268 0 obj << +/D [5264 0 R /XYZ 71.731 579.547 null] >> endobj -1876 0 obj << -/D [5089 0 R /XYZ 71.731 494.915 null] +1919 0 obj << +/D [5264 0 R /XYZ 71.731 494.915 null] >> endobj -986 0 obj << -/D [5089 0 R /XYZ 188.364 451.818 null] +1014 0 obj << +/D [5264 0 R /XYZ 188.364 451.818 null] >> endobj -5094 0 obj << -/D [5089 0 R /XYZ 71.731 442.995 null] +5269 0 obj << +/D [5264 0 R /XYZ 71.731 442.995 null] >> endobj -1877 0 obj << -/D [5089 0 R /XYZ 71.731 384.266 null] +1920 0 obj << +/D [5264 0 R /XYZ 71.731 384.266 null] >> endobj -990 0 obj << -/D [5089 0 R /XYZ 365.182 341.169 null] +1018 0 obj << +/D [5264 0 R /XYZ 365.182 341.169 null] >> endobj -5095 0 obj << -/D [5089 0 R /XYZ 71.731 332.346 null] +5270 0 obj << +/D [5264 0 R /XYZ 71.731 332.346 null] >> endobj -5096 0 obj << -/D [5089 0 R /XYZ 179.356 293.707 null] +5271 0 obj << +/D [5264 0 R /XYZ 179.356 293.707 null] >> endobj -5097 0 obj << -/D [5089 0 R /XYZ 71.731 286.568 null] +5272 0 obj << +/D [5264 0 R /XYZ 71.731 286.568 null] >> endobj -1878 0 obj << -/D [5089 0 R /XYZ 71.731 216.83 null] +1921 0 obj << +/D [5264 0 R /XYZ 71.731 216.83 null] >> endobj -994 0 obj << -/D [5089 0 R /XYZ 433.251 173.732 null] +1022 0 obj << +/D [5264 0 R /XYZ 433.251 173.732 null] >> endobj -5098 0 obj << -/D [5089 0 R /XYZ 71.731 161.561 null] +5273 0 obj << +/D [5264 0 R /XYZ 71.731 161.561 null] >> endobj -5099 0 obj << -/D [5089 0 R /XYZ 71.731 137.065 null] +5274 0 obj << +/D [5264 0 R /XYZ 71.731 137.065 null] >> endobj -5100 0 obj << -/D [5089 0 R /XYZ 71.731 127.102 null] +5275 0 obj << +/D [5264 0 R /XYZ 71.731 127.102 null] >> endobj -5088 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R /F23 1173 0 R >> +5263 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R /F23 1201 0 R >> /ProcSet [ /PDF /Text ] >> endobj -5103 0 obj << +5278 0 obj << /Length 789 /Filter /FlateDecode >> @@ -19289,29 +19850,29 @@ xڕUQo �C�!��ܐ��n@��� �{�z�����?j�)Um�KQS��N<���M֪��b��L�����D�%���m���j��8(�y� İ�XD�=�� GN���p<�n�1&l�/��><!zx���Fݣs%n�^�z��J�#m"���^;j���`�x�Q\CQ�KYo"���@�Bfr��D�X��g�Al���Ѯ���;#6�B��P��4Y� ��i#EGj��סs��Zp:��j+��q�F6gTٵ5 -��½�ᛰ�p� ��le�+"�^�{T^Is�#1q�jM���_��G�Z�Ҡ<�|��BZ�<*�kB��lT?S��su�]�$O��s���[�ݍp��Q��������Lc��8T��Q�v���|��endstream +��½�ᛰ�p� ��le�+"�^�{T^Is�#1q�jM���_��G�Z�Ҡ<�|��BZ�<*�kB��lT?S��su�]�$O��s���[�ݍp��Q��������Lc��8T��Q�_��N{����endstream endobj -5102 0 obj << +5277 0 obj << /Type /Page -/Contents 5103 0 R -/Resources 5101 0 R +/Contents 5278 0 R +/Resources 5276 0 R /MediaBox [0 0 609.714 789.041] -/Parent 5038 0 R +/Parent 5282 0 R >> endobj -5104 0 obj << -/D [5102 0 R /XYZ 71.731 729.265 null] +5279 0 obj << +/D [5277 0 R /XYZ 71.731 729.265 null] >> endobj -5105 0 obj << -/D [5102 0 R /XYZ 71.731 689.765 null] +5280 0 obj << +/D [5277 0 R /XYZ 71.731 689.765 null] >> endobj -5106 0 obj << -/D [5102 0 R /XYZ 71.731 647.771 null] +5281 0 obj << +/D [5277 0 R /XYZ 71.731 647.771 null] >> endobj -5101 0 obj << -/Font << /F33 1278 0 R /F27 1180 0 R >> +5276 0 obj << +/Font << /F33 1306 0 R /F27 1208 0 R >> /ProcSet [ /PDF /Text ] >> endobj -5109 0 obj << +5285 0 obj << /Length 1875 /Filter /FlateDecode >> @@ -19322,190 +19883,190 @@ gkx ��� ��n��Xwi�)�ǧ�^��V��A�l>�r�YpN�y����}Ae2������<��,�DGAz8I��oB�h"+�o�%�G�/����B�wp��렯��r�4]�W�rG�v \�*�ip�:�I��Hcb�I��:҈��w���TZ�ap�W���P;�=���� ��9xM��K�4�uӵ����~������3 W��t� zĵߩr{��*m/I05�bOj ��]X}�!cz?VT��V�. T�����8*�(n��c�zky�/����+,��S|�p9��r�cH��b��:���Y�O Y�c��O1@;h�,ɓg7�u�����1O���_� ��_\�i,*v�x�A -\ƥ��q�.�j<_�XzWyendstream +\ƥ��q��.�j<_�X�W{endstream endobj -5108 0 obj << +5284 0 obj << /Type /Page -/Contents 5109 0 R -/Resources 5107 0 R +/Contents 5285 0 R +/Resources 5283 0 R /MediaBox [0 0 609.714 789.041] -/Parent 5038 0 R -/Annots [ 5155 0 R ] +/Parent 5282 0 R +/Annots [ 5331 0 R ] >> endobj -5155 0 obj << +5331 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [375.699 134.004 435.474 142.915] /Subtype /Link /A << /S /GoTo /D (http-apache) >> >> endobj -5110 0 obj << -/D [5108 0 R /XYZ 71.731 729.265 null] +5286 0 obj << +/D [5284 0 R /XYZ 71.731 729.265 null] >> endobj -1879 0 obj << -/D [5108 0 R /XYZ 71.731 718.306 null] +1922 0 obj << +/D [5284 0 R /XYZ 71.731 718.306 null] >> endobj -998 0 obj << -/D [5108 0 R /XYZ 160.355 703.236 null] +1026 0 obj << +/D [5284 0 R /XYZ 160.355 703.236 null] >> endobj -5111 0 obj << -/D [5108 0 R /XYZ 71.731 692.504 null] +5287 0 obj << +/D [5284 0 R /XYZ 71.731 692.504 null] >> endobj -1002 0 obj << -/D [5108 0 R /XYZ 208.364 644.101 null] +1030 0 obj << +/D [5284 0 R /XYZ 208.364 644.101 null] >> endobj -3585 0 obj << -/D [5108 0 R /XYZ 71.731 629.175 null] +3750 0 obj << +/D [5284 0 R /XYZ 71.731 629.175 null] >> endobj -1006 0 obj << -/D [5108 0 R /XYZ 117.14 620.82 null] +1034 0 obj << +/D [5284 0 R /XYZ 117.14 620.82 null] >> endobj -5112 0 obj << -/D [5108 0 R /XYZ 71.731 615.714 null] +5288 0 obj << +/D [5284 0 R /XYZ 71.731 615.714 null] >> endobj -5113 0 obj << -/D [5108 0 R /XYZ 71.731 610.733 null] +5289 0 obj << +/D [5284 0 R /XYZ 71.731 610.733 null] >> endobj -5114 0 obj << -/D [5108 0 R /XYZ 118.328 584.955 null] +5290 0 obj << +/D [5284 0 R /XYZ 118.328 584.955 null] >> endobj -5115 0 obj << -/D [5108 0 R /XYZ 296.214 572.003 null] +5291 0 obj << +/D [5284 0 R /XYZ 296.214 572.003 null] >> endobj -5116 0 obj << -/D [5108 0 R /XYZ 71.731 536.138 null] +5292 0 obj << +/D [5284 0 R /XYZ 71.731 536.138 null] >> endobj -1010 0 obj << -/D [5108 0 R /XYZ 86.646 483.825 null] +1038 0 obj << +/D [5284 0 R /XYZ 86.646 483.825 null] >> endobj -5117 0 obj << -/D [5108 0 R /XYZ 71.731 473.496 null] +5293 0 obj << +/D [5284 0 R /XYZ 71.731 473.496 null] >> endobj -1014 0 obj << -/D [5108 0 R /XYZ 107.616 460.544 null] +1042 0 obj << +/D [5284 0 R /XYZ 107.616 460.544 null] >> endobj -5118 0 obj << -/D [5108 0 R /XYZ 71.731 453.501 null] +5294 0 obj << +/D [5284 0 R /XYZ 71.731 453.501 null] >> endobj -5119 0 obj << -/D [5108 0 R /XYZ 71.731 448.519 null] +5295 0 obj << +/D [5284 0 R /XYZ 71.731 448.519 null] >> endobj -5120 0 obj << -/D [5108 0 R /XYZ 256.795 411.727 null] +5296 0 obj << +/D [5284 0 R /XYZ 256.795 411.727 null] >> endobj -5121 0 obj << -/D [5108 0 R /XYZ 392.166 411.727 null] +5297 0 obj << +/D [5284 0 R /XYZ 392.166 411.727 null] >> endobj -5122 0 obj << -/D [5108 0 R /XYZ 71.731 409.57 null] +5298 0 obj << +/D [5284 0 R /XYZ 71.731 409.57 null] >> endobj -5123 0 obj << -/D [5108 0 R /XYZ 71.731 395.623 null] +5299 0 obj << +/D [5284 0 R /XYZ 71.731 395.623 null] >> endobj -1018 0 obj << -/D [5108 0 R /XYZ 320.85 382.238 null] +1046 0 obj << +/D [5284 0 R /XYZ 320.85 382.238 null] >> endobj -5124 0 obj << -/D [5108 0 R /XYZ 71.731 369.615 null] +5300 0 obj << +/D [5284 0 R /XYZ 71.731 369.615 null] >> endobj -5125 0 obj << -/D [5108 0 R /XYZ 71.731 369.615 null] +5301 0 obj << +/D [5284 0 R /XYZ 71.731 369.615 null] >> endobj -5126 0 obj << -/D [5108 0 R /XYZ 71.731 369.615 null] +5302 0 obj << +/D [5284 0 R /XYZ 71.731 369.615 null] >> endobj -5127 0 obj << -/D [5108 0 R /XYZ 71.731 357.916 null] +5303 0 obj << +/D [5284 0 R /XYZ 71.731 357.916 null] >> endobj -5128 0 obj << -/D [5108 0 R /XYZ 111.582 341.391 null] +5304 0 obj << +/D [5284 0 R /XYZ 111.582 341.391 null] >> endobj -5129 0 obj << -/D [5108 0 R /XYZ 71.731 329.271 null] +5305 0 obj << +/D [5284 0 R /XYZ 71.731 329.271 null] >> endobj -5130 0 obj << -/D [5108 0 R /XYZ 71.731 329.271 null] +5306 0 obj << +/D [5284 0 R /XYZ 71.731 329.271 null] >> endobj -5131 0 obj << -/D [5108 0 R /XYZ 71.731 329.271 null] +5307 0 obj << +/D [5284 0 R /XYZ 71.731 329.271 null] >> endobj -5132 0 obj << -/D [5108 0 R /XYZ 71.731 317.069 null] +5308 0 obj << +/D [5284 0 R /XYZ 71.731 317.069 null] >> endobj -5133 0 obj << -/D [5108 0 R /XYZ 71.731 317.069 null] +5309 0 obj << +/D [5284 0 R /XYZ 71.731 317.069 null] >> endobj -5134 0 obj << -/D [5108 0 R /XYZ 71.731 317.069 null] +5310 0 obj << +/D [5284 0 R /XYZ 71.731 317.069 null] >> endobj -5135 0 obj << -/D [5108 0 R /XYZ 71.731 304.118 null] +5311 0 obj << +/D [5284 0 R /XYZ 71.731 304.118 null] >> endobj -5136 0 obj << -/D [5108 0 R /XYZ 111.582 287.593 null] +5312 0 obj << +/D [5284 0 R /XYZ 111.582 287.593 null] >> endobj -5137 0 obj << -/D [5108 0 R /XYZ 326.852 274.641 null] +5313 0 obj << +/D [5284 0 R /XYZ 326.852 274.641 null] >> endobj -5138 0 obj << -/D [5108 0 R /XYZ 71.731 262.522 null] +5314 0 obj << +/D [5284 0 R /XYZ 71.731 262.522 null] >> endobj -5139 0 obj << -/D [5108 0 R /XYZ 71.731 262.522 null] +5315 0 obj << +/D [5284 0 R /XYZ 71.731 262.522 null] >> endobj -5140 0 obj << -/D [5108 0 R /XYZ 71.731 262.522 null] +5316 0 obj << +/D [5284 0 R /XYZ 71.731 262.522 null] >> endobj -5141 0 obj << -/D [5108 0 R /XYZ 71.731 250.319 null] +5317 0 obj << +/D [5284 0 R /XYZ 71.731 250.319 null] >> endobj -5142 0 obj << -/D [5108 0 R /XYZ 111.582 233.794 null] +5318 0 obj << +/D [5284 0 R /XYZ 111.582 233.794 null] >> endobj -5143 0 obj << -/D [5108 0 R /XYZ 352.018 233.794 null] +5319 0 obj << +/D [5284 0 R /XYZ 352.018 233.794 null] >> endobj -5144 0 obj << -/D [5108 0 R /XYZ 135.374 220.843 null] +5320 0 obj << +/D [5284 0 R /XYZ 135.374 220.843 null] >> endobj -5145 0 obj << -/D [5108 0 R /XYZ 224.983 220.843 null] +5321 0 obj << +/D [5284 0 R /XYZ 224.983 220.843 null] >> endobj -5146 0 obj << -/D [5108 0 R /XYZ 297.992 220.843 null] +5322 0 obj << +/D [5284 0 R /XYZ 297.992 220.843 null] >> endobj -5147 0 obj << -/D [5108 0 R /XYZ 419.728 220.843 null] +5323 0 obj << +/D [5284 0 R /XYZ 419.728 220.843 null] >> endobj -5148 0 obj << -/D [5108 0 R /XYZ 111.582 207.892 null] +5324 0 obj << +/D [5284 0 R /XYZ 111.582 207.892 null] >> endobj -5149 0 obj << -/D [5108 0 R /XYZ 71.731 196.521 null] +5325 0 obj << +/D [5284 0 R /XYZ 71.731 196.521 null] >> endobj -5150 0 obj << -/D [5108 0 R /XYZ 71.731 196.521 null] +5326 0 obj << +/D [5284 0 R /XYZ 71.731 196.521 null] >> endobj -5151 0 obj << -/D [5108 0 R /XYZ 71.731 196.521 null] +5327 0 obj << +/D [5284 0 R /XYZ 71.731 196.521 null] >> endobj -5152 0 obj << -/D [5108 0 R /XYZ 71.731 183.57 null] +5328 0 obj << +/D [5284 0 R /XYZ 71.731 183.57 null] >> endobj -5153 0 obj << -/D [5108 0 R /XYZ 111.582 167.045 null] +5329 0 obj << +/D [5284 0 R /XYZ 111.582 167.045 null] >> endobj -5154 0 obj << -/D [5108 0 R /XYZ 71.731 146.955 null] +5330 0 obj << +/D [5284 0 R /XYZ 71.731 146.955 null] >> endobj -5156 0 obj << -/D [5108 0 R /XYZ 71.731 113.246 null] +5332 0 obj << +/D [5284 0 R /XYZ 71.731 113.246 null] >> endobj -5107 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F32 1187 0 R /F33 1278 0 R >> +5283 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F32 1215 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -5159 0 obj << +5335 0 obj << /Length 1473 /Filter /FlateDecode >> @@ -19515,569 +20076,575 @@ xڕWM :M/�*�I�<�2�㢈�g� �9��xP�S��{!/!PQ���F&�'�Cgy��F̳�" aT+ݰs�"hP�ɢ^��`�~�|B�Ϟ��6C�'v���^Yk��A]1�f�)h�U��Os�zA{6��4l,��1Ʋ6?�`s�4:��Q���4I�VR�H���8��ܽ 5c�P�--R`�-*v�h�Sއ����0˜����R���TI��ތ�p��>���E�����gݓ� �� �#�Ϭ�u��z�C�a���;�m������䋆�'�=>�����FFw_��p����܄�,�,\����e���IBfhxg��ٴ��B�~�WLB���w@��#Q�M���b5�Qh��X���%;�CK�d3�e��� -�kB�%v�d]�f����v�\��R'7��{JS����i�?��3a#MN�F���I��Gရ�[K�G�N�^�!�2P�,��4�8��~A���bl��C��>#������<M��ɾ���Lxw��d�H���ɞ�?w�? ������*~���w��#������N��|�n��.qZ�a����JQ�Q�X�%�W��>���@� �_��NM�� �%%j���g���U����6��z�V@�ܞ�@ =.�Y�)6ޱ������33����،=+6�� ?"�f�0.l���v���o�N�X�� �ˋI����K)�96A$�Ȟ�?f_���`�fendstream +�kB�%v�d]�f����v�\��R'7��{JS����i�?��3a#MN�F���I��Gရ�[K�G�N�.W�SI \�S�mv� �HJ� ���!L��S�B�f��[�&�j�d�Xha&�;�z2u$�k�dOݟ� ��OW���y��`T��s�jvH�n���v'�g�g�DX�8��0ȁI�_%���(T,����+�eY�c��X�/Lx'��P���LY䈳�dq�*�D�^mhg= �B+ x� nOR�������S�NZ�����klƎ���ڄ�g3Y�~�a;}b�c�A�^�e���$|�Ώ\��� �B�C��/c����aendstream endobj -5158 0 obj << +5334 0 obj << /Type /Page -/Contents 5159 0 R -/Resources 5157 0 R +/Contents 5335 0 R +/Resources 5333 0 R /MediaBox [0 0 609.714 789.041] -/Parent 5189 0 R +/Parent 5282 0 R >> endobj -5160 0 obj << -/D [5158 0 R /XYZ 71.731 729.265 null] +5336 0 obj << +/D [5334 0 R /XYZ 71.731 729.265 null] >> endobj -1022 0 obj << -/D [5158 0 R /XYZ 86.646 703.68 null] +1050 0 obj << +/D [5334 0 R /XYZ 86.646 703.68 null] >> endobj -5161 0 obj << -/D [5158 0 R /XYZ 71.731 693.351 null] +5337 0 obj << +/D [5334 0 R /XYZ 71.731 693.351 null] >> endobj -1026 0 obj << -/D [5158 0 R /XYZ 91.098 680.4 null] +1054 0 obj << +/D [5334 0 R /XYZ 91.098 680.4 null] >> endobj -5162 0 obj << -/D [5158 0 R /XYZ 71.731 673.202 null] +5338 0 obj << +/D [5334 0 R /XYZ 71.731 673.202 null] >> endobj -5163 0 obj << -/D [5158 0 R /XYZ 71.731 668.22 null] +5339 0 obj << +/D [5334 0 R /XYZ 71.731 668.22 null] >> endobj -5164 0 obj << -/D [5158 0 R /XYZ 101.865 657.485 null] +5340 0 obj << +/D [5334 0 R /XYZ 101.865 657.485 null] >> endobj -5165 0 obj << -/D [5158 0 R /XYZ 236.362 644.534 null] +5341 0 obj << +/D [5334 0 R /XYZ 236.362 644.534 null] >> endobj -5166 0 obj << -/D [5158 0 R /XYZ 284.401 644.534 null] +5342 0 obj << +/D [5334 0 R /XYZ 284.401 644.534 null] >> endobj -5167 0 obj << -/D [5158 0 R /XYZ 71.731 619.129 null] +5343 0 obj << +/D [5334 0 R /XYZ 71.731 619.129 null] >> endobj -1030 0 obj << -/D [5158 0 R /XYZ 131.506 606.178 null] +1058 0 obj << +/D [5334 0 R /XYZ 131.506 606.178 null] >> endobj -5168 0 obj << -/D [5158 0 R /XYZ 71.731 598.98 null] +5344 0 obj << +/D [5334 0 R /XYZ 71.731 598.98 null] >> endobj -5169 0 obj << -/D [5158 0 R /XYZ 71.731 593.999 null] +5345 0 obj << +/D [5334 0 R /XYZ 71.731 593.999 null] >> endobj -1998 0 obj << -/D [5158 0 R /XYZ 71.731 544.908 null] +2041 0 obj << +/D [5334 0 R /XYZ 71.731 544.908 null] >> endobj -1034 0 obj << -/D [5158 0 R /XYZ 109.927 531.956 null] +1062 0 obj << +/D [5334 0 R /XYZ 109.927 531.956 null] >> endobj -5170 0 obj << -/D [5158 0 R /XYZ 71.731 524.758 null] +5346 0 obj << +/D [5334 0 R /XYZ 71.731 524.758 null] >> endobj -5171 0 obj << -/D [5158 0 R /XYZ 71.731 519.777 null] +5347 0 obj << +/D [5334 0 R /XYZ 71.731 519.777 null] >> endobj -5172 0 obj << -/D [5158 0 R /XYZ 71.731 486.128 null] +5348 0 obj << +/D [5334 0 R /XYZ 71.731 486.128 null] >> endobj -1038 0 obj << -/D [5158 0 R /XYZ 86.646 433.815 null] +1066 0 obj << +/D [5334 0 R /XYZ 86.646 433.815 null] >> endobj -2060 0 obj << -/D [5158 0 R /XYZ 71.731 423.228 null] +2103 0 obj << +/D [5334 0 R /XYZ 71.731 423.228 null] >> endobj -1042 0 obj << -/D [5158 0 R /XYZ 202.589 410.535 null] +1070 0 obj << +/D [5334 0 R /XYZ 202.589 410.535 null] >> endobj -5173 0 obj << -/D [5158 0 R /XYZ 71.731 403.491 null] +5349 0 obj << +/D [5334 0 R /XYZ 71.731 403.491 null] >> endobj -5174 0 obj << -/D [5158 0 R /XYZ 71.731 398.51 null] +5350 0 obj << +/D [5334 0 R /XYZ 71.731 398.51 null] >> endobj -5175 0 obj << -/D [5158 0 R /XYZ 71.731 398.51 null] +5351 0 obj << +/D [5334 0 R /XYZ 71.731 398.51 null] >> endobj -5176 0 obj << -/D [5158 0 R /XYZ 257.363 374.669 null] +5352 0 obj << +/D [5334 0 R /XYZ 257.363 374.669 null] >> endobj -5177 0 obj << -/D [5158 0 R /XYZ 71.731 349.264 null] +5353 0 obj << +/D [5334 0 R /XYZ 71.731 349.264 null] >> endobj -1046 0 obj << -/D [5158 0 R /XYZ 127.073 336.313 null] +1074 0 obj << +/D [5334 0 R /XYZ 127.073 336.313 null] >> endobj -5178 0 obj << -/D [5158 0 R /XYZ 71.731 329.269 null] +5354 0 obj << +/D [5334 0 R /XYZ 71.731 329.269 null] >> endobj -5179 0 obj << -/D [5158 0 R /XYZ 71.731 324.288 null] +5355 0 obj << +/D [5334 0 R /XYZ 71.731 324.288 null] >> endobj -2650 0 obj << -/D [5158 0 R /XYZ 71.731 262.091 null] +2743 0 obj << +/D [5334 0 R /XYZ 71.731 262.091 null] >> endobj -1050 0 obj << -/D [5158 0 R /XYZ 248.655 249.14 null] +1078 0 obj << +/D [5334 0 R /XYZ 248.655 249.14 null] >> endobj -5180 0 obj << -/D [5158 0 R /XYZ 71.731 242.096 null] +5356 0 obj << +/D [5334 0 R /XYZ 71.731 242.096 null] >> endobj -5181 0 obj << -/D [5158 0 R /XYZ 71.731 237.115 null] +5357 0 obj << +/D [5334 0 R /XYZ 71.731 237.115 null] >> endobj -5182 0 obj << -/D [5158 0 R /XYZ 71.731 237.115 null] +5358 0 obj << +/D [5334 0 R /XYZ 71.731 237.115 null] >> endobj -5183 0 obj << -/D [5158 0 R /XYZ 180.012 226.226 null] +5359 0 obj << +/D [5334 0 R /XYZ 180.012 226.226 null] >> endobj -5184 0 obj << -/D [5158 0 R /XYZ 118.495 213.274 null] +5360 0 obj << +/D [5334 0 R /XYZ 118.495 213.274 null] >> endobj -2527 0 obj << -/D [5158 0 R /XYZ 71.731 187.87 null] +2614 0 obj << +/D [5334 0 R /XYZ 71.731 187.87 null] >> endobj -5185 0 obj << -/D [5158 0 R /XYZ 71.731 187.87 null] +5361 0 obj << +/D [5334 0 R /XYZ 71.731 187.87 null] >> endobj -1054 0 obj << -/D [5158 0 R /XYZ 109.39 174.918 null] +1082 0 obj << +/D [5334 0 R /XYZ 109.39 174.918 null] >> endobj -5186 0 obj << -/D [5158 0 R /XYZ 71.731 169.757 null] +5362 0 obj << +/D [5334 0 R /XYZ 71.731 169.757 null] >> endobj -5187 0 obj << -/D [5158 0 R /XYZ 71.731 164.776 null] +5363 0 obj << +/D [5334 0 R /XYZ 71.731 164.776 null] >> endobj -5188 0 obj << -/D [5158 0 R /XYZ 109.568 153.299 null] +5364 0 obj << +/D [5334 0 R /XYZ 109.568 153.299 null] >> endobj -5157 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F33 1278 0 R /F58 2421 0 R /F35 1525 0 R >> +5333 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F33 1306 0 R /F60 2527 0 R /F35 1567 0 R >> /ProcSet [ /PDF /Text ] >> endobj -5192 0 obj << -/Length 1536 +5367 0 obj << +/Length 1537 /Filter /FlateDecode >> stream -xڍ�n�6�=_��@��>��۴A����[�D�Dt�H%p��3����n����\�[�"�/Z�(X�J�y����p���ǻ�1�<q����*K -Q��bu������o�bQ�*O�ݢ�D��",E���M�G`�.WqrR��=����{�ڃ�<�f�������V�lgh�V:�Ȅ���4�Iu������ �9;gX��0���hc'�]�a0�b����<Y���_� �|��s���{���U_&�� 1P�g]��Q�M -2N�Wh�M2� $�rQE��C���Ò�0Cm�DII�s��K�a��2����R��j�p<�����ߺm%��������,z;)�tz(��XEq�R���*����@)tZQ��50�Y�����<��ݫ�e!�F��pB<i^JD\�}�ꆞ�."��3�LN�ށޠS�> -4č����z���b�i����,������7��<�lR����i? 3��� �w��W��$� ���X�G���:�ǀb��ȃp�����h��/*�z���sTE��{�`}4Vu���kK;S�� c���.�`�P�ï_+SO����~���JC -�gؽɅ��;�Oms���i�s����o��=���uW�3F� -b�q1h�$��4E���(��(k$�Y�F�<�Ђ��[^Ԗ6W�_UH�r˕pr��8\�(����UZ�*�*� ��Ӛ靵�8���g�|Y!�=휇�0xP����x�J��kx��$�zbBmh}9`N#�$�l\���(B�dZ�C=QԵ2���y9���¼�e�I�JB:�e��_:ƺ�#MB<�`�{E��vX��V'��0u.�;�2��cV �g�Ӝt˰����A3M�� -7[��#��ʸ�*H��N��!s���H�׳{ι�p�_�2tӿ0c�moDsy�hvї����-���k��7�ӼǑ�.'U*�4�9Rx����H��h� �J*��_�/�A?�O�����0B����?�(;�F���\�3��Ӄ��q�;�Q����S� �6��A�3��s��(�W!|~PM�q��MCG�nn�[��a�j�X� "?M#�E �o=���{�$��<���us[�?ȣ��k�y�u�x�K�ST�߄��/�@��؛��W�"�>Q8��o���qB��h>�n�U*��q�l��|�y�qB.�K � ���3�ːU͵3 -:%{*'��ЏU������tRs%5��'m��_ îM:�`0��xòc+k�A\ĮںA�H��{�=�`�6P+�����հ%|���d%1�Z:Q �`��bA�j\���f/D -���x�<�!l�tcH(3������f�*����;ƉG���S��� -!���L;ͽaZs?K+q���Y&r�'���3�~�h�g[�v�gE.����=���4Q��{����m� �I�O<�l�ٓS*^V^�τ��_�[u�1VgWu/-���Cp���(}+���^��F��hendstream -endobj -5191 0 obj << +xڍ�n�6�=_��@�갮��6m�Eo�}�-�6^�J�~}g8Cۉ�v��ù8��Y_2+Qf���H�|��w�l7�w c,�B�y +���<+E]e�����/�M�Y-�"����:E^�ʸ�r9[�Dn/�|��q$���h=(�����U���6�y��vzd�8c;u��a4�"��i�F�jp6�C؍�9���gX�G�8mt�j����8�P 1�s�^��*xy�/O�i1[��(�Ŀ��ѩ�lq��(c��j@�$���J2NV�h��r��K$�Q'%�6������J㊱Z0C��DYI�w�FG�q�1���Z�uTK0o��Y=|?���]'���Y��f/�g����顠�l��1K +�z���<�#��ie=�S��`|;{�=��E^�Y-�<AF����x +�����"�HՏ#]D��g�)��X��A'��}i�K[I���&�q���w�[0�E�^7{:�i���=��lR����ig� ��V�;FکA�i��~���Q+�����1�X' y��7#x���E Y�sU������O��֩���Ӣ�hgi0v� ��V��w{:��5����0Ǵ�����FZRp�8���.�Ȑ7���~��k���X�!��.��@����Ywe�1��U㌋A{%y�-sQ&���[d��!K�hQ�ZP�ˋ���J�� +�^� +����Њ��^,+�cBeP�9�~ZQ"�s�<~�옯j$����pG +U��XI�z�ҍ��DYOL�-�/{�i������W=E��Hk�`�c J��Q��1 1/o^�\�ן7Ln�AIH��u�K�X;�Ɉg�N��V������n;��0`c�Q�ސ�z�*C�,v��n9V2��k�i�Q�f�bt�"�B�X���i�<@Ȝ�%:����s�#�"�W���/�X��\@�%!�}�8�y��Ң�Z~���4/�i"b��Y��2�9R����H��h� ��R@1�_f"�~����ſa�� ~GoXPv ȏ"���g�`�E)�q����Χ�A$m HY�(gVq�Q��B�"���B3�ڷ5cO�~�>t��d�X� �8M+�Eᛃ �o����$��"��t�[�?%ȣ����k�y�u�x�K�UT�߄����H�����?T�2�>Qz��o���Ѡ��`?���Uj��q�l��|�y�� �- c/�����3�ː=��kg�JTNBA`����,���JjU3펁_îMz�`0��xò�N6^��L}=����z�E;��{���o�V�]��aK�D�(�$1�Zj��i�?��N� |5���W�"��I�injN<`��6���\,�5������*4��;�Y@ ��S��� +!STիL;ͽaZ��0K'q���y. +�'���3�~�h�g[���gE.�������4ьc�{���ǩk� �IvO<�l�)�S*^V^�τ��_�[u�1g_u/-���UZ.��ߊ +��ײ�HV�pendstream +endobj +5366 0 obj << /Type /Page -/Contents 5192 0 R -/Resources 5190 0 R +/Contents 5367 0 R +/Resources 5365 0 R /MediaBox [0 0 609.714 789.041] -/Parent 5189 0 R -/Annots [ 5206 0 R ] +/Parent 5282 0 R +/Annots [ 5381 0 R ] >> endobj -5206 0 obj << +5381 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [221.059 393.303 273.526 401.497] /Subtype /Link /A << /S /GoTo /D (security-webserver-mod-throttle) >> >> endobj -5193 0 obj << -/D [5191 0 R /XYZ 71.731 729.265 null] +5368 0 obj << +/D [5366 0 R /XYZ 71.731 729.265 null] >> endobj -5194 0 obj << -/D [5191 0 R /XYZ 71.731 741.22 null] +5369 0 obj << +/D [5366 0 R /XYZ 71.731 741.22 null] >> endobj -5195 0 obj << -/D [5191 0 R /XYZ 527.567 708.344 null] +5370 0 obj << +/D [5366 0 R /XYZ 527.567 708.344 null] >> endobj -5196 0 obj << -/D [5191 0 R /XYZ 71.731 691.243 null] +5371 0 obj << +/D [5366 0 R /XYZ 71.731 691.243 null] >> endobj -5197 0 obj << -/D [5191 0 R /XYZ 194.722 681.743 null] +5372 0 obj << +/D [5366 0 R /XYZ 194.722 681.743 null] >> endobj -5198 0 obj << -/D [5191 0 R /XYZ 71.731 606.326 null] +5373 0 obj << +/D [5366 0 R /XYZ 71.731 606.326 null] >> endobj -1058 0 obj << -/D [5191 0 R /XYZ 86.646 554.013 null] +1086 0 obj << +/D [5366 0 R /XYZ 86.646 554.013 null] >> endobj -3478 0 obj << -/D [5191 0 R /XYZ 71.731 543.684 null] +3643 0 obj << +/D [5366 0 R /XYZ 71.731 543.684 null] >> endobj -1062 0 obj << -/D [5191 0 R /XYZ 109.927 530.733 null] +1090 0 obj << +/D [5366 0 R /XYZ 109.927 530.733 null] >> endobj -5199 0 obj << -/D [5191 0 R /XYZ 71.731 525.627 null] +5374 0 obj << +/D [5366 0 R /XYZ 71.731 525.627 null] >> endobj -5200 0 obj << -/D [5191 0 R /XYZ 71.731 520.646 null] +5375 0 obj << +/D [5366 0 R /XYZ 71.731 520.646 null] >> endobj -5201 0 obj << -/D [5191 0 R /XYZ 408.876 494.867 null] +5376 0 obj << +/D [5366 0 R /XYZ 408.876 494.867 null] >> endobj -5202 0 obj << -/D [5191 0 R /XYZ 91.656 481.916 null] +5377 0 obj << +/D [5366 0 R /XYZ 91.656 481.916 null] >> endobj -3611 0 obj << -/D [5191 0 R /XYZ 71.731 456.511 null] +3775 0 obj << +/D [5366 0 R /XYZ 71.731 456.511 null] >> endobj -1066 0 obj << -/D [5191 0 R /XYZ 126.336 443.56 null] +1094 0 obj << +/D [5366 0 R /XYZ 126.336 443.56 null] >> endobj -5203 0 obj << -/D [5191 0 R /XYZ 71.731 438.454 null] +5378 0 obj << +/D [5366 0 R /XYZ 71.731 438.454 null] >> endobj -5204 0 obj << -/D [5191 0 R /XYZ 71.731 433.473 null] +5379 0 obj << +/D [5366 0 R /XYZ 71.731 433.473 null] >> endobj -5205 0 obj << -/D [5191 0 R /XYZ 91.656 394.743 null] +5380 0 obj << +/D [5366 0 R /XYZ 91.656 394.743 null] >> endobj -5207 0 obj << -/D [5191 0 R /XYZ 71.731 345.926 null] +5382 0 obj << +/D [5366 0 R /XYZ 71.731 345.926 null] >> endobj -1070 0 obj << -/D [5191 0 R /XYZ 87.803 293.613 null] +1098 0 obj << +/D [5366 0 R /XYZ 87.803 293.613 null] >> endobj -5208 0 obj << -/D [5191 0 R /XYZ 71.731 283.026 null] +5383 0 obj << +/D [5366 0 R /XYZ 71.731 283.026 null] >> endobj -1074 0 obj << -/D [5191 0 R /XYZ 106.959 270.332 null] +1102 0 obj << +/D [5366 0 R /XYZ 106.959 270.332 null] >> endobj -5209 0 obj << -/D [5191 0 R /XYZ 71.731 263.289 null] +5384 0 obj << +/D [5366 0 R /XYZ 71.731 263.289 null] >> endobj -5210 0 obj << -/D [5191 0 R /XYZ 71.731 258.307 null] +5385 0 obj << +/D [5366 0 R /XYZ 71.731 258.307 null] >> endobj -5211 0 obj << -/D [5191 0 R /XYZ 135.305 247.418 null] +5386 0 obj << +/D [5366 0 R /XYZ 135.305 247.418 null] >> endobj -5212 0 obj << -/D [5191 0 R /XYZ 477.105 234.467 null] +5387 0 obj << +/D [5366 0 R /XYZ 477.105 234.467 null] >> endobj -5213 0 obj << -/D [5191 0 R /XYZ 91.656 221.515 null] +5388 0 obj << +/D [5366 0 R /XYZ 91.656 221.515 null] >> endobj -5214 0 obj << -/D [5191 0 R /XYZ 71.731 198.601 null] +5389 0 obj << +/D [5366 0 R /XYZ 71.731 198.601 null] >> endobj -1078 0 obj << -/D [5191 0 R /XYZ 83.217 146.288 null] +1106 0 obj << +/D [5366 0 R /XYZ 83.217 146.288 null] >> endobj -5215 0 obj << -/D [5191 0 R /XYZ 71.731 135.701 null] +5390 0 obj << +/D [5366 0 R /XYZ 71.731 135.701 null] >> endobj -1082 0 obj << -/D [5191 0 R /XYZ 121.773 123.008 null] +1110 0 obj << +/D [5366 0 R /XYZ 121.773 123.008 null] >> endobj -5216 0 obj << -/D [5191 0 R /XYZ 71.731 115.964 null] +5391 0 obj << +/D [5366 0 R /XYZ 71.731 115.964 null] >> endobj -5217 0 obj << -/D [5191 0 R /XYZ 71.731 110.983 null] +5392 0 obj << +/D [5366 0 R /XYZ 71.731 110.983 null] >> endobj -5190 0 obj << -/Font << /F27 1180 0 R /F23 1173 0 R /F44 1994 0 R /F35 1525 0 R /F33 1278 0 R >> +5365 0 obj << +/Font << /F27 1208 0 R /F23 1201 0 R /F44 2037 0 R /F35 1567 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -5220 0 obj << -/Length 1556 +5395 0 obj << +/Length 1555 /Filter /FlateDecode >> stream -xڭXKo�6��W�h1-�z�t��M�6z�#Ѷ��襤�_�嗼�=,X�p8��H�O�㓄�D�GdL��$�o��V~��#�c&"�+��H&,K�d~"���f�^ȉXe��ՠ%�8��s���q���+cY,�)�̅d"�Ġ�V�x0]���gs����YL�jڭ�@ ���=W3�@"��Q4���@�`����<NR��8A�2�w�~��MG�eK߾�-v�(�i:k*�tM��@����;Z0+��Z�`�g7 }}�}�����7i�m{Teuw��ڢ�.�@fН�Al�n{�X�Z�|��jD�����(�n��a���1U�@i/2��l[�>��2�.��p�LkS���%�nS��?��/e��("@`Z��� ��MAt��%j��3(��hp&DN�{�a���I��O��h��YQ�0�+m]�pG�`��l��R��Jװ���4-1���pU�]��ʋC��ƀ�I*�Uo�A,��Z��$�Z�}�x��^ -]��i��u�1ŕ�䜅�<�۳UV�O�l.!�.=@�, � ��s����EϜ#�a̲ �lV�K�r�at�Y��L����� �avV��S��(p��o�;@���$�lH�i�2`�`C�<����1LF1����߾2�s.�tX x8�{�U���dW.H�1t��������� b�]�ԁg~�� U�xr)�������Hc -�ok�<#��Q4>��Z',�#�O"���h.�@(�ʨ;�V�Դ�1l���b(�z�~�Xnj�L�(8.�j�� �������6�� -��QuY�ʖ_�3̐Ӷ�Zˮ�64���K�Q&��w�گnʵ��5eӵ�EY}7 �HX������O���Op{�3@��.t��-l�Օ��$CJb(�PBX��9�v~�_~吅Ш T�Qܨ��TTґ����������b�dp�O1*�GYu�U�zH76a|քl1��2߾G� �r�#�~��~+�2�C���x���j<t�CA���_�jz����f��}sNO� ���w'�TE Y��5�=˛�!���Z 7RH�i~��D��æ�3z��x�{����*>��!Q#1/���͔�S�K�Q��S�y\��ǁ�(t�W,G�K*�Į���7m�^������e -&��-��ϛ�\ -BO�t~40db��s��7�{���_:?��o���\���$b$�j��3b9��,��,>�L�3x8|?.UsJ��u)����m��"IU�%�S�v5 پZ��xwr����3n�o/���ŕ[ˠ��ֲ������~�Hx�,-mq��H����̢a���3vO<�����='��܊��-M�,w�ƙ�[��bع#�)^b��h��Թ>ښU�s'�V,}QV�wO�͕�<۴U��R��r�C5�1q>p�'SoM����s�����hvF�I��4(4�p�����q'�H�KgtZ:��J ��C�l��&0x��C��<��rm�P3e�A���lh�FS���j;{���et-���� R�$ΣKU�? ƺ�,�5�endstream -endobj -5219 0 obj << +xڭX�o�6�_�G�(��gޒ�:�����:�D�B��RR �����e�M�P�����;�|��_Ĝ�>"e" +y}�/6��� �A1 +_YtC�4�w"����{'�B�, +���z�������������7Õ�4���/\!�H81��˖�w6K���+��yZ&����۵(����r5K$�Ds�����ȿ_�Q��� �R8OA�QPPGO\���a���ᦂ&}K�y������ҷ�>��l�"t�4o��UuVV���7�Ow�zU3�<�r�"��ݣj +�c��'H����m���<�S�η,�e �P���xE���[���(ë����p�v5��K7��Y)]Ѩn��R�8��~[�[�?��eUe4:������4����gS�s��+��yQ�B��f�[F��|Ԙ��9Ь(��&E��)�v��fC���U���/ۦ#�kY�YUH!�}�h2HZ1Qd�٪)6.(�����C��\������V��-�(�,���=�Lg���2(�$���@l��M�~a���#Β�[���c�?�X�ǖM��C��Qn?��8����B~���*@F�x��U���p� +�o�z@���$�mH]�\ ����6�7����1L�!����3��\<p�Ac�a� ٔ�mM�o�>S�8�� H�ӫ�:�&��r�ɥ ���7g�`8y]��i�D�1���L�9B����ܟD�q��� l�6+���Z�5�Z�������>t�+���I&��g5�϶�l���Ѷ���k�"Y]Ve�˯��ȩ;U��e_�[Р�K�Qm>�߭U��vu[n��][6}GZ2��F�1KRj~Y�i���g>�y��S�G[ض�+�I��DP�,M��X0��y���! ��w"nV �Xa"�*�g#�u6�4�`��1q2�������r�g/Y��t�!���;L�q���w��"H��H��������S��q(��ω�o�s�AW�7�:;�����E��x��Pi�9�=� �h�Q����5U�K��E����f=�Cȳ�S?�V�?��J�h�<�Ц7Gs����hR�c�fb���{)�;��������o���#0��v�@�zh���Qi� +y���#�t�f�:��i��2LF�k>�#ϫ�\ +BOU~20`b��9�ګ�-���/����#<�K��L�Sm�{G���x��w��e�^�毋Y3%���Bκ]��"IU�%��zej�}����{3i}�wƍ�mo���]���j'���F'�f���{G��f�i���%F���8}�` s���V�����a��s��Rpg�t�4m��6�o)�� +.�=]��b�!a�Fv��չЮ]�{ӹ���鋲��Ax"�o����ŦtVa�1�*sa��xO��D���wm������ ����&uv�A��u��[�a� o��f�-�Up���!v�Dw�`�!�WT`��'�C�[9��.�}� Kx|�8[��2���PrQ< +A�8�/5�?�U���6Gendstream +endobj +5394 0 obj << /Type /Page -/Contents 5220 0 R -/Resources 5218 0 R +/Contents 5395 0 R +/Resources 5393 0 R /MediaBox [0 0 609.714 789.041] -/Parent 5189 0 R -/Annots [ 5232 0 R 5248 0 R ] +/Parent 5282 0 R +/Annots [ 5407 0 R 5423 0 R ] >> endobj -5232 0 obj << +5407 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [222.931 489.622 255.658 498.533] /Subtype /Link /A << /S /GoTo /D (gloss-rdbms) >> >> endobj -5248 0 obj << +5423 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[1 0 0] /Rect [342.364 349.149 387.195 358.06] /Subtype /Link /A << /S /GoTo /D (security-mysql) >> >> endobj -5221 0 obj << -/D [5219 0 R /XYZ 71.731 729.265 null] +5396 0 obj << +/D [5394 0 R /XYZ 71.731 729.265 null] >> endobj -1086 0 obj << -/D [5219 0 R /XYZ 88.939 651.05 null] +1114 0 obj << +/D [5394 0 R /XYZ 88.939 651.05 null] >> endobj -4589 0 obj << -/D [5219 0 R /XYZ 71.731 640.72 null] +4770 0 obj << +/D [5394 0 R /XYZ 71.731 640.72 null] >> endobj -1090 0 obj << -/D [5219 0 R /XYZ 193.573 627.769 null] +1118 0 obj << +/D [5394 0 R /XYZ 193.573 627.769 null] >> endobj -5222 0 obj << -/D [5219 0 R /XYZ 71.731 620.571 null] +5397 0 obj << +/D [5394 0 R /XYZ 71.731 620.571 null] >> endobj -5223 0 obj << -/D [5219 0 R /XYZ 71.731 615.59 null] +5398 0 obj << +/D [5394 0 R /XYZ 71.731 615.59 null] >> endobj -5224 0 obj << -/D [5219 0 R /XYZ 487.065 604.855 null] +5399 0 obj << +/D [5394 0 R /XYZ 488.718 604.855 null] >> endobj -5225 0 obj << -/D [5219 0 R /XYZ 91.656 566 null] +5400 0 obj << +/D [5394 0 R /XYZ 91.656 566 null] >> endobj -5226 0 obj << -/D [5219 0 R /XYZ 364.962 566 null] +5401 0 obj << +/D [5394 0 R /XYZ 364.962 566 null] >> endobj -5227 0 obj << -/D [5219 0 R /XYZ 478.805 566 null] +5402 0 obj << +/D [5394 0 R /XYZ 478.805 566 null] >> endobj -5228 0 obj << -/D [5219 0 R /XYZ 154.739 553.049 null] +5403 0 obj << +/D [5394 0 R /XYZ 154.739 553.049 null] >> endobj -5229 0 obj << -/D [5219 0 R /XYZ 71.731 527.644 null] +5404 0 obj << +/D [5394 0 R /XYZ 71.731 527.644 null] >> endobj -1094 0 obj << -/D [5219 0 R /XYZ 106.052 514.693 null] +1122 0 obj << +/D [5394 0 R /XYZ 106.052 514.693 null] >> endobj -5230 0 obj << -/D [5219 0 R /XYZ 71.731 507.649 null] +5405 0 obj << +/D [5394 0 R /XYZ 71.731 507.649 null] >> endobj -5231 0 obj << -/D [5219 0 R /XYZ 71.731 502.668 null] +5406 0 obj << +/D [5394 0 R /XYZ 71.731 502.668 null] >> endobj -5233 0 obj << -/D [5219 0 R /XYZ 444.255 491.779 null] +5408 0 obj << +/D [5394 0 R /XYZ 444.255 491.779 null] >> endobj -5234 0 obj << -/D [5219 0 R /XYZ 71.731 476.671 null] +5409 0 obj << +/D [5394 0 R /XYZ 71.731 476.671 null] >> endobj -5235 0 obj << -/D [5219 0 R /XYZ 71.731 461.727 null] +5410 0 obj << +/D [5394 0 R /XYZ 71.731 461.727 null] >> endobj -5236 0 obj << -/D [5219 0 R /XYZ 71.731 461.727 null] +5411 0 obj << +/D [5394 0 R /XYZ 71.731 461.727 null] >> endobj -5237 0 obj << -/D [5219 0 R /XYZ 71.731 448.775 null] +5412 0 obj << +/D [5394 0 R /XYZ 71.731 448.775 null] >> endobj -5238 0 obj << -/D [5219 0 R /XYZ 111.582 432.999 null] +5413 0 obj << +/D [5394 0 R /XYZ 111.582 432.999 null] >> endobj -5239 0 obj << -/D [5219 0 R /XYZ 71.731 420.88 null] +5414 0 obj << +/D [5394 0 R /XYZ 71.731 420.88 null] >> endobj -5240 0 obj << -/D [5219 0 R /XYZ 71.731 420.88 null] +5415 0 obj << +/D [5394 0 R /XYZ 71.731 420.88 null] >> endobj -5241 0 obj << -/D [5219 0 R /XYZ 71.731 407.928 null] +5416 0 obj << +/D [5394 0 R /XYZ 71.731 407.928 null] >> endobj -5242 0 obj << -/D [5219 0 R /XYZ 111.582 392.152 null] +5417 0 obj << +/D [5394 0 R /XYZ 111.582 392.152 null] >> endobj -5243 0 obj << -/D [5219 0 R /XYZ 315.276 392.152 null] +5418 0 obj << +/D [5394 0 R /XYZ 315.276 392.152 null] >> endobj -5244 0 obj << -/D [5219 0 R /XYZ 71.731 380.033 null] +5419 0 obj << +/D [5394 0 R /XYZ 71.731 380.033 null] >> endobj -5245 0 obj << -/D [5219 0 R /XYZ 71.731 380.033 null] +5420 0 obj << +/D [5394 0 R /XYZ 71.731 380.033 null] >> endobj -5246 0 obj << -/D [5219 0 R /XYZ 71.731 367.082 null] +5421 0 obj << +/D [5394 0 R /XYZ 71.731 367.082 null] >> endobj -5247 0 obj << -/D [5219 0 R /XYZ 111.582 351.306 null] +5422 0 obj << +/D [5394 0 R /XYZ 111.582 351.306 null] >> endobj -5249 0 obj << -/D [5219 0 R /XYZ 71.731 328.392 null] +5424 0 obj << +/D [5394 0 R /XYZ 71.731 328.392 null] >> endobj -1098 0 obj << -/D [5219 0 R /XYZ 85.51 276.079 null] +1126 0 obj << +/D [5394 0 R /XYZ 85.51 276.079 null] >> endobj -2586 0 obj << -/D [5219 0 R /XYZ 71.731 265.749 null] +2707 0 obj << +/D [5394 0 R /XYZ 71.731 265.749 null] >> endobj -1102 0 obj << -/D [5219 0 R /XYZ 176.696 252.798 null] +1130 0 obj << +/D [5394 0 R /XYZ 176.696 252.798 null] >> endobj -5250 0 obj << -/D [5219 0 R /XYZ 71.731 245.6 null] +5425 0 obj << +/D [5394 0 R /XYZ 71.731 245.6 null] >> endobj -5251 0 obj << -/D [5219 0 R /XYZ 71.731 240.619 null] +5426 0 obj << +/D [5394 0 R /XYZ 71.731 240.619 null] >> endobj -5252 0 obj << -/D [5219 0 R /XYZ 71.731 240.619 null] +5427 0 obj << +/D [5394 0 R /XYZ 71.731 240.619 null] >> endobj -3002 0 obj << -/D [5219 0 R /XYZ 71.731 204.479 null] +3115 0 obj << +/D [5394 0 R /XYZ 71.731 204.479 null] >> endobj -1106 0 obj << -/D [5219 0 R /XYZ 109.17 191.528 null] +1134 0 obj << +/D [5394 0 R /XYZ 109.17 191.528 null] >> endobj -5253 0 obj << -/D [5219 0 R /XYZ 71.731 186.422 null] +5428 0 obj << +/D [5394 0 R /XYZ 71.731 186.422 null] >> endobj -5254 0 obj << -/D [5219 0 R /XYZ 71.731 181.441 null] +5429 0 obj << +/D [5394 0 R /XYZ 71.731 181.441 null] >> endobj -5218 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F35 1525 0 R /F33 1278 0 R >> +5393 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F35 1567 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -5258 0 obj << -/Length 1297 +5433 0 obj << +/Length 1296 /Filter /FlateDecode >> stream -xڍWKo�8��W؋،�-�-i�Ew��&1��f�LKD%R �����(��̙�p^�f�$����&a���d�:�U�E<�a珋$h��k��)�g6�y�ae�͖�ۋ˛4���\g����$.X�ZͶ����,��i��m��͓rT�ϖi�ʄ�o��n�̲Ut4�9���=��77&�_�E�]�]xJZZ9-F̓���+ߵ�D�ѵ�1-W��k����7<�qM8�J<�q�>�P�����w���t�����@1� $uƄ�r��F8��C!��VF�N���1:��<�C���#�h!��l!Wo�4��*��@,�w��t��ݛ���W���<ͣ�0�b~�d��-����.�e��,C�yL1���� xVK��#�C�C�- �,g�x�d��q�$9/��� -p��l��hdYlS��朥`mݞ�N� �4ciAi�^� �i��^�� -��jC�˩��<n�+�{a�"l��#��D}�.\Y;�*��>*Z;m����yRD�hY�q��O����7�hu� Nj:8�!d��;��=��I�V��')}�!�vR��4�4����M� �=��,}��ʑ���@J%��#%렞����N@�B0��}fini_�u��{0���3=ZC��4X�:�W��9ë���_a-�}����(ŚSᡙ�ɂd+�� -��V,��f���cY 1�=B%�����~�\���h��>��3�:����n�t�ݯ��N�W�¦��sǯ��}���Xs����Nػ�Nto�IL���2��~�v���+`�>��{��V~��T�5|<����T�E:�{u����Иc��Q�t�� '�8[56�<�#���/��͜�C��'����=B�{c=�p`���$��<#!V�/��� ��I`O��FPê��%����Հ������l������:�����霭/{l��g�`�����&YA�˧�X�X߈��_!��V��7Y�7U�O����� -��=�Ж��@["�ٴB�F+,̂�����n�d��6��Vm��o$���VV#RA���F�1"�y���}f �`B��F�.A�����ԃ�$K��X� ��х�R���\�@��V�';�l��7�#_U�8�����Y�b�W{�b,�u�b����������������gң�ɿPNaA���#�Q��/�|l��Q�b���V�@|����π���><�W+���~�X>������Ɗ��`FI�~�j�Wᵯ�2�Sendstream -endobj -5257 0 obj << +xڍWKo�8��W؋،�-�-i�Ew��&1��f�LKD)Q �����(��̙�p^�f�$����&a���d�:�U�E<�a珋$h��k��)�g6�y�ae�͖�ۋ˛4���\g����$.X�ZͶ����,��Q������I9*�g�4eeB�7�X7_f�*:���=��77&�_�Eq��~F���VN��$j���wJ��7�6�%F�x-����3� �v�q����/`3gy�]���P�e C�1a�9az#��ϡed+#{'���1:��<�C���#�P�{ +u���7��ɂd�nw ��w��t��ݛ������y�GGa��4���j/����.�e��,C�yL1���� xVK��#�C�C*�_�&��&^5�*�C��ˎV�Ep8Mc��K4�,�)K@s�R���nOz'_�F����4n���4�n��w�_`�!��TBE��ý�e���y�f�>p +���*��>v��چ�yRD�hY�q��O����7�P�oENj:8�!d��;�;{����2�OR��C� �4�F'ii�;h9M���D�x�����*G�Vg);�-)Y��f�v�����{0�Hs�H�2���݃+���h �o`�`�K�_9_�S�y���r|m��$� �0ԣkN��f2'2�JQ*=VJ,��f���Q'Ʋb�{�J�߁+ �R��;܇�&Ԟ�>��3�:����n�t�ݯ��N(�+�_aSD���� +�>q���Xs����Nػ�N�o�IL���2��~�v���w0��}�-���� ������k�x��1��i��Q��Z�Ϗ�Bc��G=�q�&���l��<��뒟�L7s��������U���Lr���^��$��d��X= R��6Xį'=�=�sx�.�V /����轮�hT�����f�\���e��^Wn/O�l}�c3�=kk\�~��dI.��c�b}#����{�[��d%�Tu?ٳ�>+���tC[�yl��g� +��aa$��vK'[DX��v0�j�#�V�+Y�H�G>(qƈ������q|�� 1l�UL ��kXS��,]CC@`u32�� +F�J���y'yl� +ZJ�';�l��7�#_U�8�����Y�b�W{�b,�u�b����������������gң�ɿPNaA�����g>��t�b���V�@|����π���><�W+���~�X>�����z��`FIR�t5������1�Sendstream +endobj +5432 0 obj << /Type /Page -/Contents 5258 0 R -/Resources 5256 0 R +/Contents 5433 0 R +/Resources 5431 0 R /MediaBox [0 0 609.714 789.041] -/Parent 5189 0 R +/Parent 5282 0 R >> endobj -5259 0 obj << -/D [5257 0 R /XYZ 71.731 729.265 null] +5434 0 obj << +/D [5432 0 R /XYZ 71.731 729.265 null] >> endobj -5260 0 obj << -/D [5257 0 R /XYZ 71.731 718.306 null] +5435 0 obj << +/D [5432 0 R /XYZ 71.731 718.306 null] >> endobj -1110 0 obj << -/D [5257 0 R /XYZ 90.261 708.344 null] +1138 0 obj << +/D [5432 0 R /XYZ 90.261 708.344 null] >> endobj -5261 0 obj << -/D [5257 0 R /XYZ 71.731 703.238 null] +5436 0 obj << +/D [5432 0 R /XYZ 71.731 703.238 null] >> endobj -5262 0 obj << -/D [5257 0 R /XYZ 71.731 698.257 null] +5437 0 obj << +/D [5432 0 R /XYZ 71.731 698.257 null] >> endobj -5263 0 obj << -/D [5257 0 R /XYZ 134.824 659.527 null] +5438 0 obj << +/D [5432 0 R /XYZ 134.824 659.527 null] >> endobj -5264 0 obj << -/D [5257 0 R /XYZ 71.731 636.613 null] +5439 0 obj << +/D [5432 0 R /XYZ 71.731 636.613 null] >> endobj -1114 0 obj << -/D [5257 0 R /XYZ 87.803 584.3 null] +1142 0 obj << +/D [5432 0 R /XYZ 87.803 584.3 null] >> endobj -5265 0 obj << -/D [5257 0 R /XYZ 71.731 572.897 null] +5440 0 obj << +/D [5432 0 R /XYZ 71.731 572.897 null] >> endobj -1118 0 obj << -/D [5257 0 R /XYZ 86.675 561.019 null] +1146 0 obj << +/D [5432 0 R /XYZ 86.675 561.019 null] >> endobj -5266 0 obj << -/D [5257 0 R /XYZ 71.731 555.52 null] +5441 0 obj << +/D [5432 0 R /XYZ 71.731 555.52 null] >> endobj -5267 0 obj << -/D [5257 0 R /XYZ 71.731 550.539 null] +5442 0 obj << +/D [5432 0 R /XYZ 71.731 550.539 null] >> endobj -5268 0 obj << -/D [5257 0 R /XYZ 71.731 550.539 null] +5443 0 obj << +/D [5432 0 R /XYZ 71.731 550.539 null] >> endobj -5269 0 obj << -/D [5257 0 R /XYZ 119.841 538.105 null] +5444 0 obj << +/D [5432 0 R /XYZ 119.841 538.105 null] >> endobj -5270 0 obj << -/D [5257 0 R /XYZ 167.644 538.105 null] +5445 0 obj << +/D [5432 0 R /XYZ 167.644 538.105 null] >> endobj -5271 0 obj << -/D [5257 0 R /XYZ 249.411 538.105 null] +5446 0 obj << +/D [5432 0 R /XYZ 249.411 538.105 null] >> endobj -5272 0 obj << -/D [5257 0 R /XYZ 442.122 512.202 null] +5447 0 obj << +/D [5432 0 R /XYZ 442.122 512.202 null] >> endobj -5273 0 obj << -/D [5257 0 R /XYZ 71.731 476.337 null] +5448 0 obj << +/D [5432 0 R /XYZ 71.731 476.337 null] >> endobj -1122 0 obj << -/D [5257 0 R /XYZ 86.646 424.024 null] +1150 0 obj << +/D [5432 0 R /XYZ 86.646 424.024 null] >> endobj -5255 0 obj << -/D [5257 0 R /XYZ 71.731 413.695 null] +5430 0 obj << +/D [5432 0 R /XYZ 71.731 413.695 null] >> endobj -1126 0 obj << -/D [5257 0 R /XYZ 269.378 400.743 null] +1154 0 obj << +/D [5432 0 R /XYZ 269.378 400.743 null] >> endobj -5274 0 obj << -/D [5257 0 R /XYZ 71.731 393.545 null] +5449 0 obj << +/D [5432 0 R /XYZ 71.731 393.545 null] >> endobj -5275 0 obj << -/D [5257 0 R /XYZ 71.731 388.564 null] +5450 0 obj << +/D [5432 0 R /XYZ 71.731 388.564 null] >> endobj -5276 0 obj << -/D [5257 0 R /XYZ 71.731 339.473 null] +5451 0 obj << +/D [5432 0 R /XYZ 71.731 339.473 null] >> endobj -1130 0 obj << -/D [5257 0 R /XYZ 165.299 326.522 null] +1158 0 obj << +/D [5432 0 R /XYZ 165.299 326.522 null] >> endobj -5277 0 obj << -/D [5257 0 R /XYZ 71.731 319.324 null] +5452 0 obj << +/D [5432 0 R /XYZ 71.731 319.324 null] >> endobj -5278 0 obj << -/D [5257 0 R /XYZ 71.731 314.342 null] +5453 0 obj << +/D [5432 0 R /XYZ 71.731 314.342 null] >> endobj -5279 0 obj << -/D [5257 0 R /XYZ 476.554 303.607 null] +5454 0 obj << +/D [5432 0 R /XYZ 476.554 303.607 null] >> endobj -5280 0 obj << -/D [5257 0 R /XYZ 71.731 267.742 null] +5455 0 obj << +/D [5432 0 R /XYZ 71.731 267.742 null] >> endobj -1134 0 obj << -/D [5257 0 R /XYZ 85.51 215.429 null] +1162 0 obj << +/D [5432 0 R /XYZ 85.51 215.429 null] >> endobj -3479 0 obj << -/D [5257 0 R /XYZ 71.731 204.842 null] +3644 0 obj << +/D [5432 0 R /XYZ 71.731 204.842 null] >> endobj -1138 0 obj << -/D [5257 0 R /XYZ 107.277 192.148 null] +1166 0 obj << +/D [5432 0 R /XYZ 107.277 192.148 null] >> endobj -5281 0 obj << -/D [5257 0 R /XYZ 71.731 187.043 null] +5456 0 obj << +/D [5432 0 R /XYZ 71.731 187.043 null] >> endobj -5282 0 obj << -/D [5257 0 R /XYZ 71.731 182.061 null] +5457 0 obj << +/D [5432 0 R /XYZ 71.731 182.061 null] >> endobj -5283 0 obj << -/D [5257 0 R /XYZ 382.967 156.283 null] +5458 0 obj << +/D [5432 0 R /XYZ 382.967 156.283 null] >> endobj -5256 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F33 1278 0 R >> +5431 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -5286 0 obj << -/Length 1982 +5461 0 obj << +/Length 1983 /Filter /FlateDecode >> stream @@ -20091,377 +20658,439 @@ wy Ð��Ax� �GF��6W���5�p�K��9Eg�n����(��[ª�a.#W�N�.� kE�+�1���;,µu���������0�u��k����a�n ":��ɴ���݊4��!���u�B�Ǟt��e�P��*C�<P�z�� ;kп�i��X��_�vr7]>�b�;��Q���e��^�X8� ��`��a�쒚����-cZ&1�쟠l$9̭@\��{��g6t�r������͊4������1l���O!�lh�sf��|/n�hc���J�-������X.[1~{��+0��i~�31�}~%ثϒ-���\��WW7��� AX������UH��{W���zS����<;� -�r7��*2"��$.����v�Nm8�_�iI?yh�V���U\����-��Q��sY�7t�?�Jj���j19�a��:k6�+zo�M-Xt��-#.�(�a^,�d�t��f%���%D��_����d��w\�5�͢�6;�p��ߛ<��n�8�}�����Asl��מ�i�EZl(n�WaR��;ų��G]�������~�� �ʰ�����1��J�~e[�l���+�#nT�����u/Y� G�G�endstream +�r7��*2"��$.����v�Nm8�_�iI?yh�V���U\����-��Q��sY�7t�?�Jj���j19�a��:k6�+zo�M-Xt��-#.�(�a^,�d�t��f%���%D��_����d��w\�5�͢�6;�p��ߛ<��n�8�}�����Asl��מ�i�EZl(n�WaR��;ų��G]�������~�� �ʰ�����1��J�~e[�l��$���͊q������%�?��G�endstream endobj -5285 0 obj << +5460 0 obj << /Type /Page -/Contents 5286 0 R -/Resources 5284 0 R +/Contents 5461 0 R +/Resources 5459 0 R /MediaBox [0 0 609.714 789.041] -/Parent 5189 0 R +/Parent 5493 0 R >> endobj -5287 0 obj << -/D [5285 0 R /XYZ 71.731 729.265 null] +5462 0 obj << +/D [5460 0 R /XYZ 71.731 729.265 null] >> endobj -5288 0 obj << -/D [5285 0 R /XYZ 71.731 718.306 null] +5463 0 obj << +/D [5460 0 R /XYZ 71.731 718.306 null] >> endobj -5289 0 obj << -/D [5285 0 R /XYZ 71.731 718.306 null] +5464 0 obj << +/D [5460 0 R /XYZ 71.731 718.306 null] >> endobj -1142 0 obj << -/D [5285 0 R /XYZ 103.282 708.344 null] +1170 0 obj << +/D [5460 0 R /XYZ 103.282 708.344 null] >> endobj -5290 0 obj << -/D [5285 0 R /XYZ 71.731 703.238 null] +5465 0 obj << +/D [5460 0 R /XYZ 71.731 703.238 null] >> endobj -5291 0 obj << -/D [5285 0 R /XYZ 71.731 698.257 null] +5466 0 obj << +/D [5460 0 R /XYZ 71.731 698.257 null] >> endobj -5292 0 obj << -/D [5285 0 R /XYZ 71.731 698.257 null] +5467 0 obj << +/D [5460 0 R /XYZ 71.731 698.257 null] >> endobj -5293 0 obj << -/D [5285 0 R /XYZ 166.836 685.43 null] +5468 0 obj << +/D [5460 0 R /XYZ 166.836 685.43 null] >> endobj -5294 0 obj << -/D [5285 0 R /XYZ 408.475 672.478 null] +5469 0 obj << +/D [5460 0 R /XYZ 408.475 672.478 null] >> endobj -5295 0 obj << -/D [5285 0 R /XYZ 243.467 659.527 null] +5470 0 obj << +/D [5460 0 R /XYZ 243.467 659.527 null] >> endobj -5296 0 obj << -/D [5285 0 R /XYZ 246.801 659.527 null] +5471 0 obj << +/D [5460 0 R /XYZ 246.801 659.527 null] >> endobj -5297 0 obj << -/D [5285 0 R /XYZ 298.91 659.527 null] +5472 0 obj << +/D [5460 0 R /XYZ 298.91 659.527 null] >> endobj -5298 0 obj << -/D [5285 0 R /XYZ 448.559 659.527 null] +5473 0 obj << +/D [5460 0 R /XYZ 448.559 659.527 null] >> endobj -5299 0 obj << -/D [5285 0 R /XYZ 164.884 646.575 null] +5474 0 obj << +/D [5460 0 R /XYZ 164.884 646.575 null] >> endobj -5300 0 obj << -/D [5285 0 R /XYZ 481.157 646.575 null] +5475 0 obj << +/D [5460 0 R /XYZ 481.157 646.575 null] >> endobj -5301 0 obj << -/D [5285 0 R /XYZ 132.363 633.624 null] +5476 0 obj << +/D [5460 0 R /XYZ 132.363 633.624 null] >> endobj -5302 0 obj << -/D [5285 0 R /XYZ 71.731 610.71 null] +5477 0 obj << +/D [5460 0 R /XYZ 71.731 610.71 null] >> endobj -1146 0 obj << -/D [5285 0 R /XYZ 84.353 558.397 null] +1174 0 obj << +/D [5460 0 R /XYZ 84.353 558.397 null] >> endobj -5303 0 obj << -/D [5285 0 R /XYZ 71.731 548.068 null] +5478 0 obj << +/D [5460 0 R /XYZ 71.731 548.068 null] >> endobj -1150 0 obj << -/D [5285 0 R /XYZ 150.047 535.116 null] +1178 0 obj << +/D [5460 0 R /XYZ 150.047 535.116 null] >> endobj -5304 0 obj << -/D [5285 0 R /XYZ 71.731 527.918 null] +5479 0 obj << +/D [5460 0 R /XYZ 71.731 527.918 null] >> endobj -5305 0 obj << -/D [5285 0 R /XYZ 71.731 522.937 null] +5480 0 obj << +/D [5460 0 R /XYZ 71.731 522.937 null] >> endobj -5306 0 obj << -/D [5285 0 R /XYZ 192.963 499.251 null] +5481 0 obj << +/D [5460 0 R /XYZ 192.963 499.251 null] >> endobj -5307 0 obj << -/D [5285 0 R /XYZ 71.731 447.943 null] +5482 0 obj << +/D [5460 0 R /XYZ 71.731 447.943 null] >> endobj -1154 0 obj << -/D [5285 0 R /XYZ 193.264 434.992 null] +1182 0 obj << +/D [5460 0 R /XYZ 193.264 434.992 null] >> endobj -5308 0 obj << -/D [5285 0 R /XYZ 71.731 427.794 null] +5483 0 obj << +/D [5460 0 R /XYZ 71.731 427.794 null] >> endobj -5309 0 obj << -/D [5285 0 R /XYZ 71.731 422.813 null] +5484 0 obj << +/D [5460 0 R /XYZ 71.731 422.813 null] >> endobj -5310 0 obj << -/D [5285 0 R /XYZ 71.731 363.261 null] +5485 0 obj << +/D [5460 0 R /XYZ 71.731 363.261 null] >> endobj -1158 0 obj << -/D [5285 0 R /XYZ 84.353 310.948 null] +1186 0 obj << +/D [5460 0 R /XYZ 84.353 310.948 null] >> endobj -5311 0 obj << -/D [5285 0 R /XYZ 71.731 300.619 null] +5486 0 obj << +/D [5460 0 R /XYZ 71.731 300.619 null] >> endobj -1162 0 obj << -/D [5285 0 R /XYZ 163.964 287.667 null] +1190 0 obj << +/D [5460 0 R /XYZ 163.964 287.667 null] >> endobj -5312 0 obj << -/D [5285 0 R /XYZ 71.731 280.469 null] +5487 0 obj << +/D [5460 0 R /XYZ 71.731 280.469 null] >> endobj -5313 0 obj << -/D [5285 0 R /XYZ 71.731 275.488 null] +5488 0 obj << +/D [5460 0 R /XYZ 71.731 275.488 null] >> endobj -5314 0 obj << -/D [5285 0 R /XYZ 71.731 249.645 null] +5489 0 obj << +/D [5460 0 R /XYZ 71.731 249.645 null] >> endobj -5315 0 obj << -/D [5285 0 R /XYZ 71.731 239.682 null] +5490 0 obj << +/D [5460 0 R /XYZ 71.731 239.682 null] >> endobj -5316 0 obj << -/D [5285 0 R /XYZ 71.731 176.635 null] +5491 0 obj << +/D [5460 0 R /XYZ 71.731 176.635 null] >> endobj -5317 0 obj << -/D [5285 0 R /XYZ 469.856 143.607 null] +5492 0 obj << +/D [5460 0 R /XYZ 469.856 143.607 null] >> endobj -5284 0 obj << -/Font << /F23 1173 0 R /F27 1180 0 R /F33 1278 0 R >> +5459 0 obj << +/Font << /F23 1201 0 R /F27 1208 0 R /F33 1306 0 R >> /ProcSet [ /PDF /Text ] >> endobj -2629 0 obj << +2737 0 obj << /Type /Font /Subtype /Type1 /BaseFont /ZapfDingbats >> endobj -5318 0 obj << +5494 0 obj << /Type /Encoding /Differences [ 0 /.notdef 1/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash/ogonek/ring 10/.notdef 11/breve/minus 13/.notdef 14/Zcaron/zcaron/caron/dotlessi/dotlessj/ff/ffi/ffl 22/.notdef 30/grave/quotesingle/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde 127/.notdef 128/Euro 129/.notdef 130/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE 141/.notdef 147/quotedblleft/quotedblright/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe 157/.notdef 159/Ydieresis 160/.notdef 161/exclamdown/cent/sterling/currency/yen/brokenbar/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis] >> endobj -2421 0 obj << +2527 0 obj << /Type /Font /Subtype /Type1 -/Encoding 5318 0 R +/Encoding 5494 0 R /BaseFont /Courier-Bold >> endobj -2249 0 obj << +2322 0 obj << /Type /Font /Subtype /Type1 -/Encoding 5318 0 R +/Encoding 5494 0 R /BaseFont /Courier-Oblique >> endobj -2006 0 obj << +2049 0 obj << /Type /Font /Subtype /Type1 -/Encoding 5318 0 R +/Encoding 5494 0 R /BaseFont /Helvetica-Oblique >> endobj -1994 0 obj << +2037 0 obj << /Type /Font /Subtype /Type1 -/Encoding 5318 0 R +/Encoding 5494 0 R /BaseFont /Helvetica >> endobj -1525 0 obj << +1567 0 obj << /Type /Font /Subtype /Type1 -/Encoding 5318 0 R +/Encoding 5494 0 R /BaseFont /Courier >> endobj -1278 0 obj << +1306 0 obj << /Type /Font /Subtype /Type1 -/Encoding 5318 0 R +/Encoding 5494 0 R /BaseFont /Times-Italic >> endobj -1187 0 obj << +1215 0 obj << /Type /Font /Subtype /Type1 -/Encoding 5318 0 R +/Encoding 5494 0 R /BaseFont /Times-Bold >> endobj -1180 0 obj << +1208 0 obj << /Type /Font /Subtype /Type1 -/Encoding 5318 0 R +/Encoding 5494 0 R /BaseFont /Times-Roman >> endobj -1173 0 obj << +1201 0 obj << /Type /Font /Subtype /Type1 -/Encoding 5318 0 R +/Encoding 5494 0 R /BaseFont /Helvetica-Bold >> endobj -1174 0 obj << +1202 0 obj << /Type /Pages /Count 6 -/Parent 5319 0 R -/Kids [1166 0 R 1176 0 R 1182 0 R 1325 0 R 1470 0 R 1617 0 R] +/Parent 5495 0 R +/Kids [1194 0 R 1204 0 R 1210 0 R 1353 0 R 1498 0 R 1645 0 R] >> endobj -1841 0 obj << +1879 0 obj << /Type /Pages /Count 6 -/Parent 5319 0 R -/Kids [1762 0 R 1881 0 R 1903 0 R 1934 0 R 1986 0 R 2000 0 R] +/Parent 5495 0 R +/Kids [1790 0 R 1924 0 R 1946 0 R 1977 0 R 2029 0 R 2043 0 R] >> endobj -2059 0 obj << +2102 0 obj << /Type /Pages /Count 6 -/Parent 5319 0 R -/Kids [2036 0 R 2062 0 R 2098 0 R 2159 0 R 2178 0 R 2201 0 R] +/Parent 5495 0 R +/Kids [2079 0 R 2105 0 R 2141 0 R 2213 0 R 2231 0 R 2250 0 R] >> endobj -2274 0 obj << +2310 0 obj << /Type /Pages /Count 6 -/Parent 5319 0 R -/Kids [2233 0 R 2276 0 R 2318 0 R 2351 0 R 2390 0 R 2428 0 R] +/Parent 5495 0 R +/Kids [2285 0 R 2312 0 R 2357 0 R 2391 0 R 2433 0 R 2472 0 R] >> endobj -2487 0 obj << +2550 0 obj << /Type /Pages /Count 6 -/Parent 5319 0 R -/Kids [2460 0 R 2489 0 R 2529 0 R 2562 0 R 2588 0 R 2611 0 R] +/Parent 5495 0 R +/Kids [2513 0 R 2552 0 R 2576 0 R 2616 0 R 2656 0 R 2682 0 R] >> endobj -2667 0 obj << +2742 0 obj << /Type /Pages /Count 6 -/Parent 5319 0 R -/Kids [2652 0 R 2669 0 R 2700 0 R 2724 0 R 2753 0 R 2773 0 R] +/Parent 5495 0 R +/Kids [2709 0 R 2745 0 R 2776 0 R 2798 0 R 2825 0 R 2848 0 R] >> endobj -2818 0 obj << +2892 0 obj << /Type /Pages /Count 6 -/Parent 5320 0 R -/Kids [2785 0 R 2820 0 R 2845 0 R 2871 0 R 2899 0 R 2951 0 R] +/Parent 5496 0 R +/Kids [2875 0 R 2894 0 R 2928 0 R 2955 0 R 2978 0 R 3009 0 R] >> endobj -3001 0 obj << +3084 0 obj << /Type /Pages /Count 6 -/Parent 5320 0 R -/Kids [2974 0 R 3004 0 R 3035 0 R 3078 0 R 3116 0 R 3166 0 R] +/Parent 5496 0 R +/Kids [3063 0 R 3086 0 R 3117 0 R 3158 0 R 3204 0 R 3242 0 R] >> endobj -3227 0 obj << +3318 0 obj << /Type /Pages /Count 6 -/Parent 5320 0 R -/Kids [3199 0 R 3229 0 R 3256 0 R 3295 0 R 3325 0 R 3344 0 R] +/Parent 5496 0 R +/Kids [3287 0 R 3320 0 R 3355 0 R 3383 0 R 3410 0 R 3449 0 R] >> endobj -3390 0 obj << +3497 0 obj << /Type /Pages /Count 6 -/Parent 5320 0 R -/Kids [3360 0 R 3392 0 R 3422 0 R 3451 0 R 3481 0 R 3510 0 R] +/Parent 5496 0 R +/Kids [3479 0 R 3499 0 R 3516 0 R 3546 0 R 3580 0 R 3609 0 R] >> endobj -3610 0 obj << +3642 0 obj << /Type /Pages /Count 6 -/Parent 5320 0 R -/Kids [3587 0 R 3613 0 R 3641 0 R 3706 0 R 3717 0 R 3752 0 R] +/Parent 5496 0 R +/Kids [3615 0 R 3646 0 R 3675 0 R 3752 0 R 3777 0 R 3806 0 R] >> endobj -3802 0 obj << +3887 0 obj << /Type /Pages /Count 6 -/Parent 5320 0 R -/Kids [3774 0 R 3804 0 R 3826 0 R 3841 0 R 3855 0 R 3875 0 R] +/Parent 5496 0 R +/Kids [3856 0 R 3889 0 R 3899 0 R 3934 0 R 3954 0 R 3984 0 R] >> endobj -3946 0 obj << +4022 0 obj << /Type /Pages /Count 6 -/Parent 5321 0 R -/Kids [3915 0 R 3948 0 R 3964 0 R 3981 0 R 4002 0 R 4019 0 R] +/Parent 5497 0 R +/Kids [4006 0 R 4024 0 R 4038 0 R 4056 0 R 4092 0 R 4129 0 R] >> endobj -4055 0 obj << +4161 0 obj << /Type /Pages /Count 6 -/Parent 5321 0 R -/Kids [4027 0 R 4057 0 R 4083 0 R 4122 0 R 4151 0 R 4182 0 R] +/Parent 5497 0 R +/Kids [4145 0 R 4163 0 R 4182 0 R 4200 0 R 4211 0 R 4239 0 R] >> endobj -4242 0 obj << +4297 0 obj << /Type /Pages /Count 6 -/Parent 5321 0 R -/Kids [4220 0 R 4244 0 R 4260 0 R 4290 0 R 4299 0 R 4330 0 R] +/Parent 5497 0 R +/Kids [4271 0 R 4299 0 R 4337 0 R 4359 0 R 4389 0 R 4425 0 R] >> endobj -4388 0 obj << +4461 0 obj << /Type /Pages /Count 6 -/Parent 5321 0 R -/Kids [4359 0 R 4390 0 R 4419 0 R 4445 0 R 4479 0 R 4505 0 R] +/Parent 5497 0 R +/Kids [4444 0 R 4463 0 R 4481 0 R 4513 0 R 4539 0 R 4574 0 R] >> endobj -4588 0 obj << +4626 0 obj << /Type /Pages /Count 6 -/Parent 5321 0 R -/Kids [4538 0 R 4591 0 R 4619 0 R 4656 0 R 4686 0 R 4721 0 R] +/Parent 5497 0 R +/Kids [4600 0 R 4628 0 R 4662 0 R 4691 0 R 4723 0 R 4772 0 R] >> endobj -4758 0 obj << +4836 0 obj << /Type /Pages /Count 6 -/Parent 5321 0 R -/Kids [4732 0 R 4760 0 R 4783 0 R 4798 0 R 4820 0 R 4834 0 R] +/Parent 5497 0 R +/Kids [4806 0 R 4838 0 R 4874 0 R 4901 0 R 4939 0 R 4966 0 R] >> endobj -4905 0 obj << +5012 0 obj << /Type /Pages /Count 6 -/Parent 5322 0 R -/Kids [4878 0 R 4907 0 R 4938 0 R 4967 0 R 4998 0 R 5012 0 R] +/Parent 5498 0 R +/Kids [4991 0 R 5014 0 R 5031 0 R 5075 0 R 5102 0 R 5133 0 R] >> endobj -5038 0 obj << +5186 0 obj << /Type /Pages /Count 6 -/Parent 5322 0 R -/Kids [5028 0 R 5040 0 R 5077 0 R 5089 0 R 5102 0 R 5108 0 R] +/Parent 5498 0 R +/Kids [5163 0 R 5188 0 R 5204 0 R 5215 0 R 5252 0 R 5264 0 R] >> endobj -5189 0 obj << +5282 0 obj << /Type /Pages -/Count 5 -/Parent 5322 0 R -/Kids [5158 0 R 5191 0 R 5219 0 R 5257 0 R 5285 0 R] +/Count 6 +/Parent 5498 0 R +/Kids [5277 0 R 5284 0 R 5334 0 R 5366 0 R 5394 0 R 5432 0 R] >> endobj -5319 0 obj << +5493 0 obj << +/Type /Pages +/Count 1 +/Parent 5498 0 R +/Kids [5460 0 R] +>> endobj +5495 0 obj << /Type /Pages /Count 36 -/Parent 5323 0 R -/Kids [1174 0 R 1841 0 R 2059 0 R 2274 0 R 2487 0 R 2667 0 R] +/Parent 5499 0 R +/Kids [1202 0 R 1879 0 R 2102 0 R 2310 0 R 2550 0 R 2742 0 R] >> endobj -5320 0 obj << +5496 0 obj << /Type /Pages /Count 36 -/Parent 5323 0 R -/Kids [2818 0 R 3001 0 R 3227 0 R 3390 0 R 3610 0 R 3802 0 R] +/Parent 5499 0 R +/Kids [2892 0 R 3084 0 R 3318 0 R 3497 0 R 3642 0 R 3887 0 R] >> endobj -5321 0 obj << +5497 0 obj << /Type /Pages /Count 36 -/Parent 5323 0 R -/Kids [3946 0 R 4055 0 R 4242 0 R 4388 0 R 4588 0 R 4758 0 R] +/Parent 5499 0 R +/Kids [4022 0 R 4161 0 R 4297 0 R 4461 0 R 4626 0 R 4836 0 R] >> endobj -5322 0 obj << +5498 0 obj << /Type /Pages -/Count 17 -/Parent 5323 0 R -/Kids [4905 0 R 5038 0 R 5189 0 R] +/Count 19 +/Parent 5499 0 R +/Kids [5012 0 R 5186 0 R 5282 0 R 5493 0 R] >> endobj -5323 0 obj << +5499 0 obj << /Type /Pages -/Count 125 -/Kids [5319 0 R 5320 0 R 5321 0 R 5322 0 R] +/Count 127 +/Kids [5495 0 R 5496 0 R 5497 0 R 5498 0 R] >> endobj -5324 0 obj << +5500 0 obj << /Type /Outlines /First 3 0 R -/Last 1159 0 R +/Last 1187 0 R /Count 30 >> endobj +1191 0 obj << +/Title 1192 0 R +/A 1189 0 R +/Parent 1187 0 R +>> endobj +1187 0 obj << +/Title 1188 0 R +/A 1185 0 R +/Parent 5500 0 R +/Prev 1175 0 R +/First 1191 0 R +/Last 1191 0 R +/Count -1 +>> endobj +1183 0 obj << +/Title 1184 0 R +/A 1181 0 R +/Parent 1179 0 R +>> endobj +1179 0 obj << +/Title 1180 0 R +/A 1177 0 R +/Parent 1175 0 R +/First 1183 0 R +/Last 1183 0 R +/Count -1 +>> endobj +1175 0 obj << +/Title 1176 0 R +/A 1173 0 R +/Parent 5500 0 R +/Prev 1163 0 R +/Next 1187 0 R +/First 1179 0 R +/Last 1179 0 R +/Count -1 +>> endobj +1171 0 obj << +/Title 1172 0 R +/A 1169 0 R +/Parent 1167 0 R +>> endobj +1167 0 obj << +/Title 1168 0 R +/A 1165 0 R +/Parent 1163 0 R +/First 1171 0 R +/Last 1171 0 R +/Count -1 +>> endobj 1163 0 obj << /Title 1164 0 R /A 1161 0 R -/Parent 1159 0 R +/Parent 5500 0 R +/Prev 1151 0 R +/Next 1175 0 R +/First 1167 0 R +/Last 1167 0 R +/Count -1 >> endobj 1159 0 obj << /Title 1160 0 R /A 1157 0 R -/Parent 5324 0 R -/Prev 1147 0 R -/First 1163 0 R -/Last 1163 0 R -/Count -1 +/Parent 1155 0 R >> endobj 1155 0 obj << /Title 1156 0 R /A 1153 0 R /Parent 1151 0 R +/First 1159 0 R +/Last 1159 0 R +/Count -1 >> endobj 1151 0 obj << /Title 1152 0 R /A 1149 0 R -/Parent 1147 0 R +/Parent 5500 0 R +/Prev 1143 0 R +/Next 1163 0 R /First 1155 0 R /Last 1155 0 R /Count -1 @@ -20469,45 +21098,44 @@ endobj 1147 0 obj << /Title 1148 0 R /A 1145 0 R -/Parent 5324 0 R -/Prev 1135 0 R -/Next 1159 0 R -/First 1151 0 R -/Last 1151 0 R -/Count -1 +/Parent 1143 0 R >> endobj 1143 0 obj << /Title 1144 0 R /A 1141 0 R -/Parent 1139 0 R +/Parent 5500 0 R +/Prev 1127 0 R +/Next 1151 0 R +/First 1147 0 R +/Last 1147 0 R +/Count -1 >> endobj 1139 0 obj << /Title 1140 0 R /A 1137 0 R -/Parent 1135 0 R -/First 1143 0 R -/Last 1143 0 R -/Count -1 +/Parent 1131 0 R +/Prev 1135 0 R >> endobj 1135 0 obj << /Title 1136 0 R /A 1133 0 R -/Parent 5324 0 R -/Prev 1123 0 R -/Next 1147 0 R -/First 1139 0 R -/Last 1139 0 R -/Count -1 +/Parent 1131 0 R +/Next 1139 0 R >> endobj 1131 0 obj << /Title 1132 0 R /A 1129 0 R /Parent 1127 0 R +/First 1135 0 R +/Last 1139 0 R +/Count -2 >> endobj 1127 0 obj << /Title 1128 0 R /A 1125 0 R -/Parent 1123 0 R +/Parent 5500 0 R +/Prev 1115 0 R +/Next 1143 0 R /First 1131 0 R /Last 1131 0 R /Count -1 @@ -20515,24 +21143,22 @@ endobj 1123 0 obj << /Title 1124 0 R /A 1121 0 R -/Parent 5324 0 R -/Prev 1115 0 R -/Next 1135 0 R -/First 1127 0 R -/Last 1127 0 R -/Count -1 +/Parent 1119 0 R >> endobj 1119 0 obj << /Title 1120 0 R /A 1117 0 R /Parent 1115 0 R +/First 1123 0 R +/Last 1123 0 R +/Count -1 >> endobj 1115 0 obj << /Title 1116 0 R /A 1113 0 R -/Parent 5324 0 R -/Prev 1099 0 R -/Next 1123 0 R +/Parent 5500 0 R +/Prev 1107 0 R +/Next 1127 0 R /First 1119 0 R /Last 1119 0 R /Count -1 @@ -20540,29 +21166,29 @@ endobj 1111 0 obj << /Title 1112 0 R /A 1109 0 R -/Parent 1103 0 R -/Prev 1107 0 R +/Parent 1107 0 R >> endobj 1107 0 obj << /Title 1108 0 R /A 1105 0 R -/Parent 1103 0 R -/Next 1111 0 R +/Parent 5500 0 R +/Prev 1099 0 R +/Next 1115 0 R +/First 1111 0 R +/Last 1111 0 R +/Count -1 >> endobj 1103 0 obj << /Title 1104 0 R /A 1101 0 R /Parent 1099 0 R -/First 1107 0 R -/Last 1111 0 R -/Count -2 >> endobj 1099 0 obj << /Title 1100 0 R /A 1097 0 R -/Parent 5324 0 R +/Parent 5500 0 R /Prev 1087 0 R -/Next 1115 0 R +/Next 1107 0 R /First 1103 0 R /Last 1103 0 R /Count -1 @@ -20583,8 +21209,8 @@ endobj 1087 0 obj << /Title 1088 0 R /A 1085 0 R -/Parent 5324 0 R -/Prev 1079 0 R +/Parent 5500 0 R +/Prev 1067 0 R /Next 1099 0 R /First 1091 0 R /Last 1091 0 R @@ -20593,89 +21219,89 @@ endobj 1083 0 obj << /Title 1084 0 R /A 1081 0 R -/Parent 1079 0 R +/Parent 1071 0 R +/Prev 1079 0 R >> endobj 1079 0 obj << /Title 1080 0 R /A 1077 0 R -/Parent 5324 0 R -/Prev 1071 0 R -/Next 1087 0 R -/First 1083 0 R -/Last 1083 0 R -/Count -1 +/Parent 1071 0 R +/Prev 1075 0 R +/Next 1083 0 R >> endobj 1075 0 obj << /Title 1076 0 R /A 1073 0 R /Parent 1071 0 R +/Next 1079 0 R >> endobj 1071 0 obj << /Title 1072 0 R /A 1069 0 R -/Parent 5324 0 R -/Prev 1059 0 R -/Next 1079 0 R +/Parent 1067 0 R /First 1075 0 R -/Last 1075 0 R -/Count -1 +/Last 1083 0 R +/Count -3 >> endobj 1067 0 obj << /Title 1068 0 R /A 1065 0 R -/Parent 1063 0 R +/Parent 5500 0 R +/Prev 1051 0 R +/Next 1087 0 R +/First 1071 0 R +/Last 1071 0 R +/Count -1 >> endobj 1063 0 obj << /Title 1064 0 R /A 1061 0 R -/Parent 1059 0 R -/First 1067 0 R -/Last 1067 0 R -/Count -1 +/Parent 1055 0 R +/Prev 1059 0 R >> endobj 1059 0 obj << /Title 1060 0 R /A 1057 0 R -/Parent 5324 0 R -/Prev 1039 0 R -/Next 1071 0 R -/First 1063 0 R -/Last 1063 0 R -/Count -1 +/Parent 1055 0 R +/Next 1063 0 R >> endobj 1055 0 obj << /Title 1056 0 R /A 1053 0 R -/Parent 1043 0 R -/Prev 1051 0 R +/Parent 1051 0 R +/First 1059 0 R +/Last 1063 0 R +/Count -2 >> endobj 1051 0 obj << /Title 1052 0 R /A 1049 0 R -/Parent 1043 0 R -/Prev 1047 0 R -/Next 1055 0 R +/Parent 5500 0 R +/Prev 1039 0 R +/Next 1067 0 R +/First 1055 0 R +/Last 1055 0 R +/Count -1 >> endobj 1047 0 obj << /Title 1048 0 R /A 1045 0 R /Parent 1043 0 R -/Next 1051 0 R >> endobj 1043 0 obj << /Title 1044 0 R /A 1041 0 R /Parent 1039 0 R /First 1047 0 R -/Last 1055 0 R -/Count -3 +/Last 1047 0 R +/Count -1 >> endobj 1039 0 obj << /Title 1040 0 R /A 1037 0 R -/Parent 5324 0 R -/Prev 1023 0 R -/Next 1059 0 R +/Parent 5500 0 R +/Prev 1031 0 R +/Next 1051 0 R /First 1043 0 R /Last 1043 0 R /Count -1 @@ -20683,153 +21309,151 @@ endobj 1035 0 obj << /Title 1036 0 R /A 1033 0 R -/Parent 1027 0 R -/Prev 1031 0 R +/Parent 1031 0 R >> endobj 1031 0 obj << /Title 1032 0 R /A 1029 0 R -/Parent 1027 0 R -/Next 1035 0 R +/Parent 5500 0 R +/Prev 1027 0 R +/Next 1039 0 R +/First 1035 0 R +/Last 1035 0 R +/Count -1 >> endobj 1027 0 obj << /Title 1028 0 R /A 1025 0 R -/Parent 1023 0 R -/First 1031 0 R -/Last 1035 0 R -/Count -2 +/Parent 5500 0 R +/Prev 975 0 R +/Next 1031 0 R >> endobj 1023 0 obj << /Title 1024 0 R /A 1021 0 R -/Parent 5324 0 R -/Prev 1011 0 R -/Next 1039 0 R -/First 1027 0 R -/Last 1027 0 R -/Count -1 +/Parent 975 0 R +/Prev 1019 0 R >> endobj 1019 0 obj << /Title 1020 0 R /A 1017 0 R -/Parent 1015 0 R +/Parent 975 0 R +/Prev 1015 0 R +/Next 1023 0 R >> endobj 1015 0 obj << /Title 1016 0 R /A 1013 0 R -/Parent 1011 0 R -/First 1019 0 R -/Last 1019 0 R -/Count -1 +/Parent 975 0 R +/Prev 1011 0 R +/Next 1019 0 R >> endobj 1011 0 obj << /Title 1012 0 R /A 1009 0 R -/Parent 5324 0 R -/Prev 1003 0 R -/Next 1023 0 R -/First 1015 0 R -/Last 1015 0 R -/Count -1 +/Parent 975 0 R +/Prev 1007 0 R +/Next 1015 0 R >> endobj 1007 0 obj << /Title 1008 0 R /A 1005 0 R -/Parent 1003 0 R +/Parent 975 0 R +/Prev 1003 0 R +/Next 1011 0 R >> endobj 1003 0 obj << /Title 1004 0 R /A 1001 0 R -/Parent 5324 0 R +/Parent 975 0 R /Prev 999 0 R -/Next 1011 0 R -/First 1007 0 R -/Last 1007 0 R -/Count -1 +/Next 1007 0 R >> endobj 999 0 obj << /Title 1000 0 R /A 997 0 R -/Parent 5324 0 R -/Prev 947 0 R +/Parent 975 0 R +/Prev 995 0 R /Next 1003 0 R >> endobj 995 0 obj << /Title 996 0 R /A 993 0 R -/Parent 947 0 R +/Parent 975 0 R /Prev 991 0 R +/Next 999 0 R >> endobj 991 0 obj << /Title 992 0 R /A 989 0 R -/Parent 947 0 R +/Parent 975 0 R /Prev 987 0 R /Next 995 0 R >> endobj 987 0 obj << /Title 988 0 R /A 985 0 R -/Parent 947 0 R +/Parent 975 0 R /Prev 983 0 R /Next 991 0 R >> endobj 983 0 obj << /Title 984 0 R /A 981 0 R -/Parent 947 0 R +/Parent 975 0 R /Prev 979 0 R /Next 987 0 R >> endobj 979 0 obj << /Title 980 0 R /A 977 0 R -/Parent 947 0 R -/Prev 975 0 R +/Parent 975 0 R /Next 983 0 R >> endobj 975 0 obj << /Title 976 0 R /A 973 0 R -/Parent 947 0 R -/Prev 971 0 R -/Next 979 0 R +/Parent 5500 0 R +/Prev 959 0 R +/Next 1027 0 R +/First 979 0 R +/Last 1023 0 R +/Count -12 >> endobj 971 0 obj << /Title 972 0 R /A 969 0 R -/Parent 947 0 R +/Parent 959 0 R /Prev 967 0 R -/Next 975 0 R >> endobj 967 0 obj << /Title 968 0 R /A 965 0 R -/Parent 947 0 R +/Parent 959 0 R /Prev 963 0 R /Next 971 0 R >> endobj 963 0 obj << /Title 964 0 R /A 961 0 R -/Parent 947 0 R -/Prev 959 0 R +/Parent 959 0 R /Next 967 0 R >> endobj 959 0 obj << /Title 960 0 R /A 957 0 R -/Parent 947 0 R -/Prev 955 0 R -/Next 963 0 R +/Parent 5500 0 R +/Prev 947 0 R +/Next 975 0 R +/First 963 0 R +/Last 971 0 R +/Count -3 >> endobj 955 0 obj << /Title 956 0 R /A 953 0 R /Parent 947 0 R /Prev 951 0 R -/Next 959 0 R >> endobj 951 0 obj << /Title 952 0 R @@ -20840,588 +21464,587 @@ endobj 947 0 obj << /Title 948 0 R /A 945 0 R -/Parent 5324 0 R -/Prev 931 0 R -/Next 999 0 R +/Parent 5500 0 R +/Prev 907 0 R +/Next 959 0 R /First 951 0 R -/Last 995 0 R -/Count -12 +/Last 955 0 R +/Count -2 >> endobj 943 0 obj << /Title 944 0 R /A 941 0 R -/Parent 931 0 R +/Parent 907 0 R /Prev 939 0 R >> endobj 939 0 obj << /Title 940 0 R /A 937 0 R -/Parent 931 0 R +/Parent 907 0 R /Prev 935 0 R /Next 943 0 R >> endobj 935 0 obj << /Title 936 0 R /A 933 0 R -/Parent 931 0 R +/Parent 907 0 R +/Prev 931 0 R /Next 939 0 R >> endobj 931 0 obj << /Title 932 0 R /A 929 0 R -/Parent 5324 0 R -/Prev 919 0 R -/Next 947 0 R -/First 935 0 R -/Last 943 0 R -/Count -3 +/Parent 907 0 R +/Prev 927 0 R +/Next 935 0 R >> endobj 927 0 obj << /Title 928 0 R /A 925 0 R -/Parent 919 0 R +/Parent 907 0 R /Prev 923 0 R +/Next 931 0 R >> endobj 923 0 obj << /Title 924 0 R /A 921 0 R -/Parent 919 0 R +/Parent 907 0 R +/Prev 919 0 R /Next 927 0 R >> endobj 919 0 obj << /Title 920 0 R /A 917 0 R -/Parent 5324 0 R -/Prev 875 0 R -/Next 931 0 R -/First 923 0 R -/Last 927 0 R -/Count -2 +/Parent 907 0 R +/Prev 915 0 R +/Next 923 0 R >> endobj 915 0 obj << /Title 916 0 R /A 913 0 R -/Parent 875 0 R +/Parent 907 0 R /Prev 911 0 R +/Next 919 0 R >> endobj 911 0 obj << /Title 912 0 R /A 909 0 R -/Parent 875 0 R -/Prev 907 0 R +/Parent 907 0 R /Next 915 0 R >> endobj 907 0 obj << /Title 908 0 R /A 905 0 R -/Parent 875 0 R +/Parent 5500 0 R /Prev 903 0 R -/Next 911 0 R +/Next 947 0 R +/First 911 0 R +/Last 943 0 R +/Count -9 >> endobj 903 0 obj << /Title 904 0 R /A 901 0 R -/Parent 875 0 R -/Prev 899 0 R +/Parent 5500 0 R +/Prev 835 0 R /Next 907 0 R >> endobj 899 0 obj << /Title 900 0 R /A 897 0 R -/Parent 875 0 R +/Parent 879 0 R /Prev 895 0 R -/Next 903 0 R >> endobj 895 0 obj << /Title 896 0 R /A 893 0 R -/Parent 875 0 R +/Parent 879 0 R /Prev 891 0 R /Next 899 0 R >> endobj 891 0 obj << /Title 892 0 R /A 889 0 R -/Parent 875 0 R +/Parent 879 0 R /Prev 887 0 R /Next 895 0 R >> endobj 887 0 obj << /Title 888 0 R /A 885 0 R -/Parent 875 0 R +/Parent 879 0 R /Prev 883 0 R /Next 891 0 R >> endobj 883 0 obj << /Title 884 0 R /A 881 0 R -/Parent 875 0 R -/Prev 879 0 R +/Parent 879 0 R /Next 887 0 R >> endobj 879 0 obj << /Title 880 0 R /A 877 0 R -/Parent 875 0 R -/Next 883 0 R +/Parent 835 0 R +/Prev 875 0 R +/First 883 0 R +/Last 899 0 R +/Count -5 >> endobj 875 0 obj << /Title 876 0 R /A 873 0 R -/Parent 5324 0 R +/Parent 835 0 R /Prev 871 0 R -/Next 919 0 R -/First 879 0 R -/Last 915 0 R -/Count -10 +/Next 879 0 R >> endobj 871 0 obj << /Title 872 0 R /A 869 0 R -/Parent 5324 0 R -/Prev 799 0 R +/Parent 835 0 R +/Prev 843 0 R /Next 875 0 R >> endobj 867 0 obj << /Title 868 0 R /A 865 0 R -/Parent 847 0 R +/Parent 843 0 R /Prev 863 0 R >> endobj 863 0 obj << /Title 864 0 R /A 861 0 R -/Parent 847 0 R +/Parent 843 0 R /Prev 859 0 R /Next 867 0 R >> endobj 859 0 obj << /Title 860 0 R /A 857 0 R -/Parent 847 0 R +/Parent 843 0 R /Prev 855 0 R /Next 863 0 R >> endobj 855 0 obj << /Title 856 0 R /A 853 0 R -/Parent 847 0 R +/Parent 843 0 R /Prev 851 0 R /Next 859 0 R >> endobj 851 0 obj << /Title 852 0 R /A 849 0 R -/Parent 847 0 R +/Parent 843 0 R +/Prev 847 0 R /Next 855 0 R >> endobj 847 0 obj << /Title 848 0 R /A 845 0 R -/Parent 799 0 R -/Prev 843 0 R -/First 851 0 R -/Last 867 0 R -/Count -5 +/Parent 843 0 R +/Next 851 0 R >> endobj 843 0 obj << /Title 844 0 R /A 841 0 R -/Parent 799 0 R -/Prev 835 0 R -/Next 847 0 R +/Parent 835 0 R +/Prev 839 0 R +/Next 871 0 R +/First 847 0 R +/Last 867 0 R +/Count -6 >> endobj 839 0 obj << /Title 840 0 R /A 837 0 R /Parent 835 0 R +/Next 843 0 R >> endobj 835 0 obj << /Title 836 0 R /A 833 0 R -/Parent 799 0 R -/Prev 831 0 R -/Next 843 0 R +/Parent 5500 0 R +/Prev 651 0 R +/Next 903 0 R /First 839 0 R -/Last 839 0 R -/Count -1 +/Last 879 0 R +/Count -5 >> endobj 831 0 obj << /Title 832 0 R /A 829 0 R -/Parent 799 0 R -/Prev 803 0 R -/Next 835 0 R +/Parent 815 0 R +/Prev 827 0 R >> endobj 827 0 obj << /Title 828 0 R /A 825 0 R -/Parent 803 0 R +/Parent 815 0 R /Prev 823 0 R +/Next 831 0 R >> endobj 823 0 obj << /Title 824 0 R /A 821 0 R -/Parent 803 0 R +/Parent 815 0 R /Prev 819 0 R /Next 827 0 R >> endobj 819 0 obj << /Title 820 0 R /A 817 0 R -/Parent 803 0 R -/Prev 815 0 R +/Parent 815 0 R /Next 823 0 R >> endobj 815 0 obj << /Title 816 0 R /A 813 0 R -/Parent 803 0 R +/Parent 651 0 R /Prev 811 0 R -/Next 819 0 R +/First 819 0 R +/Last 831 0 R +/Count -4 >> endobj 811 0 obj << /Title 812 0 R /A 809 0 R -/Parent 803 0 R -/Prev 807 0 R +/Parent 651 0 R +/Prev 791 0 R /Next 815 0 R >> endobj 807 0 obj << /Title 808 0 R /A 805 0 R -/Parent 803 0 R -/Next 811 0 R +/Parent 799 0 R +/Prev 803 0 R >> endobj 803 0 obj << /Title 804 0 R /A 801 0 R /Parent 799 0 R -/Next 831 0 R -/First 807 0 R -/Last 827 0 R -/Count -6 +/Next 807 0 R >> endobj 799 0 obj << /Title 800 0 R /A 797 0 R -/Parent 5324 0 R -/Prev 615 0 R -/Next 871 0 R +/Parent 791 0 R +/Prev 795 0 R /First 803 0 R -/Last 847 0 R -/Count -5 +/Last 807 0 R +/Count -2 >> endobj 795 0 obj << /Title 796 0 R /A 793 0 R -/Parent 779 0 R -/Prev 791 0 R +/Parent 791 0 R +/Next 799 0 R >> endobj 791 0 obj << /Title 792 0 R /A 789 0 R -/Parent 779 0 R -/Prev 787 0 R -/Next 795 0 R +/Parent 651 0 R +/Prev 771 0 R +/Next 811 0 R +/First 795 0 R +/Last 799 0 R +/Count -2 >> endobj 787 0 obj << /Title 788 0 R /A 785 0 R -/Parent 779 0 R +/Parent 771 0 R /Prev 783 0 R -/Next 791 0 R >> endobj 783 0 obj << /Title 784 0 R /A 781 0 R -/Parent 779 0 R +/Parent 771 0 R +/Prev 779 0 R /Next 787 0 R >> endobj 779 0 obj << /Title 780 0 R /A 777 0 R -/Parent 615 0 R +/Parent 771 0 R /Prev 775 0 R -/First 783 0 R -/Last 795 0 R -/Count -4 +/Next 783 0 R >> endobj 775 0 obj << /Title 776 0 R /A 773 0 R -/Parent 615 0 R -/Prev 755 0 R +/Parent 771 0 R /Next 779 0 R >> endobj 771 0 obj << /Title 772 0 R /A 769 0 R -/Parent 763 0 R +/Parent 651 0 R /Prev 767 0 R +/Next 791 0 R +/First 775 0 R +/Last 787 0 R +/Count -4 >> endobj 767 0 obj << /Title 768 0 R /A 765 0 R -/Parent 763 0 R +/Parent 651 0 R +/Prev 751 0 R /Next 771 0 R >> endobj 763 0 obj << /Title 764 0 R /A 761 0 R -/Parent 755 0 R +/Parent 751 0 R /Prev 759 0 R -/First 767 0 R -/Last 771 0 R -/Count -2 >> endobj 759 0 obj << /Title 760 0 R /A 757 0 R -/Parent 755 0 R +/Parent 751 0 R +/Prev 755 0 R /Next 763 0 R >> endobj 755 0 obj << /Title 756 0 R /A 753 0 R -/Parent 615 0 R -/Prev 735 0 R -/Next 775 0 R -/First 759 0 R -/Last 763 0 R -/Count -2 +/Parent 751 0 R +/Next 759 0 R >> endobj 751 0 obj << /Title 752 0 R /A 749 0 R -/Parent 735 0 R -/Prev 747 0 R +/Parent 651 0 R +/Prev 715 0 R +/Next 767 0 R +/First 755 0 R +/Last 763 0 R +/Count -3 >> endobj 747 0 obj << /Title 748 0 R /A 745 0 R -/Parent 735 0 R +/Parent 719 0 R /Prev 743 0 R -/Next 751 0 R >> endobj 743 0 obj << /Title 744 0 R /A 741 0 R -/Parent 735 0 R +/Parent 719 0 R /Prev 739 0 R /Next 747 0 R >> endobj 739 0 obj << /Title 740 0 R /A 737 0 R -/Parent 735 0 R +/Parent 719 0 R +/Prev 735 0 R /Next 743 0 R >> endobj 735 0 obj << /Title 736 0 R /A 733 0 R -/Parent 615 0 R +/Parent 719 0 R /Prev 731 0 R -/Next 755 0 R -/First 739 0 R -/Last 751 0 R -/Count -4 +/Next 739 0 R >> endobj 731 0 obj << /Title 732 0 R /A 729 0 R -/Parent 615 0 R -/Prev 715 0 R +/Parent 719 0 R +/Prev 727 0 R /Next 735 0 R >> endobj 727 0 obj << /Title 728 0 R /A 725 0 R -/Parent 715 0 R +/Parent 719 0 R /Prev 723 0 R +/Next 731 0 R >> endobj 723 0 obj << /Title 724 0 R /A 721 0 R -/Parent 715 0 R -/Prev 719 0 R +/Parent 719 0 R /Next 727 0 R >> endobj 719 0 obj << /Title 720 0 R /A 717 0 R /Parent 715 0 R -/Next 723 0 R +/First 723 0 R +/Last 747 0 R +/Count -7 >> endobj 715 0 obj << /Title 716 0 R /A 713 0 R -/Parent 615 0 R -/Prev 679 0 R -/Next 731 0 R +/Parent 651 0 R +/Prev 703 0 R +/Next 751 0 R /First 719 0 R -/Last 727 0 R -/Count -3 +/Last 719 0 R +/Count -1 >> endobj 711 0 obj << /Title 712 0 R /A 709 0 R -/Parent 683 0 R +/Parent 703 0 R /Prev 707 0 R >> endobj 707 0 obj << /Title 708 0 R /A 705 0 R -/Parent 683 0 R -/Prev 703 0 R +/Parent 703 0 R /Next 711 0 R >> endobj 703 0 obj << /Title 704 0 R /A 701 0 R -/Parent 683 0 R -/Prev 699 0 R -/Next 707 0 R +/Parent 651 0 R +/Prev 671 0 R +/Next 715 0 R +/First 707 0 R +/Last 711 0 R +/Count -2 >> endobj 699 0 obj << /Title 700 0 R /A 697 0 R -/Parent 683 0 R +/Parent 671 0 R /Prev 695 0 R -/Next 703 0 R >> endobj 695 0 obj << /Title 696 0 R /A 693 0 R -/Parent 683 0 R +/Parent 671 0 R /Prev 691 0 R /Next 699 0 R >> endobj 691 0 obj << /Title 692 0 R /A 689 0 R -/Parent 683 0 R -/Prev 687 0 R +/Parent 671 0 R +/Prev 675 0 R /Next 695 0 R >> endobj 687 0 obj << /Title 688 0 R /A 685 0 R -/Parent 683 0 R -/Next 691 0 R +/Parent 675 0 R +/Prev 683 0 R >> endobj 683 0 obj << /Title 684 0 R /A 681 0 R -/Parent 679 0 R -/First 687 0 R -/Last 711 0 R -/Count -7 +/Parent 675 0 R +/Prev 679 0 R +/Next 687 0 R >> endobj 679 0 obj << /Title 680 0 R /A 677 0 R -/Parent 615 0 R -/Prev 667 0 R -/Next 715 0 R -/First 683 0 R -/Last 683 0 R -/Count -1 +/Parent 675 0 R +/Next 683 0 R >> endobj 675 0 obj << /Title 676 0 R /A 673 0 R -/Parent 667 0 R -/Prev 671 0 R +/Parent 671 0 R +/Next 691 0 R +/First 679 0 R +/Last 687 0 R +/Count -3 >> endobj 671 0 obj << /Title 672 0 R /A 669 0 R -/Parent 667 0 R -/Next 675 0 R +/Parent 651 0 R +/Prev 667 0 R +/Next 703 0 R +/First 675 0 R +/Last 699 0 R +/Count -4 >> endobj 667 0 obj << /Title 668 0 R /A 665 0 R -/Parent 615 0 R -/Prev 635 0 R -/Next 679 0 R -/First 671 0 R -/Last 675 0 R -/Count -2 +/Parent 651 0 R +/Prev 663 0 R +/Next 671 0 R >> endobj 663 0 obj << /Title 664 0 R /A 661 0 R -/Parent 635 0 R +/Parent 651 0 R /Prev 659 0 R +/Next 667 0 R >> endobj 659 0 obj << /Title 660 0 R /A 657 0 R -/Parent 635 0 R +/Parent 651 0 R /Prev 655 0 R /Next 663 0 R >> endobj 655 0 obj << /Title 656 0 R /A 653 0 R -/Parent 635 0 R -/Prev 639 0 R +/Parent 651 0 R /Next 659 0 R >> endobj 651 0 obj << /Title 652 0 R /A 649 0 R -/Parent 639 0 R -/Prev 647 0 R +/Parent 5500 0 R +/Prev 595 0 R +/Next 835 0 R +/First 655 0 R +/Last 815 0 R +/Count -13 >> endobj 647 0 obj << /Title 648 0 R /A 645 0 R -/Parent 639 0 R -/Prev 643 0 R -/Next 651 0 R +/Parent 643 0 R >> endobj 643 0 obj << /Title 644 0 R /A 641 0 R -/Parent 639 0 R -/Next 647 0 R +/Parent 595 0 R +/Prev 631 0 R +/First 647 0 R +/Last 647 0 R +/Count -1 >> endobj 639 0 obj << /Title 640 0 R /A 637 0 R -/Parent 635 0 R -/Next 655 0 R -/First 643 0 R -/Last 651 0 R -/Count -3 +/Parent 631 0 R +/Prev 635 0 R >> endobj 635 0 obj << /Title 636 0 R /A 633 0 R -/Parent 615 0 R -/Prev 631 0 R -/Next 667 0 R -/First 639 0 R -/Last 663 0 R -/Count -4 +/Parent 631 0 R +/Next 639 0 R >> endobj 631 0 obj << /Title 632 0 R /A 629 0 R -/Parent 615 0 R -/Prev 627 0 R -/Next 635 0 R +/Parent 595 0 R +/Prev 615 0 R +/Next 643 0 R +/First 635 0 R +/Last 639 0 R +/Count -2 >> endobj 627 0 obj << /Title 628 0 R /A 625 0 R /Parent 615 0 R /Prev 623 0 R -/Next 631 0 R >> endobj 623 0 obj << /Title 624 0 R @@ -21439,83 +22062,85 @@ endobj 615 0 obj << /Title 616 0 R /A 613 0 R -/Parent 5324 0 R -/Prev 559 0 R -/Next 799 0 R +/Parent 595 0 R +/Prev 599 0 R +/Next 631 0 R /First 619 0 R -/Last 779 0 R -/Count -13 +/Last 627 0 R +/Count -3 >> endobj 611 0 obj << /Title 612 0 R /A 609 0 R -/Parent 607 0 R +/Parent 599 0 R +/Prev 607 0 R >> endobj 607 0 obj << /Title 608 0 R /A 605 0 R -/Parent 559 0 R -/Prev 595 0 R -/First 611 0 R -/Last 611 0 R -/Count -1 +/Parent 599 0 R +/Prev 603 0 R +/Next 611 0 R >> endobj 603 0 obj << /Title 604 0 R /A 601 0 R -/Parent 595 0 R -/Prev 599 0 R +/Parent 599 0 R +/Next 607 0 R >> endobj 599 0 obj << /Title 600 0 R /A 597 0 R /Parent 595 0 R -/Next 603 0 R +/Next 615 0 R +/First 603 0 R +/Last 611 0 R +/Count -3 >> endobj 595 0 obj << /Title 596 0 R /A 593 0 R -/Parent 559 0 R -/Prev 579 0 R -/Next 607 0 R +/Parent 5500 0 R +/Prev 335 0 R +/Next 651 0 R /First 599 0 R -/Last 603 0 R -/Count -2 +/Last 643 0 R +/Count -4 >> endobj 591 0 obj << /Title 592 0 R /A 589 0 R -/Parent 579 0 R -/Prev 587 0 R +/Parent 563 0 R +/Prev 575 0 R >> endobj 587 0 obj << /Title 588 0 R /A 585 0 R -/Parent 579 0 R +/Parent 575 0 R /Prev 583 0 R -/Next 591 0 R >> endobj 583 0 obj << /Title 584 0 R /A 581 0 R -/Parent 579 0 R +/Parent 575 0 R +/Prev 579 0 R /Next 587 0 R >> endobj 579 0 obj << /Title 580 0 R /A 577 0 R -/Parent 559 0 R -/Prev 563 0 R -/Next 595 0 R -/First 583 0 R -/Last 591 0 R -/Count -3 +/Parent 575 0 R +/Next 583 0 R >> endobj 575 0 obj << /Title 576 0 R /A 573 0 R /Parent 563 0 R /Prev 571 0 R +/Next 591 0 R +/First 579 0 R +/Last 587 0 R +/Count -3 >> endobj 571 0 obj << /Title 572 0 R @@ -21533,45 +22158,45 @@ endobj 563 0 obj << /Title 564 0 R /A 561 0 R -/Parent 559 0 R -/Next 579 0 R +/Parent 335 0 R +/Prev 531 0 R /First 567 0 R -/Last 575 0 R -/Count -3 +/Last 591 0 R +/Count -4 >> endobj 559 0 obj << /Title 560 0 R /A 557 0 R -/Parent 5324 0 R -/Prev 319 0 R -/Next 615 0 R -/First 563 0 R -/Last 607 0 R -/Count -4 +/Parent 547 0 R +/Prev 555 0 R >> endobj 555 0 obj << /Title 556 0 R /A 553 0 R -/Parent 531 0 R -/Prev 539 0 R +/Parent 547 0 R +/Prev 551 0 R +/Next 559 0 R >> endobj 551 0 obj << /Title 552 0 R /A 549 0 R -/Parent 539 0 R -/Prev 547 0 R +/Parent 547 0 R +/Next 555 0 R >> endobj 547 0 obj << /Title 548 0 R /A 545 0 R -/Parent 539 0 R +/Parent 531 0 R /Prev 543 0 R -/Next 551 0 R +/First 551 0 R +/Last 559 0 R +/Count -3 >> endobj 543 0 obj << /Title 544 0 R /A 541 0 R -/Parent 539 0 R +/Parent 531 0 R +/Prev 539 0 R /Next 547 0 R >> endobj 539 0 obj << @@ -21579,10 +22204,7 @@ endobj /A 537 0 R /Parent 531 0 R /Prev 535 0 R -/Next 555 0 R -/First 543 0 R -/Last 551 0 R -/Count -3 +/Next 543 0 R >> endobj 535 0 obj << /Title 536 0 R @@ -21593,187 +22215,189 @@ endobj 531 0 obj << /Title 532 0 R /A 529 0 R -/Parent 319 0 R -/Prev 499 0 R +/Parent 335 0 R +/Prev 527 0 R +/Next 563 0 R /First 535 0 R -/Last 555 0 R -/Count -3 +/Last 547 0 R +/Count -4 >> endobj 527 0 obj << /Title 528 0 R /A 525 0 R -/Parent 515 0 R +/Parent 335 0 R /Prev 523 0 R +/Next 531 0 R >> endobj 523 0 obj << /Title 524 0 R /A 521 0 R -/Parent 515 0 R -/Prev 519 0 R +/Parent 335 0 R +/Prev 511 0 R /Next 527 0 R >> endobj 519 0 obj << /Title 520 0 R /A 517 0 R -/Parent 515 0 R -/Next 523 0 R +/Parent 511 0 R +/Prev 515 0 R >> endobj 515 0 obj << /Title 516 0 R /A 513 0 R -/Parent 499 0 R -/Prev 511 0 R -/First 519 0 R -/Last 527 0 R -/Count -3 +/Parent 511 0 R +/Next 519 0 R >> endobj 511 0 obj << /Title 512 0 R /A 509 0 R -/Parent 499 0 R -/Prev 507 0 R -/Next 515 0 R +/Parent 335 0 R +/Prev 495 0 R +/Next 523 0 R +/First 515 0 R +/Last 519 0 R +/Count -2 >> endobj 507 0 obj << /Title 508 0 R /A 505 0 R -/Parent 499 0 R +/Parent 495 0 R /Prev 503 0 R -/Next 511 0 R >> endobj 503 0 obj << /Title 504 0 R /A 501 0 R -/Parent 499 0 R +/Parent 495 0 R +/Prev 499 0 R /Next 507 0 R >> endobj 499 0 obj << /Title 500 0 R /A 497 0 R -/Parent 319 0 R -/Prev 495 0 R -/Next 531 0 R -/First 503 0 R -/Last 515 0 R -/Count -4 +/Parent 495 0 R +/Next 503 0 R >> endobj 495 0 obj << /Title 496 0 R /A 493 0 R -/Parent 319 0 R -/Prev 491 0 R -/Next 499 0 R +/Parent 335 0 R +/Prev 403 0 R +/Next 511 0 R +/First 499 0 R +/Last 507 0 R +/Count -3 >> endobj 491 0 obj << /Title 492 0 R /A 489 0 R -/Parent 319 0 R -/Prev 479 0 R -/Next 495 0 R +/Parent 435 0 R +/Prev 487 0 R >> endobj 487 0 obj << /Title 488 0 R /A 485 0 R -/Parent 479 0 R -/Prev 483 0 R +/Parent 435 0 R +/Prev 439 0 R +/Next 491 0 R >> endobj 483 0 obj << /Title 484 0 R /A 481 0 R -/Parent 479 0 R -/Next 487 0 R +/Parent 439 0 R +/Prev 479 0 R >> endobj 479 0 obj << /Title 480 0 R /A 477 0 R -/Parent 319 0 R -/Prev 387 0 R -/Next 491 0 R -/First 483 0 R -/Last 487 0 R -/Count -2 +/Parent 439 0 R +/Prev 475 0 R +/Next 483 0 R >> endobj 475 0 obj << /Title 476 0 R /A 473 0 R -/Parent 419 0 R +/Parent 439 0 R /Prev 471 0 R +/Next 479 0 R >> endobj 471 0 obj << /Title 472 0 R /A 469 0 R -/Parent 419 0 R -/Prev 423 0 R +/Parent 439 0 R +/Prev 467 0 R /Next 475 0 R >> endobj 467 0 obj << /Title 468 0 R /A 465 0 R -/Parent 423 0 R +/Parent 439 0 R /Prev 463 0 R +/Next 471 0 R >> endobj 463 0 obj << /Title 464 0 R /A 461 0 R -/Parent 423 0 R +/Parent 439 0 R /Prev 459 0 R /Next 467 0 R >> endobj 459 0 obj << /Title 460 0 R /A 457 0 R -/Parent 423 0 R +/Parent 439 0 R /Prev 455 0 R /Next 463 0 R >> endobj 455 0 obj << /Title 456 0 R /A 453 0 R -/Parent 423 0 R +/Parent 439 0 R /Prev 451 0 R /Next 459 0 R >> endobj 451 0 obj << /Title 452 0 R /A 449 0 R -/Parent 423 0 R +/Parent 439 0 R /Prev 447 0 R /Next 455 0 R >> endobj 447 0 obj << /Title 448 0 R /A 445 0 R -/Parent 423 0 R +/Parent 439 0 R /Prev 443 0 R /Next 451 0 R >> endobj 443 0 obj << /Title 444 0 R /A 441 0 R -/Parent 423 0 R -/Prev 439 0 R +/Parent 439 0 R /Next 447 0 R >> endobj 439 0 obj << /Title 440 0 R /A 437 0 R -/Parent 423 0 R -/Prev 435 0 R -/Next 443 0 R +/Parent 435 0 R +/Next 487 0 R +/First 443 0 R +/Last 483 0 R +/Count -11 >> endobj 435 0 obj << /Title 436 0 R /A 433 0 R -/Parent 423 0 R -/Prev 431 0 R -/Next 439 0 R +/Parent 403 0 R +/Prev 423 0 R +/First 439 0 R +/Last 491 0 R +/Count -3 >> endobj 431 0 obj << /Title 432 0 R /A 429 0 R /Parent 423 0 R /Prev 427 0 R -/Next 435 0 R >> endobj 427 0 obj << /Title 428 0 R @@ -21784,134 +22408,132 @@ endobj 423 0 obj << /Title 424 0 R /A 421 0 R -/Parent 419 0 R -/Next 471 0 R +/Parent 403 0 R +/Prev 419 0 R +/Next 435 0 R /First 427 0 R -/Last 467 0 R -/Count -11 +/Last 431 0 R +/Count -2 >> endobj 419 0 obj << /Title 420 0 R /A 417 0 R -/Parent 387 0 R -/Prev 407 0 R -/First 423 0 R -/Last 475 0 R -/Count -3 +/Parent 403 0 R +/Prev 411 0 R +/Next 423 0 R >> endobj 415 0 obj << /Title 416 0 R /A 413 0 R -/Parent 407 0 R -/Prev 411 0 R +/Parent 411 0 R >> endobj 411 0 obj << /Title 412 0 R /A 409 0 R -/Parent 407 0 R -/Next 415 0 R +/Parent 403 0 R +/Prev 407 0 R +/Next 419 0 R +/First 415 0 R +/Last 415 0 R +/Count -1 >> endobj 407 0 obj << /Title 408 0 R /A 405 0 R -/Parent 387 0 R -/Prev 403 0 R -/Next 419 0 R -/First 411 0 R -/Last 415 0 R -/Count -2 +/Parent 403 0 R +/Next 411 0 R >> endobj 403 0 obj << /Title 404 0 R /A 401 0 R -/Parent 387 0 R -/Prev 395 0 R -/Next 407 0 R +/Parent 335 0 R +/Prev 399 0 R +/Next 495 0 R +/First 407 0 R +/Last 435 0 R +/Count -5 >> endobj 399 0 obj << /Title 400 0 R /A 397 0 R -/Parent 395 0 R +/Parent 335 0 R +/Prev 395 0 R +/Next 403 0 R >> endobj 395 0 obj << /Title 396 0 R /A 393 0 R -/Parent 387 0 R +/Parent 335 0 R /Prev 391 0 R -/Next 403 0 R -/First 399 0 R -/Last 399 0 R -/Count -1 +/Next 399 0 R >> endobj 391 0 obj << /Title 392 0 R /A 389 0 R -/Parent 387 0 R +/Parent 335 0 R +/Prev 387 0 R /Next 395 0 R >> endobj 387 0 obj << /Title 388 0 R /A 385 0 R -/Parent 319 0 R +/Parent 335 0 R /Prev 383 0 R -/Next 479 0 R -/First 391 0 R -/Last 419 0 R -/Count -5 +/Next 391 0 R >> endobj 383 0 obj << /Title 384 0 R /A 381 0 R -/Parent 319 0 R -/Prev 379 0 R +/Parent 335 0 R +/Prev 343 0 R /Next 387 0 R >> endobj 379 0 obj << /Title 380 0 R /A 377 0 R -/Parent 319 0 R +/Parent 351 0 R /Prev 375 0 R -/Next 383 0 R >> endobj 375 0 obj << /Title 376 0 R /A 373 0 R -/Parent 319 0 R +/Parent 351 0 R /Prev 371 0 R /Next 379 0 R >> endobj 371 0 obj << /Title 372 0 R /A 369 0 R -/Parent 319 0 R -/Prev 367 0 R +/Parent 351 0 R +/Prev 359 0 R /Next 375 0 R >> endobj 367 0 obj << /Title 368 0 R /A 365 0 R -/Parent 319 0 R -/Prev 327 0 R -/Next 371 0 R +/Parent 359 0 R +/Prev 363 0 R >> endobj 363 0 obj << /Title 364 0 R /A 361 0 R -/Parent 335 0 R -/Prev 359 0 R +/Parent 359 0 R +/Next 367 0 R >> endobj 359 0 obj << /Title 360 0 R /A 357 0 R -/Parent 335 0 R +/Parent 351 0 R /Prev 355 0 R -/Next 363 0 R +/Next 371 0 R +/First 363 0 R +/Last 367 0 R +/Count -2 >> endobj 355 0 obj << /Title 356 0 R /A 353 0 R -/Parent 335 0 R -/Prev 343 0 R +/Parent 351 0 R /Next 359 0 R >> endobj 351 0 obj << @@ -21919,6 +22541,9 @@ endobj /A 349 0 R /Parent 343 0 R /Prev 347 0 R +/First 355 0 R +/Last 379 0 R +/Count -5 >> endobj 347 0 obj << /Title 348 0 R @@ -21931,7 +22556,7 @@ endobj /A 341 0 R /Parent 335 0 R /Prev 339 0 R -/Next 355 0 R +/Next 383 0 R /First 347 0 R /Last 351 0 R /Count -2 @@ -21945,130 +22570,126 @@ endobj 335 0 obj << /Title 336 0 R /A 333 0 R -/Parent 327 0 R -/Prev 331 0 R +/Parent 5500 0 R +/Prev 43 0 R +/Next 595 0 R /First 339 0 R -/Last 363 0 R -/Count -5 +/Last 563 0 R +/Count -14 >> endobj 331 0 obj << /Title 332 0 R /A 329 0 R -/Parent 327 0 R -/Next 335 0 R +/Parent 279 0 R +/Prev 323 0 R >> endobj 327 0 obj << /Title 328 0 R /A 325 0 R -/Parent 319 0 R -/Prev 323 0 R -/Next 367 0 R -/First 331 0 R -/Last 335 0 R -/Count -2 +/Parent 323 0 R >> endobj 323 0 obj << /Title 324 0 R /A 321 0 R -/Parent 319 0 R -/Next 327 0 R +/Parent 279 0 R +/Prev 311 0 R +/Next 331 0 R +/First 327 0 R +/Last 327 0 R +/Count -1 >> endobj 319 0 obj << /Title 320 0 R /A 317 0 R -/Parent 5324 0 R -/Prev 43 0 R -/Next 559 0 R -/First 323 0 R -/Last 531 0 R -/Count -13 +/Parent 311 0 R +/Prev 315 0 R >> endobj 315 0 obj << /Title 316 0 R /A 313 0 R -/Parent 263 0 R -/Prev 307 0 R +/Parent 311 0 R +/Next 319 0 R >> endobj 311 0 obj << /Title 312 0 R /A 309 0 R -/Parent 307 0 R +/Parent 279 0 R +/Prev 307 0 R +/Next 323 0 R +/First 315 0 R +/Last 319 0 R +/Count -2 >> endobj 307 0 obj << /Title 308 0 R /A 305 0 R -/Parent 263 0 R -/Prev 295 0 R -/Next 315 0 R -/First 311 0 R -/Last 311 0 R -/Count -1 +/Parent 279 0 R +/Prev 287 0 R +/Next 311 0 R >> endobj 303 0 obj << /Title 304 0 R /A 301 0 R -/Parent 295 0 R +/Parent 291 0 R /Prev 299 0 R >> endobj 299 0 obj << /Title 300 0 R /A 297 0 R -/Parent 295 0 R +/Parent 291 0 R +/Prev 295 0 R /Next 303 0 R >> endobj 295 0 obj << /Title 296 0 R /A 293 0 R -/Parent 263 0 R -/Prev 291 0 R -/Next 307 0 R -/First 299 0 R -/Last 303 0 R -/Count -2 +/Parent 291 0 R +/Next 299 0 R >> endobj 291 0 obj << /Title 292 0 R /A 289 0 R -/Parent 263 0 R -/Prev 271 0 R -/Next 295 0 R +/Parent 287 0 R +/First 295 0 R +/Last 303 0 R +/Count -3 >> endobj 287 0 obj << /Title 288 0 R /A 285 0 R -/Parent 275 0 R +/Parent 279 0 R /Prev 283 0 R +/Next 307 0 R +/First 291 0 R +/Last 291 0 R +/Count -1 >> endobj 283 0 obj << /Title 284 0 R /A 281 0 R -/Parent 275 0 R -/Prev 279 0 R +/Parent 279 0 R /Next 287 0 R >> endobj 279 0 obj << /Title 280 0 R /A 277 0 R -/Parent 275 0 R -/Next 283 0 R +/Parent 43 0 R +/Prev 235 0 R +/First 283 0 R +/Last 331 0 R +/Count -6 >> endobj 275 0 obj << /Title 276 0 R /A 273 0 R -/Parent 271 0 R -/First 279 0 R -/Last 287 0 R -/Count -3 +/Parent 235 0 R +/Prev 263 0 R >> endobj 271 0 obj << /Title 272 0 R /A 269 0 R /Parent 263 0 R /Prev 267 0 R -/Next 291 0 R -/First 275 0 R -/Last 275 0 R -/Count -1 >> endobj 267 0 obj << /Title 268 0 R @@ -22079,223 +22700,224 @@ endobj 263 0 obj << /Title 264 0 R /A 261 0 R -/Parent 43 0 R -/Prev 219 0 R +/Parent 235 0 R +/Prev 239 0 R +/Next 275 0 R /First 267 0 R -/Last 315 0 R -/Count -6 +/Last 271 0 R +/Count -2 >> endobj 259 0 obj << /Title 260 0 R /A 257 0 R -/Parent 219 0 R -/Prev 247 0 R +/Parent 239 0 R +/Prev 255 0 R >> endobj 255 0 obj << /Title 256 0 R /A 253 0 R -/Parent 247 0 R +/Parent 239 0 R /Prev 251 0 R +/Next 259 0 R >> endobj 251 0 obj << /Title 252 0 R /A 249 0 R -/Parent 247 0 R +/Parent 239 0 R +/Prev 247 0 R /Next 255 0 R >> endobj 247 0 obj << /Title 248 0 R /A 245 0 R -/Parent 219 0 R -/Prev 223 0 R -/Next 259 0 R -/First 251 0 R -/Last 255 0 R -/Count -2 +/Parent 239 0 R +/Prev 243 0 R +/Next 251 0 R >> endobj 243 0 obj << /Title 244 0 R /A 241 0 R -/Parent 223 0 R -/Prev 239 0 R +/Parent 239 0 R +/Next 247 0 R >> endobj 239 0 obj << /Title 240 0 R /A 237 0 R -/Parent 223 0 R -/Prev 235 0 R -/Next 243 0 R +/Parent 235 0 R +/Next 263 0 R +/First 243 0 R +/Last 259 0 R +/Count -5 >> endobj 235 0 obj << /Title 236 0 R /A 233 0 R -/Parent 223 0 R +/Parent 43 0 R /Prev 231 0 R -/Next 239 0 R +/Next 279 0 R +/First 239 0 R +/Last 275 0 R +/Count -3 >> endobj 231 0 obj << /Title 232 0 R /A 229 0 R -/Parent 223 0 R -/Prev 227 0 R +/Parent 43 0 R +/Prev 199 0 R /Next 235 0 R >> endobj 227 0 obj << /Title 228 0 R /A 225 0 R -/Parent 223 0 R -/Next 231 0 R +/Parent 199 0 R +/Prev 223 0 R >> endobj 223 0 obj << /Title 224 0 R /A 221 0 R -/Parent 219 0 R -/Next 247 0 R -/First 227 0 R -/Last 243 0 R -/Count -5 +/Parent 199 0 R +/Prev 219 0 R +/Next 227 0 R >> endobj 219 0 obj << /Title 220 0 R /A 217 0 R -/Parent 43 0 R +/Parent 199 0 R /Prev 215 0 R -/Next 263 0 R -/First 223 0 R -/Last 259 0 R -/Count -3 +/Next 223 0 R >> endobj 215 0 obj << /Title 216 0 R /A 213 0 R -/Parent 43 0 R -/Prev 183 0 R +/Parent 199 0 R +/Prev 211 0 R /Next 219 0 R >> endobj 211 0 obj << /Title 212 0 R /A 209 0 R -/Parent 183 0 R +/Parent 199 0 R /Prev 207 0 R +/Next 215 0 R >> endobj 207 0 obj << /Title 208 0 R /A 205 0 R -/Parent 183 0 R +/Parent 199 0 R /Prev 203 0 R /Next 211 0 R >> endobj 203 0 obj << /Title 204 0 R /A 201 0 R -/Parent 183 0 R -/Prev 199 0 R +/Parent 199 0 R /Next 207 0 R >> endobj 199 0 obj << /Title 200 0 R /A 197 0 R -/Parent 183 0 R -/Prev 195 0 R -/Next 203 0 R +/Parent 43 0 R +/Prev 123 0 R +/Next 231 0 R +/First 203 0 R +/Last 227 0 R +/Count -7 >> endobj 195 0 obj << /Title 196 0 R /A 193 0 R -/Parent 183 0 R -/Prev 191 0 R -/Next 199 0 R +/Parent 123 0 R +/Prev 175 0 R >> endobj 191 0 obj << /Title 192 0 R /A 189 0 R -/Parent 183 0 R -/Prev 187 0 R -/Next 195 0 R +/Parent 175 0 R +/Prev 179 0 R >> endobj 187 0 obj << /Title 188 0 R /A 185 0 R -/Parent 183 0 R -/Next 191 0 R +/Parent 179 0 R +/Prev 183 0 R >> endobj 183 0 obj << /Title 184 0 R /A 181 0 R -/Parent 43 0 R -/Prev 115 0 R -/Next 215 0 R -/First 187 0 R -/Last 211 0 R -/Count -7 +/Parent 179 0 R +/Next 187 0 R >> endobj 179 0 obj << /Title 180 0 R /A 177 0 R -/Parent 115 0 R -/Prev 167 0 R +/Parent 175 0 R +/Next 191 0 R +/First 183 0 R +/Last 187 0 R +/Count -2 >> endobj 175 0 obj << /Title 176 0 R /A 173 0 R -/Parent 167 0 R +/Parent 123 0 R /Prev 171 0 R +/Next 195 0 R +/First 179 0 R +/Last 191 0 R +/Count -2 >> endobj 171 0 obj << /Title 172 0 R /A 169 0 R -/Parent 167 0 R +/Parent 123 0 R +/Prev 131 0 R /Next 175 0 R >> endobj 167 0 obj << /Title 168 0 R /A 165 0 R -/Parent 115 0 R +/Parent 159 0 R /Prev 163 0 R -/Next 179 0 R -/First 171 0 R -/Last 175 0 R -/Count -2 >> endobj 163 0 obj << /Title 164 0 R /A 161 0 R -/Parent 115 0 R -/Prev 123 0 R +/Parent 159 0 R /Next 167 0 R >> endobj 159 0 obj << /Title 160 0 R /A 157 0 R -/Parent 151 0 R -/Prev 155 0 R +/Parent 131 0 R +/Prev 139 0 R +/First 163 0 R +/Last 167 0 R +/Count -2 >> endobj 155 0 obj << /Title 156 0 R /A 153 0 R -/Parent 151 0 R -/Next 159 0 R +/Parent 139 0 R +/Prev 151 0 R >> endobj 151 0 obj << /Title 152 0 R /A 149 0 R -/Parent 123 0 R -/Prev 131 0 R -/First 155 0 R -/Last 159 0 R -/Count -2 +/Parent 139 0 R +/Prev 147 0 R +/Next 155 0 R >> endobj 147 0 obj << /Title 148 0 R /A 145 0 R -/Parent 131 0 R +/Parent 139 0 R /Prev 143 0 R +/Next 151 0 R >> endobj 143 0 obj << /Title 144 0 R /A 141 0 R -/Parent 131 0 R -/Prev 139 0 R +/Parent 139 0 R /Next 147 0 R >> endobj 139 0 obj << @@ -22303,7 +22925,10 @@ endobj /A 137 0 R /Parent 131 0 R /Prev 135 0 R -/Next 143 0 R +/Next 159 0 R +/First 143 0 R +/Last 155 0 R +/Count -4 >> endobj 135 0 obj << /Title 136 0 R @@ -22316,10 +22941,10 @@ endobj /A 129 0 R /Parent 123 0 R /Prev 127 0 R -/Next 151 0 R +/Next 171 0 R /First 135 0 R -/Last 147 0 R -/Count -4 +/Last 159 0 R +/Count -3 >> endobj 127 0 obj << /Title 128 0 R @@ -22330,40 +22955,38 @@ endobj 123 0 obj << /Title 124 0 R /A 121 0 R -/Parent 115 0 R -/Prev 119 0 R -/Next 163 0 R +/Parent 43 0 R +/Prev 47 0 R +/Next 199 0 R /First 127 0 R -/Last 151 0 R -/Count -3 +/Last 195 0 R +/Count -5 >> endobj 119 0 obj << /Title 120 0 R /A 117 0 R -/Parent 115 0 R -/Next 123 0 R +/Parent 47 0 R +/Prev 115 0 R >> endobj 115 0 obj << /Title 116 0 R /A 113 0 R -/Parent 43 0 R -/Prev 47 0 R -/Next 183 0 R -/First 119 0 R -/Last 179 0 R -/Count -5 +/Parent 47 0 R +/Prev 75 0 R +/Next 119 0 R >> endobj 111 0 obj << /Title 112 0 R /A 109 0 R -/Parent 47 0 R -/Prev 75 0 R +/Parent 75 0 R +/Prev 107 0 R >> endobj 107 0 obj << /Title 108 0 R /A 105 0 R /Parent 75 0 R /Prev 103 0 R +/Next 111 0 R >> endobj 103 0 obj << /Title 104 0 R @@ -22418,10 +23041,10 @@ endobj /A 73 0 R /Parent 47 0 R /Prev 71 0 R -/Next 111 0 R +/Next 115 0 R /First 79 0 R -/Last 107 0 R -/Count -8 +/Last 111 0 R +/Count -9 >> endobj 71 0 obj << /Title 72 0 R @@ -22469,19 +23092,19 @@ endobj /Title 48 0 R /A 45 0 R /Parent 43 0 R -/Next 115 0 R +/Next 123 0 R /First 51 0 R -/Last 111 0 R -/Count -6 +/Last 119 0 R +/Count -7 >> endobj 43 0 obj << /Title 44 0 R /A 41 0 R -/Parent 5324 0 R +/Parent 5500 0 R /Prev 19 0 R -/Next 319 0 R +/Next 335 0 R /First 47 0 R -/Last 263 0 R +/Last 279 0 R /Count -6 >> endobj 39 0 obj << @@ -22520,7 +23143,7 @@ endobj 19 0 obj << /Title 20 0 R /A 17 0 R -/Parent 5324 0 R +/Parent 5500 0 R /Prev 15 0 R /Next 43 0 R /First 23 0 R @@ -22530,5391 +23153,5567 @@ endobj 15 0 obj << /Title 16 0 R /A 13 0 R -/Parent 5324 0 R +/Parent 5500 0 R /Prev 11 0 R /Next 19 0 R >> endobj 11 0 obj << /Title 12 0 R /A 9 0 R -/Parent 5324 0 R +/Parent 5500 0 R /Prev 7 0 R /Next 15 0 R >> endobj 7 0 obj << /Title 8 0 R /A 5 0 R -/Parent 5324 0 R +/Parent 5500 0 R /Prev 3 0 R /Next 11 0 R >> endobj 3 0 obj << /Title 4 0 R /A 1 0 R -/Parent 5324 0 R +/Parent 5500 0 R /Next 7 0 R >> endobj -5325 0 obj << -/Names [(1.0) 2 0 R (10.0) 798 0 R (10.42.1) 802 0 R (10.42.73.2) 806 0 R (10.42.74.2) 810 0 R (10.42.75.2) 814 0 R (10.42.76.2) 818 0 R (10.42.77.2) 822 0 R (10.42.78.2) 826 0 R (10.43.1) 830 0 R (10.44.1) 834 0 R (10.44.79.2) 838 0 R (10.45.1) 842 0 R (10.46.1) 846 0 R (10.46.80.2) 850 0 R (10.46.81.2) 854 0 R (10.46.82.2) 858 0 R (10.46.83.2) 862 0 R (10.46.84.2) 866 0 R (1000) 1442 0 R (1002) 2767 0 R (1004) 2769 0 R (1005) 2770 0 R (1006) 2771 0 R (1007) 2776 0 R (1008) 2777 0 R (1009) 2778 0 R (101) 1971 0 R (1010) 2779 0 R (1011) 2780 0 R (1012) 2781 0 R (1013) 2782 0 R (1014) 2783 0 R (1019) 2788 0 R (102) 1972 0 R (1020) 2789 0 R (1022) 2790 0 R (1024) 2791 0 R (1025) 2792 0 R (1026) 2793 0 R (1028) 2794 0 R (1029) 2795 0 R (103) 1973 0 R (1030) 2796 0 R (1031) 2797 0 R (1032) 2798 0 R (1033) 2799 0 R (1034) 2800 0 R (1036) 2801 0 R (1037) 2802 0 R (1038) 2803 0 R (104) 1974 0 R (1040) 2804 0 R (1041) 2805 0 R (1042) 2806 0 R (1043) 2807 0 R (1045) 2808 0 R (1046) 2809 0 R (1047) 2810 0 R (1048) 2811 0 R (105) 1975 0 R (1050) 2812 0 R (1051) 2813 0 R (1052) 2814 0 R (1053) 2815 0 R (1054) 2816 0 R (1055) 2817 0 R (1057) 2823 0 R (1059) 2824 0 R (106) 1976 0 R (1060) 2825 0 R (1061) 2826 0 R (1062) 2827 0 R (1063) 2828 0 R (1064) 2829 0 R (1066) 2830 0 R (1067) 2831 0 R (1068) 2832 0 R (1069) 2833 0 R (107) 1977 0 R (1071) 2834 0 R (1072) 2835 0 R (1073) 2836 0 R (1074) 2837 0 R (1076) 2838 0 R (1077) 2839 0 R (1078) 2840 0 R (108) 1978 0 R (1080) 2841 0 R (1081) 2842 0 R (1082) 2843 0 R (1084) 2849 0 R (1085) 2850 0 R (1086) 2851 0 R (1088) 2852 0 R (1089) 2853 0 R (109) 1979 0 R (1090) 2854 0 R (1091) 2855 0 R (1092) 2856 0 R (1093) 2857 0 R (1095) 2858 0 R (1096) 2859 0 R (1097) 2860 0 R (1098) 2861 0 R (11.0) 870 0 R (110) 1980 0 R (1100) 2862 0 R (1101) 2863 0 R (1102) 2864 0 R (1104) 2865 0 R (1105) 2866 0 R (1106) 2867 0 R (111) 1981 0 R (1111) 2868 0 R (1112) 2869 0 R (1113) 2848 0 R (1118) 2874 0 R (1119) 2875 0 R (112) 1982 0 R (1120) 2876 0 R (1121) 2877 0 R (1122) 2878 0 R (1123) 2879 0 R (1128) 2881 0 R (1129) 2882 0 R (113) 1983 0 R (1130) 2883 0 R (1131) 2884 0 R (1135) 2887 0 R (1136) 2888 0 R (1137) 2889 0 R (1138) 2890 0 R (1139) 2891 0 R (114) 1984 0 R (1140) 2892 0 R (1141) 2893 0 R (1142) 2894 0 R (1143) 2895 0 R (1144) 2896 0 R (1145) 2897 0 R (1148) 2902 0 R (1149) 2903 0 R (1150) 2904 0 R (1151) 2905 0 R (1152) 2906 0 R (1153) 2907 0 R (1154) 2908 0 R (1155) 2909 0 R (1156) 2910 0 R (1157) 2911 0 R (1158) 2912 0 R (1159) 2913 0 R (1160) 2914 0 R (1161) 2915 0 R (1162) 2916 0 R (1163) 2917 0 R (1164) 2918 0 R (1165) 2919 0 R (1166) 2920 0 R (1167) 2921 0 R (1168) 2922 0 R (1169) 2923 0 R (117) 1988 0 R (1170) 2924 0 R (1171) 2925 0 R (1172) 2926 0 R (1173) 2927 0 R (1174) 2928 0 R (1175) 2929 0 R (1176) 2930 0 R (1177) 2931 0 R (1178) 2932 0 R (1179) 2933 0 R (1180) 2934 0 R (1181) 2935 0 R (1182) 2936 0 R (1183) 2937 0 R (1184) 2938 0 R (1185) 2939 0 R (1186) 2940 0 R (1187) 2941 0 R (1188) 2942 0 R (1189) 2943 0 R (119) 1989 0 R (1190) 2944 0 R (1191) 2945 0 R (1192) 2946 0 R (1193) 2947 0 R (1194) 2948 0 R (1195) 2949 0 R (1196) 2954 0 R (1197) 2955 0 R (12.0) 874 0 R (12.47.1) 878 0 R (12.48.1) 882 0 R (12.49.1) 886 0 R (12.50.1) 890 0 R (12.51.1) 894 0 R (12.52.1) 898 0 R (12.53.1) 902 0 R (12.54.1) 906 0 R (12.55.1) 910 0 R (12.56.1) 914 0 R (120) 1990 0 R (1200) 2956 0 R (1201) 2957 0 R (1205) 2959 0 R (1206) 2960 0 R (1207) 2961 0 R (1208) 2962 0 R (1209) 2963 0 R (121) 1991 0 R (1210) 2964 0 R (1211) 2965 0 R (1212) 2966 0 R (1213) 2967 0 R (1216) 2968 0 R (1217) 2969 0 R (1218) 2970 0 R (1219) 2971 0 R (1220) 2972 0 R (1221) 2977 0 R (1224) 2978 0 R (1226) 2980 0 R (1227) 2981 0 R (1228) 2982 0 R (1229) 2983 0 R (1230) 2984 0 R (1231) 2985 0 R (1232) 2986 0 R (1233) 2987 0 R (1234) 2988 0 R (1235) 2989 0 R (1238) 2990 0 R (1239) 2991 0 R (1240) 2992 0 R (1241) 2993 0 R (1242) 2994 0 R (1243) 2995 0 R (1244) 2996 0 R (1245) 2997 0 R (1246) 2998 0 R (1247) 2999 0 R (1248) 3000 0 R (1251) 3008 0 R (1252) 3009 0 R (1253) 3010 0 R (1254) 3011 0 R (1255) 3012 0 R (1256) 3013 0 R (1257) 3014 0 R (1258) 3015 0 R (1259) 3016 0 R (1262) 3017 0 R (1263) 3018 0 R (1264) 3019 0 R (1265) 3020 0 R (1266) 3021 0 R (1267) 3022 0 R (1268) 3023 0 R (1269) 3024 0 R (1270) 3025 0 R (1271) 3026 0 R (1272) 3027 0 R (1273) 3028 0 R (1274) 3029 0 R (1277) 3030 0 R (1278) 3031 0 R (1279) 3032 0 R (1280) 3033 0 R (1283) 3039 0 R (1284) 3040 0 R (1285) 3041 0 R (1286) 3007 0 R (1293) 3042 0 R (1294) 3043 0 R (1295) 3044 0 R (1296) 3045 0 R (1297) 3046 0 R (1298) 3047 0 R (1299) 3048 0 R (13.0) 918 0 R (13.57.1) 922 0 R (13.58.1) 926 0 R (1300) 3049 0 R (1301) 3050 0 R (1302) 3051 0 R (1303) 3052 0 R (1304) 3053 0 R (1305) 3054 0 R (1306) 3055 0 R (1307) 3056 0 R (1308) 3057 0 R (1309) 3058 0 R (1314) 3059 0 R (1315) 3060 0 R (1317) 3061 0 R (1318) 3062 0 R (1319) 3063 0 R (1320) 3064 0 R (1322) 3065 0 R (1323) 3066 0 R (1324) 3067 0 R (1325) 3068 0 R (1326) 3069 0 R (1328) 3070 0 R (1329) 3071 0 R (1330) 3072 0 R (1331) 3073 0 R (1332) 3074 0 R (1333) 3075 0 R (1334) 3076 0 R (1337) 3081 0 R (1338) 3082 0 R (1339) 3083 0 R (1340) 3084 0 R (1341) 3085 0 R (1342) 3038 0 R (1344) 3086 0 R (1345) 3087 0 R (1346) 3088 0 R (1347) 3089 0 R (1350) 3090 0 R (1353) 3091 0 R (1354) 3092 0 R (1355) 3093 0 R (1356) 3094 0 R (1357) 3095 0 R (1358) 3096 0 R (1359) 3097 0 R (1360) 3098 0 R (1361) 3099 0 R (1362) 3100 0 R (1363) 3101 0 R (1364) 3102 0 R (1365) 3103 0 R (1366) 3104 0 R (1367) 3105 0 R (1368) 3106 0 R (1369) 3107 0 R (1370) 3108 0 R (1371) 3109 0 R (1374) 3110 0 R (1375) 3111 0 R (1376) 3112 0 R (1377) 3113 0 R (1378) 3114 0 R (1381) 3119 0 R (1382) 3120 0 R (1383) 3121 0 R (1384) 3122 0 R (1385) 3123 0 R (1388) 3124 0 R (1389) 3125 0 R (1392) 3127 0 R (1395) 3129 0 R (1396) 3130 0 R (1397) 3131 0 R (14.0) 930 0 R (14.59.1) 934 0 R (14.60.1) 938 0 R (14.61.1) 942 0 R (1400) 3133 0 R (1401) 3134 0 R (1402) 3135 0 R (1403) 3136 0 R (1404) 3137 0 R (1405) 3138 0 R (1406) 3139 0 R (1407) 3140 0 R (1408) 3141 0 R (1409) 3142 0 R (1410) 3143 0 R (1411) 3144 0 R (1412) 3145 0 R (1413) 3146 0 R (1414) 3147 0 R (1415) 3148 0 R (1416) 3149 0 R (1417) 3150 0 R (1418) 3151 0 R (1419) 3152 0 R (1420) 3153 0 R (1421) 3154 0 R (1422) 3155 0 R (1423) 3156 0 R (1424) 3157 0 R (1425) 3158 0 R (1426) 3159 0 R (1427) 3160 0 R (1428) 3161 0 R (1429) 3162 0 R (1430) 3163 0 R (1433) 3169 0 R (1434) 3170 0 R (1435) 3171 0 R (1438) 3173 0 R (1439) 3174 0 R (1442) 3176 0 R (1443) 3177 0 R (1444) 3178 0 R (1445) 3179 0 R (1446) 3180 0 R (1447) 3181 0 R (1450) 3183 0 R (1451) 3184 0 R (1454) 3186 0 R (1455) 3187 0 R (1456) 3188 0 R (1457) 3189 0 R (1460) 3191 0 R (1463) 3193 0 R (1464) 3194 0 R (1465) 3195 0 R (1466) 3196 0 R (1469) 3203 0 R (1470) 3204 0 R (1473) 3205 0 R (1474) 3206 0 R (1475) 3207 0 R (1476) 3208 0 R (1477) 3209 0 R (1478) 3210 0 R (1479) 3211 0 R (1480) 3212 0 R (1483) 3213 0 R (1484) 3214 0 R (1485) 3215 0 R (1488) 3216 0 R (1489) 3217 0 R (1492) 3218 0 R (1493) 3219 0 R (1494) 3220 0 R (1495) 3221 0 R (1498) 3222 0 R (1499) 3223 0 R (15.0) 946 0 R (15.62.1) 950 0 R (15.63.1) 954 0 R (15.64.1) 958 0 R (15.65.1) 962 0 R (15.66.1) 966 0 R (15.67.1) 970 0 R (15.68.1) 974 0 R (15.69.1) 978 0 R (15.70.1) 982 0 R (15.71.1) 986 0 R (15.72.1) 990 0 R (15.73.1) 994 0 R (1500) 3224 0 R (1501) 3225 0 R (1502) 3226 0 R (1503) 3232 0 R (1504) 3202 0 R (1507) 3233 0 R (1508) 3234 0 R (1509) 3235 0 R (1510) 3236 0 R (1511) 3237 0 R (1512) 3238 0 R (1513) 3239 0 R (1514) 3240 0 R (1515) 3241 0 R (1516) 3242 0 R (1517) 3243 0 R (1518) 3244 0 R (1519) 3245 0 R (1520) 3246 0 R (1521) 3247 0 R (1522) 3248 0 R (1525) 3249 0 R (1526) 3250 0 R (1527) 3251 0 R (1528) 3252 0 R (1529) 3253 0 R (1530) 3254 0 R (1533) 3259 0 R (1534) 3260 0 R (1535) 3261 0 R (1536) 3262 0 R (1537) 3263 0 R (1538) 3264 0 R (1539) 3265 0 R (1540) 3266 0 R (1541) 3267 0 R (1542) 3268 0 R (1543) 3269 0 R (1544) 1576 0 R (1546) 3270 0 R (1547) 3271 0 R (1548) 3272 0 R (1549) 3273 0 R (1550) 3274 0 R (1551) 3275 0 R (1552) 3276 0 R (1553) 3277 0 R (1554) 3278 0 R (1555) 3279 0 R (1556) 3280 0 R (1557) 3281 0 R (1558) 3282 0 R (1559) 3283 0 R (1560) 3284 0 R (1561) 3285 0 R (1562) 3286 0 R (1563) 3287 0 R (1564) 3288 0 R (1565) 3289 0 R (1566) 3290 0 R (1567) 3291 0 R (1568) 3292 0 R (1569) 3293 0 R (1570) 3299 0 R (1571) 1577 0 R (1573) 3300 0 R (1574) 3301 0 R (1575) 3302 0 R (1576) 3303 0 R (1577) 3304 0 R (1578) 3305 0 R (1579) 3306 0 R (1580) 3307 0 R (1581) 1578 0 R (1583) 3308 0 R (1584) 3309 0 R (1585) 3310 0 R (1586) 3311 0 R (1587) 3312 0 R (1588) 3313 0 R (1589) 3314 0 R (1590) 3315 0 R (1591) 3316 0 R (1592) 3317 0 R (1593) 3318 0 R (1594) 3319 0 R (1595) 3320 0 R (1596) 3321 0 R (1597) 3322 0 R (1598) 3323 0 R (1599) 1579 0 R (16.0) 998 0 R (1601) 1580 0 R (1603) 3328 0 R (1604) 3298 0 R (1605) 1581 0 R (1607) 3329 0 R (1608) 3330 0 R (1609) 1582 0 R (1611) 3331 0 R (1612) 3332 0 R (1613) 3333 0 R (1614) 3334 0 R (1615) 3335 0 R (1616) 3336 0 R (1617) 3337 0 R (1618) 3338 0 R (1619) 3339 0 R (1620) 3340 0 R (1621) 3341 0 R (1622) 3342 0 R (1625) 3347 0 R (1626) 3348 0 R (1627) 3349 0 R (1628) 3350 0 R (1629) 3351 0 R (1630) 3352 0 R (1633) 3353 0 R (1634) 3354 0 R (1635) 3355 0 R (1636) 3356 0 R (1637) 3357 0 R (1638) 3358 0 R (1641) 3363 0 R (1642) 3364 0 R (1643) 3365 0 R (1644) 3366 0 R (1646) 3368 0 R (1647) 3369 0 R (1649) 3371 0 R (1650) 3372 0 R (1652) 3374 0 R (1654) 3376 0 R (1655) 3377 0 R (1656) 3378 0 R (1657) 3379 0 R (1658) 3380 0 R (1661) 3381 0 R (1662) 3382 0 R (1663) 3383 0 R (1664) 3384 0 R (1665) 3385 0 R (1666) 3386 0 R (1667) 3387 0 R (1668) 3388 0 R (1669) 3389 0 R (1670) 3395 0 R (1671) 3396 0 R (1672) 3397 0 R (1673) 3398 0 R (1674) 3399 0 R (1677) 3400 0 R (1678) 3401 0 R (1679) 3402 0 R (1680) 3403 0 R (1681) 3404 0 R (1682) 3405 0 R (1683) 3406 0 R (1684) 3407 0 R (1685) 3408 0 R (1686) 3409 0 R (1687) 3410 0 R (1688) 3411 0 R (1689) 3412 0 R (1690) 3413 0 R (1691) 3414 0 R (1692) 3415 0 R (1693) 3416 0 R (1694) 3417 0 R (1695) 3418 0 R (1696) 3419 0 R (1697) 3420 0 R (17.0) 1002 0 R (17.73.85.2) 1006 0 R (1700) 3425 0 R (1701) 3426 0 R (1702) 3427 0 R (1703) 3428 0 R (1704) 3429 0 R (1705) 3430 0 R (1706) 3431 0 R (1707) 3432 0 R (1708) 3433 0 R (1709) 3434 0 R (1710) 3435 0 R (1711) 3436 0 R (1712) 3437 0 R (1713) 3438 0 R (1717) 3440 0 R (1718) 3441 0 R (1719) 3442 0 R (1720) 3443 0 R (1721) 3444 0 R (1722) 3445 0 R (1723) 3446 0 R (1724) 3447 0 R (1725) 3448 0 R (1726) 3449 0 R (1729) 3454 0 R (1730) 3455 0 R (1731) 3456 0 R (1736) 3457 0 R (1739) 3458 0 R (1741) 3460 0 R (1742) 3461 0 R (1743) 3462 0 R (1744) 3463 0 R (1746) 3465 0 R (1747) 3466 0 R (1748) 3467 0 R (1749) 3468 0 R (1750) 3469 0 R (1751) 3470 0 R (1752) 3471 0 R (1753) 3472 0 R (1754) 3473 0 R (1755) 3474 0 R (1756) 3475 0 R (1760) 3476 0 R (1761) 3477 0 R (1766) 3484 0 R (1772) 3486 0 R (1773) 3487 0 R (1774) 3488 0 R (1775) 3489 0 R (1779) 3490 0 R (1780) 3491 0 R (1781) 3492 0 R (1782) 3493 0 R (1783) 3494 0 R (1787) 3495 0 R (1788) 3496 0 R (1790) 3497 0 R (1791) 3498 0 R (1792) 3499 0 R (1793) 3500 0 R (1794) 3501 0 R (1795) 3502 0 R (18.0) 1010 0 R (18.73.86.2) 1014 0 R (18.73.86.56.3) 1018 0 R (1800) 3504 0 R (1804) 3506 0 R (1805) 3507 0 R (1806) 3508 0 R (1811) 3513 0 R (1812) 3514 0 R (1813) 3515 0 R (1814) 3516 0 R (1818) 3519 0 R (1819) 3520 0 R (182) 1996 0 R (1820) 3521 0 R (1821) 3522 0 R (1822) 3523 0 R (1823) 3524 0 R (1825) 3525 0 R (1826) 3526 0 R (1827) 3527 0 R (1828) 3528 0 R (1829) 3529 0 R (183) 1997 0 R (1830) 3530 0 R (1831) 3531 0 R (1832) 3532 0 R (1833) 3533 0 R (1834) 3534 0 R (1835) 3535 0 R (1836) 3536 0 R (1838) 3537 0 R (1839) 3538 0 R (1840) 3539 0 R (1841) 3540 0 R (1842) 3541 0 R (1843) 3542 0 R (1844) 3543 0 R (1845) 3544 0 R (1846) 3545 0 R (1847) 3546 0 R (1848) 3547 0 R (1849) 3548 0 R (1850) 3549 0 R (1852) 3550 0 R (1853) 3551 0 R (1854) 3552 0 R (1855) 3553 0 R (1856) 3554 0 R (1857) 3555 0 R (1858) 3556 0 R (1859) 3557 0 R (1860) 3558 0 R (1862) 3559 0 R (1863) 3560 0 R (1864) 3561 0 R (1865) 3562 0 R (1866) 3563 0 R (1867) 3564 0 R (1868) 3565 0 R (1869) 3566 0 R (1870) 3567 0 R (1871) 3568 0 R (1872) 3569 0 R (1873) 3570 0 R (1874) 3571 0 R (1875) 3572 0 R (1876) 3573 0 R (1877) 3574 0 R (1878) 3575 0 R (1879) 3576 0 R (188) 2002 0 R (1880) 3577 0 R (1881) 3578 0 R (1882) 3579 0 R (1883) 3580 0 R (1884) 3581 0 R (1885) 3582 0 R (1886) 3583 0 R (1887) 3584 0 R (1888) 3590 0 R (1889) 3591 0 R (189) 2003 0 R (1890) 3592 0 R (1891) 3593 0 R (1892) 3594 0 R (1897) 3596 0 R (1898) 3597 0 R (1899) 3598 0 R (19.0) 1022 0 R (19.73.87.2) 1026 0 R (19.73.88.2) 1030 0 R (19.73.89.2) 1034 0 R (190) 2004 0 R (1901) 3600 0 R (1902) 3601 0 R (1903) 3602 0 R (1904) 3603 0 R (1909) 3604 0 R (191) 2007 0 R (1910) 3605 0 R (1911) 3606 0 R (1912) 3607 0 R (1913) 3608 0 R (1914) 3609 0 R (1919) 3616 0 R (1920) 3617 0 R (1923) 3618 0 R (1924) 3619 0 R (1925) 3620 0 R (1926) 3621 0 R (1927) 3622 0 R (1928) 3623 0 R (1929) 3624 0 R (193) 2010 0 R (1930) 3625 0 R (1931) 3626 0 R (1932) 3627 0 R (1933) 3628 0 R (1934) 3629 0 R (1935) 3630 0 R (1936) 3631 0 R (1939) 3632 0 R (194) 2011 0 R (1940) 3633 0 R (1941) 3634 0 R (1942) 3635 0 R (1943) 3636 0 R (1944) 3637 0 R (1945) 3638 0 R (195) 2012 0 R (196) 2013 0 R (1966) 3644 0 R (1967) 3645 0 R (1968) 3646 0 R (1969) 3647 0 R (197) 2014 0 R (1970) 3648 0 R (1971) 3649 0 R (1972) 3650 0 R (1973) 3651 0 R (1974) 3652 0 R (1975) 3653 0 R (1976) 3654 0 R (1977) 3655 0 R (1978) 3656 0 R (1979) 3657 0 R (198) 2015 0 R (1980) 3658 0 R (1981) 3659 0 R (1982) 3660 0 R (1983) 3661 0 R (1984) 3662 0 R (1985) 3663 0 R (1986) 3664 0 R (1987) 3665 0 R (1988) 3666 0 R (1989) 3667 0 R (199) 2016 0 R (1990) 3668 0 R (1991) 3669 0 R (1992) 3670 0 R (1993) 3671 0 R (1994) 3672 0 R (1995) 3673 0 R (1996) 3674 0 R (1997) 3675 0 R (1998) 3676 0 R (1999) 3677 0 R (2.0) 6 0 R (20.0) 1038 0 R (20.73.90.2) 1042 0 R (20.73.91.2) 1046 0 R (20.73.92.2) 1050 0 R (20.73.93.2) 1054 0 R (200) 2017 0 R (2000) 3678 0 R (2001) 3679 0 R (2002) 3680 0 R (2003) 3681 0 R (2004) 3682 0 R (2005) 3683 0 R (2006) 3684 0 R (2007) 3685 0 R (2008) 3686 0 R (2009) 3687 0 R (201) 2018 0 R (2010) 3688 0 R (2011) 3689 0 R (2012) 3690 0 R (2033) 3692 0 R (2034) 3693 0 R (2035) 3694 0 R (2036) 3695 0 R (2037) 3696 0 R (2038) 3697 0 R (2039) 3698 0 R (204) 2020 0 R (2040) 3699 0 R (2041) 3700 0 R (2042) 3701 0 R (2043) 3702 0 R (2044) 3703 0 R (2047) 3710 0 R (2049) 3712 0 R (2050) 3713 0 R (2053) 3714 0 R (2058) 3715 0 R (2059) 3721 0 R (2060) 3709 0 R (2061) 3722 0 R (2064) 3723 0 R (2065) 3724 0 R (2066) 3725 0 R (2067) 3726 0 R (2068) 3727 0 R (2069) 3728 0 R (207) 2022 0 R (2070) 3729 0 R (2071) 3730 0 R (2072) 3731 0 R (2073) 3732 0 R (2074) 3733 0 R (2075) 3734 0 R (2076) 3735 0 R (2077) 3736 0 R (2078) 3737 0 R (2079) 3738 0 R (2080) 3739 0 R (2083) 3740 0 R (2086) 3741 0 R (2087) 3742 0 R (2088) 3743 0 R (2089) 3744 0 R (2090) 3745 0 R (2091) 3746 0 R (2092) 3747 0 R (2093) 3748 0 R (2094) 3749 0 R (2095) 3750 0 R (2096) 3720 0 R (2097) 3755 0 R (2098) 3756 0 R (21.0) 1058 0 R (21.73.94.2) 1062 0 R (21.73.95.2) 1066 0 R (210) 2024 0 R (2101) 3757 0 R (2102) 3758 0 R (2103) 3759 0 R (2104) 3760 0 R (2105) 3761 0 R (2106) 3762 0 R (2109) 3763 0 R (2110) 3764 0 R (2111) 3765 0 R (2112) 3766 0 R (2113) 3767 0 R (2116) 3768 0 R (2117) 3769 0 R (2118) 3770 0 R (213) 2026 0 R (2139) 3772 0 R (2142) 3777 0 R (2143) 3778 0 R (2144) 3779 0 R (2146) 3781 0 R (2147) 3782 0 R (2148) 3783 0 R (2149) 3784 0 R (2154) 3785 0 R (2155) 3786 0 R (2156) 3787 0 R (2157) 3788 0 R (2158) 3789 0 R (2159) 3790 0 R (216) 2028 0 R (2160) 3791 0 R (2161) 3792 0 R (2162) 3793 0 R (2163) 3794 0 R (2164) 3795 0 R (2165) 3796 0 R (2166) 3797 0 R (2167) 3798 0 R (2168) 3799 0 R (2169) 3800 0 R (2170) 3801 0 R (2171) 3807 0 R (2172) 3808 0 R (2173) 3809 0 R (2174) 3810 0 R (2175) 3811 0 R (2176) 3812 0 R (2177) 3813 0 R (2178) 3814 0 R (2179) 3815 0 R (2182) 3816 0 R (2183) 3817 0 R (2184) 3818 0 R (2187) 3819 0 R (2188) 3820 0 R (2189) 3821 0 R (219) 2030 0 R (2190) 3822 0 R (2191) 3823 0 R (2192) 3824 0 R (2193) 3829 0 R (2194) 3830 0 R (2195) 3831 0 R (2198) 3832 0 R (2199) 3833 0 R (22.0) 1070 0 R (22.73.96.2) 1074 0 R (2200) 3834 0 R (2210) 3836 0 R (2213) 3837 0 R (2216) 3838 0 R (2219) 3839 0 R (2222) 3844 0 R (2225) 3845 0 R (2226) 3846 0 R (2229) 3847 0 R (223) 2031 0 R (2232) 3848 0 R (2233) 1728 0 R (2235) 3849 0 R (2236) 3850 0 R (2237) 3851 0 R (224) 2032 0 R (2246) 3853 0 R (2249) 3858 0 R (225) 2033 0 R (2250) 3859 0 R (2253) 3860 0 R (2254) 3861 0 R (2255) 3862 0 R (2258) 3863 0 R (2259) 3864 0 R (226) 2034 0 R (2260) 3865 0 R (2261) 3866 0 R (2262) 3867 0 R (2263) 3868 0 R (2264) 3869 0 R (2267) 3870 0 R (2270) 3871 0 R (2271) 3872 0 R (2272) 3873 0 R (2275) 3878 0 R (2276) 3879 0 R (2277) 3880 0 R (2278) 3881 0 R (2279) 3882 0 R (2280) 3883 0 R (2281) 3884 0 R (2282) 3885 0 R (2283) 3886 0 R (2284) 3887 0 R (2285) 3888 0 R (2289) 3890 0 R (229) 2038 0 R (2290) 3891 0 R (2293) 3892 0 R (2294) 3893 0 R (2295) 3894 0 R (2296) 3895 0 R (2297) 3896 0 R (2298) 3897 0 R (2299) 3898 0 R (23.0) 1078 0 R (23.73.97.2) 1082 0 R (2300) 3899 0 R (2301) 3900 0 R (2302) 3901 0 R (2303) 3902 0 R (2304) 3903 0 R (2305) 3904 0 R (2306) 3905 0 R (2307) 3906 0 R (2308) 3907 0 R (2309) 3908 0 R (2310) 3909 0 R (2311) 3910 0 R (2312) 3911 0 R (2313) 3912 0 R (2314) 3913 0 R (2315) 3919 0 R (2316) 3920 0 R (2317) 3921 0 R (2318) 3922 0 R (2319) 3923 0 R (232) 2039 0 R (2320) 3924 0 R (2321) 3925 0 R (2322) 3926 0 R (2323) 3927 0 R (2324) 3928 0 R (2325) 3929 0 R (2326) 3930 0 R (2327) 3931 0 R (2328) 3932 0 R (2329) 3933 0 R (233) 2040 0 R (2330) 3934 0 R (2331) 3935 0 R (2332) 3936 0 R (2333) 3937 0 R (2334) 3938 0 R (2335) 3939 0 R (2336) 3940 0 R (2337) 3941 0 R (2338) 3942 0 R (2339) 3943 0 R (234) 2041 0 R (2342) 3944 0 R (2345) 3945 0 R (2348) 3952 0 R (2349) 3918 0 R (235) 2042 0 R (2350) 3953 0 R (2351) 3954 0 R (2352) 3955 0 R (2355) 3956 0 R (2356) 3957 0 R (2357) 3958 0 R (2358) 3959 0 R (2359) 3960 0 R (236) 2043 0 R (2360) 3961 0 R (2361) 1740 0 R (2363) 3962 0 R (2364) 3967 0 R (2365) 3951 0 R (2366) 3968 0 R (2367) 3969 0 R (2368) 1741 0 R (237) 2044 0 R (2370) 3970 0 R (2371) 3971 0 R (2374) 3972 0 R (2375) 3973 0 R (2376) 3974 0 R (2377) 3975 0 R (2378) 3976 0 R (2379) 3977 0 R (238) 2045 0 R (2380) 3978 0 R (2381) 3979 0 R (2384) 3985 0 R (2385) 3986 0 R (2386) 3987 0 R (2387) 3988 0 R (2388) 3989 0 R (2389) 3990 0 R (239) 2046 0 R (2391) 3992 0 R (2392) 3993 0 R (2396) 3995 0 R (2397) 3996 0 R (2398) 3997 0 R (24) 1905 0 R (24.0) 1086 0 R (24.73.98.2) 1090 0 R (24.73.99.2) 1094 0 R (240) 2047 0 R (2401) 3998 0 R (2402) 3999 0 R (2403) 4000 0 R (2404) 4005 0 R (2405) 3984 0 R (2406) 4006 0 R (2407) 4007 0 R (2408) 4008 0 R (2411) 4009 0 R (2412) 4010 0 R (2413) 4011 0 R (2415) 4013 0 R (2416) 4014 0 R (2417) 4015 0 R (2418) 4016 0 R (2419) 4017 0 R (2420) 4022 0 R (2421) 1747 0 R (2423) 4023 0 R (2424) 4024 0 R (2425) 4025 0 R (243) 2048 0 R (2430) 4030 0 R (2431) 4031 0 R (2435) 4033 0 R (2436) 4034 0 R (2437) 4035 0 R (2438) 4036 0 R (2439) 4037 0 R (244) 2049 0 R (2440) 4038 0 R (2441) 4039 0 R (2442) 4040 0 R (2443) 4041 0 R (2444) 4042 0 R (2447) 4043 0 R (2448) 4044 0 R (2449) 4045 0 R (245) 2050 0 R (2450) 4046 0 R (2451) 4047 0 R (2452) 4048 0 R (2453) 4049 0 R (2454) 4050 0 R (2455) 4051 0 R (2456) 4052 0 R (2457) 4053 0 R (2458) 4054 0 R (2459) 4060 0 R (246) 2051 0 R (2460) 4061 0 R (2461) 4062 0 R (2462) 4063 0 R (2463) 4064 0 R (2464) 4065 0 R (2465) 4066 0 R (2466) 4067 0 R (2467) 4068 0 R (2468) 4069 0 R (2469) 4070 0 R (247) 2052 0 R (2470) 4071 0 R (2473) 4072 0 R (2474) 4073 0 R (2475) 4074 0 R (2476) 4075 0 R (2477) 4076 0 R (2478) 4077 0 R (2479) 4078 0 R (2480) 4079 0 R (2481) 4080 0 R (2482) 4081 0 R (2485) 4086 0 R (2486) 4087 0 R (2487) 4088 0 R (2488) 4089 0 R (2489) 4090 0 R (2490) 4091 0 R (2491) 4092 0 R (2492) 4093 0 R (2493) 4094 0 R (2494) 4095 0 R (2495) 4096 0 R (2496) 4097 0 R (2497) 4098 0 R (2498) 4099 0 R (2499) 4100 0 R (25) 1906 0 R (25.0) 1098 0 R (25.73.100.2) 1102 0 R (25.73.101.2) 1106 0 R (25.73.102.2) 1110 0 R (250) 2053 0 R (2500) 4101 0 R (2501) 4102 0 R (2504) 4103 0 R (2505) 4104 0 R (2506) 4105 0 R (2507) 4106 0 R (2508) 4107 0 R (2509) 4108 0 R (251) 2054 0 R (2510) 4109 0 R (2511) 4110 0 R (2512) 4111 0 R (2513) 4112 0 R (2514) 4113 0 R (2515) 4114 0 R (2516) 4115 0 R (2517) 4116 0 R (2518) 4117 0 R (2519) 4118 0 R (2520) 4119 0 R (2521) 4120 0 R (2522) 4125 0 R (2523) 4126 0 R (2524) 4127 0 R (2525) 4128 0 R (2526) 4129 0 R (2527) 4130 0 R (2528) 4131 0 R (2529) 4132 0 R (253) 2056 0 R (2530) 4133 0 R (2531) 4134 0 R (2532) 4135 0 R (2533) 4136 0 R (2534) 4137 0 R (2535) 4138 0 R (2536) 4139 0 R (2537) 4140 0 R (2538) 4141 0 R (2539) 4142 0 R (254) 2057 0 R (2540) 4143 0 R (2541) 4144 0 R (2542) 4145 0 R (2543) 4146 0 R (2544) 4147 0 R (2545) 4148 0 R (2546) 4149 0 R (2549) 4154 0 R (255) 2058 0 R (2550) 4155 0 R (2551) 4156 0 R (2552) 4157 0 R (2553) 4158 0 R (2554) 4159 0 R (2555) 4160 0 R (2558) 4161 0 R (2559) 4162 0 R (2560) 4163 0 R (2561) 4164 0 R (2562) 4165 0 R (2563) 4166 0 R (2564) 4167 0 R (2565) 4168 0 R (2566) 4169 0 R (2567) 4170 0 R (2568) 4171 0 R (2569) 4172 0 R (2570) 4173 0 R (2571) 4174 0 R (2572) 4175 0 R (2573) 4176 0 R (2574) 4177 0 R (2575) 4178 0 R (258) 2064 0 R (2580) 4180 0 R (2581) 4185 0 R (2582) 4186 0 R (2583) 4187 0 R (2584) 4188 0 R (2585) 4189 0 R (2586) 4190 0 R (2587) 4191 0 R (2588) 4192 0 R (2589) 4193 0 R (259) 2065 0 R (2590) 4194 0 R (2591) 4195 0 R (2592) 4196 0 R (2593) 4197 0 R (2594) 4198 0 R (2595) 4199 0 R (2596) 4200 0 R (2597) 4201 0 R (2598) 4202 0 R (2599) 4203 0 R (26) 1907 0 R (26.0) 1114 0 R (26.73.103.2) 1118 0 R (260) 2066 0 R (2600) 4204 0 R (2601) 4205 0 R (2602) 4206 0 R (2603) 4207 0 R (2604) 4208 0 R (2605) 4209 0 R (2606) 4210 0 R (2607) 4211 0 R (2608) 4212 0 R (2609) 4213 0 R (261) 2067 0 R (2610) 4214 0 R (2611) 4215 0 R (2612) 4216 0 R (2613) 4217 0 R (2614) 4218 0 R (2615) 4224 0 R (2616) 4225 0 R (2617) 4226 0 R (2618) 4227 0 R (2619) 4228 0 R (262) 2068 0 R (2620) 4229 0 R (2623) 4230 0 R (2624) 4231 0 R (2625) 4232 0 R (2626) 4233 0 R (2627) 4234 0 R (2628) 4235 0 R (2629) 4236 0 R (263) 2069 0 R (2630) 4237 0 R (2631) 4238 0 R (2632) 4239 0 R (2633) 4240 0 R (2634) 4241 0 R (2635) 4247 0 R (2636) 4223 0 R (2637) 4248 0 R (2638) 4249 0 R (2639) 4250 0 R (264) 2070 0 R (2640) 4251 0 R (2641) 4252 0 R (2642) 4253 0 R (2643) 4254 0 R (2644) 4255 0 R (2647) 4256 0 R (2648) 4257 0 R (2649) 4258 0 R (265) 2071 0 R (2652) 4263 0 R (2653) 4264 0 R (2654) 4265 0 R (2655) 4266 0 R (2656) 4267 0 R (2657) 4268 0 R (2658) 4269 0 R (2659) 4270 0 R (266) 2072 0 R (2660) 4271 0 R (2665) 4272 0 R (267) 2073 0 R (2670) 4276 0 R (2671) 4277 0 R (2672) 4278 0 R (2673) 4279 0 R (2674) 4280 0 R (2675) 4281 0 R (2676) 4282 0 R (2677) 4283 0 R (2680) 4284 0 R (2681) 4285 0 R (2682) 4286 0 R (2683) 4287 0 R (2684) 4288 0 R (2687) 4293 0 R (2688) 4294 0 R (2691) 4295 0 R (2692) 4296 0 R (2693) 4297 0 R (2696) 4302 0 R (2697) 4303 0 R (2699) 4305 0 R (27.0) 1122 0 R (27.73.104.2) 1126 0 R (27.73.105.2) 1130 0 R (270) 2074 0 R (2703) 4307 0 R (2705) 4308 0 R (2709) 4310 0 R (271) 2075 0 R (2711) 4311 0 R (2712) 4312 0 R (2716) 4314 0 R (2718) 4315 0 R (2719) 4316 0 R (2720) 4317 0 R (2724) 4319 0 R (2726) 4320 0 R (273) 2077 0 R (2730) 4322 0 R (2732) 4323 0 R (2733) 4324 0 R (2737) 4326 0 R (2739) 4327 0 R (274) 2078 0 R (2740) 4328 0 R (2741) 4334 0 R (2742) 4335 0 R (2743) 4336 0 R (2744) 4337 0 R (2748) 4339 0 R (275) 2079 0 R (2750) 4340 0 R (2751) 4341 0 R (2752) 4342 0 R (2753) 4343 0 R (2754) 4344 0 R (2755) 4345 0 R (2756) 4346 0 R (276) 2080 0 R (2760) 4348 0 R (2761) 4349 0 R (2763) 4350 0 R (2764) 4351 0 R (2768) 4353 0 R (2769) 4354 0 R (277) 2081 0 R (2770) 4355 0 R (2772) 4356 0 R (2773) 4357 0 R (2774) 4333 0 R (2776) 4362 0 R (2777) 4363 0 R (2778) 4364 0 R (2779) 4365 0 R (278) 2082 0 R (2780) 4366 0 R (2781) 4367 0 R (2782) 4368 0 R (2783) 4369 0 R (2784) 4370 0 R (2785) 4371 0 R (2786) 4372 0 R (2787) 4373 0 R (2788) 4374 0 R (2789) 4375 0 R (279) 2083 0 R (2793) 4377 0 R (2798) 4379 0 R (2799) 4380 0 R (28) 1909 0 R (28.0) 1134 0 R (28.73.106.2) 1138 0 R (28.73.107.2) 1142 0 R (280) 2084 0 R (2801) 4381 0 R (2803) 4383 0 R (2807) 4385 0 R (2812) 4387 0 R (2814) 4393 0 R (2815) 4394 0 R (2819) 4396 0 R (2821) 4397 0 R (2823) 4399 0 R (2827) 4401 0 R (283) 2087 0 R (2832) 4403 0 R (2834) 4404 0 R (2835) 4405 0 R (2836) 4406 0 R (284) 2088 0 R (2840) 4408 0 R (2841) 4409 0 R (2843) 4410 0 R (2844) 4411 0 R (2845) 4412 0 R (2846) 4413 0 R (2847) 4414 0 R (2848) 4415 0 R (2849) 4416 0 R (285) 2089 0 R (2853) 4422 0 R (2855) 4423 0 R (2856) 4424 0 R (286) 2090 0 R (2860) 4426 0 R (2865) 4428 0 R (2867) 4429 0 R (287) 2091 0 R (2871) 4431 0 R (2872) 4432 0 R (2874) 4433 0 R (2878) 4435 0 R (288) 2092 0 R (2883) 4437 0 R (2888) 4439 0 R (289) 2093 0 R (2892) 4442 0 R (2896) 4448 0 R (29.0) 1146 0 R (29.73.108.2) 1150 0 R (29.73.109.2) 1154 0 R (290) 2094 0 R (2901) 4450 0 R (2906) 4452 0 R (2908) 4453 0 R (2909) 4454 0 R (291) 2095 0 R (2910) 4455 0 R (2911) 4456 0 R (2912) 4457 0 R (2913) 4458 0 R (2914) 4459 0 R (2915) 4460 0 R (2916) 4461 0 R (2917) 4462 0 R (2918) 4463 0 R (2919) 4464 0 R (292) 2096 0 R (2920) 4465 0 R (2921) 4466 0 R (2922) 4467 0 R (2923) 4468 0 R (2924) 4469 0 R (2925) 4470 0 R (293) 2100 0 R (2930) 4473 0 R (2932) 4474 0 R (2933) 4475 0 R (2934) 4476 0 R (2935) 4477 0 R (2936) 4482 0 R (2937) 4483 0 R (294) 2101 0 R (2941) 4485 0 R (2943) 4486 0 R (2944) 4487 0 R (2945) 4488 0 R (2946) 4489 0 R (2947) 4490 0 R (2948) 4491 0 R (2949) 4492 0 R (295) 2102 0 R (2950) 4493 0 R (2952) 4495 0 R (2953) 4496 0 R (2954) 4497 0 R (2955) 4498 0 R (2956) 4499 0 R (2957) 4500 0 R (2959) 4502 0 R (296) 2103 0 R (2963) 4508 0 R (2965) 4509 0 R (2966) 4510 0 R (2967) 4511 0 R (2968) 4512 0 R (297) 2104 0 R (2973) 4515 0 R (2976) 4517 0 R (298) 2105 0 R (2980) 4519 0 R (2982) 4520 0 R (2986) 4522 0 R (2988) 4523 0 R (2989) 4524 0 R (299) 2106 0 R (2990) 4525 0 R (2991) 4526 0 R (2992) 4527 0 R (2993) 4528 0 R (2994) 4529 0 R (2995) 4530 0 R (2996) 4531 0 R (2997) 4532 0 R (2998) 4533 0 R (2999) 4534 0 R (3.0) 10 0 R (30.0) 1158 0 R (30.73.110.2) 1162 0 R (300) 2107 0 R (3000) 4535 0 R (3001) 4536 0 R (3002) 4541 0 R (3003) 4542 0 R (3004) 4543 0 R (3005) 4544 0 R (3006) 4545 0 R (3007) 4546 0 R (3008) 4547 0 R (3009) 4548 0 R (301) 2108 0 R (3010) 4549 0 R (3011) 4550 0 R (3015) 4552 0 R (3017) 4553 0 R (3018) 4554 0 R (3019) 4555 0 R (302) 2109 0 R (3020) 4556 0 R (3024) 4558 0 R (3029) 4560 0 R (303) 2110 0 R (3031) 4561 0 R (3032) 4562 0 R (3033) 4563 0 R (3034) 4564 0 R (3035) 4565 0 R (3036) 4566 0 R (3037) 4567 0 R (3038) 4568 0 R (304) 2111 0 R (3040) 4570 0 R (3041) 4571 0 R (3045) 4573 0 R (3047) 4574 0 R (3048) 4575 0 R (3049) 4576 0 R (305) 2112 0 R (3050) 4577 0 R (3051) 4578 0 R (3052) 4579 0 R (3053) 4580 0 R (3055) 4582 0 R (3059) 4584 0 R (306) 2113 0 R (3061) 4585 0 R (3062) 4586 0 R (3063) 4587 0 R (3067) 4596 0 R (3069) 4597 0 R (307) 2114 0 R (3070) 4598 0 R (3071) 4599 0 R (3072) 4600 0 R (3073) 4601 0 R (3077) 4603 0 R (3079) 4604 0 R (308) 2115 0 R (3080) 4605 0 R (3081) 4606 0 R (3082) 4607 0 R (3086) 4609 0 R (3088) 4610 0 R (3089) 4611 0 R (3090) 4612 0 R (3092) 4614 0 R (3096) 4616 0 R (3098) 4617 0 R (31) 1910 0 R (310) 2117 0 R (3100) 4594 0 R (3105) 4624 0 R (311) 2118 0 R (3110) 4626 0 R (3111) 4627 0 R (3113) 4628 0 R (3114) 4629 0 R (3115) 4630 0 R (3116) 4631 0 R (3117) 4632 0 R (312) 2119 0 R (3121) 4634 0 R (3123) 4635 0 R (3124) 4636 0 R (3125) 4637 0 R (3126) 4638 0 R (3127) 4639 0 R (3128) 4640 0 R (3129) 4641 0 R (313) 2120 0 R (3130) 4642 0 R (3131) 4643 0 R (3132) 4644 0 R (3133) 4645 0 R (3134) 4646 0 R (3135) 4647 0 R (3136) 4648 0 R (3138) 4650 0 R (314) 2121 0 R (3142) 4652 0 R (3147) 4654 0 R (3149) 4660 0 R (315) 2122 0 R (3150) 4661 0 R (3151) 4662 0 R (3152) 4663 0 R (3153) 4664 0 R (3154) 4665 0 R (3158) 4667 0 R (3159) 4668 0 R (316) 2123 0 R (3161) 4669 0 R (317) 2124 0 R (3172) 4672 0 R (3173) 4673 0 R (3178) 4675 0 R (3180) 4676 0 R (3184) 4678 0 R (3185) 4679 0 R (3187) 4680 0 R (3188) 4681 0 R (3189) 4682 0 R (319) 2126 0 R (3190) 4683 0 R (3191) 4684 0 R (3193) 4659 0 R (3197) 4691 0 R (3199) 4692 0 R (32) 1911 0 R (320) 2127 0 R (3200) 4693 0 R (3201) 4694 0 R (3205) 4696 0 R (3207) 4697 0 R (3208) 4698 0 R (3209) 4699 0 R (321) 2128 0 R (3210) 4700 0 R (3214) 4702 0 R (3215) 4703 0 R (3216) 4704 0 R (3218) 4705 0 R (3219) 4706 0 R (322) 2129 0 R (3220) 4707 0 R (3224) 4709 0 R (3226) 4710 0 R (3227) 4711 0 R (3228) 4712 0 R (3229) 4713 0 R (323) 2130 0 R (3230) 4714 0 R (3231) 4715 0 R (3232) 4716 0 R (3233) 4717 0 R (3234) 4718 0 R (3235) 4719 0 R (3236) 4724 0 R (3237) 4725 0 R (3238) 4726 0 R (3239) 4727 0 R (324) 2131 0 R (3240) 4728 0 R (3241) 4729 0 R (3242) 4730 0 R (3245) 4735 0 R (3248) 4736 0 R (3249) 4737 0 R (325) 2132 0 R (3250) 4738 0 R (3251) 4739 0 R (3254) 4742 0 R (3255) 4743 0 R (3256) 4744 0 R (3257) 4745 0 R (3258) 4746 0 R (326) 2133 0 R (3261) 4747 0 R (3262) 4748 0 R (3263) 4749 0 R (3264) 4750 0 R (3265) 4751 0 R (3269) 4752 0 R (327) 2134 0 R (3270) 4753 0 R (3271) 4754 0 R (3272) 4755 0 R (3273) 4756 0 R (3274) 4757 0 R (3275) 4763 0 R (3278) 4764 0 R (3279) 4765 0 R (328) 2135 0 R (3280) 4766 0 R (3281) 4767 0 R (3282) 4768 0 R (3283) 4769 0 R (3284) 4770 0 R (3285) 4771 0 R (3288) 4772 0 R (3289) 4773 0 R (329) 2136 0 R (3290) 4774 0 R (3291) 4775 0 R (3292) 4776 0 R (3293) 4777 0 R (3294) 4778 0 R (3295) 4779 0 R (3296) 4780 0 R (3297) 4781 0 R (33) 1912 0 R (330) 2137 0 R (3300) 4786 0 R (3301) 4787 0 R (3302) 4788 0 R (3303) 4789 0 R (3304) 4790 0 R (3305) 4791 0 R (3308) 4792 0 R (3309) 4793 0 R (331) 2138 0 R (3310) 4794 0 R (3311) 4795 0 R (3312) 4796 0 R (3313) 4801 0 R (3316) 4802 0 R (3317) 4803 0 R (3318) 4804 0 R (3319) 4805 0 R (3320) 4806 0 R (3323) 4807 0 R (3324) 4808 0 R (3325) 4809 0 R (3326) 4810 0 R (3327) 4811 0 R (3328) 4812 0 R (3329) 4813 0 R (333) 2140 0 R (3332) 4814 0 R (3333) 4815 0 R (3334) 4816 0 R (3335) 4817 0 R (3336) 4818 0 R (334) 2141 0 R (3340) 4823 0 R (3341) 4824 0 R (3342) 4825 0 R (3343) 4826 0 R (3347) 4828 0 R (3348) 4829 0 R (3349) 4830 0 R (3350) 4831 0 R (3351) 4832 0 R (3354) 4837 0 R (3355) 4838 0 R (3358) 4839 0 R (3359) 4840 0 R (336) 2143 0 R (3360) 4841 0 R (3361) 4842 0 R (3362) 4843 0 R (3363) 4844 0 R (3364) 4845 0 R (3365) 4846 0 R (3366) 4847 0 R (3367) 4848 0 R (3368) 4849 0 R (3369) 4850 0 R (337) 2144 0 R (3370) 4851 0 R (3371) 4852 0 R (3372) 4853 0 R (3373) 4854 0 R (3374) 4855 0 R (3375) 4856 0 R (3376) 4857 0 R (3377) 4858 0 R (3378) 4859 0 R (3379) 4860 0 R (3380) 4861 0 R (3381) 4862 0 R (3382) 4863 0 R (3383) 4864 0 R (3384) 4865 0 R (3385) 4866 0 R (3386) 4867 0 R (3389) 4868 0 R (339) 2146 0 R (3390) 4869 0 R (3391) 4870 0 R (3392) 4871 0 R (3393) 4872 0 R (3394) 4873 0 R (3395) 4874 0 R (3396) 4875 0 R (3397) 4876 0 R (340) 2147 0 R (3402) 4881 0 R (3403) 4882 0 R (3404) 4883 0 R (3405) 4884 0 R (3406) 4885 0 R (3407) 4886 0 R (3408) 4887 0 R (3409) 4888 0 R (3410) 4889 0 R (3411) 4890 0 R (3412) 4891 0 R (3413) 4892 0 R (3414) 4893 0 R (3415) 4894 0 R (3416) 4895 0 R (3417) 4896 0 R (342) 2149 0 R (3420) 4897 0 R (3421) 4898 0 R (3422) 4899 0 R (3423) 4900 0 R (3424) 4901 0 R (3425) 4902 0 R (3426) 4903 0 R (3427) 4911 0 R (3428) 4904 0 R (343) 2150 0 R (3430) 4912 0 R (3431) 4913 0 R (3432) 4914 0 R (3433) 4915 0 R (3434) 4916 0 R (3435) 4917 0 R (3436) 4918 0 R (3437) 4919 0 R (3438) 4920 0 R (3439) 4921 0 R (3440) 4922 0 R (3441) 4923 0 R (3442) 4924 0 R (3443) 4925 0 R (3444) 4926 0 R (3445) 4927 0 R (3446) 4928 0 R (3447) 4929 0 R (3448) 4930 0 R (3449) 4931 0 R (345) 2152 0 R (3450) 4932 0 R (3451) 4933 0 R (3452) 4934 0 R (3453) 4935 0 R (3454) 4936 0 R (3455) 4942 0 R (3456) 4910 0 R (3458) 4943 0 R (3459) 4944 0 R (346) 2153 0 R (3460) 4945 0 R (3461) 4946 0 R (3462) 4947 0 R (3463) 4948 0 R (3464) 4949 0 R (3465) 4950 0 R (3466) 4951 0 R (3467) 4952 0 R (3468) 4953 0 R (3469) 4954 0 R (3470) 4955 0 R (3471) 4956 0 R (3472) 4957 0 R (3473) 4958 0 R (3474) 4959 0 R (3475) 4960 0 R (3476) 4961 0 R (3477) 4962 0 R (3478) 4963 0 R (3479) 4964 0 R (348) 2155 0 R (3480) 4965 0 R (3481) 4970 0 R (3482) 4941 0 R (3484) 4971 0 R (3485) 4972 0 R (3486) 4973 0 R (3487) 4974 0 R (3488) 4975 0 R (3489) 4976 0 R (349) 2156 0 R (3490) 4977 0 R (3493) 4978 0 R (3494) 4979 0 R (3495) 4980 0 R (3496) 4981 0 R (3497) 4982 0 R (3498) 4983 0 R (3499) 4984 0 R (3500) 4985 0 R (3501) 4986 0 R (3502) 4987 0 R (3503) 4988 0 R (3504) 4989 0 R (3505) 4990 0 R (3506) 4991 0 R (3507) 4992 0 R (3508) 4993 0 R (3509) 4994 0 R (3510) 4995 0 R (3511) 4996 0 R (3512) 5001 0 R (3513) 5002 0 R (3514) 5003 0 R (3515) 5004 0 R (3516) 5005 0 R (3517) 5006 0 R (3518) 5007 0 R (3519) 5008 0 R (352) 2157 0 R (3520) 5009 0 R (3521) 5010 0 R (3524) 5015 0 R (3525) 5016 0 R (3526) 5017 0 R (3529) 5018 0 R (353) 2161 0 R (3530) 5019 0 R (3531) 5020 0 R (3534) 5021 0 R (3535) 5022 0 R (3536) 5023 0 R (3537) 5024 0 R (3538) 5025 0 R (3539) 5026 0 R (3540) 5031 0 R (3541) 5032 0 R (3544) 5033 0 R (3545) 5034 0 R (3548) 5035 0 R (3549) 5036 0 R (3550) 5037 0 R (3551) 5044 0 R (3554) 5045 0 R (3555) 5046 0 R (3556) 5047 0 R (3557) 5048 0 R (3558) 5049 0 R (3559) 5050 0 R (356) 2162 0 R (3560) 5051 0 R (3561) 5052 0 R (3562) 5053 0 R (3563) 5054 0 R (3564) 5055 0 R (3565) 5056 0 R (3566) 5057 0 R (3567) 5058 0 R (3568) 5059 0 R (3569) 5060 0 R (3570) 5061 0 R (3571) 5062 0 R (3572) 5063 0 R (3573) 5064 0 R (3574) 5065 0 R (3575) 5066 0 R (3576) 5067 0 R (3577) 5068 0 R (3578) 5069 0 R (3579) 5070 0 R (3580) 5071 0 R (3581) 5072 0 R (3582) 5073 0 R (3583) 5074 0 R (3584) 5075 0 R (3585) 5043 0 R (3586) 5080 0 R (3587) 5081 0 R (359) 2163 0 R (3590) 5082 0 R (3591) 5083 0 R (3592) 5084 0 R (3595) 5085 0 R (3596) 5086 0 R (3599) 5087 0 R (36) 1913 0 R (360) 2164 0 R (3600) 5092 0 R (3603) 5093 0 R (3606) 5094 0 R (3609) 5095 0 R (361) 2165 0 R (3610) 5096 0 R (3611) 5097 0 R (3614) 5098 0 R (3615) 5099 0 R (3616) 5100 0 R (3617) 5105 0 R (3618) 5106 0 R (362) 2166 0 R (3620) 5111 0 R (3624) 5112 0 R (3625) 5113 0 R (3626) 5114 0 R (3627) 5115 0 R (363) 2167 0 R (3632) 5118 0 R (3633) 5119 0 R (3634) 5120 0 R (3635) 5121 0 R (3636) 5122 0 R (3637) 5123 0 R (3639) 5124 0 R (364) 2168 0 R (3640) 5125 0 R (3641) 5126 0 R (3642) 5127 0 R (3643) 5128 0 R (3645) 5129 0 R (3646) 5130 0 R (3647) 5131 0 R (3648) 5132 0 R (3649) 5133 0 R (365) 2169 0 R (3650) 5134 0 R (3651) 5135 0 R (3652) 5136 0 R (3653) 5137 0 R (3655) 5138 0 R (3656) 5139 0 R (3657) 5140 0 R (3658) 5141 0 R (3659) 5142 0 R (366) 2170 0 R (3660) 5143 0 R (3661) 5144 0 R (3662) 5145 0 R (3663) 5146 0 R (3664) 5147 0 R (3665) 5148 0 R (3667) 5149 0 R (3668) 5150 0 R (3669) 5151 0 R (367) 2171 0 R (3670) 5152 0 R (3671) 5153 0 R (3672) 5154 0 R (3677) 5161 0 R (3678) 5162 0 R (3679) 5163 0 R (3680) 5164 0 R (3681) 5165 0 R (3682) 5166 0 R (3684) 5167 0 R (3685) 5168 0 R (3686) 5169 0 R (3689) 5170 0 R (3690) 5171 0 R (3696) 5173 0 R (3697) 5174 0 R (3698) 5175 0 R (3699) 5176 0 R (37) 1914 0 R (370) 2172 0 R (3702) 5178 0 R (3703) 5179 0 R (3707) 5180 0 R (3708) 5181 0 R (3709) 5182 0 R (3710) 5183 0 R (3711) 5184 0 R (3714) 5185 0 R (3715) 5186 0 R (3716) 5187 0 R (3717) 5188 0 R (3718) 5195 0 R (3719) 5196 0 R (3720) 5197 0 R (3725) 5199 0 R (3726) 5200 0 R (3727) 5201 0 R (3728) 5202 0 R (373) 2173 0 R (3731) 5203 0 R (3732) 5204 0 R (3733) 5205 0 R (3739) 5209 0 R (3740) 5210 0 R (3741) 5211 0 R (3742) 5212 0 R (3743) 5213 0 R (3748) 5216 0 R (3749) 5217 0 R (3755) 5222 0 R (3756) 5223 0 R (3757) 5224 0 R (3758) 5225 0 R (3759) 5226 0 R (376) 2174 0 R (3760) 5227 0 R (3761) 5228 0 R (3764) 5230 0 R (3765) 5231 0 R (3767) 5233 0 R (3768) 5234 0 R (3770) 5235 0 R (3771) 5236 0 R (3772) 5237 0 R (3773) 5238 0 R (3775) 5239 0 R (3776) 5240 0 R (3777) 5241 0 R (3778) 5242 0 R (3779) 5243 0 R (3781) 5244 0 R (3782) 5245 0 R (3783) 5246 0 R (3784) 5247 0 R (379) 2175 0 R (3791) 5250 0 R (3792) 5251 0 R (3793) 5252 0 R (3796) 5253 0 R (3797) 5254 0 R (3799) 5260 0 R (38) 1915 0 R (380) 2176 0 R (3800) 5261 0 R (3801) 5262 0 R (3802) 5263 0 R (3806) 5265 0 R (3807) 5266 0 R (3808) 5267 0 R (3809) 5268 0 R (3810) 5269 0 R (3811) 5270 0 R (3812) 5271 0 R (3813) 5272 0 R (3819) 5274 0 R (3820) 5275 0 R (3824) 5277 0 R (3825) 5278 0 R (3826) 5279 0 R (383) 2181 0 R (3831) 5281 0 R (3832) 5282 0 R (3833) 5283 0 R (3835) 5288 0 R (3836) 5289 0 R (3837) 5290 0 R (3838) 5291 0 R (3839) 5292 0 R (3840) 5293 0 R (3841) 5294 0 R (3842) 5295 0 R (3843) 5296 0 R (3844) 5297 0 R (3845) 5298 0 R (3846) 5299 0 R (3847) 5300 0 R (3848) 5301 0 R (3853) 5304 0 R (3854) 5305 0 R (3855) 5306 0 R (3859) 5308 0 R (386) 2182 0 R (3860) 5309 0 R (3865) 5312 0 R (3866) 5313 0 R (3867) 5314 0 R (3868) 5317 0 R (3869) 5315 0 R (387) 2183 0 R (3870) 5316 0 R (388) 2184 0 R (389) 2185 0 R (39) 1916 0 R (390) 2186 0 R (392) 2188 0 R (393) 2189 0 R (394) 2190 0 R (395) 2191 0 R (398) 2192 0 R (399) 2193 0 R (4.0) 14 0 R (40) 1917 0 R (403) 2195 0 R (404) 2196 0 R (405) 2197 0 R (406) 2198 0 R (407) 2199 0 R (408) 2204 0 R (409) 2205 0 R (41) 1918 0 R (410) 2206 0 R (411) 2207 0 R (412) 2208 0 R (413) 2209 0 R (414) 2210 0 R (415) 2211 0 R (416) 2212 0 R (417) 2213 0 R (418) 2214 0 R (419) 2215 0 R (42) 1919 0 R (420) 2216 0 R (423) 2217 0 R (428) 2220 0 R (429) 2221 0 R (43) 1920 0 R (432) 2222 0 R (433) 2223 0 R (437) 2226 0 R (438) 2227 0 R (439) 2228 0 R (44) 1921 0 R (440) 2229 0 R (441) 2230 0 R (442) 2231 0 R (443) 2236 0 R (444) 2237 0 R (446) 2238 0 R (447) 2239 0 R (448) 2240 0 R (449) 2241 0 R (45) 1922 0 R (450) 2242 0 R (451) 2243 0 R (454) 2245 0 R (455) 2246 0 R (456) 2247 0 R (457) 2250 0 R (459) 2252 0 R (46) 1923 0 R (460) 2253 0 R (461) 2254 0 R (462) 2255 0 R (463) 2256 0 R (464) 2257 0 R (465) 2258 0 R (466) 2259 0 R (467) 2260 0 R (468) 2261 0 R (469) 2262 0 R (47) 1924 0 R (470) 2263 0 R (471) 2264 0 R (473) 2265 0 R (474) 2266 0 R (475) 2267 0 R (476) 2268 0 R (477) 2269 0 R (478) 2270 0 R (479) 2271 0 R (48) 1925 0 R (480) 2272 0 R (481) 2273 0 R (482) 2279 0 R (483) 2280 0 R (484) 2281 0 R (487) 2282 0 R (488) 2283 0 R (489) 2284 0 R (49) 1926 0 R (491) 2285 0 R (492) 2286 0 R (493) 2287 0 R (494) 2288 0 R (496) 2290 0 R (497) 2291 0 R (498) 2292 0 R (499) 2293 0 R (5.0) 18 0 R (5.1.1) 22 0 R (5.2.1) 26 0 R (5.3.1) 30 0 R (5.4.1) 34 0 R (5.5.1) 38 0 R (50) 1927 0 R (500) 2294 0 R (501) 2295 0 R (502) 2296 0 R (503) 2297 0 R (504) 2298 0 R (505) 2299 0 R (507) 2300 0 R (508) 2301 0 R (509) 2302 0 R (51) 1928 0 R (510) 2303 0 R (511) 2304 0 R (512) 2305 0 R (513) 2306 0 R (514) 2307 0 R (515) 2308 0 R (516) 2309 0 R (517) 2310 0 R (518) 2311 0 R (519) 2312 0 R (52) 1929 0 R (520) 2313 0 R (521) 2314 0 R (522) 2315 0 R (523) 2316 0 R (524) 2321 0 R (525) 2322 0 R (526) 2323 0 R (527) 2324 0 R (528) 1309 0 R (53) 1930 0 R (530) 2325 0 R (531) 2326 0 R (532) 2327 0 R (533) 2328 0 R (534) 2329 0 R (535) 2330 0 R (538) 2331 0 R (539) 2332 0 R (54) 1931 0 R (541) 2334 0 R (545) 2335 0 R (546) 2336 0 R (547) 2337 0 R (549) 2338 0 R (55) 1932 0 R (550) 2339 0 R (551) 2340 0 R (553) 2341 0 R (554) 2342 0 R (555) 2343 0 R (556) 2344 0 R (557) 2345 0 R (558) 2346 0 R (559) 2347 0 R (56) 1936 0 R (560) 2348 0 R (561) 2349 0 R (562) 2354 0 R (564) 2355 0 R (565) 2356 0 R (566) 2357 0 R (567) 2358 0 R (568) 2359 0 R (569) 2360 0 R (57) 1937 0 R (570) 2361 0 R (572) 2362 0 R (573) 2363 0 R (574) 2364 0 R (575) 2365 0 R (579) 2366 0 R (58) 1938 0 R (580) 2367 0 R (581) 2368 0 R (582) 2369 0 R (583) 2370 0 R (584) 2371 0 R (585) 2372 0 R (586) 2373 0 R (587) 2374 0 R (588) 2375 0 R (589) 2376 0 R (59) 1939 0 R (590) 2377 0 R (591) 2378 0 R (592) 2379 0 R (593) 2380 0 R (594) 2381 0 R (595) 2382 0 R (596) 2383 0 R (597) 2384 0 R (598) 2385 0 R (599) 2386 0 R (6.0) 42 0 R (6.10.1) 218 0 R (6.10.19.16.3) 226 0 R (6.10.19.17.3) 230 0 R (6.10.19.18.3) 234 0 R (6.10.19.19.3) 238 0 R (6.10.19.2) 222 0 R (6.10.19.20.3) 242 0 R (6.10.20.2) 246 0 R (6.10.20.21.3) 250 0 R (6.10.20.22.3) 254 0 R (6.10.21.2) 258 0 R (6.11.1) 262 0 R (6.11.22.2) 266 0 R (6.11.23.2) 270 0 R (6.11.23.23.3) 274 0 R (6.11.23.23.7.4) 278 0 R (6.11.23.23.8.4) 282 0 R (6.11.23.23.9.4) 286 0 R (6.11.24.2) 290 0 R (6.11.25.2) 294 0 R (6.11.25.24.3) 298 0 R (6.11.25.25.3) 302 0 R (6.11.26.2) 306 0 R (6.11.26.26.3) 310 0 R (6.11.27.2) 314 0 R (6.6.1) 46 0 R (6.6.1.2) 50 0 R (6.6.2.1.3) 58 0 R (6.6.2.2) 54 0 R (6.6.2.2.3) 62 0 R (6.6.3.2) 66 0 R (6.6.4.2) 70 0 R (6.6.5.10.3) 106 0 R (6.6.5.2) 74 0 R (6.6.5.3.3) 78 0 R (6.6.5.4.3) 82 0 R (6.6.5.5.3) 86 0 R (6.6.5.6.3) 90 0 R (6.6.5.7.3) 94 0 R (6.6.5.8.3) 98 0 R (6.6.5.9.3) 102 0 R (6.6.6.2) 110 0 R (6.7.1) 114 0 R (6.7.10.14.3) 170 0 R (6.7.10.15.3) 174 0 R (6.7.10.2) 166 0 R (6.7.11.2) 178 0 R (6.7.7.2) 118 0 R (6.7.8.11.3) 126 0 R (6.7.8.12.1.4) 134 0 R (6.7.8.12.2.4) 138 0 R (6.7.8.12.3) 130 0 R (6.7.8.12.3.4) 142 0 R (6.7.8.12.4.4) 146 0 R (6.7.8.13.3) 150 0 R (6.7.8.13.5.4) 154 0 R (6.7.8.13.6.4) 158 0 R (6.7.8.2) 122 0 R (6.7.9.2) 162 0 R (6.8.1) 182 0 R (6.8.12.2) 186 0 R (6.8.13.2) 190 0 R (6.8.14.2) 194 0 R (6.8.15.2) 198 0 R (6.8.16.2) 202 0 R (6.8.17.2) 206 0 R (6.8.18.2) 210 0 R (6.9.1) 214 0 R (600) 2387 0 R (601) 2388 0 R (602) 2393 0 R (603) 2394 0 R (604) 2395 0 R (605) 2396 0 R (609) 2398 0 R (610) 2399 0 R (612) 2401 0 R (613) 2402 0 R (614) 2403 0 R (615) 2404 0 R (617) 2406 0 R (618) 2407 0 R (619) 2408 0 R (62) 1940 0 R (620) 2409 0 R (621) 2410 0 R (622) 2411 0 R (623) 2412 0 R (624) 2413 0 R (628) 2415 0 R (629) 1315 0 R (63) 1941 0 R (631) 2416 0 R (632) 2417 0 R (633) 2418 0 R (634) 2419 0 R (635) 2422 0 R (636) 2423 0 R (637) 2424 0 R (638) 2425 0 R (639) 2426 0 R (640) 2431 0 R (641) 2432 0 R (642) 2433 0 R (643) 2434 0 R (644) 2435 0 R (645) 2436 0 R (646) 2437 0 R (647) 2438 0 R (648) 1316 0 R (65) 1942 0 R (650) 2439 0 R (651) 2440 0 R (652) 2441 0 R (653) 2442 0 R (654) 2443 0 R (655) 2444 0 R (656) 2445 0 R (657) 2446 0 R (658) 2447 0 R (659) 2448 0 R (66) 1943 0 R (660) 2449 0 R (661) 2450 0 R (662) 2451 0 R (663) 2452 0 R (666) 2453 0 R (667) 2454 0 R (668) 2455 0 R (669) 2456 0 R (67) 1944 0 R (670) 2457 0 R (671) 2458 0 R (674) 2464 0 R (676) 2466 0 R (677) 2467 0 R (678) 2468 0 R (679) 2469 0 R (68) 1945 0 R (680) 2470 0 R (681) 2471 0 R (682) 2472 0 R (685) 2473 0 R (686) 2474 0 R (687) 2475 0 R (688) 2476 0 R (689) 2477 0 R (690) 2478 0 R (691) 2479 0 R (692) 2480 0 R (693) 2481 0 R (694) 2482 0 R (695) 2483 0 R (698) 2484 0 R (699) 2485 0 R (7.0) 318 0 R (7.12.1) 322 0 R (7.13.1) 326 0 R (7.13.28.2) 330 0 R (7.13.29.2) 334 0 R (7.13.29.27.3) 338 0 R (7.13.29.28.10.4) 346 0 R (7.13.29.28.11.4) 350 0 R (7.13.29.28.3) 342 0 R (7.13.29.29.3) 354 0 R (7.13.29.30.3) 358 0 R (7.13.29.31.3) 362 0 R (7.14.1) 366 0 R (7.15.1) 370 0 R (7.16.1) 374 0 R (7.17.1) 378 0 R (7.18.1) 382 0 R (7.19.1) 386 0 R (7.19.30.2) 390 0 R (7.19.31.2) 394 0 R (7.19.31.32.3) 398 0 R (7.19.32.2) 402 0 R (7.19.33.2) 406 0 R (7.19.33.33.3) 410 0 R (7.19.33.34.3) 414 0 R (7.19.34.2) 418 0 R (7.19.34.35.12.4) 426 0 R (7.19.34.35.13.4) 430 0 R (7.19.34.35.14.4) 434 0 R (7.19.34.35.15.4) 438 0 R (7.19.34.35.16.4) 442 0 R (7.19.34.35.17.4) 446 0 R (7.19.34.35.18.4) 450 0 R (7.19.34.35.19.4) 454 0 R (7.19.34.35.20.4) 458 0 R (7.19.34.35.21.4) 462 0 R (7.19.34.35.22.4) 466 0 R (7.19.34.35.3) 422 0 R (7.19.34.36.3) 470 0 R (7.19.34.37.3) 474 0 R (7.20.1) 478 0 R (7.20.35.2) 482 0 R (7.20.36.2) 486 0 R (7.21.1) 490 0 R (7.22.1) 494 0 R (7.23.1) 498 0 R (7.23.37.2) 502 0 R (7.23.38.2) 506 0 R (7.23.39.2) 510 0 R (7.23.40.2) 514 0 R (7.23.40.38.3) 518 0 R (7.23.40.39.3) 522 0 R (7.23.40.40.3) 526 0 R (7.24.1) 530 0 R (7.24.41.2) 534 0 R (7.24.42.2) 538 0 R (7.24.42.41.3) 542 0 R (7.24.42.42.3) 546 0 R (7.24.42.43.3) 550 0 R (7.24.43.2) 554 0 R (70) 1946 0 R (700) 2486 0 R (701) 2493 0 R (702) 2494 0 R (705) 2496 0 R (706) 2463 0 R (707) 2497 0 R (71) 1947 0 R (710) 2499 0 R (711) 2500 0 R (712) 2501 0 R (713) 2502 0 R (714) 2503 0 R (715) 2504 0 R (716) 2505 0 R (719) 2507 0 R (72) 1948 0 R (720) 2508 0 R (721) 2509 0 R (722) 2510 0 R (723) 2511 0 R (726) 2513 0 R (727) 2514 0 R (728) 2515 0 R (729) 2516 0 R (73) 1949 0 R (732) 2518 0 R (733) 2519 0 R (734) 2520 0 R (735) 2521 0 R (738) 2523 0 R (739) 2524 0 R (740) 2525 0 R (741) 2526 0 R (744) 2533 0 R (745) 2534 0 R (746) 2492 0 R (75) 1950 0 R (750) 2535 0 R (751) 2536 0 R (752) 2537 0 R (753) 2538 0 R (754) 2539 0 R (755) 2540 0 R (756) 2541 0 R (757) 2542 0 R (758) 2543 0 R (759) 2544 0 R (76) 1951 0 R (760) 2545 0 R (761) 2546 0 R (762) 1322 0 R (764) 2547 0 R (765) 2548 0 R (766) 2549 0 R (767) 2550 0 R (768) 2551 0 R (769) 2552 0 R (77) 1952 0 R (770) 2553 0 R (771) 2554 0 R (772) 2555 0 R (773) 2556 0 R (774) 2557 0 R (775) 2558 0 R (776) 2559 0 R (777) 2560 0 R (778) 2565 0 R (78) 1953 0 R (781) 2566 0 R (782) 2567 0 R (783) 2568 0 R (786) 2569 0 R (789) 2570 0 R (790) 2571 0 R (791) 2572 0 R (794) 2573 0 R (797) 2576 0 R (798) 2577 0 R (799) 2578 0 R (8.0) 558 0 R (8.25.1) 562 0 R (8.25.44.2) 566 0 R (8.25.45.2) 570 0 R (8.25.46.2) 574 0 R (8.26.1) 578 0 R (8.26.47.2) 582 0 R (8.26.48.2) 586 0 R (8.26.49.2) 590 0 R (8.27.1) 594 0 R (8.27.50.2) 598 0 R (8.27.51.2) 602 0 R (8.28.1) 606 0 R (8.28.52.2) 610 0 R (80) 1954 0 R (800) 2579 0 R (801) 2580 0 R (802) 2581 0 R (803) 2582 0 R (804) 2583 0 R (805) 2584 0 R (806) 2585 0 R (809) 2591 0 R (81) 1955 0 R (812) 2592 0 R (815) 2595 0 R (816) 2596 0 R (817) 2597 0 R (818) 2598 0 R (82) 1956 0 R (821) 2599 0 R (825) 2600 0 R (828) 2601 0 R (829) 2602 0 R (83) 1957 0 R (830) 2603 0 R (834) 2605 0 R (835) 2606 0 R (836) 2607 0 R (837) 2608 0 R (838) 2609 0 R (839) 2614 0 R (841) 2616 0 R (842) 2617 0 R (843) 2618 0 R (844) 2619 0 R (845) 2620 0 R (846) 2621 0 R (847) 2622 0 R (848) 2623 0 R (849) 2624 0 R (85) 1958 0 R (850) 2625 0 R (851) 2626 0 R (852) 2627 0 R (856) 2630 0 R (857) 2631 0 R (859) 2632 0 R (86) 1959 0 R (861) 2633 0 R (864) 2634 0 R (865) 2635 0 R (866) 2636 0 R (867) 2637 0 R (868) 2638 0 R (869) 2639 0 R (87) 1960 0 R (870) 2640 0 R (871) 2641 0 R (872) 2642 0 R (873) 2643 0 R (874) 2644 0 R (875) 2645 0 R (877) 2646 0 R (878) 2647 0 R (879) 2648 0 R (88) 1961 0 R (880) 2649 0 R (884) 1433 0 R (886) 2655 0 R (888) 1434 0 R (890) 2657 0 R (891) 2658 0 R (892) 2659 0 R (893) 2660 0 R (894) 2661 0 R (895) 2662 0 R (896) 1435 0 R (898) 2663 0 R (9.0) 614 0 R (9.29.1) 618 0 R (9.30.1) 622 0 R (9.31.1) 626 0 R (9.32.1) 630 0 R (9.33.1) 634 0 R (9.33.53.2) 638 0 R (9.33.53.44.3) 642 0 R (9.33.53.45.3) 646 0 R (9.33.53.46.3) 650 0 R (9.33.54.2) 654 0 R (9.33.55.2) 658 0 R (9.33.56.2) 662 0 R (9.34.1) 666 0 R (9.34.57.2) 670 0 R (9.34.58.2) 674 0 R (9.35.1) 678 0 R (9.35.59.2) 682 0 R (9.35.59.47.3) 686 0 R (9.35.59.48.3) 690 0 R (9.35.59.49.3) 694 0 R (9.35.59.50.3) 698 0 R (9.35.59.51.3) 702 0 R (9.35.59.52.3) 706 0 R (9.35.59.53.3) 710 0 R (9.36.1) 714 0 R (9.36.60.2) 718 0 R (9.36.61.2) 722 0 R (9.36.62.2) 726 0 R (9.37.1) 730 0 R (9.38.1) 734 0 R (9.38.63.2) 738 0 R (9.38.64.2) 742 0 R (9.38.65.2) 746 0 R (9.38.66.2) 750 0 R (9.39.1) 754 0 R (9.39.67.2) 758 0 R (9.39.68.2) 762 0 R (9.39.68.54.3) 766 0 R (9.39.68.55.3) 770 0 R (9.40.1) 774 0 R (9.41.1) 778 0 R (9.41.69.2) 782 0 R (9.41.70.2) 786 0 R (9.41.71.2) 790 0 R (9.41.72.2) 794 0 R (90) 1962 0 R (900) 2664 0 R (901) 2665 0 R (902) 2666 0 R (904) 2672 0 R (905) 2673 0 R (906) 2674 0 R (907) 2675 0 R (909) 2676 0 R (91) 1963 0 R (910) 2677 0 R (911) 2678 0 R (912) 2679 0 R (913) 2680 0 R (914) 2681 0 R (915) 2682 0 R (916) 2683 0 R (917) 2684 0 R (918) 2685 0 R (919) 2686 0 R (92) 1964 0 R (920) 2687 0 R (921) 2688 0 R (922) 2689 0 R (923) 1436 0 R (925) 2690 0 R (926) 2691 0 R (927) 2692 0 R (928) 2693 0 R (929) 2694 0 R (93) 1965 0 R (930) 2695 0 R (931) 2696 0 R (932) 2697 0 R (933) 2698 0 R (934) 2703 0 R (935) 2704 0 R (936) 2705 0 R (937) 2706 0 R (938) 2707 0 R (941) 2708 0 R (942) 1438 0 R (944) 2709 0 R (945) 2710 0 R (946) 2711 0 R (947) 2712 0 R (948) 2713 0 R (949) 2714 0 R (95) 1966 0 R (950) 2715 0 R (951) 2716 0 R (952) 2717 0 R (953) 2718 0 R (954) 2719 0 R (955) 1439 0 R (957) 2720 0 R (958) 2721 0 R (959) 2722 0 R (96) 1967 0 R (960) 2727 0 R (961) 2728 0 R (962) 2729 0 R (963) 2730 0 R (964) 2731 0 R (965) 2732 0 R (966) 2733 0 R (967) 2734 0 R (968) 2735 0 R (969) 2736 0 R (97) 1968 0 R (970) 2737 0 R (971) 2738 0 R (972) 2739 0 R (973) 2740 0 R (974) 2741 0 R (975) 2742 0 R (976) 2743 0 R (977) 2744 0 R (978) 2745 0 R (979) 2746 0 R (98) 1969 0 R (980) 2747 0 R (981) 2748 0 R (982) 2749 0 R (983) 2750 0 R (984) 2751 0 R (985) 2756 0 R (986) 2757 0 R (987) 2758 0 R (988) 1440 0 R (99) 1970 0 R (990) 2759 0 R (991) 1441 0 R (993) 2760 0 R (994) 2761 0 R (995) 2762 0 R (996) 2763 0 R (997) 2764 0 R (998) 2765 0 R (999) 2766 0 R (Doc-Start) 1170 0 R (about) 1279 0 R (accountpreferences) 1733 0 R (administration) 1443 0 R (apache-addtype) 1321 0 R (attachments) 1718 0 R (bonsai) 1842 0 R (boolean) 1610 0 R (bug_page) 1607 0 R (bugreports) 1715 0 R (bzldap) 1320 0 R (charts) 1739 0 R (classifications) 1453 0 R (cloningbugs) 1717 0 R (cmdline) 1860 0 R (cmdline-bugmail) 1861 0 R (commenting) 1729 0 R (components) 1455 0 R (configuration) 1303 0 R (conventions) 1284 0 R (copyright) 1280 0 R (createnewusers) 1449 0 R (credits) 1283 0 R (cust-change-permissions) 1757 0 R (cust-group-check) 1758 0 R (cust-hooks) 1756 0 R (cust-templates) 1749 0 R (customization) 1748 0 R (cvs) 1843 0 R (database-engine) 1305 0 R (database-schema) 1306 0 R (dbmodify) 1759 0 R (defaultuser) 1446 0 R (dependencytree) 1730 0 R (disclaimer) 1281 0 R (edit-values) 1570 0 R (edit-values-delete) 1572 0 R (edit-values-list) 1571 0 R (emailpreferences) 1735 0 R (extraconfig) 1314 0 R (faq) 1847 0 R (faq-admin) 4441 0 R (faq-admin-cvsupdate) 4451 0 R (faq-admin-enable-unconfirmed) 4472 0 R (faq-admin-livebackup) 4449 0 R (faq-admin-midair) 4443 0 R (faq-admin-moving) 4484 0 R (faq-db) 4581 0 R (faq-db-corrupted) 4583 0 R (faq-db-manualedit) 4595 0 R (faq-db-permissions) 4602 0 R (faq-db-synchronize) 4608 0 R (faq-email) 4516 0 R (faq-email-mailif) 4557 0 R (faq-email-nomail) 4518 0 R (faq-email-nonreceived) 4572 0 R (faq-email-sendmailnow) 4559 0 R (faq-email-testing) 4521 0 R (faq-email-whine) 4551 0 R (faq-general) 4304 0 R (faq-general-bonsaitools) 4347 0 R (faq-general-bzmissing) 4325 0 R (faq-general-companies) 4313 0 R (faq-general-compare) 4321 0 R (faq-general-cookie) 4376 0 R (faq-general-license) 4306 0 R (faq-general-maintainers) 4318 0 R (faq-general-mysql) 4338 0 R (faq-general-perlpath) 4352 0 R (faq-general-support) 4309 0 R (faq-hacking) 4689 0 R (faq-hacking-bugzillabugs) 4695 0 R (faq-hacking-patches) 4708 0 R (faq-hacking-priority) 4701 0 R (faq-hacking-templatestyle) 4690 0 R (faq-mod-perl) 4378 0 R (faq-nt) 4613 0 R (faq-nt-bundle) 4623 0 R (faq-nt-dbi) 4633 0 R (faq-nt-easiest) 4615 0 R (faq-nt-mappings) 4625 0 R (faq-phb) 4382 0 R (faq-phb-backup) 4427 0 R (faq-phb-client) 4384 0 R (faq-phb-cost) 4436 0 R (faq-phb-data) 4407 0 R (faq-phb-email) 4400 0 R (faq-phb-emailapp) 4402 0 R (faq-phb-installtime) 4434 0 R (faq-phb-l10n) 4417 0 R (faq-phb-maintenance) 4430 0 R (faq-phb-priorities) 4386 0 R (faq-phb-renameBugs) 4438 0 R (faq-phb-reporting) 4395 0 R (faq-phb-reports) 4425 0 R (faq-security) 4501 0 R (faq-security-knownproblems) 4514 0 R (faq-security-mysql) 4503 0 R (faq-use) 4649 0 R (faq-use-accept) 4666 0 R (faq-use-attachment) 4671 0 R (faq-use-changeaddress) 4651 0 R (faq-use-close) 4677 0 R (faq-use-keyword) 4674 0 R (faq-use-query) 4653 0 R (fillingbugs) 1716 0 R (flag-askto) 1462 0 R (flag-type-attachment) 1464 0 R (flag-type-bug) 1465 0 R (flag-types) 1463 0 R (flag-values) 1461 0 R (flags) 1742 0 R (flags-about) 1460 0 R (flags-admin) 1466 0 R (flags-create) 1467 0 R (flags-create-field-active) 3172 0 R (flags-create-field-category) 3132 0 R (flags-create-field-cclist) 3190 0 R (flags-create-field-description) 3128 0 R (flags-create-field-multiplicable) 3185 0 R (flags-create-field-name) 3126 0 R (flags-create-field-requestable) 3175 0 R (flags-create-field-sortkey) 3164 0 R (flags-create-field-specific) 3182 0 R (flags-create-grant-group) 3192 0 R (flags-create-request-group) 3197 0 R (flags-delete) 1468 0 R (flags-edit) 1569 0 R (flags-overview) 1458 0 R (flags-simpleexample) 1459 0 R (general-advice) 1849 0 R (generalpreferences) 1734 0 R (gfdl) 1866 0 R (gfdl-0) 1867 0 R (gfdl-1) 1868 0 R (gfdl-10) 1877 0 R (gfdl-2) 1869 0 R (gfdl-3) 1870 0 R (gfdl-4) 1871 0 R (gfdl-5) 1872 0 R (gfdl-6) 1873 0 R (gfdl-7) 1874 0 R (gfdl-8) 1875 0 R (gfdl-9) 1876 0 R (gfdl-howto) 1878 0 R (gloss-a) 5116 0 R (gloss-apache) 5117 0 R (gloss-b) 5156 0 R (gloss-bugzilla) 1998 0 R (gloss-c) 5172 0 R (gloss-cgi) 2060 0 R (gloss-component) 5177 0 R (gloss-contrib) 2527 0 R (gloss-cpan) 2650 0 R (gloss-d) 5198 0 R (gloss-daemon) 3478 0 R (gloss-dos) 3611 0 R (gloss-g) 5207 0 R (gloss-groups) 5208 0 R (gloss-htaccess) 3585 0 R (gloss-j) 5214 0 R (gloss-javascript) 5215 0 R (gloss-m) 5194 0 R (gloss-mta) 4589 0 R (gloss-mysql) 5229 0 R (gloss-p) 5249 0 R (gloss-ppm) 2586 0 R (gloss-product) 3002 0 R (gloss-q) 5264 0 R (gloss-r) 5273 0 R (gloss-rdbms) 5255 0 R (gloss-regexp) 5276 0 R (gloss-s) 5280 0 R (gloss-service) 3479 0 R (gloss-t) 5302 0 R (gloss-target-milestone) 5303 0 R (gloss-tcl) 5307 0 R (gloss-z) 5310 0 R (gloss-zarro) 5311 0 R (glossary) 1879 0 R (groups) 1575 0 R (hintsandtips) 1727 0 R (http) 1310 0 R (http-apache) 1311 0 R (http-iis) 1312 0 R (impersonatingusers) 1452 0 R (index) 1171 0 R (individual-buglists) 1714 0 R (install-MTA) 1302 0 R (install-bzfiles) 1292 0 R (install-config-bugzilla) 1313 0 R (install-database) 1288 0 R (install-modules-chart-base) 1297 0 R (install-modules-dbd-mysql) 1294 0 R (install-modules-gd) 1296 0 R (install-modules-gd-graph) 1298 0 R (install-modules-gd-text-align) 1299 0 R (install-modules-patchreader) 1301 0 R (install-modules-template) 1295 0 R (install-modules-xml-twig) 1300 0 R (install-mysql) 1289 0 R (install-perl) 1287 0 R (install-perlmodules) 1293 0 R (install-perlmodules-manual) 1862 0 R (install-perlmodules-nonroot) 1437 0 R (install-pg) 1290 0 R (install-setupdatabase) 2225 0 R (install-setupdatabase-adduser) 2244 0 R (install-webserver) 1291 0 R (installation) 1286 0 R (installation-whining) 1318 0 R (installation-whining-cron) 1317 0 R (installing-bugzilla) 1285 0 R (integration) 1760 0 R (lifecycle) 1608 0 R (lifecycle-image) 1896 0 R (list) 1615 0 R (localconfig) 1304 0 R (macosx-libraries) 1430 0 R (macosx-sendmail) 1429 0 R (manageusers) 1447 0 R (milestones) 1457 0 R (modifyusers) 1450 0 R (modules-manual-download) 1864 0 R (modules-manual-instructions) 1863 0 R (modules-manual-optional) 1865 0 R (multiplecharts) 1613 0 R (myaccount) 1606 0 R (mysql) 1307 0 R (negation) 1612 0 R (newversions) 1282 0 R (nonroot) 1432 0 R (os-macosx) 1428 0 R (os-mandrake) 1431 0 R (os-specific) 1323 0 R (os-win32) 1422 0 R (page.1) 1169 0 R (page.10) 2203 0 R (page.100) 4836 0 R (page.101) 4880 0 R (page.102) 4909 0 R (page.103) 4940 0 R (page.104) 4969 0 R (page.105) 5000 0 R (page.106) 5014 0 R (page.107) 5030 0 R (page.108) 5042 0 R (page.109) 5079 0 R (page.11) 2235 0 R (page.110) 5091 0 R (page.111) 5104 0 R (page.112) 5110 0 R (page.113) 5160 0 R (page.114) 5193 0 R (page.115) 5221 0 R (page.116) 5259 0 R (page.117) 5287 0 R (page.12) 2278 0 R (page.13) 2320 0 R (page.14) 2353 0 R (page.15) 2392 0 R (page.16) 2430 0 R (page.17) 2462 0 R (page.18) 2491 0 R (page.19) 2531 0 R (page.2) 1178 0 R (page.20) 2564 0 R (page.21) 2590 0 R (page.22) 2613 0 R (page.23) 2654 0 R (page.24) 2671 0 R (page.25) 2702 0 R (page.26) 2726 0 R (page.27) 2755 0 R (page.28) 2775 0 R (page.29) 2787 0 R (page.3) 1184 0 R (page.30) 2822 0 R (page.31) 2847 0 R (page.32) 2873 0 R (page.33) 2901 0 R (page.34) 2953 0 R (page.35) 2976 0 R (page.36) 3006 0 R (page.37) 3037 0 R (page.38) 3080 0 R (page.39) 3118 0 R (page.4) 1327 0 R (page.40) 3168 0 R (page.41) 3201 0 R (page.42) 3231 0 R (page.43) 3258 0 R (page.44) 3297 0 R (page.45) 3327 0 R (page.46) 3346 0 R (page.47) 3362 0 R (page.48) 3394 0 R (page.49) 3424 0 R (page.5) 1472 0 R (page.50) 3453 0 R (page.51) 3483 0 R (page.52) 3512 0 R (page.53) 3589 0 R (page.54) 3615 0 R (page.55) 3643 0 R (page.56) 3708 0 R (page.57) 3719 0 R (page.58) 3754 0 R (page.59) 3776 0 R (page.6) 1619 0 R (page.60) 3806 0 R (page.61) 3828 0 R (page.62) 3843 0 R (page.63) 3857 0 R (page.64) 3877 0 R (page.65) 3917 0 R (page.66) 3950 0 R (page.67) 3966 0 R (page.68) 3983 0 R (page.69) 4004 0 R (page.7) 1764 0 R (page.70) 4021 0 R (page.71) 4029 0 R (page.72) 4059 0 R (page.73) 4085 0 R (page.74) 4124 0 R (page.75) 4153 0 R (page.76) 4184 0 R (page.77) 4222 0 R (page.78) 4246 0 R (page.79) 4262 0 R (page.8) 1883 0 R (page.80) 4292 0 R (page.81) 4301 0 R (page.82) 4332 0 R (page.83) 4361 0 R (page.84) 4392 0 R (page.85) 4421 0 R (page.86) 4447 0 R (page.87) 4481 0 R (page.88) 4507 0 R (page.89) 4540 0 R (page.9) 2180 0 R (page.90) 4593 0 R (page.91) 4621 0 R (page.92) 4658 0 R (page.93) 4688 0 R (page.94) 4723 0 R (page.95) 4734 0 R (page.96) 4762 0 R (page.97) 4785 0 R (page.98) 4800 0 R (page.99) 4822 0 R (param-LDAPBaseDN) 2517 0 R (param-LDAPbinddn) 2512 0 R (param-LDAPmailattribute) 2532 0 R (param-LDAPserver) 2506 0 R (param-LDAPuidattribute) 2522 0 R (param-user_verify_class) 2498 0 R (parameters) 1444 0 R (paranoid-security) 1853 0 R (patch-viewer) 1319 0 R (patches) 1859 0 R (patchviewer) 1719 0 R (patchviewer_bonsai_lxr) 1725 0 R (patchviewer_collapse) 1723 0 R (patchviewer_context) 1722 0 R (patchviewer_diff) 1721 0 R (patchviewer_link) 1724 0 R (patchviewer_unified_diff) 1726 0 R (patchviewer_view) 1720 0 R (permissionsettings) 1736 0 R (postgresql) 1308 0 R (products) 1454 0 R (pronouns) 1611 0 R (query) 1609 0 R (quicksearch) 1614 0 R (quips) 1574 0 R (reporting) 1737 0 R (reports) 1738 0 R (scm) 1844 0 R (security) 1590 0 R (security-bugzilla) 1602 0 R (security-bugzilla-charset) 1603 0 R (security-mysql) 1595 0 R (security-mysql-account) 1596 0 R (security-mysql-account-anonymous) 1898 0 R (security-mysql-account-root) 1897 0 R (security-mysql-network) 1598 0 R (security-mysql-network-ex) 1899 0 R (security-mysql-root) 1597 0 R (security-os) 1591 0 R (security-os-accounts) 1593 0 R (security-os-chroot) 1594 0 R (security-os-ports) 1592 0 R (security-webserver) 1599 0 R (security-webserver-access) 1600 0 R (security-webserver-mod-throttle) 1601 0 R (self-registration) 2880 0 R (svn) 1845 0 R (table.1) 1992 0 R (table.2) 3639 0 R (table.3) 3691 0 R (table.4) 3771 0 R (table.5) 3835 0 R (table.6) 3852 0 R (table.7) 3889 0 R (table.8) 4179 0 R (table.9) 4670 0 R (template-directory) 1750 0 R (template-edit) 1752 0 R (template-formats) 1753 0 R (template-http-accept) 1755 0 R (template-method) 1751 0 R (template-specific) 1754 0 R (timetracking) 1731 0 R (tinderbox) 1846 0 R (trbl-dbdSponge) 1852 0 R (trbl-index) 1857 0 R (trbl-passwd-encryption) 1858 0 R (trbl-perlmodule) 1851 0 R (trbl-relogin-everyone) 1855 0 R (trbl-relogin-everyone-restrict) 1901 0 R (trbl-relogin-everyone-share) 1900 0 R (trbl-relogin-some) 1856 0 R (trbl-testserver) 1850 0 R (trouble-filetemp) 1854 0 R (troubleshooting) 1848 0 R (upgrade-cvs) 1586 0 R (upgrade-patches) 1588 0 R (upgrade-tarball) 1587 0 R (upgrading) 1583 0 R (upgrading-completion) 1589 0 R (upgrading-methods) 1585 0 R (upgrading-version-defns) 1584 0 R (user-account-creation) 2886 0 R (user-account-deletion) 1451 0 R (user-account-search) 1448 0 R (useradmin) 1445 0 R (userpreferences) 1732 0 R (using) 1604 0 R (using-intro) 1605 0 R (versions) 1456 0 R (voting) 1573 0 R (whining) 1743 0 R (whining-overview) 1744 0 R (whining-query) 1746 0 R (whining-schedule) 1745 0 R (win32-code-changes) 1425 0 R (win32-email) 1427 0 R (win32-http) 1426 0 R (win32-perl) 1423 0 R (win32-perl-modules) 1424 0 R] +5501 0 obj << +/Names [(1.0) 2 0 R (10.0) 834 0 R (10.43.1) 838 0 R (10.44.1) 842 0 R (10.44.78.2) 846 0 R (10.44.79.2) 850 0 R (10.44.80.2) 854 0 R (10.44.81.2) 858 0 R (10.44.82.2) 862 0 R (10.44.83.2) 866 0 R (10.45.1) 870 0 R (10.46.1) 874 0 R (10.47.1) 878 0 R (10.47.84.2) 882 0 R (10.47.85.2) 886 0 R (10.47.86.2) 890 0 R (10.47.87.2) 894 0 R (10.47.88.2) 898 0 R (1000) 2806 0 R (1001) 2807 0 R (1002) 2808 0 R (1003) 2809 0 R (1004) 2810 0 R (1005) 2811 0 R (1006) 2812 0 R (1007) 2813 0 R (1008) 2814 0 R (1009) 2815 0 R (101) 2014 0 R (1012) 2816 0 R (1013) 1468 0 R (1015) 2817 0 R (1016) 2818 0 R (1017) 2819 0 R (1018) 2820 0 R (1019) 2821 0 R (102) 2015 0 R (1020) 2822 0 R (1021) 2823 0 R (1022) 2828 0 R (1023) 2829 0 R (1024) 2830 0 R (1025) 2831 0 R (1026) 1469 0 R (1028) 2832 0 R (1029) 2833 0 R (103) 2016 0 R (1030) 2834 0 R (1031) 2835 0 R (1032) 2836 0 R (1033) 2837 0 R (1034) 2838 0 R (1035) 2839 0 R (1036) 2840 0 R (1037) 2841 0 R (1038) 2842 0 R (1039) 2843 0 R (104) 2017 0 R (1040) 2844 0 R (1041) 2845 0 R (1042) 2846 0 R (1043) 2851 0 R (1044) 2852 0 R (1045) 2853 0 R (1046) 2854 0 R (1047) 2855 0 R (1048) 2856 0 R (1049) 2857 0 R (105) 2018 0 R (1050) 2858 0 R (1051) 2859 0 R (1052) 2860 0 R (1053) 2861 0 R (1054) 2862 0 R (1055) 2863 0 R (1056) 2864 0 R (1057) 2865 0 R (1058) 2866 0 R (1059) 1470 0 R (106) 2019 0 R (1061) 2867 0 R (1062) 1471 0 R (1064) 2868 0 R (1065) 2869 0 R (1066) 2870 0 R (1067) 2871 0 R (1068) 2872 0 R (1069) 2873 0 R (107) 2020 0 R (1070) 2878 0 R (1071) 1472 0 R (1073) 2879 0 R (1075) 2881 0 R (1076) 2882 0 R (1077) 2883 0 R (1078) 2884 0 R (1079) 2885 0 R (108) 2021 0 R (1080) 2886 0 R (1081) 2887 0 R (1082) 2888 0 R (1083) 2889 0 R (1084) 2890 0 R (1085) 2891 0 R (109) 2022 0 R (1090) 2897 0 R (1091) 2898 0 R (1093) 2899 0 R (1095) 2900 0 R (1096) 2901 0 R (1097) 2902 0 R (1099) 2903 0 R (11.0) 902 0 R (110) 2023 0 R (1100) 2904 0 R (1101) 2905 0 R (1102) 2906 0 R (1103) 2907 0 R (1104) 2908 0 R (1105) 2909 0 R (1107) 2910 0 R (1108) 2911 0 R (1109) 2912 0 R (111) 2024 0 R (1111) 2913 0 R (1112) 2914 0 R (1113) 2915 0 R (1114) 2916 0 R (1116) 2917 0 R (1117) 2918 0 R (1118) 2919 0 R (1119) 2920 0 R (112) 2025 0 R (1121) 2921 0 R (1122) 2922 0 R (1123) 2923 0 R (1124) 2924 0 R (1125) 2925 0 R (1126) 2926 0 R (1128) 2931 0 R (113) 2026 0 R (1130) 2932 0 R (1131) 2933 0 R (1132) 2934 0 R (1133) 2935 0 R (1134) 2936 0 R (1135) 2937 0 R (1137) 2938 0 R (1138) 2939 0 R (1139) 2940 0 R (114) 2027 0 R (1140) 2941 0 R (1142) 2942 0 R (1143) 2943 0 R (1144) 2944 0 R (1146) 2945 0 R (1147) 2946 0 R (1148) 2947 0 R (1150) 2948 0 R (1151) 2949 0 R (1152) 2950 0 R (1154) 2951 0 R (1155) 2952 0 R (1156) 2953 0 R (1158) 2958 0 R (1159) 2959 0 R (1160) 2960 0 R (1161) 2961 0 R (1162) 2962 0 R (1163) 2963 0 R (1165) 2964 0 R (1166) 2965 0 R (1167) 2966 0 R (1168) 2967 0 R (117) 2031 0 R (1170) 2968 0 R (1171) 2969 0 R (1172) 2970 0 R (1174) 2971 0 R (1175) 2972 0 R (1176) 2973 0 R (1181) 2974 0 R (1182) 2975 0 R (1183) 2976 0 R (1188) 2981 0 R (1189) 2982 0 R (119) 2032 0 R (1190) 2983 0 R (1191) 2984 0 R (1192) 2985 0 R (1193) 2986 0 R (1198) 2988 0 R (1199) 2989 0 R (12.0) 906 0 R (12.48.1) 910 0 R (12.49.1) 914 0 R (12.50.1) 918 0 R (12.51.1) 922 0 R (12.52.1) 926 0 R (12.53.1) 930 0 R (12.54.1) 934 0 R (12.55.1) 938 0 R (12.56.1) 942 0 R (120) 2033 0 R (1200) 2990 0 R (1201) 2991 0 R (1205) 2994 0 R (1206) 2995 0 R (1207) 2996 0 R (1208) 2997 0 R (1209) 2998 0 R (121) 2034 0 R (1210) 2999 0 R (1211) 3000 0 R (1212) 3001 0 R (1213) 3002 0 R (1214) 3003 0 R (1215) 3004 0 R (1218) 3005 0 R (1219) 3006 0 R (1220) 3007 0 R (1221) 3012 0 R (1222) 3013 0 R (1223) 3014 0 R (1224) 3015 0 R (1225) 3016 0 R (1226) 3017 0 R (1227) 3018 0 R (1228) 3019 0 R (1229) 3020 0 R (1230) 3021 0 R (1231) 3022 0 R (1232) 3023 0 R (1233) 3024 0 R (1234) 3025 0 R (1235) 3026 0 R (1236) 3027 0 R (1237) 3028 0 R (1238) 3029 0 R (1239) 3030 0 R (1240) 3031 0 R (1241) 3032 0 R (1242) 3033 0 R (1243) 3034 0 R (1244) 3035 0 R (1245) 3036 0 R (1246) 3037 0 R (1247) 3038 0 R (1248) 3039 0 R (1249) 3040 0 R (1250) 3041 0 R (1251) 3042 0 R (1252) 3043 0 R (1253) 3044 0 R (1254) 3045 0 R (1255) 3046 0 R (1256) 3047 0 R (1257) 3048 0 R (1258) 3049 0 R (1259) 3050 0 R (1260) 3051 0 R (1261) 3052 0 R (1262) 3053 0 R (1263) 3054 0 R (1264) 3055 0 R (1265) 3056 0 R (1266) 3057 0 R (1267) 3058 0 R (1268) 3059 0 R (1269) 3060 0 R (1270) 3061 0 R (1273) 3066 0 R (1274) 3067 0 R (1278) 3069 0 R (1279) 3070 0 R (1280) 3071 0 R (1281) 3072 0 R (1282) 3073 0 R (1283) 3074 0 R (1284) 3075 0 R (1285) 3076 0 R (1286) 3077 0 R (1289) 3078 0 R (1290) 3079 0 R (1291) 3080 0 R (1292) 3081 0 R (1293) 3082 0 R (1294) 3083 0 R (1297) 3089 0 R (1299) 3091 0 R (13.0) 946 0 R (13.57.1) 950 0 R (13.58.1) 954 0 R (1300) 3092 0 R (1301) 3093 0 R (1302) 3094 0 R (1303) 3095 0 R (1304) 3096 0 R (1305) 3097 0 R (1306) 3098 0 R (1307) 3099 0 R (1308) 3100 0 R (1311) 3101 0 R (1312) 3102 0 R (1313) 3103 0 R (1314) 3104 0 R (1315) 3105 0 R (1316) 3106 0 R (1317) 3107 0 R (1318) 3108 0 R (1319) 3109 0 R (1320) 3110 0 R (1321) 3111 0 R (1324) 3112 0 R (1325) 3113 0 R (1326) 3114 0 R (1327) 3120 0 R (1328) 3121 0 R (1329) 3122 0 R (1330) 3123 0 R (1331) 3124 0 R (1332) 3125 0 R (1335) 3126 0 R (1336) 3127 0 R (1337) 3128 0 R (1338) 3129 0 R (1339) 3130 0 R (1340) 3131 0 R (1341) 3132 0 R (1342) 3133 0 R (1343) 3134 0 R (1344) 3135 0 R (1345) 3136 0 R (1346) 3137 0 R (1347) 3138 0 R (1350) 3139 0 R (1351) 3140 0 R (1352) 3141 0 R (1353) 3142 0 R (1356) 3143 0 R (1357) 3144 0 R (1358) 3145 0 R (1359) 3146 0 R (1360) 3147 0 R (1361) 3148 0 R (1362) 3149 0 R (1363) 3150 0 R (1364) 3151 0 R (1365) 3152 0 R (1366) 3153 0 R (1367) 3154 0 R (1368) 3155 0 R (1369) 3156 0 R (1370) 3161 0 R (1371) 3162 0 R (1372) 3163 0 R (1373) 3164 0 R (1374) 3165 0 R (1375) 3166 0 R (1376) 3167 0 R (1377) 3168 0 R (1378) 3169 0 R (1379) 3170 0 R (1380) 3171 0 R (1381) 3172 0 R (1382) 3173 0 R (1387) 3174 0 R (1388) 3175 0 R (1390) 3176 0 R (1391) 3177 0 R (1392) 3178 0 R (1393) 3179 0 R (1395) 3180 0 R (1396) 3181 0 R (1397) 3182 0 R (1398) 3183 0 R (1399) 3184 0 R (14.0) 958 0 R (14.59.1) 962 0 R (14.60.1) 966 0 R (14.61.1) 970 0 R (1401) 3185 0 R (1402) 3186 0 R (1403) 3187 0 R (1404) 3188 0 R (1405) 3189 0 R (1406) 3190 0 R (1407) 3191 0 R (1410) 3192 0 R (1411) 3193 0 R (1412) 3194 0 R (1413) 3195 0 R (1414) 3196 0 R (1415) 3197 0 R (1416) 3198 0 R (1417) 3199 0 R (1418) 3200 0 R (1419) 3201 0 R (1420) 3202 0 R (1423) 3208 0 R (1426) 3209 0 R (1427) 3210 0 R (1428) 3211 0 R (1429) 3212 0 R (1430) 3213 0 R (1431) 3214 0 R (1432) 3215 0 R (1433) 3216 0 R (1434) 3217 0 R (1435) 3218 0 R (1436) 3219 0 R (1437) 3220 0 R (1438) 3221 0 R (1439) 3222 0 R (1440) 3223 0 R (1441) 3224 0 R (1442) 3225 0 R (1443) 3226 0 R (1444) 3227 0 R (1447) 3228 0 R (1448) 3229 0 R (1449) 3230 0 R (1450) 3231 0 R (1451) 3232 0 R (1454) 3233 0 R (1455) 3234 0 R (1456) 3235 0 R (1457) 3236 0 R (1458) 3237 0 R (1461) 3238 0 R (1462) 3239 0 R (1465) 3245 0 R (1468) 3246 0 R (1469) 3247 0 R (1470) 3248 0 R (1473) 3250 0 R (1474) 3251 0 R (1475) 3252 0 R (1476) 3253 0 R (1477) 3254 0 R (1478) 3255 0 R (1479) 3256 0 R (1480) 3257 0 R (1481) 3258 0 R (1482) 3259 0 R (1483) 3260 0 R (1484) 3261 0 R (1485) 3262 0 R (1486) 3263 0 R (1487) 3264 0 R (1488) 3265 0 R (1489) 3266 0 R (1490) 3267 0 R (1491) 3268 0 R (1492) 3269 0 R (1493) 3270 0 R (1494) 3271 0 R (1495) 3272 0 R (1496) 3273 0 R (1497) 3274 0 R (1498) 3275 0 R (1499) 3276 0 R (15.0) 974 0 R (15.62.1) 978 0 R (15.63.1) 982 0 R (15.64.1) 986 0 R (15.65.1) 990 0 R (15.66.1) 994 0 R (15.67.1) 998 0 R (15.68.1) 1002 0 R (15.69.1) 1006 0 R (15.70.1) 1010 0 R (15.71.1) 1014 0 R (15.72.1) 1018 0 R (15.73.1) 1022 0 R (1500) 3277 0 R (1501) 3278 0 R (1502) 3279 0 R (1503) 3280 0 R (1506) 3282 0 R (1507) 3283 0 R (1508) 3284 0 R (1511) 3291 0 R (1512) 3292 0 R (1515) 3294 0 R (1516) 3295 0 R (1517) 3296 0 R (1518) 3297 0 R (1519) 3298 0 R (1520) 3299 0 R (1523) 3301 0 R (1524) 3302 0 R (1527) 3304 0 R (1528) 3305 0 R (1529) 3306 0 R (1530) 3307 0 R (1533) 3309 0 R (1536) 3311 0 R (1537) 3312 0 R (1538) 3313 0 R (1539) 3314 0 R (1542) 3316 0 R (1543) 3317 0 R (1546) 3323 0 R (1547) 3324 0 R (1548) 3290 0 R (1550) 3325 0 R (1551) 3326 0 R (1552) 3327 0 R (1553) 3328 0 R (1556) 3329 0 R (1557) 3330 0 R (1558) 3331 0 R (1561) 3332 0 R (1562) 3333 0 R (1565) 3334 0 R (1566) 3335 0 R (1567) 3336 0 R (1568) 3337 0 R (1569) 3338 0 R (1570) 3339 0 R (1571) 3340 0 R (1572) 3341 0 R (1573) 3342 0 R (1574) 3343 0 R (1575) 3344 0 R (1576) 3345 0 R (1577) 3346 0 R (1578) 3347 0 R (1579) 3348 0 R (1581) 3350 0 R (1582) 3351 0 R (1583) 3352 0 R (1584) 3353 0 R (1585) 3358 0 R (1586) 3359 0 R (1588) 3361 0 R (1589) 3362 0 R (1590) 3363 0 R (1591) 3364 0 R (1592) 3365 0 R (1593) 3366 0 R (1596) 3367 0 R (16.0) 1026 0 R (1600) 3369 0 R (1603) 3370 0 R (1604) 3371 0 R (1607) 3372 0 R (1608) 3373 0 R (1609) 3374 0 R (1610) 3375 0 R (1613) 3376 0 R (1614) 3377 0 R (1615) 3378 0 R (1616) 3379 0 R (1617) 3380 0 R (1618) 3381 0 R (1619) 3386 0 R (1622) 3387 0 R (1623) 3388 0 R (1624) 3389 0 R (1625) 3390 0 R (1626) 3391 0 R (1627) 3392 0 R (1628) 3393 0 R (1629) 3394 0 R (1630) 3395 0 R (1631) 3396 0 R (1632) 3397 0 R (1633) 3398 0 R (1634) 3399 0 R (1635) 3400 0 R (1636) 3401 0 R (1637) 3402 0 R (1640) 3403 0 R (1641) 3404 0 R (1642) 3405 0 R (1643) 3406 0 R (1644) 3407 0 R (1645) 3408 0 R (1648) 3413 0 R (1649) 3414 0 R (1650) 3415 0 R (1651) 3416 0 R (1652) 3417 0 R (1653) 3418 0 R (1654) 3419 0 R (1655) 3420 0 R (1656) 3421 0 R (1657) 3422 0 R (1658) 3423 0 R (1659) 1610 0 R (1661) 3424 0 R (1662) 3425 0 R (1663) 3426 0 R (1664) 3427 0 R (1665) 3428 0 R (1666) 3429 0 R (1667) 3430 0 R (1668) 3431 0 R (1669) 3432 0 R (1670) 3433 0 R (1671) 3434 0 R (1672) 3435 0 R (1673) 3436 0 R (1674) 3437 0 R (1675) 3438 0 R (1676) 3439 0 R (1677) 3440 0 R (1678) 3441 0 R (1679) 3442 0 R (1680) 3443 0 R (1681) 3444 0 R (1682) 3445 0 R (1683) 3446 0 R (1684) 3447 0 R (1685) 3453 0 R (1686) 1611 0 R (1688) 3454 0 R (1689) 3455 0 R (1690) 3456 0 R (1691) 3457 0 R (1692) 3458 0 R (1693) 3459 0 R (1694) 3460 0 R (1695) 3461 0 R (1696) 1612 0 R (1698) 3462 0 R (1699) 3463 0 R (17.0) 1030 0 R (17.73.89.2) 1034 0 R (1700) 3464 0 R (1701) 3465 0 R (1702) 3466 0 R (1703) 3467 0 R (1704) 3468 0 R (1705) 3469 0 R (1706) 3470 0 R (1707) 3471 0 R (1708) 3472 0 R (1709) 3473 0 R (1710) 3474 0 R (1711) 3475 0 R (1712) 3476 0 R (1713) 3477 0 R (1714) 1613 0 R (1716) 1614 0 R (1718) 3482 0 R (1719) 3452 0 R (1720) 1615 0 R (1722) 3483 0 R (1723) 3484 0 R (1724) 1616 0 R (1726) 3485 0 R (1727) 3486 0 R (1728) 3487 0 R (1729) 3488 0 R (1730) 3489 0 R (1731) 3490 0 R (1732) 3491 0 R (1733) 3492 0 R (1734) 3493 0 R (1735) 3494 0 R (1736) 3495 0 R (1737) 3496 0 R (1740) 3502 0 R (1741) 3503 0 R (1742) 3504 0 R (1743) 3505 0 R (1744) 3506 0 R (1745) 3507 0 R (1748) 3508 0 R (1749) 3509 0 R (1750) 3510 0 R (1751) 3511 0 R (1752) 3512 0 R (1753) 3513 0 R (1754) 3514 0 R (1757) 3519 0 R (1758) 3520 0 R (1760) 3522 0 R (1761) 3523 0 R (1764) 3524 0 R (1765) 3525 0 R (1766) 3526 0 R (1767) 3527 0 R (1769) 3529 0 R (1770) 3530 0 R (1772) 3532 0 R (1773) 3533 0 R (1775) 3535 0 R (1777) 3537 0 R (1778) 3538 0 R (1779) 3539 0 R (1780) 3540 0 R (1781) 3541 0 R (1784) 3542 0 R (1785) 3543 0 R (1786) 3544 0 R (1787) 3549 0 R (1788) 3550 0 R (1789) 3551 0 R (1790) 3552 0 R (1791) 3553 0 R (1792) 3554 0 R (1793) 3555 0 R (1794) 3556 0 R (1795) 3557 0 R (1796) 3558 0 R (1797) 3559 0 R (18.0) 1038 0 R (18.73.90.2) 1042 0 R (18.73.90.57.3) 1046 0 R (1800) 3560 0 R (1801) 3561 0 R (1802) 3562 0 R (1803) 3563 0 R (1804) 3564 0 R (1805) 3565 0 R (1806) 3566 0 R (1807) 3567 0 R (1808) 3568 0 R (1809) 3569 0 R (1810) 3570 0 R (1811) 3571 0 R (1812) 3572 0 R (1813) 3573 0 R (1814) 3574 0 R (1815) 3575 0 R (1816) 3576 0 R (1817) 3577 0 R (1818) 3578 0 R (1819) 3583 0 R (182) 2039 0 R (1820) 3584 0 R (1823) 3585 0 R (1824) 3586 0 R (1825) 3587 0 R (1826) 3588 0 R (1827) 3589 0 R (1828) 3590 0 R (1829) 3591 0 R (183) 2040 0 R (1830) 3592 0 R (1831) 3593 0 R (1832) 3594 0 R (1833) 3595 0 R (1834) 3596 0 R (1835) 3597 0 R (1836) 3598 0 R (1840) 3600 0 R (1841) 3601 0 R (1842) 3602 0 R (1843) 3603 0 R (1844) 3604 0 R (1845) 3605 0 R (1846) 3606 0 R (1847) 3607 0 R (1848) 3612 0 R (1849) 3613 0 R (1852) 3618 0 R (1853) 3619 0 R (1854) 3620 0 R (1859) 3621 0 R (1862) 3622 0 R (1864) 3624 0 R (1865) 3625 0 R (1866) 3626 0 R (1867) 3627 0 R (1869) 3629 0 R (1870) 3630 0 R (1871) 3631 0 R (1872) 3632 0 R (1873) 3633 0 R (1874) 3634 0 R (1875) 3635 0 R (1876) 3636 0 R (1877) 3637 0 R (1878) 3638 0 R (1879) 3639 0 R (188) 2045 0 R (1883) 3640 0 R (1884) 3641 0 R (1889) 3649 0 R (189) 2046 0 R (1895) 3651 0 R (1896) 3652 0 R (1897) 3653 0 R (1898) 3654 0 R (19.0) 1050 0 R (19.73.91.2) 1054 0 R (19.73.92.2) 1058 0 R (19.73.93.2) 1062 0 R (190) 2047 0 R (1902) 3655 0 R (1903) 3656 0 R (1904) 3657 0 R (1905) 3658 0 R (1906) 3659 0 R (191) 2050 0 R (1910) 3660 0 R (1911) 3661 0 R (1913) 3662 0 R (1914) 3663 0 R (1915) 3664 0 R (1916) 3665 0 R (1917) 3666 0 R (1918) 3667 0 R (1923) 3669 0 R (1927) 3671 0 R (1928) 3672 0 R (1929) 3673 0 R (193) 2053 0 R (1934) 3678 0 R (1935) 3679 0 R (1936) 3680 0 R (1937) 3681 0 R (194) 2054 0 R (1941) 3684 0 R (1942) 3685 0 R (1943) 3686 0 R (1944) 3687 0 R (1945) 3688 0 R (1946) 3689 0 R (1948) 3690 0 R (1949) 3691 0 R (195) 2055 0 R (1950) 3692 0 R (1951) 3693 0 R (1952) 3694 0 R (1953) 3695 0 R (1954) 3696 0 R (1955) 3697 0 R (1956) 3698 0 R (1957) 3699 0 R (1958) 3700 0 R (1959) 3701 0 R (196) 2056 0 R (1961) 3702 0 R (1962) 3703 0 R (1963) 3704 0 R (1964) 3705 0 R (1965) 3706 0 R (1966) 3707 0 R (1967) 3708 0 R (1968) 3709 0 R (1969) 3710 0 R (197) 2057 0 R (1970) 3711 0 R (1971) 3712 0 R (1972) 3713 0 R (1973) 3714 0 R (1975) 3715 0 R (1976) 3716 0 R (1977) 3717 0 R (1978) 3718 0 R (1979) 3719 0 R (198) 2058 0 R (1980) 3720 0 R (1981) 3721 0 R (1982) 3722 0 R (1983) 3723 0 R (1985) 3724 0 R (1986) 3725 0 R (1987) 3726 0 R (1988) 3727 0 R (1989) 3728 0 R (199) 2059 0 R (1990) 3729 0 R (1991) 3730 0 R (1992) 3731 0 R (1993) 3732 0 R (1994) 3733 0 R (1995) 3734 0 R (1996) 3735 0 R (1997) 3736 0 R (1998) 3737 0 R (1999) 3738 0 R (2.0) 6 0 R (20.0) 1066 0 R (20.73.94.2) 1070 0 R (20.73.95.2) 1074 0 R (20.73.96.2) 1078 0 R (20.73.97.2) 1082 0 R (200) 2060 0 R (2000) 3739 0 R (2001) 3740 0 R (2002) 3741 0 R (2003) 3742 0 R (2004) 3743 0 R (2005) 3744 0 R (2006) 3745 0 R (2007) 3746 0 R (2008) 3747 0 R (2009) 3748 0 R (201) 2061 0 R (2010) 3749 0 R (2011) 3755 0 R (2012) 3756 0 R (2013) 3757 0 R (2014) 3758 0 R (2015) 3759 0 R (2020) 3761 0 R (2021) 3762 0 R (2022) 3763 0 R (2024) 3765 0 R (2025) 3766 0 R (2026) 3767 0 R (2027) 3768 0 R (2032) 3769 0 R (2033) 3770 0 R (2034) 3771 0 R (2035) 3772 0 R (2036) 3773 0 R (2037) 3774 0 R (204) 2063 0 R (2042) 3780 0 R (2043) 3781 0 R (2046) 3782 0 R (2047) 3783 0 R (2048) 3784 0 R (2049) 3785 0 R (2050) 3786 0 R (2051) 3787 0 R (2052) 3788 0 R (2053) 3789 0 R (2054) 3790 0 R (2055) 3791 0 R (2056) 3792 0 R (2057) 3793 0 R (2058) 3794 0 R (2059) 3795 0 R (2060) 3796 0 R (2061) 3797 0 R (2062) 3798 0 R (2063) 3799 0 R (2064) 3800 0 R (2065) 3801 0 R (2066) 3802 0 R (2067) 3803 0 R (2068) 3804 0 R (2069) 3809 0 R (207) 2065 0 R (2072) 3810 0 R (2073) 3811 0 R (2074) 3812 0 R (2075) 3813 0 R (2076) 3814 0 R (2077) 3815 0 R (2078) 3816 0 R (2099) 3818 0 R (21.0) 1086 0 R (21.73.98.2) 1090 0 R (21.73.99.2) 1094 0 R (210) 2067 0 R (2100) 3819 0 R (2101) 3820 0 R (2102) 3821 0 R (2103) 3822 0 R (2104) 3823 0 R (2105) 3824 0 R (2106) 3825 0 R (2107) 3826 0 R (2108) 3827 0 R (2109) 3828 0 R (2110) 3829 0 R (2111) 3830 0 R (2112) 3831 0 R (2113) 3832 0 R (2114) 3833 0 R (2115) 3834 0 R (2116) 3835 0 R (2117) 3836 0 R (2118) 3837 0 R (2119) 3838 0 R (2120) 3839 0 R (2121) 3840 0 R (2122) 3841 0 R (2123) 3842 0 R (2124) 3843 0 R (2125) 3844 0 R (2126) 3845 0 R (2127) 3846 0 R (2128) 3847 0 R (2129) 3848 0 R (213) 2069 0 R (2130) 3849 0 R (2131) 3850 0 R (2132) 3851 0 R (2133) 3852 0 R (2134) 3853 0 R (2135) 3859 0 R (2136) 3860 0 R (2137) 3861 0 R (2138) 3862 0 R (2139) 3863 0 R (2140) 3864 0 R (2141) 3865 0 R (2142) 3866 0 R (2143) 3867 0 R (2144) 3868 0 R (2145) 3869 0 R (216) 2071 0 R (2166) 3871 0 R (2167) 3872 0 R (2168) 3873 0 R (2169) 3874 0 R (2170) 3875 0 R (2171) 3876 0 R (2172) 3877 0 R (2173) 3878 0 R (2174) 3879 0 R (2175) 3880 0 R (2176) 3881 0 R (2177) 3882 0 R (2180) 3883 0 R (2182) 3885 0 R (2183) 3886 0 R (2186) 3892 0 R (219) 2073 0 R (2191) 3893 0 R (2192) 3894 0 R (2193) 3895 0 R (2194) 3896 0 R (2198) 3902 0 R (2199) 3903 0 R (22.0) 1098 0 R (22.73.100.2) 1102 0 R (2200) 3904 0 R (2201) 3905 0 R (2202) 3906 0 R (2203) 3907 0 R (2204) 3908 0 R (2205) 3909 0 R (2206) 3910 0 R (2207) 3911 0 R (2208) 3912 0 R (2209) 3913 0 R (2210) 3914 0 R (2211) 3915 0 R (2212) 3916 0 R (2213) 3917 0 R (2214) 3918 0 R (2217) 3919 0 R (2220) 3920 0 R (2221) 3921 0 R (2222) 3922 0 R (2223) 3923 0 R (2224) 3924 0 R (2225) 3925 0 R (2226) 3926 0 R (2227) 3927 0 R (2228) 3928 0 R (2229) 3929 0 R (223) 2074 0 R (2230) 3930 0 R (2231) 3931 0 R (2232) 3932 0 R (2235) 3937 0 R (2236) 3938 0 R (2237) 3939 0 R (2238) 3940 0 R (2239) 3941 0 R (224) 2075 0 R (2240) 3942 0 R (2243) 3943 0 R (2244) 3944 0 R (2245) 3945 0 R (2246) 3946 0 R (2247) 3947 0 R (225) 2076 0 R (2250) 3948 0 R (2251) 3949 0 R (2252) 3950 0 R (226) 2077 0 R (2273) 3952 0 R (2276) 3957 0 R (2277) 3958 0 R (2279) 3960 0 R (2280) 3961 0 R (2281) 3962 0 R (2282) 3963 0 R (2287) 3964 0 R (2288) 3965 0 R (2289) 3966 0 R (229) 2081 0 R (2290) 3967 0 R (2291) 3968 0 R (2292) 3969 0 R (2293) 3970 0 R (2294) 3971 0 R (2295) 3972 0 R (2296) 3973 0 R (2297) 3974 0 R (2298) 3975 0 R (2299) 3976 0 R (23.0) 1106 0 R (23.73.101.2) 1110 0 R (2300) 3977 0 R (2301) 3978 0 R (2302) 3979 0 R (2303) 3980 0 R (2304) 3981 0 R (2305) 3982 0 R (2306) 3987 0 R (2307) 3988 0 R (2308) 3989 0 R (2309) 3990 0 R (2310) 3991 0 R (2311) 3992 0 R (2312) 3993 0 R (2313) 3994 0 R (2314) 3995 0 R (2315) 3996 0 R (2316) 3997 0 R (2319) 3998 0 R (232) 2082 0 R (2320) 3999 0 R (2321) 4000 0 R (2324) 4001 0 R (2325) 4002 0 R (2326) 4003 0 R (2327) 4004 0 R (2328) 4009 0 R (2329) 4010 0 R (233) 2083 0 R (2330) 4011 0 R (2331) 4012 0 R (2332) 4013 0 R (2333) 4014 0 R (2336) 4015 0 R (2337) 4016 0 R (2338) 4017 0 R (234) 2084 0 R (2348) 4019 0 R (235) 2085 0 R (2351) 4020 0 R (2354) 4021 0 R (2357) 4027 0 R (236) 2086 0 R (2360) 4028 0 R (2363) 4029 0 R (2364) 4030 0 R (2367) 4031 0 R (237) 2087 0 R (2370) 4032 0 R (2371) 1763 0 R (2373) 4033 0 R (2374) 4034 0 R (2375) 4035 0 R (238) 2088 0 R (2384) 4041 0 R (2387) 4042 0 R (2388) 4043 0 R (239) 2089 0 R (2391) 4044 0 R (2392) 4045 0 R (2393) 4046 0 R (2396) 4047 0 R (2397) 4048 0 R (2398) 4049 0 R (2399) 4050 0 R (24) 1948 0 R (24.0) 1114 0 R (24.73.102.2) 1118 0 R (24.73.103.2) 1122 0 R (240) 2090 0 R (2400) 4051 0 R (2401) 4052 0 R (2402) 4053 0 R (2405) 4054 0 R (2408) 4059 0 R (2409) 4060 0 R (2410) 4061 0 R (2413) 4062 0 R (2414) 4063 0 R (2415) 4064 0 R (2416) 4065 0 R (2417) 4066 0 R (2418) 4067 0 R (2419) 4068 0 R (2420) 4069 0 R (2421) 4070 0 R (2422) 4071 0 R (2423) 4072 0 R (2427) 4074 0 R (2428) 4075 0 R (243) 2091 0 R (2431) 4076 0 R (2432) 4077 0 R (2433) 4078 0 R (2434) 4079 0 R (2435) 4080 0 R (2436) 4081 0 R (2437) 4082 0 R (2438) 4083 0 R (2439) 4084 0 R (244) 2092 0 R (2440) 4085 0 R (2441) 4086 0 R (2442) 4087 0 R (2443) 4088 0 R (2444) 4089 0 R (2445) 4090 0 R (2446) 4095 0 R (2447) 4096 0 R (2448) 4097 0 R (2449) 4098 0 R (245) 2093 0 R (2450) 4099 0 R (2451) 4100 0 R (2452) 4101 0 R (2453) 4102 0 R (2454) 4103 0 R (2455) 4104 0 R (2456) 4105 0 R (2457) 4106 0 R (2458) 4107 0 R (2459) 4108 0 R (246) 2094 0 R (2460) 4109 0 R (2461) 4110 0 R (2462) 4111 0 R (2463) 4112 0 R (2464) 4113 0 R (2465) 4114 0 R (2466) 4115 0 R (2467) 4116 0 R (2468) 4117 0 R (2469) 4118 0 R (247) 2095 0 R (2470) 4119 0 R (2471) 4120 0 R (2472) 4121 0 R (2473) 4122 0 R (2474) 4123 0 R (2475) 4124 0 R (2476) 4125 0 R (2477) 4126 0 R (2480) 4127 0 R (2483) 4132 0 R (2486) 4133 0 R (2487) 4134 0 R (2488) 4135 0 R (2489) 4136 0 R (2490) 4137 0 R (2493) 4138 0 R (2494) 4139 0 R (2495) 4140 0 R (2496) 4141 0 R (2497) 4142 0 R (2498) 4143 0 R (2499) 1775 0 R (25) 1949 0 R (25.0) 1126 0 R (25.73.104.2) 1130 0 R (25.73.105.2) 1134 0 R (25.73.106.2) 1138 0 R (250) 2096 0 R (2501) 4148 0 R (2502) 4149 0 R (2503) 4150 0 R (2504) 4151 0 R (2505) 4152 0 R (2506) 1776 0 R (2508) 4153 0 R (2509) 4154 0 R (251) 2097 0 R (2512) 4155 0 R (2513) 4156 0 R (2514) 4157 0 R (2515) 4158 0 R (2516) 4159 0 R (2517) 4160 0 R (2518) 4166 0 R (2519) 4167 0 R (2522) 4168 0 R (2523) 4169 0 R (2524) 4170 0 R (2525) 4171 0 R (2526) 4172 0 R (2527) 4173 0 R (2529) 4175 0 R (253) 2099 0 R (2530) 4176 0 R (2534) 4178 0 R (2535) 4179 0 R (2536) 4180 0 R (2539) 4185 0 R (254) 2100 0 R (2540) 4186 0 R (2541) 4187 0 R (2542) 4188 0 R (2543) 4189 0 R (2544) 4190 0 R (2545) 4191 0 R (2546) 4192 0 R (2549) 4193 0 R (255) 2101 0 R (2550) 4194 0 R (2551) 4195 0 R (2553) 4197 0 R (2554) 4198 0 R (2555) 4203 0 R (2556) 4204 0 R (2557) 4205 0 R (2558) 4206 0 R (2559) 1782 0 R (2561) 4207 0 R (2562) 4208 0 R (2563) 4209 0 R (2568) 4214 0 R (2569) 4215 0 R (2570) 4216 0 R (2571) 4217 0 R (2572) 4218 0 R (2573) 4219 0 R (2574) 4220 0 R (2575) 4221 0 R (2576) 4222 0 R (2577) 4223 0 R (2578) 4224 0 R (258) 2107 0 R (2581) 4225 0 R (2582) 4226 0 R (2586) 4228 0 R (2587) 4229 0 R (2588) 4230 0 R (2589) 4231 0 R (259) 2108 0 R (2590) 4232 0 R (2591) 4233 0 R (2592) 4234 0 R (2593) 4235 0 R (2594) 4236 0 R (2595) 4237 0 R (2598) 4243 0 R (2599) 4244 0 R (26) 1950 0 R (26.0) 1142 0 R (26.73.107.2) 1146 0 R (260) 2109 0 R (2600) 4245 0 R (2601) 4246 0 R (2602) 4247 0 R (2603) 4248 0 R (2604) 4249 0 R (2605) 4250 0 R (2606) 4251 0 R (2607) 4252 0 R (2608) 4253 0 R (2609) 4254 0 R (261) 2110 0 R (2610) 4255 0 R (2611) 4256 0 R (2612) 4257 0 R (2613) 4258 0 R (2614) 4259 0 R (2615) 4260 0 R (2616) 4261 0 R (2617) 4262 0 R (2618) 4263 0 R (2619) 4264 0 R (262) 2111 0 R (2620) 4265 0 R (2621) 4266 0 R (2624) 4267 0 R (2625) 4268 0 R (2626) 4269 0 R (2627) 4242 0 R (2629) 4275 0 R (263) 2112 0 R (2630) 4276 0 R (2631) 4277 0 R (2632) 4278 0 R (2633) 4279 0 R (2636) 4280 0 R (2637) 4281 0 R (2638) 4282 0 R (2639) 4283 0 R (264) 2113 0 R (2640) 4284 0 R (2641) 4285 0 R (2642) 4286 0 R (2643) 4287 0 R (2644) 4288 0 R (2645) 4289 0 R (2646) 4290 0 R (2647) 4291 0 R (2648) 4292 0 R (2649) 4293 0 R (265) 2114 0 R (2650) 4294 0 R (2651) 4295 0 R (2652) 4296 0 R (2655) 4303 0 R (2656) 4274 0 R (2658) 4304 0 R (2659) 4305 0 R (266) 2115 0 R (2660) 4306 0 R (2661) 4307 0 R (2662) 4308 0 R (2663) 4309 0 R (2664) 4310 0 R (2665) 4311 0 R (2666) 4312 0 R (2667) 4313 0 R (2668) 4314 0 R (2669) 4315 0 R (267) 2116 0 R (2670) 4316 0 R (2671) 4317 0 R (2672) 4318 0 R (2673) 4319 0 R (2674) 4320 0 R (2675) 4321 0 R (2676) 4322 0 R (2677) 4323 0 R (2678) 4324 0 R (2679) 4325 0 R (2680) 4326 0 R (2681) 4327 0 R (2682) 4328 0 R (2683) 4329 0 R (2684) 4330 0 R (2685) 4331 0 R (2686) 4332 0 R (2687) 4333 0 R (2688) 4334 0 R (2689) 4335 0 R (2690) 4302 0 R (2692) 4341 0 R (2693) 4342 0 R (2694) 4343 0 R (2695) 4344 0 R (2696) 4345 0 R (2697) 4346 0 R (27.0) 1150 0 R (27.73.108.2) 1154 0 R (27.73.109.2) 1158 0 R (270) 2117 0 R (2700) 4347 0 R (2701) 4348 0 R (2702) 4349 0 R (2703) 4350 0 R (2704) 4351 0 R (2705) 4352 0 R (2706) 4353 0 R (2709) 4354 0 R (271) 2118 0 R (2710) 4355 0 R (2711) 4356 0 R (2712) 4357 0 R (2713) 4362 0 R (2714) 4340 0 R (2716) 4363 0 R (2717) 4364 0 R (2718) 4365 0 R (2719) 4366 0 R (2720) 4367 0 R (2721) 4368 0 R (2722) 4369 0 R (2723) 4370 0 R (2724) 4371 0 R (2725) 4372 0 R (2726) 4373 0 R (2727) 4374 0 R (2728) 4375 0 R (2729) 4376 0 R (273) 2120 0 R (2730) 4377 0 R (2731) 4378 0 R (2732) 4379 0 R (2733) 4380 0 R (2738) 4382 0 R (2739) 4383 0 R (274) 2121 0 R (2740) 4384 0 R (2741) 4385 0 R (2742) 4386 0 R (2743) 4387 0 R (2744) 4392 0 R (2745) 4393 0 R (2746) 4394 0 R (2747) 4395 0 R (2748) 4396 0 R (2749) 4397 0 R (275) 2122 0 R (2750) 4398 0 R (2751) 4399 0 R (2752) 4400 0 R (2753) 4401 0 R (2754) 4402 0 R (2755) 4403 0 R (2756) 4404 0 R (2757) 4405 0 R (2758) 4406 0 R (2759) 4407 0 R (276) 2123 0 R (2760) 4408 0 R (2761) 4409 0 R (2762) 4410 0 R (2763) 4411 0 R (2764) 4412 0 R (2765) 4413 0 R (2766) 4414 0 R (2767) 4415 0 R (2768) 4416 0 R (2769) 4417 0 R (277) 2124 0 R (2770) 4418 0 R (2771) 4419 0 R (2772) 4420 0 R (2773) 4421 0 R (2774) 4422 0 R (2775) 4423 0 R (2776) 4428 0 R (2779) 4429 0 R (278) 2125 0 R (2780) 4430 0 R (2781) 4431 0 R (2782) 4432 0 R (2783) 4433 0 R (2784) 4434 0 R (2785) 4435 0 R (2786) 4436 0 R (2787) 4437 0 R (2788) 4438 0 R (2789) 4439 0 R (279) 2126 0 R (2790) 4440 0 R (2791) 4441 0 R (2792) 4442 0 R (2793) 4447 0 R (2794) 4448 0 R (2795) 4449 0 R (2796) 4450 0 R (2797) 4451 0 R (2798) 4452 0 R (28) 1952 0 R (28.0) 1162 0 R (28.73.110.2) 1166 0 R (28.73.111.2) 1170 0 R (280) 2127 0 R (2803) 4453 0 R (2808) 4457 0 R (2809) 4458 0 R (2810) 4459 0 R (2811) 4460 0 R (2812) 4466 0 R (2813) 4467 0 R (2814) 4468 0 R (2815) 4469 0 R (2818) 4470 0 R (2819) 4471 0 R (2820) 4472 0 R (2821) 4473 0 R (2822) 4474 0 R (2825) 4475 0 R (2826) 4476 0 R (2829) 4477 0 R (283) 2130 0 R (2830) 4478 0 R (2831) 4479 0 R (2834) 4484 0 R (2835) 4485 0 R (2837) 4487 0 R (284) 2131 0 R (2841) 4489 0 R (2843) 4490 0 R (2847) 4492 0 R (2849) 4493 0 R (285) 2132 0 R (2853) 4495 0 R (2855) 4496 0 R (2856) 4497 0 R (286) 2133 0 R (2860) 4499 0 R (2862) 4500 0 R (2863) 4501 0 R (2864) 4502 0 R (2868) 4504 0 R (287) 2134 0 R (2870) 4505 0 R (2874) 4507 0 R (2876) 4508 0 R (2877) 4509 0 R (288) 2135 0 R (2881) 4511 0 R (2883) 4516 0 R (2884) 4517 0 R (2885) 4518 0 R (2886) 4519 0 R (2887) 4520 0 R (2888) 4521 0 R (289) 2136 0 R (2892) 4523 0 R (2894) 4524 0 R (2895) 4525 0 R (2896) 4526 0 R (2897) 4527 0 R (2898) 4528 0 R (2899) 4529 0 R (29.0) 1174 0 R (29.73.112.2) 1178 0 R (29.73.113.2) 1182 0 R (290) 2137 0 R (2900) 4530 0 R (2901) 4531 0 R (2905) 4533 0 R (2906) 4534 0 R (2908) 4535 0 R (2909) 4536 0 R (291) 2138 0 R (2913) 4543 0 R (2914) 4544 0 R (2915) 4545 0 R (2917) 4546 0 R (2918) 4547 0 R (2919) 4548 0 R (292) 2139 0 R (2920) 4549 0 R (2921) 4550 0 R (2922) 4551 0 R (2923) 4552 0 R (2924) 4553 0 R (2925) 4554 0 R (2926) 4555 0 R (2927) 4556 0 R (2928) 4557 0 R (2929) 4558 0 R (293) 2143 0 R (2930) 4559 0 R (2931) 4560 0 R (2932) 4561 0 R (2933) 4562 0 R (2934) 4563 0 R (2938) 4565 0 R (294) 2144 0 R (2943) 4567 0 R (2944) 4568 0 R (2946) 4569 0 R (295) 2145 0 R (2950) 4571 0 R (2952) 4572 0 R (2954) 4542 0 R (2958) 4579 0 R (296) 2146 0 R (2963) 4581 0 R (2965) 4582 0 R (2966) 4583 0 R (297) 2147 0 R (2970) 4585 0 R (2972) 4586 0 R (2974) 4588 0 R (2978) 4590 0 R (298) 2148 0 R (2983) 4592 0 R (2985) 4593 0 R (2986) 4594 0 R (2987) 4595 0 R (299) 2149 0 R (2991) 4597 0 R (2992) 4598 0 R (2994) 4603 0 R (2995) 4604 0 R (2996) 4605 0 R (2997) 4606 0 R (2998) 4607 0 R (2999) 4608 0 R (3.0) 10 0 R (30.0) 1186 0 R (30.73.114.2) 1190 0 R (300) 2150 0 R (3000) 4609 0 R (3004) 4611 0 R (3006) 4612 0 R (3007) 4613 0 R (301) 2151 0 R (3011) 4615 0 R (3016) 4617 0 R (3018) 4618 0 R (302) 2152 0 R (3022) 4620 0 R (3023) 4621 0 R (3025) 4622 0 R (3029) 4624 0 R (303) 2153 0 R (3034) 4632 0 R (3039) 4634 0 R (304) 2154 0 R (3043) 4637 0 R (3047) 4639 0 R (3052) 4641 0 R (3057) 4643 0 R (3059) 4644 0 R (306) 2156 0 R (3060) 4645 0 R (3061) 4646 0 R (3062) 4647 0 R (3063) 4648 0 R (3064) 4649 0 R (3065) 4650 0 R (3066) 4651 0 R (3067) 4652 0 R (3068) 4653 0 R (3069) 4654 0 R (307) 2157 0 R (3070) 4655 0 R (3071) 4656 0 R (3072) 4657 0 R (3073) 4658 0 R (3074) 4659 0 R (3075) 4660 0 R (3076) 4631 0 R (308) 2158 0 R (3081) 4668 0 R (3083) 4669 0 R (3084) 4670 0 R (3085) 4671 0 R (3086) 4672 0 R (3087) 4673 0 R (3088) 4674 0 R (309) 2159 0 R (3092) 4676 0 R (3094) 4677 0 R (3095) 4678 0 R (3096) 4679 0 R (3097) 4680 0 R (3098) 4681 0 R (3099) 4682 0 R (31) 1953 0 R (310) 2160 0 R (3100) 4683 0 R (3101) 4684 0 R (3103) 4686 0 R (3104) 4687 0 R (3105) 4688 0 R (3106) 4689 0 R (3107) 4665 0 R (311) 2161 0 R (3110) 4696 0 R (3114) 4698 0 R (3116) 4699 0 R (3117) 4700 0 R (3118) 4701 0 R (3119) 4702 0 R (3124) 4705 0 R (3127) 4707 0 R (313) 2163 0 R (3131) 4709 0 R (3133) 4710 0 R (3137) 4712 0 R (3139) 4713 0 R (314) 2164 0 R (3140) 4714 0 R (3141) 4715 0 R (3142) 4716 0 R (3143) 4717 0 R (3144) 4718 0 R (3145) 4719 0 R (3146) 4720 0 R (3147) 4721 0 R (3148) 4694 0 R (315) 2165 0 R (3150) 4727 0 R (3151) 4728 0 R (3152) 4729 0 R (3153) 4730 0 R (3154) 4731 0 R (3155) 4732 0 R (3156) 4733 0 R (3157) 4734 0 R (3158) 4735 0 R (3159) 4736 0 R (316) 2166 0 R (3160) 4737 0 R (3161) 4738 0 R (3162) 4739 0 R (3166) 4741 0 R (3168) 4742 0 R (3169) 4743 0 R (317) 2167 0 R (3170) 4744 0 R (3171) 4745 0 R (3175) 4747 0 R (318) 2168 0 R (3180) 4749 0 R (3182) 4750 0 R (3183) 4751 0 R (3184) 4752 0 R (3185) 4753 0 R (3186) 4754 0 R (3187) 4755 0 R (3188) 4756 0 R (3189) 4757 0 R (319) 2169 0 R (3191) 4759 0 R (3192) 4760 0 R (3196) 4762 0 R (3198) 4763 0 R (3199) 4764 0 R (32) 1954 0 R (3200) 4765 0 R (3201) 4766 0 R (3202) 4767 0 R (3203) 4768 0 R (3204) 4769 0 R (3206) 4726 0 R (321) 2171 0 R (3210) 4777 0 R (3212) 4778 0 R (3213) 4779 0 R (3214) 4780 0 R (3218) 4782 0 R (322) 2172 0 R (3220) 4783 0 R (3221) 4784 0 R (3222) 4785 0 R (3223) 4786 0 R (3224) 4787 0 R (3228) 4789 0 R (323) 2173 0 R (3230) 4790 0 R (3231) 4791 0 R (3232) 4792 0 R (3233) 4793 0 R (3234) 4794 0 R (3235) 4795 0 R (3236) 4796 0 R (3237) 4797 0 R (3238) 4798 0 R (3239) 4799 0 R (324) 2174 0 R (3240) 4800 0 R (3241) 4801 0 R (3242) 4802 0 R (3243) 4803 0 R (3244) 4804 0 R (3245) 4809 0 R (3246) 4810 0 R (3247) 4811 0 R (3248) 4812 0 R (3249) 4813 0 R (3250) 4814 0 R (3251) 4815 0 R (3255) 4817 0 R (3257) 4818 0 R (3258) 4819 0 R (3259) 4820 0 R (326) 2176 0 R (3261) 4822 0 R (3265) 4824 0 R (3267) 4825 0 R (3269) 4827 0 R (327) 2177 0 R (3270) 4828 0 R (3274) 4830 0 R (3279) 4832 0 R (3280) 4833 0 R (3282) 4834 0 R (3283) 4835 0 R (3284) 4841 0 R (3285) 4842 0 R (3286) 4843 0 R (329) 2179 0 R (3290) 4845 0 R (3292) 4846 0 R (3293) 4847 0 R (3294) 4848 0 R (3295) 4849 0 R (3296) 4850 0 R (3297) 4851 0 R (3298) 4852 0 R (3299) 4853 0 R (33) 1955 0 R (330) 2180 0 R (3300) 4854 0 R (3301) 4855 0 R (3302) 4856 0 R (3303) 4857 0 R (3304) 4858 0 R (3305) 4859 0 R (3307) 4861 0 R (3311) 4863 0 R (3316) 4865 0 R (3318) 4866 0 R (3319) 4867 0 R (332) 2182 0 R (3320) 4868 0 R (3321) 4869 0 R (3322) 4870 0 R (3323) 4871 0 R (3327) 4877 0 R (3328) 4878 0 R (333) 2183 0 R (3330) 4879 0 R (3341) 4882 0 R (3342) 4883 0 R (3347) 4885 0 R (3349) 4886 0 R (335) 2185 0 R (3353) 4888 0 R (3354) 4889 0 R (3356) 4890 0 R (3357) 4891 0 R (3358) 4892 0 R (3359) 4893 0 R (336) 2186 0 R (3360) 4894 0 R (3362) 4896 0 R (3366) 4898 0 R (3368) 4899 0 R (3369) 4904 0 R (337) 2187 0 R (3370) 4905 0 R (3374) 4907 0 R (3376) 4908 0 R (3377) 4909 0 R (3378) 4910 0 R (3379) 4911 0 R (338) 2188 0 R (3383) 4913 0 R (3384) 4914 0 R (3385) 4915 0 R (3387) 4916 0 R (3388) 4917 0 R (3389) 4918 0 R (339) 2189 0 R (3393) 4920 0 R (3395) 4921 0 R (3396) 4922 0 R (3397) 4923 0 R (3398) 4924 0 R (3399) 4925 0 R (340) 2190 0 R (3400) 4926 0 R (3401) 4927 0 R (3402) 4928 0 R (3403) 4929 0 R (3404) 4930 0 R (3405) 4931 0 R (3406) 4932 0 R (3407) 4933 0 R (3408) 4934 0 R (3409) 4935 0 R (3410) 4936 0 R (3411) 4937 0 R (3414) 4942 0 R (3417) 4943 0 R (3418) 4944 0 R (3419) 4945 0 R (342) 2192 0 R (3420) 4946 0 R (3423) 4949 0 R (3424) 4950 0 R (3425) 4951 0 R (3426) 4952 0 R (3427) 4953 0 R (343) 2193 0 R (3430) 4954 0 R (3431) 4955 0 R (3432) 4956 0 R (3433) 4957 0 R (3434) 4958 0 R (3438) 4959 0 R (3439) 4960 0 R (344) 2194 0 R (3440) 4961 0 R (3441) 4962 0 R (3442) 4963 0 R (3443) 4964 0 R (3444) 4969 0 R (3447) 4970 0 R (3448) 4971 0 R (3449) 4972 0 R (345) 2195 0 R (3450) 4973 0 R (3451) 4974 0 R (3452) 4975 0 R (3453) 4976 0 R (3454) 4977 0 R (3457) 4978 0 R (3458) 4979 0 R (3459) 4980 0 R (346) 2196 0 R (3460) 4981 0 R (3461) 4982 0 R (3462) 4983 0 R (3463) 4984 0 R (3464) 4985 0 R (3465) 4986 0 R (3466) 4987 0 R (3469) 4988 0 R (347) 2197 0 R (3470) 4989 0 R (3471) 4994 0 R (3472) 4995 0 R (3473) 4996 0 R (3474) 4997 0 R (3477) 4998 0 R (3478) 4999 0 R (3479) 5000 0 R (3480) 5001 0 R (3481) 5002 0 R (3484) 5003 0 R (3485) 5004 0 R (3486) 5005 0 R (3487) 5006 0 R (3488) 5007 0 R (3489) 5008 0 R (349) 2199 0 R (3490) 5009 0 R (3493) 5010 0 R (3494) 5011 0 R (3495) 5017 0 R (3496) 5018 0 R (3497) 5019 0 R (350) 2200 0 R (3501) 5020 0 R (3502) 5021 0 R (3503) 5022 0 R (3504) 5023 0 R (3508) 5025 0 R (3509) 5026 0 R (351) 2201 0 R (3510) 5027 0 R (3511) 5028 0 R (3512) 5029 0 R (3515) 5034 0 R (3516) 5035 0 R (3519) 5036 0 R (352) 2202 0 R (3520) 5037 0 R (3521) 5038 0 R (3522) 5039 0 R (3523) 5040 0 R (3524) 5041 0 R (3525) 5042 0 R (3526) 5043 0 R (3527) 5044 0 R (3528) 5045 0 R (3529) 5046 0 R (353) 2203 0 R (3530) 5047 0 R (3531) 5048 0 R (3532) 5049 0 R (3533) 5050 0 R (3534) 5051 0 R (3535) 5052 0 R (3536) 5053 0 R (3537) 5054 0 R (3538) 5055 0 R (3539) 5056 0 R (354) 2204 0 R (3540) 5057 0 R (3541) 5058 0 R (3542) 5059 0 R (3543) 5060 0 R (3544) 5061 0 R (3545) 5062 0 R (3546) 5063 0 R (3547) 5064 0 R (355) 2205 0 R (3550) 5065 0 R (3551) 5066 0 R (3552) 5067 0 R (3553) 5068 0 R (3554) 5069 0 R (3555) 5070 0 R (3556) 5071 0 R (3557) 5072 0 R (3558) 5073 0 R (356) 2206 0 R (3563) 5078 0 R (3564) 5079 0 R (3565) 5080 0 R (3566) 5081 0 R (3567) 5082 0 R (3568) 5083 0 R (3569) 5084 0 R (357) 2207 0 R (3570) 5085 0 R (3571) 5086 0 R (3572) 5087 0 R (3573) 5088 0 R (3574) 5089 0 R (3575) 5090 0 R (3576) 5091 0 R (3577) 5092 0 R (3578) 5093 0 R (358) 2208 0 R (3581) 5094 0 R (3582) 5095 0 R (3583) 5096 0 R (3584) 5097 0 R (3585) 5098 0 R (3586) 5099 0 R (3587) 5106 0 R (3588) 5100 0 R (359) 2209 0 R (3590) 5107 0 R (3591) 5108 0 R (3592) 5109 0 R (3593) 5110 0 R (3594) 5111 0 R (3595) 5112 0 R (3596) 5113 0 R (3597) 5114 0 R (3598) 5115 0 R (3599) 5116 0 R (36) 1956 0 R (360) 2210 0 R (3600) 5117 0 R (3601) 5118 0 R (3602) 5119 0 R (3603) 5120 0 R (3604) 5121 0 R (3605) 5122 0 R (3606) 5123 0 R (3607) 5124 0 R (3608) 5125 0 R (3609) 5126 0 R (361) 2211 0 R (3610) 5127 0 R (3611) 5128 0 R (3612) 5129 0 R (3613) 5130 0 R (3614) 5131 0 R (3615) 5136 0 R (3616) 5105 0 R (3618) 5137 0 R (3619) 5138 0 R (362) 2215 0 R (3620) 5139 0 R (3621) 5140 0 R (3622) 5141 0 R (3623) 5142 0 R (3624) 5143 0 R (3625) 5144 0 R (3626) 5145 0 R (3627) 5146 0 R (3628) 5147 0 R (3629) 5148 0 R (3630) 5149 0 R (3631) 5150 0 R (3632) 5151 0 R (3633) 5152 0 R (3636) 5153 0 R (3637) 5154 0 R (3638) 5155 0 R (3639) 5156 0 R (3640) 5157 0 R (3641) 5158 0 R (3642) 5159 0 R (3643) 5160 0 R (3644) 5161 0 R (3645) 5166 0 R (3646) 5167 0 R (3647) 5168 0 R (3648) 5169 0 R (3649) 5170 0 R (365) 2216 0 R (3650) 5171 0 R (3651) 5172 0 R (3652) 5173 0 R (3653) 5174 0 R (3654) 5175 0 R (3655) 5176 0 R (3656) 5177 0 R (3657) 5178 0 R (3658) 5179 0 R (3659) 5180 0 R (366) 2217 0 R (3660) 5181 0 R (3661) 5182 0 R (3662) 5183 0 R (3663) 5184 0 R (3664) 5185 0 R (3667) 5191 0 R (3668) 5192 0 R (3669) 5193 0 R (3672) 5194 0 R (3673) 5195 0 R (3674) 5196 0 R (3677) 5197 0 R (3678) 5198 0 R (3679) 5199 0 R (3680) 5200 0 R (3681) 5201 0 R (3682) 5202 0 R (3683) 5207 0 R (3684) 5208 0 R (3687) 5209 0 R (3688) 5210 0 R (369) 2218 0 R (3691) 5211 0 R (3692) 5212 0 R (3693) 5213 0 R (3694) 5219 0 R (3697) 5220 0 R (3698) 5221 0 R (3699) 5222 0 R (37) 1957 0 R (3700) 5223 0 R (3701) 5224 0 R (3702) 5225 0 R (3703) 5226 0 R (3704) 5227 0 R (3705) 5228 0 R (3706) 5229 0 R (3707) 5230 0 R (3708) 5231 0 R (3709) 5232 0 R (3710) 5233 0 R (3711) 5234 0 R (3712) 5235 0 R (3713) 5236 0 R (3714) 5237 0 R (3715) 5238 0 R (3716) 5239 0 R (3717) 5240 0 R (3718) 5241 0 R (3719) 5242 0 R (372) 2219 0 R (3720) 5243 0 R (3721) 5244 0 R (3722) 5245 0 R (3723) 5246 0 R (3724) 5247 0 R (3725) 5248 0 R (3726) 5249 0 R (3727) 5250 0 R (3728) 5218 0 R (3729) 5255 0 R (373) 2220 0 R (3730) 5256 0 R (3733) 5257 0 R (3734) 5258 0 R (3735) 5259 0 R (3738) 5260 0 R (3739) 5261 0 R (374) 2221 0 R (3742) 5262 0 R (3743) 5267 0 R (3746) 5268 0 R (3749) 5269 0 R (375) 2222 0 R (3752) 5270 0 R (3753) 5271 0 R (3754) 5272 0 R (3757) 5273 0 R (3758) 5274 0 R (3759) 5275 0 R (376) 2223 0 R (3760) 5280 0 R (3761) 5281 0 R (3763) 5287 0 R (3767) 5288 0 R (3768) 5289 0 R (3769) 5290 0 R (377) 2224 0 R (3770) 5291 0 R (3775) 5294 0 R (3776) 5295 0 R (3777) 5296 0 R (3778) 5297 0 R (3779) 5298 0 R (378) 2225 0 R (3780) 5299 0 R (3782) 5300 0 R (3783) 5301 0 R (3784) 5302 0 R (3785) 5303 0 R (3786) 5304 0 R (3788) 5305 0 R (3789) 5306 0 R (379) 2226 0 R (3790) 5307 0 R (3791) 5308 0 R (3792) 5309 0 R (3793) 5310 0 R (3794) 5311 0 R (3795) 5312 0 R (3796) 5313 0 R (3798) 5314 0 R (3799) 5315 0 R (38) 1958 0 R (380) 2227 0 R (3800) 5316 0 R (3801) 5317 0 R (3802) 5318 0 R (3803) 5319 0 R (3804) 5320 0 R (3805) 5321 0 R (3806) 5322 0 R (3807) 5323 0 R (3808) 5324 0 R (3810) 5325 0 R (3811) 5326 0 R (3812) 5327 0 R (3813) 5328 0 R (3814) 5329 0 R (3815) 5330 0 R (3820) 5337 0 R (3821) 5338 0 R (3822) 5339 0 R (3823) 5340 0 R (3824) 5341 0 R (3825) 5342 0 R (3827) 5343 0 R (3828) 5344 0 R (3829) 5345 0 R (383) 2228 0 R (3832) 5346 0 R (3833) 5347 0 R (3839) 5349 0 R (3840) 5350 0 R (3841) 5351 0 R (3842) 5352 0 R (3845) 5354 0 R (3846) 5355 0 R (3850) 5356 0 R (3851) 5357 0 R (3852) 5358 0 R (3853) 5359 0 R (3854) 5360 0 R (3857) 5361 0 R (3858) 5362 0 R (3859) 5363 0 R (386) 2229 0 R (3860) 5364 0 R (3861) 5370 0 R (3862) 5371 0 R (3863) 5372 0 R (3868) 5374 0 R (3869) 5375 0 R (3870) 5376 0 R (3871) 5377 0 R (3874) 5378 0 R (3875) 5379 0 R (3876) 5380 0 R (3882) 5384 0 R (3883) 5385 0 R (3884) 5386 0 R (3885) 5387 0 R (3886) 5388 0 R (389) 2234 0 R (3891) 5391 0 R (3892) 5392 0 R (3898) 5397 0 R (3899) 5398 0 R (39) 1959 0 R (3900) 5399 0 R (3901) 5400 0 R (3902) 5401 0 R (3903) 5402 0 R (3904) 5403 0 R (3907) 5405 0 R (3908) 5406 0 R (3910) 5408 0 R (3911) 5409 0 R (3913) 5410 0 R (3914) 5411 0 R (3915) 5412 0 R (3916) 5413 0 R (3918) 5414 0 R (3919) 5415 0 R (392) 2235 0 R (3920) 5416 0 R (3921) 5417 0 R (3922) 5418 0 R (3924) 5419 0 R (3925) 5420 0 R (3926) 5421 0 R (3927) 5422 0 R (393) 2236 0 R (3934) 5425 0 R (3935) 5426 0 R (3936) 5427 0 R (3939) 5428 0 R (3940) 5429 0 R (3942) 5435 0 R (3943) 5436 0 R (3944) 5437 0 R (3945) 5438 0 R (3949) 5440 0 R (3950) 5441 0 R (3951) 5442 0 R (3952) 5443 0 R (3953) 5444 0 R (3954) 5445 0 R (3955) 5446 0 R (3956) 5447 0 R (396) 2237 0 R (3962) 5449 0 R (3963) 5450 0 R (3967) 5452 0 R (3968) 5453 0 R (3969) 5454 0 R (3974) 5456 0 R (3975) 5457 0 R (3976) 5458 0 R (3978) 5463 0 R (3979) 5464 0 R (3980) 5465 0 R (3981) 5466 0 R (3982) 5467 0 R (3983) 5468 0 R (3984) 5469 0 R (3985) 5470 0 R (3986) 5471 0 R (3987) 5472 0 R (3988) 5473 0 R (3989) 5474 0 R (399) 2238 0 R (3990) 5475 0 R (3991) 5476 0 R (3996) 5479 0 R (3997) 5480 0 R (3998) 5481 0 R (4.0) 14 0 R (40) 1960 0 R (4002) 5483 0 R (4003) 5484 0 R (4008) 5487 0 R (4009) 5488 0 R (4010) 5489 0 R (4011) 5492 0 R (4012) 5490 0 R (4013) 5491 0 R (402) 2239 0 R (403) 2240 0 R (404) 2241 0 R (405) 2242 0 R (406) 2243 0 R (408) 2245 0 R (409) 2246 0 R (41) 1961 0 R (410) 2247 0 R (411) 2248 0 R (414) 2253 0 R (415) 2254 0 R (416) 2255 0 R (417) 2256 0 R (418) 2257 0 R (419) 2258 0 R (42) 1962 0 R (420) 2259 0 R (421) 2260 0 R (422) 2261 0 R (423) 2262 0 R (426) 2263 0 R (427) 2264 0 R (43) 1963 0 R (431) 2266 0 R (432) 2267 0 R (433) 2268 0 R (434) 2269 0 R (435) 2270 0 R (436) 2271 0 R (437) 2272 0 R (438) 2273 0 R (439) 2274 0 R (44) 1964 0 R (440) 2275 0 R (441) 2276 0 R (442) 2277 0 R (443) 2278 0 R (444) 2279 0 R (445) 2280 0 R (446) 2281 0 R (447) 2282 0 R (448) 2283 0 R (45) 1965 0 R (451) 2289 0 R (456) 2292 0 R (457) 2293 0 R (46) 1966 0 R (460) 2294 0 R (461) 2295 0 R (465) 2298 0 R (466) 2299 0 R (467) 2300 0 R (468) 2301 0 R (469) 2302 0 R (47) 1967 0 R (470) 2303 0 R (471) 2304 0 R (472) 2305 0 R (474) 2306 0 R (475) 2307 0 R (476) 2308 0 R (477) 2309 0 R (478) 2316 0 R (479) 2317 0 R (48) 1968 0 R (482) 2318 0 R (483) 2319 0 R (484) 2320 0 R (485) 2323 0 R (487) 2325 0 R (488) 2326 0 R (489) 2327 0 R (49) 1969 0 R (490) 2328 0 R (491) 2329 0 R (492) 2330 0 R (493) 2331 0 R (494) 2332 0 R (495) 2333 0 R (496) 2334 0 R (497) 2335 0 R (498) 2336 0 R (499) 2337 0 R (5.0) 18 0 R (5.1.1) 22 0 R (5.2.1) 26 0 R (5.3.1) 30 0 R (5.4.1) 34 0 R (5.5.1) 38 0 R (50) 1970 0 R (501) 2338 0 R (502) 2339 0 R (503) 2340 0 R (504) 2341 0 R (505) 2342 0 R (506) 2343 0 R (507) 2344 0 R (508) 2345 0 R (509) 2346 0 R (51) 1971 0 R (510) 2347 0 R (511) 2348 0 R (512) 2349 0 R (515) 2350 0 R (517) 2351 0 R (518) 2352 0 R (519) 2353 0 R (52) 1972 0 R (520) 2354 0 R (522) 2360 0 R (523) 2315 0 R (525) 2361 0 R (526) 2362 0 R (527) 2363 0 R (528) 2364 0 R (529) 2365 0 R (53) 1973 0 R (530) 2366 0 R (531) 2367 0 R (533) 2368 0 R (534) 2369 0 R (535) 2370 0 R (536) 2371 0 R (537) 2372 0 R (538) 2373 0 R (539) 2374 0 R (54) 1974 0 R (540) 2375 0 R (541) 2376 0 R (542) 2377 0 R (543) 2378 0 R (544) 2379 0 R (545) 1339 0 R (547) 2380 0 R (548) 2381 0 R (549) 2382 0 R (55) 1975 0 R (550) 2383 0 R (551) 2384 0 R (552) 2385 0 R (555) 2386 0 R (556) 2387 0 R (558) 2389 0 R (56) 1979 0 R (561) 2394 0 R (567) 2398 0 R (568) 2399 0 R (569) 2400 0 R (57) 1980 0 R (571) 2401 0 R (572) 2402 0 R (573) 2403 0 R (575) 2404 0 R (576) 2405 0 R (577) 2406 0 R (578) 2407 0 R (579) 2408 0 R (58) 1981 0 R (580) 2409 0 R (581) 2410 0 R (582) 2411 0 R (583) 2412 0 R (584) 2413 0 R (586) 2414 0 R (587) 2415 0 R (588) 2416 0 R (589) 2417 0 R (59) 1982 0 R (590) 2418 0 R (591) 2419 0 R (592) 2420 0 R (594) 2421 0 R (595) 2422 0 R (596) 2423 0 R (597) 2424 0 R (6.0) 42 0 R (6.10.1) 234 0 R (6.10.20.17.3) 242 0 R (6.10.20.18.3) 246 0 R (6.10.20.19.3) 250 0 R (6.10.20.2) 238 0 R (6.10.20.20.3) 254 0 R (6.10.20.21.3) 258 0 R (6.10.21.2) 262 0 R (6.10.21.22.3) 266 0 R (6.10.21.23.3) 270 0 R (6.10.22.2) 274 0 R (6.11.1) 278 0 R (6.11.23.2) 282 0 R (6.11.24.2) 286 0 R (6.11.24.24.10.4) 298 0 R (6.11.24.24.11.4) 302 0 R (6.11.24.24.3) 290 0 R (6.11.24.24.9.4) 294 0 R (6.11.25.2) 306 0 R (6.11.26.2) 310 0 R (6.11.26.25.3) 314 0 R (6.11.26.26.3) 318 0 R (6.11.27.2) 322 0 R (6.11.27.27.3) 326 0 R (6.11.28.2) 330 0 R (6.6.1) 46 0 R (6.6.1.2) 50 0 R (6.6.2.1.3) 58 0 R (6.6.2.2) 54 0 R (6.6.2.2.3) 62 0 R (6.6.3.2) 66 0 R (6.6.4.2) 70 0 R (6.6.5.10.3) 106 0 R (6.6.5.11.3) 110 0 R (6.6.5.2) 74 0 R (6.6.5.3.3) 78 0 R (6.6.5.4.3) 82 0 R (6.6.5.5.3) 86 0 R (6.6.5.6.3) 90 0 R (6.6.5.7.3) 94 0 R (6.6.5.8.3) 98 0 R (6.6.5.9.3) 102 0 R (6.6.6.2) 114 0 R (6.6.7.2) 118 0 R (6.7.1) 122 0 R (6.7.10.2) 170 0 R (6.7.11.15.3) 178 0 R (6.7.11.15.7.4) 182 0 R (6.7.11.15.8.4) 186 0 R (6.7.11.16.3) 190 0 R (6.7.11.2) 174 0 R (6.7.12.2) 194 0 R (6.7.8.2) 126 0 R (6.7.9.12.3) 134 0 R (6.7.9.13.1.4) 142 0 R (6.7.9.13.2.4) 146 0 R (6.7.9.13.3) 138 0 R (6.7.9.13.3.4) 150 0 R (6.7.9.13.4.4) 154 0 R (6.7.9.14.3) 158 0 R (6.7.9.14.5.4) 162 0 R (6.7.9.14.6.4) 166 0 R (6.7.9.2) 130 0 R (6.8.1) 198 0 R (6.8.13.2) 202 0 R (6.8.14.2) 206 0 R (6.8.15.2) 210 0 R (6.8.16.2) 214 0 R (6.8.17.2) 218 0 R (6.8.18.2) 222 0 R (6.8.19.2) 226 0 R (6.9.1) 230 0 R (601) 2426 0 R (602) 2427 0 R (603) 2428 0 R (605) 2429 0 R (606) 2430 0 R (607) 2431 0 R (609) 2436 0 R (610) 2437 0 R (611) 2438 0 R (612) 2439 0 R (613) 2440 0 R (614) 2441 0 R (615) 2442 0 R (616) 2443 0 R (617) 2444 0 R (619) 2445 0 R (62) 1983 0 R (620) 2446 0 R (621) 2447 0 R (622) 2448 0 R (623) 2449 0 R (624) 2450 0 R (625) 2451 0 R (626) 2452 0 R (627) 2453 0 R (628) 2454 0 R (629) 2455 0 R (63) 1984 0 R (630) 2456 0 R (631) 2457 0 R (632) 2458 0 R (633) 2459 0 R (634) 2460 0 R (635) 2461 0 R (636) 2462 0 R (637) 2463 0 R (638) 2464 0 R (639) 2465 0 R (640) 2466 0 R (641) 2467 0 R (645) 2468 0 R (646) 2469 0 R (647) 2470 0 R (648) 2475 0 R (649) 2476 0 R (65) 1985 0 R (650) 2477 0 R (651) 2478 0 R (652) 2479 0 R (653) 2480 0 R (654) 2481 0 R (655) 2482 0 R (656) 2483 0 R (657) 2484 0 R (658) 2485 0 R (659) 2486 0 R (66) 1986 0 R (660) 2487 0 R (661) 2488 0 R (662) 2489 0 R (663) 2490 0 R (664) 2491 0 R (665) 2492 0 R (666) 2493 0 R (667) 2494 0 R (668) 2495 0 R (669) 2496 0 R (67) 1987 0 R (670) 2497 0 R (671) 2498 0 R (675) 2500 0 R (676) 2501 0 R (678) 2503 0 R (679) 2504 0 R (68) 1988 0 R (680) 2505 0 R (681) 2506 0 R (683) 2508 0 R (684) 2509 0 R (685) 2510 0 R (686) 2511 0 R (687) 2516 0 R (688) 2517 0 R (689) 2518 0 R (690) 2519 0 R (694) 2521 0 R (695) 1345 0 R (697) 2522 0 R (698) 2523 0 R (699) 2524 0 R (7.0) 334 0 R (7.12.1) 338 0 R (7.13.1) 342 0 R (7.13.29.2) 346 0 R (7.13.30.2) 350 0 R (7.13.30.28.3) 354 0 R (7.13.30.29.12.4) 362 0 R (7.13.30.29.13.4) 366 0 R (7.13.30.29.3) 358 0 R (7.13.30.30.3) 370 0 R (7.13.30.31.3) 374 0 R (7.13.30.32.3) 378 0 R (7.14.1) 382 0 R (7.15.1) 386 0 R (7.16.1) 390 0 R (7.17.1) 394 0 R (7.18.1) 398 0 R (7.19.1) 402 0 R (7.19.31.2) 406 0 R (7.19.32.2) 410 0 R (7.19.32.33.3) 414 0 R (7.19.33.2) 418 0 R (7.19.34.2) 422 0 R (7.19.34.34.3) 426 0 R (7.19.34.35.3) 430 0 R (7.19.35.2) 434 0 R (7.19.35.36.14.4) 442 0 R (7.19.35.36.15.4) 446 0 R (7.19.35.36.16.4) 450 0 R (7.19.35.36.17.4) 454 0 R (7.19.35.36.18.4) 458 0 R (7.19.35.36.19.4) 462 0 R (7.19.35.36.20.4) 466 0 R (7.19.35.36.21.4) 470 0 R (7.19.35.36.22.4) 474 0 R (7.19.35.36.23.4) 478 0 R (7.19.35.36.24.4) 482 0 R (7.19.35.36.3) 438 0 R (7.19.35.37.3) 486 0 R (7.19.35.38.3) 490 0 R (7.20.1) 494 0 R (7.20.36.2) 498 0 R (7.20.37.2) 502 0 R (7.20.38.2) 506 0 R (7.21.1) 510 0 R (7.21.39.2) 514 0 R (7.21.40.2) 518 0 R (7.22.1) 522 0 R (7.23.1) 526 0 R (7.24.1) 530 0 R (7.24.41.2) 534 0 R (7.24.42.2) 538 0 R (7.24.43.2) 542 0 R (7.24.44.2) 546 0 R (7.24.44.39.3) 550 0 R (7.24.44.40.3) 554 0 R (7.24.44.41.3) 558 0 R (7.25.1) 562 0 R (7.25.45.2) 566 0 R (7.25.46.2) 570 0 R (7.25.47.2) 574 0 R (7.25.47.42.3) 578 0 R (7.25.47.43.3) 582 0 R (7.25.47.44.3) 586 0 R (7.25.48.2) 590 0 R (70) 1989 0 R (700) 2525 0 R (701) 2528 0 R (702) 2529 0 R (703) 2530 0 R (704) 2531 0 R (705) 2532 0 R (706) 2533 0 R (707) 2534 0 R (708) 2535 0 R (709) 2536 0 R (71) 1990 0 R (710) 2537 0 R (711) 2538 0 R (712) 2539 0 R (713) 2540 0 R (714) 1346 0 R (716) 2541 0 R (717) 2542 0 R (718) 2543 0 R (719) 2544 0 R (72) 1991 0 R (720) 2545 0 R (721) 2546 0 R (722) 2547 0 R (723) 2548 0 R (724) 2549 0 R (725) 2555 0 R (726) 2556 0 R (727) 2557 0 R (728) 2558 0 R (729) 2559 0 R (73) 1992 0 R (732) 2560 0 R (733) 2561 0 R (734) 2562 0 R (735) 2563 0 R (736) 2564 0 R (737) 2565 0 R (740) 2566 0 R (742) 2568 0 R (743) 2569 0 R (744) 2570 0 R (745) 2571 0 R (746) 2572 0 R (747) 2573 0 R (748) 2574 0 R (75) 1993 0 R (751) 2579 0 R (752) 2580 0 R (753) 2581 0 R (754) 2582 0 R (755) 2583 0 R (756) 2584 0 R (757) 2585 0 R (758) 2586 0 R (759) 2587 0 R (76) 1994 0 R (760) 2588 0 R (761) 2589 0 R (764) 2590 0 R (765) 2591 0 R (766) 2592 0 R (767) 2593 0 R (768) 2594 0 R (77) 1995 0 R (771) 2596 0 R (772) 2597 0 R (773) 2598 0 R (776) 2600 0 R (777) 2601 0 R (778) 2602 0 R (779) 2603 0 R (78) 1996 0 R (780) 2604 0 R (781) 2605 0 R (782) 2606 0 R (785) 2608 0 R (786) 2609 0 R (787) 2610 0 R (788) 2611 0 R (789) 2612 0 R (790) 2613 0 R (791) 2619 0 R (792) 2620 0 R (793) 2621 0 R (794) 2622 0 R (797) 2624 0 R (798) 2625 0 R (799) 2626 0 R (8.0) 594 0 R (8.26.1) 598 0 R (8.26.49.2) 602 0 R (8.26.50.2) 606 0 R (8.26.51.2) 610 0 R (8.27.1) 614 0 R (8.27.52.2) 618 0 R (8.27.53.2) 622 0 R (8.27.54.2) 626 0 R (8.28.1) 630 0 R (8.28.55.2) 634 0 R (8.28.56.2) 638 0 R (8.29.1) 642 0 R (8.29.57.2) 646 0 R (80) 1997 0 R (800) 2627 0 R (803) 2629 0 R (804) 2630 0 R (805) 2631 0 R (806) 2632 0 R (809) 2634 0 R (81) 1998 0 R (810) 2635 0 R (811) 2636 0 R (812) 2637 0 R (815) 2639 0 R (816) 2640 0 R (817) 2641 0 R (818) 2642 0 R (82) 1999 0 R (821) 2643 0 R (822) 2644 0 R (823) 2645 0 R (824) 2646 0 R (825) 2647 0 R (826) 2648 0 R (827) 2649 0 R (828) 2650 0 R (829) 2651 0 R (83) 2000 0 R (830) 2652 0 R (831) 2653 0 R (832) 2654 0 R (833) 1450 0 R (835) 2659 0 R (836) 2660 0 R (837) 2661 0 R (838) 2662 0 R (839) 2663 0 R (840) 2664 0 R (841) 2665 0 R (842) 2666 0 R (843) 2667 0 R (844) 2668 0 R (845) 2669 0 R (846) 2670 0 R (847) 2671 0 R (848) 2672 0 R (849) 2673 0 R (85) 2001 0 R (852) 2674 0 R (853) 2675 0 R (854) 2676 0 R (857) 2677 0 R (86) 2002 0 R (860) 2678 0 R (861) 2679 0 R (862) 2680 0 R (865) 2685 0 R (868) 2688 0 R (869) 2689 0 R (87) 2003 0 R (870) 2690 0 R (871) 2691 0 R (872) 2692 0 R (873) 2693 0 R (874) 2694 0 R (875) 2695 0 R (876) 2696 0 R (877) 2697 0 R (88) 2004 0 R (880) 2698 0 R (883) 2699 0 R (886) 2702 0 R (887) 2703 0 R (888) 2704 0 R (889) 2705 0 R (892) 2706 0 R (896) 2712 0 R (899) 2713 0 R (9.0) 650 0 R (9.30.1) 654 0 R (9.31.1) 658 0 R (9.32.1) 662 0 R (9.33.1) 666 0 R (9.34.1) 670 0 R (9.34.58.2) 674 0 R (9.34.58.45.3) 678 0 R (9.34.58.46.3) 682 0 R (9.34.58.47.3) 686 0 R (9.34.59.2) 690 0 R (9.34.60.2) 694 0 R (9.34.61.2) 698 0 R (9.35.1) 702 0 R (9.35.62.2) 706 0 R (9.35.63.2) 710 0 R (9.36.1) 714 0 R (9.36.64.2) 718 0 R (9.36.64.48.3) 722 0 R (9.36.64.49.3) 726 0 R (9.36.64.50.3) 730 0 R (9.36.64.51.3) 734 0 R (9.36.64.52.3) 738 0 R (9.36.64.53.3) 742 0 R (9.36.64.54.3) 746 0 R (9.37.1) 750 0 R (9.37.65.2) 754 0 R (9.37.66.2) 758 0 R (9.37.67.2) 762 0 R (9.38.1) 766 0 R (9.39.1) 770 0 R (9.39.68.2) 774 0 R (9.39.69.2) 778 0 R (9.39.70.2) 782 0 R (9.39.71.2) 786 0 R (9.40.1) 790 0 R (9.40.72.2) 794 0 R (9.40.73.2) 798 0 R (9.40.73.55.3) 802 0 R (9.40.73.56.3) 806 0 R (9.41.1) 810 0 R (9.42.1) 814 0 R (9.42.74.2) 818 0 R (9.42.75.2) 822 0 R (9.42.76.2) 826 0 R (9.42.77.2) 830 0 R (90) 2005 0 R (900) 2714 0 R (901) 2715 0 R (905) 2717 0 R (906) 2718 0 R (907) 2719 0 R (908) 2720 0 R (909) 2721 0 R (91) 2006 0 R (910) 2722 0 R (912) 2724 0 R (913) 2725 0 R (914) 2726 0 R (915) 2727 0 R (916) 2728 0 R (917) 2729 0 R (918) 2730 0 R (919) 2731 0 R (92) 2007 0 R (920) 2732 0 R (921) 2733 0 R (922) 2734 0 R (923) 2735 0 R (927) 2738 0 R (928) 2739 0 R (93) 2008 0 R (930) 2740 0 R (932) 2741 0 R (935) 2748 0 R (936) 2749 0 R (937) 2750 0 R (938) 2751 0 R (939) 2752 0 R (940) 2753 0 R (941) 2754 0 R (942) 2755 0 R (943) 2756 0 R (944) 2757 0 R (945) 2758 0 R (946) 2759 0 R (948) 2760 0 R (949) 2761 0 R (95) 2009 0 R (950) 2762 0 R (951) 2763 0 R (955) 1463 0 R (957) 2764 0 R (959) 1464 0 R (96) 2010 0 R (961) 2766 0 R (962) 2767 0 R (963) 2768 0 R (964) 2769 0 R (965) 2770 0 R (966) 2771 0 R (967) 1465 0 R (969) 2772 0 R (97) 2011 0 R (971) 2773 0 R (972) 2774 0 R (973) 2779 0 R (975) 2780 0 R (976) 2781 0 R (977) 2782 0 R (978) 2783 0 R (98) 2012 0 R (980) 2784 0 R (981) 2785 0 R (982) 2786 0 R (983) 2787 0 R (984) 2788 0 R (985) 2789 0 R (986) 2790 0 R (987) 2791 0 R (988) 2792 0 R (989) 2793 0 R (99) 2013 0 R (990) 2794 0 R (991) 2795 0 R (992) 2796 0 R (993) 2801 0 R (994) 1466 0 R (996) 2802 0 R (997) 2803 0 R (998) 2804 0 R (999) 2805 0 R (Doc-Start) 1198 0 R (about) 1307 0 R (accountpreferences) 1768 0 R (add-custom-fields) 1601 0 R (administration) 1473 0 R (apache-addtype) 1351 0 R (attachments) 1753 0 R (bonsai) 1886 0 R (boolean) 1743 0 R (bug_page) 1642 0 R (bugreports) 1750 0 R (bzldap) 1350 0 R (charts) 1774 0 R (classifications) 1483 0 R (cloningbugs) 1752 0 R (cmdline) 1903 0 R (cmdline-bugmail) 1904 0 R (commenting) 1764 0 R (components) 1485 0 R (configuration) 1333 0 R (conventions) 1312 0 R (copyright) 1308 0 R (createnewusers) 1479 0 R (credits) 1311 0 R (cust-change-permissions) 1884 0 R (cust-hooks) 1883 0 R (cust-skins) 1784 0 R (cust-templates) 1785 0 R (custom-fields) 1600 0 R (customization) 1783 0 R (cvs) 1887 0 R (database-engine) 1335 0 R (database-schema) 1336 0 R (defaultuser) 1476 0 R (delete-custom-fields) 1603 0 R (dependencytree) 1765 0 R (disclaimer) 1309 0 R (edit-custom-fields) 1602 0 R (edit-values) 1604 0 R (edit-values-delete) 1606 0 R (edit-values-list) 1605 0 R (emailpreferences) 1770 0 R (extraconfig) 1344 0 R (faq) 1891 0 R (faq-admin) 4636 0 R (faq-admin-cvsupdate) 4642 0 R (faq-admin-enable-unconfirmed) 4667 0 R (faq-admin-livebackup) 4640 0 R (faq-admin-midair) 4638 0 R (faq-admin-moving) 4675 0 R (faq-db) 4775 0 R (faq-db-corrupted) 4776 0 R (faq-db-manualedit) 4781 0 R (faq-db-permissions) 4788 0 R (faq-db-synchronize) 4816 0 R (faq-email) 4706 0 R (faq-email-mailif) 4746 0 R (faq-email-nomail) 4708 0 R (faq-email-nonreceived) 4761 0 R (faq-email-sendmailnow) 4748 0 R (faq-email-testing) 4711 0 R (faq-email-whine) 4740 0 R (faq-general) 4486 0 R (faq-general-bonsaitools) 4532 0 R (faq-general-bzmissing) 4510 0 R (faq-general-companies) 4498 0 R (faq-general-compare) 4506 0 R (faq-general-cookie) 4564 0 R (faq-general-license) 4491 0 R (faq-general-maintainers) 4503 0 R (faq-general-mysql) 4522 0 R (faq-general-perlpath) 4537 0 R (faq-general-selinux) 4570 0 R (faq-general-support) 4494 0 R (faq-general-tryout) 4488 0 R (faq-hacking) 4895 0 R (faq-hacking-bugzillabugs) 4906 0 R (faq-hacking-patches) 4919 0 R (faq-hacking-priority) 4912 0 R (faq-hacking-templatestyle) 4897 0 R (faq-mod-perl) 4566 0 R (faq-nt) 4821 0 R (faq-nt-bundle) 4829 0 R (faq-nt-dbi) 4844 0 R (faq-nt-easiest) 4823 0 R (faq-nt-mappings) 4831 0 R (faq-phb) 4577 0 R (faq-phb-backup) 4616 0 R (faq-phb-client) 4578 0 R (faq-phb-cost) 4625 0 R (faq-phb-data) 4596 0 R (faq-phb-email) 4589 0 R (faq-phb-emailapp) 4591 0 R (faq-phb-installtime) 4623 0 R (faq-phb-l10n) 4610 0 R (faq-phb-maintenance) 4619 0 R (faq-phb-priorities) 4580 0 R (faq-phb-renameBugs) 4633 0 R (faq-phb-reporting) 4584 0 R (faq-phb-reports) 4614 0 R (faq-security) 4695 0 R (faq-security-knownproblems) 4704 0 R (faq-security-mysql) 4697 0 R (faq-use) 4860 0 R (faq-use-accept) 4872 0 R (faq-use-attachment) 4881 0 R (faq-use-changeaddress) 4862 0 R (faq-use-close) 4887 0 R (faq-use-keyword) 4884 0 R (faq-use-query) 4864 0 R (fillingbugs) 1751 0 R (flag-askto) 1492 0 R (flag-type-attachment) 1494 0 R (flag-type-bug) 1495 0 R (flag-types) 1493 0 R (flag-values) 1491 0 R (flags) 1777 0 R (flags-about) 1490 0 R (flags-admin) 1496 0 R (flags-create) 1597 0 R (flags-create-field-active) 3285 0 R (flags-create-field-category) 3249 0 R (flags-create-field-cclist) 3308 0 R (flags-create-field-description) 3207 0 R (flags-create-field-multiplicable) 3303 0 R (flags-create-field-name) 3240 0 R (flags-create-field-requestable) 3293 0 R (flags-create-field-sortkey) 3281 0 R (flags-create-field-specific) 3300 0 R (flags-create-grant-group) 3310 0 R (flags-create-request-group) 3315 0 R (flags-delete) 1598 0 R (flags-edit) 1599 0 R (flags-overview) 1488 0 R (flags-simpleexample) 1489 0 R (general-advice) 1893 0 R (generalpreferences) 1769 0 R (gfdl) 1909 0 R (gfdl-0) 1910 0 R (gfdl-1) 1911 0 R (gfdl-10) 1920 0 R (gfdl-2) 1912 0 R (gfdl-3) 1913 0 R (gfdl-4) 1914 0 R (gfdl-5) 1915 0 R (gfdl-6) 1916 0 R (gfdl-7) 1917 0 R (gfdl-8) 1918 0 R (gfdl-9) 1919 0 R (gfdl-howto) 1921 0 R (gloss-a) 5292 0 R (gloss-apache) 5293 0 R (gloss-b) 5332 0 R (gloss-bugzilla) 2041 0 R (gloss-c) 5348 0 R (gloss-cgi) 2103 0 R (gloss-component) 5353 0 R (gloss-contrib) 2614 0 R (gloss-cpan) 2743 0 R (gloss-d) 5373 0 R (gloss-daemon) 3643 0 R (gloss-dos) 3775 0 R (gloss-g) 5382 0 R (gloss-groups) 5383 0 R (gloss-htaccess) 3750 0 R (gloss-j) 5389 0 R (gloss-javascript) 5390 0 R (gloss-m) 5369 0 R (gloss-mta) 4770 0 R (gloss-mysql) 5404 0 R (gloss-p) 5424 0 R (gloss-ppm) 2707 0 R (gloss-product) 3115 0 R (gloss-q) 5439 0 R (gloss-r) 5448 0 R (gloss-rdbms) 5430 0 R (gloss-regexp) 5451 0 R (gloss-s) 5455 0 R (gloss-service) 3644 0 R (gloss-t) 5477 0 R (gloss-target-milestone) 5478 0 R (gloss-tcl) 5482 0 R (gloss-z) 5485 0 R (gloss-zarro) 5486 0 R (glossary) 1922 0 R (groups) 1609 0 R (hintsandtips) 1762 0 R (http) 1340 0 R (http-apache) 1341 0 R (http-apache-mod_cgi) 2397 0 R (http-apache-mod_perl) 2425 0 R (http-iis) 1342 0 R (impersonatingusers) 1482 0 R (index) 1199 0 R (individual-buglists) 1749 0 R (install-MTA) 1331 0 R (install-bzfiles) 1320 0 R (install-config-bugzilla) 1343 0 R (install-database) 1316 0 R (install-modules-chart-base) 1325 0 R (install-modules-dbd-mysql) 1322 0 R (install-modules-gd) 1324 0 R (install-modules-gd-graph) 1326 0 R (install-modules-gd-text) 1327 0 R (install-modules-patchreader) 1330 0 R (install-modules-soap-lite) 1329 0 R (install-modules-template) 1323 0 R (install-modules-xml-twig) 1328 0 R (install-mysql) 1317 0 R (install-perl) 1315 0 R (install-perlmodules) 1321 0 R (install-perlmodules-manual) 1905 0 R (install-perlmodules-nonroot) 1467 0 R (install-pg) 1318 0 R (install-setupdatabase) 2297 0 R (install-setupdatabase-adduser) 2288 0 R (install-webserver) 1319 0 R (installation) 1314 0 R (installation-whining) 1348 0 R (installation-whining-cron) 1347 0 R (installing-bugzilla) 1313 0 R (integration) 1885 0 R (lifecycle) 1643 0 R (lifecycle-image) 1939 0 R (list) 1748 0 R (localconfig) 1334 0 R (macosx-libraries) 1460 0 R (macosx-sendmail) 1459 0 R (manageusers) 1477 0 R (milestones) 1487 0 R (modifyusers) 1480 0 R (modules-manual-download) 1907 0 R (modules-manual-instructions) 1906 0 R (modules-manual-optional) 1908 0 R (multiplecharts) 1746 0 R (myaccount) 1641 0 R (mysql) 1337 0 R (negation) 1745 0 R (newversions) 1310 0 R (nonroot) 1462 0 R (os-macosx) 1458 0 R (os-mandrake) 1461 0 R (os-specific) 1451 0 R (os-win32) 1452 0 R (page.1) 1197 0 R (page.10) 2252 0 R (page.100) 4968 0 R (page.101) 4993 0 R (page.102) 5016 0 R (page.103) 5033 0 R (page.104) 5077 0 R (page.105) 5104 0 R (page.106) 5135 0 R (page.107) 5165 0 R (page.108) 5190 0 R (page.109) 5206 0 R (page.11) 2287 0 R (page.110) 5217 0 R (page.111) 5254 0 R (page.112) 5266 0 R (page.113) 5279 0 R (page.114) 5286 0 R (page.115) 5336 0 R (page.116) 5368 0 R (page.117) 5396 0 R (page.118) 5434 0 R (page.119) 5462 0 R (page.12) 2314 0 R (page.13) 2359 0 R (page.14) 2393 0 R (page.15) 2435 0 R (page.16) 2474 0 R (page.17) 2515 0 R (page.18) 2554 0 R (page.19) 2578 0 R (page.2) 1206 0 R (page.20) 2618 0 R (page.21) 2658 0 R (page.22) 2684 0 R (page.23) 2711 0 R (page.24) 2747 0 R (page.25) 2778 0 R (page.26) 2800 0 R (page.27) 2827 0 R (page.28) 2850 0 R (page.29) 2877 0 R (page.3) 1212 0 R (page.30) 2896 0 R (page.31) 2930 0 R (page.32) 2957 0 R (page.33) 2980 0 R (page.34) 3011 0 R (page.35) 3065 0 R (page.36) 3088 0 R (page.37) 3119 0 R (page.38) 3160 0 R (page.39) 3206 0 R (page.4) 1355 0 R (page.40) 3244 0 R (page.41) 3289 0 R (page.42) 3322 0 R (page.43) 3357 0 R (page.44) 3385 0 R (page.45) 3412 0 R (page.46) 3451 0 R (page.47) 3481 0 R (page.48) 3501 0 R (page.49) 3518 0 R (page.5) 1500 0 R (page.50) 3548 0 R (page.51) 3582 0 R (page.52) 3611 0 R (page.53) 3617 0 R (page.54) 3648 0 R (page.55) 3677 0 R (page.56) 3754 0 R (page.57) 3779 0 R (page.58) 3808 0 R (page.59) 3858 0 R (page.6) 1647 0 R (page.60) 3891 0 R (page.61) 3901 0 R (page.62) 3936 0 R (page.63) 3956 0 R (page.64) 3986 0 R (page.65) 4008 0 R (page.66) 4026 0 R (page.67) 4040 0 R (page.68) 4058 0 R (page.69) 4094 0 R (page.7) 1792 0 R (page.70) 4131 0 R (page.71) 4147 0 R (page.72) 4165 0 R (page.73) 4184 0 R (page.74) 4202 0 R (page.75) 4213 0 R (page.76) 4241 0 R (page.77) 4273 0 R (page.78) 4301 0 R (page.79) 4339 0 R (page.8) 1926 0 R (page.80) 4361 0 R (page.81) 4391 0 R (page.82) 4427 0 R (page.83) 4446 0 R (page.84) 4465 0 R (page.85) 4483 0 R (page.86) 4515 0 R (page.87) 4541 0 R (page.88) 4576 0 R (page.89) 4602 0 R (page.9) 2233 0 R (page.90) 4630 0 R (page.91) 4664 0 R (page.92) 4693 0 R (page.93) 4725 0 R (page.94) 4774 0 R (page.95) 4808 0 R (page.96) 4840 0 R (page.97) 4876 0 R (page.98) 4903 0 R (page.99) 4941 0 R (param-LDAPBaseDN) 2628 0 R (param-LDAPbinddn) 2623 0 R (param-LDAPmailattribute) 2638 0 R (param-LDAPserver) 2607 0 R (param-LDAPuidattribute) 2633 0 R (param-user_verify_class) 2599 0 R (parameters) 1474 0 R (paranoid-security) 1897 0 R (patch-viewer) 1349 0 R (patches) 1902 0 R (patchviewer) 1754 0 R (patchviewer_bonsai_lxr) 1760 0 R (patchviewer_collapse) 1758 0 R (patchviewer_context) 1757 0 R (patchviewer_diff) 1756 0 R (patchviewer_link) 1759 0 R (patchviewer_unified_diff) 1761 0 R (patchviewer_view) 1755 0 R (permissionsettings) 1771 0 R (postgresql) 1338 0 R (products) 1484 0 R (pronouns) 1744 0 R (query) 1742 0 R (quicksearch) 1747 0 R (quips) 1608 0 R (reporting) 1772 0 R (reports) 1773 0 R (scm) 1888 0 R (security) 1625 0 R (security-bugzilla) 1637 0 R (security-bugzilla-charset) 1638 0 R (security-mysql) 1630 0 R (security-mysql-account) 1631 0 R (security-mysql-account-anonymous) 1941 0 R (security-mysql-account-root) 1940 0 R (security-mysql-network) 1633 0 R (security-mysql-network-ex) 1942 0 R (security-mysql-root) 1632 0 R (security-os) 1626 0 R (security-os-accounts) 1628 0 R (security-os-chroot) 1629 0 R (security-os-ports) 1627 0 R (security-webserver) 1634 0 R (security-webserver-access) 1635 0 R (security-webserver-mod-throttle) 1636 0 R (self-registration) 2987 0 R (svn) 1889 0 R (table.1) 2035 0 R (table.2) 3817 0 R (table.3) 3870 0 R (table.4) 3951 0 R (table.5) 4018 0 R (table.6) 4036 0 R (table.7) 4073 0 R (table.8) 4381 0 R (table.9) 4880 0 R (template-directory) 1786 0 R (template-edit) 1788 0 R (template-formats) 1880 0 R (template-http-accept) 1882 0 R (template-method) 1787 0 R (template-specific) 1881 0 R (timetracking) 1766 0 R (tinderbox) 1890 0 R (trbl-dbdSponge) 1896 0 R (trbl-index) 1900 0 R (trbl-passwd-encryption) 1901 0 R (trbl-perlmodule) 1895 0 R (trbl-relogin-everyone) 1898 0 R (trbl-relogin-everyone-restrict) 1944 0 R (trbl-relogin-everyone-share) 1943 0 R (trbl-relogin-some) 1899 0 R (trbl-testserver) 1894 0 R (troubleshooting) 1892 0 R (upgrade-cvs) 1621 0 R (upgrade-patches) 1623 0 R (upgrade-tarball) 1622 0 R (upgrading) 1617 0 R (upgrading-completion) 1624 0 R (upgrading-methods) 1620 0 R (upgrading-notifications) 1619 0 R (upgrading-version-defns) 1618 0 R (user-account-creation) 2993 0 R (user-account-deletion) 1481 0 R (user-account-search) 1478 0 R (useradmin) 1475 0 R (userpreferences) 1767 0 R (using) 1639 0 R (using-intro) 1640 0 R (using-mod_perl-with-bugzilla) 1332 0 R (versions) 1486 0 R (voting) 1607 0 R (whining) 1778 0 R (whining-overview) 1779 0 R (whining-query) 1781 0 R (whining-schedule) 1780 0 R (win32-code-changes) 1455 0 R (win32-email) 1457 0 R (win32-http) 1456 0 R (win32-perl) 1453 0 R (win32-perl-modules) 1454 0 R] /Limits [(1.0) (win32-perl-modules)] >> endobj -5326 0 obj << -/Kids [5325 0 R] +5502 0 obj << +/Kids [5501 0 R] >> endobj -5327 0 obj << -/Dests 5326 0 R +5503 0 obj << +/Dests 5502 0 R >> endobj -5328 0 obj << +5504 0 obj << /Type /Catalog -/Pages 5323 0 R -/Outlines 5324 0 R -/Names 5327 0 R +/Pages 5499 0 R +/Outlines 5500 0 R +/Names 5503 0 R /PageMode /UseOutlines /URI<</Base()>> /ViewerPreferences<<>> -/OpenAction 1165 0 R +/OpenAction 1193 0 R /PTEX.Fullbanner (This is pdfTeX, Version 3.14159-1.10b) >> endobj -5329 0 obj << +5505 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.10b)/Keywords() -/CreationDate (D:20070823120500) +/CreationDate (D:20070509155900) >> endobj xref -0 5330 -0000001172 65535 f +0 5506 +0000001200 65535 f 0000000009 00000 n -0000027327 00000 n -0001006518 00000 n +0000027994 00000 n +0001034395 00000 n 0000000048 00000 n -0000000099 00000 n -0000100083 00000 n -0001006433 00000 n -0000000138 00000 n -0000000173 00000 n -0000386856 00000 n -0001006346 00000 n -0000000212 00000 n -0000000246 00000 n -0000386918 00000 n -0001006257 00000 n -0000000286 00000 n -0000000321 00000 n -0000390109 00000 n -0001006131 00000 n -0000000361 00000 n -0000000407 00000 n -0000390234 00000 n -0001006057 00000 n -0000000449 00000 n -0000000494 00000 n -0000390611 00000 n -0001005970 00000 n -0000000536 00000 n -0000000570 00000 n -0000390925 00000 n -0001005883 00000 n -0000000612 00000 n -0000000648 00000 n -0000394975 00000 n -0001005796 00000 n -0000000690 00000 n -0000000721 00000 n -0000399808 00000 n -0001005722 00000 n -0000000763 00000 n -0000000807 00000 n -0000404476 00000 n -0001005594 00000 n -0000000847 00000 n -0000000896 00000 n -0000404601 00000 n -0001005481 00000 n -0000000938 00000 n -0000000974 00000 n -0000405923 00000 n -0001005407 00000 n -0000001018 00000 n -0000001048 00000 n -0000408784 00000 n -0001005283 00000 n -0000001092 00000 n -0000001133 00000 n -0000408972 00000 n -0001005209 00000 n -0000001179 00000 n -0000001212 00000 n -0000409667 00000 n -0001005135 00000 n -0000001258 00000 n -0000001296 00000 n -0000410108 00000 n -0001005048 00000 n -0000001340 00000 n -0000001376 00000 n -0000414441 00000 n -0001004961 00000 n -0000001420 00000 n -0000001454 00000 n -0000415202 00000 n -0001004835 00000 n -0000001498 00000 n -0000001536 00000 n -0000423439 00000 n -0001004761 00000 n -0000001582 00000 n -0000001620 00000 n -0000425883 00000 n -0001004674 00000 n -0000001666 00000 n -0000001719 00000 n -0000426071 00000 n -0001004587 00000 n -0000001765 00000 n -0000001804 00000 n -0000426765 00000 n -0001004500 00000 n -0000001850 00000 n -0000001897 00000 n -0000426952 00000 n -0001004413 00000 n -0000001943 00000 n -0000001988 00000 n -0000427139 00000 n -0001004324 00000 n -0000002034 00000 n -0000002086 00000 n -0000427327 00000 n -0001004233 00000 n -0000002133 00000 n -0000002179 00000 n -0000430733 00000 n -0001004155 00000 n -0000002227 00000 n -0000002277 00000 n -0000430922 00000 n -0001004078 00000 n -0000002322 00000 n -0000002376 00000 n -0000431613 00000 n -0001003948 00000 n -0000002419 00000 n -0000002457 00000 n -0000431866 00000 n -0001003869 00000 n -0000002502 00000 n -0000002540 00000 n -0000436880 00000 n -0001003737 00000 n -0000002585 00000 n -0000002627 00000 n -0000437069 00000 n -0001003658 00000 n -0000002675 00000 n -0000002728 00000 n -0000437322 00000 n -0001003526 00000 n -0000002776 00000 n -0000002810 00000 n -0000437575 00000 n -0001003447 00000 n -0000002860 00000 n -0000002914 00000 n -0000441186 00000 n -0001003354 00000 n -0000002964 00000 n -0000003032 00000 n -0000441689 00000 n -0001003261 00000 n -0000003082 00000 n -0000003132 00000 n -0000442832 00000 n -0001003182 00000 n -0000003182 00000 n -0000003256 00000 n -0000446490 00000 n -0001003064 00000 n -0000003304 00000 n -0000003343 00000 n -0000446742 00000 n -0001002985 00000 n -0000003393 00000 n -0000003448 00000 n -0000447690 00000 n -0001002906 00000 n -0000003498 00000 n -0000003549 00000 n -0000452510 00000 n -0001002813 00000 n -0000003594 00000 n -0000003634 00000 n -0000453016 00000 n -0001002681 00000 n -0000003680 00000 n -0000003717 00000 n -0000453332 00000 n -0001002602 00000 n -0000003766 00000 n -0000003807 00000 n -0000458416 00000 n -0001002523 00000 n -0000003856 00000 n -0000003924 00000 n -0000463850 00000 n -0001002444 00000 n -0000003970 00000 n -0000004005 00000 n -0000464861 00000 n -0001002313 00000 n -0000004048 00000 n -0000004106 00000 n -0000465049 00000 n -0001002234 00000 n -0000004152 00000 n -0000004189 00000 n -0000468669 00000 n -0001002141 00000 n -0000004235 00000 n -0000004279 00000 n -0000469678 00000 n -0001002048 00000 n -0000004325 00000 n -0000004368 00000 n -0000473520 00000 n -0001001955 00000 n -0000004414 00000 n -0000004448 00000 n -0000474151 00000 n -0001001862 00000 n -0000004494 00000 n -0000004533 00000 n -0000474973 00000 n -0001001769 00000 n -0000004579 00000 n -0000004625 00000 n -0000483045 00000 n -0001001690 00000 n -0000004671 00000 n -0000004748 00000 n -0000483931 00000 n -0001001598 00000 n -0000004791 00000 n -0000004870 00000 n -0000488079 00000 n -0001001467 00000 n -0000004914 00000 n -0000004968 00000 n -0000488395 00000 n -0001001349 00000 n -0000005015 00000 n -0000005059 00000 n -0000488583 00000 n -0001001270 00000 n -0000005109 00000 n -0000005148 00000 n -0000488900 00000 n -0001001177 00000 n -0000005198 00000 n -0000005248 00000 n -0000492722 00000 n -0001001084 00000 n -0000005298 00000 n -0000005364 00000 n -0000492910 00000 n -0001000991 00000 n -0000005414 00000 n -0000005464 00000 n -0000493352 00000 n -0001000912 00000 n -0000005514 00000 n -0000005556 00000 n -0000493541 00000 n -0001000780 00000 n -0000005603 00000 n -0000005638 00000 n -0000493726 00000 n -0001000701 00000 n -0000005688 00000 n -0000005725 00000 n -0000494042 00000 n -0001000622 00000 n -0000005775 00000 n -0000005843 00000 n -0000498326 00000 n -0001000543 00000 n -0000005890 00000 n -0000005934 00000 n -0000501873 00000 n -0001000426 00000 n -0000005978 00000 n -0000006038 00000 n -0000501999 00000 n -0001000347 00000 n -0000006085 00000 n -0000006124 00000 n -0000502187 00000 n -0001000215 00000 n -0000006171 00000 n -0000006203 00000 n -0000502694 00000 n -0001000111 00000 n +0000000096 00000 n +0000100634 00000 n +0001034310 00000 n +0000000135 00000 n +0000000170 00000 n +0000395006 00000 n +0001034223 00000 n +0000000209 00000 n +0000000243 00000 n +0000395068 00000 n +0001034134 00000 n +0000000283 00000 n +0000000318 00000 n +0000398257 00000 n +0001034008 00000 n +0000000358 00000 n +0000000404 00000 n +0000398382 00000 n +0001033934 00000 n +0000000446 00000 n +0000000491 00000 n +0000398759 00000 n +0001033847 00000 n +0000000533 00000 n +0000000567 00000 n +0000399073 00000 n +0001033760 00000 n +0000000609 00000 n +0000000645 00000 n +0000403123 00000 n +0001033673 00000 n +0000000687 00000 n +0000000718 00000 n +0000407956 00000 n +0001033599 00000 n +0000000760 00000 n +0000000804 00000 n +0000412623 00000 n +0001033471 00000 n +0000000844 00000 n +0000000893 00000 n +0000412748 00000 n +0001033358 00000 n +0000000935 00000 n +0000000971 00000 n +0000414070 00000 n +0001033284 00000 n +0000001015 00000 n +0000001045 00000 n +0000416936 00000 n +0001033160 00000 n +0000001089 00000 n +0000001130 00000 n +0000417124 00000 n +0001033086 00000 n +0000001176 00000 n +0000001209 00000 n +0000417819 00000 n +0001033012 00000 n +0000001255 00000 n +0000001293 00000 n +0000418260 00000 n +0001032925 00000 n +0000001337 00000 n +0000001373 00000 n +0000422593 00000 n +0001032838 00000 n +0000001417 00000 n +0000001451 00000 n +0000423354 00000 n +0001032712 00000 n +0000001495 00000 n +0000001533 00000 n +0000434940 00000 n +0001032638 00000 n +0000001579 00000 n +0000001617 00000 n +0000435190 00000 n +0001032551 00000 n +0000001663 00000 n +0000001716 00000 n +0000435378 00000 n +0001032464 00000 n +0000001762 00000 n +0000001801 00000 n +0000436071 00000 n +0001032377 00000 n +0000001847 00000 n +0000001894 00000 n +0000436259 00000 n +0001032290 00000 n +0000001940 00000 n +0000001985 00000 n +0000439253 00000 n +0001032201 00000 n +0000002031 00000 n +0000002076 00000 n +0000439378 00000 n +0001032110 00000 n +0000002123 00000 n +0000002169 00000 n +0000439631 00000 n +0001032018 00000 n +0000002217 00000 n +0000002264 00000 n +0000439820 00000 n +0001031940 00000 n +0000002312 00000 n +0000002362 00000 n +0000440009 00000 n +0001031849 00000 n +0000002407 00000 n +0000002461 00000 n +0000443926 00000 n +0001031771 00000 n +0000002506 00000 n +0000002563 00000 n +0000444688 00000 n +0001031641 00000 n +0000002606 00000 n +0000002644 00000 n +0000444941 00000 n +0001031562 00000 n +0000002689 00000 n +0000002727 00000 n +0000449363 00000 n +0001031430 00000 n +0000002772 00000 n +0000002814 00000 n +0000449552 00000 n +0001031351 00000 n +0000002862 00000 n +0000002915 00000 n +0000449805 00000 n +0001031219 00000 n +0000002963 00000 n +0000002997 00000 n +0000450058 00000 n +0001031140 00000 n +0000003047 00000 n +0000003101 00000 n +0000450625 00000 n +0001031047 00000 n +0000003151 00000 n +0000003219 00000 n +0000454256 00000 n +0001030954 00000 n +0000003269 00000 n +0000003319 00000 n +0000455397 00000 n +0001030875 00000 n +0000003369 00000 n +0000003443 00000 n +0000456284 00000 n +0001030757 00000 n +0000003491 00000 n +0000003530 00000 n +0000456410 00000 n +0001030678 00000 n +0000003580 00000 n +0000003635 00000 n +0000460342 00000 n +0001030599 00000 n +0000003685 00000 n +0000003736 00000 n +0000461227 00000 n +0001030506 00000 n +0000003782 00000 n +0000003822 00000 n +0000461729 00000 n +0001030374 00000 n +0000003868 00000 n +0000003905 00000 n +0000465405 00000 n +0001030256 00000 n +0000003954 00000 n +0000004004 00000 n +0000465594 00000 n +0001030177 00000 n +0000004055 00000 n +0000004110 00000 n +0000467429 00000 n +0001030098 00000 n +0000004161 00000 n +0000004217 00000 n +0000473351 00000 n +0001030019 00000 n +0000004266 00000 n +0000004334 00000 n +0000479088 00000 n +0001029940 00000 n +0000004380 00000 n +0000004415 00000 n +0000482713 00000 n +0001029809 00000 n +0000004458 00000 n +0000004516 00000 n +0000482901 00000 n +0001029730 00000 n +0000004562 00000 n +0000004599 00000 n +0000484096 00000 n +0001029637 00000 n +0000004645 00000 n +0000004689 00000 n +0000487822 00000 n +0001029544 00000 n +0000004735 00000 n +0000004778 00000 n +0000488326 00000 n +0001029451 00000 n +0000004824 00000 n +0000004858 00000 n +0000492647 00000 n +0001029358 00000 n +0000004904 00000 n +0000004943 00000 n +0000493470 00000 n +0001029265 00000 n +0000004989 00000 n +0000005035 00000 n +0000498653 00000 n +0001029186 00000 n +0000005081 00000 n +0000005158 00000 n +0000502541 00000 n +0001029094 00000 n +0000005201 00000 n +0000005280 00000 n +0000503619 00000 n +0001028963 00000 n +0000005324 00000 n +0000005378 00000 n +0000503935 00000 n +0001028845 00000 n +0000005425 00000 n +0000005469 00000 n +0000504124 00000 n +0001028766 00000 n +0000005519 00000 n +0000005558 00000 n +0000507757 00000 n +0001028673 00000 n +0000005608 00000 n +0000005658 00000 n +0000508576 00000 n +0001028580 00000 n +0000005708 00000 n +0000005774 00000 n +0000508763 00000 n +0001028487 00000 n +0000005824 00000 n +0000005874 00000 n +0000509203 00000 n +0001028408 00000 n +0000005924 00000 n +0000005966 00000 n +0000512771 00000 n +0001028276 00000 n +0000006013 00000 n +0000006048 00000 n +0000512960 00000 n +0001028197 00000 n +0000006098 00000 n +0000006135 00000 n +0000513276 00000 n +0001028118 00000 n +0000006185 00000 n 0000006253 00000 n -0000006306 00000 n -0000502820 00000 n -0001000032 00000 n -0000006358 00000 n -0000006420 00000 n -0000505378 00000 n -0000999939 00000 n -0000006472 00000 n -0000006526 00000 n -0000505694 00000 n -0000999860 00000 n -0000006578 00000 n -0000006628 00000 n -0000506708 00000 n -0000999767 00000 n -0000006675 00000 n -0000006706 00000 n -0000509735 00000 n -0000999635 00000 n -0000006753 00000 n -0000006792 00000 n -0000509923 00000 n -0000999556 00000 n -0000006842 00000 n -0000006893 00000 n -0000510746 00000 n -0000999477 00000 n -0000006943 00000 n -0000006988 00000 n -0000517679 00000 n -0000999345 00000 n -0000007035 00000 n -0000007073 00000 n -0000517868 00000 n -0000999280 00000 n -0000007123 00000 n -0000007177 00000 n -0000518436 00000 n -0000999201 00000 n -0000007224 00000 n -0000007259 00000 n -0000523589 00000 n -0000999068 00000 n -0000007300 00000 n -0000007353 00000 n -0000523715 00000 n -0000998989 00000 n -0000007397 00000 n -0000007444 00000 n -0000533924 00000 n -0000998857 00000 n -0000007488 00000 n -0000007532 00000 n -0000534049 00000 n -0000998778 00000 n -0000007579 00000 n -0000007631 00000 n -0000537326 00000 n -0000998660 00000 n -0000007678 00000 n -0000007725 00000 n -0000537452 00000 n -0000998581 00000 n -0000007775 00000 n -0000007832 00000 n -0000537957 00000 n -0000998449 00000 n -0000007882 00000 n -0000007929 00000 n -0000538083 00000 n -0000998370 00000 n -0000007982 00000 n -0000008029 00000 n -0000538461 00000 n -0000998291 00000 n -0000008082 00000 n -0000008149 00000 n -0000543050 00000 n -0000998198 00000 n -0000008199 00000 n -0000008243 00000 n -0000549373 00000 n -0000998105 00000 n -0000008293 00000 n -0000008336 00000 n -0000549625 00000 n -0000998026 00000 n -0000008386 00000 n -0000008434 00000 n -0000550319 00000 n -0000997933 00000 n -0000008478 00000 n -0000008518 00000 n -0000553837 00000 n -0000997840 00000 n -0000008562 00000 n -0000008595 00000 n -0000554656 00000 n -0000997747 00000 n -0000008639 00000 n -0000008674 00000 n -0000557947 00000 n -0000997654 00000 n -0000008718 00000 n -0000008751 00000 n -0000558639 00000 n -0000997561 00000 n -0000008795 00000 n -0000008830 00000 n -0000559581 00000 n -0000997429 00000 n -0000008874 00000 n -0000008904 00000 n -0000562080 00000 n -0000997350 00000 n -0000008951 00000 n -0000008994 00000 n -0000563471 00000 n -0000997218 00000 n -0000009041 00000 n -0000009079 00000 n -0000563597 00000 n -0000997153 00000 n -0000009129 00000 n -0000009164 00000 n -0000567541 00000 n -0000997060 00000 n -0000009211 00000 n -0000009257 00000 n -0000568237 00000 n -0000996928 00000 n -0000009304 00000 n -0000009349 00000 n -0000568426 00000 n -0000996849 00000 n -0000009399 00000 n -0000009444 00000 n -0000569751 00000 n -0000996770 00000 n -0000009494 00000 n -0000009532 00000 n -0000573291 00000 n -0000996652 00000 n -0000009579 00000 n -0000009625 00000 n -0000573735 00000 n -0000996533 00000 n -0000009675 00000 n -0000009719 00000 n -0000573985 00000 n -0000996454 00000 n -0000009772 00000 n -0000009807 00000 n -0000574174 00000 n -0000996361 00000 n -0000009860 00000 n -0000009902 00000 n -0000574491 00000 n -0000996268 00000 n -0000009955 00000 n -0000009994 00000 n -0000579236 00000 n -0000996175 00000 n -0000010047 00000 n -0000010086 00000 n -0000579551 00000 n -0000996082 00000 n -0000010139 00000 n -0000010176 00000 n -0000579803 00000 n -0000995989 00000 n -0000010229 00000 n -0000010271 00000 n -0000580311 00000 n -0000995896 00000 n -0000010324 00000 n -0000010379 00000 n -0000580563 00000 n -0000995803 00000 n -0000010432 00000 n -0000010476 00000 n -0000580944 00000 n -0000995710 00000 n -0000010529 00000 n -0000010567 00000 n -0000581133 00000 n -0000995617 00000 n -0000010620 00000 n -0000010663 00000 n -0000584017 00000 n -0000995538 00000 n -0000010716 00000 n -0000010761 00000 n -0000584269 00000 n -0000995445 00000 n -0000010811 00000 n -0000010855 00000 n -0000584903 00000 n -0000995366 00000 n -0000010905 00000 n -0000010948 00000 n -0000585218 00000 n -0000995234 00000 n -0000010992 00000 n -0000011029 00000 n -0000585469 00000 n -0000995155 00000 n -0000011076 00000 n -0000011131 00000 n -0000585846 00000 n -0000995076 00000 n -0000011178 00000 n -0000011226 00000 n -0000589501 00000 n -0000994983 00000 n -0000011270 00000 n -0000011302 00000 n -0000590631 00000 n -0000994890 00000 n -0000011346 00000 n -0000011377 00000 n -0000594277 00000 n -0000994758 00000 n -0000011421 00000 n -0000011472 00000 n -0000595100 00000 n -0000994679 00000 n -0000011519 00000 n -0000011562 00000 n -0000599228 00000 n -0000994586 00000 n -0000011609 00000 n -0000011662 00000 n -0000599858 00000 n -0000994493 00000 n -0000011709 00000 n -0000011773 00000 n -0000602661 00000 n -0000994375 00000 n -0000011820 00000 n -0000011885 00000 n -0000602787 00000 n -0000994296 00000 n -0000011935 00000 n -0000012004 00000 n -0000602975 00000 n -0000994203 00000 n -0000012054 00000 n -0000012127 00000 n -0000603227 00000 n -0000994124 00000 n -0000012177 00000 n -0000012242 00000 n -0000606945 00000 n -0000994006 00000 n -0000012286 00000 n -0000012337 00000 n -0000607447 00000 n -0000993927 00000 n -0000012384 00000 n -0000012431 00000 n -0000612027 00000 n -0000993795 00000 n -0000012478 00000 n -0000012537 00000 n -0000613037 00000 n -0000993716 00000 n -0000012587 00000 n -0000012636 00000 n -0000616663 00000 n -0000993623 00000 n -0000012686 00000 n -0000012743 00000 n -0000621021 00000 n -0000993544 00000 n -0000012793 00000 n -0000012846 00000 n -0000622032 00000 n -0000993465 00000 n -0000012893 00000 n -0000012944 00000 n -0000626081 00000 n -0000993332 00000 n -0000012985 00000 n -0000013033 00000 n -0000626397 00000 n -0000993214 00000 n -0000013077 00000 n -0000013118 00000 n -0000626522 00000 n -0000993135 00000 n -0000013165 00000 n -0000013204 00000 n -0000626711 00000 n -0000993042 00000 n -0000013251 00000 n -0000013298 00000 n -0000627855 00000 n -0000992963 00000 n -0000013345 00000 n -0000013387 00000 n -0000630684 00000 n -0000992831 00000 n -0000013431 00000 n -0000013461 00000 n -0000630810 00000 n -0000992752 00000 n -0000013508 00000 n -0000013559 00000 n -0000630998 00000 n -0000992659 00000 n -0000013606 00000 n -0000013667 00000 n -0000632322 00000 n -0000992580 00000 n -0000013714 00000 n -0000013755 00000 n -0000635629 00000 n -0000992448 00000 n -0000013799 00000 n -0000013834 00000 n -0000635755 00000 n -0000992369 00000 n -0000013881 00000 n -0000013963 00000 n -0000643503 00000 n -0000992290 00000 n -0000014010 00000 n -0000014071 00000 n -0000644074 00000 n -0000992172 00000 n -0000014115 00000 n -0000014148 00000 n -0000644200 00000 n -0000992107 00000 n -0000014195 00000 n -0000014266 00000 n -0000647534 00000 n -0000991973 00000 n -0000014307 00000 n -0000014352 00000 n -0000647660 00000 n -0000991894 00000 n -0000014396 00000 n -0000014433 00000 n -0000647911 00000 n -0000991801 00000 n -0000014477 00000 n -0000014527 00000 n -0000648921 00000 n -0000991708 00000 n -0000014571 00000 n -0000014612 00000 n -0000709678 00000 n -0000991615 00000 n -0000014656 00000 n -0000014700 00000 n -0000710120 00000 n -0000991483 00000 n -0000014744 00000 n -0000014787 00000 n -0000713245 00000 n -0000991365 00000 n -0000014834 00000 n -0000014875 00000 n -0000714442 00000 n -0000991286 00000 n -0000014925 00000 n -0000014974 00000 n -0000714631 00000 n -0000991193 00000 n -0000015024 00000 n -0000015061 00000 n -0000718786 00000 n -0000991114 00000 n -0000015111 00000 n -0000015155 00000 n -0000719291 00000 n -0000991021 00000 n -0000015202 00000 n -0000015240 00000 n -0000719735 00000 n -0000990928 00000 n -0000015287 00000 n -0000015323 00000 n -0000723495 00000 n -0000990849 00000 n -0000015370 00000 n -0000015434 00000 n -0000724065 00000 n -0000990717 00000 n -0000015478 00000 n -0000015514 00000 n -0000724191 00000 n -0000990638 00000 n -0000015561 00000 n -0000015607 00000 n -0000729225 00000 n -0000990559 00000 n -0000015654 00000 n -0000015702 00000 n -0000729541 00000 n -0000990427 00000 n -0000015746 00000 n -0000015782 00000 n -0000733132 00000 n -0000990323 00000 n -0000015829 00000 n -0000015868 00000 n -0000733508 00000 n -0000990244 00000 n -0000015918 00000 n -0000015978 00000 n -0000733696 00000 n -0000990151 00000 n -0000016028 00000 n -0000016098 00000 n -0000733885 00000 n -0000990058 00000 n -0000016148 00000 n -0000016208 00000 n -0000734074 00000 n -0000989965 00000 n -0000016258 00000 n -0000016331 00000 n -0000736324 00000 n -0000989872 00000 n -0000016381 00000 n -0000016441 00000 n -0000736513 00000 n -0000989779 00000 n -0000016491 00000 n -0000016543 00000 n -0000736765 00000 n -0000989700 00000 n -0000016593 00000 n -0000016645 00000 n -0000736954 00000 n -0000989568 00000 n -0000016689 00000 n -0000016728 00000 n -0000737143 00000 n -0000989489 00000 n -0000016775 00000 n -0000016819 00000 n -0000740454 00000 n -0000989396 00000 n -0000016866 00000 n -0000016901 00000 n -0000740706 00000 n -0000989317 00000 n -0000016948 00000 n -0000016990 00000 n -0000741019 00000 n -0000989224 00000 n -0000017034 00000 n +0000517548 00000 n +0001028039 00000 n +0000006300 00000 n +0000006344 00000 n +0000518681 00000 n +0001027922 00000 n +0000006388 00000 n +0000006448 00000 n +0000518807 00000 n +0001027843 00000 n +0000006495 00000 n +0000006534 00000 n +0000518994 00000 n +0001027711 00000 n +0000006581 00000 n +0000006613 00000 n +0000519502 00000 n +0001027607 00000 n +0000006663 00000 n +0000006716 00000 n +0000519628 00000 n +0001027528 00000 n +0000006768 00000 n +0000006830 00000 n +0000521690 00000 n +0001027435 00000 n +0000006883 00000 n +0000006937 00000 n +0000522006 00000 n +0001027356 00000 n +0000006990 00000 n +0000007040 00000 n +0000525204 00000 n +0001027263 00000 n +0000007087 00000 n +0000007118 00000 n +0000526210 00000 n +0001027131 00000 n +0000007165 00000 n +0000007204 00000 n +0000526399 00000 n +0001027052 00000 n +0000007254 00000 n +0000007305 00000 n +0000529235 00000 n +0001026973 00000 n +0000007355 00000 n +0000007400 00000 n +0000533624 00000 n +0001026841 00000 n +0000007447 00000 n +0000007485 00000 n +0000533812 00000 n +0001026776 00000 n +0000007535 00000 n +0000007589 00000 n +0000536803 00000 n +0001026697 00000 n +0000007636 00000 n +0000007671 00000 n +0000540492 00000 n +0001026564 00000 n +0000007712 00000 n +0000007765 00000 n +0000540618 00000 n +0001026485 00000 n +0000007809 00000 n +0000007856 00000 n +0000550878 00000 n +0001026353 00000 n +0000007900 00000 n +0000007944 00000 n +0000551003 00000 n +0001026274 00000 n +0000007991 00000 n +0000008043 00000 n +0000554166 00000 n +0001026156 00000 n +0000008090 00000 n +0000008137 00000 n +0000554292 00000 n +0001026077 00000 n +0000008187 00000 n +0000008244 00000 n +0000554796 00000 n +0001025945 00000 n +0000008294 00000 n +0000008341 00000 n +0000554922 00000 n +0001025866 00000 n +0000008394 00000 n +0000008441 00000 n +0000555300 00000 n +0001025787 00000 n +0000008494 00000 n +0000008561 00000 n +0000556119 00000 n +0001025694 00000 n +0000008611 00000 n +0000008655 00000 n +0000566538 00000 n +0001025601 00000 n +0000008705 00000 n +0000008748 00000 n +0000566790 00000 n +0001025522 00000 n +0000008798 00000 n +0000008846 00000 n +0000567484 00000 n +0001025429 00000 n +0000008890 00000 n +0000008930 00000 n +0000571037 00000 n +0001025336 00000 n +0000008974 00000 n +0000009007 00000 n +0000571856 00000 n +0001025243 00000 n +0000009051 00000 n +0000009086 00000 n +0000572675 00000 n +0001025150 00000 n +0000009130 00000 n +0000009163 00000 n +0000576077 00000 n +0001025057 00000 n +0000009207 00000 n +0000009242 00000 n +0000577018 00000 n +0001024925 00000 n +0000009286 00000 n +0000009316 00000 n +0000577398 00000 n +0001024846 00000 n +0000009363 00000 n +0000009406 00000 n +0000581515 00000 n +0001024714 00000 n +0000009453 00000 n +0000009491 00000 n +0000581641 00000 n +0001024649 00000 n +0000009541 00000 n +0000009576 00000 n +0000582902 00000 n +0001024556 00000 n +0000009623 00000 n +0000009669 00000 n +0000586217 00000 n +0001024424 00000 n +0000009716 00000 n +0000009761 00000 n +0000586406 00000 n +0001024345 00000 n +0000009811 00000 n +0000009856 00000 n +0000587732 00000 n +0001024266 00000 n +0000009906 00000 n +0000009944 00000 n +0000588173 00000 n +0001024148 00000 n +0000009991 00000 n +0000010037 00000 n +0000588616 00000 n +0001024029 00000 n +0000010087 00000 n +0000010131 00000 n +0000591929 00000 n +0001023950 00000 n +0000010184 00000 n +0000010219 00000 n +0000592055 00000 n +0001023857 00000 n +0000010272 00000 n +0000010314 00000 n +0000592372 00000 n +0001023764 00000 n +0000010367 00000 n +0000010406 00000 n +0000594467 00000 n +0001023671 00000 n +0000010459 00000 n +0000010498 00000 n +0000597264 00000 n +0001023578 00000 n +0000010551 00000 n +0000010588 00000 n +0000597516 00000 n +0001023485 00000 n +0000010641 00000 n +0000010683 00000 n +0000598023 00000 n +0001023392 00000 n +0000010736 00000 n +0000010791 00000 n +0000598275 00000 n +0001023299 00000 n +0000010844 00000 n +0000010888 00000 n +0000598656 00000 n +0001023206 00000 n +0000010941 00000 n +0000010979 00000 n +0000598845 00000 n +0001023113 00000 n +0000011032 00000 n +0000011075 00000 n +0000599226 00000 n +0001023034 00000 n +0000011128 00000 n +0000011173 00000 n +0000602622 00000 n +0001022941 00000 n +0000011223 00000 n +0000011267 00000 n +0000603129 00000 n +0001022862 00000 n +0000011317 00000 n +0000011360 00000 n +0000603445 00000 n +0001022730 00000 n +0000011404 00000 n +0000011442 00000 n +0000603698 00000 n +0001022651 00000 n +0000011489 00000 n +0000011536 00000 n +0000608421 00000 n +0001022558 00000 n +0000011583 00000 n +0000011631 00000 n +0000608610 00000 n +0001022479 00000 n +0000011678 00000 n +0000011727 00000 n +0000608797 00000 n +0001022347 00000 n +0000011771 00000 n +0000011809 00000 n +0000609050 00000 n +0001022268 00000 n +0000011856 00000 n +0000011912 00000 n +0000609429 00000 n +0001022189 00000 n +0000011959 00000 n +0000012008 00000 n +0000613068 00000 n +0001022096 00000 n +0000012052 00000 n +0000012084 00000 n +0000614199 00000 n +0001022003 00000 n +0000012128 00000 n +0000012159 00000 n +0000617845 00000 n +0001021871 00000 n +0000012203 00000 n +0000012254 00000 n +0000618668 00000 n +0001021792 00000 n +0000012301 00000 n +0000012344 00000 n +0000622796 00000 n +0001021699 00000 n +0000012391 00000 n +0000012444 00000 n +0000623426 00000 n +0001021606 00000 n +0000012491 00000 n +0000012555 00000 n +0000626229 00000 n +0001021488 00000 n +0000012602 00000 n +0000012667 00000 n +0000626355 00000 n +0001021409 00000 n +0000012717 00000 n +0000012786 00000 n +0000626543 00000 n +0001021316 00000 n +0000012836 00000 n +0000012909 00000 n +0000626795 00000 n +0001021237 00000 n +0000012959 00000 n +0000013024 00000 n +0000630365 00000 n +0001021119 00000 n +0000013068 00000 n +0000013119 00000 n +0000630867 00000 n +0001021040 00000 n +0000013166 00000 n +0000013213 00000 n +0000635739 00000 n +0001020947 00000 n +0000013260 00000 n +0000013311 00000 n +0000636118 00000 n +0001020815 00000 n +0000013358 00000 n +0000013417 00000 n +0000637128 00000 n +0001020736 00000 n +0000013467 00000 n +0000013516 00000 n +0000640576 00000 n +0001020643 00000 n +0000013566 00000 n +0000013623 00000 n +0000644965 00000 n +0001020564 00000 n +0000013673 00000 n +0000013726 00000 n +0000645977 00000 n +0001020485 00000 n +0000013773 00000 n +0000013824 00000 n +0000650971 00000 n +0001020352 00000 n +0000013865 00000 n +0000013913 00000 n +0000651287 00000 n +0001020234 00000 n +0000013957 00000 n +0000013998 00000 n +0000651412 00000 n +0001020155 00000 n +0000014045 00000 n +0000014084 00000 n +0000651601 00000 n +0001020062 00000 n +0000014131 00000 n +0000014178 00000 n +0000652745 00000 n +0001019983 00000 n +0000014225 00000 n +0000014267 00000 n +0000655575 00000 n +0001019851 00000 n +0000014311 00000 n +0000014341 00000 n +0000655701 00000 n +0001019772 00000 n +0000014388 00000 n +0000014439 00000 n +0000655889 00000 n +0001019679 00000 n +0000014486 00000 n +0000014547 00000 n +0000657213 00000 n +0001019600 00000 n +0000014594 00000 n +0000014635 00000 n +0000660520 00000 n +0001019468 00000 n +0000014679 00000 n +0000014714 00000 n +0000660646 00000 n +0001019389 00000 n +0000014761 00000 n +0000014843 00000 n +0000668393 00000 n +0001019310 00000 n +0000014890 00000 n +0000014951 00000 n +0000668964 00000 n +0001019192 00000 n +0000014995 00000 n +0000015028 00000 n +0000669090 00000 n +0001019127 00000 n +0000015075 00000 n +0000015146 00000 n +0000672472 00000 n +0001018993 00000 n +0000015187 00000 n +0000015232 00000 n +0000672598 00000 n +0001018914 00000 n +0000015276 00000 n +0000015313 00000 n +0000672849 00000 n +0001018821 00000 n +0000015357 00000 n +0000015407 00000 n +0000678189 00000 n +0001018728 00000 n +0000015451 00000 n +0000015492 00000 n +0000685276 00000 n +0001018635 00000 n +0000015536 00000 n +0000015580 00000 n +0000736934 00000 n +0001018503 00000 n +0000015624 00000 n +0000015667 00000 n +0000739894 00000 n +0001018385 00000 n +0000015714 00000 n +0000015755 00000 n +0000741093 00000 n +0001018306 00000 n +0000015805 00000 n +0000015854 00000 n +0000741281 00000 n +0001018213 00000 n +0000015904 00000 n +0000015941 00000 n +0000745466 00000 n +0001018134 00000 n +0000015991 00000 n +0000016035 00000 n +0000745972 00000 n +0001018041 00000 n +0000016082 00000 n +0000016120 00000 n +0000746414 00000 n +0001017948 00000 n +0000016167 00000 n +0000016203 00000 n +0000750490 00000 n +0001017869 00000 n +0000016250 00000 n +0000016310 00000 n +0000750996 00000 n +0001017737 00000 n +0000016354 00000 n +0000016390 00000 n +0000751122 00000 n +0001017658 00000 n +0000016437 00000 n +0000016483 00000 n +0000756302 00000 n +0001017579 00000 n +0000016530 00000 n +0000016578 00000 n +0000756617 00000 n +0001017447 00000 n +0000016622 00000 n +0000016658 00000 n +0000760331 00000 n +0001017343 00000 n +0000016705 00000 n +0000016744 00000 n +0000760708 00000 n +0001017264 00000 n +0000016794 00000 n +0000016854 00000 n +0000760896 00000 n +0001017171 00000 n +0000016904 00000 n +0000016974 00000 n +0000761080 00000 n +0001017078 00000 n +0000017024 00000 n 0000017084 00000 n -0000741588 00000 n -0000989092 00000 n -0000017128 00000 n -0000017170 00000 n -0000741777 00000 n -0000989013 00000 n -0000017217 00000 n -0000017264 00000 n -0000745060 00000 n -0000988920 00000 n -0000017311 00000 n -0000017358 00000 n -0000746069 00000 n -0000988827 00000 n -0000017405 00000 n -0000017450 00000 n -0000752175 00000 n -0000988748 00000 n -0000017497 00000 n -0000017536 00000 n -0000752364 00000 n -0000988616 00000 n -0000017580 00000 n -0000017624 00000 n -0000755637 00000 n -0000988537 00000 n -0000017671 00000 n -0000017706 00000 n -0000756015 00000 n -0000988419 00000 n -0000017753 00000 n -0000017787 00000 n -0000756518 00000 n -0000988340 00000 n -0000017837 00000 n -0000017882 00000 n -0000759977 00000 n -0000988261 00000 n -0000017932 00000 n -0000017984 00000 n -0000760229 00000 n -0000988168 00000 n -0000018028 00000 n -0000018059 00000 n -0000764249 00000 n -0000988050 00000 n -0000018103 00000 n -0000018136 00000 n -0000764877 00000 n -0000987971 00000 n -0000018183 00000 n -0000018220 00000 n -0000765191 00000 n -0000987878 00000 n -0000018267 00000 n -0000018311 00000 n -0000769215 00000 n -0000987785 00000 n -0000018358 00000 n -0000018401 00000 n -0000771245 00000 n -0000987706 00000 n -0000018448 00000 n -0000018495 00000 n -0000774613 00000 n -0000987573 00000 n -0000018537 00000 n -0000018588 00000 n -0000774738 00000 n -0000987455 00000 n -0000018633 00000 n -0000018680 00000 n -0000774990 00000 n -0000987376 00000 n -0000018728 00000 n -0000018783 00000 n -0000775751 00000 n -0000987283 00000 n -0000018831 00000 n -0000018889 00000 n -0000780784 00000 n -0000987190 00000 n -0000018937 00000 n -0000018985 00000 n -0000785113 00000 n -0000987097 00000 n -0000019033 00000 n -0000019086 00000 n -0000786312 00000 n -0000987004 00000 n -0000019134 00000 n -0000019181 00000 n -0000795688 00000 n -0000986925 00000 n -0000019229 00000 n -0000019306 00000 n -0000796258 00000 n -0000986832 00000 n -0000019351 00000 n -0000019390 00000 n -0000806634 00000 n -0000986700 00000 n -0000019435 00000 n -0000019491 00000 n -0000810461 00000 n -0000986635 00000 n -0000019539 00000 n -0000019597 00000 n -0000814308 00000 n -0000986542 00000 n -0000019642 00000 n -0000019696 00000 n -0000815003 00000 n -0000986424 00000 n -0000019741 00000 n -0000019808 00000 n -0000815129 00000 n -0000986345 00000 n -0000019856 00000 n -0000019889 00000 n -0000815318 00000 n -0000986252 00000 n -0000019937 00000 n -0000019967 00000 n -0000815950 00000 n -0000986159 00000 n -0000020015 00000 n -0000020054 00000 n -0000817485 00000 n -0000986066 00000 n -0000020102 00000 n -0000020139 00000 n -0000817738 00000 n -0000985987 00000 n -0000020187 00000 n -0000020234 00000 n -0000820858 00000 n -0000985893 00000 n -0000020276 00000 n -0000020324 00000 n -0000886715 00000 n -0000985759 00000 n -0000020366 00000 n -0000020413 00000 n -0000886904 00000 n -0000985680 00000 n -0000020458 00000 n -0000020497 00000 n -0000887600 00000 n -0000985587 00000 n -0000020542 00000 n -0000020617 00000 n -0000888041 00000 n -0000985494 00000 n -0000020662 00000 n -0000020758 00000 n -0000890547 00000 n -0000985401 00000 n -0000020803 00000 n -0000020858 00000 n -0000891176 00000 n -0000985308 00000 n -0000020903 00000 n -0000020961 00000 n -0000894135 00000 n -0000985215 00000 n +0000763461 00000 n +0001016985 00000 n +0000017134 00000 n +0000017207 00000 n +0000763650 00000 n +0001016892 00000 n +0000017257 00000 n +0000017317 00000 n +0000763839 00000 n +0001016799 00000 n +0000017367 00000 n +0000017419 00000 n +0000764091 00000 n +0001016720 00000 n +0000017469 00000 n +0000017521 00000 n +0000764280 00000 n +0001016588 00000 n +0000017565 00000 n +0000017604 00000 n +0000764469 00000 n +0001016509 00000 n +0000017651 00000 n +0000017695 00000 n +0000767538 00000 n +0001016416 00000 n +0000017742 00000 n +0000017777 00000 n +0000767789 00000 n +0001016337 00000 n +0000017824 00000 n +0000017866 00000 n +0000768103 00000 n +0001016244 00000 n +0000017910 00000 n +0000017960 00000 n +0000768672 00000 n +0001016112 00000 n +0000018004 00000 n +0000018046 00000 n +0000771800 00000 n +0001016033 00000 n +0000018093 00000 n +0000018140 00000 n +0000772117 00000 n +0001015940 00000 n +0000018187 00000 n +0000018234 00000 n +0000773125 00000 n +0001015847 00000 n +0000018281 00000 n +0000018326 00000 n +0000779359 00000 n +0001015768 00000 n +0000018373 00000 n +0000018412 00000 n +0000782398 00000 n +0001015636 00000 n +0000018456 00000 n +0000018500 00000 n +0000782587 00000 n +0001015557 00000 n +0000018547 00000 n +0000018582 00000 n +0000783028 00000 n +0001015439 00000 n +0000018629 00000 n +0000018663 00000 n +0000786582 00000 n +0001015360 00000 n +0000018713 00000 n +0000018758 00000 n +0000787023 00000 n +0001015281 00000 n +0000018808 00000 n +0000018860 00000 n +0000787275 00000 n +0001015188 00000 n +0000018904 00000 n +0000018935 00000 n +0000791264 00000 n +0001015070 00000 n +0000018979 00000 n +0000019012 00000 n +0000791893 00000 n +0001014991 00000 n +0000019059 00000 n +0000019096 00000 n +0000795741 00000 n +0001014898 00000 n +0000019143 00000 n +0000019187 00000 n +0000796371 00000 n +0001014805 00000 n +0000019234 00000 n +0000019278 00000 n +0000798731 00000 n +0001014726 00000 n +0000019325 00000 n +0000019372 00000 n +0000801816 00000 n +0001014593 00000 n +0000019414 00000 n +0000019465 00000 n +0000801942 00000 n +0001014514 00000 n +0000019510 00000 n +0000019547 00000 n +0000802763 00000 n +0001014382 00000 n +0000019592 00000 n +0000019639 00000 n +0000803014 00000 n +0001014303 00000 n +0000019687 00000 n +0000019742 00000 n +0000806961 00000 n +0001014210 00000 n +0000019790 00000 n +0000019848 00000 n +0000808610 00000 n +0001014117 00000 n +0000019896 00000 n +0000019944 00000 n +0000812827 00000 n +0001014024 00000 n +0000019992 00000 n +0000020045 00000 n +0000817888 00000 n +0001013931 00000 n +0000020093 00000 n +0000020140 00000 n +0000823318 00000 n +0001013852 00000 n +0000020188 00000 n +0000020265 00000 n +0000823887 00000 n +0001013759 00000 n +0000020310 00000 n +0000020367 00000 n +0000837777 00000 n +0001013666 00000 n +0000020412 00000 n +0000020468 00000 n +0000842215 00000 n +0001013548 00000 n +0000020513 00000 n +0000020580 00000 n +0000842341 00000 n +0001013469 00000 n +0000020628 00000 n +0000020661 00000 n +0000842530 00000 n +0001013376 00000 n +0000020709 00000 n +0000020739 00000 n +0000845070 00000 n +0001013283 00000 n +0000020787 00000 n +0000020826 00000 n +0000845513 00000 n +0001013190 00000 n +0000020874 00000 n +0000020911 00000 n +0000845766 00000 n +0001013111 00000 n +0000020959 00000 n 0000021006 00000 n -0000021081 00000 n -0000894640 00000 n -0000985122 00000 n -0000021126 00000 n -0000021198 00000 n -0000898605 00000 n -0000985029 00000 n -0000021243 00000 n -0000021317 00000 n -0000900885 00000 n -0000984936 00000 n -0000021362 00000 n -0000021440 00000 n -0000901264 00000 n -0000984857 00000 n -0000021485 00000 n -0000021605 00000 n -0000905116 00000 n -0000984724 00000 n -0000021647 00000 n -0000021686 00000 n -0000905367 00000 n -0000984645 00000 n -0000021731 00000 n -0000021784 00000 n -0000907329 00000 n -0000984566 00000 n -0000021829 00000 n -0000021892 00000 n -0000909944 00000 n -0000984433 00000 n -0000021934 00000 n -0000022001 00000 n -0000910069 00000 n -0000984354 00000 n -0000022046 00000 n -0000022083 00000 n -0000911204 00000 n -0000984261 00000 n -0000022128 00000 n -0000022171 00000 n -0000918779 00000 n -0000984182 00000 n -0000022216 00000 n -0000022257 00000 n -0000924712 00000 n -0000984048 00000 n -0000022299 00000 n -0000022361 00000 n -0000925026 00000 n -0000983969 00000 n -0000022406 00000 n -0000022437 00000 n -0000925339 00000 n -0000983876 00000 n -0000022482 00000 n -0000022533 00000 n -0000929420 00000 n -0000983783 00000 n -0000022578 00000 n -0000022617 00000 n -0000929671 00000 n -0000983690 00000 n -0000022662 00000 n -0000022704 00000 n -0000933667 00000 n -0000983597 00000 n -0000022749 00000 n -0000022785 00000 n -0000938903 00000 n -0000983504 00000 n -0000022830 00000 n -0000022872 00000 n -0000939217 00000 n -0000983411 00000 n -0000022917 00000 n -0000022964 00000 n -0000939469 00000 n -0000983318 00000 n -0000023009 00000 n -0000023066 00000 n -0000942594 00000 n -0000983225 00000 n -0000023111 00000 n -0000023145 00000 n -0000942782 00000 n -0000983132 00000 n -0000023190 00000 n -0000023224 00000 n -0000942971 00000 n -0000983039 00000 n -0000023269 00000 n -0000023325 00000 n -0000943286 00000 n -0000982960 00000 n -0000023370 00000 n -0000023432 00000 n -0000947293 00000 n -0000982864 00000 n -0000023474 00000 n -0000023503 00000 n -0000947419 00000 n -0000982725 00000 n -0000023546 00000 n -0000023581 00000 n -0000947546 00000 n -0000982656 00000 n -0000023630 00000 n -0000023660 00000 n -0000947925 00000 n -0000982516 00000 n -0000023703 00000 n -0000023725 00000 n -0000948051 00000 n -0000982406 00000 n -0000023774 00000 n -0000023801 00000 n -0000948494 00000 n -0000982337 00000 n -0000023853 00000 n -0000023917 00000 n -0000952454 00000 n -0000982197 00000 n -0000023960 00000 n -0000023982 00000 n -0000952579 00000 n -0000982087 00000 n -0000024031 00000 n -0000024055 00000 n -0000953020 00000 n -0000982003 00000 n -0000024104 00000 n -0000024135 00000 n -0000953272 00000 n -0000981919 00000 n -0000024184 00000 n -0000024213 00000 n -0000953525 00000 n -0000981779 00000 n -0000024256 00000 n -0000024278 00000 n -0000953651 00000 n -0000981669 00000 n -0000024327 00000 n -0000024372 00000 n -0000954029 00000 n -0000981585 00000 n -0000024421 00000 n -0000024451 00000 n -0000954282 00000 n -0000981486 00000 n -0000024500 00000 n -0000024555 00000 n -0000954786 00000 n -0000981402 00000 n -0000024604 00000 n -0000024632 00000 n -0000957485 00000 n -0000981262 00000 n -0000024675 00000 n -0000024697 00000 n -0000957611 00000 n -0000981152 00000 n -0000024746 00000 n -0000024773 00000 n -0000957991 00000 n -0000981083 00000 n -0000024822 00000 n -0000024853 00000 n -0000958306 00000 n -0000980943 00000 n -0000024896 00000 n -0000024918 00000 n -0000958432 00000 n -0000980874 00000 n -0000024967 00000 n -0000024994 00000 n -0000958876 00000 n -0000980734 00000 n +0000848700 00000 n +0001013017 00000 n +0000021048 00000 n +0000021096 00000 n +0000917618 00000 n +0001012884 00000 n +0000021138 00000 n +0000021185 00000 n +0000917807 00000 n +0001012805 00000 n +0000021230 00000 n +0000021269 00000 n +0000918503 00000 n +0001012712 00000 n +0000021314 00000 n +0000021389 00000 n +0000918944 00000 n +0001012619 00000 n +0000021434 00000 n +0000021530 00000 n +0000921675 00000 n +0001012526 00000 n +0000021575 00000 n +0000021630 00000 n +0000922304 00000 n +0001012433 00000 n +0000021675 00000 n +0000021733 00000 n +0000923065 00000 n +0001012340 00000 n +0000021778 00000 n +0000021850 00000 n +0000927025 00000 n +0001012247 00000 n +0000021895 00000 n +0000021969 00000 n +0000929839 00000 n +0001012154 00000 n +0000022014 00000 n +0000022092 00000 n +0000930219 00000 n +0001012075 00000 n +0000022137 00000 n +0000022256 00000 n +0000934069 00000 n +0001011942 00000 n +0000022298 00000 n +0000022337 00000 n +0000934320 00000 n +0001011863 00000 n +0000022382 00000 n +0000022435 00000 n +0000936282 00000 n +0001011784 00000 n +0000022480 00000 n +0000022543 00000 n +0000938882 00000 n +0001011651 00000 n +0000022585 00000 n +0000022652 00000 n +0000939007 00000 n +0001011572 00000 n +0000022697 00000 n +0000022734 00000 n +0000940142 00000 n +0001011479 00000 n +0000022779 00000 n +0000022822 00000 n +0000945665 00000 n +0001011400 00000 n +0000022867 00000 n +0000022908 00000 n +0000951790 00000 n +0001011264 00000 n +0000022950 00000 n +0000023012 00000 n +0000952104 00000 n +0001011185 00000 n +0000023057 00000 n +0000023088 00000 n +0000952417 00000 n +0001011092 00000 n +0000023133 00000 n +0000023184 00000 n +0000956499 00000 n +0001010999 00000 n +0000023229 00000 n +0000023268 00000 n +0000956750 00000 n +0001010906 00000 n +0000023313 00000 n +0000023355 00000 n +0000960746 00000 n +0001010813 00000 n +0000023400 00000 n +0000023436 00000 n +0000965981 00000 n +0001010718 00000 n +0000023481 00000 n +0000023524 00000 n +0000966295 00000 n +0001010621 00000 n +0000023570 00000 n +0000023618 00000 n +0000966548 00000 n +0001010523 00000 n +0000023664 00000 n +0000023722 00000 n +0000969674 00000 n +0001010425 00000 n +0000023768 00000 n +0000023803 00000 n +0000969863 00000 n +0001010327 00000 n +0000023849 00000 n +0000023884 00000 n +0000970053 00000 n +0001010229 00000 n +0000023930 00000 n +0000023987 00000 n +0000970369 00000 n +0001010146 00000 n +0000024033 00000 n +0000024096 00000 n +0000974377 00000 n +0001010048 00000 n +0000024139 00000 n +0000024168 00000 n +0000974504 00000 n +0001009908 00000 n +0000024211 00000 n +0000024246 00000 n +0000974631 00000 n +0001009839 00000 n +0000024295 00000 n +0000024325 00000 n +0000975010 00000 n +0001009699 00000 n +0000024368 00000 n +0000024390 00000 n +0000975136 00000 n +0001009589 00000 n +0000024439 00000 n +0000024466 00000 n +0000975579 00000 n +0001009520 00000 n +0000024518 00000 n +0000024582 00000 n +0000979539 00000 n +0001009380 00000 n +0000024625 00000 n +0000024647 00000 n +0000979664 00000 n +0001009270 00000 n +0000024696 00000 n +0000024720 00000 n +0000980105 00000 n +0001009186 00000 n +0000024769 00000 n +0000024800 00000 n +0000980357 00000 n +0001009102 00000 n +0000024849 00000 n +0000024878 00000 n +0000980610 00000 n +0001008962 00000 n +0000024921 00000 n +0000024943 00000 n +0000980736 00000 n +0001008852 00000 n +0000024992 00000 n 0000025037 00000 n -0000025059 00000 n -0000959002 00000 n -0000980665 00000 n -0000025108 00000 n -0000025139 00000 n -0000961488 00000 n -0000980525 00000 n -0000025182 00000 n -0000025204 00000 n -0000961612 00000 n -0000980415 00000 n -0000025253 00000 n +0000981114 00000 n +0001008768 00000 n +0000025086 00000 n +0000025116 00000 n +0000981367 00000 n +0001008669 00000 n +0000025165 00000 n +0000025220 00000 n +0000981871 00000 n +0001008585 00000 n +0000025269 00000 n 0000025297 00000 n -0000962171 00000 n -0000980346 00000 n -0000025346 00000 n -0000025372 00000 n -0000963372 00000 n -0000980206 00000 n -0000025415 00000 n -0000025437 00000 n -0000963497 00000 n -0000980096 00000 n +0000984571 00000 n +0001008445 00000 n +0000025340 00000 n +0000025362 00000 n +0000984697 00000 n +0001008335 00000 n +0000025411 00000 n +0000025438 00000 n +0000985077 00000 n +0001008266 00000 n 0000025487 00000 n -0000025528 00000 n -0000963811 00000 n -0000980012 00000 n -0000025578 00000 n -0000025606 00000 n -0000965744 00000 n -0000979928 00000 n -0000025656 00000 n -0000025681 00000 n -0000966060 00000 n -0000979788 00000 n -0000025724 00000 n -0000025746 00000 n -0000966184 00000 n -0000979719 00000 n -0000025796 00000 n -0000025819 00000 n -0000966754 00000 n -0000979579 00000 n -0000025862 00000 n -0000025884 00000 n -0000966880 00000 n -0000979469 00000 n -0000025934 00000 n -0000025992 00000 n -0000967133 00000 n -0000979400 00000 n -0000026042 00000 n -0000026081 00000 n -0000967450 00000 n -0000979260 00000 n -0000026124 00000 n -0000026146 00000 n -0000967575 00000 n -0000979150 00000 n -0000026196 00000 n -0000026224 00000 n -0000970307 00000 n -0000979081 00000 n -0000026274 00000 n -0000026300 00000 n -0000971196 00000 n -0000978941 00000 n -0000026343 00000 n -0000026365 00000 n -0000971322 00000 n -0000978831 00000 n +0000025518 00000 n +0000985392 00000 n +0001008126 00000 n +0000025561 00000 n +0000025583 00000 n +0000985518 00000 n +0001008057 00000 n +0000025633 00000 n +0000025660 00000 n +0000985962 00000 n +0001007917 00000 n +0000025703 00000 n +0000025725 00000 n +0000986088 00000 n +0001007848 00000 n +0000025775 00000 n +0000025806 00000 n +0000988573 00000 n +0001007708 00000 n +0000025849 00000 n +0000025871 00000 n +0000988697 00000 n +0001007598 00000 n +0000025921 00000 n +0000025965 00000 n +0000989256 00000 n +0001007529 00000 n +0000026015 00000 n +0000026041 00000 n +0000990457 00000 n +0001007389 00000 n +0000026084 00000 n +0000026106 00000 n +0000990582 00000 n +0001007279 00000 n +0000026156 00000 n +0000026197 00000 n +0000990896 00000 n +0001007195 00000 n +0000026247 00000 n +0000026275 00000 n +0000992828 00000 n +0001007111 00000 n +0000026325 00000 n +0000026350 00000 n +0000993144 00000 n +0001006971 00000 n +0000026393 00000 n 0000026415 00000 n -0000026452 00000 n -0000971639 00000 n -0000978762 00000 n -0000026502 00000 n -0000026544 00000 n -0000971892 00000 n -0000978637 00000 n -0000026587 00000 n -0000026609 00000 n -0000972018 00000 n -0000978568 00000 n -0000026659 00000 n -0000026697 00000 n -0000027014 00000 n -0000027387 00000 n -0000026751 00000 n -0000027138 00000 n -0000027201 00000 n -0000027264 00000 n -0000001179 00000 f -0000975208 00000 n -0000975305 00000 n -0000028255 00000 n -0000028068 00000 n -0000027461 00000 n -0000028192 00000 n -0000001186 00000 f -0000975114 00000 n -0000100144 00000 n -0000084935 00000 n -0000028343 00000 n -0000100020 00000 n -0000085881 00000 n -0000001277 00000 f -0000975021 00000 n -0000086028 00000 n -0000086176 00000 n -0000086328 00000 n -0000086481 00000 n -0000086634 00000 n -0000086788 00000 n -0000086941 00000 n -0000087095 00000 n -0000087245 00000 n -0000087396 00000 n -0000087550 00000 n -0000087705 00000 n -0000087867 00000 n +0000993268 00000 n +0001006902 00000 n +0000026465 00000 n +0000026488 00000 n +0000993838 00000 n +0001006762 00000 n +0000026531 00000 n +0000026553 00000 n +0000993964 00000 n +0001006652 00000 n +0000026603 00000 n +0000026661 00000 n +0000994217 00000 n +0001006583 00000 n +0000026711 00000 n +0000026750 00000 n +0000994534 00000 n +0001006443 00000 n +0000026793 00000 n +0000026815 00000 n +0000994659 00000 n +0001006333 00000 n +0000026865 00000 n +0000026893 00000 n +0000997392 00000 n +0001006264 00000 n +0000026943 00000 n +0000026969 00000 n +0000998281 00000 n +0001006124 00000 n +0000027012 00000 n +0000027034 00000 n +0000998407 00000 n +0001006014 00000 n +0000027084 00000 n +0000027121 00000 n +0000998724 00000 n +0001005945 00000 n +0000027171 00000 n +0000027213 00000 n +0000998977 00000 n +0001005820 00000 n +0000027256 00000 n +0000027278 00000 n +0000999103 00000 n +0001005751 00000 n +0000027328 00000 n +0000027366 00000 n +0000027681 00000 n +0000028055 00000 n +0000027420 00000 n +0000027805 00000 n +0000027868 00000 n +0000027931 00000 n +0000001207 00000 f +0001002293 00000 n +0001002390 00000 n +0000028918 00000 n +0000028731 00000 n +0000028129 00000 n +0000028855 00000 n +0000001214 00000 f +0001002199 00000 n +0000100695 00000 n +0000085415 00000 n +0000029006 00000 n +0000100571 00000 n +0000086361 00000 n +0000001305 00000 f +0001002106 00000 n +0000086508 00000 n +0000086656 00000 n +0000086808 00000 n +0000086961 00000 n +0000087114 00000 n +0000087268 00000 n +0000087421 00000 n +0000087575 00000 n +0000087725 00000 n +0000087876 00000 n 0000088030 00000 n 0000088185 00000 n -0000088341 00000 n -0000088497 00000 n -0000088653 00000 n -0000088813 00000 n -0000088973 00000 n -0000089130 00000 n -0000089287 00000 n -0000089440 00000 n -0000089593 00000 n -0000089753 00000 n -0000089913 00000 n -0000090072 00000 n -0000090231 00000 n -0000090394 00000 n -0000090557 00000 n -0000090726 00000 n -0000090895 00000 n -0000091063 00000 n -0000091231 00000 n -0000091393 00000 n -0000091555 00000 n -0000091725 00000 n -0000091895 00000 n -0000092062 00000 n -0000092229 00000 n -0000092402 00000 n -0000092575 00000 n -0000092743 00000 n -0000092911 00000 n -0000093082 00000 n -0000093253 00000 n -0000093408 00000 n -0000093563 00000 n -0000093719 00000 n -0000093876 00000 n -0000094030 00000 n -0000094184 00000 n -0000094341 00000 n -0000094497 00000 n -0000094656 00000 n -0000094814 00000 n -0000094963 00000 n -0000095111 00000 n -0000095265 00000 n -0000095418 00000 n -0000095565 00000 n -0000095711 00000 n -0000095858 00000 n -0000096005 00000 n -0000096158 00000 n -0000096311 00000 n -0000096462 00000 n -0000096612 00000 n -0000096779 00000 n -0000096945 00000 n -0000097099 00000 n -0000097253 00000 n -0000097400 00000 n -0000097546 00000 n -0000097693 00000 n -0000097839 00000 n -0000098008 00000 n -0000098176 00000 n -0000098339 00000 n -0000098501 00000 n -0000098656 00000 n -0000098810 00000 n -0000098959 00000 n -0000099108 00000 n -0000099266 00000 n -0000099423 00000 n -0000099567 00000 n -0000099713 00000 n -0000099866 00000 n -0000001524 00000 f -0000974926 00000 n -0000390046 00000 n -0000390171 00000 n -0000390548 00000 n -0000390862 00000 n -0000394913 00000 n -0000397885 00000 n -0000404413 00000 n -0000404538 00000 n -0000405860 00000 n -0000408721 00000 n -0000408909 00000 n -0000409604 00000 n -0000410045 00000 n -0000410487 00000 n -0000415139 00000 n -0000423376 00000 n -0000425820 00000 n -0000426008 00000 n -0000426702 00000 n -0000426890 00000 n -0000427076 00000 n -0000427264 00000 n -0000427517 00000 n -0000430859 00000 n -0000431551 00000 n -0000431803 00000 n -0000436817 00000 n -0000437006 00000 n -0000437259 00000 n -0000446427 00000 n -0000452447 00000 n -0000452953 00000 n -0000453269 00000 n -0000458353 00000 n -0000463787 00000 n -0000464798 00000 n -0000464986 00000 n -0000468606 00000 n -0000469615 00000 n -0000470117 00000 n -0000474088 00000 n -0000474911 00000 n -0000482982 00000 n -0000483868 00000 n -0000482731 00000 n -0000173021 00000 n -0000157492 00000 n -0000100260 00000 n -0000172958 00000 n -0000158474 00000 n -0000158625 00000 n -0000158776 00000 n -0000158930 00000 n -0000159083 00000 n -0000159245 00000 n -0000159406 00000 n -0000159568 00000 n -0000159729 00000 n -0000159883 00000 n -0000160036 00000 n -0000160190 00000 n -0000160343 00000 n -0000160495 00000 n -0000160646 00000 n -0000160805 00000 n -0000160963 00000 n -0000161121 00000 n -0000161280 00000 n -0000161435 00000 n -0000161589 00000 n -0000161739 00000 n -0000161889 00000 n -0000162036 00000 n -0000162182 00000 n -0000162328 00000 n -0000162473 00000 n -0000162618 00000 n -0000162763 00000 n -0000162910 00000 n -0000163056 00000 n -0000163227 00000 n -0000163397 00000 n -0000163544 00000 n -0000163690 00000 n -0000163835 00000 n -0000163980 00000 n -0000164127 00000 n -0000164273 00000 n -0000164419 00000 n -0000164564 00000 n -0000164711 00000 n -0000164857 00000 n -0000165013 00000 n -0000165169 00000 n -0000165322 00000 n -0000165475 00000 n -0000165627 00000 n -0000165779 00000 n -0000165933 00000 n -0000166086 00000 n -0000166240 00000 n -0000166393 00000 n -0000166556 00000 n -0000166718 00000 n -0000166876 00000 n -0000167033 00000 n -0000167188 00000 n -0000167342 00000 n -0000167507 00000 n -0000167671 00000 n -0000167833 00000 n -0000167994 00000 n -0000168152 00000 n -0000168310 00000 n -0000168460 00000 n -0000168610 00000 n -0000168763 00000 n -0000168916 00000 n -0000169067 00000 n -0000169218 00000 n -0000169371 00000 n -0000169524 00000 n -0000169681 00000 n -0000169838 00000 n -0000170001 00000 n -0000170163 00000 n -0000170317 00000 n -0000170470 00000 n -0000170624 00000 n -0000170777 00000 n -0000170931 00000 n -0000171084 00000 n -0000171238 00000 n -0000171391 00000 n -0000171555 00000 n -0000171718 00000 n -0000171875 00000 n -0000172031 00000 n -0000172186 00000 n -0000172340 00000 n -0000172495 00000 n -0000172649 00000 n -0000172804 00000 n -0000488332 00000 n -0000488520 00000 n -0000488837 00000 n -0000487954 00000 n -0000492847 00000 n -0000493289 00000 n -0000493478 00000 n -0000493667 00000 n -0000493979 00000 n -0000498263 00000 n -0000499396 00000 n -0000501936 00000 n -0000502125 00000 n -0000502632 00000 n -0000506645 00000 n -0000509672 00000 n -0000509861 00000 n -0000510683 00000 n -0000517617 00000 n -0000517805 00000 n -0000518373 00000 n -0000523526 00000 n -0000523652 00000 n -0000533861 00000 n -0000533987 00000 n -0000537263 00000 n -0000537389 00000 n -0000537894 00000 n -0000542987 00000 n -0000542925 00000 n -0000549562 00000 n -0000550256 00000 n -0000553774 00000 n -0000554593 00000 n -0000555413 00000 n -0000558576 00000 n -0000559518 00000 n -0000559899 00000 n -0000563408 00000 n -0000563534 00000 n -0000564795 00000 n -0000568174 00000 n -0000568363 00000 n -0000569688 00000 n -0000570131 00000 n -0000573672 00000 n -0000584206 00000 n -0000245533 00000 n -0000229897 00000 n -0000173123 00000 n -0000245470 00000 n -0000230879 00000 n -0000231033 00000 n -0000231186 00000 n -0000231340 00000 n -0000231494 00000 n -0000231654 00000 n -0000231813 00000 n -0000231975 00000 n -0000232136 00000 n -0000232285 00000 n -0000232434 00000 n -0000232581 00000 n -0000232728 00000 n -0000232876 00000 n -0000233024 00000 n -0000233172 00000 n -0000233319 00000 n -0000233467 00000 n -0000233614 00000 n -0000233762 00000 n -0000233909 00000 n -0000234057 00000 n -0000234204 00000 n -0000234352 00000 n -0000234499 00000 n -0000234646 00000 n -0000234792 00000 n -0000234939 00000 n -0000235085 00000 n -0000235237 00000 n -0000235389 00000 n -0000235556 00000 n -0000235722 00000 n -0000235883 00000 n -0000236043 00000 n -0000236198 00000 n -0000236352 00000 n -0000236511 00000 n -0000236669 00000 n -0000236826 00000 n -0000236983 00000 n -0000237146 00000 n +0000088347 00000 n +0000088510 00000 n +0000088665 00000 n +0000088821 00000 n +0000088977 00000 n +0000089133 00000 n +0000089293 00000 n +0000089453 00000 n +0000089610 00000 n +0000089767 00000 n +0000089920 00000 n +0000090073 00000 n +0000090233 00000 n +0000090393 00000 n +0000090552 00000 n +0000090711 00000 n +0000090874 00000 n +0000091037 00000 n +0000091206 00000 n +0000091375 00000 n +0000091543 00000 n +0000091711 00000 n +0000091873 00000 n +0000092035 00000 n +0000092205 00000 n +0000092375 00000 n +0000092542 00000 n +0000092709 00000 n +0000092876 00000 n +0000093043 00000 n +0000093211 00000 n +0000093379 00000 n +0000093548 00000 n +0000093717 00000 n +0000093888 00000 n +0000094059 00000 n +0000094214 00000 n +0000094369 00000 n +0000094539 00000 n +0000094710 00000 n +0000094864 00000 n +0000095018 00000 n +0000095173 00000 n +0000095327 00000 n +0000095486 00000 n +0000095644 00000 n +0000095803 00000 n +0000095961 00000 n +0000096110 00000 n +0000096258 00000 n +0000096412 00000 n +0000096565 00000 n +0000096711 00000 n +0000096856 00000 n +0000097002 00000 n +0000097148 00000 n +0000097303 00000 n +0000097457 00000 n +0000097609 00000 n +0000097760 00000 n +0000097927 00000 n +0000098093 00000 n +0000098247 00000 n +0000098401 00000 n +0000098548 00000 n +0000098694 00000 n +0000098840 00000 n +0000098985 00000 n +0000099153 00000 n +0000099320 00000 n +0000099484 00000 n +0000099647 00000 n +0000099803 00000 n +0000099958 00000 n +0000100107 00000 n +0000100256 00000 n +0000100414 00000 n +0000001566 00000 f +0001002011 00000 n +0000398194 00000 n +0000398319 00000 n +0000398696 00000 n +0000399010 00000 n +0000403061 00000 n +0000406033 00000 n +0000412560 00000 n +0000412685 00000 n +0000414007 00000 n +0000416873 00000 n +0000417061 00000 n +0000417756 00000 n +0000418197 00000 n +0000418639 00000 n +0000423291 00000 n +0000434877 00000 n +0000435127 00000 n +0000435315 00000 n +0000436009 00000 n +0000436196 00000 n +0000436384 00000 n +0000434752 00000 n +0000439568 00000 n +0000439757 00000 n +0000439946 00000 n +0000440638 00000 n +0000444625 00000 n +0000444878 00000 n +0000446139 00000 n +0000449489 00000 n +0000449742 00000 n +0000456221 00000 n +0000461164 00000 n +0000461666 00000 n +0000461982 00000 n +0000473288 00000 n +0000479025 00000 n +0000482650 00000 n +0000482838 00000 n +0000484033 00000 n +0000487759 00000 n +0000488263 00000 n +0000488893 00000 n +0000493408 00000 n +0000498590 00000 n +0000173423 00000 n +0000157911 00000 n +0000100811 00000 n +0000173360 00000 n +0000158893 00000 n +0000159037 00000 n +0000159183 00000 n +0000159336 00000 n +0000159490 00000 n +0000159641 00000 n +0000159792 00000 n +0000159945 00000 n +0000160097 00000 n +0000160259 00000 n +0000160420 00000 n +0000160581 00000 n +0000160741 00000 n +0000160894 00000 n +0000161046 00000 n +0000161201 00000 n +0000161355 00000 n +0000161508 00000 n +0000161660 00000 n +0000161819 00000 n +0000161977 00000 n +0000162134 00000 n +0000162292 00000 n +0000162447 00000 n +0000162601 00000 n +0000162751 00000 n +0000162901 00000 n +0000163047 00000 n +0000163192 00000 n +0000163339 00000 n +0000163485 00000 n +0000163631 00000 n +0000163777 00000 n +0000163924 00000 n +0000164070 00000 n +0000164240 00000 n +0000164409 00000 n +0000164557 00000 n +0000164704 00000 n +0000164851 00000 n +0000164998 00000 n +0000165145 00000 n +0000165291 00000 n +0000165439 00000 n +0000165586 00000 n +0000165734 00000 n +0000165881 00000 n +0000166038 00000 n +0000166195 00000 n +0000166347 00000 n +0000166499 00000 n +0000166650 00000 n +0000166801 00000 n +0000166956 00000 n +0000167110 00000 n +0000167265 00000 n +0000167419 00000 n +0000167582 00000 n +0000167744 00000 n +0000167902 00000 n +0000168059 00000 n +0000168214 00000 n +0000168368 00000 n +0000168532 00000 n +0000168695 00000 n +0000168856 00000 n +0000169016 00000 n +0000169174 00000 n +0000169332 00000 n +0000169483 00000 n +0000169634 00000 n +0000169787 00000 n +0000169940 00000 n +0000170091 00000 n +0000170242 00000 n +0000170395 00000 n +0000170548 00000 n +0000170704 00000 n +0000170860 00000 n +0000171022 00000 n +0000171183 00000 n +0000171338 00000 n +0000171492 00000 n +0000171647 00000 n +0000171801 00000 n +0000171955 00000 n +0000172108 00000 n +0000172262 00000 n +0000172415 00000 n +0000172579 00000 n +0000172742 00000 n +0000172898 00000 n +0000173053 00000 n +0000173207 00000 n +0000499477 00000 n +0000503557 00000 n +0000503872 00000 n +0000504061 00000 n +0000504378 00000 n +0000508513 00000 n +0000508701 00000 n +0000509141 00000 n +0000509329 00000 n +0000512897 00000 n +0000513213 00000 n +0000514735 00000 n +0000518618 00000 n +0000518744 00000 n +0000518933 00000 n +0000519439 00000 n +0000525141 00000 n +0000526147 00000 n +0000526336 00000 n +0000529172 00000 n +0000533561 00000 n +0000533750 00000 n +0000536740 00000 n +0000540429 00000 n +0000540555 00000 n +0000550815 00000 n +0000550941 00000 n +0000554103 00000 n +0000554229 00000 n +0000554733 00000 n +0000556057 00000 n +0000566475 00000 n +0000566727 00000 n +0000567421 00000 n +0000567924 00000 n +0000571793 00000 n +0000572612 00000 n +0000576014 00000 n +0000576956 00000 n +0000577335 00000 n +0000581452 00000 n +0000581578 00000 n +0000582839 00000 n +0000583663 00000 n +0000586343 00000 n +0000587669 00000 n +0000588110 00000 n +0000245502 00000 n +0000229750 00000 n +0000173525 00000 n +0000245439 00000 n +0000230732 00000 n +0000230888 00000 n +0000231043 00000 n +0000231199 00000 n +0000231354 00000 n +0000231508 00000 n +0000231661 00000 n +0000231816 00000 n +0000231971 00000 n +0000232132 00000 n +0000232292 00000 n +0000232453 00000 n +0000232613 00000 n +0000232776 00000 n +0000232938 00000 n +0000233092 00000 n +0000233246 00000 n +0000233406 00000 n +0000233565 00000 n +0000233727 00000 n +0000233888 00000 n +0000234037 00000 n +0000234186 00000 n +0000234334 00000 n +0000234482 00000 n +0000234630 00000 n +0000234778 00000 n +0000234925 00000 n +0000235071 00000 n +0000235219 00000 n +0000235366 00000 n +0000235514 00000 n +0000235661 00000 n +0000235809 00000 n +0000235956 00000 n +0000236104 00000 n +0000236251 00000 n +0000236399 00000 n +0000236546 00000 n +0000236693 00000 n +0000236839 00000 n +0000236990 00000 n +0000237141 00000 n 0000237308 00000 n -0000237457 00000 n -0000237607 00000 n -0000237761 00000 n -0000237915 00000 n -0000238076 00000 n -0000238236 00000 n -0000238399 00000 n -0000238561 00000 n -0000001993 00000 f -0000974836 00000 n -0000238722 00000 n -0000238882 00000 n -0000239039 00000 n -0000239196 00000 n -0000239362 00000 n -0000239527 00000 n -0000239690 00000 n -0000239852 00000 n -0000240018 00000 n -0000240183 00000 n -0000240344 00000 n -0000240505 00000 n -0000240673 00000 n -0000240840 00000 n -0000241014 00000 n -0000241187 00000 n -0000241347 00000 n -0000241507 00000 n -0000241676 00000 n -0000241844 00000 n -0000241992 00000 n -0000242140 00000 n -0000242294 00000 n -0000242448 00000 n -0000242599 00000 n -0000242750 00000 n -0000242900 00000 n -0000243050 00000 n -0000243202 00000 n -0000243354 00000 n -0000243502 00000 n -0000243650 00000 n -0000243801 00000 n -0000243951 00000 n -0000244102 00000 n -0000244252 00000 n -0000244404 00000 n -0000244555 00000 n -0000244712 00000 n -0000244868 00000 n -0000245022 00000 n -0000245175 00000 n -0000245323 00000 n -0000584840 00000 n -0000585155 00000 n -0000585406 00000 n -0000585783 00000 n -0000589438 00000 n -0000590568 00000 n -0000591073 00000 n -0000595037 00000 n -0000594215 00000 n -0000599795 00000 n -0000600925 00000 n -0000602724 00000 n -0000602912 00000 n -0000603164 00000 n -0000606882 00000 n -0000607384 00000 n -0000607889 00000 n -0000612974 00000 n -0000616600 00000 n -0000620958 00000 n -0000621969 00000 n -0000626018 00000 n -0000626334 00000 n -0000626459 00000 n -0000626648 00000 n -0000627792 00000 n -0000628045 00000 n -0000630747 00000 n -0000630935 00000 n -0000632259 00000 n -0000635566 00000 n -0000635692 00000 n -0000643440 00000 n -0000644011 00000 n -0000644137 00000 n -0000647471 00000 n -0000647597 00000 n -0000647848 00000 n -0000648858 00000 n -0000653530 00000 n -0000710057 00000 n -0000713182 00000 n -0000714379 00000 n -0000714568 00000 n -0000718723 00000 n -0000719229 00000 n -0000719672 00000 n -0000317587 00000 n -0000301839 00000 n -0000245649 00000 n -0000317524 00000 n -0000302821 00000 n -0000302983 00000 n -0000303145 00000 n -0000303297 00000 n -0000303450 00000 n -0000303605 00000 n -0000303759 00000 n -0000303914 00000 n -0000304068 00000 n -0000304222 00000 n -0000304376 00000 n -0000304531 00000 n -0000304685 00000 n -0000304844 00000 n -0000305002 00000 n -0000305162 00000 n -0000305321 00000 n -0000305484 00000 n -0000305646 00000 n -0000305810 00000 n -0000305973 00000 n -0000306133 00000 n -0000306292 00000 n -0000306458 00000 n -0000306623 00000 n -0000306790 00000 n -0000306956 00000 n -0000307110 00000 n -0000307264 00000 n -0000307412 00000 n -0000307559 00000 n -0000307713 00000 n -0000307866 00000 n -0000308024 00000 n -0000308181 00000 n -0000308336 00000 n -0000308491 00000 n -0000308649 00000 n -0000308807 00000 n -0000308969 00000 n -0000309130 00000 n -0000309291 00000 n -0000309451 00000 n -0000309611 00000 n -0000309770 00000 n -0000309932 00000 n -0000310093 00000 n -0000310244 00000 n -0000310396 00000 n -0000310547 00000 n -0000310697 00000 n -0000310847 00000 n -0000310996 00000 n -0000311143 00000 n -0000311289 00000 n -0000311436 00000 n -0000311582 00000 n -0000311730 00000 n -0000311878 00000 n -0000312028 00000 n -0000312178 00000 n -0000312338 00000 n -0000312497 00000 n -0000312657 00000 n -0000312816 00000 n -0000312973 00000 n -0000313129 00000 n -0000313276 00000 n -0000313422 00000 n -0000313578 00000 n -0000313734 00000 n -0000313891 00000 n -0000314048 00000 n -0000314209 00000 n -0000314370 00000 n -0000314529 00000 n -0000314687 00000 n -0000314843 00000 n -0000314998 00000 n -0000315157 00000 n -0000315315 00000 n -0000315475 00000 n -0000315635 00000 n -0000315799 00000 n -0000315962 00000 n -0000316114 00000 n -0000316267 00000 n -0000316433 00000 n -0000316599 00000 n -0000316759 00000 n -0000316918 00000 n -0000317068 00000 n -0000317218 00000 n -0000317371 00000 n -0000723432 00000 n -0000724002 00000 n -0000724128 00000 n -0000729162 00000 n -0000729478 00000 n -0000733069 00000 n -0000733445 00000 n -0000733633 00000 n -0000733822 00000 n -0000734011 00000 n -0000732817 00000 n -0000736450 00000 n -0000736702 00000 n -0000736891 00000 n -0000737080 00000 n -0000737521 00000 n -0000740643 00000 n -0000740957 00000 n -0000741525 00000 n -0000741714 00000 n -0000742030 00000 n -0000746006 00000 n -0000752112 00000 n -0000752301 00000 n -0000752490 00000 n -0000755952 00000 n -0000756455 00000 n -0000759914 00000 n -0000760166 00000 n -0000760795 00000 n -0000764814 00000 n -0000765129 00000 n -0000769152 00000 n -0000771182 00000 n -0000774550 00000 n -0000774675 00000 n -0000774927 00000 n -0000775688 00000 n -0000780721 00000 n -0000781480 00000 n -0000786249 00000 n -0000792210 00000 n -0000796195 00000 n -0000806571 00000 n -0000810398 00000 n -0000810713 00000 n -0000814940 00000 n -0000377492 00000 n -0000364891 00000 n -0000317689 00000 n -0000377429 00000 n -0000365711 00000 n -0000365861 00000 n -0000366010 00000 n -0000366157 00000 n -0000366303 00000 n -0000366450 00000 n -0000366596 00000 n -0000366742 00000 n -0000366887 00000 n -0000367039 00000 n -0000367191 00000 n -0000367336 00000 n -0000367481 00000 n -0000367639 00000 n -0000367797 00000 n -0000367954 00000 n -0000368111 00000 n -0000368269 00000 n -0000368427 00000 n -0000368585 00000 n -0000368743 00000 n -0000368900 00000 n -0000369057 00000 n -0000369216 00000 n -0000369376 00000 n -0000369534 00000 n -0000369693 00000 n -0000369857 00000 n -0000370021 00000 n -0000370181 00000 n -0000370341 00000 n -0000370494 00000 n -0000370647 00000 n -0000370812 00000 n -0000370977 00000 n -0000371127 00000 n -0000371278 00000 n -0000371428 00000 n -0000371579 00000 n -0000371737 00000 n -0000371896 00000 n -0000372065 00000 n -0000372235 00000 n -0000372405 00000 n -0000372576 00000 n -0000372741 00000 n -0000372907 00000 n -0000373073 00000 n -0000373240 00000 n -0000373387 00000 n -0000373535 00000 n -0000373684 00000 n -0000373834 00000 n -0000373982 00000 n -0000374131 00000 n -0000374279 00000 n -0000374428 00000 n -0000374577 00000 n -0000374727 00000 n -0000374876 00000 n -0000375026 00000 n -0000375175 00000 n -0000375325 00000 n -0000375474 00000 n -0000375624 00000 n -0000375773 00000 n -0000375923 00000 n -0000376072 00000 n -0000376222 00000 n -0000376370 00000 n -0000376519 00000 n -0000376669 00000 n -0000376820 00000 n -0000376972 00000 n -0000377126 00000 n -0000377277 00000 n -0000975430 00000 n -0000815066 00000 n -0000815255 00000 n -0000815887 00000 n -0000816330 00000 n -0000817675 00000 n -0000820795 00000 n -0000886652 00000 n -0000886841 00000 n -0000887537 00000 n -0000887978 00000 n -0000888479 00000 n -0000891113 00000 n -0000891874 00000 n -0000894577 00000 n -0000898542 00000 n -0000898985 00000 n -0000901201 00000 n -0000905053 00000 n -0000905304 00000 n -0000907267 00000 n -0000909881 00000 n -0000910006 00000 n -0000911141 00000 n -0000918716 00000 n -0000924649 00000 n -0000924963 00000 n -0000925276 00000 n -0000929357 00000 n -0000929608 00000 n -0000933604 00000 n -0000938840 00000 n -0000939155 00000 n -0000939406 00000 n -0000942531 00000 n -0000942719 00000 n -0000942908 00000 n -0000943224 00000 n -0000947230 00000 n -0000386980 00000 n -0000384525 00000 n -0000377608 00000 n -0000386793 00000 n -0000384769 00000 n -0000384926 00000 n -0000385083 00000 n -0000385253 00000 n -0000385423 00000 n -0000385598 00000 n -0000385773 00000 n -0000385941 00000 n -0000386109 00000 n -0000386278 00000 n -0000386448 00000 n -0000386620 00000 n -0000709931 00000 n -0000631314 00000 n -0000631692 00000 n -0000632448 00000 n -0000897655 00000 n -0000898034 00000 n -0000392255 00000 n -0000389753 00000 n -0000387082 00000 n -0000390296 00000 n -0000390359 00000 n -0000390422 00000 n -0000389898 00000 n -0000390485 00000 n -0000390673 00000 n -0000390736 00000 n -0000390799 00000 n -0000390987 00000 n -0000391050 00000 n -0000391113 00000 n -0000391177 00000 n -0000391241 00000 n -0000391304 00000 n -0000391367 00000 n -0000391430 00000 n -0000391492 00000 n -0000391555 00000 n -0000391618 00000 n -0000391682 00000 n -0000391746 00000 n -0000391810 00000 n -0000391873 00000 n -0000391936 00000 n -0000391999 00000 n -0000392063 00000 n -0000392127 00000 n -0000392191 00000 n -0000397948 00000 n -0000394536 00000 n -0000392371 00000 n -0000394660 00000 n -0000394723 00000 n -0000394787 00000 n -0000394850 00000 n -0000395037 00000 n -0000395099 00000 n -0000395162 00000 n -0000395224 00000 n -0000395286 00000 n -0000395349 00000 n -0000395412 00000 n -0000395475 00000 n -0000395539 00000 n -0000395602 00000 n -0000395665 00000 n -0000395728 00000 n -0000395791 00000 n -0000395854 00000 n -0000395917 00000 n -0000395980 00000 n -0000396044 00000 n -0000396107 00000 n -0000396169 00000 n -0000396232 00000 n -0000396296 00000 n -0000396359 00000 n -0000396422 00000 n -0000396485 00000 n -0000396549 00000 n -0000396612 00000 n -0000396675 00000 n -0000396738 00000 n -0000396802 00000 n -0000396865 00000 n -0000396928 00000 n -0000396991 00000 n -0000397055 00000 n -0000397119 00000 n -0000397183 00000 n -0000397247 00000 n -0000397311 00000 n -0000397375 00000 n -0000397439 00000 n -0000397503 00000 n -0000397567 00000 n -0000397630 00000 n -0000397694 00000 n -0000397758 00000 n -0000397821 00000 n -0000400312 00000 n -0000399505 00000 n -0000398064 00000 n -0000399870 00000 n -0000399933 00000 n -0000399996 00000 n -0000400059 00000 n -0000400122 00000 n -0000002005 00000 f -0000974744 00000 n -0000399650 00000 n -0000400185 00000 n -0000400248 00000 n -0000953209 00000 n -0000406239 00000 n -0000402951 00000 n -0000400456 00000 n -0000404663 00000 n -0000404726 00000 n -0000404789 00000 n -0000002248 00000 f -0000974644 00000 n -0000404853 00000 n -0000403159 00000 n -0000403314 00000 n -0000404916 00000 n -0000404978 00000 n -0000405041 00000 n -0000405104 00000 n -0000405167 00000 n -0000405231 00000 n -0000405293 00000 n -0000405356 00000 n -0000405419 00000 n -0000403467 00000 n -0000405482 00000 n -0000403620 00000 n -0000405545 00000 n -0000403779 00000 n -0000405608 00000 n +0000237474 00000 n +0000237641 00000 n +0000237807 00000 n +0000237968 00000 n +0000238128 00000 n +0000238283 00000 n +0000238437 00000 n +0000238596 00000 n +0000238754 00000 n +0000238911 00000 n +0000239068 00000 n +0000239231 00000 n +0000239393 00000 n +0000239542 00000 n +0000239692 00000 n +0000239846 00000 n +0000240000 00000 n +0000240161 00000 n +0000240321 00000 n +0000240484 00000 n +0000240646 00000 n +0000002036 00000 f +0001001921 00000 n +0000240807 00000 n +0000240967 00000 n +0000241124 00000 n +0000241281 00000 n +0000241447 00000 n +0000241612 00000 n +0000241775 00000 n +0000241937 00000 n +0000242103 00000 n +0000242268 00000 n +0000242429 00000 n +0000242590 00000 n +0000242758 00000 n +0000242925 00000 n +0000243099 00000 n +0000243272 00000 n +0000243432 00000 n +0000243592 00000 n +0000243761 00000 n +0000243929 00000 n +0000244077 00000 n +0000244225 00000 n +0000244379 00000 n +0000244533 00000 n +0000244684 00000 n +0000244835 00000 n +0000244985 00000 n +0000245135 00000 n +0000245287 00000 n +0000588553 00000 n +0000599416 00000 n +0000603066 00000 n +0000603382 00000 n +0000603635 00000 n +0000608358 00000 n +0000608547 00000 n +0000608735 00000 n +0000608987 00000 n +0000609367 00000 n +0000613005 00000 n +0000614136 00000 n +0000614640 00000 n +0000618605 00000 n +0000617783 00000 n +0000623363 00000 n +0000624493 00000 n +0000626292 00000 n +0000626480 00000 n +0000626732 00000 n +0000630302 00000 n +0000630804 00000 n +0000631371 00000 n +0000636055 00000 n +0000637065 00000 n +0000640513 00000 n +0000644902 00000 n +0000645914 00000 n +0000650908 00000 n +0000651224 00000 n +0000651349 00000 n +0000651538 00000 n +0000652682 00000 n +0000652935 00000 n +0000655638 00000 n +0000655826 00000 n +0000657150 00000 n +0000660457 00000 n +0000660583 00000 n +0000668330 00000 n +0000668901 00000 n +0000669027 00000 n +0000672409 00000 n +0000672535 00000 n +0000672786 00000 n +0000678126 00000 n +0000685213 00000 n +0000318719 00000 n +0000303072 00000 n +0000245618 00000 n +0000318656 00000 n +0000304054 00000 n +0000304202 00000 n +0000304350 00000 n +0000304501 00000 n +0000304651 00000 n +0000304803 00000 n +0000304954 00000 n +0000305106 00000 n +0000305257 00000 n +0000305415 00000 n +0000305572 00000 n +0000305727 00000 n +0000305881 00000 n +0000306028 00000 n +0000306174 00000 n +0000306337 00000 n +0000306499 00000 n +0000306651 00000 n +0000306804 00000 n +0000306959 00000 n +0000307113 00000 n +0000307268 00000 n +0000307422 00000 n +0000307576 00000 n +0000307730 00000 n +0000307885 00000 n +0000308039 00000 n +0000308198 00000 n +0000308356 00000 n +0000308516 00000 n +0000308675 00000 n +0000308838 00000 n +0000309000 00000 n +0000309164 00000 n +0000309327 00000 n +0000309487 00000 n +0000309646 00000 n +0000309812 00000 n +0000309977 00000 n +0000310144 00000 n +0000310310 00000 n +0000310464 00000 n +0000310618 00000 n +0000310766 00000 n +0000310913 00000 n +0000311067 00000 n +0000311220 00000 n +0000311378 00000 n +0000311535 00000 n +0000311690 00000 n +0000311845 00000 n +0000312003 00000 n +0000312161 00000 n +0000312323 00000 n +0000312484 00000 n +0000312645 00000 n +0000312805 00000 n +0000312965 00000 n +0000313124 00000 n +0000313286 00000 n +0000313447 00000 n +0000313598 00000 n +0000313750 00000 n +0000313901 00000 n +0000314051 00000 n +0000314201 00000 n +0000314350 00000 n +0000314497 00000 n +0000314643 00000 n +0000314790 00000 n +0000314936 00000 n +0000315084 00000 n +0000315232 00000 n +0000315382 00000 n +0000315532 00000 n +0000315692 00000 n +0000315851 00000 n +0000316011 00000 n +0000316170 00000 n +0000316327 00000 n +0000316483 00000 n +0000316630 00000 n +0000316776 00000 n +0000316932 00000 n +0000317088 00000 n +0000317241 00000 n +0000317394 00000 n +0000317551 00000 n +0000317708 00000 n +0000317869 00000 n +0000318030 00000 n +0000318188 00000 n +0000318345 00000 n +0000318501 00000 n +0000683637 00000 n +0000739831 00000 n +0000741030 00000 n +0000741219 00000 n +0000739769 00000 n +0000745909 00000 n +0000746351 00000 n +0000746790 00000 n +0000750933 00000 n +0000751059 00000 n +0000756239 00000 n +0000756554 00000 n +0000760268 00000 n +0000760645 00000 n +0000760833 00000 n +0000761021 00000 n +0000761206 00000 n +0000763587 00000 n +0000763776 00000 n +0000764028 00000 n +0000764217 00000 n +0000764406 00000 n +0000767475 00000 n +0000767726 00000 n +0000768040 00000 n +0000768609 00000 n +0000768797 00000 n +0000772054 00000 n +0000773062 00000 n +0000779296 00000 n +0000779485 00000 n +0000782524 00000 n +0000782965 00000 n +0000783466 00000 n +0000786960 00000 n +0000787212 00000 n +0000791201 00000 n +0000791830 00000 n +0000792144 00000 n +0000796309 00000 n +0000798668 00000 n +0000801753 00000 n +0000801879 00000 n +0000802700 00000 n +0000802952 00000 n +0000803711 00000 n +0000808547 00000 n +0000385669 00000 n +0000371385 00000 n +0000318821 00000 n +0000385606 00000 n +0000372295 00000 n +0000372455 00000 n +0000372614 00000 n +0000372774 00000 n +0000372934 00000 n +0000373098 00000 n +0000373261 00000 n +0000373414 00000 n +0000373567 00000 n +0000373733 00000 n +0000373899 00000 n +0000374052 00000 n +0000374205 00000 n +0000374354 00000 n +0000374502 00000 n +0000374649 00000 n +0000374795 00000 n +0000374942 00000 n +0000375088 00000 n +0000375235 00000 n +0000375381 00000 n +0000375532 00000 n +0000375683 00000 n +0000375829 00000 n +0000375975 00000 n +0000376133 00000 n +0000376291 00000 n +0000376448 00000 n +0000376605 00000 n +0000376763 00000 n +0000376921 00000 n +0000377078 00000 n +0000377235 00000 n +0000377392 00000 n +0000377550 00000 n +0000377709 00000 n +0000377870 00000 n +0000378034 00000 n +0000378199 00000 n +0000378359 00000 n +0000378520 00000 n +0000378673 00000 n +0000378827 00000 n +0000378992 00000 n +0000379158 00000 n +0000379308 00000 n +0000379459 00000 n +0000379608 00000 n +0000379758 00000 n +0000379916 00000 n +0000380075 00000 n +0000380244 00000 n +0000380414 00000 n +0000380583 00000 n +0000380753 00000 n +0000380919 00000 n +0000381086 00000 n +0000381251 00000 n +0000381417 00000 n +0000381564 00000 n +0000381712 00000 n +0000381861 00000 n +0000382011 00000 n +0000382160 00000 n +0000382310 00000 n +0000382459 00000 n +0000382609 00000 n +0000382757 00000 n +0000382906 00000 n +0000383054 00000 n +0000383203 00000 n +0000383352 00000 n +0000383502 00000 n +0000383651 00000 n +0000383801 00000 n +0000383950 00000 n +0000384100 00000 n +0000384249 00000 n +0000384399 00000 n +0000384548 00000 n +0000384698 00000 n +0000384848 00000 n +0000384999 00000 n +0000385150 00000 n +0000385303 00000 n +0000385454 00000 n +0001002515 00000 n +0000812764 00000 n +0000813967 00000 n +0000823255 00000 n +0000823824 00000 n +0000837714 00000 n +0000842152 00000 n +0000842278 00000 n +0000842467 00000 n +0000845008 00000 n +0000845450 00000 n +0000845703 00000 n +0000848637 00000 n +0000917555 00000 n +0000917744 00000 n +0000918440 00000 n +0000918881 00000 n +0000919382 00000 n +0000922241 00000 n +0000923002 00000 n +0000926962 00000 n +0000929776 00000 n +0000930156 00000 n +0000934006 00000 n +0000934257 00000 n +0000936220 00000 n +0000938819 00000 n +0000938944 00000 n +0000940079 00000 n +0000945602 00000 n +0000951727 00000 n +0000952041 00000 n +0000952354 00000 n +0000956436 00000 n +0000956687 00000 n +0000960683 00000 n +0000965918 00000 n +0000966233 00000 n +0000966485 00000 n +0000969611 00000 n +0000969800 00000 n +0000969990 00000 n +0000970307 00000 n +0000974314 00000 n +0000395130 00000 n +0000392673 00000 n +0000385785 00000 n +0000394943 00000 n +0000392917 00000 n +0000393074 00000 n +0000393231 00000 n +0000393401 00000 n +0000393571 00000 n +0000393746 00000 n +0000393921 00000 n +0000394089 00000 n +0000394257 00000 n +0000394426 00000 n +0000394597 00000 n +0000394769 00000 n +0000685530 00000 n +0000656205 00000 n +0000656583 00000 n +0000657339 00000 n +0000926077 00000 n +0000926457 00000 n +0000400403 00000 n +0000397901 00000 n +0000395232 00000 n +0000398444 00000 n +0000398507 00000 n +0000398570 00000 n +0000398046 00000 n +0000398633 00000 n +0000398821 00000 n +0000398884 00000 n +0000398947 00000 n +0000399135 00000 n +0000399198 00000 n +0000399261 00000 n +0000399325 00000 n +0000399389 00000 n +0000399452 00000 n +0000399515 00000 n +0000399578 00000 n +0000399640 00000 n +0000399703 00000 n +0000399766 00000 n +0000399830 00000 n +0000399894 00000 n +0000399958 00000 n +0000400021 00000 n +0000400084 00000 n +0000400147 00000 n +0000400211 00000 n +0000400275 00000 n +0000400339 00000 n +0000406096 00000 n +0000402684 00000 n +0000400519 00000 n +0000402808 00000 n +0000402871 00000 n +0000402935 00000 n +0000402998 00000 n +0000403185 00000 n +0000403247 00000 n +0000403310 00000 n +0000403372 00000 n +0000403434 00000 n +0000403497 00000 n +0000403560 00000 n +0000403623 00000 n +0000403687 00000 n +0000403750 00000 n +0000403813 00000 n +0000403876 00000 n 0000403939 00000 n -0000405671 00000 n -0000404097 00000 n -0000405734 00000 n -0000404259 00000 n -0000405797 00000 n -0000405985 00000 n -0000406048 00000 n -0000406112 00000 n -0000406175 00000 n -0000410550 00000 n -0000408424 00000 n -0000406383 00000 n -0000408846 00000 n -0000409034 00000 n -0000409097 00000 n -0000409161 00000 n -0000409224 00000 n -0000409288 00000 n -0000409351 00000 n -0000409413 00000 n -0000409477 00000 n -0000409541 00000 n -0000409728 00000 n -0000409791 00000 n -0000409855 00000 n -0000409918 00000 n -0000409982 00000 n -0000410170 00000 n -0000410233 00000 n -0000408569 00000 n -0000410296 00000 n -0000410360 00000 n -0000410423 00000 n -0000975555 00000 n -0000953588 00000 n -0000416527 00000 n -0000413791 00000 n -0000410680 00000 n -0000414503 00000 n -0000414566 00000 n -0000414630 00000 n -0000414694 00000 n -0000414758 00000 n -0000414821 00000 n -0000414885 00000 n -0000414949 00000 n -0000415013 00000 n -0000415076 00000 n -0000415264 00000 n -0000415326 00000 n -0000413954 00000 n -0000415390 00000 n -0000415453 00000 n -0000415517 00000 n -0000415580 00000 n -0000415643 00000 n -0000415706 00000 n -0000415769 00000 n -0000415832 00000 n -0000414110 00000 n -0000414272 00000 n -0000415895 00000 n -0000415958 00000 n -0000416021 00000 n -0000416084 00000 n -0000416147 00000 n -0000416210 00000 n -0000416273 00000 n -0000416337 00000 n -0000416401 00000 n -0000416464 00000 n -0000423564 00000 n -0000418743 00000 n -0000416671 00000 n -0000420290 00000 n -0000420354 00000 n -0000420417 00000 n -0000420480 00000 n -0000420544 00000 n -0000420607 00000 n -0000420670 00000 n -0000420733 00000 n -0000420796 00000 n -0000420859 00000 n -0000420922 00000 n -0000420985 00000 n -0000421048 00000 n -0000421110 00000 n -0000421172 00000 n -0000421235 00000 n -0000418951 00000 n -0000421298 00000 n -0000421360 00000 n -0000421423 00000 n -0000421486 00000 n -0000421549 00000 n -0000421612 00000 n -0000421675 00000 n -0000421738 00000 n -0000419118 00000 n -0000421801 00000 n -0000421864 00000 n -0000421927 00000 n -0000421990 00000 n -0000422053 00000 n -0000422116 00000 n -0000422179 00000 n -0000422242 00000 n -0000422305 00000 n -0000422368 00000 n -0000422431 00000 n -0000422494 00000 n -0000422557 00000 n -0000419285 00000 n -0000422620 00000 n -0000422683 00000 n -0000419445 00000 n -0000422746 00000 n -0000422809 00000 n -0000419614 00000 n -0000422872 00000 n -0000422935 00000 n -0000419781 00000 n -0000422998 00000 n -0000423061 00000 n -0000419953 00000 n -0000423124 00000 n -0000423187 00000 n -0000420120 00000 n -0000423250 00000 n -0000423313 00000 n -0000423501 00000 n -0000427580 00000 n -0000425634 00000 n -0000423694 00000 n -0000425758 00000 n -0000425945 00000 n -0000426133 00000 n -0000426196 00000 n -0000426259 00000 n -0000426322 00000 n -0000426385 00000 n -0000426449 00000 n -0000426512 00000 n -0000426575 00000 n -0000426639 00000 n -0000426827 00000 n -0000427013 00000 n -0000427201 00000 n -0000427390 00000 n -0000427453 00000 n -0000432244 00000 n -0000430211 00000 n -0000427710 00000 n -0000430670 00000 n -0000430796 00000 n -0000430984 00000 n -0000431047 00000 n -0000431110 00000 n -0000431173 00000 n -0000431236 00000 n -0000430365 00000 n -0000431300 00000 n -0000431362 00000 n -0000431425 00000 n -0000431488 00000 n -0000431676 00000 n -0000431739 00000 n -0000430518 00000 n -0000431929 00000 n -0000431992 00000 n -0000432055 00000 n -0000432118 00000 n -0000432181 00000 n -0000438017 00000 n -0000435306 00000 n -0000432374 00000 n -0000435930 00000 n -0000435993 00000 n -0000436056 00000 n -0000436120 00000 n -0000436184 00000 n -0000436247 00000 n -0000436310 00000 n -0000436372 00000 n -0000436436 00000 n -0000436500 00000 n -0000436564 00000 n -0000436627 00000 n -0000436690 00000 n -0000436753 00000 n -0000436943 00000 n -0000435469 00000 n -0000435618 00000 n -0000437132 00000 n -0000437195 00000 n -0000437385 00000 n -0000437448 00000 n -0000435772 00000 n -0000437512 00000 n -0000437638 00000 n -0000437701 00000 n -0000437765 00000 n -0000437828 00000 n -0000437891 00000 n -0000437954 00000 n -0000443468 00000 n -0000440697 00000 n -0000438161 00000 n -0000440997 00000 n -0000441060 00000 n -0000441123 00000 n -0000441248 00000 n -0000441310 00000 n -0000441373 00000 n -0000441436 00000 n -0000441499 00000 n -0000441562 00000 n -0000441626 00000 n -0000441752 00000 n -0000441815 00000 n -0000441879 00000 n -0000002420 00000 f -0000974546 00000 n -0000441943 00000 n -0000440842 00000 n -0000442007 00000 n -0000442070 00000 n -0000442134 00000 n -0000442198 00000 n -0000442262 00000 n -0000442326 00000 n -0000442390 00000 n -0000442453 00000 n -0000442517 00000 n -0000442580 00000 n -0000442643 00000 n -0000442705 00000 n -0000442769 00000 n -0000442895 00000 n -0000442958 00000 n -0000443021 00000 n -0000443085 00000 n -0000443149 00000 n -0000443213 00000 n -0000443276 00000 n -0000443340 00000 n -0000443404 00000 n -0000975680 00000 n -0000448828 00000 n -0000445875 00000 n -0000443640 00000 n -0000446175 00000 n -0000446238 00000 n -0000446301 00000 n -0000446364 00000 n -0000446553 00000 n -0000446616 00000 n -0000446679 00000 n -0000446805 00000 n -0000446868 00000 n -0000446932 00000 n -0000446996 00000 n -0000446020 00000 n -0000447060 00000 n -0000447123 00000 n -0000447186 00000 n -0000447249 00000 n -0000447312 00000 n -0000447375 00000 n -0000447438 00000 n -0000447501 00000 n -0000447564 00000 n -0000447627 00000 n -0000447753 00000 n -0000447816 00000 n -0000447880 00000 n -0000447943 00000 n -0000448006 00000 n -0000448069 00000 n -0000448132 00000 n -0000448195 00000 n -0000448259 00000 n -0000448323 00000 n -0000448387 00000 n -0000448450 00000 n -0000448513 00000 n -0000448576 00000 n -0000448639 00000 n -0000448702 00000 n -0000448765 00000 n -0000454343 00000 n -0000451815 00000 n -0000449000 00000 n -0000452129 00000 n -0000452192 00000 n -0000452255 00000 n -0000452319 00000 n -0000452383 00000 n -0000452573 00000 n -0000452636 00000 n -0000452700 00000 n -0000452763 00000 n -0000452826 00000 n -0000452889 00000 n -0000453079 00000 n -0000453142 00000 n -0000451960 00000 n -0000453205 00000 n -0000453395 00000 n -0000453458 00000 n -0000453521 00000 n -0000453584 00000 n -0000453648 00000 n -0000453712 00000 n -0000453774 00000 n -0000453838 00000 n -0000453902 00000 n -0000453965 00000 n -0000454028 00000 n -0000454092 00000 n -0000454154 00000 n -0000454217 00000 n -0000454279 00000 n -0000459937 00000 n -0000457404 00000 n -0000454473 00000 n -0000457528 00000 n -0000457591 00000 n -0000457654 00000 n -0000457717 00000 n -0000457781 00000 n -0000457844 00000 n -0000457908 00000 n -0000457972 00000 n -0000458036 00000 n -0000458099 00000 n -0000458163 00000 n -0000458227 00000 n -0000458290 00000 n -0000458478 00000 n -0000458541 00000 n -0000458605 00000 n -0000458669 00000 n -0000458733 00000 n -0000458796 00000 n -0000458859 00000 n -0000458923 00000 n -0000458987 00000 n -0000459051 00000 n -0000459114 00000 n -0000459177 00000 n -0000459241 00000 n -0000459305 00000 n -0000459367 00000 n -0000459431 00000 n -0000459494 00000 n -0000459557 00000 n -0000459620 00000 n -0000459683 00000 n -0000459746 00000 n -0000459809 00000 n -0000459873 00000 n -0000465678 00000 n -0000462662 00000 n -0000460095 00000 n -0000463470 00000 n -0000463533 00000 n -0000463596 00000 n -0000463659 00000 n -0000463723 00000 n -0000462834 00000 n -0000463912 00000 n -0000463975 00000 n -0000463003 00000 n -0000464039 00000 n -0000464102 00000 n -0000464165 00000 n -0000464228 00000 n -0000463162 00000 n -0000464292 00000 n -0000464356 00000 n -0000464420 00000 n -0000464483 00000 n -0000464545 00000 n -0000464608 00000 n -0000464672 00000 n -0000464735 00000 n -0000463316 00000 n -0000464923 00000 n -0000465112 00000 n -0000465175 00000 n -0000465238 00000 n -0000465301 00000 n -0000002628 00000 f -0000974451 00000 n -0000465364 00000 n -0000465427 00000 n -0000465491 00000 n -0000465553 00000 n -0000465615 00000 n -0000470180 00000 n -0000467914 00000 n -0000465836 00000 n -0000468038 00000 n -0000468101 00000 n -0000468164 00000 n -0000468227 00000 n -0000468290 00000 n -0000468353 00000 n -0000468416 00000 n -0000468479 00000 n -0000468542 00000 n -0000468731 00000 n -0000468793 00000 n -0000468856 00000 n -0000468919 00000 n -0000468982 00000 n -0000469045 00000 n -0000469109 00000 n -0000469172 00000 n -0000469235 00000 n -0000469298 00000 n -0000469361 00000 n -0000469424 00000 n -0000469488 00000 n -0000469551 00000 n -0000469740 00000 n -0000469803 00000 n -0000469866 00000 n -0000469929 00000 n -0000469991 00000 n -0000470054 00000 n -0000475225 00000 n -0000473099 00000 n -0000470324 00000 n -0000473395 00000 n -0000473458 00000 n -0000473583 00000 n -0000473244 00000 n -0000473646 00000 n -0000473709 00000 n -0000473772 00000 n -0000473835 00000 n -0000473898 00000 n -0000473961 00000 n -0000474024 00000 n -0000474214 00000 n -0000474277 00000 n -0000474340 00000 n -0000474404 00000 n -0000474468 00000 n -0000474531 00000 n -0000474594 00000 n -0000474658 00000 n -0000474722 00000 n -0000474785 00000 n -0000474847 00000 n -0000475036 00000 n -0000475099 00000 n -0000475162 00000 n -0000975805 00000 n -0000479992 00000 n -0000477475 00000 n -0000475355 00000 n -0000477777 00000 n -0000477840 00000 n -0000477902 00000 n -0000477966 00000 n -0000477620 00000 n -0000478030 00000 n -0000478094 00000 n -0000478157 00000 n -0000478219 00000 n -0000478282 00000 n -0000478345 00000 n -0000478409 00000 n -0000478473 00000 n -0000478537 00000 n -0000478600 00000 n -0000478664 00000 n -0000478727 00000 n -0000478790 00000 n -0000478853 00000 n -0000478916 00000 n -0000478980 00000 n -0000479044 00000 n -0000479107 00000 n -0000479170 00000 n -0000479233 00000 n -0000479296 00000 n -0000479360 00000 n -0000479423 00000 n -0000479486 00000 n -0000479549 00000 n -0000479612 00000 n -0000479676 00000 n -0000479739 00000 n -0000479802 00000 n -0000479865 00000 n -0000479928 00000 n -0000954662 00000 n -0000484884 00000 n -0000482544 00000 n -0000480136 00000 n -0000482668 00000 n -0000482793 00000 n -0000482856 00000 n -0000482919 00000 n -0000483107 00000 n -0000483170 00000 n -0000483234 00000 n -0000483298 00000 n -0000483361 00000 n -0000483425 00000 n -0000483489 00000 n -0000483552 00000 n -0000483615 00000 n -0000483679 00000 n -0000483742 00000 n -0000483805 00000 n -0000483994 00000 n -0000484056 00000 n -0000484120 00000 n -0000484184 00000 n -0000484248 00000 n -0000484312 00000 n -0000484376 00000 n -0000484440 00000 n -0000484503 00000 n -0000484567 00000 n -0000484631 00000 n -0000484695 00000 n -0000484759 00000 n -0000484822 00000 n -0000489656 00000 n -0000487422 00000 n -0000485014 00000 n -0000487891 00000 n -0000488016 00000 n -0000488142 00000 n -0000488205 00000 n -0000488268 00000 n -0000488457 00000 n -0000488646 00000 n -0000488709 00000 n -0000488773 00000 n -0000488963 00000 n -0000487576 00000 n -0000487739 00000 n -0000489026 00000 n -0000489089 00000 n -0000489153 00000 n -0000489216 00000 n -0000489279 00000 n -0000489342 00000 n -0000489405 00000 n -0000489467 00000 n -0000489530 00000 n -0000489593 00000 n -0000963434 00000 n -0000494421 00000 n -0000492026 00000 n -0000489800 00000 n -0000492659 00000 n -0000492784 00000 n -0000492973 00000 n -0000492189 00000 n -0000492358 00000 n -0000493036 00000 n -0000493099 00000 n -0000493162 00000 n -0000493225 00000 n -0000493415 00000 n -0000493604 00000 n -0000493789 00000 n -0000493852 00000 n -0000493916 00000 n -0000492506 00000 n -0000494105 00000 n -0000494168 00000 n -0000494231 00000 n -0000494295 00000 n -0000494357 00000 n -0000499459 00000 n -0000496821 00000 n -0000494551 00000 n -0000497120 00000 n -0000497183 00000 n -0000496966 00000 n -0000497246 00000 n -0000497309 00000 n -0000497372 00000 n -0000497436 00000 n -0000497500 00000 n -0000497564 00000 n -0000497628 00000 n -0000497692 00000 n -0000497756 00000 n -0000497820 00000 n -0000497883 00000 n -0000497947 00000 n +0000404002 00000 n +0000404065 00000 n +0000404128 00000 n +0000404192 00000 n +0000404255 00000 n +0000404317 00000 n +0000404380 00000 n +0000404444 00000 n +0000404507 00000 n +0000404570 00000 n +0000404633 00000 n +0000404697 00000 n +0000404760 00000 n +0000404823 00000 n +0000404886 00000 n +0000404950 00000 n +0000405013 00000 n +0000405076 00000 n +0000405139 00000 n +0000405203 00000 n +0000405267 00000 n +0000405331 00000 n +0000405395 00000 n +0000405459 00000 n +0000405523 00000 n +0000405587 00000 n +0000405651 00000 n +0000405715 00000 n +0000405778 00000 n +0000405842 00000 n +0000405906 00000 n +0000405969 00000 n +0000408460 00000 n +0000407653 00000 n +0000406212 00000 n +0000408018 00000 n +0000408081 00000 n +0000408144 00000 n +0000408207 00000 n +0000408270 00000 n +0000002048 00000 f +0001001829 00000 n +0000407798 00000 n +0000408333 00000 n +0000408396 00000 n +0000980294 00000 n +0000414386 00000 n +0000411098 00000 n +0000408604 00000 n +0000412810 00000 n +0000412873 00000 n +0000412936 00000 n +0000002321 00000 f +0001001729 00000 n +0000413000 00000 n +0000411306 00000 n +0000411461 00000 n +0000413063 00000 n +0000413125 00000 n +0000413188 00000 n +0000413251 00000 n +0000413314 00000 n +0000413378 00000 n +0000413440 00000 n +0000413503 00000 n +0000413566 00000 n +0000411614 00000 n +0000413629 00000 n +0000411767 00000 n +0000413692 00000 n +0000411926 00000 n +0000413755 00000 n +0000412086 00000 n +0000413818 00000 n +0000412244 00000 n +0000413881 00000 n +0000412406 00000 n +0000413944 00000 n +0000414132 00000 n +0000414195 00000 n +0000414259 00000 n +0000414322 00000 n +0000418702 00000 n +0000416576 00000 n +0000414530 00000 n +0000416998 00000 n +0000417186 00000 n +0000417249 00000 n +0000417313 00000 n +0000417376 00000 n +0000417440 00000 n +0000417503 00000 n +0000417565 00000 n +0000417629 00000 n +0000417693 00000 n +0000417880 00000 n +0000417943 00000 n +0000418007 00000 n +0000418070 00000 n +0000418134 00000 n +0000418322 00000 n +0000418385 00000 n +0000416721 00000 n +0000418448 00000 n +0000418512 00000 n +0000418575 00000 n +0001002640 00000 n +0000980673 00000 n +0000424679 00000 n +0000421943 00000 n +0000418832 00000 n +0000422655 00000 n +0000422718 00000 n +0000422782 00000 n +0000422846 00000 n +0000422910 00000 n +0000422973 00000 n +0000423037 00000 n +0000423101 00000 n +0000423165 00000 n +0000423228 00000 n +0000423416 00000 n +0000423478 00000 n +0000422106 00000 n +0000423542 00000 n +0000423605 00000 n +0000423669 00000 n +0000423732 00000 n +0000423795 00000 n +0000423858 00000 n +0000423921 00000 n +0000423984 00000 n +0000422262 00000 n +0000422424 00000 n +0000424047 00000 n +0000424110 00000 n +0000424173 00000 n +0000424236 00000 n +0000424299 00000 n +0000424362 00000 n +0000424425 00000 n +0000424489 00000 n +0000424553 00000 n +0000424616 00000 n +0000432531 00000 n +0000427037 00000 n +0000424823 00000 n +0000428754 00000 n +0000428818 00000 n +0000428881 00000 n +0000428944 00000 n +0000429008 00000 n +0000429071 00000 n +0000429134 00000 n +0000429197 00000 n +0000429260 00000 n +0000429323 00000 n +0000429386 00000 n +0000429449 00000 n +0000427254 00000 n +0000429512 00000 n +0000429575 00000 n +0000429637 00000 n +0000429700 00000 n +0000429763 00000 n +0000429825 00000 n +0000427422 00000 n +0000429888 00000 n +0000429951 00000 n +0000430014 00000 n +0000430077 00000 n +0000430140 00000 n +0000430204 00000 n +0000430267 00000 n +0000427589 00000 n +0000430330 00000 n +0000430393 00000 n +0000430456 00000 n +0000430519 00000 n +0000427749 00000 n +0000430582 00000 n +0000430645 00000 n +0000427917 00000 n +0000430708 00000 n +0000430771 00000 n +0000428084 00000 n +0000430833 00000 n +0000430896 00000 n +0000428250 00000 n +0000430959 00000 n +0000431021 00000 n +0000431084 00000 n +0000431147 00000 n +0000431210 00000 n +0000431273 00000 n +0000428416 00000 n +0000431336 00000 n +0000431399 00000 n +0000431462 00000 n +0000431525 00000 n +0000431588 00000 n +0000431651 00000 n +0000428586 00000 n +0000431714 00000 n +0000431777 00000 n +0000431840 00000 n +0000431903 00000 n +0000431966 00000 n +0000432029 00000 n +0000432092 00000 n +0000432155 00000 n +0000432217 00000 n +0000432280 00000 n +0000432343 00000 n +0000432405 00000 n +0000432468 00000 n +0000436447 00000 n +0000434628 00000 n +0000432647 00000 n +0000434814 00000 n +0000435001 00000 n +0000435064 00000 n +0000435252 00000 n +0000435440 00000 n +0000435503 00000 n +0000435566 00000 n +0000435629 00000 n +0000435692 00000 n +0000435756 00000 n +0000435819 00000 n +0000435882 00000 n +0000435946 00000 n +0000436133 00000 n +0000436321 00000 n +0000440701 00000 n +0000438891 00000 n +0000436577 00000 n +0000439190 00000 n +0000439315 00000 n +0000439441 00000 n +0000439504 00000 n +0000439694 00000 n +0000439883 00000 n +0000440071 00000 n +0000440134 00000 n +0000440197 00000 n +0000440260 00000 n +0000440322 00000 n +0000439036 00000 n +0000440386 00000 n +0000440449 00000 n +0000440512 00000 n +0000440575 00000 n +0000446202 00000 n +0000443567 00000 n +0000440831 00000 n +0000443863 00000 n +0000443989 00000 n +0000444052 00000 n +0000444116 00000 n +0000444180 00000 n +0000444244 00000 n +0000444307 00000 n +0000444371 00000 n +0000444435 00000 n +0000444498 00000 n +0000444561 00000 n +0000444751 00000 n +0000444814 00000 n +0000443712 00000 n +0000445004 00000 n +0000445067 00000 n +0000445129 00000 n +0000445191 00000 n +0000445253 00000 n +0000445315 00000 n +0000445376 00000 n +0000445440 00000 n +0000445504 00000 n +0000445567 00000 n +0000445631 00000 n +0000445694 00000 n +0000445758 00000 n +0000445822 00000 n +0000445886 00000 n +0000445949 00000 n +0000446012 00000 n +0000446075 00000 n +0000450939 00000 n +0000448615 00000 n +0000446332 00000 n +0000449238 00000 n +0000449301 00000 n +0000449426 00000 n +0000448778 00000 n +0000448927 00000 n +0000449615 00000 n +0000449678 00000 n +0000449868 00000 n +0000449931 00000 n +0000449081 00000 n +0000449995 00000 n +0000450121 00000 n +0000450184 00000 n +0000450248 00000 n +0000450311 00000 n +0000450374 00000 n +0000450438 00000 n +0000450501 00000 n +0000450564 00000 n +0000450687 00000 n +0000450750 00000 n +0000450813 00000 n +0000450876 00000 n +0001002765 00000 n +0000456726 00000 n +0000453542 00000 n +0000451083 00000 n +0000454004 00000 n +0000454067 00000 n +0000454129 00000 n +0000454192 00000 n +0000454319 00000 n +0000454382 00000 n +0000454445 00000 n +0000002526 00000 f +0001001631 00000 n +0000454509 00000 n +0000453696 00000 n +0000454573 00000 n +0000454635 00000 n +0000454699 00000 n +0000454763 00000 n +0000454827 00000 n +0000454891 00000 n +0000454955 00000 n +0000455018 00000 n +0000455081 00000 n +0000455143 00000 n +0000455206 00000 n +0000455270 00000 n +0000455334 00000 n +0000455460 00000 n +0000455523 00000 n +0000455586 00000 n +0000455649 00000 n +0000455713 00000 n +0000455777 00000 n +0000455840 00000 n +0000455904 00000 n +0000455968 00000 n +0000456032 00000 n +0000456095 00000 n +0000456158 00000 n +0000456347 00000 n +0000456473 00000 n +0000456536 00000 n +0000456600 00000 n +0000456663 00000 n +0000453851 00000 n +0000462045 00000 n +0000459459 00000 n +0000456898 00000 n +0000459773 00000 n +0000459836 00000 n +0000459899 00000 n +0000459962 00000 n +0000460025 00000 n +0000460088 00000 n +0000460151 00000 n +0000460215 00000 n +0000460279 00000 n +0000460405 00000 n +0000460467 00000 n +0000460531 00000 n +0000460594 00000 n +0000460657 00000 n +0000460720 00000 n +0000460783 00000 n +0000460846 00000 n +0000460909 00000 n +0000460972 00000 n +0000461036 00000 n +0000461100 00000 n +0000461290 00000 n +0000461353 00000 n +0000461417 00000 n +0000461480 00000 n +0000461541 00000 n +0000461602 00000 n +0000461792 00000 n +0000461855 00000 n +0000459604 00000 n +0000461918 00000 n +0000467871 00000 n +0000464861 00000 n +0000462189 00000 n +0000465342 00000 n +0000465468 00000 n +0000465015 00000 n +0000465178 00000 n +0000465531 00000 n +0000465657 00000 n +0000465720 00000 n +0000465783 00000 n +0000465846 00000 n +0000465908 00000 n +0000465970 00000 n +0000466033 00000 n +0000466097 00000 n +0000466161 00000 n +0000466224 00000 n +0000466287 00000 n +0000466351 00000 n +0000466414 00000 n +0000466477 00000 n +0000466540 00000 n +0000466604 00000 n +0000466667 00000 n +0000466730 00000 n +0000466794 00000 n +0000466857 00000 n +0000466921 00000 n +0000466985 00000 n +0000467049 00000 n +0000467112 00000 n +0000467176 00000 n +0000467240 00000 n +0000467303 00000 n +0000467366 00000 n +0000467491 00000 n +0000467554 00000 n +0000467617 00000 n +0000467680 00000 n +0000467744 00000 n +0000467808 00000 n +0000473604 00000 n +0000471070 00000 n +0000468029 00000 n +0000471194 00000 n +0000471257 00000 n +0000471320 00000 n +0000471383 00000 n +0000471447 00000 n +0000471511 00000 n +0000471573 00000 n +0000471637 00000 n +0000471700 00000 n +0000471763 00000 n +0000471826 00000 n +0000471889 00000 n +0000471953 00000 n +0000472016 00000 n +0000472080 00000 n +0000472144 00000 n +0000472208 00000 n +0000472271 00000 n +0000472334 00000 n +0000472397 00000 n +0000472461 00000 n +0000472524 00000 n +0000472588 00000 n +0000472651 00000 n +0000472715 00000 n +0000472779 00000 n +0000472843 00000 n +0000472906 00000 n +0000472970 00000 n +0000473034 00000 n +0000473097 00000 n +0000473161 00000 n +0000473224 00000 n +0000473413 00000 n +0000473476 00000 n +0000473540 00000 n +0000479784 00000 n +0000476795 00000 n +0000473762 00000 n +0000477439 00000 n +0000477502 00000 n +0000477566 00000 n +0000477630 00000 n +0000477694 00000 n +0000477758 00000 n +0000477822 00000 n +0000477886 00000 n +0000477949 00000 n +0000478012 00000 n +0000478076 00000 n +0000478140 00000 n +0000478203 00000 n +0000478265 00000 n +0000478328 00000 n +0000478391 00000 n +0000478454 00000 n +0000478517 00000 n +0000478580 00000 n +0000478643 00000 n +0000478707 00000 n +0000478771 00000 n +0000478834 00000 n +0000478897 00000 n +0000478961 00000 n +0000476958 00000 n +0000479151 00000 n +0000479214 00000 n +0000477127 00000 n +0000479278 00000 n +0000479341 00000 n +0000479404 00000 n +0000479467 00000 n +0000477285 00000 n +0000479531 00000 n +0000479595 00000 n +0000479659 00000 n +0000479722 00000 n +0000484723 00000 n +0000482035 00000 n +0000479942 00000 n +0000482334 00000 n +0000482397 00000 n +0000482460 00000 n +0000482524 00000 n +0000482587 00000 n +0000482180 00000 n +0000482775 00000 n +0000482964 00000 n +0000483027 00000 n +0000483090 00000 n +0000483153 00000 n +0000002736 00000 f +0001001536 00000 n +0000483216 00000 n +0000483279 00000 n +0000483343 00000 n +0000483405 00000 n +0000483467 00000 n +0000483530 00000 n +0000483592 00000 n +0000483655 00000 n +0000483718 00000 n +0000483781 00000 n +0000483844 00000 n +0000483907 00000 n +0000483970 00000 n +0000484158 00000 n +0000484220 00000 n +0000484283 00000 n +0000484346 00000 n +0000484409 00000 n +0000484472 00000 n +0000484536 00000 n +0000484598 00000 n +0000484661 00000 n +0001002890 00000 n +0000488956 00000 n +0000487085 00000 n +0000484867 00000 n +0000487380 00000 n +0000487443 00000 n +0000487506 00000 n +0000487568 00000 n +0000487632 00000 n +0000487695 00000 n +0000487884 00000 n +0000487947 00000 n +0000488010 00000 n +0000488073 00000 n +0000488136 00000 n +0000488199 00000 n +0000488389 00000 n +0000487230 00000 n +0000488452 00000 n +0000488515 00000 n +0000488578 00000 n +0000488641 00000 n +0000488704 00000 n +0000488766 00000 n +0000488829 00000 n +0000494988 00000 n +0000492282 00000 n +0000489086 00000 n +0000492584 00000 n +0000492710 00000 n +0000492773 00000 n +0000492836 00000 n +0000492900 00000 n +0000492964 00000 n +0000493027 00000 n +0000493090 00000 n +0000493154 00000 n +0000493218 00000 n +0000493281 00000 n +0000493344 00000 n +0000493533 00000 n +0000493596 00000 n +0000493659 00000 n +0000493722 00000 n +0000493786 00000 n +0000492427 00000 n +0000493849 00000 n +0000493912 00000 n +0000493975 00000 n +0000494038 00000 n +0000494101 00000 n +0000494164 00000 n +0000494227 00000 n +0000494291 00000 n +0000494355 00000 n +0000494419 00000 n +0000494483 00000 n +0000494547 00000 n +0000494610 00000 n +0000494673 00000 n +0000494736 00000 n +0000494797 00000 n +0000494861 00000 n +0000494925 00000 n +0000981747 00000 n +0000499540 00000 n +0000496885 00000 n +0000495132 00000 n +0000497009 00000 n +0000497072 00000 n +0000497135 00000 n +0000497199 00000 n +0000497263 00000 n +0000497327 00000 n +0000497390 00000 n +0000497452 00000 n +0000497515 00000 n +0000497578 00000 n +0000497642 00000 n +0000497705 00000 n +0000497768 00000 n +0000497831 00000 n +0000497894 00000 n +0000497958 00000 n +0000498021 00000 n +0000498084 00000 n +0000498147 00000 n +0000498210 00000 n +0000498274 00000 n +0000498337 00000 n +0000498400 00000 n +0000498463 00000 n +0000498526 00000 n +0000498716 00000 n +0000498779 00000 n +0000498843 00000 n +0000498907 00000 n +0000498970 00000 n +0000499034 00000 n +0000499098 00000 n +0000499161 00000 n +0000499225 00000 n +0000499289 00000 n +0000499352 00000 n +0000499414 00000 n +0000504441 00000 n +0000502354 00000 n +0000499656 00000 n +0000502478 00000 n +0000502604 00000 n +0000502666 00000 n +0000502730 00000 n +0000502794 00000 n +0000502858 00000 n +0000502922 00000 n +0000502986 00000 n +0000503049 00000 n +0000503112 00000 n +0000503176 00000 n +0000503240 00000 n +0000503304 00000 n +0000503368 00000 n +0000503431 00000 n +0000503494 00000 n +0000503682 00000 n +0000503745 00000 n +0000503808 00000 n +0000503998 00000 n +0000504187 00000 n +0000504250 00000 n +0000504314 00000 n +0000509392 00000 n +0000506890 00000 n +0000504571 00000 n +0000507694 00000 n +0000507820 00000 n +0000507062 00000 n +0000507225 00000 n +0000507883 00000 n +0000507946 00000 n +0000508010 00000 n +0000508073 00000 n +0000508136 00000 n +0000508199 00000 n +0000508262 00000 n +0000508325 00000 n +0000508388 00000 n +0000508451 00000 n +0000508638 00000 n +0000508825 00000 n +0000507377 00000 n +0000507546 00000 n +0000508888 00000 n +0000508951 00000 n +0000509014 00000 n +0000509077 00000 n +0000509266 00000 n +0000990519 00000 n +0000514798 00000 n +0000512247 00000 n +0000509536 00000 n +0000512708 00000 n +0000512834 00000 n +0000513023 00000 n +0000513086 00000 n +0000513150 00000 n +0000512401 00000 n +0000513339 00000 n +0000513402 00000 n +0000513465 00000 n +0000513529 00000 n +0000513591 00000 n +0000513655 00000 n +0000512554 00000 n +0000513718 00000 n +0000513781 00000 n +0000513844 00000 n +0000513908 00000 n +0000513972 00000 n +0000514036 00000 n +0000514100 00000 n +0000514164 00000 n +0000514228 00000 n +0000514292 00000 n +0000514355 00000 n +0000514419 00000 n 0000000000 00000 f -0000972563 00000 n -0000498010 00000 n -0000498073 00000 n -0000498136 00000 n -0000498199 00000 n -0000498389 00000 n -0000498452 00000 n -0000498516 00000 n -0000498579 00000 n -0000498642 00000 n -0000498705 00000 n -0000498768 00000 n -0000498830 00000 n -0000498893 00000 n -0000498956 00000 n -0000499019 00000 n -0000499082 00000 n -0000499145 00000 n -0000499208 00000 n -0000499271 00000 n -0000499334 00000 n -0000954219 00000 n -0000503071 00000 n -0000501509 00000 n -0000499631 00000 n -0000501810 00000 n -0000502062 00000 n -0000501654 00000 n -0000502250 00000 n -0000502313 00000 n -0000502376 00000 n -0000502440 00000 n -0000502504 00000 n -0000502568 00000 n -0000502757 00000 n -0000502883 00000 n -0000502945 00000 n -0000503008 00000 n -0000975930 00000 n -0000507338 00000 n -0000505191 00000 n -0000503215 00000 n -0000505315 00000 n -0000505441 00000 n -0000505504 00000 n -0000505568 00000 n -0000505631 00000 n -0000505757 00000 n -0000505820 00000 n -0000505883 00000 n -0000505947 00000 n -0000506011 00000 n -0000506074 00000 n -0000506137 00000 n -0000506201 00000 n -0000506265 00000 n -0000506328 00000 n -0000506392 00000 n -0000506455 00000 n -0000506518 00000 n -0000506581 00000 n -0000506771 00000 n -0000506834 00000 n -0000506897 00000 n -0000506960 00000 n -0000507023 00000 n -0000507086 00000 n -0000507149 00000 n -0000507212 00000 n -0000507275 00000 n -0000510997 00000 n -0000509169 00000 n -0000507510 00000 n -0000509293 00000 n -0000509356 00000 n -0000509419 00000 n -0000509482 00000 n -0000509545 00000 n -0000509608 00000 n -0000509798 00000 n -0000509986 00000 n -0000510049 00000 n -0000510112 00000 n -0000510175 00000 n -0000510239 00000 n -0000510303 00000 n -0000510366 00000 n -0000510429 00000 n -0000510492 00000 n -0000510556 00000 n -0000510620 00000 n -0000510809 00000 n -0000510871 00000 n -0000510934 00000 n -0000514694 00000 n -0000512921 00000 n -0000511127 00000 n -0000513045 00000 n -0000513108 00000 n -0000513171 00000 n -0000513235 00000 n -0000513299 00000 n -0000513363 00000 n -0000513427 00000 n -0000513490 00000 n -0000513553 00000 n -0000513615 00000 n -0000513678 00000 n -0000513742 00000 n -0000513805 00000 n -0000513868 00000 n -0000513931 00000 n -0000513995 00000 n -0000514059 00000 n -0000514122 00000 n -0000514185 00000 n -0000514248 00000 n -0000514312 00000 n -0000514376 00000 n -0000514439 00000 n -0000514502 00000 n -0000514566 00000 n -0000514630 00000 n -0000518751 00000 n -0000517047 00000 n -0000514810 00000 n -0000517362 00000 n -0000517425 00000 n -0000517489 00000 n -0000517553 00000 n -0000517742 00000 n -0000517931 00000 n -0000517994 00000 n -0000518057 00000 n -0000518120 00000 n -0000518183 00000 n -0000518246 00000 n -0000518309 00000 n -0000518498 00000 n -0000517192 00000 n -0000518561 00000 n -0000518624 00000 n -0000518687 00000 n -0000520726 00000 n -0000520030 00000 n -0000518909 00000 n -0000520154 00000 n -0000520217 00000 n -0000520280 00000 n -0000520344 00000 n -0000520408 00000 n -0000520472 00000 n -0000520535 00000 n -0000520598 00000 n -0000520662 00000 n -0000525670 00000 n -0000523339 00000 n -0000520870 00000 n -0000523463 00000 n -0000523778 00000 n -0000523841 00000 n -0000523903 00000 n -0000523965 00000 n -0000524028 00000 n -0000524091 00000 n -0000524154 00000 n -0000524217 00000 n -0000524280 00000 n -0000524343 00000 n -0000524406 00000 n -0000524470 00000 n -0000524534 00000 n -0000524598 00000 n -0000524661 00000 n -0000524724 00000 n -0000524787 00000 n -0000524850 00000 n -0000524913 00000 n -0000524975 00000 n -0000525039 00000 n -0000525102 00000 n -0000525165 00000 n -0000525228 00000 n -0000525292 00000 n -0000525355 00000 n -0000525418 00000 n -0000525481 00000 n -0000525544 00000 n -0000525608 00000 n -0000976055 00000 n -0000529774 00000 n -0000528263 00000 n -0000525786 00000 n -0000528387 00000 n -0000528450 00000 n -0000528512 00000 n -0000528575 00000 n -0000528638 00000 n -0000528701 00000 n -0000528764 00000 n -0000528827 00000 n -0000528891 00000 n -0000528954 00000 n -0000529017 00000 n -0000529080 00000 n -0000529143 00000 n -0000529206 00000 n -0000529269 00000 n -0000529332 00000 n -0000529396 00000 n -0000529459 00000 n -0000529522 00000 n -0000529585 00000 n -0000529648 00000 n -0000529711 00000 n -0000534237 00000 n -0000532416 00000 n -0000529904 00000 n -0000532540 00000 n -0000532603 00000 n -0000532665 00000 n -0000532728 00000 n -0000532791 00000 n -0000532854 00000 n -0000532917 00000 n -0000532980 00000 n -0000533043 00000 n -0000533106 00000 n -0000533169 00000 n -0000533232 00000 n -0000533295 00000 n -0000533358 00000 n -0000533421 00000 n -0000533485 00000 n -0000533546 00000 n -0000533609 00000 n -0000533672 00000 n -0000533735 00000 n -0000533798 00000 n -0000534112 00000 n -0000534175 00000 n -0000539217 00000 n -0000536901 00000 n -0000534353 00000 n -0000537200 00000 n -0000537515 00000 n -0000537578 00000 n -0000537642 00000 n -0000537706 00000 n -0000537769 00000 n -0000537831 00000 n -0000538020 00000 n -0000538146 00000 n -0000538209 00000 n -0000538273 00000 n -0000538336 00000 n -0000537046 00000 n -0000538399 00000 n -0000538523 00000 n -0000538586 00000 n -0000538649 00000 n -0000538711 00000 n -0000538774 00000 n -0000538837 00000 n -0000538900 00000 n -0000538963 00000 n -0000539026 00000 n -0000539089 00000 n -0000539153 00000 n -0000546139 00000 n -0000542738 00000 n -0000539347 00000 n -0000542862 00000 n -0000543113 00000 n -0000543176 00000 n -0000543239 00000 n -0000543302 00000 n -0000543365 00000 n -0000543428 00000 n -0000543492 00000 n -0000543554 00000 n -0000543617 00000 n -0000543680 00000 n -0000543743 00000 n -0000543806 00000 n -0000543869 00000 n -0000543932 00000 n -0000543995 00000 n -0000544058 00000 n -0000544121 00000 n -0000544185 00000 n -0000544248 00000 n -0000544311 00000 n -0000544375 00000 n -0000544438 00000 n -0000544502 00000 n -0000544565 00000 n -0000544628 00000 n -0000544691 00000 n -0000544754 00000 n -0000544817 00000 n -0000544880 00000 n -0000544943 00000 n -0000545006 00000 n -0000545069 00000 n -0000545132 00000 n -0000545195 00000 n -0000545258 00000 n -0000545321 00000 n -0000545384 00000 n -0000545447 00000 n -0000545510 00000 n -0000545573 00000 n -0000545636 00000 n -0000545699 00000 n -0000545761 00000 n -0000545823 00000 n -0000545886 00000 n -0000545949 00000 n -0000546012 00000 n -0000546076 00000 n -0000550697 00000 n -0000548886 00000 n -0000546283 00000 n -0000549184 00000 n -0000549247 00000 n -0000549310 00000 n -0000549436 00000 n -0000549499 00000 n -0000549031 00000 n -0000549688 00000 n -0000549751 00000 n -0000549815 00000 n -0000549878 00000 n -0000549941 00000 n -0000550004 00000 n -0000550067 00000 n -0000550130 00000 n -0000550192 00000 n -0000550382 00000 n -0000550445 00000 n -0000550508 00000 n -0000550571 00000 n -0000550634 00000 n -0000555476 00000 n -0000553347 00000 n -0000550841 00000 n -0000553648 00000 n -0000553711 00000 n -0000553900 00000 n -0000553492 00000 n -0000553963 00000 n -0000554026 00000 n -0000554089 00000 n -0000554152 00000 n -0000554215 00000 n -0000554278 00000 n -0000554341 00000 n -0000554404 00000 n -0000554467 00000 n -0000554530 00000 n -0000554719 00000 n -0000554782 00000 n -0000554845 00000 n -0000554909 00000 n -0000554972 00000 n -0000555035 00000 n -0000555098 00000 n -0000555161 00000 n -0000555224 00000 n -0000555287 00000 n -0000555350 00000 n -0000976180 00000 n -0000963748 00000 n -0000559962 00000 n -0000557698 00000 n -0000555578 00000 n -0000557822 00000 n -0000557885 00000 n -0000558009 00000 n -0000558072 00000 n -0000558135 00000 n -0000558198 00000 n -0000558261 00000 n -0000558324 00000 n -0000558387 00000 n -0000558450 00000 n -0000558513 00000 n -0000558700 00000 n -0000558763 00000 n -0000558826 00000 n -0000558889 00000 n -0000558952 00000 n -0000559015 00000 n -0000559078 00000 n -0000559141 00000 n -0000559203 00000 n -0000559266 00000 n -0000559329 00000 n -0000559392 00000 n -0000559455 00000 n -0000559644 00000 n -0000559707 00000 n -0000559771 00000 n -0000559835 00000 n -0000564858 00000 n -0000561831 00000 n -0000560078 00000 n -0000561955 00000 n -0000562018 00000 n -0000562143 00000 n -0000562206 00000 n -0000562270 00000 n -0000562334 00000 n -0000562397 00000 n -0000562461 00000 n -0000562525 00000 n -0000562589 00000 n -0000562651 00000 n -0000562714 00000 n -0000562778 00000 n -0000562840 00000 n -0000562903 00000 n -0000562967 00000 n -0000563031 00000 n -0000563094 00000 n -0000563157 00000 n -0000563219 00000 n -0000563282 00000 n -0000563345 00000 n -0000563660 00000 n -0000563723 00000 n -0000563785 00000 n -0000563848 00000 n -0000563911 00000 n -0000563973 00000 n -0000564036 00000 n -0000564099 00000 n -0000564162 00000 n -0000564225 00000 n -0000564288 00000 n -0000564352 00000 n -0000564415 00000 n -0000564478 00000 n -0000564541 00000 n -0000564604 00000 n -0000564668 00000 n -0000564731 00000 n -0000570194 00000 n -0000567354 00000 n -0000564974 00000 n -0000567478 00000 n -0000567602 00000 n -0000567665 00000 n -0000567729 00000 n -0000567793 00000 n -0000567857 00000 n -0000567921 00000 n -0000567983 00000 n -0000568047 00000 n -0000568110 00000 n -0000568300 00000 n -0000568485 00000 n -0000568548 00000 n -0000568611 00000 n -0000568675 00000 n -0000568738 00000 n -0000568801 00000 n -0000568864 00000 n -0000568928 00000 n -0000568991 00000 n -0000569054 00000 n -0000569118 00000 n -0000569181 00000 n -0000569244 00000 n -0000569307 00000 n -0000569371 00000 n -0000569434 00000 n -0000569497 00000 n -0000569561 00000 n -0000569624 00000 n -0000569814 00000 n -0000569877 00000 n -0000569940 00000 n -0000570004 00000 n -0000570067 00000 n -0000576586 00000 n -0000573104 00000 n -0000570310 00000 n -0000573228 00000 n -0000573354 00000 n -0000573417 00000 n -0000573481 00000 n -0000573545 00000 n -0000573609 00000 n -0000573796 00000 n -0000573859 00000 n -0000573923 00000 n -0000574048 00000 n -0000574111 00000 n -0000574237 00000 n -0000574300 00000 n -0000574364 00000 n -0000574428 00000 n -0000574554 00000 n -0000574617 00000 n -0000574680 00000 n -0000574744 00000 n -0000574807 00000 n -0000574870 00000 n -0000574934 00000 n -0000574998 00000 n -0000575062 00000 n -0000575125 00000 n -0000575188 00000 n -0000575252 00000 n -0000575315 00000 n -0000575379 00000 n -0000575442 00000 n -0000575505 00000 n -0000575569 00000 n -0000575633 00000 n -0000575697 00000 n -0000575761 00000 n +0000999648 00000 n +0000514482 00000 n +0000514545 00000 n +0000514608 00000 n +0000514671 00000 n +0001003015 00000 n +0000981304 00000 n +0000519816 00000 n +0000517184 00000 n +0000514942 00000 n +0000517485 00000 n +0000517611 00000 n +0000517674 00000 n +0000517738 00000 n +0000517801 00000 n +0000517864 00000 n +0000517927 00000 n +0000517990 00000 n +0000518052 00000 n +0000518115 00000 n +0000518178 00000 n +0000518241 00000 n +0000518304 00000 n +0000518367 00000 n +0000518430 00000 n +0000518493 00000 n +0000518556 00000 n +0000518870 00000 n +0000517329 00000 n +0000519057 00000 n +0000519120 00000 n +0000519183 00000 n +0000519247 00000 n +0000519311 00000 n +0000519375 00000 n +0000519565 00000 n +0000519691 00000 n +0000519753 00000 n +0000522893 00000 n +0000521440 00000 n +0000520002 00000 n +0000521564 00000 n +0000521627 00000 n +0000521752 00000 n +0000521815 00000 n +0000521879 00000 n +0000521943 00000 n +0000522069 00000 n +0000522132 00000 n +0000522195 00000 n +0000522259 00000 n +0000522323 00000 n +0000522386 00000 n +0000522449 00000 n +0000522513 00000 n +0000522577 00000 n +0000522640 00000 n +0000522704 00000 n +0000522767 00000 n +0000522830 00000 n +0000526903 00000 n +0000524890 00000 n +0000523065 00000 n +0000525014 00000 n +0000525077 00000 n +0000525267 00000 n +0000525330 00000 n +0000525392 00000 n +0000525454 00000 n +0000525517 00000 n +0000525580 00000 n +0000525643 00000 n +0000525706 00000 n +0000525769 00000 n +0000525832 00000 n +0000525895 00000 n +0000525957 00000 n +0000526020 00000 n +0000526083 00000 n +0000526273 00000 n +0000526462 00000 n +0000526525 00000 n +0000526587 00000 n +0000526650 00000 n +0000526714 00000 n +0000526778 00000 n +0000526840 00000 n +0000530247 00000 n +0000528731 00000 n +0000527047 00000 n +0000528855 00000 n +0000528918 00000 n +0000528981 00000 n +0000529045 00000 n +0000529109 00000 n +0000529298 00000 n +0000529361 00000 n +0000529424 00000 n +0000529487 00000 n +0000529550 00000 n +0000529614 00000 n +0000529678 00000 n +0000529742 00000 n +0000529806 00000 n +0000529869 00000 n +0000529932 00000 n +0000529995 00000 n +0000530059 00000 n +0000530121 00000 n +0000530184 00000 n +0000534254 00000 n +0000532362 00000 n +0000530377 00000 n +0000532486 00000 n +0000532549 00000 n +0000532612 00000 n +0000532676 00000 n +0000532740 00000 n +0000532803 00000 n +0000532865 00000 n +0000532928 00000 n +0000532992 00000 n +0000533056 00000 n +0000533118 00000 n +0000533181 00000 n +0000533241 00000 n +0000533305 00000 n +0000533369 00000 n +0000533433 00000 n +0000533497 00000 n +0000533687 00000 n +0000533875 00000 n +0000533938 00000 n +0000534002 00000 n +0000534065 00000 n +0000534128 00000 n +0000534191 00000 n +0000537629 00000 n +0000536297 00000 n +0000534412 00000 n +0000536613 00000 n +0000536676 00000 n +0000536866 00000 n +0000536442 00000 n +0000536929 00000 n +0000536992 00000 n +0000537055 00000 n +0000537119 00000 n +0000537182 00000 n +0000537246 00000 n +0000537310 00000 n +0000537374 00000 n +0000537437 00000 n +0000537501 00000 n +0000537565 00000 n +0001003140 00000 n +0000542573 00000 n +0000540242 00000 n +0000537773 00000 n +0000540366 00000 n +0000540681 00000 n +0000540744 00000 n +0000540806 00000 n +0000540868 00000 n +0000540931 00000 n +0000540994 00000 n +0000541057 00000 n +0000541120 00000 n +0000541183 00000 n +0000541246 00000 n +0000541309 00000 n +0000541373 00000 n +0000541437 00000 n +0000541501 00000 n +0000541564 00000 n +0000541627 00000 n +0000541690 00000 n +0000541753 00000 n +0000541816 00000 n +0000541878 00000 n +0000541942 00000 n +0000542005 00000 n +0000542068 00000 n +0000542131 00000 n +0000542195 00000 n +0000542258 00000 n +0000542321 00000 n +0000542384 00000 n +0000542447 00000 n +0000542511 00000 n +0000547025 00000 n +0000545390 00000 n +0000542689 00000 n +0000545514 00000 n +0000545577 00000 n +0000545639 00000 n +0000545702 00000 n +0000545765 00000 n +0000545828 00000 n +0000545891 00000 n +0000545954 00000 n +0000546018 00000 n +0000546081 00000 n +0000546144 00000 n +0000546207 00000 n +0000546271 00000 n +0000546334 00000 n +0000546397 00000 n +0000546460 00000 n +0000546523 00000 n +0000546586 00000 n +0000546649 00000 n +0000546712 00000 n +0000546775 00000 n +0000546837 00000 n +0000546900 00000 n +0000546963 00000 n +0000551255 00000 n +0000549621 00000 n +0000547155 00000 n +0000549745 00000 n +0000549808 00000 n +0000549871 00000 n +0000549934 00000 n +0000549997 00000 n +0000550060 00000 n +0000550123 00000 n +0000550186 00000 n +0000550248 00000 n +0000550311 00000 n +0000550374 00000 n +0000550438 00000 n +0000550500 00000 n +0000550563 00000 n +0000550626 00000 n +0000550689 00000 n +0000550752 00000 n +0000551066 00000 n +0000551129 00000 n +0000551192 00000 n +0000556371 00000 n +0000553745 00000 n +0000551371 00000 n +0000554040 00000 n +0000554354 00000 n +0000554417 00000 n +0000554481 00000 n +0000554545 00000 n +0000554608 00000 n +0000554670 00000 n +0000554859 00000 n +0000554985 00000 n +0000555048 00000 n +0000555110 00000 n +0000555174 00000 n +0000553890 00000 n +0000555237 00000 n +0000555363 00000 n +0000555426 00000 n +0000555489 00000 n +0000555552 00000 n +0000555615 00000 n +0000555678 00000 n +0000555741 00000 n +0000555804 00000 n +0000555866 00000 n +0000555929 00000 n +0000555993 00000 n +0000556182 00000 n +0000556245 00000 n +0000556308 00000 n +0000563430 00000 n +0000560090 00000 n +0000556501 00000 n +0000560214 00000 n +0000560277 00000 n +0000560340 00000 n +0000560403 00000 n +0000560467 00000 n +0000560530 00000 n +0000560593 00000 n +0000560656 00000 n +0000560719 00000 n +0000560782 00000 n +0000560845 00000 n +0000560908 00000 n +0000560971 00000 n +0000561034 00000 n +0000561097 00000 n +0000561160 00000 n +0000561223 00000 n +0000561286 00000 n +0000561350 00000 n +0000561413 00000 n +0000561476 00000 n +0000561540 00000 n +0000561603 00000 n +0000561667 00000 n +0000561730 00000 n +0000561793 00000 n +0000561856 00000 n +0000561919 00000 n +0000561982 00000 n +0000562045 00000 n +0000562108 00000 n +0000562171 00000 n +0000562234 00000 n +0000562297 00000 n +0000562360 00000 n +0000562423 00000 n +0000562486 00000 n +0000562549 00000 n +0000562612 00000 n +0000562675 00000 n +0000562738 00000 n +0000562801 00000 n +0000562864 00000 n +0000562926 00000 n +0000562988 00000 n +0000563051 00000 n +0000563114 00000 n +0000563177 00000 n +0000563241 00000 n +0000563304 00000 n +0000563367 00000 n +0000567987 00000 n +0000566113 00000 n +0000563574 00000 n +0000566412 00000 n +0000566601 00000 n +0000566664 00000 n +0000566258 00000 n +0000566853 00000 n +0000566916 00000 n +0000566980 00000 n +0000567043 00000 n +0000567106 00000 n +0000567169 00000 n +0000567232 00000 n +0000567295 00000 n +0000567357 00000 n +0000567547 00000 n +0000567610 00000 n +0000567673 00000 n +0000567736 00000 n +0000567799 00000 n +0000567863 00000 n +0001003265 00000 n +0000572925 00000 n +0000570673 00000 n +0000568131 00000 n +0000570974 00000 n +0000571100 00000 n +0000570818 00000 n +0000571163 00000 n +0000571226 00000 n +0000571289 00000 n +0000571352 00000 n +0000571415 00000 n +0000571478 00000 n +0000571541 00000 n +0000571604 00000 n +0000571667 00000 n +0000571730 00000 n +0000571919 00000 n +0000571982 00000 n +0000572045 00000 n +0000572109 00000 n +0000572172 00000 n +0000572235 00000 n +0000572298 00000 n +0000572361 00000 n +0000572424 00000 n +0000572487 00000 n +0000572550 00000 n +0000572737 00000 n +0000572800 00000 n +0000572863 00000 n +0000990833 00000 n +0000578347 00000 n +0000575449 00000 n +0000573027 00000 n +0000575573 00000 n +0000575636 00000 n +0000575699 00000 n +0000575762 00000 n 0000575825 00000 n 0000575888 00000 n -0000575952 00000 n -0000576015 00000 n -0000576077 00000 n -0000576139 00000 n -0000576203 00000 n -0000576267 00000 n -0000576331 00000 n -0000576395 00000 n -0000576459 00000 n -0000576523 00000 n -0000581514 00000 n -0000579049 00000 n -0000576702 00000 n -0000579173 00000 n -0000579299 00000 n -0000579362 00000 n -0000579425 00000 n -0000579488 00000 n -0000579614 00000 n -0000579677 00000 n -0000579740 00000 n -0000579866 00000 n -0000579929 00000 n -0000579993 00000 n -0000580057 00000 n -0000580121 00000 n -0000580184 00000 n -0000580248 00000 n -0000580374 00000 n -0000580437 00000 n -0000580500 00000 n -0000580626 00000 n -0000580689 00000 n -0000580753 00000 n -0000580817 00000 n -0000580881 00000 n -0000581007 00000 n -0000581070 00000 n -0000581196 00000 n -0000581259 00000 n -0000581323 00000 n -0000581387 00000 n -0000581451 00000 n -0000586222 00000 n -0000583768 00000 n -0000581616 00000 n -0000583892 00000 n -0000583955 00000 n -0000584080 00000 n -0000584143 00000 n -0000584332 00000 n -0000584394 00000 n -0000584458 00000 n -0000584521 00000 n -0000584585 00000 n -0000584648 00000 n -0000584712 00000 n -0000584776 00000 n -0000584966 00000 n -0000585029 00000 n -0000585091 00000 n -0000585281 00000 n -0000585343 00000 n -0000585532 00000 n -0000585594 00000 n -0000585657 00000 n -0000585720 00000 n -0000585909 00000 n -0000585972 00000 n -0000586033 00000 n -0000586096 00000 n -0000586159 00000 n -0000976305 00000 n -0000591136 00000 n -0000589188 00000 n -0000586366 00000 n -0000589312 00000 n -0000589375 00000 n -0000589564 00000 n -0000589627 00000 n -0000589689 00000 n -0000589752 00000 n -0000589815 00000 n -0000589877 00000 n -0000589940 00000 n -0000590003 00000 n -0000590066 00000 n -0000590128 00000 n -0000590191 00000 n -0000590254 00000 n -0000590317 00000 n -0000590380 00000 n -0000590443 00000 n -0000590505 00000 n -0000590694 00000 n -0000590757 00000 n -0000590820 00000 n -0000590884 00000 n -0000590947 00000 n -0000591010 00000 n -0000596677 00000 n -0000594028 00000 n -0000591238 00000 n -0000594152 00000 n +0000575951 00000 n +0000576138 00000 n +0000576201 00000 n +0000576264 00000 n +0000576326 00000 n +0000576389 00000 n +0000576452 00000 n +0000576515 00000 n +0000576578 00000 n +0000576641 00000 n +0000576704 00000 n +0000576767 00000 n +0000576830 00000 n +0000576893 00000 n +0000577081 00000 n +0000577144 00000 n +0000577208 00000 n +0000577272 00000 n +0000577461 00000 n +0000577524 00000 n +0000577588 00000 n +0000577651 00000 n +0000577714 00000 n +0000577778 00000 n +0000577840 00000 n +0000577903 00000 n +0000577967 00000 n +0000578030 00000 n +0000578093 00000 n +0000578155 00000 n +0000578219 00000 n +0000578283 00000 n +0000583726 00000 n +0000580442 00000 n +0000578463 00000 n +0000580566 00000 n +0000580629 00000 n +0000580692 00000 n +0000580755 00000 n +0000580819 00000 n +0000580882 00000 n +0000580945 00000 n +0000581009 00000 n +0000581073 00000 n +0000581136 00000 n +0000581199 00000 n +0000581262 00000 n +0000581326 00000 n +0000581389 00000 n +0000581704 00000 n +0000581767 00000 n +0000581831 00000 n +0000581894 00000 n +0000581957 00000 n +0000582020 00000 n +0000582083 00000 n +0000582145 00000 n +0000582207 00000 n +0000582270 00000 n +0000582333 00000 n +0000582397 00000 n +0000582460 00000 n +0000582523 00000 n +0000582586 00000 n +0000582649 00000 n +0000582713 00000 n +0000582776 00000 n +0000582963 00000 n +0000583026 00000 n +0000583090 00000 n +0000583154 00000 n +0000583218 00000 n +0000583282 00000 n +0000583345 00000 n +0000583409 00000 n +0000583472 00000 n +0000583536 00000 n +0000583599 00000 n +0000588867 00000 n +0000585968 00000 n +0000583842 00000 n +0000586092 00000 n +0000586155 00000 n +0000586280 00000 n +0000586465 00000 n +0000586528 00000 n +0000586591 00000 n +0000586655 00000 n +0000586719 00000 n +0000586782 00000 n +0000586845 00000 n +0000586909 00000 n +0000586972 00000 n +0000587035 00000 n +0000587099 00000 n +0000587162 00000 n +0000587225 00000 n +0000587288 00000 n +0000587352 00000 n +0000587415 00000 n +0000587478 00000 n +0000587542 00000 n +0000587605 00000 n +0000587793 00000 n +0000587856 00000 n +0000587919 00000 n +0000587983 00000 n +0000588046 00000 n +0000588235 00000 n +0000588298 00000 n +0000588362 00000 n +0000588426 00000 n +0000588490 00000 n +0000588678 00000 n +0000588741 00000 n +0000588804 00000 n +0000594782 00000 n +0000591742 00000 n +0000588983 00000 n +0000591866 00000 n +0000591992 00000 n +0000592118 00000 n +0000592181 00000 n +0000592245 00000 n +0000592309 00000 n +0000592435 00000 n +0000592498 00000 n +0000592561 00000 n +0000592625 00000 n +0000592688 00000 n +0000592751 00000 n +0000592815 00000 n +0000592879 00000 n +0000592943 00000 n +0000593006 00000 n +0000593069 00000 n +0000593133 00000 n +0000593196 00000 n +0000593260 00000 n +0000593323 00000 n +0000593386 00000 n +0000593450 00000 n +0000593514 00000 n +0000593578 00000 n +0000593642 00000 n +0000593706 00000 n +0000593769 00000 n +0000593833 00000 n +0000593896 00000 n +0000593958 00000 n +0000594020 00000 n +0000594084 00000 n +0000594148 00000 n +0000594212 00000 n +0000594276 00000 n 0000594340 00000 n -0000594403 00000 n -0000594467 00000 n +0000594404 00000 n 0000594530 00000 n 0000594593 00000 n 0000594656 00000 n -0000594720 00000 n -0000594783 00000 n -0000594847 00000 n -0000594910 00000 n -0000594973 00000 n -0000595163 00000 n -0000595226 00000 n -0000595289 00000 n -0000595351 00000 n -0000595414 00000 n -0000595478 00000 n -0000595541 00000 n -0000595603 00000 n -0000595666 00000 n -0000595729 00000 n -0000595792 00000 n -0000595855 00000 n -0000595918 00000 n -0000595982 00000 n -0000596046 00000 n -0000596110 00000 n -0000596174 00000 n -0000596237 00000 n -0000596300 00000 n -0000596363 00000 n -0000596426 00000 n -0000596490 00000 n -0000596553 00000 n -0000596616 00000 n -0000600988 00000 n -0000598916 00000 n -0000596793 00000 n -0000599040 00000 n -0000599103 00000 n -0000599165 00000 n -0000599291 00000 n -0000599354 00000 n -0000599417 00000 n -0000599480 00000 n -0000599543 00000 n -0000599606 00000 n -0000599669 00000 n -0000599732 00000 n -0000599921 00000 n -0000599984 00000 n -0000600047 00000 n -0000600110 00000 n -0000600173 00000 n -0000600235 00000 n -0000600298 00000 n -0000600361 00000 n -0000600423 00000 n -0000600482 00000 n -0000600545 00000 n -0000600608 00000 n -0000600671 00000 n -0000600735 00000 n -0000600799 00000 n -0000600862 00000 n -0000604045 00000 n -0000602474 00000 n -0000601104 00000 n -0000602598 00000 n -0000602849 00000 n -0000603038 00000 n -0000603101 00000 n -0000603290 00000 n -0000603353 00000 n -0000603416 00000 n -0000603479 00000 n -0000603542 00000 n -0000603605 00000 n -0000603668 00000 n -0000603731 00000 n -0000603794 00000 n -0000603856 00000 n -0000603919 00000 n -0000603982 00000 n -0000607952 00000 n -0000606695 00000 n -0000604161 00000 n -0000606819 00000 n -0000607007 00000 n -0000607070 00000 n -0000607132 00000 n -0000607195 00000 n -0000607258 00000 n -0000607321 00000 n -0000607510 00000 n -0000607573 00000 n -0000607636 00000 n -0000607699 00000 n -0000607762 00000 n -0000607825 00000 n -0000613664 00000 n -0000611163 00000 n -0000608096 00000 n -0000611964 00000 n -0000612090 00000 n -0000612153 00000 n -0000612216 00000 n -0000612279 00000 n -0000611335 00000 n -0000612342 00000 n -0000612405 00000 n -0000611489 00000 n -0000612468 00000 n -0000612531 00000 n -0000611648 00000 n -0000612594 00000 n -0000611806 00000 n -0000612657 00000 n -0000612720 00000 n -0000612783 00000 n -0000612847 00000 n -0000612910 00000 n -0000613099 00000 n -0000613162 00000 n -0000613223 00000 n -0000613286 00000 n -0000613349 00000 n -0000613411 00000 n -0000613474 00000 n -0000613537 00000 n -0000613601 00000 n -0000976430 00000 n -0000618051 00000 n -0000616095 00000 n -0000613822 00000 n -0000616219 00000 n -0000616282 00000 n -0000616345 00000 n -0000616408 00000 n -0000616472 00000 n -0000616536 00000 n -0000616726 00000 n -0000616789 00000 n -0000616852 00000 n -0000616915 00000 n -0000616979 00000 n -0000617042 00000 n -0000617105 00000 n -0000617168 00000 n -0000617231 00000 n -0000617294 00000 n -0000617357 00000 n -0000617420 00000 n -0000617483 00000 n -0000617546 00000 n -0000617609 00000 n -0000617672 00000 n -0000617734 00000 n -0000617797 00000 n -0000617861 00000 n -0000617925 00000 n -0000617988 00000 n -0000622725 00000 n -0000620596 00000 n -0000618209 00000 n -0000620895 00000 n -0000621084 00000 n -0000621147 00000 n -0000621211 00000 n -0000621275 00000 n -0000621338 00000 n -0000621400 00000 n -0000621463 00000 n -0000621526 00000 n -0000621589 00000 n -0000621652 00000 n -0000621715 00000 n -0000621778 00000 n -0000621841 00000 n -0000621905 00000 n -0000620741 00000 n -0000622095 00000 n -0000622158 00000 n -0000622222 00000 n -0000622285 00000 n -0000622348 00000 n -0000622407 00000 n -0000622470 00000 n -0000622534 00000 n -0000622598 00000 n -0000622661 00000 n -0000628108 00000 n -0000625489 00000 n -0000622897 00000 n -0000625955 00000 n -0000626144 00000 n -0000626207 00000 n -0000626271 00000 n -0000626585 00000 n -0000626773 00000 n -0000625643 00000 n -0000626836 00000 n -0000626899 00000 n -0000626963 00000 n -0000627027 00000 n -0000625798 00000 n -0000627091 00000 n -0000627155 00000 n -0000627219 00000 n -0000627283 00000 n -0000627347 00000 n -0000627410 00000 n -0000627474 00000 n -0000627537 00000 n -0000627600 00000 n -0000627664 00000 n -0000627728 00000 n -0000627918 00000 n -0000627981 00000 n -0000957548 00000 n -0000967512 00000 n -0000632700 00000 n -0000629962 00000 n -0000628252 00000 n -0000630621 00000 n -0000630872 00000 n -0000630125 00000 n -0000631060 00000 n -0000631123 00000 n -0000631187 00000 n -0000631251 00000 n -0000631377 00000 n -0000631440 00000 n -0000631503 00000 n -0000631566 00000 n -0000631630 00000 n -0000631755 00000 n -0000631818 00000 n -0000631881 00000 n -0000631944 00000 n -0000632008 00000 n -0000632071 00000 n -0000632133 00000 n -0000632196 00000 n -0000630289 00000 n -0000632385 00000 n -0000630460 00000 n -0000632510 00000 n -0000632573 00000 n -0000632637 00000 n -0000640232 00000 n -0000635036 00000 n -0000632858 00000 n -0000635503 00000 n -0000635818 00000 n -0000635881 00000 n -0000635945 00000 n -0000636007 00000 n -0000635190 00000 n -0000635348 00000 n -0000636070 00000 n -0000636133 00000 n -0000636196 00000 n -0000636259 00000 n -0000636322 00000 n -0000636385 00000 n -0000636448 00000 n -0000636512 00000 n -0000636576 00000 n -0000636640 00000 n -0000636704 00000 n -0000636767 00000 n -0000636830 00000 n -0000636893 00000 n -0000636956 00000 n -0000637019 00000 n -0000637082 00000 n -0000637145 00000 n -0000637204 00000 n -0000637264 00000 n -0000637324 00000 n -0000637387 00000 n -0000637450 00000 n -0000637513 00000 n -0000637576 00000 n -0000637639 00000 n -0000637702 00000 n -0000637765 00000 n -0000637828 00000 n -0000637892 00000 n -0000637955 00000 n -0000638019 00000 n -0000638083 00000 n -0000638147 00000 n -0000638210 00000 n -0000638273 00000 n -0000638335 00000 n -0000638397 00000 n -0000638461 00000 n -0000638524 00000 n -0000638588 00000 n -0000638652 00000 n -0000638716 00000 n -0000638780 00000 n -0000638844 00000 n -0000638908 00000 n -0000638972 00000 n -0000639036 00000 n -0000639100 00000 n -0000639163 00000 n -0000639225 00000 n -0000639288 00000 n -0000639351 00000 n -0000639415 00000 n -0000639478 00000 n -0000639541 00000 n -0000639604 00000 n -0000639667 00000 n -0000639730 00000 n -0000639792 00000 n -0000639855 00000 n -0000639918 00000 n -0000639981 00000 n -0000640044 00000 n -0000640107 00000 n -0000640170 00000 n -0000947483 00000 n -0000644645 00000 n -0000642605 00000 n -0000640376 00000 n -0000643059 00000 n -0000643122 00000 n -0000643186 00000 n -0000643250 00000 n -0000643314 00000 n -0000643377 00000 n -0000642759 00000 n -0000643566 00000 n -0000643629 00000 n -0000643692 00000 n -0000642907 00000 n -0000643755 00000 n -0000643819 00000 n -0000643883 00000 n -0000643947 00000 n -0000644263 00000 n -0000644326 00000 n -0000644390 00000 n -0000644454 00000 n -0000644518 00000 n -0000644581 00000 n -0000976555 00000 n -0000957928 00000 n -0000649487 00000 n -0000647284 00000 n -0000644803 00000 n -0000647408 00000 n -0000647723 00000 n -0000647786 00000 n -0000647973 00000 n -0000648036 00000 n -0000648099 00000 n -0000648162 00000 n -0000648224 00000 n -0000648287 00000 n -0000648351 00000 n -0000648415 00000 n -0000648478 00000 n -0000648541 00000 n -0000648604 00000 n -0000648667 00000 n -0000648731 00000 n -0000648795 00000 n -0000648984 00000 n -0000649047 00000 n -0000649110 00000 n -0000649173 00000 n -0000649235 00000 n -0000649298 00000 n -0000649361 00000 n -0000649424 00000 n -0000657369 00000 n -0000653343 00000 n -0000649589 00000 n -0000653467 00000 n -0000653592 00000 n -0000653655 00000 n -0000653718 00000 n -0000653781 00000 n -0000653844 00000 n -0000653907 00000 n -0000653970 00000 n -0000654033 00000 n -0000654096 00000 n -0000654159 00000 n -0000654222 00000 n -0000654285 00000 n -0000654348 00000 n -0000654410 00000 n -0000654473 00000 n -0000654536 00000 n -0000654599 00000 n -0000654662 00000 n -0000654725 00000 n -0000654788 00000 n -0000654851 00000 n -0000654914 00000 n -0000654975 00000 n -0000655038 00000 n -0000655101 00000 n -0000655164 00000 n -0000655227 00000 n -0000655290 00000 n -0000655353 00000 n -0000655416 00000 n -0000655479 00000 n -0000655542 00000 n -0000655605 00000 n -0000655668 00000 n -0000655731 00000 n -0000655794 00000 n -0000655857 00000 n -0000655920 00000 n -0000655983 00000 n -0000656046 00000 n -0000656109 00000 n -0000656172 00000 n -0000656235 00000 n -0000656298 00000 n -0000656361 00000 n -0000656424 00000 n -0000656488 00000 n -0000656552 00000 n -0000656614 00000 n -0000656677 00000 n -0000656740 00000 n -0000656803 00000 n -0000656866 00000 n -0000656929 00000 n -0000656992 00000 n -0000657054 00000 n -0000657117 00000 n -0000657180 00000 n -0000657243 00000 n -0000657306 00000 n -0000658548 00000 n -0000710246 00000 n -0000658403 00000 n -0000657457 00000 n -0000709553 00000 n -0000709616 00000 n -0000709741 00000 n -0000709394 00000 n -0000709803 00000 n -0000709867 00000 n -0000709994 00000 n -0000710183 00000 n -0000715326 00000 n -0000712807 00000 n -0000710399 00000 n -0000712931 00000 n -0000712994 00000 n -0000713056 00000 n -0000713120 00000 n -0000713308 00000 n -0000713371 00000 n -0000713433 00000 n -0000713496 00000 n -0000713560 00000 n -0000713623 00000 n -0000713686 00000 n -0000713749 00000 n -0000713812 00000 n -0000713875 00000 n -0000713938 00000 n -0000714001 00000 n -0000714064 00000 n -0000714127 00000 n -0000714190 00000 n -0000714253 00000 n -0000714316 00000 n -0000714505 00000 n -0000714693 00000 n -0000714756 00000 n -0000714820 00000 n -0000714882 00000 n -0000714946 00000 n -0000715009 00000 n -0000715073 00000 n -0000715136 00000 n -0000715200 00000 n -0000715263 00000 n -0000720113 00000 n -0000718409 00000 n -0000715428 00000 n -0000718533 00000 n -0000718596 00000 n -0000718660 00000 n -0000718849 00000 n -0000718912 00000 n -0000718976 00000 n -0000719039 00000 n -0000719103 00000 n -0000719166 00000 n -0000719354 00000 n -0000719417 00000 n -0000719481 00000 n -0000719545 00000 n -0000719608 00000 n -0000719798 00000 n -0000719861 00000 n -0000719924 00000 n -0000719987 00000 n -0000720050 00000 n -0000725330 00000 n -0000723065 00000 n -0000720229 00000 n -0000723369 00000 n -0000723558 00000 n -0000723621 00000 n -0000723685 00000 n -0000723210 00000 n -0000723748 00000 n -0000723810 00000 n -0000723874 00000 n -0000723938 00000 n -0000724254 00000 n -0000724317 00000 n -0000724381 00000 n -0000724444 00000 n -0000724507 00000 n -0000724570 00000 n -0000724633 00000 n -0000724697 00000 n -0000724761 00000 n -0000724824 00000 n -0000724887 00000 n -0000724951 00000 n -0000725014 00000 n -0000725077 00000 n -0000725140 00000 n -0000725203 00000 n -0000725267 00000 n -0000976680 00000 n -0000729982 00000 n -0000728409 00000 n -0000725446 00000 n -0000728533 00000 n -0000728596 00000 n -0000728659 00000 n -0000728723 00000 n -0000728785 00000 n -0000728848 00000 n -0000728911 00000 n -0000728973 00000 n -0000729037 00000 n -0000729100 00000 n -0000729288 00000 n -0000729351 00000 n -0000729415 00000 n -0000729604 00000 n -0000729667 00000 n -0000729730 00000 n -0000729792 00000 n -0000729855 00000 n -0000729918 00000 n -0000734200 00000 n -0000732630 00000 n -0000730112 00000 n -0000732754 00000 n -0000732879 00000 n -0000732943 00000 n -0000733006 00000 n -0000733195 00000 n -0000733258 00000 n -0000733321 00000 n -0000733383 00000 n -0000733571 00000 n -0000733759 00000 n -0000733948 00000 n -0000734137 00000 n -0000737584 00000 n -0000736137 00000 n -0000734302 00000 n -0000736261 00000 n -0000736387 00000 n -0000736576 00000 n -0000736639 00000 n -0000736828 00000 n -0000737017 00000 n -0000737206 00000 n -0000737269 00000 n -0000737333 00000 n -0000737396 00000 n -0000737459 00000 n -0000742093 00000 n -0000740267 00000 n -0000737686 00000 n -0000740391 00000 n -0000740517 00000 n -0000740580 00000 n -0000740768 00000 n -0000740830 00000 n -0000740894 00000 n -0000741082 00000 n -0000741145 00000 n -0000741209 00000 n -0000741272 00000 n -0000741335 00000 n -0000741399 00000 n -0000741462 00000 n -0000741651 00000 n -0000741840 00000 n -0000741902 00000 n -0000741966 00000 n -0000747524 00000 n -0000744873 00000 n -0000742209 00000 n -0000744997 00000 n -0000745123 00000 n -0000745186 00000 n -0000745249 00000 n -0000745312 00000 n -0000745375 00000 n -0000745438 00000 n -0000745501 00000 n -0000745564 00000 n -0000745627 00000 n -0000745690 00000 n -0000745753 00000 n -0000745817 00000 n -0000745880 00000 n -0000745943 00000 n -0000746131 00000 n -0000746194 00000 n -0000746257 00000 n -0000746321 00000 n -0000746384 00000 n -0000746447 00000 n -0000746510 00000 n -0000746574 00000 n -0000746638 00000 n -0000746702 00000 n -0000746765 00000 n -0000746829 00000 n -0000746893 00000 n -0000746955 00000 n -0000747018 00000 n -0000747081 00000 n -0000747144 00000 n -0000747208 00000 n -0000747271 00000 n -0000747334 00000 n -0000747397 00000 n -0000747461 00000 n -0000752552 00000 n -0000750286 00000 n -0000747654 00000 n -0000750410 00000 n -0000750473 00000 n -0000750535 00000 n -0000750598 00000 n -0000750662 00000 n -0000750725 00000 n -0000750788 00000 n -0000750852 00000 n -0000750915 00000 n -0000750978 00000 n -0000751042 00000 n -0000751105 00000 n -0000751168 00000 n -0000751232 00000 n -0000751295 00000 n -0000751358 00000 n -0000751421 00000 n -0000751484 00000 n -0000751547 00000 n -0000751611 00000 n -0000751674 00000 n -0000751736 00000 n -0000751800 00000 n -0000751863 00000 n -0000751927 00000 n -0000751990 00000 n -0000752052 00000 n -0000752238 00000 n -0000752427 00000 n -0000976805 00000 n -0000756644 00000 n -0000755388 00000 n -0000752668 00000 n -0000755512 00000 n -0000755575 00000 n -0000755700 00000 n -0000755763 00000 n -0000755826 00000 n -0000755889 00000 n -0000756077 00000 n -0000756140 00000 n -0000756203 00000 n -0000756266 00000 n -0000756329 00000 n -0000756392 00000 n -0000756581 00000 n -0000760858 00000 n -0000759538 00000 n -0000756760 00000 n -0000759662 00000 n -0000759725 00000 n -0000759788 00000 n -0000759851 00000 n -0000760040 00000 n -0000760103 00000 n -0000760292 00000 n -0000760355 00000 n -0000760418 00000 n -0000760481 00000 n -0000760544 00000 n -0000760606 00000 n -0000760669 00000 n -0000760732 00000 n -0000765443 00000 n -0000763637 00000 n -0000760960 00000 n -0000764124 00000 n -0000764187 00000 n -0000764310 00000 n -0000764372 00000 n -0000764435 00000 n -0000764499 00000 n -0000764562 00000 n -0000764625 00000 n -0000763791 00000 n -0000764688 00000 n -0000764751 00000 n -0000763955 00000 n -0000764940 00000 n -0000765003 00000 n -0000765066 00000 n -0000765254 00000 n -0000765317 00000 n -0000765380 00000 n -0000769781 00000 n -0000768545 00000 n -0000765559 00000 n -0000768836 00000 n -0000768899 00000 n -0000768963 00000 n -0000769026 00000 n -0000769089 00000 n -0000769278 00000 n -0000769341 00000 n -0000769403 00000 n -0000768690 00000 n -0000769466 00000 n -0000769529 00000 n -0000769592 00000 n -0000769655 00000 n -0000769718 00000 n -0000771497 00000 n -0000770931 00000 n -0000769897 00000 n -0000771055 00000 n -0000771118 00000 n -0000771308 00000 n -0000771371 00000 n -0000771434 00000 n -0000776572 00000 n -0000774178 00000 n +0000594719 00000 n +0000599479 00000 n +0000597015 00000 n +0000594884 00000 n +0000597139 00000 n +0000597202 00000 n +0000597327 00000 n +0000597390 00000 n +0000597453 00000 n +0000597579 00000 n +0000597641 00000 n +0000597705 00000 n +0000597769 00000 n +0000597833 00000 n +0000597896 00000 n +0000597960 00000 n +0000598086 00000 n +0000598149 00000 n +0000598212 00000 n +0000598338 00000 n +0000598401 00000 n +0000598465 00000 n +0000598529 00000 n +0000598593 00000 n +0000598719 00000 n +0000598782 00000 n +0000598908 00000 n +0000598971 00000 n +0000599035 00000 n +0000599099 00000 n +0000599163 00000 n +0000599289 00000 n +0000599352 00000 n +0001003390 00000 n +0000604960 00000 n +0000602255 00000 n +0000599581 00000 n +0000602559 00000 n +0000602685 00000 n +0000602748 00000 n +0000602812 00000 n +0000602875 00000 n +0000602938 00000 n +0000603002 00000 n +0000603192 00000 n +0000603255 00000 n +0000603318 00000 n +0000603508 00000 n +0000603571 00000 n +0000603761 00000 n +0000603824 00000 n +0000603887 00000 n +0000603950 00000 n +0000604013 00000 n +0000604076 00000 n +0000604139 00000 n +0000604202 00000 n +0000604266 00000 n +0000604330 00000 n +0000604393 00000 n +0000604456 00000 n +0000604519 00000 n +0000604582 00000 n +0000604645 00000 n +0000602400 00000 n +0000604708 00000 n +0000604771 00000 n +0000604834 00000 n +0000604897 00000 n +0000609870 00000 n +0000607325 00000 n +0000605090 00000 n +0000607793 00000 n +0000607856 00000 n +0000607919 00000 n +0000607479 00000 n +0000607982 00000 n +0000608045 00000 n +0000608108 00000 n +0000608171 00000 n +0000608232 00000 n +0000608295 00000 n +0000608484 00000 n +0000607633 00000 n +0000608672 00000 n +0000608860 00000 n +0000608923 00000 n +0000609113 00000 n +0000609176 00000 n +0000609240 00000 n +0000609304 00000 n +0000609492 00000 n +0000609555 00000 n +0000609618 00000 n +0000609681 00000 n +0000609744 00000 n +0000609807 00000 n +0000614703 00000 n +0000612755 00000 n +0000609986 00000 n +0000612879 00000 n +0000612942 00000 n +0000613131 00000 n +0000613194 00000 n +0000613257 00000 n +0000613320 00000 n +0000613382 00000 n +0000613445 00000 n +0000613508 00000 n +0000613570 00000 n +0000613632 00000 n +0000613695 00000 n +0000613758 00000 n +0000613821 00000 n +0000613884 00000 n +0000613947 00000 n +0000614010 00000 n +0000614073 00000 n +0000614262 00000 n +0000614324 00000 n +0000614387 00000 n +0000614451 00000 n +0000614514 00000 n +0000614577 00000 n +0000620245 00000 n +0000617596 00000 n +0000614805 00000 n +0000617720 00000 n +0000617908 00000 n +0000617971 00000 n +0000618035 00000 n +0000618098 00000 n +0000618161 00000 n +0000618224 00000 n +0000618288 00000 n +0000618351 00000 n +0000618415 00000 n +0000618478 00000 n +0000618541 00000 n +0000618731 00000 n +0000618794 00000 n +0000618857 00000 n +0000618919 00000 n +0000618982 00000 n +0000619046 00000 n +0000619109 00000 n +0000619171 00000 n +0000619234 00000 n +0000619297 00000 n +0000619360 00000 n +0000619423 00000 n +0000619486 00000 n +0000619550 00000 n +0000619614 00000 n +0000619678 00000 n +0000619742 00000 n +0000619805 00000 n +0000619868 00000 n +0000619931 00000 n +0000619994 00000 n +0000620058 00000 n +0000620121 00000 n +0000620184 00000 n +0000624556 00000 n +0000622484 00000 n +0000620361 00000 n +0000622608 00000 n +0000622671 00000 n +0000622733 00000 n +0000622859 00000 n +0000622922 00000 n +0000622985 00000 n +0000623048 00000 n +0000623111 00000 n +0000623174 00000 n +0000623237 00000 n +0000623300 00000 n +0000623489 00000 n +0000623552 00000 n +0000623615 00000 n +0000623678 00000 n +0000623741 00000 n +0000623803 00000 n +0000623866 00000 n +0000623929 00000 n +0000623991 00000 n +0000624050 00000 n +0000624113 00000 n +0000624176 00000 n +0000624239 00000 n +0000624303 00000 n +0000624367 00000 n +0000624430 00000 n +0000627613 00000 n +0000626042 00000 n +0000624672 00000 n +0000626166 00000 n +0000626417 00000 n +0000626606 00000 n +0000626669 00000 n +0000626858 00000 n +0000626921 00000 n +0000626984 00000 n +0000627047 00000 n +0000627110 00000 n +0000627173 00000 n +0000627236 00000 n +0000627299 00000 n +0000627362 00000 n +0000627424 00000 n +0000627487 00000 n +0000627550 00000 n +0001003515 00000 n +0000631434 00000 n +0000630115 00000 n +0000627729 00000 n +0000630239 00000 n +0000630427 00000 n +0000630490 00000 n +0000630552 00000 n +0000630615 00000 n +0000630678 00000 n +0000630741 00000 n +0000630930 00000 n +0000630993 00000 n +0000631057 00000 n +0000631120 00000 n +0000631182 00000 n +0000631245 00000 n +0000631307 00000 n +0000637379 00000 n +0000634713 00000 n +0000631578 00000 n +0000635676 00000 n +0000635802 00000 n +0000635865 00000 n +0000634894 00000 n +0000635928 00000 n +0000635991 00000 n +0000636181 00000 n +0000636244 00000 n +0000636307 00000 n +0000636370 00000 n +0000635048 00000 n +0000636433 00000 n +0000636496 00000 n +0000635202 00000 n +0000636559 00000 n +0000636622 00000 n +0000635360 00000 n +0000636685 00000 n +0000635519 00000 n +0000636748 00000 n +0000636811 00000 n +0000636874 00000 n +0000636938 00000 n +0000637001 00000 n +0000637191 00000 n +0000637253 00000 n +0000637316 00000 n +0000641837 00000 n +0000639631 00000 n +0000637509 00000 n +0000639755 00000 n +0000639818 00000 n +0000639881 00000 n +0000639943 00000 n +0000640006 00000 n +0000640069 00000 n +0000640133 00000 n +0000640196 00000 n +0000640259 00000 n +0000640321 00000 n +0000640385 00000 n +0000640449 00000 n +0000640639 00000 n +0000640702 00000 n +0000640765 00000 n +0000640828 00000 n +0000640892 00000 n +0000640955 00000 n +0000641018 00000 n +0000641080 00000 n +0000641143 00000 n +0000641206 00000 n +0000641269 00000 n +0000641332 00000 n +0000641395 00000 n +0000641457 00000 n +0000641520 00000 n +0000641583 00000 n +0000641646 00000 n +0000641709 00000 n +0000641773 00000 n +0000646546 00000 n +0000644414 00000 n +0000641995 00000 n +0000644713 00000 n +0000644776 00000 n +0000644839 00000 n +0000645028 00000 n +0000645091 00000 n +0000645155 00000 n +0000645219 00000 n +0000645282 00000 n +0000645345 00000 n +0000645408 00000 n +0000645471 00000 n +0000645534 00000 n +0000645597 00000 n +0000645660 00000 n +0000645723 00000 n +0000645786 00000 n +0000645850 00000 n +0000644559 00000 n +0000646040 00000 n +0000646103 00000 n +0000646167 00000 n +0000646230 00000 n +0000646293 00000 n +0000646356 00000 n +0000646419 00000 n +0000646482 00000 n +0000647699 00000 n +0000647385 00000 n +0000646718 00000 n +0000647509 00000 n +0000647572 00000 n +0000647635 00000 n +0000652998 00000 n +0000650379 00000 n +0000647787 00000 n +0000650845 00000 n +0000651034 00000 n +0000651097 00000 n +0000651161 00000 n +0000651475 00000 n +0000651663 00000 n +0000650533 00000 n +0000651726 00000 n +0000651789 00000 n +0000651853 00000 n +0000651917 00000 n +0000650688 00000 n +0000651981 00000 n +0000652045 00000 n +0000652109 00000 n +0000652173 00000 n +0000652237 00000 n +0000652300 00000 n +0000652364 00000 n +0000652427 00000 n +0000652490 00000 n +0000652554 00000 n +0000652618 00000 n +0000652808 00000 n +0000652871 00000 n +0001003640 00000 n +0000984634 00000 n +0000994596 00000 n +0000657591 00000 n +0000654853 00000 n +0000653142 00000 n +0000655512 00000 n +0000655763 00000 n +0000655016 00000 n +0000655951 00000 n +0000656014 00000 n +0000656078 00000 n +0000656142 00000 n +0000656268 00000 n +0000656331 00000 n +0000656394 00000 n +0000656457 00000 n +0000656521 00000 n +0000656646 00000 n +0000656709 00000 n +0000656772 00000 n +0000656835 00000 n +0000656899 00000 n +0000656962 00000 n +0000657024 00000 n +0000657087 00000 n +0000655180 00000 n +0000657276 00000 n +0000655351 00000 n +0000657401 00000 n +0000657464 00000 n +0000657528 00000 n +0000665123 00000 n +0000659927 00000 n +0000657749 00000 n +0000660394 00000 n +0000660709 00000 n +0000660772 00000 n +0000660836 00000 n +0000660898 00000 n +0000660081 00000 n +0000660239 00000 n +0000660961 00000 n +0000661024 00000 n +0000661087 00000 n +0000661150 00000 n +0000661213 00000 n +0000661276 00000 n +0000661339 00000 n +0000661403 00000 n +0000661467 00000 n +0000661531 00000 n +0000661595 00000 n +0000661658 00000 n +0000661721 00000 n +0000661784 00000 n +0000661847 00000 n +0000661910 00000 n +0000661973 00000 n +0000662036 00000 n +0000662095 00000 n +0000662155 00000 n +0000662215 00000 n +0000662278 00000 n +0000662341 00000 n +0000662404 00000 n +0000662467 00000 n +0000662530 00000 n +0000662593 00000 n +0000662656 00000 n +0000662719 00000 n +0000662783 00000 n +0000662846 00000 n +0000662910 00000 n +0000662974 00000 n +0000663038 00000 n +0000663101 00000 n +0000663164 00000 n +0000663226 00000 n +0000663288 00000 n +0000663352 00000 n +0000663415 00000 n +0000663479 00000 n +0000663543 00000 n +0000663607 00000 n +0000663671 00000 n +0000663735 00000 n +0000663799 00000 n +0000663863 00000 n +0000663927 00000 n +0000663991 00000 n +0000664054 00000 n +0000664116 00000 n +0000664179 00000 n +0000664242 00000 n +0000664306 00000 n +0000664369 00000 n +0000664432 00000 n +0000664495 00000 n +0000664558 00000 n +0000664621 00000 n +0000664683 00000 n +0000664746 00000 n +0000664809 00000 n +0000664872 00000 n +0000664935 00000 n +0000664998 00000 n +0000665061 00000 n +0000974568 00000 n +0000669535 00000 n +0000667495 00000 n +0000665267 00000 n +0000667949 00000 n +0000668012 00000 n +0000668076 00000 n +0000668140 00000 n +0000668204 00000 n +0000668267 00000 n +0000667649 00000 n +0000668456 00000 n +0000668519 00000 n +0000668582 00000 n +0000667797 00000 n +0000668645 00000 n +0000668709 00000 n +0000668773 00000 n +0000668837 00000 n +0000669153 00000 n +0000669216 00000 n +0000669280 00000 n +0000669344 00000 n +0000669408 00000 n +0000669471 00000 n +0000985014 00000 n +0000674362 00000 n +0000672222 00000 n +0000669693 00000 n +0000672346 00000 n +0000672661 00000 n +0000672724 00000 n +0000672911 00000 n +0000672974 00000 n +0000673037 00000 n +0000673100 00000 n +0000673162 00000 n +0000673225 00000 n +0000673289 00000 n +0000673352 00000 n +0000673416 00000 n +0000673480 00000 n +0000673543 00000 n +0000673606 00000 n +0000673669 00000 n +0000673732 00000 n +0000673794 00000 n +0000673857 00000 n +0000673920 00000 n +0000673983 00000 n +0000674046 00000 n +0000674109 00000 n +0000674172 00000 n +0000674235 00000 n +0000674298 00000 n +0000681017 00000 n +0000677876 00000 n +0000674492 00000 n +0000678000 00000 n +0000678063 00000 n +0000678252 00000 n +0000678315 00000 n +0000678378 00000 n +0000678441 00000 n +0000678504 00000 n +0000678567 00000 n +0000678630 00000 n +0000678693 00000 n +0000678756 00000 n +0000678819 00000 n +0000678882 00000 n +0000678945 00000 n +0000679008 00000 n +0000679071 00000 n +0000679134 00000 n +0000679197 00000 n +0000679260 00000 n +0000679323 00000 n +0000679386 00000 n +0000679449 00000 n +0000679512 00000 n +0000679575 00000 n +0000679638 00000 n +0000679701 00000 n +0000679764 00000 n +0000679827 00000 n +0000679890 00000 n +0000679953 00000 n +0000680014 00000 n +0000680075 00000 n +0000680138 00000 n +0000680201 00000 n +0000680264 00000 n +0000680327 00000 n +0000680390 00000 n +0000680453 00000 n +0000680516 00000 n +0000680579 00000 n +0000680642 00000 n +0000680704 00000 n +0000680767 00000 n +0000680830 00000 n +0000680893 00000 n +0000680955 00000 n +0000687223 00000 n +0000685593 00000 n +0000683270 00000 n +0000681119 00000 n +0000683574 00000 n +0000683699 00000 n +0000683762 00000 n +0000683825 00000 n +0000683888 00000 n +0000683951 00000 n +0000684014 00000 n +0000684077 00000 n +0000684140 00000 n +0000684203 00000 n +0000684266 00000 n +0000684330 00000 n +0000684394 00000 n +0000684457 00000 n +0000684520 00000 n +0000684583 00000 n +0000684646 00000 n +0000684709 00000 n +0000684772 00000 n +0000684835 00000 n +0000684898 00000 n +0000684961 00000 n +0000685024 00000 n +0000685087 00000 n +0000685150 00000 n +0000685339 00000 n +0000683415 00000 n +0000685402 00000 n +0000685466 00000 n +0001003765 00000 n +0000737250 00000 n +0000687078 00000 n +0000685695 00000 n +0000736808 00000 n +0000736871 00000 n +0000736997 00000 n +0000737060 00000 n +0000737124 00000 n +0000737187 00000 n +0000736658 00000 n +0000742167 00000 n +0000739582 00000 n +0000737403 00000 n +0000739706 00000 n +0000739957 00000 n +0000740020 00000 n +0000740083 00000 n +0000740146 00000 n +0000740209 00000 n +0000740273 00000 n +0000740337 00000 n +0000740400 00000 n +0000740463 00000 n +0000740526 00000 n +0000740589 00000 n +0000740652 00000 n +0000740715 00000 n +0000740778 00000 n +0000740841 00000 n +0000740904 00000 n +0000740967 00000 n +0000741156 00000 n +0000741342 00000 n +0000741405 00000 n +0000741469 00000 n +0000741532 00000 n +0000741596 00000 n +0000741659 00000 n +0000741723 00000 n +0000741786 00000 n +0000741850 00000 n +0000741913 00000 n +0000741977 00000 n +0000742040 00000 n +0000742104 00000 n +0000746853 00000 n +0000745279 00000 n +0000742269 00000 n +0000745403 00000 n +0000745529 00000 n +0000745592 00000 n +0000745656 00000 n +0000745719 00000 n +0000745783 00000 n +0000745846 00000 n +0000746035 00000 n +0000746098 00000 n +0000746160 00000 n +0000746224 00000 n +0000746287 00000 n +0000746477 00000 n +0000746540 00000 n +0000746603 00000 n +0000746665 00000 n +0000746727 00000 n +0000752383 00000 n +0000750123 00000 n +0000746969 00000 n +0000750427 00000 n +0000750553 00000 n +0000750616 00000 n +0000750268 00000 n +0000750679 00000 n +0000750741 00000 n +0000750805 00000 n +0000750869 00000 n +0000751185 00000 n +0000751248 00000 n +0000751312 00000 n +0000751374 00000 n +0000751437 00000 n +0000751500 00000 n +0000751562 00000 n +0000751625 00000 n +0000751688 00000 n +0000751751 00000 n +0000751814 00000 n +0000751878 00000 n +0000751941 00000 n +0000752004 00000 n +0000752067 00000 n +0000752129 00000 n +0000752193 00000 n +0000752256 00000 n +0000752319 00000 n +0000756931 00000 n +0000755359 00000 n +0000752499 00000 n +0000755483 00000 n +0000755546 00000 n +0000755609 00000 n +0000755671 00000 n +0000755734 00000 n +0000755797 00000 n +0000755860 00000 n +0000755923 00000 n +0000755986 00000 n +0000756049 00000 n +0000756113 00000 n +0000756176 00000 n +0000756365 00000 n +0000756428 00000 n +0000756492 00000 n +0000756679 00000 n +0000756742 00000 n +0000756805 00000 n +0000756868 00000 n +0000761269 00000 n +0000759699 00000 n +0000757061 00000 n +0000759823 00000 n +0000759886 00000 n +0000759949 00000 n +0000760013 00000 n +0000760077 00000 n +0000760141 00000 n +0000760204 00000 n +0000760394 00000 n +0000760457 00000 n +0000760519 00000 n +0000760582 00000 n +0000760770 00000 n +0000760958 00000 n +0000761143 00000 n +0001003890 00000 n +0000764785 00000 n +0000763274 00000 n +0000761371 00000 n +0000763398 00000 n +0000763524 00000 n +0000763713 00000 n +0000763902 00000 n +0000763965 00000 n +0000764154 00000 n +0000764343 00000 n +0000764532 00000 n +0000764595 00000 n +0000764659 00000 n +0000764722 00000 n +0000768860 00000 n +0000767225 00000 n +0000764887 00000 n +0000767349 00000 n +0000767412 00000 n +0000767601 00000 n +0000767664 00000 n +0000767850 00000 n +0000767913 00000 n +0000767977 00000 n +0000768166 00000 n +0000768229 00000 n +0000768293 00000 n +0000768356 00000 n +0000768419 00000 n +0000768483 00000 n +0000768546 00000 n +0000768735 00000 n +0000774137 00000 n 0000771613 00000 n -0000774487 00000 n -0000774801 00000 n -0000774864 00000 n -0000774323 00000 n -0000775053 00000 n -0000775116 00000 n -0000775180 00000 n -0000775244 00000 n -0000775308 00000 n -0000775371 00000 n -0000775433 00000 n -0000775496 00000 n -0000775560 00000 n -0000775624 00000 n -0000775814 00000 n -0000775877 00000 n -0000775940 00000 n -0000776004 00000 n -0000776068 00000 n -0000776131 00000 n -0000776194 00000 n -0000776257 00000 n -0000776320 00000 n -0000776383 00000 n -0000776446 00000 n -0000776509 00000 n -0000976930 00000 n -0000781543 00000 n -0000779774 00000 n -0000776730 00000 n -0000779898 00000 n -0000779961 00000 n -0000780024 00000 n -0000780085 00000 n -0000780148 00000 n -0000780210 00000 n -0000780274 00000 n -0000780338 00000 n -0000780402 00000 n -0000780465 00000 n -0000780529 00000 n -0000780593 00000 n -0000780657 00000 n -0000780847 00000 n -0000780910 00000 n -0000780973 00000 n -0000781036 00000 n -0000781099 00000 n -0000781163 00000 n -0000781226 00000 n -0000781289 00000 n -0000781352 00000 n -0000781416 00000 n -0000787512 00000 n -0000784926 00000 n -0000781687 00000 n -0000785050 00000 n -0000785176 00000 n -0000785239 00000 n -0000785303 00000 n -0000785366 00000 n -0000785430 00000 n -0000785491 00000 n -0000785555 00000 n -0000785618 00000 n -0000785680 00000 n -0000785743 00000 n -0000785806 00000 n -0000785870 00000 n -0000785933 00000 n -0000785996 00000 n -0000786059 00000 n -0000786122 00000 n -0000786185 00000 n -0000786374 00000 n -0000786437 00000 n -0000786500 00000 n -0000786563 00000 n -0000786626 00000 n -0000786689 00000 n -0000786752 00000 n -0000786815 00000 n -0000786879 00000 n -0000786942 00000 n -0000787005 00000 n -0000787068 00000 n -0000787131 00000 n -0000787195 00000 n -0000787259 00000 n -0000787323 00000 n -0000787386 00000 n -0000787449 00000 n -0000792273 00000 n -0000790445 00000 n -0000787656 00000 n -0000790569 00000 n -0000790632 00000 n -0000790695 00000 n -0000790758 00000 n -0000790820 00000 n -0000790882 00000 n -0000790945 00000 n -0000791008 00000 n -0000791072 00000 n -0000791136 00000 n -0000791199 00000 n -0000791262 00000 n -0000791326 00000 n -0000791389 00000 n -0000791452 00000 n -0000791515 00000 n -0000791579 00000 n -0000791643 00000 n -0000791707 00000 n -0000791770 00000 n -0000791833 00000 n -0000791896 00000 n -0000791960 00000 n -0000792023 00000 n -0000792086 00000 n -0000792147 00000 n -0000797587 00000 n -0000795501 00000 n -0000792389 00000 n -0000795625 00000 n -0000795751 00000 n -0000795814 00000 n -0000795877 00000 n -0000795940 00000 n -0000796004 00000 n -0000796068 00000 n -0000796131 00000 n -0000796321 00000 n -0000796384 00000 n -0000796448 00000 n -0000796511 00000 n -0000796574 00000 n -0000796637 00000 n -0000796700 00000 n -0000796763 00000 n -0000796827 00000 n -0000796891 00000 n -0000796954 00000 n -0000797018 00000 n -0000797082 00000 n -0000797146 00000 n -0000797209 00000 n -0000797272 00000 n -0000797334 00000 n -0000797398 00000 n -0000797461 00000 n -0000797524 00000 n -0000802929 00000 n -0000800587 00000 n -0000797731 00000 n -0000800711 00000 n -0000800774 00000 n -0000800837 00000 n -0000800900 00000 n -0000800963 00000 n -0000801026 00000 n -0000801089 00000 n -0000801153 00000 n -0000801216 00000 n -0000801280 00000 n -0000801344 00000 n -0000801408 00000 n -0000801471 00000 n -0000801534 00000 n -0000801597 00000 n -0000801661 00000 n -0000801724 00000 n -0000801787 00000 n -0000801850 00000 n -0000801913 00000 n -0000801977 00000 n -0000802040 00000 n -0000802103 00000 n -0000802166 00000 n -0000802229 00000 n -0000802292 00000 n -0000802355 00000 n -0000802418 00000 n -0000802482 00000 n -0000802546 00000 n -0000802610 00000 n -0000802674 00000 n -0000802737 00000 n -0000802801 00000 n -0000802865 00000 n -0000807457 00000 n -0000805943 00000 n -0000803031 00000 n -0000806067 00000 n -0000806130 00000 n -0000806192 00000 n -0000806255 00000 n -0000806318 00000 n -0000806381 00000 n -0000806445 00000 n -0000806508 00000 n -0000806696 00000 n -0000806759 00000 n -0000806823 00000 n -0000806886 00000 n -0000806949 00000 n -0000807012 00000 n -0000807076 00000 n -0000807140 00000 n -0000807203 00000 n -0000807267 00000 n -0000807330 00000 n -0000807393 00000 n -0000977055 00000 n -0000810776 00000 n -0000809641 00000 n -0000807587 00000 n -0000809765 00000 n -0000809828 00000 n -0000809891 00000 n -0000809954 00000 n -0000810016 00000 n -0000810079 00000 n -0000810143 00000 n -0000810207 00000 n -0000810270 00000 n -0000810334 00000 n -0000810523 00000 n -0000810586 00000 n -0000810649 00000 n -0000816393 00000 n -0000813630 00000 n -0000810906 00000 n -0000814245 00000 n -0000814371 00000 n -0000814433 00000 n -0000814497 00000 n -0000814560 00000 n -0000814623 00000 n -0000814687 00000 n -0000814751 00000 n -0000814814 00000 n -0000814877 00000 n -0000815192 00000 n -0000813793 00000 n -0000813940 00000 n -0000814093 00000 n -0000815381 00000 n -0000815444 00000 n -0000815507 00000 n -0000815570 00000 n -0000815633 00000 n -0000815696 00000 n -0000815760 00000 n -0000815823 00000 n -0000816013 00000 n -0000816076 00000 n -0000816139 00000 n -0000816203 00000 n -0000816267 00000 n -0000817990 00000 n -0000817298 00000 n -0000816523 00000 n -0000817422 00000 n -0000817548 00000 n -0000817611 00000 n -0000817800 00000 n -0000817863 00000 n -0000817926 00000 n -0000822623 00000 n -0000820608 00000 n -0000818092 00000 n -0000820732 00000 n -0000820921 00000 n -0000820984 00000 n -0000821047 00000 n -0000821110 00000 n -0000821172 00000 n -0000821235 00000 n -0000821298 00000 n -0000821362 00000 n -0000821425 00000 n -0000821488 00000 n -0000821551 00000 n -0000821613 00000 n -0000821676 00000 n -0000821738 00000 n -0000821802 00000 n -0000821865 00000 n -0000821927 00000 n -0000821990 00000 n -0000822053 00000 n -0000822117 00000 n -0000822180 00000 n -0000822243 00000 n -0000822306 00000 n -0000822370 00000 n -0000822433 00000 n -0000822496 00000 n -0000822559 00000 n -0000827831 00000 n -0000826063 00000 n -0000822753 00000 n -0000826187 00000 n -0000826250 00000 n -0000826312 00000 n -0000826375 00000 n -0000826439 00000 n -0000826503 00000 n -0000826567 00000 n -0000826630 00000 n -0000826693 00000 n -0000826756 00000 n -0000826820 00000 n -0000826883 00000 n -0000826947 00000 n -0000827010 00000 n -0000827073 00000 n -0000827136 00000 n -0000827199 00000 n -0000827263 00000 n -0000827325 00000 n -0000827389 00000 n -0000827452 00000 n -0000827515 00000 n -0000827579 00000 n -0000827642 00000 n -0000827705 00000 n -0000827768 00000 n -0000832181 00000 n -0000830349 00000 n -0000827947 00000 n -0000830473 00000 n -0000830536 00000 n -0000830599 00000 n -0000830662 00000 n -0000830725 00000 n -0000830789 00000 n -0000830851 00000 n -0000830914 00000 n -0000830978 00000 n -0000831042 00000 n -0000831105 00000 n -0000831168 00000 n -0000831232 00000 n -0000831295 00000 n -0000831359 00000 n -0000831423 00000 n -0000831486 00000 n -0000831549 00000 n -0000831612 00000 n -0000831676 00000 n -0000831739 00000 n -0000831803 00000 n -0000831866 00000 n -0000831929 00000 n -0000831992 00000 n -0000832055 00000 n -0000832118 00000 n -0000977180 00000 n -0000836994 00000 n -0000835119 00000 n -0000832325 00000 n -0000835417 00000 n -0000835480 00000 n -0000835543 00000 n -0000835607 00000 n -0000835669 00000 n -0000835732 00000 n -0000835264 00000 n -0000835796 00000 n -0000835859 00000 n -0000835921 00000 n -0000835984 00000 n -0000836047 00000 n -0000836110 00000 n -0000836172 00000 n -0000836235 00000 n -0000836298 00000 n -0000836361 00000 n -0000836424 00000 n -0000836487 00000 n -0000836550 00000 n -0000836613 00000 n -0000836676 00000 n -0000836740 00000 n -0000836804 00000 n -0000836867 00000 n -0000836931 00000 n -0000841664 00000 n -0000839975 00000 n -0000837138 00000 n -0000840278 00000 n -0000840341 00000 n -0000840404 00000 n -0000840466 00000 n -0000840530 00000 n -0000840593 00000 n -0000840656 00000 n -0000840719 00000 n -0000840782 00000 n -0000840845 00000 n -0000840908 00000 n -0000840972 00000 n -0000841035 00000 n -0000841098 00000 n -0000841161 00000 n -0000841224 00000 n -0000841287 00000 n -0000841349 00000 n -0000841412 00000 n -0000840120 00000 n -0000841475 00000 n -0000841538 00000 n -0000841601 00000 n -0000847073 00000 n -0000844877 00000 n -0000841766 00000 n -0000845175 00000 n -0000845238 00000 n -0000845301 00000 n -0000845362 00000 n -0000845425 00000 n -0000845488 00000 n -0000845551 00000 n -0000845614 00000 n -0000845677 00000 n -0000845741 00000 n -0000845804 00000 n -0000845867 00000 n -0000845931 00000 n -0000845994 00000 n -0000846058 00000 n -0000846122 00000 n -0000846185 00000 n -0000846248 00000 n -0000846312 00000 n -0000846376 00000 n -0000846440 00000 n -0000846503 00000 n -0000846566 00000 n -0000846630 00000 n -0000845022 00000 n -0000846693 00000 n -0000846756 00000 n -0000846819 00000 n -0000846882 00000 n -0000846945 00000 n -0000847009 00000 n -0000851387 00000 n -0000849687 00000 n -0000847217 00000 n -0000849995 00000 n -0000850058 00000 n -0000850121 00000 n -0000850185 00000 n -0000850248 00000 n -0000850311 00000 n -0000850374 00000 n -0000850438 00000 n -0000850501 00000 n -0000850565 00000 n -0000850629 00000 n -0000850693 00000 n -0000850757 00000 n -0000849832 00000 n -0000850820 00000 n -0000850883 00000 n -0000850947 00000 n -0000851009 00000 n -0000851072 00000 n -0000851135 00000 n -0000851199 00000 n -0000851262 00000 n -0000851325 00000 n -0000856138 00000 n -0000854002 00000 n -0000851531 00000 n -0000854305 00000 n -0000854368 00000 n -0000854431 00000 n -0000854494 00000 n -0000854557 00000 n -0000854620 00000 n -0000854147 00000 n -0000854684 00000 n -0000854747 00000 n -0000854809 00000 n -0000854872 00000 n -0000854935 00000 n -0000854998 00000 n -0000855061 00000 n -0000855125 00000 n -0000855188 00000 n -0000855251 00000 n -0000855315 00000 n -0000855379 00000 n -0000855442 00000 n -0000855506 00000 n -0000855570 00000 n -0000855633 00000 n -0000855696 00000 n -0000855759 00000 n -0000855823 00000 n -0000855886 00000 n -0000855949 00000 n -0000856013 00000 n -0000856075 00000 n -0000862348 00000 n -0000859067 00000 n -0000856296 00000 n -0000859365 00000 n -0000859428 00000 n -0000859492 00000 n -0000859556 00000 n -0000859620 00000 n -0000859683 00000 n -0000859747 00000 n -0000859811 00000 n -0000859875 00000 n -0000859938 00000 n -0000860002 00000 n -0000860066 00000 n -0000860129 00000 n -0000860192 00000 n -0000860256 00000 n -0000860319 00000 n -0000860382 00000 n -0000860444 00000 n -0000860507 00000 n -0000860570 00000 n -0000860633 00000 n -0000860696 00000 n -0000860760 00000 n -0000860824 00000 n -0000860888 00000 n -0000860952 00000 n -0000861016 00000 n -0000861080 00000 n -0000861143 00000 n -0000859212 00000 n -0000861206 00000 n -0000861270 00000 n -0000861334 00000 n -0000861396 00000 n -0000861459 00000 n -0000861523 00000 n -0000861587 00000 n -0000861650 00000 n -0000861713 00000 n -0000861777 00000 n -0000861840 00000 n -0000861904 00000 n -0000861967 00000 n -0000862030 00000 n -0000862093 00000 n -0000862156 00000 n -0000862220 00000 n -0000862284 00000 n -0000977305 00000 n -0000961550 00000 n -0000866960 00000 n -0000865260 00000 n -0000862464 00000 n -0000865384 00000 n -0000865447 00000 n -0000865509 00000 n -0000865572 00000 n -0000865635 00000 n -0000865699 00000 n -0000865761 00000 n -0000865825 00000 n -0000865888 00000 n -0000865952 00000 n -0000866014 00000 n -0000866077 00000 n -0000866141 00000 n -0000866204 00000 n -0000866267 00000 n -0000866331 00000 n -0000866394 00000 n -0000866457 00000 n -0000866520 00000 n -0000866583 00000 n -0000866647 00000 n -0000866709 00000 n -0000866771 00000 n -0000866834 00000 n -0000866897 00000 n -0000872080 00000 n -0000869697 00000 n -0000867104 00000 n -0000869994 00000 n -0000869842 00000 n -0000870057 00000 n -0000870120 00000 n -0000870183 00000 n -0000870245 00000 n -0000870309 00000 n -0000870372 00000 n -0000870435 00000 n -0000870499 00000 n -0000870562 00000 n -0000870625 00000 n -0000870689 00000 n -0000870752 00000 n -0000870815 00000 n -0000870879 00000 n -0000870942 00000 n -0000871006 00000 n -0000871065 00000 n -0000871129 00000 n -0000871192 00000 n -0000871256 00000 n -0000871319 00000 n -0000871383 00000 n -0000871446 00000 n -0000871510 00000 n -0000871574 00000 n -0000871638 00000 n -0000871702 00000 n -0000871765 00000 n -0000871828 00000 n -0000871891 00000 n -0000871954 00000 n -0000872017 00000 n -0000877194 00000 n -0000875367 00000 n -0000872196 00000 n -0000875491 00000 n -0000875554 00000 n -0000875616 00000 n -0000875679 00000 n -0000875742 00000 n -0000875806 00000 n -0000875869 00000 n -0000875932 00000 n -0000875995 00000 n -0000876057 00000 n -0000876120 00000 n -0000876183 00000 n -0000876246 00000 n -0000876309 00000 n -0000876372 00000 n -0000876436 00000 n -0000876499 00000 n -0000876562 00000 n -0000876624 00000 n -0000876688 00000 n -0000876751 00000 n -0000876815 00000 n -0000876878 00000 n -0000876941 00000 n -0000877005 00000 n -0000877068 00000 n -0000877131 00000 n -0000881666 00000 n -0000879515 00000 n -0000877324 00000 n -0000879639 00000 n -0000879702 00000 n -0000879765 00000 n -0000879828 00000 n -0000879890 00000 n -0000879953 00000 n -0000880016 00000 n -0000880079 00000 n -0000880142 00000 n -0000880205 00000 n -0000880269 00000 n -0000880332 00000 n -0000880396 00000 n -0000880460 00000 n -0000880523 00000 n -0000880586 00000 n -0000880650 00000 n -0000880713 00000 n -0000880777 00000 n -0000880841 00000 n -0000880905 00000 n -0000880968 00000 n -0000881031 00000 n -0000881094 00000 n -0000881155 00000 n -0000881219 00000 n -0000881283 00000 n -0000881347 00000 n -0000881410 00000 n -0000881474 00000 n -0000881538 00000 n -0000881602 00000 n -0000883491 00000 n -0000882863 00000 n -0000881782 00000 n -0000882987 00000 n -0000883050 00000 n -0000883114 00000 n -0000883177 00000 n -0000883240 00000 n -0000883301 00000 n -0000883365 00000 n -0000883428 00000 n -0000888541 00000 n -0000886122 00000 n -0000883579 00000 n -0000886589 00000 n -0000886778 00000 n -0000886967 00000 n -0000887030 00000 n -0000887093 00000 n -0000887157 00000 n -0000886276 00000 n -0000886432 00000 n -0000887220 00000 n -0000887283 00000 n +0000768976 00000 n +0000771737 00000 n +0000771863 00000 n +0000771926 00000 n +0000771990 00000 n +0000772180 00000 n +0000772243 00000 n +0000772306 00000 n +0000772369 00000 n +0000772432 00000 n +0000772495 00000 n +0000772558 00000 n +0000772621 00000 n +0000772684 00000 n +0000772747 00000 n +0000772810 00000 n +0000772874 00000 n +0000772937 00000 n +0000773000 00000 n +0000773187 00000 n +0000773250 00000 n +0000773313 00000 n +0000773377 00000 n +0000773440 00000 n +0000773503 00000 n +0000773566 00000 n +0000773630 00000 n +0000773694 00000 n +0000773757 00000 n +0000773820 00000 n +0000773884 00000 n +0000773948 00000 n +0000774011 00000 n +0000774074 00000 n +0000779547 00000 n +0000777091 00000 n +0000774267 00000 n +0000777215 00000 n +0000777278 00000 n +0000777341 00000 n +0000777405 00000 n +0000777468 00000 n +0000777531 00000 n +0000777594 00000 n +0000777658 00000 n +0000777721 00000 n +0000777784 00000 n +0000777847 00000 n +0000777910 00000 n +0000777973 00000 n +0000778037 00000 n +0000778099 00000 n +0000778162 00000 n +0000778226 00000 n +0000778289 00000 n +0000778352 00000 n +0000778416 00000 n +0000778479 00000 n +0000778542 00000 n +0000778605 00000 n +0000778668 00000 n +0000778731 00000 n +0000778795 00000 n +0000778858 00000 n +0000778921 00000 n +0000778985 00000 n +0000779047 00000 n +0000779111 00000 n +0000779174 00000 n +0000779237 00000 n +0000779422 00000 n +0000783529 00000 n +0000782211 00000 n +0000779663 00000 n +0000782335 00000 n +0000782461 00000 n +0000782650 00000 n +0000782713 00000 n +0000782776 00000 n +0000782839 00000 n +0000782902 00000 n +0000783090 00000 n +0000783152 00000 n +0000783214 00000 n +0000783277 00000 n +0000783340 00000 n +0000783403 00000 n +0000787713 00000 n +0000786395 00000 n +0000783645 00000 n +0000786519 00000 n +0000786645 00000 n +0000786708 00000 n +0000786771 00000 n +0000786834 00000 n +0000786897 00000 n +0000787086 00000 n +0000787149 00000 n +0000787338 00000 n +0000787400 00000 n +0000787462 00000 n +0000787525 00000 n +0000787588 00000 n +0000787651 00000 n +0001004015 00000 n +0000792207 00000 n +0000790527 00000 n +0000787815 00000 n +0000791012 00000 n +0000791075 00000 n +0000791138 00000 n +0000791324 00000 n +0000791387 00000 n +0000791450 00000 n +0000791514 00000 n +0000791578 00000 n +0000791641 00000 n +0000790681 00000 n +0000791704 00000 n +0000791767 00000 n +0000790844 00000 n +0000791956 00000 n +0000792019 00000 n +0000792081 00000 n +0000796749 00000 n +0000795386 00000 n +0000792323 00000 n +0000795678 00000 n +0000795804 00000 n +0000795867 00000 n +0000795930 00000 n +0000795993 00000 n +0000796057 00000 n +0000796120 00000 n +0000796183 00000 n +0000796246 00000 n +0000796434 00000 n +0000796497 00000 n +0000796560 00000 n +0000795531 00000 n +0000796623 00000 n +0000796686 00000 n +0000798983 00000 n +0000798228 00000 n +0000796865 00000 n +0000798352 00000 n +0000798415 00000 n +0000798478 00000 n +0000798541 00000 n +0000798604 00000 n +0000798794 00000 n +0000798857 00000 n +0000798920 00000 n +0000803774 00000 n +0000801382 00000 n +0000799099 00000 n +0000801690 00000 n +0000802005 00000 n +0000802068 00000 n +0000802132 00000 n +0000802195 00000 n +0000802258 00000 n +0000802322 00000 n +0000802385 00000 n +0000802448 00000 n +0000802512 00000 n +0000802574 00000 n +0000802637 00000 n +0000802826 00000 n +0000802889 00000 n +0000801527 00000 n +0000803077 00000 n +0000803140 00000 n +0000803203 00000 n +0000803267 00000 n +0000803331 00000 n +0000803394 00000 n +0000803456 00000 n +0000803519 00000 n +0000803583 00000 n +0000803647 00000 n +0000808863 00000 n +0000806712 00000 n +0000803918 00000 n +0000806836 00000 n +0000806899 00000 n +0000807024 00000 n +0000807087 00000 n +0000807150 00000 n +0000807214 00000 n +0000807278 00000 n +0000807341 00000 n +0000807404 00000 n +0000807467 00000 n +0000807530 00000 n +0000807594 00000 n +0000807657 00000 n +0000807720 00000 n +0000807784 00000 n +0000807847 00000 n +0000807910 00000 n +0000807973 00000 n +0000808036 00000 n +0000808100 00000 n +0000808164 00000 n +0000808228 00000 n +0000808291 00000 n +0000808355 00000 n +0000808419 00000 n +0000808483 00000 n +0000808673 00000 n +0000808736 00000 n +0000808799 00000 n +0000814030 00000 n +0000812199 00000 n +0000809021 00000 n +0000812323 00000 n +0000812386 00000 n +0000812448 00000 n +0000812511 00000 n +0000812574 00000 n +0000812637 00000 n +0000812700 00000 n +0000812890 00000 n +0000812953 00000 n +0000813017 00000 n +0000813080 00000 n +0000813144 00000 n +0000813207 00000 n +0000813271 00000 n +0000813334 00000 n +0000813397 00000 n +0000813460 00000 n +0000813523 00000 n +0000813587 00000 n +0000813650 00000 n +0000813713 00000 n +0000813776 00000 n +0000813839 00000 n +0000813903 00000 n +0001004140 00000 n +0000820036 00000 n +0000817639 00000 n +0000814160 00000 n +0000817763 00000 n +0000817826 00000 n +0000817950 00000 n +0000818013 00000 n +0000818076 00000 n +0000818139 00000 n +0000818201 00000 n +0000818263 00000 n +0000818327 00000 n +0000818390 00000 n +0000818453 00000 n +0000818516 00000 n +0000818579 00000 n +0000818643 00000 n +0000818707 00000 n +0000818771 00000 n +0000818834 00000 n +0000818897 00000 n +0000818960 00000 n +0000819023 00000 n +0000819086 00000 n +0000819149 00000 n +0000819212 00000 n +0000819275 00000 n +0000819338 00000 n +0000819402 00000 n +0000819465 00000 n +0000819528 00000 n +0000819591 00000 n +0000819655 00000 n +0000819719 00000 n +0000819781 00000 n +0000819844 00000 n +0000819908 00000 n +0000819972 00000 n +0000824204 00000 n +0000822628 00000 n +0000820166 00000 n +0000822752 00000 n +0000822815 00000 n +0000822877 00000 n +0000822939 00000 n +0000823003 00000 n +0000823066 00000 n +0000823129 00000 n +0000823192 00000 n +0000823381 00000 n +0000823444 00000 n +0000823507 00000 n +0000823570 00000 n +0000823633 00000 n +0000823697 00000 n +0000823760 00000 n +0000823950 00000 n +0000824013 00000 n +0000824077 00000 n +0000824141 00000 n +0000829498 00000 n +0000827662 00000 n +0000824334 00000 n +0000827786 00000 n +0000827849 00000 n +0000827912 00000 n +0000827975 00000 n +0000828038 00000 n +0000828102 00000 n +0000828166 00000 n +0000828230 00000 n +0000828293 00000 n +0000828356 00000 n +0000828419 00000 n +0000828483 00000 n +0000828547 00000 n +0000828611 00000 n +0000828674 00000 n +0000828738 00000 n +0000828802 00000 n +0000828866 00000 n +0000828929 00000 n +0000828993 00000 n +0000829056 00000 n +0000829119 00000 n +0000829182 00000 n +0000829245 00000 n +0000829308 00000 n +0000829371 00000 n +0000829434 00000 n +0000834535 00000 n +0000832324 00000 n +0000829614 00000 n +0000832448 00000 n +0000832511 00000 n +0000832574 00000 n +0000832638 00000 n +0000832702 00000 n +0000832766 00000 n +0000832829 00000 n +0000832892 00000 n +0000832955 00000 n +0000833019 00000 n +0000833081 00000 n +0000833144 00000 n +0000833208 00000 n +0000833271 00000 n +0000833333 00000 n +0000833396 00000 n +0000833459 00000 n +0000833522 00000 n +0000833585 00000 n +0000833648 00000 n +0000833711 00000 n +0000833774 00000 n +0000833837 00000 n +0000833900 00000 n +0000833964 00000 n +0000834027 00000 n +0000834091 00000 n +0000834155 00000 n +0000834219 00000 n +0000834282 00000 n +0000834345 00000 n +0000834409 00000 n +0000834472 00000 n +0000838724 00000 n +0000837464 00000 n +0000834637 00000 n +0000837588 00000 n +0000837651 00000 n +0000837839 00000 n +0000837902 00000 n +0000837966 00000 n +0000838029 00000 n +0000838092 00000 n +0000838156 00000 n +0000838219 00000 n +0000838282 00000 n +0000838344 00000 n +0000838408 00000 n +0000838471 00000 n +0000838534 00000 n +0000838598 00000 n +0000838661 00000 n +0000842844 00000 n +0000841094 00000 n +0000838854 00000 n +0000841709 00000 n +0000841772 00000 n +0000841835 00000 n +0000841898 00000 n +0000841961 00000 n +0000842025 00000 n +0000842089 00000 n +0000842404 00000 n +0000841257 00000 n +0000841404 00000 n +0000841557 00000 n +0000842593 00000 n +0000842656 00000 n +0000842719 00000 n +0000842782 00000 n +0001004265 00000 n +0000846019 00000 n +0000844567 00000 n +0000842974 00000 n +0000844691 00000 n +0000844754 00000 n +0000844817 00000 n +0000844881 00000 n +0000844944 00000 n +0000845133 00000 n +0000845196 00000 n +0000845259 00000 n +0000845323 00000 n +0000845387 00000 n +0000845576 00000 n +0000845639 00000 n +0000845829 00000 n +0000845892 00000 n +0000845955 00000 n +0000850530 00000 n +0000848450 00000 n +0000846121 00000 n +0000848574 00000 n +0000848763 00000 n +0000848826 00000 n +0000848889 00000 n +0000848952 00000 n +0000849014 00000 n +0000849077 00000 n +0000849140 00000 n +0000849204 00000 n +0000849267 00000 n +0000849330 00000 n +0000849394 00000 n +0000849457 00000 n +0000849520 00000 n +0000849583 00000 n +0000849646 00000 n +0000849709 00000 n +0000849772 00000 n +0000849836 00000 n +0000849899 00000 n +0000849962 00000 n +0000850025 00000 n +0000850087 00000 n +0000850151 00000 n +0000850214 00000 n +0000850277 00000 n +0000850340 00000 n +0000850404 00000 n +0000850467 00000 n +0000855491 00000 n +0000853911 00000 n +0000850660 00000 n +0000854035 00000 n +0000854098 00000 n +0000854161 00000 n +0000854225 00000 n +0000854288 00000 n +0000854352 00000 n +0000854416 00000 n +0000854480 00000 n +0000854543 00000 n +0000854606 00000 n +0000854669 00000 n +0000854732 00000 n +0000854795 00000 n +0000854859 00000 n +0000854922 00000 n +0000854986 00000 n +0000855049 00000 n +0000855112 00000 n +0000855175 00000 n +0000855239 00000 n +0000855301 00000 n +0000855365 00000 n +0000855428 00000 n +0000860355 00000 n +0000858209 00000 n +0000855607 00000 n +0000858333 00000 n +0000858396 00000 n +0000858458 00000 n +0000858522 00000 n +0000858586 00000 n +0000858649 00000 n +0000858712 00000 n +0000858775 00000 n +0000858838 00000 n +0000858902 00000 n +0000858965 00000 n +0000859028 00000 n +0000859091 00000 n +0000859155 00000 n +0000859218 00000 n +0000859281 00000 n +0000859345 00000 n +0000859409 00000 n +0000859470 00000 n +0000859533 00000 n +0000859596 00000 n +0000859659 00000 n +0000859723 00000 n +0000859787 00000 n +0000859849 00000 n +0000859912 00000 n +0000859975 00000 n +0000860039 00000 n +0000860102 00000 n +0000860166 00000 n +0000860229 00000 n +0000860292 00000 n +0000864789 00000 n +0000863107 00000 n +0000860499 00000 n +0000863404 00000 n +0000863467 00000 n +0000863530 00000 n +0000863593 00000 n +0000863656 00000 n +0000863719 00000 n +0000863781 00000 n +0000863844 00000 n +0000863906 00000 n +0000863969 00000 n +0000864032 00000 n +0000863252 00000 n +0000864096 00000 n +0000864159 00000 n +0000864222 00000 n +0000864285 00000 n +0000864348 00000 n +0000864411 00000 n +0000864474 00000 n +0000864537 00000 n +0000864599 00000 n +0000864662 00000 n +0000864726 00000 n +0000869367 00000 n +0000867726 00000 n +0000864919 00000 n +0000867850 00000 n +0000867913 00000 n +0000867976 00000 n +0000868040 00000 n +0000868102 00000 n +0000868166 00000 n +0000868230 00000 n +0000868293 00000 n +0000868357 00000 n +0000868420 00000 n +0000868483 00000 n +0000868545 00000 n +0000868609 00000 n +0000868672 00000 n +0000868735 00000 n +0000868798 00000 n +0000868861 00000 n +0000868925 00000 n +0000868988 00000 n +0000869052 00000 n +0000869115 00000 n +0000869178 00000 n +0000869241 00000 n +0000869304 00000 n +0001004390 00000 n +0000874885 00000 n +0000872690 00000 n +0000869483 00000 n +0000872994 00000 n +0000873057 00000 n +0000873119 00000 n +0000873182 00000 n +0000873243 00000 n +0000872835 00000 n +0000873306 00000 n +0000873369 00000 n +0000873432 00000 n +0000873495 00000 n +0000873558 00000 n +0000873621 00000 n +0000873683 00000 n +0000873746 00000 n +0000873809 00000 n +0000873872 00000 n +0000873935 00000 n +0000873998 00000 n +0000874061 00000 n +0000874124 00000 n +0000874188 00000 n +0000874251 00000 n +0000874314 00000 n +0000874377 00000 n +0000874439 00000 n +0000874502 00000 n +0000874566 00000 n +0000874630 00000 n +0000874694 00000 n +0000874757 00000 n +0000874821 00000 n +0000879794 00000 n +0000877806 00000 n +0000875015 00000 n +0000878276 00000 n +0000878339 00000 n +0000877960 00000 n +0000878401 00000 n +0000878464 00000 n +0000878527 00000 n +0000878590 00000 n +0000878653 00000 n +0000878717 00000 n +0000878781 00000 n +0000878844 00000 n +0000878907 00000 n +0000878970 00000 n +0000879033 00000 n +0000879096 00000 n +0000879160 00000 n +0000879222 00000 n +0000879286 00000 n +0000879350 00000 n +0000879414 00000 n +0000879478 00000 n +0000878113 00000 n +0000879541 00000 n +0000879604 00000 n +0000879668 00000 n +0000879731 00000 n +0000884548 00000 n +0000882477 00000 n +0000879938 00000 n +0000882780 00000 n +0000882843 00000 n +0000882905 00000 n +0000882968 00000 n +0000883031 00000 n +0000883094 00000 n +0000883157 00000 n +0000883220 00000 n +0000883283 00000 n +0000883346 00000 n +0000882622 00000 n +0000883410 00000 n +0000883473 00000 n +0000883536 00000 n +0000883599 00000 n +0000883662 00000 n +0000883725 00000 n +0000883787 00000 n +0000883851 00000 n +0000883914 00000 n +0000883977 00000 n +0000884041 00000 n +0000884105 00000 n +0000884168 00000 n +0000884232 00000 n +0000884296 00000 n +0000884359 00000 n +0000884422 00000 n +0000884485 00000 n +0000890290 00000 n +0000887201 00000 n +0000884706 00000 n +0000887499 00000 n +0000887562 00000 n +0000887624 00000 n +0000887688 00000 n +0000887750 00000 n +0000887813 00000 n +0000887877 00000 n +0000887941 00000 n +0000888005 00000 n +0000888068 00000 n +0000888132 00000 n +0000888196 00000 n +0000888260 00000 n +0000888323 00000 n +0000888387 00000 n +0000888451 00000 n +0000888514 00000 n +0000888577 00000 n +0000888641 00000 n +0000888704 00000 n +0000888767 00000 n +0000888830 00000 n +0000888893 00000 n +0000888956 00000 n +0000889019 00000 n +0000889082 00000 n +0000889146 00000 n +0000889210 00000 n +0000889274 00000 n +0000889338 00000 n +0000889402 00000 n +0000889466 00000 n +0000889529 00000 n 0000887346 00000 n -0000887410 00000 n -0000887473 00000 n -0000887663 00000 n -0000887726 00000 n -0000887789 00000 n -0000887852 00000 n -0000887915 00000 n -0000888103 00000 n -0000888166 00000 n -0000888229 00000 n -0000888291 00000 n -0000888354 00000 n -0000888416 00000 n -0000977430 00000 n -0000891937 00000 n -0000890297 00000 n -0000888685 00000 n -0000890421 00000 n -0000890484 00000 n -0000890609 00000 n -0000890672 00000 n -0000890735 00000 n -0000890798 00000 n -0000890862 00000 n -0000890925 00000 n -0000890987 00000 n -0000891050 00000 n -0000891239 00000 n -0000891302 00000 n -0000891366 00000 n -0000891429 00000 n -0000891492 00000 n -0000891556 00000 n -0000891620 00000 n -0000891684 00000 n -0000891747 00000 n -0000891810 00000 n -0000895020 00000 n -0000893948 00000 n -0000892081 00000 n -0000894072 00000 n -0000894197 00000 n -0000894260 00000 n -0000894324 00000 n -0000894387 00000 n -0000894450 00000 n -0000894514 00000 n -0000894703 00000 n -0000894766 00000 n -0000894830 00000 n -0000894893 00000 n -0000894957 00000 n -0000899048 00000 n -0000897405 00000 n -0000895136 00000 n -0000897529 00000 n -0000897592 00000 n -0000897718 00000 n -0000897780 00000 n -0000897843 00000 n -0000897907 00000 n -0000897971 00000 n -0000898097 00000 n -0000898160 00000 n -0000898223 00000 n -0000898287 00000 n -0000898351 00000 n -0000898414 00000 n -0000898478 00000 n -0000898668 00000 n -0000898731 00000 n -0000898794 00000 n -0000898857 00000 n -0000898921 00000 n -0000901643 00000 n -0000900523 00000 n -0000899164 00000 n -0000900822 00000 n -0000900948 00000 n -0000901011 00000 n -0000901073 00000 n -0000901137 00000 n -0000900668 00000 n -0000901327 00000 n -0000901390 00000 n -0000901453 00000 n -0000901516 00000 n -0000901579 00000 n -0000907955 00000 n -0000904866 00000 n -0000901773 00000 n -0000904990 00000 n -0000905179 00000 n -0000905242 00000 n -0000905429 00000 n -0000905492 00000 n -0000905556 00000 n -0000905619 00000 n -0000905683 00000 n -0000905747 00000 n -0000905810 00000 n -0000905874 00000 n -0000905937 00000 n -0000906000 00000 n -0000906063 00000 n -0000906126 00000 n -0000906188 00000 n -0000906250 00000 n -0000906314 00000 n -0000906378 00000 n -0000906442 00000 n -0000906506 00000 n -0000906570 00000 n -0000906634 00000 n -0000906697 00000 n -0000906760 00000 n -0000906823 00000 n -0000906886 00000 n -0000906950 00000 n -0000907013 00000 n -0000907076 00000 n -0000907139 00000 n -0000907203 00000 n -0000907388 00000 n -0000907451 00000 n -0000907514 00000 n -0000907578 00000 n -0000907640 00000 n -0000907704 00000 n -0000907768 00000 n -0000907831 00000 n -0000907893 00000 n -0000911773 00000 n -0000909694 00000 n -0000908099 00000 n -0000909818 00000 n -0000910132 00000 n -0000910194 00000 n -0000910257 00000 n -0000910320 00000 n -0000910383 00000 n -0000910446 00000 n -0000910509 00000 n -0000910572 00000 n -0000910635 00000 n -0000910698 00000 n -0000910761 00000 n -0000910824 00000 n -0000910888 00000 n -0000910952 00000 n -0000911014 00000 n -0000911077 00000 n -0000911267 00000 n -0000911330 00000 n -0000911393 00000 n -0000911456 00000 n -0000911519 00000 n -0000911583 00000 n -0000911647 00000 n -0000911711 00000 n -0000977555 00000 n -0000914508 00000 n -0000912608 00000 n -0000911903 00000 n -0000912732 00000 n -0000912795 00000 n -0000912857 00000 n -0000912920 00000 n -0000912984 00000 n -0000913046 00000 n -0000913109 00000 n -0000913173 00000 n -0000913237 00000 n -0000913300 00000 n -0000913363 00000 n -0000913427 00000 n -0000913491 00000 n -0000913555 00000 n -0000913617 00000 n -0000913680 00000 n -0000913744 00000 n -0000913808 00000 n -0000913872 00000 n -0000913935 00000 n -0000913998 00000 n -0000914062 00000 n -0000914126 00000 n -0000914190 00000 n -0000914253 00000 n -0000914316 00000 n -0000914380 00000 n -0000914444 00000 n -0000917127 00000 n -0000915355 00000 n -0000914596 00000 n -0000915479 00000 n -0000915542 00000 n -0000915604 00000 n -0000915667 00000 n -0000915731 00000 n -0000915793 00000 n -0000915856 00000 n -0000915920 00000 n -0000915984 00000 n -0000916047 00000 n -0000916110 00000 n -0000916174 00000 n -0000916238 00000 n -0000916302 00000 n -0000916364 00000 n -0000916427 00000 n -0000916491 00000 n -0000916555 00000 n -0000916618 00000 n -0000916681 00000 n -0000916745 00000 n -0000916809 00000 n -0000916873 00000 n -0000916936 00000 n -0000916999 00000 n -0000917063 00000 n -0000920048 00000 n -0000918021 00000 n -0000917215 00000 n -0000918145 00000 n -0000918208 00000 n -0000918271 00000 n -0000918335 00000 n -0000918399 00000 n -0000918461 00000 n -0000918524 00000 n -0000918588 00000 n -0000918652 00000 n -0000918841 00000 n -0000918904 00000 n -0000918967 00000 n -0000919031 00000 n -0000919095 00000 n -0000919159 00000 n -0000919222 00000 n -0000919285 00000 n -0000919349 00000 n -0000919413 00000 n -0000919477 00000 n -0000919540 00000 n -0000919603 00000 n -0000919667 00000 n -0000919731 00000 n -0000919795 00000 n -0000919858 00000 n -0000919921 00000 n -0000919985 00000 n -0000921605 00000 n -0000920783 00000 n -0000920150 00000 n -0000920907 00000 n -0000920970 00000 n -0000921034 00000 n -0000921097 00000 n -0000921160 00000 n -0000921224 00000 n -0000921287 00000 n -0000921351 00000 n -0000921414 00000 n -0000921477 00000 n -0000921541 00000 n -0000925780 00000 n -0000924462 00000 n -0000921693 00000 n -0000924586 00000 n -0000924775 00000 n -0000924838 00000 n -0000924900 00000 n -0000925088 00000 n -0000925151 00000 n -0000925214 00000 n -0000925402 00000 n -0000925465 00000 n -0000925528 00000 n -0000925591 00000 n -0000925654 00000 n -0000925717 00000 n -0000929923 00000 n -0000929044 00000 n -0000925882 00000 n -0000929168 00000 n -0000929231 00000 n -0000929294 00000 n -0000929483 00000 n -0000929545 00000 n -0000929734 00000 n -0000929797 00000 n -0000929860 00000 n -0000977680 00000 n -0000935680 00000 n -0000933292 00000 n -0000930025 00000 n -0000933416 00000 n -0000933479 00000 n -0000933541 00000 n -0000933730 00000 n -0000933793 00000 n -0000933856 00000 n -0000933919 00000 n -0000933982 00000 n -0000934045 00000 n -0000934108 00000 n -0000934171 00000 n -0000934234 00000 n -0000934296 00000 n -0000934359 00000 n -0000934422 00000 n -0000934485 00000 n -0000934548 00000 n -0000934611 00000 n -0000934674 00000 n -0000934737 00000 n -0000934800 00000 n -0000934862 00000 n -0000934925 00000 n -0000934988 00000 n -0000935051 00000 n -0000935113 00000 n -0000935176 00000 n -0000935239 00000 n -0000935302 00000 n -0000935365 00000 n -0000935428 00000 n -0000935491 00000 n -0000935554 00000 n -0000935617 00000 n -0000939595 00000 n -0000938527 00000 n -0000935782 00000 n -0000938651 00000 n -0000938714 00000 n -0000938777 00000 n -0000938966 00000 n -0000939029 00000 n -0000939092 00000 n -0000939280 00000 n -0000939343 00000 n -0000939532 00000 n -0000943538 00000 n -0000942281 00000 n -0000939697 00000 n -0000942405 00000 n -0000942468 00000 n -0000942656 00000 n -0000942845 00000 n -0000943034 00000 n -0000943097 00000 n -0000943161 00000 n -0000943349 00000 n -0000943412 00000 n -0000943475 00000 n -0000944823 00000 n -0000944510 00000 n -0000943640 00000 n -0000944634 00000 n -0000944697 00000 n -0000944760 00000 n -0000950583 00000 n -0000946867 00000 n -0000944911 00000 n -0000947167 00000 n -0000947356 00000 n -0000947608 00000 n -0000947671 00000 n -0000947734 00000 n -0000947798 00000 n -0000947862 00000 n -0000947988 00000 n -0000948115 00000 n -0000948178 00000 n -0000948241 00000 n -0000948305 00000 n -0000948369 00000 n -0000948431 00000 n -0000948557 00000 n -0000948620 00000 n +0000889592 00000 n +0000889656 00000 n +0000889719 00000 n +0000889782 00000 n +0000889845 00000 n +0000889909 00000 n +0000889973 00000 n +0000890036 00000 n +0000890099 00000 n +0000890163 00000 n +0000890226 00000 n +0000988635 00000 n +0000895328 00000 n +0000893249 00000 n +0000890406 00000 n +0000893373 00000 n +0000893436 00000 n +0000893499 00000 n +0000893562 00000 n +0000893624 00000 n +0000893688 00000 n +0000893752 00000 n +0000893816 00000 n +0000893879 00000 n +0000893942 00000 n +0000894006 00000 n +0000894068 00000 n +0000894132 00000 n +0000894195 00000 n +0000894259 00000 n +0000894322 00000 n +0000894385 00000 n +0000894449 00000 n +0000894513 00000 n +0000894575 00000 n +0000894639 00000 n +0000894702 00000 n +0000894765 00000 n +0000894828 00000 n +0000894891 00000 n +0000894954 00000 n +0000895016 00000 n +0000895077 00000 n +0000895138 00000 n +0000895201 00000 n +0000895265 00000 n +0000899963 00000 n +0000897968 00000 n +0000895472 00000 n +0000898265 00000 n +0000898328 00000 n +0000898392 00000 n +0000898455 00000 n +0000898518 00000 n +0000898580 00000 n +0000898641 00000 n +0000898703 00000 n +0000898766 00000 n +0000898828 00000 n +0000898891 00000 n +0000898954 00000 n +0000899017 00000 n +0000899081 00000 n +0000899144 00000 n +0000899207 00000 n +0000899269 00000 n +0000899332 00000 n +0000898113 00000 n +0000899395 00000 n +0000899457 00000 n +0000899520 00000 n +0000899583 00000 n +0000899646 00000 n +0000899709 00000 n +0000899773 00000 n +0000899836 00000 n +0000899899 00000 n +0001004515 00000 n +0000904821 00000 n +0000902612 00000 n +0000900079 00000 n +0000902736 00000 n +0000902799 00000 n +0000902862 00000 n +0000902925 00000 n +0000902989 00000 n +0000903052 00000 n +0000903115 00000 n +0000903179 00000 n +0000903242 00000 n +0000903306 00000 n +0000903369 00000 n +0000903433 00000 n +0000903496 00000 n +0000903560 00000 n +0000903623 00000 n +0000903687 00000 n +0000903749 00000 n +0000903813 00000 n +0000903877 00000 n +0000903941 00000 n +0000904004 00000 n +0000904066 00000 n +0000904128 00000 n +0000904191 00000 n +0000904254 00000 n +0000904317 00000 n +0000904380 00000 n +0000904443 00000 n +0000904506 00000 n +0000904570 00000 n +0000904633 00000 n +0000904696 00000 n +0000904759 00000 n +0000909256 00000 n +0000907619 00000 n +0000904965 00000 n +0000907743 00000 n +0000907806 00000 n +0000907869 00000 n +0000907932 00000 n +0000907995 00000 n +0000908058 00000 n +0000908120 00000 n +0000908184 00000 n +0000908247 00000 n +0000908310 00000 n +0000908373 00000 n +0000908436 00000 n +0000908499 00000 n +0000908563 00000 n +0000908626 00000 n +0000908689 00000 n +0000908753 00000 n +0000908817 00000 n +0000908880 00000 n +0000908943 00000 n +0000909005 00000 n +0000909067 00000 n +0000909130 00000 n +0000909193 00000 n +0000914365 00000 n +0000912022 00000 n +0000909372 00000 n +0000912146 00000 n +0000912209 00000 n +0000912272 00000 n +0000912335 00000 n +0000912398 00000 n +0000912461 00000 n +0000912525 00000 n +0000912588 00000 n +0000912652 00000 n +0000912716 00000 n +0000912779 00000 n +0000912842 00000 n +0000912906 00000 n +0000912969 00000 n +0000913033 00000 n +0000913097 00000 n +0000913161 00000 n +0000913224 00000 n +0000913287 00000 n +0000913350 00000 n +0000913412 00000 n +0000913476 00000 n +0000913540 00000 n +0000913604 00000 n +0000913667 00000 n +0000913730 00000 n +0000913793 00000 n +0000913856 00000 n +0000913920 00000 n +0000913984 00000 n +0000914047 00000 n +0000914111 00000 n +0000914174 00000 n +0000914238 00000 n +0000914301 00000 n +0000919444 00000 n +0000917025 00000 n +0000914481 00000 n +0000917492 00000 n +0000917681 00000 n +0000917870 00000 n +0000917933 00000 n +0000917996 00000 n +0000918060 00000 n +0000917179 00000 n +0000917335 00000 n +0000918123 00000 n +0000918186 00000 n +0000918249 00000 n +0000918313 00000 n +0000918376 00000 n +0000918566 00000 n +0000918629 00000 n +0000918692 00000 n +0000918755 00000 n +0000918818 00000 n +0000919006 00000 n +0000919069 00000 n +0000919132 00000 n +0000919194 00000 n +0000919257 00000 n +0000919319 00000 n +0000923254 00000 n +0000921425 00000 n +0000919588 00000 n +0000921549 00000 n +0000921612 00000 n +0000921737 00000 n +0000921800 00000 n +0000921863 00000 n +0000921926 00000 n +0000921990 00000 n +0000922053 00000 n +0000922115 00000 n +0000922178 00000 n +0000922367 00000 n +0000922430 00000 n +0000922494 00000 n +0000922557 00000 n +0000922620 00000 n +0000922684 00000 n +0000922748 00000 n +0000922812 00000 n +0000922875 00000 n +0000922938 00000 n +0000923128 00000 n +0000923191 00000 n +0000927214 00000 n +0000925639 00000 n +0000923398 00000 n +0000925763 00000 n +0000925826 00000 n +0000925889 00000 n +0000925953 00000 n +0000926014 00000 n +0000926140 00000 n +0000926203 00000 n +0000926266 00000 n +0000926330 00000 n +0000926394 00000 n +0000926520 00000 n +0000926583 00000 n +0000926645 00000 n +0000926709 00000 n +0000926773 00000 n +0000926836 00000 n +0000926899 00000 n +0000927088 00000 n +0000927151 00000 n +0001004640 00000 n +0000930598 00000 n +0000929223 00000 n +0000927330 00000 n +0000929522 00000 n +0000929585 00000 n +0000929648 00000 n +0000929712 00000 n +0000929902 00000 n +0000929965 00000 n +0000930028 00000 n +0000930092 00000 n +0000929368 00000 n +0000930282 00000 n +0000930345 00000 n +0000930408 00000 n +0000930471 00000 n +0000930534 00000 n +0000936908 00000 n +0000933819 00000 n +0000930728 00000 n +0000933943 00000 n +0000934132 00000 n +0000934195 00000 n +0000934382 00000 n +0000934445 00000 n +0000934509 00000 n +0000934572 00000 n +0000934636 00000 n +0000934700 00000 n +0000934763 00000 n +0000934827 00000 n +0000934890 00000 n +0000934953 00000 n +0000935016 00000 n +0000935079 00000 n +0000935141 00000 n +0000935203 00000 n +0000935267 00000 n +0000935331 00000 n +0000935395 00000 n +0000935459 00000 n +0000935523 00000 n +0000935587 00000 n +0000935650 00000 n +0000935713 00000 n +0000935776 00000 n +0000935839 00000 n +0000935903 00000 n +0000935966 00000 n +0000936029 00000 n +0000936092 00000 n +0000936156 00000 n +0000936341 00000 n +0000936404 00000 n +0000936467 00000 n +0000936531 00000 n +0000936593 00000 n +0000936657 00000 n +0000936721 00000 n +0000936784 00000 n +0000936846 00000 n +0000940647 00000 n +0000938632 00000 n +0000937052 00000 n +0000938756 00000 n +0000939070 00000 n +0000939132 00000 n +0000939195 00000 n +0000939258 00000 n +0000939321 00000 n +0000939384 00000 n +0000939447 00000 n +0000939510 00000 n +0000939573 00000 n +0000939636 00000 n +0000939699 00000 n +0000939762 00000 n +0000939826 00000 n +0000939890 00000 n +0000939952 00000 n +0000940015 00000 n +0000940205 00000 n +0000940268 00000 n +0000940331 00000 n +0000940394 00000 n +0000940457 00000 n +0000940521 00000 n +0000940585 00000 n +0000943384 00000 n +0000941484 00000 n +0000940777 00000 n +0000941608 00000 n +0000941671 00000 n +0000941733 00000 n +0000941796 00000 n +0000941860 00000 n +0000941922 00000 n +0000941985 00000 n +0000942049 00000 n +0000942113 00000 n +0000942177 00000 n +0000942240 00000 n +0000942303 00000 n +0000942367 00000 n +0000942431 00000 n +0000942495 00000 n +0000942557 00000 n +0000942620 00000 n +0000942684 00000 n +0000942748 00000 n +0000942812 00000 n +0000942875 00000 n +0000942938 00000 n +0000943002 00000 n +0000943066 00000 n +0000943130 00000 n +0000943193 00000 n +0000943256 00000 n +0000943320 00000 n +0000946298 00000 n +0000944336 00000 n +0000943472 00000 n +0000944460 00000 n +0000944523 00000 n +0000944586 00000 n +0000944650 00000 n +0000944714 00000 n +0000944776 00000 n +0000944839 00000 n +0000944903 00000 n +0000944967 00000 n +0000945031 00000 n +0000945094 00000 n +0000945157 00000 n +0000945221 00000 n +0000945285 00000 n +0000945347 00000 n +0000945410 00000 n +0000945474 00000 n +0000945538 00000 n +0000945727 00000 n +0000945790 00000 n +0000945853 00000 n +0000945917 00000 n +0000945981 00000 n +0000946045 00000 n +0000946108 00000 n +0000946171 00000 n +0000946235 00000 n 0000948683 00000 n -0000948746 00000 n -0000948809 00000 n -0000948873 00000 n -0000948936 00000 n -0000948999 00000 n -0000949062 00000 n -0000949125 00000 n -0000949188 00000 n -0000949251 00000 n -0000949314 00000 n -0000949378 00000 n -0000949442 00000 n -0000949505 00000 n -0000949568 00000 n -0000949631 00000 n -0000949694 00000 n -0000949758 00000 n -0000949822 00000 n -0000949886 00000 n -0000949950 00000 n -0000950014 00000 n -0000950078 00000 n -0000950142 00000 n -0000950205 00000 n -0000950268 00000 n -0000950331 00000 n -0000950393 00000 n -0000950457 00000 n -0000947012 00000 n -0000950520 00000 n -0000955039 00000 n -0000952267 00000 n -0000950713 00000 n -0000952391 00000 n -0000952516 00000 n -0000952640 00000 n -0000952703 00000 n -0000952765 00000 n -0000952829 00000 n -0000952893 00000 n -0000952957 00000 n -0000953084 00000 n -0000953146 00000 n -0000953336 00000 n -0000953399 00000 n -0000953462 00000 n -0000953715 00000 n -0000953778 00000 n -0000953840 00000 n -0000953902 00000 n -0000953966 00000 n -0000954093 00000 n -0000954156 00000 n -0000954345 00000 n -0000954408 00000 n -0000954471 00000 n -0000954534 00000 n -0000954598 00000 n -0000954724 00000 n -0000954849 00000 n -0000954912 00000 n -0000954975 00000 n -0000977805 00000 n -0000959192 00000 n -0000956786 00000 n -0000955169 00000 n -0000957106 00000 n -0000957169 00000 n -0000957231 00000 n -0000957295 00000 n -0000957358 00000 n -0000957422 00000 n -0000957675 00000 n -0000957738 00000 n -0000957801 00000 n -0000957865 00000 n -0000958054 00000 n -0000958117 00000 n -0000958180 00000 n -0000956931 00000 n -0000958243 00000 n -0000958369 00000 n -0000958496 00000 n -0000958559 00000 n -0000958622 00000 n -0000958686 00000 n -0000958750 00000 n -0000958813 00000 n -0000958939 00000 n -0000959066 00000 n -0000959129 00000 n -0000964000 00000 n -0000960959 00000 n -0000959322 00000 n -0000961425 00000 n -0000961676 00000 n -0000961739 00000 n -0000961801 00000 n -0000961865 00000 n -0000961924 00000 n -0000961984 00000 n -0000962044 00000 n -0000962108 00000 n -0000962235 00000 n -0000962298 00000 n -0000961113 00000 n -0000962361 00000 n -0000962425 00000 n -0000962488 00000 n -0000962551 00000 n -0000962614 00000 n -0000962677 00000 n -0000962741 00000 n -0000962803 00000 n -0000962865 00000 n -0000962928 00000 n -0000962992 00000 n -0000963056 00000 n -0000963119 00000 n -0000963182 00000 n -0000963245 00000 n -0000961268 00000 n -0000963309 00000 n -0000963561 00000 n -0000963622 00000 n -0000963685 00000 n -0000963874 00000 n -0000963937 00000 n -0000966817 00000 n -0000967829 00000 n -0000965494 00000 n -0000964116 00000 n -0000965618 00000 n -0000965681 00000 n -0000965807 00000 n -0000965870 00000 n -0000965933 00000 n -0000965997 00000 n -0000966121 00000 n -0000966247 00000 n -0000966309 00000 n -0000966372 00000 n -0000966435 00000 n -0000966499 00000 n -0000966563 00000 n -0000966627 00000 n -0000966691 00000 n -0000966944 00000 n -0000967007 00000 n -0000967070 00000 n -0000967197 00000 n -0000967260 00000 n -0000967323 00000 n -0000967387 00000 n -0000967639 00000 n -0000967702 00000 n -0000967765 00000 n -0000972461 00000 n -0000969994 00000 n -0000967931 00000 n -0000970118 00000 n -0000970181 00000 n +0000947227 00000 n +0000946400 00000 n +0000947351 00000 n +0000947414 00000 n +0000947478 00000 n +0000947541 00000 n +0000947604 00000 n +0000947668 00000 n +0000947731 00000 n +0000947795 00000 n +0000947858 00000 n +0000947921 00000 n +0000947985 00000 n +0000948049 00000 n +0000948113 00000 n +0000948176 00000 n +0000948239 00000 n +0000948303 00000 n +0000948366 00000 n +0000948430 00000 n +0000948493 00000 n +0000948555 00000 n +0000948619 00000 n +0001004765 00000 n +0000952858 00000 n +0000951540 00000 n +0000948771 00000 n +0000951664 00000 n +0000951853 00000 n +0000951916 00000 n +0000951978 00000 n +0000952166 00000 n +0000952229 00000 n +0000952292 00000 n +0000952480 00000 n +0000952543 00000 n +0000952606 00000 n +0000952669 00000 n +0000952732 00000 n +0000952795 00000 n +0000957002 00000 n +0000956123 00000 n +0000952960 00000 n +0000956247 00000 n +0000956310 00000 n +0000956373 00000 n +0000956562 00000 n +0000956624 00000 n +0000956813 00000 n +0000956876 00000 n +0000956939 00000 n +0000962759 00000 n +0000960371 00000 n +0000957104 00000 n +0000960495 00000 n +0000960558 00000 n +0000960620 00000 n +0000960809 00000 n +0000960872 00000 n +0000960935 00000 n +0000960998 00000 n +0000961061 00000 n +0000961124 00000 n +0000961187 00000 n +0000961250 00000 n +0000961313 00000 n +0000961375 00000 n +0000961438 00000 n +0000961501 00000 n +0000961564 00000 n +0000961627 00000 n +0000961690 00000 n +0000961753 00000 n +0000961816 00000 n +0000961879 00000 n +0000961941 00000 n +0000962004 00000 n +0000962067 00000 n +0000962130 00000 n +0000962192 00000 n +0000962255 00000 n +0000962318 00000 n +0000962381 00000 n +0000962444 00000 n +0000962507 00000 n +0000962570 00000 n +0000962633 00000 n +0000962696 00000 n +0000966675 00000 n +0000965605 00000 n +0000962861 00000 n +0000965729 00000 n +0000965792 00000 n +0000965855 00000 n +0000966044 00000 n +0000966107 00000 n +0000966170 00000 n +0000966359 00000 n +0000966422 00000 n +0000966612 00000 n +0000970622 00000 n +0000969361 00000 n +0000966777 00000 n +0000969485 00000 n +0000969548 00000 n +0000969737 00000 n +0000969927 00000 n +0000970117 00000 n +0000970180 00000 n 0000970244 00000 n -0000970371 00000 n -0000970434 00000 n -0000970497 00000 n -0000970560 00000 n -0000970623 00000 n -0000970687 00000 n -0000970751 00000 n -0000970815 00000 n -0000970878 00000 n -0000970942 00000 n -0000971006 00000 n -0000971070 00000 n -0000971134 00000 n -0000971259 00000 n -0000971386 00000 n -0000971449 00000 n -0000971512 00000 n -0000971576 00000 n -0000971703 00000 n -0000971766 00000 n -0000971829 00000 n -0000971955 00000 n -0000972082 00000 n -0000972145 00000 n -0000972208 00000 n -0000972271 00000 n -0000972334 00000 n -0000972397 00000 n -0000972639 00000 n -0000977921 00000 n -0000978047 00000 n -0000978173 00000 n -0000978299 00000 n -0000978398 00000 n -0000978490 00000 n -0001006590 00000 n -0001066508 00000 n -0001066549 00000 n -0001066589 00000 n -0001066821 00000 n +0000970433 00000 n +0000970496 00000 n +0000970559 00000 n +0000971907 00000 n +0000971594 00000 n +0000970724 00000 n +0000971718 00000 n +0000971781 00000 n +0000971844 00000 n +0001004890 00000 n +0000977668 00000 n +0000973951 00000 n +0000971995 00000 n +0000974251 00000 n +0000974441 00000 n +0000974693 00000 n +0000974756 00000 n +0000974819 00000 n +0000974883 00000 n +0000974947 00000 n +0000975073 00000 n +0000975200 00000 n +0000975263 00000 n +0000975326 00000 n +0000975390 00000 n +0000975454 00000 n +0000975516 00000 n +0000975642 00000 n +0000975705 00000 n +0000975768 00000 n +0000975831 00000 n +0000975894 00000 n +0000975958 00000 n +0000976021 00000 n +0000976084 00000 n +0000976147 00000 n +0000976210 00000 n +0000976273 00000 n +0000976336 00000 n +0000976399 00000 n +0000976463 00000 n +0000976527 00000 n +0000976590 00000 n +0000976653 00000 n +0000976716 00000 n +0000976779 00000 n +0000976843 00000 n +0000976907 00000 n +0000976971 00000 n +0000977035 00000 n +0000977099 00000 n +0000977163 00000 n +0000977227 00000 n +0000977290 00000 n +0000977353 00000 n +0000977416 00000 n +0000977478 00000 n +0000977542 00000 n +0000974096 00000 n +0000977605 00000 n +0000982124 00000 n +0000979352 00000 n +0000977798 00000 n +0000979476 00000 n +0000979601 00000 n +0000979725 00000 n +0000979788 00000 n +0000979850 00000 n +0000979914 00000 n +0000979978 00000 n +0000980042 00000 n +0000980169 00000 n +0000980231 00000 n +0000980421 00000 n +0000980484 00000 n +0000980547 00000 n +0000980800 00000 n +0000980863 00000 n +0000980925 00000 n +0000980987 00000 n +0000981051 00000 n +0000981178 00000 n +0000981241 00000 n +0000981430 00000 n +0000981493 00000 n +0000981556 00000 n +0000981619 00000 n +0000981683 00000 n +0000981809 00000 n +0000981934 00000 n +0000981997 00000 n +0000982060 00000 n +0000986278 00000 n +0000983872 00000 n +0000982254 00000 n +0000984192 00000 n +0000984255 00000 n +0000984317 00000 n +0000984381 00000 n +0000984444 00000 n +0000984508 00000 n +0000984761 00000 n +0000984824 00000 n +0000984887 00000 n +0000984951 00000 n +0000985140 00000 n +0000985203 00000 n +0000985266 00000 n +0000984017 00000 n +0000985329 00000 n +0000985455 00000 n +0000985582 00000 n +0000985645 00000 n +0000985708 00000 n +0000985772 00000 n +0000985836 00000 n +0000985899 00000 n +0000986025 00000 n +0000986152 00000 n +0000986215 00000 n +0000991085 00000 n +0000988044 00000 n +0000986408 00000 n +0000988510 00000 n +0000988761 00000 n +0000988824 00000 n +0000988886 00000 n +0000988950 00000 n +0000989009 00000 n +0000989069 00000 n +0000989129 00000 n +0000989193 00000 n +0000989320 00000 n +0000989383 00000 n +0000988198 00000 n +0000989446 00000 n +0000989510 00000 n +0000989573 00000 n +0000989636 00000 n +0000989699 00000 n +0000989762 00000 n +0000989826 00000 n +0000989888 00000 n +0000989950 00000 n +0000990013 00000 n +0000990077 00000 n +0000990141 00000 n +0000990204 00000 n +0000990267 00000 n +0000990330 00000 n +0000988353 00000 n +0000990394 00000 n +0000990646 00000 n +0000990707 00000 n +0000990770 00000 n +0000990959 00000 n +0000991022 00000 n +0000993901 00000 n +0000994913 00000 n +0000992578 00000 n +0000991201 00000 n +0000992702 00000 n +0000992765 00000 n +0000992891 00000 n +0000992954 00000 n +0000993017 00000 n +0000993081 00000 n +0000993205 00000 n +0000993331 00000 n +0000993393 00000 n +0000993456 00000 n +0000993519 00000 n +0000993583 00000 n +0000993647 00000 n +0000993711 00000 n +0000993775 00000 n +0000994028 00000 n +0000994091 00000 n +0000994154 00000 n +0000994281 00000 n +0000994344 00000 n +0000994407 00000 n +0000994471 00000 n +0000994723 00000 n +0000994786 00000 n +0000994849 00000 n +0000999546 00000 n +0000997079 00000 n +0000995015 00000 n +0000997203 00000 n +0000997266 00000 n +0000997329 00000 n +0000997456 00000 n +0000997519 00000 n +0000997582 00000 n +0000997645 00000 n +0000997708 00000 n +0000997772 00000 n +0000997836 00000 n +0000997900 00000 n +0000997963 00000 n +0000998027 00000 n +0000998091 00000 n +0000998155 00000 n +0000998219 00000 n +0000998344 00000 n +0000998471 00000 n +0000998534 00000 n +0000998597 00000 n +0000998661 00000 n +0000998788 00000 n +0000998851 00000 n +0000998914 00000 n +0000999040 00000 n +0000999167 00000 n +0000999230 00000 n +0000999293 00000 n +0000999356 00000 n +0000999419 00000 n +0000999482 00000 n +0001005015 00000 n +0000999724 00000 n +0001005095 00000 n +0001005221 00000 n +0001005347 00000 n +0001005473 00000 n +0001005581 00000 n +0001005673 00000 n +0001034467 00000 n +0001096677 00000 n +0001096718 00000 n +0001096758 00000 n +0001096990 00000 n trailer << -/Size 5330 -/Root 5328 0 R -/Info 5329 0 R +/Size 5506 +/Root 5504 0 R +/Info 5505 0 R >> startxref -1066977 +1097146 %%EOF diff --git a/docs/rel_notes.txt b/docs/rel_notes.txt index bf0771363..64212a292 100644 --- a/docs/rel_notes.txt +++ b/docs/rel_notes.txt @@ -1,3 +1,11 @@ +Release Notes for Bugzilla version 3.0 and higher are available in HTML +format, either on the bugzilla.org website, or in your current installation, +linked from the index page. + +bugzilla.org links for release notes +------------------------------------ +3.0: http://www.bugzilla.org/releases/3.0/release-notes.html + *************************************** *** The Bugzilla 2.22 Release Notes *** *************************************** @@ -66,20 +74,7 @@ Important Updates In This Point Release *************************************** This section describes bugs fixed in releases after the original 2.22 -release. This section only describes significant fixes. To see all -fixes, look at the Change Logs at http://www.bugzilla.org/status/changes.html - -Version 2.22.3 --------------- - -+ Bug lists in iCal format were cutting off bug summaries if they had - a comma in them. (bug 274408) - -+ If collectstats.pl encountered an invalid series when collecting data for - New Charts, it would stop processing all series, silently. This means - that several series may not have been collecting data. On PostgreSQL, - all series were failing, thus meaning that New Charts were not working - at all on PostgreSQL. (bug 257351) +release. Version 2.22.2 -------------- @@ -598,14 +593,6 @@ This is actually safe to do at any time--it just forces a logout of every single user, even those with saved sessions. (It invalidates every login cookie Bugzilla has ever given out.) -Version 2.22.3 --------------- - -This release fixes a Cross-Site Scripting vulnerability. You can read the -details of the security fix at: - -http://www.bugzilla.org/security/2.20.4/ - Version 2.22.2 -------------- @@ -2400,7 +2387,7 @@ See also next section. 'letsubmitterchoosepriority' was off. (bug 63018) -- Most CGIs are now templatized. This helps to make it +- Most CGIs are now templatised. This helps to make it easier to remember to HTML filter values and easier to spot when they are not, preventing cross site scripting attacks. (bug 86168) @@ -2411,17 +2398,17 @@ See also next section. *** IMPORTANT CHANGES *** -- 2.16 introduces "templatization", a new feature that allows - administrators to easily customize the HTML output (the "look and feel") +- 2.16 introduces "templatisation", a new feature that allows + administrators to easily customise the HTML output (the "look and feel") of Bugzilla without altering Perl code. Bugzilla uses the - "Template Toolkit" for this. Please see the "Template Customization" + "Template Toolkit" for this. Please see the "Template Customisation" section of the Bugzilla Guide for more details. - Administrators who ran the 2.15 development version with custom + Administrators who ran the 2.15 development version and customised templates should check the templates are still valid, as file names and file paths have changed. - Most output is now templatized. This process will be complete next + Most output is now templatised. This process will be complete next milestone. For speed, compiled templates are cached on disk. If you modify the @@ -2475,7 +2462,7 @@ See also next section. lengthy delays in future if this problem reoccurs. (bug 106377) -- In parallel with templatization, a lot of changes have been made to the HTML +- In parallel with templatisation, a lot of changes have been made to the HTML output of the Bugzilla CGIs. This could break code that attempts to parse such code. For example, this breaks mozbot. (no bug number) @@ -2752,8 +2739,8 @@ known to us after the Bugzilla 2.14 release. *** SECURITY ISSUES RESOLVED *** -- Multiple instances of unauthorized access to confidential - bugs have been fixed. +- Multiple instances of unauthorised access to confidential + bugs has been fixed. (bug 39524, 39526, 39527, 39531, 39533, 70189, 82781) - Multiple instances of untrusted parameters not being @@ -2764,7 +2751,7 @@ known to us after the Bugzilla 2.14 release. - After logging in passwords no longer appear in the URL. (bug 15980) -- Procedures to prevent unauthorized access to confidential +- Procedures to prevent unauthorised access to confidential files are now simpler. In particular the shadow directory no longer exists and the data/comments file no longer needs to be directly accessible, so the entire data directory can @@ -2775,7 +2762,7 @@ known to us after the Bugzilla 2.14 release. - If they do not already exist, checksetup.pl will attempt to write Apache .htaccess files by default, to prevent - unauthorized access to confidential files. You can turn this + unauthorised access to confidential files. You can turn this off in the localconfig file. (bug 76154) diff --git a/docs/txt/Bugzilla-Guide.txt b/docs/txt/Bugzilla-Guide.txt index 40e7aece5..6f1bee032 100644 --- a/docs/txt/Bugzilla-Guide.txt +++ b/docs/txt/Bugzilla-Guide.txt @@ -1,9 +1,9 @@ -The Bugzilla Guide - 2.22.3 Release +The Bugzilla Guide - 3.0 Release The Bugzilla Team - 2007-08-23 + 2007-05-09 This is the documentation for Bugzilla, a bug-tracking system from mozilla.org. Bugzilla is an enterprise-class piece of software that tracks @@ -41,11 +41,12 @@ The Bugzilla Team 3.6. Versions 3.7. Milestones 3.8. Flags - 3.9. Legal Values - 3.10. Voting - 3.11. Quips - 3.12. Groups and Group Security - 3.13. Upgrading to New Releases + 3.9. Custom Fields + 3.10. Legal Values + 3.11. Voting + 3.12. Quips + 3.13. Groups and Group Security + 3.14. Upgrading to New Releases 4. Bugzilla Security @@ -70,12 +71,12 @@ The Bugzilla Team 5.12. Flags 5.13. Whining - 6. Customizing Bugzilla + 6. Customising Bugzilla - 6.1. Template Customization - 6.2. Template Hooks - 6.3. Customizing Who Can Change What - 6.4. Modifying Your Running System + 6.1. Custom Skins + 6.2. Template Customization + 6.3. The Bugzilla Extension Mechanism + 6.4. Customizing Who Can Change What 6.5. Integrating Bugzilla with Third-Party Tools A. The Bugzilla FAQ @@ -88,11 +89,10 @@ The Bugzilla Team B.4. DBD::Sponge::db prepare failed B.5. cannot chdir(/var/spool/mqueue) - B.6. Your vendor has not defined Fcntl macro O_NOINHERIT - B.7. Everybody is constantly being forced to relogin - B.8. Some users are constantly being forced to relogin - B.9. index.cgi doesn't show up unless specified in the URL - B.10. checksetup.pl reports "Client does not support authentication + B.6. Everybody is constantly being forced to relogin + B.7. Some users are constantly being forced to relogin + B.8. index.cgi doesn't show up unless specified in the URL + B.9. checksetup.pl reports "Client does not support authentication protocol requested by server..." C. Contrib @@ -175,8 +175,8 @@ Chapter 1. About This Guide 1.3. New Versions - This is the 2.22.3 version of The Bugzilla Guide. It is so named to match - the current version of Bugzilla. + This is the 3.0 version of The Bugzilla Guide. It is so named to match the + current version of Bugzilla. The latest version of this guide can always be found at http://www.bugzilla.org, or checked out via CVS by following the Mozilla CVS @@ -188,7 +188,7 @@ Chapter 1. About This Guide languages: French, German, Japanese. Note that these may be outdated or not up to date. - In addition, there are Bugzilla template localization projects in the + In addition, there are Bugzilla template localisation projects in the following languages. They may have translated documentation available: Arabic, Belarusian, Bulgarian, Brazilian Portuguese, Chinese, French, German, Italian, Japanese, Korean, Russian and Spanish. @@ -303,7 +303,7 @@ Chapter 2. Installing Bugzilla installing Bugzilla (and at regular intervals thereafter :-). In outline, the installation proceeds as follows: - 1. Install Perl (5.6.1 or above for non-Windows platforms; 5.8.1 for + 1. Install Perl (5.8.0 or above for non-Windows platforms; 5.8.1 for Windows) 2. Install a Database Engine 3. Install a Webserver @@ -320,7 +320,7 @@ Chapter 2. Installing Bugzilla Any machine that doesn't have Perl on it is a sad machine indeed. If you don't have it and your OS doesn't provide official packages, visit - http://www.perl.com. Although Bugzilla runs with Perl 5.6.1, it's a good + http://www.perl.com. Although Bugzilla runs with Perl 5.8.0, it's a good idea to be using the latest stable version. _________________________________________________________________ @@ -336,7 +336,7 @@ Chapter 2. Installing Bugzilla Installed Version Test: mysql -V If you don't have it and your OS doesn't provide official packages, visit - http://www.mysql.com. You need MySQL version 4.0.14 or higher. + http://www.mysql.com. You need MySQL version 4.1.2 or higher. Note Many of the binary versions of MySQL store their data files in /var. On some Unix systems, this is part of a smaller root partition, and may not @@ -354,7 +354,7 @@ Chapter 2. Installing Bugzilla Installed Version Test: psql -V If you don't have it and your OS doesn't provide official packages, visit - http://www.postgresql.org/. You need PostgreSQL version 7.3.x or higher. + http://www.postgresql.org/. You need PostgreSQL version 8.00.0000 or higher. If you install from something other than a packaging/installation system, such as .rpm (Redhat Package), .deb (Debian Package), .exe (Windows @@ -445,31 +445,37 @@ Chapter 2. Installing Bugzilla Required Perl modules: - 1. AppConfig (1.52) - 2. CGI (2.93) - 3. Data::Dumper (any) - 4. Date::Format (2.21) - 5. DBI (1.38) - 6. DBD::mysql (2.9003) if using MySQL - 7. DBD::Pg (1.31) if using PostgreSQL - 8. File::Spec (0.84) - 9. File::Temp (any) - 10. Template (2.10) - 11. Text::Wrap (2001.0131) - 12. Mail::Mailer (1.67) - 13. MIME::Base64 (3.01) - 14. MIME::Parser (5.406) - 15. Storable (any) + 1. CGI 2.93 or CGI 3.11 if using mod_perl + 2. Date::Format (2.21) + 3. DBI (1.41) + 4. DBD::mysql (2.9003) if using MySQL + 5. DBD::Pg (1.45) if using PostgreSQL + 6. File::Spec (0.84) + 7. Template (2.12) + 8. Email::Send (2.00) + 9. Email::MIME::Modifier (any) Optional Perl modules: 1. GD (1.20) for bug charting - 2. Chart::Base (1.0) for bug charting - 3. GD::Graph (any) for bug charting - 4. GD::Text::Align (any) for bug charting - 5. XML::Twig (any) for the XML interface - 6. PatchReader (0.9.4) for pretty HTML view of patches - 7. Image::Magick (any) for converting BMP image attachments to PNG + 2. Template::Plugin::GD::Image (1.20) for Graphical Reports + 3. Chart::Base (1.0) for bug charting + 4. GD::Graph (any) for bug charting + 5. GD::Text (any) for bug charting + 6. XML::Twig (any) for bug import/export + 7. MIME::Parser (5.406) for bug import/export + 8. LWP::UserAgent (any) for Automatic Update Notifications + 9. PatchReader (0.9.4) for pretty HTML view of patches + 10. Image::Magick (any) for converting BMP image attachments to PNG + 11. Net::LDAP (any) for LDAP Authentication + 12. SOAP::Lite (any) for the web service interface + 13. HTML::Parser (3.40) for More HTML in Product/Group Descriptions + 14. HTML::Scrubber (any) for More HTML in Product/Group Descriptions + 15. Email::MIME::Attachment::Stripper (any) for Inbound Email + 16. Email::Reply (any) for Inbound Email + 17. mod_perl2 (1.999022) for mod_perl + 18. CGI (2.93) for mod_perl + 19. Apache::DBI (0.96) for mod_perl2 _________________________________________________________________ 2.1.5.1. DBD::mysql @@ -487,7 +493,7 @@ Chapter 2. Installing Bugzilla which MySQL creates upon installation. _________________________________________________________________ -2.1.5.2. Template Toolkit (2.10) +2.1.5.2. Template Toolkit (2.12) When you install Template Toolkit, you'll get asked various questions about features to enable. The defaults are fine, except that it is recommended you @@ -521,9 +527,9 @@ Chapter 2. Installing Bugzilla The GD::Graph module is only required if you want graphical reports. _________________________________________________________________ -2.1.5.6. GD::Text::Align (any) +2.1.5.6. GD::Text (any) - The GD::Text::Align module is only required if you want graphical reports. + The GD::Text module is only required if you want graphical reports. _________________________________________________________________ 2.1.5.7. XML::Twig (any) @@ -534,7 +540,14 @@ Chapter 2. Installing Bugzilla database. _________________________________________________________________ -2.1.5.8. PatchReader (0.9.4) +2.1.5.8. SOAP::Lite (any) + + Installing SOAP::Lite enables your Bugzilla installation to be accessible at + a standardized Web Service interface (SOAP/XML-RPC) by third-party + applications via HTTP(S). + _________________________________________________________________ + +2.1.5.9. PatchReader (0.9.4) The PatchReader module is only required if you want to use Patch Viewer, a Bugzilla feature to show code patches in your web browser in a more readable @@ -575,6 +588,22 @@ Chapter 2. Installing Bugzilla Bugzilla should also be fine. _________________________________________________________________ +2.1.7. Installing Bugzilla on mod_perl + + It is now possible to run the Bugzilla software under mod_perl on Apache. + mod_perl has some additional requirements to that of running Bugzilla under + mod_cgi (the standard and previous way). + + Bugzilla requires mod_perl to be installed, which can be obtained from + http://perl.apache.org - Bugzilla requires version 1.999022 (AKA 2.0.0-RC5) + to be installed. + + Bugzilla also requires a more up-to-date version of the CGI perl module to + be installed, version 3.11 as opposed to 2.93 + + Finally, Bugzilla also requires Apache::DBI (0.96) to be installed as well. + _________________________________________________________________ + 2.2. Configuration Warning Poorly-configured MySQL and Bugzilla installations have given @@ -719,10 +748,6 @@ Chapter 2. Installing Bugzilla 2.2.2.3. PostgreSQL - Note If you are using PostgreSQL 8.0.1 or higher, then you will require to - use a version of DBD::Pg which is equal to or greater than version 1.41 - _________________________________________________________________ - 2.2.2.3.1. Add a User to PostgreSQL You need to add a new user to PostgreSQL for the Bugzilla application to use @@ -755,16 +780,6 @@ Chapter 2. Installing Bugzilla '127.0.0.1' to 'all' databases on this server from the 'bugs' user, and use password authentication (md5) for that user. - If you are using versions of PostgreSQL before version 8, you may also need - to edit postgresql.conf , also usually found in the /var/lib/pgsql/data/ - folder. You will need to make a single line change, changing - - # tcpip_socket = false - - to - - tcpip_socket = true - Now, you will need to restart PostgreSQL, but you will need to fully stop and start the server rather than just restarting due to the possibility of a change to postgresql.conf. After the server has restarted, you will need to @@ -803,9 +818,16 @@ Chapter 2. Installing Bugzilla Bugzilla files as expected. _________________________________________________________________ -2.2.4.1. Apache httpd +2.2.4.1. Bugzilla using Apache + + You have two options for running Bugzilla under Apache - mod_cgi (the + default) and mod_perl (new in Bugzilla 2.23) + _________________________________________________________________ + +2.2.4.1.1. Apache httpd with mod_cgi - To configure your Apache web server to work with Bugzilla, do the following: + To configure your Apache web server to work with Bugzilla while using + mod_cgi, do the following: 1. Load httpd.conf in your editor. In Fedora and Red Hat Linux, this file is found in /etc/httpd/conf. 2. Apache uses <Directory> directives to permit fine-grained permission @@ -814,12 +836,12 @@ Chapter 2. Installing Bugzilla exist, you'll want to add one.) In this example, Bugzilla has been installed at /var/www/html/bugzilla. -<Directory /var/www/html/bugzilla> - AddHandler cgi-script .cgi - Options +Indexes +ExecCGI - DirectoryIndex index.cgi - AllowOverride Limit - </Directory> + <Directory /var/www/html/bugzilla> + AddHandler cgi-script .cgi + Options +Indexes +ExecCGI + DirectoryIndex index.cgi + AllowOverride Limit + </Directory> These instructions: allow apache to run .cgi files found within the bugzilla directory; instructs the server to look for a file called index.cgi if someone only types the directory name into the browser; and @@ -840,12 +862,64 @@ Chapter 2. Installing Bugzilla to add the following to the Options line of the Bugzilla <Directory> directive (the same one as in the step above): - +FollowSymLinks + +FollowSymLinks Without this directive, Apache will not follow symbolic links to places outside its own directory structure, and you will be unable to run Bugzilla. _________________________________________________________________ +2.2.4.1.2. Apache httpd with mod_perl + + Some configuration is required to make Bugzilla work with Apache and + mod_perl + 1. Load httpd.conf in your editor. In Fedora and Red Hat Linux, this file + is found in /etc/httpd/conf. + 2. Add the following information to your httpd.conf file, substituting + where appropriate with your own local paths. + + Note This should be used instead of the <Directory> block shown above. This + should also be above any other mod_perl directives within the httpd.conf and + must be specified in the order as below. + + Warning You should also ensure that you have disabled KeepAlive support in + your Apache install when utilizing Bugzilla under mod_perl + + PerlSwitches -I/var/www/html/bugzilla -w -T + PerlConfigRequire /var/www/html/bugzilla/mod_perl.pl + 3. checksetup.pl can set tighter permissions on Bugzilla's files and + directories if it knows what group the webserver runs as. Find the Group + line in httpd.conf, place the value found there in the $webservergroup + variable in localconfig, then rerun checksetup.pl. + + On restarting Apache, Bugzilla should now be running within the mod_perl + environment. Please ensure you have run checksetup.pl to set permissions + before you restart Apache. + + Note Please bear the following points in mind when looking at using Bugzilla + under mod_perl: + + * mod_perl support in Bugzilla can take up a HUGE amount of RAM. You could + be looking at 30MB per httpd child, easily. Basically, you just need a + lot of RAM. The more RAM you can get, the better. mod_perl is basically + trading RAM for speed. At least 2GB total system RAM is recommended for + running Bugzilla under mod_perl. + * Under mod_perl, you have to restart Apache if you make any manual change + to any Bugzilla file. You can't just reload--you have to actually + restart the server (as in make sure it stops and starts again). You can + change localconfig and the params file manually, if you want, because + those are re-read every time you load a page. + * You must run in Apache's Prefork MPM (this is the default). The Worker + MPM may not work--we haven't tested Bugzilla's mod_perl support under + threads. (And, in fact, we're fairly sure it won't work.) + * Bugzilla generally expects to be the only mod_perl application running + on your entire server. It may or may not work if there are other + applications also running under mod_perl. It does try its best to play + nice with other mod_perl applications, but it still may have conflicts. + * It is recommended that you have one Bugzilla instance running under + mod_perl on your server. Bugzilla has not been tested with more than one + instance running. + _________________________________________________________________ + 2.2.4.2. Microsoft Internet Information Services If you are running Bugzilla on Windows and choose to use Microsoft's @@ -1032,10 +1106,12 @@ c:\perl\bin\perl.exe -xc:\bugzilla -wT "%s" %s Bugzilla where you need to deal with user ID (e.g assigning a bug) use the email address. The LDAP authentication builds on top of this scheme, rather than replacing it. The initial log in is done with a username and password - for the LDAP directory. This then fetches the email address from LDAP and - authenticates seamlessly in the standard Bugzilla authentication scheme - using this email address. If an account for this address already exists in - your Bugzilla system, it will log in to that account. If no account for that + for the LDAP directory. Bugzilla tries to bind to LDAP using those + credentials, and if successful, try to map this account to a Bugzilla + account. If a LDAP mail attribute is defined, the value of this attribute is + used, otherwise emailsuffix parameter is appended to LDAP username to form a + full email address. If an account for this address already exists in your + Bugzilla system, it will log in to that account. If no account for that email address exists, one is created at the time of login. (In this case, Bugzilla will attempt to use the "displayName" or "cn" attribute to determine the user's full name.) After authentication, all other @@ -1067,6 +1143,13 @@ c:\perl\bin\perl.exe -xc:\bugzilla -wT "%s" %s Ex. "ldap.company.com" or "ldap.company.com:3268" + You can also specify a LDAP URI, so as to use other protocols, such + as LDAPS or LDAPI. If port was not specified in the URI, the default + is either 389 or 636 for 'LDAP' and 'LDAPS' schemes respectively. + + Ex. "ldap://ldap.company.com", "ldaps://ldap.company.com" or + "ldapi://%2fvar%2flib%2fldap_sock" + LDAPbinddn [Optional] Some LDAP servers will not allow an anonymous bind to search the directory. If this is the case with your configuration you should set @@ -1648,15 +1731,6 @@ Chapter 3. Administering Bugzilla will prompt you to log in, and your name/password will be accepted here (but nowhere else). - passwordmail - Every time a user creates an account, the text of this parameter - (with substitutions) is sent to the new user along with their - password message. - - Add any text you wish to the "passwordmail" parameter box. For - instance, many people choose to use this box to give a quick training - blurb about how to use Bugzilla at your site. - movebugs This option is an undocumented feature to allow moving bugs between separate Bugzilla installations. You will need to understand the @@ -1669,6 +1743,12 @@ Chapter 3. Administering Bugzilla addition to that of the default assignee, who will be sent carbon copies of incoming bugs. + globalwatcher + This allows to define specific users that will receive notification + each time a new bug in entered, or when an existing bug changes, + according to the normal groupset permissions. It may be useful for + sending notifications to a mailing-list, for instance. + usestatuswhiteboard This defines whether you wish to have a free-form, overwritable field associated with each bug. The advantage of the Status Whiteboard is @@ -1804,6 +1884,9 @@ Chapter 3. Administering Bugzilla * Password: You can change the user's password here. Users can automatically request a new password, so you shouldn't need to do this often. If you want to disable an account, see Disable Text below. + * Bugmail Disabled: Mark this checkbox to disable bugmail and whinemail + completely for this account. This checkbox replaces the data/nomail file + which existed in older versions of Bugzilla. * Disable Text: If you type anything in this box, including just a space, the user is prevented from logging in, or making any changes to bugs via the web interface. The HTML you type in this box is presented to the @@ -1812,8 +1895,8 @@ Chapter 3. Administering Bugzilla Users with disabled accounts will continue to receive mail from Bugzilla; furthermore, they will not be able to log in themselves to change their own preferences and stop it. If you want an account - (disabled or active) to stop receiving mail, add the account name (one - account per line) to the file data/nomail. + (disabled or active) to stop receiving mail, simply check the "Bugmail + Disabled" checkbox above. Note Even users whose accounts have been disabled can still submit bugs via the e-mail gateway, if one exists. The e-mail gateway should not be enabled @@ -2280,25 +2363,85 @@ Chapter 3. Administering Bugzilla "Creating a Flag" section. _________________________________________________________________ -3.9. Legal Values +3.9. Custom Fields + + One of the most requested features was the ability to add your own custom + fields to bugs, based on your needs. With the release of Bugzilla 3.0, this + dream finally comes true. Administrators can manage these fields using the + "Custom Fields" link in the footer of pages. The first thing they will see + is the list of existing custom fields (which is empty by default). + _________________________________________________________________ + +3.9.1. Adding Custom Fields + + The "Add a new custom field" link permits you to add a new field which can + be either a free text box or a drop down menu. More field types will be + available in future releases. + + The following attributes must be set for each new custom field: + + * Name: the name of the field, used internally. This name MUST begin with + "cf_". If you omit this string, it will be automatically added to the + name you entered. This way, all custom fields added to Bugzilla begin + with "cf_", avoiding any conflict with default fields. + * Description: the string which is used as a label for this custom field. + That is the string that users will see, and so should be short and + explicit. + * Type: as mentioned above, only two types are implemented so far. Free + text boxes let you type any string, while drop down menus only let you + choose one value in the list provided. The list of legal values for this + field can be created and edited as soon as this custom field is added to + the DB. See Section 3.10.1 for information about editing legal values. + * Sortkey: this integer determines in which order custom fields are + displayed in the UI, especially when viewing a bug. Fields with lower + values are displayed first. + * Can be set on bug creation: this boolean determines whether this field + can be set on bug creation or not. If not, then you have to create the + bug first before being able to set this field. Else you can set its + value at the same time you file a bug, see Section 5.6 about filing + bugs. + * Displayed in bugmail for new bugs: this boolean determines whether the + value set on this field should appear in bugmail when the bug is filed. + This attribute has no effect if the field cannot be set on bug creation. + * Is obsolete: this boolean determines whether or not this field should be + displayed at all. Obsolete custom fields are hidden. + _________________________________________________________________ + +3.9.2. Editing Custom Fields + + As soon as a custom field is created, its name and type cannot be changed. + If this field is a drop down menu, its legal values can be set as described + in Section 3.10.1. All other attributes can be edited as described above. + _________________________________________________________________ + +3.9.3. Deleting Custom Fields + + At this point, it is not possible to delete custom fields from your web + browser. If you don't want to make one available anymore, mark it as + obsolete. This way, you will preserve your DB referential integrity. + _________________________________________________________________ + +3.10. Legal Values Since Bugzilla 2.20 RC1, legal values for Operating Systems, platforms, bug priorities and severities can be edited from the User Interface directly. This means that it is no longer required to manually edit localconfig. + Starting with Bugzilla 2.23.3, you can also customize the list of valid + resolutions from the same interface. _________________________________________________________________ -3.9.1. Viewing/Editing legal values +3.10.1. Viewing/Editing legal values - Editing legal values requires "editcomponents" privileges. A link named - "Field Values" is visible in your footer and clicking on it displays the - list of fields whose values can be edited. + Editing legal values requires "admin" privileges. A link named "Field + Values" is visible in your footer and clicking on it displays the list of + fields whose values can be edited. You can add as many legal values as you want, and each value must be unique (on a per field basis). The sortkey is important to display these values in the desired order. _________________________________________________________________ -3.9.2. Deleting legal values +3.10.2. Deleting legal values You can also delete legal values, but only if the two following conditions are respected: @@ -2311,7 +2454,7 @@ Chapter 3. Administering Bugzilla to set another value as default for the field. _________________________________________________________________ -3.10. Voting +3.11. Voting Voting allows users to be given a pot of votes which they can allocate to bugs, to indicate that they'd like them fixed. This allows developers to @@ -2334,7 +2477,7 @@ Chapter 3. Administering Bugzilla 5. Once you have adjusted the values to your preference, click "Update". _________________________________________________________________ -3.11. Quips +3.12. Quips Quips are small text messages that can be configured to appear next to search results. A Bugzilla installation can have its own specific quips. @@ -2365,7 +2508,7 @@ Chapter 3. Administering Bugzilla to permanently delete a quip. _________________________________________________________________ -3.12. Groups and Group Security +3.13. Groups and Group Security Groups allow the administrator to isolate bugs or products that should only be seen by certain people. The association between products and groups is @@ -2389,7 +2532,7 @@ Chapter 3. Administering Bugzilla box next to either 'Reporter' or 'CC List' (or both). _________________________________________________________________ -3.12.1. Creating Groups +3.13.1. Creating Groups To create Groups: @@ -2423,7 +2566,7 @@ Chapter 3. Administering Bugzilla groups should be permitted to add and delete users from this group. _________________________________________________________________ -3.12.2. Assigning Users to Groups +3.13.2. Assigning Users to Groups Users can become a member of a group in several ways. @@ -2434,7 +2577,7 @@ Chapter 3. Administering Bugzilla specifies to automatically grant membership to the group. _________________________________________________________________ -3.12.3. Assigning Group Controls to Products +3.13.3. Assigning Group Controls to Products On the product edit page, there is a page to edit the "Group Controls" for a product. This allows you to configure how a group relates to the product. @@ -2468,9 +2611,9 @@ Chapter 3. Administering Bugzilla foo: ENTRY, MANDATORY/MANDATORY, CANEDIT _________________________________________________________________ -3.12.4. Common Applications of Group Controls +3.13.4. Common Applications of Group Controls -3.12.4.1. General User Access With Security Group +3.13.4.1. General User Access With Security Group To permit any user to file bugs in each product (A, B, C...) and to permit any user to submit those bugs into a security group.... @@ -2483,7 +2626,7 @@ Product C... security: SHOWN/SHOWN _________________________________________________________________ -3.12.4.2. General User Access With A Security Product +3.13.4.2. General User Access With A Security Product To permit any user to file bugs in a Security product while keeping those bugs from becoming visible to anyone outside the securityworkers group @@ -2493,7 +2636,7 @@ Product Security... securityworkers: DEFAULT/MANDATORY _________________________________________________________________ -3.12.4.3. Product Isolation With Common Group +3.13.4.3. Product Isolation With Common Group To permit users of product A to access the bugs for product A, users of product B to access product B, and support staff to access both, 3 groups @@ -2523,7 +2666,7 @@ Product Common... Support: ENTRY, DEFAULT/MANDATORY, CANEDIT _________________________________________________________________ -3.13. Upgrading to New Releases +3.14. Upgrading to New Releases Upgrading Bugzilla is something we all want to do from time to time, be it to get new features or pick up the latest security fix. How easy it is to @@ -2533,62 +2676,70 @@ Support: ENTRY, DEFAULT/MANDATORY, CANEDIT * How many local changes (if any) have been made _________________________________________________________________ -3.13.1. Version Definitions +3.14.1. Version Definitions - Bugzilla displays the version you are using at the top of most pages you - load. It will look something like '2.16.7' or '2.18rc3' or '2.19.1+'. The - first number in this series is the Major Version. This does not change very - often (that is to say, almost never); Bugzilla was 1.x.x when it was first - created, and went to 2.x.x when it was re-written in perl in Sept 1998. - If/When the major version is changed to 3.x.x, it will signify a significant - structural change and will be accompanied by much fanfare and many - instructions on how to upgrade, including a revision to this page. :) + Bugzilla displays the version you are using at the top of the home page + index.cgi. It looks something like '2.20.3', '2.22.1' or '3.0rc1'. The first + number in this series is the Major Version. This does not change very often; + Bugzilla was 1.x.x when it was first created, and went to 2.x.x when it was + re-written in perl in Sept 1998. The major version 3.x.x, released in early + 2007, is pretty far from what the 2.x.x series looked like, both about its + UI and its code. The second number in the version is called the 'minor number', and a release that changes the minor number is called a 'point release'. An even number in - this position (2.14, 2.16, 2.18, 2.20, etc.) represents a stable version, - while an odd number (2.17, 2.19, etc.) represents a development version. In - the past, stable point releases were feature-based, coming when certain - enhancements had been completed, or the Bugzilla development team felt that - enough progress had been made overall. As of version 2.18, however, Bugzilla - has moved to a time-based release schedule; current plans are to create a - stable point release every 6 months or so after 2.18 is deployed. + this position (2.18, 2.20, 2.22, 3.0, 3.2, etc.) represents a stable + version, while an odd number (2.19, 2.21, 2.23, etc.) represents a + development version. In the past, stable point releases were feature-based, + coming when certain enhancements had been completed, or the Bugzilla + development team felt that enough progress had been made overall. As of + version 2.18, however, Bugzilla has moved to a time-based release schedule; + current plans are to create a stable point release every 6 months or so + after 2.18 is deployed. The third number in the Bugzilla version represents a bugfix version. Bugfix - Revisions are normally released only to address security vulnerabilities; in - the future, it is likely that the Bugzilla development team will back-port - bugfixes in a new point release to the old point release for a limited - period. Once enough of these bugfixes have accumulated (or a new security - vulnerability is identified and closed), a bugfix release will be made. As - an example, 2.16.6 was a bugfix release, and improved on 2.16.5. + Revisions are released only to address security vulnerabilities and, for a + limited period, bug fixes. Once enough of these bugfixes have accumulated + (or a new security vulnerability is identified and closed), a bugfix release + is made. As an example, 2.20.3 was a bugfix release, and improved on 2.20.2. Note When reading version numbers, everything separated by a point ('.') - should be read as a single number. It is not the same as decimal. 2.14 is - newer than 2.8 because minor version 14 is greater than minor version 8. - 2.24.11 would be newer than 2.24.9 (because bugfix 11 is greater than bugfix - 9. This is confusing to some people who aren't used to dealing with - software. + should be read as a single number. It is not the same as decimal. 2.22 is + newer than 2.8 because minor version 22 is greater than minor version 8. The + now unsupported release 2.16.11 was newer than 2.16.9 (because bugfix 11 is + greater than bugfix 9. This is confusing to some people who aren't used to + dealing with software. + _________________________________________________________________ + +3.14.2. Upgrading - Notifications + + Bugzilla 3.0 introduces the ability to automatically notify administrators + when new releases are available, based on the upgrade_notification + parameter, see Section 3.1. Administrators will see these notifications when + they access the index.cgi page, i.e. generally when logging in. Bugzilla + will check once a week for new releases, unless the parameter is set to + "disabled". _________________________________________________________________ -3.13.2. Upgrading - Methods and Procedure +3.14.3. Upgrading - Methods and Procedure There are three different ways to upgrade your installation. - 1. Using CVS (Section 3.13.2.1) - 2. Downloading a new tarball (Section 3.13.2.2) - 3. Applying the relevant patches (Section 3.13.2.3) + 1. Using CVS (Section 3.14.3.1) + 2. Downloading a new tarball (Section 3.14.3.2) + 3. Applying the relevant patches (Section 3.14.3.3) Each of these options has its own pros and cons; the one that's right for you depends on how long it has been since you last installed, the degree to which you have customized your installation, and/or your network configuration. (Some discussion of the various methods of updating compared with degree and methods of local customization can be found in Section - 6.1.2.) + 6.2.2.) The larger the jump you are trying to make, the more difficult it is going - to be to upgrade if you have made local customizations. Upgrading from 2.18 - to 2.18.1 should be fairly painless even if you are heavily customized, but - going from 2.14 to 2.18 is going to mean a fair bit of work re-writing your + to be to upgrade if you have made local customizations. Upgrading from 2.22 + to 2.22.1 should be fairly painless even if you are heavily customized, but + going from 2.18 to 3.0 is going to mean a fair bit of work re-writing your local changes to use the new files, logic, templates, etc. If you have done no local changes at all, however, then upgrading should be approximately the same amount of work regardless of how long it has been since your version @@ -2600,7 +2751,7 @@ Support: ENTRY, DEFAULT/MANDATORY, CANEDIT from these backups. The examples in the following sections are written as though the user were - updating to version 2.18.1, but the procedures are the same regardless of + updating to version 2.22.1, but the procedures are the same regardless of whether one is updating to a new point release or simply trying to obtain a new bugfix release. Also, in the examples the user's Bugzilla installation is found at /var/www/html/bugzilla. If that is not the same as the location @@ -2608,7 +2759,7 @@ Support: ENTRY, DEFAULT/MANDATORY, CANEDIT appropriate. _________________________________________________________________ -3.13.2.1. Upgrading using CVS +3.14.3.1. Upgrading using CVS Every release of Bugzilla, whether it is a point release or a bugfix, is tagged in CVS. Also, every tarball that has been distributed since version @@ -2627,10 +2778,9 @@ bash$ cd /var/www/html/bugzilla bash$ cvs login Logging in to :pserver:anonymous@cvs-mirror.mozilla.org:2401/cvsroot CVS password: ('anonymous', or just leave it blank) -bash$ cvs -q update -r BUGZILLA-2_18_1 -dP +bash$ cvs -q update -r BUGZILLA-2_22_1 -dP P checksetup.pl P collectstats.pl -P globals.pl P docs/rel_notes.txt P template/en/default/list/quips.html.tmpl (etc.) @@ -2641,7 +2791,7 @@ P template/en/default/list/quips.html.tmpl the portion using that file) will be usable. _________________________________________________________________ -3.13.2.2. Upgrading using the tarball +3.14.3.2. Upgrading using the tarball If you are unable (or unwilling) to use CVS, another option that's always available is to obtain the latest tarball from the Download Page and create @@ -2653,20 +2803,19 @@ P template/en/default/list/quips.html.tmpl directory (or its equivalent, if you use something else) and omit the first three lines of the example. bash$ cd /var/www/html -bash$ wget ftp://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.18.1.tar.g -z +bash$ wget http://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.22.1.tar. +gz (Output omitted) -bash$ tar xzvf bugzilla-2.18.1.tar.gz -bugzilla-2.18.1/ -bugzilla-2.18.1/.cvsignore -bugzilla-2.18.1/1x1.gif +bash$ tar xzvf bugzilla-2.22.1.tar.gz +bugzilla-2.22.1/ +bugzilla-2.22.1/.cvsignore (Output truncated) -bash$ cd bugzilla-2.18.1 +bash$ cd bugzilla-2.22.1 bash$ cp ../bugzilla/localconfig* . bash$ cp -r ../bugzilla/data . bash$ cd .. bash$ mv bugzilla bugzilla.old -bash$ mv bugzilla-2.18.1 bugzilla +bash$ mv bugzilla-2.22.1 bugzilla Warning The cp commands both end with periods which is a very important detail, it tells the shell that the destination directory is the current @@ -2682,10 +2831,10 @@ bash$ mv bugzilla-2.18.1 bugzilla method, your code will already be set up for it. _________________________________________________________________ -3.13.2.3. Upgrading using patches +3.14.3.3. Upgrading using patches If you are doing a bugfix upgrade -- that is, one where only the last number - of the revision changes, such as from 2.16.6 to 2.16.7 -- then you have the + of the revision changes, such as from 2.22 to 2.22.1 -- then you have the option of obtaining and applying a patch file from the Download Page. This file is made available by the Bugzilla Development Team, and is a collection of all the bug fixes and security patches that have been made since the last @@ -2697,22 +2846,21 @@ bash$ mv bugzilla-2.18.1 bugzilla As above, this example starts with obtaining the file via the command line. If you have already downloaded it, you can omit the first two commands. bash$ cd /var/www/html/bugzilla -bash$ wget ftp://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.18.0-to-2. -18.1.diff.gz +bash$ wget http://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.22-to-2.2 +2.1.diff.gz (Output omitted) -bash$ gunzip bugzilla-2.18.0-to-2.18.1.diff.gz -bash$ patch -p1 < bugzilla-2.18.0-to-2.18.1.diff +bash$ gunzip bugzilla-2.22-to-2.22.1.diff.gz +bash$ patch -p1 < bugzilla-2.22-to-2.22.1.diff patching file checksetup.pl patching file collectstats.pl -patching file globals.pl (etc.) Warning Be aware that upgrading from a patch file does not change the entries in your CVS directory. This could make it more difficult to upgrade - using CVS (Section 3.13.2.1) in the future. + using CVS (Section 3.14.3.1) in the future. _________________________________________________________________ -3.13.3. Completing Your Upgrade +3.14.4. Completing Your Upgrade Regardless of which upgrade method you choose, you will need to run ./checksetup.pl before your Bugzilla upgrade will be complete. @@ -2924,22 +3072,43 @@ Chapter 5. Using Bugzilla If you want to use Bugzilla, first you need to create an account. Consult with the administrator responsible for your installation of Bugzilla for the URL you should use to access it. If you're test-driving Bugzilla, use this - URL: http://landfill.bugzilla.org/bugzilla-2.22-branch/. - - 1. Click the "Open a new Bugzilla account" link, enter your email address - and, optionally, your name in the spaces provided, then click "Create - Account" . - 2. Within moments, you should receive an email to the address you provided, - which contains your login name (generally the same as the email - address), and a password. This password is randomly generated, but can - be changed to something more memorable. - 3. Click the "Log In" link in the footer at the bottom of the page in your - browser, enter your email address and password into the spaces provided, - and click "Login". + URL: http://landfill.bugzilla.org/bugzilla-tip/. + + 1. On the home page index.cgi, click the "Open a new Bugzilla account" + link, or the "New Account" link available in the footer of pages. Now + enter your email address, then click the "Send" button. + + Note If none of these links is available, this means that the administrator + of the installation has disabled self-registration. This means that only an + administrator can create accounts for other users. One reason could be that + this installation is private. + + Note Also, if only some users are allowed to create an account on the + installation, you may see these links but your registration may fail if your + email address doesn't match the ones accepted by the installation. This is + another way to restrict who can access and edit bugs in this installation. + 2. Within moments, and if your registration is accepted, you should receive + an email to the address you provided, which contains your login name + (generally the same as the email address), and two URLs with a token (a + random string generated by the installation) to confirm, respectively + cancel, your registration. This is a way to prevent users from abusing + the generation of user accounts, for instance by entering inexistent + email addresses, or email addresses which do not belong to them. + 3. By default, you have 3 days to confirm your registration. Past this + timeframe, the token is invalidated and the registration is + automatically canceled. You can also cancel this registration sooner by + using the appropriate URL in the email you got. + 4. If you confirm your registration, Bugzilla will ask you your real name + (optional, but recommended) and your password, which must be between 3 + and 16 characters long. + 5. Now all you need to do is to click the "Log In" link in the footer at + the bottom of the page in your browser, enter your email address and + password you just chose into the login form, and click the "Log in" + button. You are now logged in. Bugzilla uses cookies to remember you are logged in so, unless you have cookies disabled or your IP address changes, you should - not have to log in again. + not have to log in again during your session. _________________________________________________________________ 5.3. Anatomy of a Bug @@ -2990,7 +3159,7 @@ Chapter 5. Using Bugzilla 10. Version: The "Version" field is usually used for versions of a product which have been released, and is set to indicate which versions of a Component have the particular problem the bug report is about. - 11. Priority: The bug assignee uses this field to prioritize his or her + 11. Priority: The bug assignee uses this field to prioritise his or her bugs. It's a good idea not to change this on other people's bugs. 12. Severity: This indicates how severe the problem is - from blocker ("application unusable") to trivial ("minor cosmetic issue"). You can @@ -3018,8 +3187,7 @@ Chapter 5. Using Bugzilla 17. Attachments: You can attach files (e.g. testcases or patches) to bugs. If there are any attachments, they are listed in this section. Attachments are normally stored in the Bugzilla database, unless they - are marked as Big Files, which are stored directly on disk and (unlike - attachments kept in the database) may be deleted at some future time. + are marked as Big Files, which are stored directly on disk. 18. *Dependencies: If this bug cannot be fixed unless other bugs are fixed (depends on), or this bug stops other bugs being fixed (blocks), their numbers are recorded here. @@ -3044,7 +3212,7 @@ Chapter 5. Using Bugzilla The Bugzilla Search page is the interface where you can find any bug report, comment, or patch currently in the Bugzilla system. You can play with it - here: http://landfill.bugzilla.org/bugzilla-2.22-branch/query.cgi. + here: http://landfill.bugzilla.org/bugzilla-tip/query.cgi. The Search page has controls for selecting different possible values for all of the fields in a bug, as described above. For some fields, multiple values @@ -3053,7 +3221,14 @@ Chapter 5. Using Bugzilla the field can take any value. Once you've run a search, you can save it as a Saved Search, which appears - in the page footer. + in the page footer. On the Saved Searches tab of your User Preferences page + (the Prefs link in Bugzilla's footer), members of the group defined in the + querysharegroup parameter can share such Saved Searches with user groups so + that other users may use them. At the same place, you can see Saved Searches + other users are sharing, and have them show up in your personal Bugzilla + footer along with your own Saved Searches. If somebody is sharing a Search + with a group she or he is allowed to assign users to, it will show up in the + group's direct members' footers by default. _________________________________________________________________ 5.5.1. Boolean Charts @@ -3199,24 +3374,27 @@ Chapter 5. Using Bugzilla Description Framework RDF/XML (ctype=rdf). _________________________________________________________________ -5.5.4. Adding individual bugs from bug lists +5.5.4. Adding/removing tags to/from bugs - You can at any time add individual bugs to a special type of saved searches, - known as "lists of bugs". The distinction between both types is that saved - searches, as described in the previous section, are stored in the form of a - list of matching criteria, while a list of bugs is an enumerated list of bug - numbers. As it is a simple list of bug numbers, you can easily edit this - list by adding bugs to it. To enable this feature, you have to turn on the - "Add individual bugs to saved searches" user preference, see Section 5.10. + You can add and remove tags from individual bugs, which let you find and + manage them more easily. Creating a new tag automatically generates a saved + search - whose name is the name of the tag - which lists bugs with this tag. + This saved search will be displayed in the footer of pages by default, as + all other saved searches. The main difference between tags and normal saved + searches is that saved searches, as described in the previous section, are + stored in the form of a list of matching criteria, while the saved search + generated by tags is a list of bug numbers. Consequently, you can easily + edit this list by either adding or removing tags from bugs. To enable this + feature, you have to turn on the "Enable tags for bugs" user preference, see + Section 5.10. This feature is disabled by default. This feature is useful when you want to keep track of several bugs, but for different reasons. Instead of adding yourself to the CC list of all these - bugs and mixing all these reasons, you can now store these bugs in different - lists, e.g. "Bugs I want to see fixed before the next release", "Interesting - bugs", or "Bugs I have to think about". One big advantage of this way to - manage bug lists is that you can easily add bugs one by one, which is not - possible to do with saved searches without having to edit the search - criteria again. + bugs and mixing all these reasons, you can now store these bugs in separate + lists, e.g. "Keep in mind", "Interesting bugs", or "Triage". One big + advantage of this way to manage bugs is that you can easily add or remove + bugs one by one, which is not possible to do with saved searches without + having to edit the search criteria again. _________________________________________________________________ 5.6. Filing Bugs @@ -3261,7 +3439,14 @@ Chapter 5. Using Bugzilla Note Try to make sure that everything in the summary is also in the first comment. Summaries are often updated and this will ensure your original information is easily accessible. - 5. Now is a good time to read your bug report again. Remove all + 5. As you file the bug, you can also attach a document (testcase, patch, or + screenshot of the problem). + 6. Depending on the Bugzilla installation you are using and the product in + which you are filing the bug, you can also request developers to + consider your bug in different ways (such as requesting review for the + patch you just attached, requesting your bug to block the next release + of the product, and many other product specific requests). + 7. Now is a good time to read your bug report again. Remove all misspellings, otherwise your bug may not be found by developers running queries for some specific words, and so your bug would not get any attention. Also make sure you didn't forget any important information @@ -3305,12 +3490,15 @@ Chapter 5. Using Bugzilla parameter on the URL, e.g. &content_type=text/plain. If you have a really large attachment, something that does not need to be - recorded forever (as most attachments are), you can mark your attachment as - a "Big File", assuming the administrator of the installation has enabled - this feature. Big Files are stored directly on disk instead of in the - database, and can be deleted when it is no longer needed. The maximum size - of a "Big File" is normally larger than the maximum size of a regular - attachment. + recorded forever (as most attachments are), or something that is too big for + your database, you can mark your attachment as a "Big File", assuming the + administrator of the installation has enabled this feature. Big Files are + stored directly on disk instead of in the database. The maximum size of a + "Big File" is normally larger than the maximum size of a regular attachment. + Independently of the storage system used, an administrator can delete these + attachments at any time. Nevertheless, if these files are stored in the + database, the "allow_attachment_deletion" parameter (which is turned off by + default) must be enabled in order to delete them. Also, if the administrator turned on the "allow_attach_url" parameter, you can enter the URL pointing to the attachment instead of uploading the @@ -3482,7 +3670,7 @@ Chapter 5. Using Bugzilla 5.10. User Preferences - Once you have logged in, you can customize various aspects of Bugzilla via + Once you have logged in, you can customise various aspects of Bugzilla via the "Edit prefs" link in the page footer. The preferences are split into three tabs: _________________________________________________________________ @@ -3787,7 +3975,7 @@ Chapter 5. Using Bugzilla first place). The next step is to specify when the Event is to be run (the Schedule) and - what searches are to be performed (the Queries). + what searches are to be performed (the Searches). _________________________________________________________________ 5.13.2. Whining Schedule @@ -3827,18 +4015,18 @@ Chapter 5. Using Bugzilla new schedule for each additional user/group. _________________________________________________________________ -5.13.3. Whining Queries +5.13.3. Whining Searches - Each whining event is associated with zero or more queries. A query is a - saved search that is executed on the schedule specified (see above). You - start out with zero queries attached to the event (which means that the - event will not run, as there will never be any results to return). To add a - query, press the "Add a new query" button. + Each whining event is associated with zero or more searches. A search is any + saved search to be run as part of the specified schedule (see above). You + start out without any searches associated with the event (which means that + the event will not run, as there will never be any results to return). To + add a search, press the "Include search" button. - The first field to examine in your new query is the Sort field. Queries are - executed, and results returned, in the order specified by the Sort field. - Queries with lower Sort values will run before queries with higher Sort - values. + The first field to examine in your newly added search is the Sort field. + Searches are run, and results included, in the order specified by the Sort + field. Searches with smaller Sort values will run before searches with + bigger Sort values. The next field to examine is the Search field. This is where you choose the actual search that is to be run. Instead of defining search parameters here, @@ -3877,9 +4065,28 @@ Chapter 5. Using Bugzilla your modifications. _________________________________________________________________ -Chapter 6. Customizing Bugzilla +Chapter 6. Customising Bugzilla + +6.1. Custom Skins + + Bugzilla allows you to have multiple skins. These are custom CSS and + possibly also custom images for Bugzilla. To create a new custom skin, you + have two choices: -6.1. Template Customization + * Make a single CSS file, and put it in the skins/contrib directory. + * Make a directory that contains all the same CSS file names as + skins/standard/, and put your directory in skins/contrib/. + + After you put the file or the directory there, make sure to run + checksetup.pl so that it can reset the file permissions correctly. + + After you have installed the new skin, it will show up as an option in the + user's General Preferences. If you would like to force a particular skin on + all users, just select it in the Default Preferences and then uncheck + "Enabled" on the preference. + _________________________________________________________________ + +6.2. Template Customization Administrators can configure the look and feel of Bugzilla without having to edit Perl files or face the nightmare of massive merge conflicts when they @@ -3887,10 +4094,10 @@ Chapter 6. Customizing Bugzilla Templatization also makes localized versions of Bugzilla possible, for the first time. It's possible to have Bugzilla's UI language determined by the - user's browser. More information is available in Section 6.1.6. + user's browser. More information is available in Section 6.2.6. _________________________________________________________________ -6.1.1. Template Directory Structure +6.2.1. Template Directory Structure The template directory structure starts with top level directory named template, which contains a directory for each installed localization. The @@ -3906,7 +4113,7 @@ Chapter 6. Customizing Bugzilla templates. _________________________________________________________________ -6.1.2. Choosing a Customization Method +6.2.2. Choosing a Customization Method If you want to edit Bugzilla's templates, the first decision you must make is how you want to go about doing so. There are two choices, and which you @@ -3956,7 +4163,7 @@ Chapter 6. Customizing Bugzilla incomprehensible error message. _________________________________________________________________ -6.1.3. How To Edit Templates +6.2.3. How To Edit Templates Note If you are making template changes that you intend on submitting back for inclusion in standard Bugzilla, you should read the relevant sections of @@ -3987,7 +4194,7 @@ Chapter 6. Customizing Bugzilla internally, but your users don't need to know that. _________________________________________________________________ -6.1.4. Template Formats and Types +6.2.4. Template Formats and Types Some CGI's have the ability to use more than one template. For example, buglist.cgi can output itself as RDF, or as two formats of HTML (complex and @@ -4027,7 +4234,7 @@ Chapter 6. Customizing Bugzilla <cginame>.cgi?format=<formatname>&ctype=<type> . _________________________________________________________________ -6.1.5. Particular Templates +6.2.5. Particular Templates There are a few templates you may be particularly interested in customizing for your installation. @@ -4119,7 +4326,7 @@ BuildID: 20020303 would appear in the initial comment. _________________________________________________________________ -6.1.6. Configuring Bugzilla to Detect the User's Language +6.2.6. Configuring Bugzilla to Detect the User's Language Bugzilla honours the user's Accept: HTTP header. You can install templates in other languages, and Bugzilla will pick the most appropriate according to @@ -4134,57 +4341,68 @@ BuildID: 20020303 English to be the default language. _________________________________________________________________ -6.2. Template Hooks +6.3. The Bugzilla Extension Mechanism - Warning Template Hooks require Template Toolkit version 2.12 or above, or + Warning Custom extensions require Template Toolkit version 2.12 or above, or the application of a patch. See bug 239112 for details. - Template hooks are a way for extensions to Bugzilla to insert code into the - standard Bugzilla templates without modifying the template files themselves. - The hooks mechanism defines a consistent API for extending the standard - templates in a way that cleanly separates standard code from extension code. - Hooks reduce merge conflicts and make it easier to write extensions that - work across multiple versions of Bugzilla, making upgrading a Bugzilla - installation with installed extensions easier. - - A template hook is just a named place in a standard template file where - extension template files for that hook get processed. Each hook has a - corresponding directory in the Bugzilla directory tree. Hooking an extension - template to a hook is as simple as putting the extension file into the - hook's directory. When Bugzilla processes the standard template and reaches - the hook, it will process all extension templates in the hook's directory. - The hooks themselves can be added into any standard template upon request by - extension authors. - - To use hooks to extend a Bugzilla template, first make sure there is a hook - at the appropriate place within the template you want to extend. Hooks - appear in the standard Bugzilla templates as a single directive in the - format [% Hook.process("name") %], where name is the unique (within that - template) name of the hook. - - If you aren't sure which template you want to extend or just want to browse - the available hooks, either use your favorite multi-file search tool (e.g. - grep) to search the standard templates for occurrences of Hook.process or - browse the directory tree in BUGZILLA_ROOT/template/en/extension/hook/, - which contains a directory for each hook in the following location: - - BUGZILLA_ROOT/template/en/extension/hook/PATH_TO_STANDARD_TEMPLATE/STANDARD_ - TEMPLATE_NAME/HOOK_NAME/ - - If there is no hook at the appropriate place within the Bugzilla template - you want to extend, file a bug requesting one, specifying: - - the template for which you are requesting a hook; - where in the template you would like the hook to be placed (line - number/position for latest version of template in CVS or description of - location); + Extensions are a way for extensions to Bugzilla to insert code into the + standard Bugzilla templates and source files without modifying these files + themselves. The extension mechanism defines a consistent API for extending + the standard templates and source files in a way that cleanly separates + standard code from extension code. Hooks reduce merge conflicts and make it + easier to write extensions that work across multiple versions of Bugzilla, + making upgrading a Bugzilla installation with installed extensions easier. + Furthermore, they make it easy to install and remove extensions as each + extension is nothing more than a simple directory structure. + + There are two main types of hooks: code hooks and template hooks. Code hooks + allow extensions to invoke code at specific points in various source files, + while template hooks allow extensions to add elements to the Bugzilla user + interface. + + A hook is just a named place in a standard source or template file where + extension source code or template files for that hook get processed. Each + extension has a corresponding directory in the Bugzilla directory tree + (BUGZILLA_ROOT/extensions/extension_name). Hooking an extension source file + or template to a hook is as simple as putting the extension file into + extension's template or code directory. When Bugzilla processes the source + file or template and reaches the hook, it will process all extension files + in the hook's directory. The hooks themselves can be added into any source + file or standard template upon request by extension authors. + + To use hooks to extend Bugzilla, first make sure there is a hook at the + appropriate place within the source file or template you want to extend. The + exact appearance of a hook depends on if the hook is a code hook or a + template hook. + + Code hooks appear in Bugzilla source files as a single method call in the + format Bugzilla::Hook->process("name");. for instance, enter_bug.cgi may + invoke the hook "enter_bug-defaultvars". Thus, a source file at + BUGZILLA_ROOT/extensions/EXTENSION_NAME/code/enter_bug-entrydefaultvars.pl + will be automatically invoked when the code hook is reached. + + Template hooks appear in the standard Bugzilla templates as a single + directive in the format [% Hook.process("name") %], where name is the unique + name of the hook. + + If you aren't sure what you want to extend or just want to browse the + available hooks, either use your favorite multi-file search tool (e.g. grep) + to search the standard templates for occurrences of Hook.process or the + source files for occurrences of Bugzilla::Hook::process. + + If there is no hook at the appropriate place within the Bugzilla source file + or template you want to extend, file a bug requesting one, specifying: + + the source or template file for which you are requesting a hook; + where in the file you would like the hook to be placed (line number/position + for latest version of the file in CVS or description of location); the purpose of the hook; a link to information about your extension, if any. The Bugzilla reviewers will promptly review each hook request, name the - hook, add it to the template, check the new version of the template into - CVS, and create the corresponding directory in - BUGZILLA_ROOT/template/en/extension/hook/. + hook, add it to the template or source file, and check the new version of + the template into CVS. You may optionally attach a patch to the bug which implements the hook and check it in yourself after receiving approval from a Bugzilla reviewer. The @@ -4196,11 +4414,11 @@ BuildID: 20020303 meet their needs. After making sure the hook you need exists (or getting it added if not), add - your extension template to the directory within the Bugzilla directory tree + your extension to the directory within the Bugzilla extensions tree corresponding to the hook. - That's it! Now, when the standard template containing the hook is processed, - your extension template will be processed at the point where the hook + That's it! Now, when the source file or template containing the hook is + processed, your extension file will be processed at the point where the hook appears. For example, let's say you have an extension named Projman that adds project @@ -4220,53 +4438,61 @@ BuildID: 20020303 [% Hook.process("edit") %] ... - The corresponding directory for this hook is - BUGZILLA_ROOT/template/en/extension/hook/global/useful-links.html.tmpl/edit/ - . - - You put a template named projman-edit-projects.html.tmpl into that directory - with the following content: + The corresponding extension file for this hook is + BUGZILLA_ROOT/extensions/projman/template/en/hook/global/useful-links-edit.h + tml.tmpl. You then create that template file and add the following constant: ...[% ', <a href="edit-projects.cgi">projects</a>' IF user.groups.projman_admin s %] Voila! The link now appears after the other administration links in the navigation bar for users in the projman_admins group. + Now, let us say your extension adds a custom "project_manager" field to + enter_bug.cgi. You want to modify the CGI script to set the default project + manager to be productname@company.com. Looking at enter_bug.cgi, you see the + enter_bug-entrydefaultvars hook near the bottom of the file before the + default form values are set. The corresponding extension source file for + this hook is located at + BUGZILLA_ROOT/extensions/projman/code/enter_bug-entrydefaultvars.pl. You + then create that file and add the following: + $default{'project_manager'} = $product.'@company.com'; + + This code will be invoked whenever enter_bug.cgi is executed. Assuming that + the rest of the customization was completed (e.g. the custom field was added + to the enter_bug template and the required hooks were used in + process_bug.cgi), the new field will now have this default value. + Notes: - * You may want to prefix your extension template names with the name of - your extension, e.g. projman-foo.html.tmpl, so they do not conflict with - the names of templates installed by other extensions. * If your extension includes entirely new templates in addition to - extensions of standard templates, it should install those new templates - into an extension-specific subdirectory of the - BUGZILLA_ROOT/template/en/extension/ directory. The extension/ - directory, like the default/ and custom/ directories, is part of the + extensions of standard templates, it should store those new templates in + its BUGZILLA_ROOT/extensions/template/en/ directory. Extension template + directories, like the default/ and custom/ directories, are part of the template search path, so putting templates there enables them to be found by the template processor. The template processor looks for templates first in the custom/ directory (i.e. templates added by the specific installation), then in - the extension/ directory (i.e. templates added by extensions), and + the extensions/ directory (i.e. templates added by extensions), and finally in the default/ directory (i.e. the standard Bugzilla - templates). Thus extension templates can override standard templates, - but installation-specific templates override both. - Note that overriding standard templates with extension templates gives - you great power but also makes upgrading an installation harder. As with - custom templates, we recommend using this functionality sparingly and - only when absolutely necessary. - * Installation customizers can also take advantage of hooks when adding - code to a Bugzilla template. To do so, create directories in - BUGZILLA_ROOT/template/en/custom/hook/ equivalent to the directories in - BUGZILLA_ROOT/template/en/extension/hook/ for the hooks you want to use, - then place your customization templates into those directories. + templates). Thus, installation-specific templates override both default + and extension templates. + * If you are looking to customize Bugzilla, you can also take advantage of + template hooks. To do so, create a directory in + BUGZILLA_ROOT/template/en/custom/hook/ that corresponds to the hook you + wish to use, then place your customization templates into those + directories. For example, if you wanted to use the hook "end" in + global/useful-links.html.tmpl, you would create the directory + BUGZILLA_ROOT/template/en/custom/hook/ + global/useful-links.html.tmpl/end/ and add your customization template + to this directory. Obviously this method of customizing Bugzilla only lets you add code to - the standard templates; you cannot change the existing code. - Nevertheless, for those customizations that only add code, this method - can reduce conflicts when merging changes, making upgrading your + the standard source files and templates; you cannot change the existing + code. Nevertheless, for those customizations that only add code, this + method can reduce conflicts when merging changes, making upgrading your customized Bugzilla installation easier. _________________________________________________________________ -6.3. Customizing Who Can Change What +6.4. Customizing Who Can Change What Warning This feature should be considered experimental; the Bugzilla code you will be changing is not stable, and could change or move between @@ -4282,9 +4508,9 @@ s %] For maximum flexibility, customizing this means editing Bugzilla's Perl code. This gives the administrator complete control over exactly who is - allowed to do what. The relevant function is called CheckCanChangeField(), - and is found in process_bug.cgi in your Bugzilla directory. If you open that - file and search for "sub CheckCanChangeField", you'll find it. + allowed to do what. The relevant method is called check_can_change_field(), + and is found in Bug.pm in your Bugzilla/ directory. If you open that file + and search for "sub check_can_change_field", you'll find it. This function has been carefully commented to allow you to see exactly how it works, and give you an idea of how to make changes to it. Certain marked @@ -4343,34 +4569,9 @@ s %] code that is bounded by DO_NOT_CHANGE blocks. Doing so could compromise security, or cause your installation to stop working entirely. - For a list of possible field names, look in data/versioncache for the list - called @::log_columns. If you need help writing custom rules for your - organization, ask in the newsgroup. - _________________________________________________________________ - -6.3.1. Modification in UserInGroup() - - The UserInGroup() function in the Bugzilla/User.pm module only accepts one - argument since 2.17.5: the name of a group. This check is now always done - against the current user, and a second argument specifying the user ID to - check this group against is no longer valid and an error is thrown if you - try to. - _________________________________________________________________ - -6.4. Modifying Your Running System - - Bugzilla optimizes database lookups by storing all relatively static - information in the versioncache file, located in the data/ subdirectory - under your installation directory. - - If you make a change to the structural data in your database (the versions - table for example), or to the "constants" encoded in defparams.pl, you will - need to remove the cached content from the data directory (by doing a rm - data/versioncache), or your changes won't show up. - - versioncache gets regenerated automatically whenever it's more than an hour - old, so Bugzilla will eventually notice your changes by itself, but - generally you want it to notice right away, so that you can test things. + For a list of possible field names, look at the bugs table in the database. + If you need help writing custom rules for your organization, ask in the + newsgroup. _________________________________________________________________ 6.5. Integrating Bugzilla with Third-Party Tools @@ -4444,27 +4645,29 @@ Appendix A. The Bugzilla FAQ 1. General Questions - A.1.1. What license is Bugzilla distributed under? - A.1.2. How do I get commercial support for Bugzilla? - A.1.3. What major companies or projects are currently using Bugzilla + A.1.1. Can I try out Bugzilla somewhere? + A.1.2. What license is Bugzilla distributed under? + A.1.3. How do I get commercial support for Bugzilla? + A.1.4. What major companies or projects are currently using Bugzilla for bug-tracking? - A.1.4. Who maintains Bugzilla? - A.1.5. How does Bugzilla stack up against other bug-tracking databases? + A.1.5. Who maintains Bugzilla? + A.1.6. How does Bugzilla stack up against other bug-tracking databases? - A.1.6. Why doesn't Bugzilla offer this or that feature or compatibility + A.1.7. Why doesn't Bugzilla offer this or that feature or compatibility with this other tracking software? - A.1.7. Why MySQL? I'm interested in seeing Bugzilla run on + A.1.8. Why MySQL? I'm interested in seeing Bugzilla run on PostgreSQL/Sybase/Oracle/Msql/MSSQL. - A.1.8. What is /usr/bonsaitools/bin/perl? - A.1.9. My perl is located at /usr/local/bin/perl and not /usr/bin/perl. - Is there an easy to change that in all the files that have this - hard-coded? + A.1.9. What is /usr/bonsaitools/bin/perl? + A.1.10. My perl is located at /usr/local/bin/perl and not + /usr/bin/perl. Is there an easy to change that in all the + files that have this hard-coded? - A.1.10. Is there an easy way to change the Bugzilla cookie name? - A.1.11. Does bugzilla run under mod_perl? + A.1.11. Is there an easy way to change the Bugzilla cookie name? + A.1.12. Does bugzilla run under mod_perl? + A.1.13. How can Bugzilla be made to work under SELinux? 2. Managerial Questions @@ -4608,12 +4811,18 @@ Appendix A. The Bugzilla FAQ 1. General Questions - A.1.1. What license is Bugzilla distributed under? + A.1.1. Can I try out Bugzilla somewhere? + + If you want to take a test ride, there are test installations at + http://landfill.bugzilla.org/, ready to play with directly from your + browser. + + A.1.2. What license is Bugzilla distributed under? Bugzilla is covered by the Mozilla Public License. See details at http://www.mozilla.org/MPL/. - A.1.2. How do I get commercial support for Bugzilla? + A.1.3. How do I get commercial support for Bugzilla? http://www.bugzilla.org/support/consulting.html is a list of companies and individuals who have asked us to list them as consultants for Bugzilla. @@ -4622,7 +4831,7 @@ Appendix A. The Bugzilla FAQ who are willing to make themselves available for generous compensation. Try sending a message to the mailing list asking for a volunteer. - A.1.3. What major companies or projects are currently using Bugzilla for + A.1.4. What major companies or projects are currently using Bugzilla for bug-tracking? There are dozens of major companies with public Bugzilla sites to track bugs @@ -4631,11 +4840,11 @@ Appendix A. The Bugzilla FAQ Bugzilla and would like to be added to the list, whether it's a public install or not, simply e-mail Gerv <gerv@mozilla.org>. - A.1.4. Who maintains Bugzilla? + A.1.5. Who maintains Bugzilla? A core team, led by Dave Miller (justdave@bugzilla.org). - A.1.5. How does Bugzilla stack up against other bug-tracking databases? + A.1.6. How does Bugzilla stack up against other bug-tracking databases? We can't find any head-to-head comparisons of Bugzilla against other defect-tracking software. If you know of one, please get in touch. In the @@ -4651,7 +4860,7 @@ Appendix A. The Bugzilla FAQ send it to <documentation@bugzilla.org> and we'd be happy to include the comparison in our documentation. - A.1.6. Why doesn't Bugzilla offer this or that feature or compatibility with + A.1.7. Why doesn't Bugzilla offer this or that feature or compatibility with this other tracking software? It may be that the support has not been built yet, or that you have not yet @@ -4677,14 +4886,26 @@ Appendix A. The Bugzilla FAQ never contributed anything to Bugzilla before, please be sure to read the Developers' Guide and Contributors' Guide before going ahead. - A.1.7. Why MySQL? I'm interested in seeing Bugzilla run on + A.1.8. Why MySQL? I'm interested in seeing Bugzilla run on PostgreSQL/Sybase/Oracle/Msql/MSSQL. MySQL was originally chosen because it is free, easy to install, and was available for the hardware Netscape intended to run it on. - There is currently work in progress to make Bugzilla work on PostgreSQL; - track the progress of this initiative in bug 98304. + Bugzilla 2.20 contains experimental support for PostgreSQL. Bugzilla 2.22 + contains complete, stable support for PostgreSQL. As of this release, using + PostgreSQL with Bugzilla should be as stable as using MySQL. If you + experience any problems with PostgreSQL compatibility, they will be taken as + seriously as if you were running MySQL. + + Red Hat once ran a version of Bugzilla that worked on Oracle, but that was + long, long ago; that version (Bugzilla 2.8) is now obsolete, insecure, and + totally unsupported. + + In August of 2005, Wim Coekaerts (Director of Linux Engineering at Oracle + Corporation) wrote to Dave Miller confirming that Oracle intends to + implement and support Bugzilla. Since then, no further information has been + forthcoming. Track progress at Bug 189947. Sybase support is no longer being worked on. Even if it eventually happens, it's VERY unlikely to work without the end-user-company having to stick a @@ -4694,18 +4915,10 @@ Appendix A. The Bugzilla FAQ application logic into stored procedures to get any kind of decent performance out of it. Bug 173130 is the relevant bug. - Red Hat once ran a version of Bugzilla that worked on Oracle, but that was - long, long ago; that version (Bugzilla 2.8) is now obsolete, insecure, and - totally unsupported. Red Hat's current Bugzilla (based on Bugzilla 2.17.1) - uses PostgreSQL, and work is being done to merge those changes into the main - distribution. (See above.) At this time we know of no recent ports of - Bugzilla to Oracle. (In our honest opinion, Bugzilla doesn't need what - Oracle offers.) - Bug 237862 is a good bug to read through if you'd like to see what progress is being made on general database compatibility. - A.1.8. What is /usr/bonsaitools/bin/perl? + A.1.9. What is /usr/bonsaitools/bin/perl? Bugzilla used to have the path to perl on the shebang line set to /usr/bonsaitools/bin/perl because when Terry first started writing the code @@ -4716,7 +4929,7 @@ Appendix A. The Bugzilla FAQ remove it now (provided that you don't have anything else, such as Bonsai, using it and you don't intend to reinstall an older version of Bugzilla). - A.1.9. My perl is located at /usr/local/bin/perl and not /usr/bin/perl. Is + A.1.10. My perl is located at /usr/local/bin/perl and not /usr/bin/perl. Is there an easy to change that in all the files that have this hard-coded? The easiest way to get around this is to create a link from one to the @@ -4750,17 +4963,24 @@ perl runtests.pl 2 --verbose it with a default value of "<full path to perl> -T", e.g. "C:\Perl\bin\perl.exe -T". - A.1.10. Is there an easy way to change the Bugzilla cookie name? + A.1.11. Is there an easy way to change the Bugzilla cookie name? At present, no. - A.1.11. Does bugzilla run under mod_perl? + A.1.12. Does bugzilla run under mod_perl? At present, no. Work is slowly taking place to remove global variables, use $cgi, and use DBI. These are all necessary for mod_perl (as well as being good for other reasons). Visit bug 87406 to view the discussion and progress. + A.1.13. How can Bugzilla be made to work under SELinux? + + Unfortunately there are no step-by-step instructions, but the following URL + contains hints on how to do it: + http://fedora.redhat.com/docs/selinux-apache-fc3/sn-debugging-and-customizin + g.html + 2. Managerial Questions A.2.1. Is Bugzilla web-based, or do you have to have specific software or a @@ -4782,7 +5002,7 @@ perl runtests.pl 2 --verbose A.2.3. Does Bugzilla provide any reporting features, metrics, graphs, etc? You know, the type of stuff that management likes to see. :) - Yes. Look at http://bugzilla.mozilla.org/report.cgi for samples of what + Yes. Look at https://bugzilla.mozilla.org/report.cgi for samples of what Bugzilla can do in reporting and graphing. Fuller documentation is provided in Section 5.11. @@ -4897,7 +5117,7 @@ perl runtests.pl 2 --verbose Yes! As of Bugzilla 2.18, it is a simple matter to change the word 'bug' into whatever word/phrase is used by your organization. See the - documentation on Customization for more details, specifically Section 6.1.5. + documentation on Customization for more details, specifically Section 6.2.5. 3. Administrative Questions @@ -4944,7 +5164,7 @@ perl runtests.pl 2 --verbose the database backups. You can't "downgrade" the system cleanly under most circumstances. - See also the instructions in Section 3.13.2.1. + See also the instructions in Section 3.14.3.1. A.3.4. How do I make it so that bugs can have an UNCONFIRMED status? @@ -5147,6 +5367,30 @@ password=mypassword should only be done when not connected to the external network as a troubleshooting step. + You may also be suffering from a client version mismatch: + + MySQL 4.1 and up uses an authentication protocol based on a password hashing + algorithm that is incompatible with that used by older clients. If you + upgrade the server to 4.1, attempts to connect to it with an older client + may fail with the following message: + +shell> mysql + Client does not support authentication protocol requested + by server; consider upgrading MySQL client + + To solve this problem, you should use one of the following approaches: + + * Upgrade all client programs to use a 4.1.1 or newer client library. + * When connecting to the server with a pre-4.1 client program, use an + account that still has a pre-4.1-style password. + * Reset the password to pre-4.1 style for each user that needs to use a + pre-4.1 client program. This can be done using the SET PASSWORD + statement and the OLD_PASSWORD() function: + + mysql> SET PASSWORD FOR + -> ' some_user '@' some_host ' = OLD_PASSWORD(' newpwd + '); + A.6.4. How do I synchronize bug information among multiple different Bugzilla databases? @@ -5217,8 +5461,8 @@ password=mypassword 4. Type 'ppm' 5. PPM> install DBI DBD-mysql GD - I reckon TimeDate and Data::Dumper come with the activeperl. You can check - the ActiveState site for packages for installation through PPM. + I reckon TimeDate comes with the activeperl. You can check the ActiveState + site for packages for installation through PPM. http://www.activestate.com/Packages/. 8. Bugzilla Usage @@ -5333,8 +5577,8 @@ password=mypassword Try this link to view current bugs or requests for enhancement for Bugzilla. - You can view bugs marked for 3.0 release here. This list includes bugs for - the 3.0 release that have already been fixed and checked into CVS. Please + You can view bugs marked for 3.2 release here. This list includes bugs for + the 3.2 release that have already been fixed and checked into CVS. Please consult the Bugzilla Project Page for details on how to check current sources out of CVS so you can have these bug fixes early! @@ -5357,7 +5601,7 @@ password=mypassword ID you submitted in step #1. Be sure and click the "Patch" checkbox to indicate the text you are sending is a patch! 3. Announce your patch and the associated URL - (http://bugzilla.mozilla.org/show_bug.cgi?id=XXXXXX) for discussion in + (https://bugzilla.mozilla.org/show_bug.cgi?id=XXXXXX) for discussion in the newsgroup (mozilla.support.bugzilla). You'll get a really good, fairly immediate reaction to the implications of your patch, which will also give us an idea how well-received the change would be. @@ -5467,43 +5711,7 @@ B.5. cannot chdir(/var/spool/mqueue) /var/spool/mqueue directory. _________________________________________________________________ -B.6. Your vendor has not defined Fcntl macro O_NOINHERIT - - This is caused by a bug in the version of File::Temp that is distributed - with perl 5.6.0. Many minor variations of this error have been reported: -Your vendor has not defined Fcntl macro O_NOINHERIT, used -at /usr/lib/perl5/site_perl/5.6.0/File/Temp.pm line 208. - -Your vendor has not defined Fcntl macro O_EXLOCK, used -at /usr/lib/perl5/site_perl/5.6.0/File/Temp.pm line 210. - -Your vendor has not defined Fcntl macro O_TEMPORARY, used -at /usr/lib/perl5/site_perl/5.6.0/File/Temp.pm line 233. - - Numerous people have reported that upgrading to version 5.6.1 or higher - solved the problem for them. A less involved fix is to apply the following - patch, which is also available as a patch file. ---- File/Temp.pm.orig Thu Feb 6 16:26:00 2003 -+++ File/Temp.pm Thu Feb 6 16:26:23 2003 -@@ -205,6 +205,7 @@ - # eg CGI::Carp - local $SIG{__DIE__} = sub {}; - local $SIG{__WARN__} = sub {}; -+ local *CORE::GLOBAL::die = sub {}; - $bit = &$func(); - 1; - }; -@@ -226,6 +227,7 @@ - # eg CGI::Carp - local $SIG{__DIE__} = sub {}; - local $SIG{__WARN__} = sub {}; -+ local *CORE::GLOBAL::die = sub {}; - $bit = &$func(); - 1; - }; - _________________________________________________________________ - -B.7. Everybody is constantly being forced to relogin +B.6. Everybody is constantly being forced to relogin The most-likely cause is that the "cookiepath" parameter is not set correctly in the Bugzilla configuration. You can change this (if you're a @@ -5557,7 +5765,7 @@ B.7. Everybody is constantly being forced to relogin browser (this is true starting with Bugzilla 2.18 and Bugzilla 2.16.5). _________________________________________________________________ -B.8. Some users are constantly being forced to relogin +B.7. Some users are constantly being forced to relogin First, make sure cookies are enabled in the user's browser. @@ -5579,7 +5787,7 @@ B.8. Some users are constantly being forced to relogin logged in. _________________________________________________________________ -B.9. index.cgi doesn't show up unless specified in the URL +B.8. index.cgi doesn't show up unless specified in the URL You probably need to set up your web server in such a way that it will serve the index.cgi page as an index page. @@ -5588,7 +5796,7 @@ B.9. index.cgi doesn't show up unless specified in the URL the DirectoryIndex line as mentioned in Section 2.2.4.1. _________________________________________________________________ -B.10. checksetup.pl reports "Client does not support authentication protocol +B.9. checksetup.pl reports "Client does not support authentication protocol requested by server..." This error is occurring because you are using the new password encryption @@ -5615,7 +5823,7 @@ C.1. Command-line Search Interface line. They live in the contrib/cmdline directory. There are three files - query.conf, buglist and bugs. - Warning These files pre-date the templatization work done as part of the + Warning These files pre-date the templatisation work done as part of the 2.16 release, and have not been updated. query.conf contains the mapping from options to field names and comparison @@ -5701,14 +5909,6 @@ D.2. Download Locations or higher. Some modules already exist in the core distribution of ActiveState Perl so no PPM link is given. (This is noted where it occurs.) - AppConfig: - - CPAN Download Page: http://search.cpan.org/src/ABW/AppConfig-1.56/li - b/AppConfig.pm - PPM Download Link: http://landfill.bugzilla.org/ppm/AppConfig.ppd - Documentation: http://search.cpan.org/~abw/AppConfig-1.56/lib/AppCon - fig.pm - CGI: CPAN Download Page: http://search.cpan.org/dist/CGI.pm/ @@ -5754,12 +5954,6 @@ D.2. Download Locations PPM Download Page: Part of core distribution. Documentation: http://perldoc.perl.org/File/Spec.html - File::Temp: - - CPAN Download Page: http://search.cpan.org/dist/File-Temp/ - PPM Download Page: Part of core distribution. - Documentation: http://www.perldoc.com/perl5.8.0/lib/File/Temp.html - Template-Toolkit: CPAN Download Page: http://search.cpan.org/dist/Template-Toolkit/ @@ -5767,12 +5961,6 @@ D.2. Download Locations .ppd Documentation: http://www.template-toolkit.org/docs.html - Text::Wrap: - - CPAN Download Page: http://search.cpan.org/dist/Text-Tabs+Wrap/ - PPM Download Link: Part of core distribution. - Documentation: http://www.perldoc.com/perl5.8.0/lib/Text/Wrap.html - GD: CPAN Download Page: http://search.cpan.org/dist/GD/ @@ -5787,13 +5975,6 @@ D.2. Download Locations Documentation: http://www.template-toolkit.org/docs/aqua/Modules/inde x.html - MIME::Base64: - - CPAN Download Page: http://search.cpan.org/dist/MIME-Base64/ - PPM Download Link: http://ppm.activestate.com/PPMPackages/zips/8xx-b - uilds-only/Windows/MIME-Base64-2.20.zip - Documentation: http://search.cpan.org/dist/MIME-Base64/Base64.pm - MIME::Parser (part of MIME-tools): CPAN Download Page: http://search.cpan.org/dist/MIME-tools/ @@ -6309,7 +6490,7 @@ M Message Transport Agent (MTA) A Message Transport Agent is used to control the flow of email on a - system. The Mail::Mailer Perl module, which Bugzilla uses to send + system. The Email::Send Perl module, which Bugzilla uses to send email, can be configured to use many different underlying implementations for actually sending the mail using the mail_delivery_method parameter. Implementations other than sendmail diff --git a/docs/xml/.cvsignore b/docs/xml/.cvsignore new file mode 100644 index 000000000..ef6b304bc --- /dev/null +++ b/docs/xml/.cvsignore @@ -0,0 +1 @@ +bugzilla.ent diff --git a/docs/xml/Bugzilla-Guide.xml b/docs/xml/Bugzilla-Guide.xml index e52c34893..baa5a9369 100644 --- a/docs/xml/Bugzilla-Guide.xml +++ b/docs/xml/Bugzilla-Guide.xml @@ -1,4 +1,8 @@ -<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ +<?xml version="1.0"?> +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ + <!ENTITY % myents SYSTEM "bugzilla.ent"> + %myents; <!-- Include macros --> <!ENTITY about SYSTEM "about.xml"> @@ -23,7 +27,6 @@ * bz-ver to current stable * bz-nexver to next stable * bz-date to the release date - * Remove the BZ-DEVEL comments - COMPILE DOCS AND CHECKIN - Also, tag and tarball before completing * bz-ver to devel version @@ -31,45 +34,18 @@ For a devel release, simple bump bz-ver and bz-date --> -<!ENTITY bz-ver "2.22.3"> -<!ENTITY bz-nextver "3.0"> -<!ENTITY bz-date "2007-08-23"> +<!ENTITY bz-ver "3.0"> +<!ENTITY bz-nextver "3.2"> +<!ENTITY bz-date "2007-05-09"> <!ENTITY current-year "2007"> -<!ENTITY landfillbase "http://landfill.bugzilla.org/bugzilla-2.22-branch/"> +<!ENTITY landfillbase "http://landfill.bugzilla.org/bugzilla-tip/"> <!ENTITY bz "http://www.bugzilla.org/"> -<!ENTITY bzg-bugs "<ulink url='http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=Documentation'>Bugzilla Documentation</ulink>"> +<!ENTITY bzg-bugs "<ulink url='https://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=Documentation'>Bugzilla Documentation</ulink>"> <!ENTITY mysql "http://www.mysql.com/"> -<!-- For minimum versions --> -<!ENTITY min-mysql-ver "4.0.14"> -<!ENTITY min-pg-ver "7.3.x"> -<!ENTITY min-perl-ver "5.6.1"> +<!ENTITY min-perl-ver "5.8.0"> <!ENTITY min-perl-ver-win "5.8.1"> -<!ENTITY min-template-ver "2.10"> -<!ENTITY min-file-temp-ver "any"> -<!ENTITY min-appconfig-ver "1.52"> -<!ENTITY min-text-wrap-ver "2001.0131"> -<!ENTITY min-file-spec-ver "0.84"> -<!ENTITY min-data-dumper-ver "any"> -<!ENTITY min-dbd-mysql-ver "2.9003"> -<!ENTITY min-dbd-pg-ver "1.31"> -<!ENTITY min-dbi-ver "1.38"> -<!ENTITY min-date-format-ver "2.21"> -<!ENTITY min-cgi-ver "2.93"> -<!ENTITY min-mail-mailer-ver "1.67"> -<!ENTITY min-mime-base64-ver "3.01"> -<!ENTITY min-mime-parser-ver "5.406"> -<!ENTITY min-storable-ver "any"> -<!-- Optional modules --> -<!ENTITY min-gd-ver "1.20"> -<!ENTITY min-gd-graph-ver "any"> -<!ENTITY min-gd-text-align-ver "any"> -<!ENTITY min-chart-base-ver "1.0"> -<!ENTITY min-xml-twig-ver "any"> -<!ENTITY min-patchreader-ver "0.9.4"> -<!ENTITY min-image-magick-ver "any"> - ]> @@ -100,8 +76,7 @@ <!-- Header --> <bookinfo> - <title>The Bugzilla Guide - &bz-ver; - Release</title> + <title>The Bugzilla Guide - &bz-ver; Release</title> <authorgroup> <corpauthor>The Bugzilla Team</corpauthor> @@ -120,7 +95,7 @@ <para> The most current version of this document can always be found on the - <ulink url="http://www.bugzilla.org/documentation.html">Bugzilla + <ulink url="http://www.bugzilla.org/docs/">Bugzilla Documentation Page</ulink>. </para> diff --git a/docs/xml/CVS/Entries b/docs/xml/CVS/Entries index eac584d71..465f929d2 100644 --- a/docs/xml/CVS/Entries +++ b/docs/xml/CVS/Entries @@ -1,21 +1,22 @@ -/Bugzilla-Guide.xml/1.57.2.7/Thu Aug 23 18:45:16 2007//TBUGZILLA-2_22_3 -/about.xml/1.19.8.6/Thu Aug 2 07:03:17 2007//TBUGZILLA-2_22_3 -/administration.xml/1.55.2.10/Sun Jul 29 16:45:37 2007//TBUGZILLA-2_22_3 -/conventions.xml/1.9/Thu Jan 15 23:54:39 2004//TBUGZILLA-2_22_3 -/customization.xml/1.21.2.8/Sun Jul 22 22:25:16 2007//TBUGZILLA-2_22_3 -/dbschema.mysql/1.2/Wed May 8 23:19:09 2002//TBUGZILLA-2_22_3 -/faq.xml/1.39.2.3/Tue Jun 6 15:25:33 2006//TBUGZILLA-2_22_3 -/filetemp.patch/1.1/Wed Apr 2 00:40:56 2003//TBUGZILLA-2_22_3 -/gfdl.xml/1.9/Sat Jan 24 18:31:00 2004//TBUGZILLA-2_22_3 -/glossary.xml/1.17.2.4/Sat Mar 10 12:05:13 2007//TBUGZILLA-2_22_3 -/index.xml/1.4/Wed Apr 23 02:04:25 2003//TBUGZILLA-2_22_3 -/installation.xml/1.107.2.17/Sat Mar 10 01:39:02 2007//TBUGZILLA-2_22_3 -/integration.xml/1.13.10.1/Sat Mar 10 02:17:03 2007//TBUGZILLA-2_22_3 -/introduction.xml/1.5.12.1/Sun Jul 22 22:25:16 2007//TBUGZILLA-2_22_3 -/modules.xml/1.4.2.3/Sat Nov 25 11:47:27 2006//TBUGZILLA-2_22_3 -/patches.xml/1.21.8.2/Sun Jul 22 22:25:16 2007//TBUGZILLA-2_22_3 -/requiredsoftware.xml/1.6/Mon May 12 19:31:48 2003//TBUGZILLA-2_22_3 -/security.xml/1.8.2.6/Mon Nov 20 19:50:22 2006//TBUGZILLA-2_22_3 -/troubleshooting.xml/1.6.2.3/Wed Jun 7 20:10:30 2006//TBUGZILLA-2_22_3 -/using.xml/1.37.2.22/Sun Jul 22 22:25:16 2007//TBUGZILLA-2_22_3 +/.cvsignore/1.1/Tue Sep 5 19:00:56 2006//TBUGZILLA-3_0 +/Bugzilla-Guide.xml/1.71.2.2/Wed May 9 22:47:17 2007//TBUGZILLA-3_0 +/about.xml/1.24.2.1/Wed May 9 22:47:17 2007//TBUGZILLA-3_0 +/administration.xml/1.70.2.1/Sat Mar 10 02:05:15 2007//TBUGZILLA-3_0 +/conventions.xml/1.11/Tue Feb 21 21:50:45 2006//TBUGZILLA-3_0 +/customization.xml/1.37.2.1/Sat Mar 10 01:54:00 2007//TBUGZILLA-3_0 +/dbschema.mysql/1.2/Wed May 8 23:19:09 2002//TBUGZILLA-3_0 +/faq.xml/1.46/Thu Nov 23 20:25:37 2006//TBUGZILLA-3_0 +/filetemp.patch/1.1/Wed Apr 2 00:40:56 2003//TBUGZILLA-3_0 +/gfdl.xml/1.11/Tue Feb 21 21:50:45 2006//TBUGZILLA-3_0 +/glossary.xml/1.23.2.1/Sat Mar 10 12:05:40 2007//TBUGZILLA-3_0 +/index.xml/1.6/Tue Feb 21 21:50:45 2006//TBUGZILLA-3_0 +/installation.xml/1.136.2.2/Sat Mar 10 01:21:11 2007//TBUGZILLA-3_0 +/integration.xml/1.13.12.1/Sat Mar 10 02:17:30 2007//TBUGZILLA-3_0 +/introduction.xml/1.5/Thu Jan 15 23:54:39 2004//TBUGZILLA-3_0 +/modules.xml/1.12/Tue Feb 13 00:19:00 2007//TBUGZILLA-3_0 +/patches.xml/1.24/Fri Mar 3 22:58:07 2006//TBUGZILLA-3_0 +/requiredsoftware.xml/1.7/Mon Jul 31 22:22:51 2006//TBUGZILLA-3_0 +/security.xml/1.16/Mon Nov 20 19:48:43 2006//TBUGZILLA-3_0 +/troubleshooting.xml/1.12/Mon Jul 31 22:22:51 2006//TBUGZILLA-3_0 +/using.xml/1.64.2.4/Mon Mar 26 08:00:21 2007//TBUGZILLA-3_0 D diff --git a/docs/xml/CVS/Tag b/docs/xml/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/docs/xml/CVS/Tag +++ b/docs/xml/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/docs/xml/about.xml b/docs/xml/about.xml index 4a0ae2dbe..fd67bb92b 100644 --- a/docs/xml/about.xml +++ b/docs/xml/about.xml @@ -1,6 +1,6 @@ <!-- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [ <!ENTITY conventions SYSTEM "conventions.xml"> ] > --> -<!-- $Id: about.xml,v 1.19.8.6 2007/08/02 07:03:17 wurblzap%gmail.com Exp $ --> +<!-- $Id: about.xml,v 1.24.2.1 2007/05/09 22:47:17 mkanat%bugzilla.org Exp $ --> <chapter id="about"> <title>About This Guide</title> @@ -85,7 +85,7 @@ </para> <para> - In addition, there are Bugzilla template localization projects in + In addition, there are Bugzilla template localisation projects in the following languages. They may have translated documentation available: <ulink url="http://sourceforge.net/projects/bugzilla-ar/">Arabic</ulink>, @@ -94,7 +94,7 @@ <ulink url="http://sourceforge.net/projects/bugzilla-br/">Brazilian Portuguese</ulink>, <ulink url="http://sourceforge.net/projects/bugzilla-cn/">Chinese</ulink>, <ulink url="http://sourceforge.net/projects/bugzilla-fr/">French</ulink>, - <ulink url="http://germzilla.ganderbay.net/">German</ulink>, + <ulink url="http://germzilla.wurblzap.net/">German</ulink>, <ulink url="http://sourceforge.net/projects/bugzilla-it/">Italian</ulink>, <ulink url="http://www.bugzilla.jp/about/jp.html">Japanese</ulink>, <ulink url="http://sourceforge.net/projects/bugzilla-kr/">Korean</ulink>, diff --git a/docs/xml/administration.xml b/docs/xml/administration.xml index f4e983bc6..fbaeb3c33 100644 --- a/docs/xml/administration.xml +++ b/docs/xml/administration.xml @@ -168,25 +168,6 @@ </listitem> </varlistentry> - <varlistentry> - <term> - passwordmail - </term> - <listitem> - <para> - Every time a user creates an account, the text of this parameter - (with substitutions) is sent to the new user along with their - password message. - </para> - - <para> - Add any text you wish to the "passwordmail" parameter box. For - instance, many people choose to use this box to give a quick - training blurb about how to use Bugzilla at your site. - </para> - </listitem> - </varlistentry> - <varlistentry> <term> movebugs @@ -215,6 +196,21 @@ </listitem> </varlistentry> + <varlistentry> + <term> + globalwatcher + </term> + <listitem> + <para> + This allows to define specific users that will + receive notification each time a new bug in entered, or when + an existing bug changes, according to the normal groupset + permissions. It may be useful for sending notifications to a + mailing-list, for instance. + </para> + </listitem> + </varlistentry> + <varlistentry> <term> usestatuswhiteboard @@ -464,6 +460,15 @@ </para> </listitem> + <listitem> + <para> + <emphasis>Bugmail Disabled</emphasis>: + Mark this checkbox to disable bugmail and whinemail completely + for this account. This checkbox replaces the data/nomail file + which existed in older versions of Bugzilla. + </para> + </listitem> + <listitem> <para> <emphasis>Disable Text</emphasis>: @@ -479,8 +484,8 @@ mail from Bugzilla; furthermore, they will not be able to log in themselves to change their own preferences and stop it. If you want an account (disabled or active) to - stop receiving mail, add the account name (one account - per line) to the file <filename>data/nomail</filename>. + stop receiving mail, simply check the + <quote>Bugmail Disabled</quote> checkbox above. </para> <note> <para> @@ -1260,6 +1265,125 @@ </section> <!-- flags --> + <section id="custom-fields"> + <title>Custom Fields</title> + + <para> + One of the most requested features was the ability to add your own custom + fields to bugs, based on your needs. With the release of Bugzilla 3.0, this + dream finally comes true. Administrators can manage these fields using the + <quote>Custom Fields</quote> link in the footer of pages. The first thing + they will see is the list of existing custom fields (which is empty by default). + </para> + + <section id="add-custom-fields"> + <title>Adding Custom Fields</title> + + <para> + The <quote>Add a new custom field</quote> link permits you to add a + new field which can be either a free text box or a drop down menu. + More field types will be available in future releases. + </para> + + <para> + The following attributes must be set for each new custom field: + <itemizedlist> + <listitem> + <para> + <emphasis>Name:</emphasis> + the name of the field, used internally. This name MUST begin + with <quote>cf_</quote>. If you omit this string, it will + be automatically added to the name you entered. This way, all + custom fields added to Bugzilla begin with <quote>cf_</quote>, + avoiding any conflict with default fields. + </para> + </listitem> + + <listitem> + <para> + <emphasis>Description:</emphasis> + the string which is used as a label for this custom field. + That is the string that users will see, and so should be + short and explicit. + </para> + </listitem> + + <listitem> + <para> + <emphasis>Type:</emphasis> + as mentioned above, only two types are implemented so far. + Free text boxes let you type any string, while drop down menus + only let you choose one value in the list provided. The list of + legal values for this field can be created and edited as soon as + this custom field is added to the DB. See + <xref linkend="edit-values-list" /> for information about editing + legal values. + </para> + </listitem> + + <listitem> + <para> + <emphasis>Sortkey:</emphasis> + this integer determines in which order custom fields are + displayed in the UI, especially when viewing a bug. Fields + with lower values are displayed first. + </para> + </listitem> + + <listitem> + <para> + <emphasis>Can be set on bug creation:</emphasis> + this boolean determines whether this field can be set on + bug creation or not. If not, then you have to create the + bug first before being able to set this field. Else you + can set its value at the same time you file a bug, + see <xref linkend="bugreports" /> about filing bugs. + </para> + </listitem> + + <listitem> + <para> + <emphasis>Displayed in bugmail for new bugs:</emphasis> + this boolean determines whether the value set on this field + should appear in bugmail when the bug is filed. This attribute + has no effect if the field cannot be set on bug creation. + </para> + </listitem> + + <listitem> + <para> + <emphasis>Is obsolete:</emphasis> + this boolean determines whether or not this field should + be displayed at all. Obsolete custom fields are hidden. + </para> + </listitem> + </itemizedlist> + </para> + </section> + + <section id="edit-custom-fields"> + <title>Editing Custom Fields</title> + + <para> + As soon as a custom field is created, its name and type cannot be + changed. If this field is a drop down menu, its legal values can + be set as described in <xref linkend="edit-values-list" />. All + other attributes can be edited as described above. + </para> + </section> + + <section id="delete-custom-fields"> + <title>Deleting Custom Fields</title> + + <para> + At this point, it is not possible to delete custom fields from + your web browser. If you don't want to make one available anymore, + mark it as obsolete. This way, you will preserve your DB + referential integrity. + </para> + </section> + </section> + <section id="edit-values"> <title>Legal Values</title> @@ -1267,13 +1391,14 @@ Since Bugzilla 2.20 RC1, legal values for Operating Systems, platforms, bug priorities and severities can be edited from the User Interface directly. This means that it is no longer required to manually edit - <filename>localconfig</filename>. + <filename>localconfig</filename>. Starting with Bugzilla 2.23.3, you + can also customize the list of valid resolutions from the same interface. </para> <section id="edit-values-list"> <title>Viewing/Editing legal values</title> <para> - Editing legal values requires <quote>editcomponents</quote> privileges. + Editing legal values requires <quote>admin</quote> privileges. A link named <quote>Field Values</quote> is visible in your footer and clicking on it displays the list of fields whose values can be edited. </para> @@ -1671,22 +1796,21 @@ Support: ENTRY, DEFAULT/MANDATORY, CANEDIT <title>Version Definitions</title> <para> - Bugzilla displays the version you are using at the top of most - pages you load. It will look something like '2.16.7' or '2.18rc3' - or '2.19.1+'. The first number in this series is the Major Version. - This does not change very often (that is to say, almost never); + Bugzilla displays the version you are using at the top of the home + page <filename>index.cgi</filename>. It looks something like + '2.20.3', '2.22.1' or '3.0rc1'. The first number in this series is + the Major Version. This does not change very often; Bugzilla was 1.x.x when it was first created, and went to 2.x.x - when it was re-written in perl in Sept 1998. If/When the major version - is changed to 3.x.x, it will signify a significant structural change - and will be accompanied by much fanfare and many instructions on - how to upgrade, including a revision to this page. :) + when it was re-written in perl in Sept 1998. The major version + 3.x.x, released in early 2007, is pretty far from what the 2.x.x + series looked like, both about its UI and its code. </para> <para> The second number in the version is called the 'minor number', and a release that changes the minor number is called a 'point release'. - An even number in this position (2.14, 2.16, 2.18, 2.20, etc.) - represents a stable version, while an odd number (2.17, 2.19, etc.) + An even number in this position (2.18, 2.20, 2.22, 3.0, 3.2, etc.) + represents a stable version, while an odd number (2.19, 2.21, 2.23, etc.) represents a development version. In the past, stable point releases were feature-based, coming when certain enhancements had been completed, or the Bugzilla development team felt that enough @@ -1698,27 +1822,40 @@ Support: ENTRY, DEFAULT/MANDATORY, CANEDIT <para> The third number in the Bugzilla version represents a bugfix version. - Bugfix Revisions are normally released only to address security - vulnerabilities; in the future, it is likely that the Bugzilla - development team will back-port bugfixes in a new point release to - the old point release for a limited period. Once enough of these + Bugfix Revisions are released only to address security vulnerabilities + and, for a limited period, bug fixes. Once enough of these bugfixes have accumulated (or a new security vulnerability is - identified and closed), a bugfix release will be made. As an - example, 2.16.6 was a bugfix release, and improved on 2.16.5. + identified and closed), a bugfix release is made. As an + example, 2.20.3 was a bugfix release, and improved on 2.20.2. </para> <note> <para> When reading version numbers, everything separated by a point ('.') should be read as a single number. It is <emphasis>not</emphasis> - the same as decimal. 2.14 is newer than 2.8 because minor version - 14 is greater than minor version 8. 2.24.11 would be newer than - 2.24.9 (because bugfix 11 is greater than bugfix 9. This is + the same as decimal. 2.22 is newer than 2.8 because minor version + 22 is greater than minor version 8. The now unsupported release 2.16.11 + was newer than 2.16.9 (because bugfix 11 is greater than bugfix 9. This is confusing to some people who aren't used to dealing with software. </para> </note> </section> + <section id="upgrading-notifications"> + <title>Upgrading - Notifications</title> + + <para> + Bugzilla 3.0 introduces the ability to automatically notify + administrators when new releases are available, based on the + <literal>upgrade_notification</literal> parameter, see + <xref linkend="parameters"/>. Administrators will see these + notifications when they access the <filename>index.cgi</filename> + page, i.e. generally when logging in. Bugzilla will check once a + week for new releases, unless the parameter is set to + <quote>disabled</quote>. + </para> + </section> + <section id="upgrading-methods"> <title>Upgrading - Methods and Procedure</title> <para> @@ -1755,8 +1892,8 @@ Support: ENTRY, DEFAULT/MANDATORY, CANEDIT <para> The larger the jump you are trying to make, the more difficult it is going to be to upgrade if you have made local customizations. - Upgrading from 2.18 to 2.18.1 should be fairly painless even if - you are heavily customized, but going from 2.14 to 2.18 is going + Upgrading from 2.22 to 2.22.1 should be fairly painless even if + you are heavily customized, but going from 2.18 to 3.0 is going to mean a fair bit of work re-writing your local changes to use the new files, logic, templates, etc. If you have done no local changes at all, however, then upgrading should be approximately @@ -1775,7 +1912,7 @@ Support: ENTRY, DEFAULT/MANDATORY, CANEDIT <para> The examples in the following sections are written as though the - user were updating to version 2.18.1, but the procedures are the + user were updating to version 2.22.1, but the procedures are the same regardless of whether one is updating to a new point release or simply trying to obtain a new bugfix release. Also, in the examples the user's Bugzilla installation is found at @@ -1814,10 +1951,9 @@ bash$ <command>cd /var/www/html/bugzilla</command> bash$ <command>cvs login</command> Logging in to :pserver:anonymous@cvs-mirror.mozilla.org:2401/cvsroot CVS password: <emphasis>('anonymous', or just leave it blank)</emphasis> -bash$ <command>cvs -q update -r BUGZILLA-2_18_1 -dP</command> +bash$ <command>cvs -q update -r BUGZILLA-2_22_1 -dP</command> P checksetup.pl P collectstats.pl -P globals.pl P docs/rel_notes.txt P template/en/default/list/quips.html.tmpl <emphasis>(etc.)</emphasis> @@ -1855,19 +1991,18 @@ P template/en/default/list/quips.html.tmpl <programlisting> bash$ <command>cd /var/www/html</command> -bash$ <command>wget ftp://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.18.1.tar.gz</command> +bash$ <command>wget http://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.22.1.tar.gz</command> <emphasis>(Output omitted)</emphasis> -bash$ <command>tar xzvf bugzilla-2.18.1.tar.gz</command> -bugzilla-2.18.1/ -bugzilla-2.18.1/.cvsignore -bugzilla-2.18.1/1x1.gif +bash$ <command>tar xzvf bugzilla-2.22.1.tar.gz</command> +bugzilla-2.22.1/ +bugzilla-2.22.1/.cvsignore <emphasis>(Output truncated)</emphasis> -bash$ <command>cd bugzilla-2.18.1</command> +bash$ <command>cd bugzilla-2.22.1</command> bash$ <command>cp ../bugzilla/localconfig* .</command> bash$ <command>cp -r ../bugzilla/data .</command> bash$ <command>cd ..</command> bash$ <command>mv bugzilla bugzilla.old</command> -bash$ <command>mv bugzilla-2.18.1 bugzilla</command> +bash$ <command>mv bugzilla-2.22.1 bugzilla</command> </programlisting> <warning> @@ -1897,7 +2032,7 @@ bash$ <command>mv bugzilla-2.18.1 bugzilla</command> <para> If you are doing a bugfix upgrade -- that is, one where only the - last number of the revision changes, such as from 2.16.6 to 2.16.7 + last number of the revision changes, such as from 2.22 to 2.22.1 -- then you have the option of obtaining and applying a patch file from the <ulink url="http://www.bugzilla.org/download/">Download Page</ulink>. @@ -1919,13 +2054,12 @@ bash$ <command>mv bugzilla-2.18.1 bugzilla</command> <programlisting> bash$ <command>cd /var/www/html/bugzilla</command> -bash$ <command>wget ftp://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.18.0-to-2.18.1.diff.gz</command> +bash$ <command>wget http://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-2.22-to-2.22.1.diff.gz</command> <emphasis>(Output omitted)</emphasis> -bash$ <command>gunzip bugzilla-2.18.0-to-2.18.1.diff.gz</command> -bash$ <command>patch -p1 < bugzilla-2.18.0-to-2.18.1.diff</command> +bash$ <command>gunzip bugzilla-2.22-to-2.22.1.diff.gz</command> +bash$ <command>patch -p1 < bugzilla-2.22-to-2.22.1.diff</command> patching file checksetup.pl patching file collectstats.pl -patching file globals.pl <emphasis>(etc.)</emphasis> </programlisting> diff --git a/docs/xml/bugzilla.ent b/docs/xml/bugzilla.ent new file mode 100644 index 000000000..c5f503ba5 --- /dev/null +++ b/docs/xml/bugzilla.ent @@ -0,0 +1,36 @@ +<?xml version="1.0"?> + +<!-- Module Versions --> +<!ENTITY min-cgi-ver "2.93"> +<!ENTITY min-date-format-ver "2.21"> +<!ENTITY min-dbi-ver "1.41"> +<!ENTITY min-file-spec-ver "0.84"> +<!ENTITY min-template-ver "2.12"> +<!ENTITY min-email-send-ver "2.00"> +<!ENTITY min-email-mime-modifier-ver "any"> +<!ENTITY min-gd-ver "1.20"> +<!ENTITY min-template-plugin-gd-image-ver "any"> +<!ENTITY min-chart-base-ver "1.0"> +<!ENTITY min-gd-graph-ver "any"> +<!ENTITY min-gd-text-ver "any"> +<!ENTITY min-xml-twig-ver "any"> +<!ENTITY min-mime-parser-ver "5.406"> +<!ENTITY min-lwp-useragent-ver "any"> +<!ENTITY min-patchreader-ver "0.9.4"> +<!ENTITY min-image-magick-ver "any"> +<!ENTITY min-net-ldap-ver "any"> +<!ENTITY min-soap-lite-ver "any"> +<!ENTITY min-html-parser-ver "3.40"> +<!ENTITY min-html-scrubber-ver "any"> +<!ENTITY min-email-mime-attachment-stripper-ver "any"> +<!ENTITY min-email-reply-ver "any"> +<!ENTITY min-mod_perl2-ver "1.999022"> +<!ENTITY min-cgi-ver "3.11"> +<!ENTITY min-apache-dbi-ver "0.96"> +<!ENTITY min-mp-cgi-ver "3.11"> + + <!-- Database Versions --> +<!ENTITY min-dbd-pg-ver "1.45"> +<!ENTITY min-pg-ver "8.00.0000"> +<!ENTITY min-dbd-mysql-ver "2.9003"> +<!ENTITY min-mysql-ver "4.1.2"> diff --git a/docs/xml/customization.xml b/docs/xml/customization.xml index 617790137..5b9e99dee 100644 --- a/docs/xml/customization.xml +++ b/docs/xml/customization.xml @@ -1,7 +1,43 @@ <!-- <!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook V4.1//EN"> --> <chapter id="customization"> - <title>Customizing Bugzilla</title> + <title>Customising Bugzilla</title> + <section id="cust-skins"> + <title>Custom Skins</title> + + <para> + Bugzilla allows you to have multiple skins. These are custom CSS and possibly + also custom images for Bugzilla. To create a new custom skin, you have two + choices: + <itemizedlist> + <listitem> + <para> + Make a single CSS file, and put it in the + <filename>skins/contrib</filename> directory. + </para> + </listitem> + <listitem> + <para> + Make a directory that contains all the same CSS file + names as <filename>skins/standard/</filename>, and put + your directory in <filename>skins/contrib/</filename>. + </para> + </listitem> + </itemizedlist> + </para> + + <para> + After you put the file or the directory there, make sure to run checksetup.pl + so that it can reset the file permissions correctly. + </para> + <para> + After you have installed the new skin, it will show up as an option in the + user's General Preferences. If you would like to force a particular skin on all + users, just select it in the Default Preferences and then uncheck "Enabled" on + the preference. + </para> + </section> + <section id="cust-templates"> <title>Template Customization</title> @@ -411,11 +447,11 @@ </section> <section id="cust-hooks"> - <title>Template Hooks</title> + <title>The Bugzilla Extension Mechanism</title> <warning> <para> - Template Hooks require Template Toolkit version 2.12 or + Custom extensions require Template Toolkit version 2.12 or above, or the application of a patch. See <ulink url="http://bugzilla.mozilla.org/show_bug.cgi?id=239112">bug 239112</ulink> for details. @@ -423,62 +459,82 @@ </warning> <para> - Template hooks are a way for extensions to Bugzilla to insert code - into the standard Bugzilla templates without modifying the template files - themselves. The hooks mechanism defines a consistent API for extending - the standard templates in a way that cleanly separates standard code - from extension code. Hooks reduce merge conflicts and make it easier - to write extensions that work across multiple versions of Bugzilla, - making upgrading a Bugzilla installation with installed extensions easier. + Extensions are a way for extensions to Bugzilla to insert code + into the standard Bugzilla templates and source files + without modifying these files themselves. The extension mechanism + defines a consistent API for extending the standard templates and source files + in a way that cleanly separates standard code from extension code. + Hooks reduce merge conflicts and make it easier to write extensions that work + across multiple versions of Bugzilla, making upgrading a Bugzilla installation + with installed extensions easier. Furthermore, they make it easy to install + and remove extensions as each extension is nothing more than a + simple directory structure. + </para> + + <para> + There are two main types of hooks: code hooks and template hooks. Code + hooks allow extensions to invoke code at specific points in various + source files, while template hooks allow extensions to add elements to + the Bugzilla user interface. </para> <para> - A template hook is just a named place in a standard template file - where extension template files for that hook get processed. Each hook - has a corresponding directory in the Bugzilla directory tree. Hooking an - extension template to a hook is as simple as putting the extension file - into the hook's directory. When Bugzilla processes the standard template - and reaches the hook, it will process all extension templates in the - hook's directory. The hooks themselves can be added into any standard - template upon request by extension authors. + A hook is just a named place in a standard source or template file + where extension source code or template files for that hook get processed. + Each extension has a corresponding directory in the Bugzilla directory + tree (<filename>BUGZILLA_ROOT/extensions/extension_name</filename>). Hooking + an extension source file or template to a hook is as simple as putting + the extension file into extension's template or code directory. + When Bugzilla processes the source file or template and reaches the hook, + it will process all extension files in the hook's directory. + The hooks themselves can be added into any source file or standard template + upon request by extension authors. </para> <para> - To use hooks to extend a Bugzilla template, first make sure there is - a hook at the appropriate place within the template you want to extend. - Hooks appear in the standard Bugzilla templates as a single directive - in the format - <literal role="code">[% Hook.process("<varname>name</varname>") %]</literal>, - where <varname>name</varname> is the unique (within that template) - name of the hook. + To use hooks to extend Bugzilla, first make sure there is + a hook at the appropriate place within the source file or template you + want to extend. The exact appearance of a hook depends on if the hook + is a code hook or a template hook. </para> - + <para> - If you aren't sure which template you want to extend or just want - to browse the available hooks, either use your favorite multi-file search - tool (e.g. <command>grep</command>) to search the standard templates - for occurrences of <methodname>Hook.process</methodname> or browse - the directory tree in - <filename>BUGZILLA_ROOT/template/en/extension/hook/</filename>, - which contains a directory for each hook in the following location: + Code hooks appear in Bugzilla source files as a single method call + in the format <literal role="code">Bugzilla::Hook->process("<varname>name</varname>");</literal>. + for instance, <filename>enter_bug.cgi</filename> may invoke the hook + "<varname>enter_bug-defaultvars</varname>". Thus, a source file at + <filename>BUGZILLA_ROOT/extensions/EXTENSION_NAME/code/enter_bug-entrydefaultvars.pl</filename> + will be automatically invoked when the code hook is reached. + </para> + + <para> + Template hooks appear in the standard Bugzilla templates as a + single directive in the format + <literal role="code">[% Hook.process("<varname>name</varname>") %]</literal>, + where <varname>name</varname> is the unique name of the hook. </para> <para> - <filename>BUGZILLA_ROOT/template/en/extension/hook/PATH_TO_STANDARD_TEMPLATE/STANDARD_TEMPLATE_NAME/HOOK_NAME/</filename> + If you aren't sure what you want to extend or just want to browse the + available hooks, either use your favorite multi-file search + tool (e.g. <command>grep</command>) to search the standard templates + for occurrences of <methodname>Hook.process</methodname> or the source + files for occurrences of <methodname>Bugzilla::Hook::process</methodname>. </para> <para> - If there is no hook at the appropriate place within the Bugzilla template - you want to extend, + If there is no hook at the appropriate place within the Bugzilla + source file or template you want to extend, <ulink url="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla&component=User%20Interface">file a bug requesting one</ulink>, specifying: </para> <simplelist> - <member>the template for which you are requesting a hook;</member> + <member>the source or template file for which you are + requesting a hook;</member> <member> - where in the template you would like the hook to be placed - (line number/position for latest version of template in CVS + where in the file you would like the hook to be placed + (line number/position for latest version of the file in CVS or description of location); </member> <member>the purpose of the hook;</member> @@ -487,9 +543,8 @@ <para> The Bugzilla reviewers will promptly review each hook request, - name the hook, add it to the template, check the new version - of the template into CVS, and create the corresponding directory in - <filename>BUGZILLA_ROOT/template/en/extension/hook/</filename>. + name the hook, add it to the template or source file, and check + the new version of the template into CVS. </para> <para> @@ -505,13 +560,13 @@ <para> After making sure the hook you need exists (or getting it added if not), - add your extension template to the directory within the Bugzilla - directory tree corresponding to the hook. + add your extension to the directory within the Bugzilla + extensions tree corresponding to the hook. </para> <para> - That's it! Now, when the standard template containing the hook - is processed, your extension template will be processed at the point + That's it! Now, when the source file or template containing the hook + is processed, your extension file will be processed at the point where the hook appears. </para> @@ -542,14 +597,9 @@ ...]]></programlisting> <para> - The corresponding directory for this hook is - <filename>BUGZILLA_ROOT/template/en/extension/hook/global/useful-links.html.tmpl/edit/</filename>. - </para> - - <para> - You put a template named - <filename>projman-edit-projects.html.tmpl</filename> - into that directory with the following content: + The corresponding extension file for this hook is + <filename>BUGZILLA_ROOT/extensions/projman/template/en/hook/global/useful-links-edit.html.tmpl</filename>. + You then create that template file and add the following constant: </para> <programlisting><![CDATA[...[% ', <a href="edit-projects.cgi">projects</a>' IF user.groups.projman_admins %]]]></programlisting> @@ -558,69 +608,76 @@ Voila! The link now appears after the other administration links in the navigation bar for users in the <literal>projman_admins</literal> group. </para> - + + <para> + Now, let us say your extension adds a custom "project_manager" field + to enter_bug.cgi. You want to modify the CGI script to set the default + project manager to be productname@company.com. Looking at + <filename>enter_bug.cgi</filename>, you see the enter_bug-entrydefaultvars + hook near the bottom of the file before the default form values are set. + The corresponding extension source file for this hook is located at + <filename>BUGZILLA_ROOT/extensions/projman/code/enter_bug-entrydefaultvars.pl</filename>. + You then create that file and add the following: + </para> + + <programlisting>$default{'project_manager'} = $product.'@company.com';</programlisting> + + <para> + This code will be invoked whenever enter_bug.cgi is executed. + Assuming that the rest of the customization was completed (e.g. the + custom field was added to the enter_bug template and the required hooks + were used in process_bug.cgi), the new field will now have this + default value. + </para> + <para> Notes: </para> <itemizedlist> - <listitem> - <para> - You may want to prefix your extension template names - with the name of your extension, e.g. - <filename>projman-foo.html.tmpl</filename>, - so they do not conflict with the names of templates installed by - other extensions. - </para> - </listitem> - <listitem> <para> If your extension includes entirely new templates in addition to - extensions of standard templates, it should install those new - templates into an extension-specific subdirectory of the - <filename>BUGZILLA_ROOT/template/en/extension/</filename> - directory. The <filename>extension/</filename> directory, like the + extensions of standard templates, it should store those new + templates in its + <filename>BUGZILLA_ROOT/extensions/template/en/</filename> + directory. Extension template directories, like the <filename>default/</filename> and <filename>custom/</filename> - directories, is part of the template search path, so putting templates + directories, are part of the template search path, so putting templates there enables them to be found by the template processor. </para> <para> The template processor looks for templates first in the <filename>custom/</filename> directory (i.e. templates added by the - specific installation), then in the <filename>extension/</filename> - directory (i.e. templates added by extensions), and finally in the + specific installation), then in the <filename>extensions/</filename> + directory (i.e. templates added by extensions), and finally in the <filename>default/</filename> directory (i.e. the standard Bugzilla - templates). Thus extension templates can override standard templates, - but installation-specific templates override both. - </para> - - <para> - Note that overriding standard templates with extension templates - gives you great power but also makes upgrading an installation harder. - As with custom templates, we recommend using this functionality - sparingly and only when absolutely necessary. + templates). Thus, installation-specific templates override both + default and extension templates. </para> </listitem> <listitem> <para> - Installation customizers can also take advantage of hooks when adding - code to a Bugzilla template. To do so, create directories in + If you are looking to customize Bugzilla, you can also take advantage + of template hooks. To do so, create a directory in <filename>BUGZILLA_ROOT/template/en/custom/hook/</filename> - equivalent to the directories in - <filename>BUGZILLA_ROOT/template/en/extension/hook/</filename> - for the hooks you want to use, then place your customization templates - into those directories. + that corresponds to the hook you wish to use, then place your + customization templates into those directories. For example, + if you wanted to use the hook "end" in + <filename>global/useful-links.html.tmpl</filename>, you would + create the directory <filename>BUGZILLA_ROOT/template/en/custom/hook/ + global/useful-links.html.tmpl/end/</filename> and add your customization + template to this directory. </para> <para> Obviously this method of customizing Bugzilla only lets you add code - to the standard templates; you cannot change the existing code. - Nevertheless, for those customizations that only add code, this method - can reduce conflicts when merging changes, making upgrading - your customized Bugzilla installation easier. + to the standard source files and templates; you cannot change the + existing code. Nevertheless, for those customizations that only add + code, this method can reduce conflicts when merging changes, + making upgrading your customized Bugzilla installation easier. </para> </listitem> </itemizedlist> @@ -652,11 +709,11 @@ <para> For maximum flexibility, customizing this means editing Bugzilla's Perl code. This gives the administrator complete control over exactly who is - allowed to do what. The relevant function is called - <filename>CheckCanChangeField()</filename>, - and is found in <filename>process_bug.cgi</filename> in your - Bugzilla directory. If you open that file and search for - <quote>sub CheckCanChangeField</quote>, you'll find it. + allowed to do what. The relevant method is called + <filename>check_can_change_field()</filename>, + and is found in <filename>Bug.pm</filename> in your + Bugzilla/ directory. If you open that file and search for + <quote>sub check_can_change_field</quote>, you'll find it. </para> <para> @@ -727,51 +784,11 @@ </warning> <para> - For a list of possible field names, look in - <filename>data/versioncache</filename> for the list called - <filename>@::log_columns</filename>. If you need help writing custom - rules for your organization, ask in the newsgroup. - </para> - - <section id="cust-group-check"> - <title>Modification in UserInGroup()</title> - - <para> - The <filename>UserInGroup()</filename> function in the - <filename>Bugzilla/User.pm</filename> module only accepts - one argument since 2.17.5: the name of a group. This check - is now always done against the current user, and a second - argument specifying the user ID to check this group against - is no longer valid and an error is thrown if you try to. - </para> - </section> - </section> - - <section id="dbmodify"> - <title>Modifying Your Running System</title> - - <para> - Bugzilla optimizes database lookups by storing all relatively - static information in the <filename>versioncache</filename> - file, located in the <filename class="directory">data/</filename> - subdirectory under your installation directory. - </para> - - <para> - If you make a change to the structural data in your database (the - versions table for example), or to the <quote>constants</quote> - encoded in <filename>defparams.pl</filename>, you will need to remove - the cached content from the data directory (by doing a - <command>rm data/versioncache</command>), or your changes won't show up. - </para> - - <para> - <filename>versioncache</filename> gets regenerated automatically - whenever it's more than an hour old, so Bugzilla will eventually - notice your changes by itself, but generally you want it to notice - right away, so that you can test things. - </para> - </section> + For a list of possible field names, look at the bugs table in the + database. If you need help writing custom rules for your organization, + ask in the newsgroup. + </para> + </section> <!-- Integrating Bugzilla with Third-Party Tools --> &integration; diff --git a/docs/xml/faq.xml b/docs/xml/faq.xml index d2cb5f5e0..80f411375 100644 --- a/docs/xml/faq.xml +++ b/docs/xml/faq.xml @@ -13,6 +13,21 @@ <qandadiv id="faq-general"> <title>General Questions</title> + <qandaentry> + <question id="faq-general-tryout"> + <para> + Can I try out Bugzilla somewhere? + </para> + </question> + <answer> + <para> + If you want to take a test ride, there are test installations + at <ulink url="http://landfill.bugzilla.org/"/>, + ready to play with directly from your browser. + </para> + </answer> + </qandaentry> + <qandaentry> <question id="faq-general-license"> <para> @@ -126,7 +141,7 @@ </para> <para> The best way to make an enhancement request is to <ulink - url="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla">file + url="https://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla">file a bug at bugzilla.mozilla.org</ulink> and set the Severity to 'enhancement'. Your 'request for enhancement' (RFE) will start out in the UNCONFIRMED state, and will stay there until @@ -169,35 +184,44 @@ and was available for the hardware Netscape intended to run it on. </para> <para> - There is currently work in progress to make Bugzilla work on - PostgreSQL; track the progress of this initiative in <ulink - url="http://bugzilla.mozilla.org/show_bug.cgi?id=98304">bug 98304</ulink>. - </para> - <para> - Sybase support is no longer being worked on. Even if it eventually - happens, it's VERY unlikely to work without the end-user-company - having to stick a few developers on making several manual changes. - Sybase is just NOT very standards-compliant (despite all the hype), - and it turned out that way too much had to be changed to make it - work -- like moving half of the application logic into stored - procedures to get any kind of decent performance out of it. - <ulink url="http://bugzilla.mozilla.org/show_bug.cgi?id=173130">Bug - 173130</ulink> is the relevant bug. + Bugzilla 2.20 contains experimental support for PostgreSQL. + Bugzilla 2.22 contains complete, stable support for PostgreSQL. + As of this release, using PostgreSQL with Bugzilla should + be as stable as using MySQL. If you experience any problems + with PostgreSQL compatibility, they will be taken as + seriously as if you were running MySQL. </para> <para> Red Hat once ran a version of Bugzilla that worked on Oracle, but that was long, long ago; that version (Bugzilla 2.8) is - now obsolete, insecure, and totally unsupported. Red Hat's - current Bugzilla (based on Bugzilla 2.17.1) uses PostgreSQL, - and work is being done to merge those changes into the main - distribution. (See above.) At this time we know of no recent - ports of Bugzilla to Oracle. (In our honest opinion, Bugzilla - doesn't need what Oracle offers.) + now obsolete, insecure, and totally unsupported. + </para> + <para> + In August of 2005, Wim Coekaerts (Director of Linux + Engineering at Oracle Corporation) wrote to Dave Miller + confirming that Oracle intends to implement and support + Bugzilla. Since then, no further information has been + forthcoming. Track progress at + <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=189947"> + Bug 189947</ulink>. </para> <para> - <ulink url="http://bugzilla.mozilla.org/show_bug.cgi?id=237862">Bug - 237862</ulink> is a good bug to read through if you'd like to see - what progress is being made on general database compatibility. + Sybase support is no longer being worked on. Even if it + eventually happens, it's VERY unlikely to work without + the end-user-company having to stick a few developers on + making several manual changes. Sybase is just NOT very + standards-compliant (despite all the hype), and it turned + out that way too much had to be changed to make it work -- + like moving half of the application logic into stored + procedures to get any kind of decent performance out of it. + <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=173130"> + Bug 173130</ulink> is the relevant bug. + </para> + <para> + <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=237862"> + Bug 237862</ulink> is a good bug to read through if you'd + like to see what progress is being made on general database + compatibility. </para> </answer> </qandaentry> @@ -301,7 +325,7 @@ perl runtests.pl 2 --verbose </para> </answer> </qandaentry> - + <qandaentry> <question id="faq-mod-perl"> <para> @@ -318,7 +342,22 @@ perl runtests.pl 2 --verbose </para> </answer> </qandaentry> - + + <qandaentry> + <question id="faq-general-selinux"> + <para> + How can Bugzilla be made to work under SELinux? + </para> + </question> + <answer> + <para> + Unfortunately there are no step-by-step instructions, + but the following URL contains hints on how to do it: + <ulink url="http://fedora.redhat.com/docs/selinux-apache-fc3/sn-debugging-and-customizing.html" /> + </para> + </answer> + </qandaentry> + </qandadiv> <qandadiv id="faq-phb"> @@ -355,7 +394,7 @@ perl runtests.pl 2 --verbose <para> There is no GUI for adding fields to Bugzilla at this time. You can follow development of this feature in - <ulink url="http://bugzilla.mozilla.org/show_bug.cgi?id=91037">bug 91037</ulink> + <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=91037">bug 91037</ulink> </para> </answer> </qandaentry> @@ -369,7 +408,7 @@ perl runtests.pl 2 --verbose </question> <answer> <para> - Yes. Look at <ulink url="http://bugzilla.mozilla.org/report.cgi"/> + Yes. Look at <ulink url="https://bugzilla.mozilla.org/report.cgi"/> for samples of what Bugzilla can do in reporting and graphing. Fuller documentation is provided in <xref linkend="reporting"/>. </para> @@ -481,7 +520,7 @@ perl runtests.pl 2 --verbose Some admin interfaces have been templatized (for easy localization) but many of them are still available in English only. Also, there may be issues with the charset not being declared. See <ulink - url="http://bugzilla.mozilla.org/show_bug.cgi?id=126266">bug 126226</ulink> + url="https://bugzilla.mozilla.org/show_bug.cgi?id=126266">bug 126226</ulink> for more information. </para> </answer> @@ -598,7 +637,7 @@ perl runtests.pl 2 --verbose See the documentation on Customization for more details, specifically <xref linkend="template-specific"/>. </para> - </answer> + </answer> </qandaentry> </qandadiv> @@ -712,7 +751,7 @@ perl runtests.pl 2 --verbose </para> <para> See also the instructions in <xref linkend="upgrade-cvs"/>. - </para> + </para> </answer> </qandaentry> @@ -781,7 +820,7 @@ password=mypassword command line. </para> </warning> - + <para> On your new machine, follow the instructions found in <xref linkend="installing-bugzilla"/> as far as setting up the physical @@ -833,7 +872,7 @@ password=mypassword Run MySQL like this: <command>mysqld --skip-grant-tables</command>. Please remember that <emphasis>this makes MySQL as secure as taping a $100 to the floor of a football stadium bathroom for - safekeeping.</emphasis> + safekeeping.</emphasis> </para> <warning> <para> @@ -952,7 +991,7 @@ password=mypassword For older versions of Bugzilla, you may be able to apply Klaas Freitag's patch for <quote>whineatassigned</quote>, which can be found in - <ulink url="http://bugzilla.mozilla.org/show_bug.cgi?id=6679">bug + <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=6679">bug 6679</ulink>. Note that this patch was made in 2000, so it may take some work to apply cleanly to any releases of Bugzilla newer than that, but you can use it as a starting point. @@ -961,7 +1000,7 @@ password=mypassword <para> An updated (and much-expanded) version of this functionality is due to be released as part of Bugzilla 2.20; see - <ulink url="http://bugzilla.mozilla.org/show_bug.cgi?id=185090">bug + <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=185090">bug 185090</ulink> for the discussion, and for more up-to-date patches if you just can't wait. </para> @@ -1124,6 +1163,61 @@ password=mypassword as a troubleshooting step. </para> </warning> + <para> + You may also be suffering from a client version mismatch: + </para> + <para> + MySQL 4.1 and up uses an authentication protocol based on + a password hashing algorithm that is incompatible with that + used by older clients. If you upgrade the server to 4.1, + attempts to connect to it with an older client may fail + with the following message: + </para> + <para> + <screen><prompt>shell></prompt> mysql + Client does not support authentication protocol requested + by server; consider upgrading MySQL client + </screen> + </para> + <para> + To solve this problem, you should use one of the following + approaches: + </para> + <para> + <itemizedlist> + <listitem> + <para> + Upgrade all client programs to use a 4.1.1 or newer + client library. + </para> + </listitem> + <listitem> + <para> + When connecting to the server with a pre-4.1 client + program, use an account that still has a + pre-4.1-style password. + </para> + </listitem> + <listitem> + <para> + Reset the password to pre-4.1 style for each user + that needs to use a pre-4.1 client program. + This can be done using the SET PASSWORD statement + and the OLD_PASSWORD() function: + <screen> + <prompt>mysql></prompt> SET PASSWORD FOR + <prompt> -></prompt> ' some_user '@' some_host ' = OLD_PASSWORD(' newpwd '); + </screen> + </para> + </listitem> + </itemizedlist> + + </para> + + + <para> + </para> + </answer> </qandaentry> @@ -1276,7 +1370,7 @@ password=mypassword </para> </listitem> </orderedlist> - I reckon TimeDate and Data::Dumper come with the activeperl. + I reckon TimeDate comes with the activeperl. You can check the ActiveState site for packages for installation through PPM. <ulink url="http://www.activestate.com/Packages/"/>. </para> @@ -1358,16 +1452,16 @@ password=mypassword have your choice of patches: <simplelist> <member> - <ulink url="http://bugzilla.mozilla.org/show_bug.cgi?id=35195">Bug 35195</ulink> + <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=35195">Bug 35195</ulink> seeks to add an <quote>...and accept the bug</quote> checkbox to the UI. It has two patches attached to it: - <ulink url="http://bugzilla.mozilla.org/showattachment.cgi?attach_id=8029">attachment 8029</ulink> + <ulink url="https://bugzilla.mozilla.org/showattachment.cgi?attach_id=8029">attachment 8029</ulink> was originally created for Bugzilla 2.12, while - <ulink url="http://bugzilla.mozilla.org/showattachment.cgi?attach_id=91372">attachment 91372</ulink> + <ulink url="https://bugzilla.mozilla.org/showattachment.cgi?attach_id=91372">attachment 91372</ulink> is an updated version for Bugzilla 2.16 </member> <member> - <ulink url="http://bugzilla.mozilla.org/show_bug.cgi?id=37613">Bug + <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=37613">Bug 37613</ulink> also provides two patches (against Bugzilla 2.12): one to add a 'Take Bug' option, and the other to automatically reassign the bug on 'Accept'. @@ -1501,13 +1595,13 @@ password=mypassword </question> <answer> <para> - Try <ulink url="http://bugzilla.mozilla.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=Bugzilla"> + Try <ulink url="https://bugzilla.mozilla.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=Bugzilla"> this link</ulink> to view current bugs or requests for enhancement for Bugzilla. </para> <para> You can view bugs marked for &bz-nextver; release - <ulink url="http://bugzilla.mozilla.org/buglist.cgi?product=Bugzilla&target_milestone=Bugzilla+&bz-nextver;">here</ulink>. + <ulink url="https://bugzilla.mozilla.org/buglist.cgi?product=Bugzilla&target_milestone=Bugzilla+&bz-nextver;">here</ulink>. This list includes bugs for the &bz-nextver; release that have already been fixed and checked into CVS. Please consult the <ulink url="http://www.bugzilla.org/"> @@ -1529,7 +1623,7 @@ password=mypassword <answer> <para> This is well-documented in <ulink - url="http://bugzilla.mozilla.org/show_bug.cgi?id=49862">bug + url="https://bugzilla.mozilla.org/show_bug.cgi?id=49862">bug 49862</ulink>. Ultimately, it's as easy as adding the <quote>---</quote> priority field to your localconfig file in the appropriate area, re-running checksetup.pl, and then @@ -1552,7 +1646,7 @@ password=mypassword <listitem> <para> Enter a bug into bugzilla.mozilla.org for the <quote><ulink - url="http://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla">Bugzilla</ulink></quote> + url="https://bugzilla.mozilla.org/enter_bug.cgi?product=Bugzilla">Bugzilla</ulink></quote> product. </para> </listitem> @@ -1571,7 +1665,7 @@ password=mypassword <listitem> <para> Announce your patch and the associated URL - (http://bugzilla.mozilla.org/show_bug.cgi?id=XXXXXX) + (https://bugzilla.mozilla.org/show_bug.cgi?id=XXXXXX) for discussion in the newsgroup (mozilla.support.bugzilla). You'll get a really good, fairly immediate reaction to the diff --git a/docs/xml/glossary.xml b/docs/xml/glossary.xml index 3556570d2..376b48cff 100644 --- a/docs/xml/glossary.xml +++ b/docs/xml/glossary.xml @@ -268,8 +268,8 @@ <acronym>MTA</acronym> <glossdef> - <para>A Message Transport Agent is used to control the flow of email - on a system. The <ulink url="http://search.cpan.org/dist/MailTools/Mail/Mailer.pm">Mail::Mailer</ulink> + <para>A Message Transport Agent is used to control the flow of email on a system. + The <ulink url="http://search.cpan.org/dist/Email-Send/lib/Email/Send.pm">Email::Send</ulink> Perl module, which Bugzilla uses to send email, can be configured to use many different underlying implementations for actually sending the mail using the <option>mail_delivery_method</option> parameter. diff --git a/docs/xml/installation.xml b/docs/xml/installation.xml index 2b5250867..7c8d43b35 100644 --- a/docs/xml/installation.xml +++ b/docs/xml/installation.xml @@ -1,5 +1,5 @@ <!-- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"> --> -<!-- $Id: installation.xml,v 1.107.2.17 2007/03/10 01:39:02 vladd%bugzilla.org Exp $ --> +<!-- $Id: installation.xml,v 1.136.2.2 2007/03/10 01:21:11 vladd%bugzilla.org Exp $ --> <chapter id="installing-bugzilla"> <title>Installing Bugzilla</title> @@ -258,7 +258,7 @@ <para>Many people complain that Perl modules will not install for them. Most times, the error messages complain that they are missing a file in - <quote>@INC</quote>. + <quote>@INC</quote>. Virtually every time, this error is due to permissions being set too restrictively for you to compile Perl modules or not having the necessary Perl development libraries installed on your system. @@ -287,147 +287,194 @@ <listitem> <para> - AppConfig (&min-appconfig-ver;) + CGI &min-cgi-ver; or CGI &min-mp-cgi-ver; if using mod_perl </para> </listitem> <listitem> <para> - CGI (&min-cgi-ver;) + Date::Format (&min-date-format-ver;) + </para> + </listitem> + + <listitem> + <para> + DBI (&min-dbi-ver;) </para> </listitem> <listitem> <para> - Data::Dumper (&min-data-dumper-ver;) + <link linkend="install-modules-dbd-mysql">DBD::mysql</link> + (&min-dbd-mysql-ver;) if using MySQL </para> </listitem> - + <listitem> <para> - Date::Format (&min-date-format-ver;) + DBD::Pg (&min-dbd-pg-ver;) if using PostgreSQL </para> </listitem> - + <listitem> <para> - DBI (&min-dbi-ver;) + File::Spec (&min-file-spec-ver;) </para> </listitem> <listitem> <para> - <link linkend="install-modules-dbd-mysql">DBD::mysql</link> - (&min-dbd-mysql-ver;) if using MySQL + <link linkend="install-modules-template">Template</link> + (&min-template-ver;) </para> </listitem> - + <listitem> <para> - DBD::Pg (&min-dbd-pg-ver;) if using PostgreSQL + Email::Send (&min-email-send-ver;) </para> </listitem> <listitem> <para> - File::Spec (&min-file-spec-ver;) + Email::MIME::Modifier (&min-email-mime-modifier-ver;) </para> </listitem> + </orderedlist> + Optional Perl modules: + <orderedlist> <listitem> <para> - File::Temp (&min-file-temp-ver;) + <link linkend="install-modules-gd">GD</link> + (&min-gd-ver;) for bug charting </para> </listitem> <listitem> <para> - <link linkend="install-modules-template">Template</link> - (&min-template-ver;) + Template::Plugin::GD::Image + (&min-gd-ver;) for Graphical Reports + </para> + </listitem> + + <listitem> + <para> + <link linkend="install-modules-chart-base">Chart::Base</link> + (&min-chart-base-ver;) for bug charting </para> </listitem> <listitem> <para> - Text::Wrap (&min-text-wrap-ver;) + <link linkend="install-modules-gd-graph">GD::Graph</link> + (&min-gd-graph-ver;) for bug charting </para> </listitem> <listitem> <para> - Mail::Mailer (&min-mail-mailer-ver;) + <link linkend="install-modules-gd-text">GD::Text</link> + (&min-gd-text-ver;) for bug charting </para> </listitem> <listitem> <para> - MIME::Base64 (&min-mime-base64-ver;) + <link linkend="install-modules-xml-twig">XML::Twig</link> + (&min-xml-twig-ver;) for bug import/export </para> </listitem> <listitem> <para> - MIME::Parser (&min-mime-parser-ver;) + MIME::Parser (&min-mime-parser-ver;) for bug import/export </para> </listitem> <listitem> <para> - Storable (&min-storable-ver;) + LWP::UserAgent + (&min-lwp-useragent-ver;) for Automatic Update Notifications </para> </listitem> - </orderedlist> - Optional Perl modules: - <orderedlist> <listitem> <para> - <link linkend="install-modules-gd">GD</link> - (&min-gd-ver;) for bug charting + <link linkend="install-modules-patchreader">PatchReader</link> + (&min-patchreader-ver;) for pretty HTML view of patches </para> </listitem> <listitem> <para> - <link linkend="install-modules-chart-base">Chart::Base</link> - (&min-chart-base-ver;) for bug charting + Image::Magick (&min-image-magick-ver;) for converting BMP image attachments to PNG </para> </listitem> <listitem> <para> - <link linkend="install-modules-gd-graph">GD::Graph</link> - (&min-gd-graph-ver;) for bug charting + Net::LDAP + (&min-net-ldap-ver;) for LDAP Authentication </para> </listitem> <listitem> <para> - <link linkend="install-modules-gd-text-align">GD::Text::Align</link> - (&min-gd-text-align-ver;) for bug charting + <link linkend="install-modules-soap-lite">SOAP::Lite</link> + (&min-soap-lite-ver;) for the web service interface </para> </listitem> <listitem> <para> - <link linkend="install-modules-xml-twig">XML::Twig</link> - (&min-xml-twig-ver;) for the XML interface + HTML::Parser + (&min-html-parser-ver;) for More HTML in Product/Group Descriptions </para> </listitem> <listitem> <para> - <link linkend="install-modules-patchreader">PatchReader</link> - (&min-patchreader-ver;) for pretty HTML view of patches + HTML::Scrubber + (&min-html-scrubber-ver;) for More HTML in Product/Group Descriptions </para> </listitem> <listitem> <para> - Image::Magick (&min-image-magick-ver;) for converting BMP image attachments to PNG + Email::MIME::Attachment::Stripper + (&min-email-mime-attachment-stripper-ver;) for Inbound Email + </para> + </listitem> + + <listitem> + <para> + Email::Reply + (&min-email-reply-ver;) for Inbound Email + </para> + </listitem> + + <listitem> + <para> + mod_perl2 + (&min-mod_perl2-ver;) for mod_perl + </para> + </listitem> + + <listitem> + <para> + CGI + (&min-cgi-ver;) for mod_perl </para> </listitem> - </orderedlist> + + <listitem> + <para> + Apache::DBI + (&min-apache-dbi-ver;) for mod_perl2 + </para> + </listitem> + </orderedlist> </para> <section id="install-modules-dbd-mysql"> @@ -500,10 +547,10 @@ </para> </section> - <section id="install-modules-gd-text-align"> - <title>GD::Text::Align (&min-gd-text-align-ver;)</title> + <section id="install-modules-gd-text"> + <title>GD::Text (&min-gd-text-ver;)</title> - <para>The GD::Text::Align module is only required if you want graphical + <para>The GD::Text module is only required if you want graphical reports. </para> </section> @@ -518,6 +565,14 @@ </para> </section> + <section id="install-modules-soap-lite"> + <title>SOAP::Lite (&min-soap-lite-ver;)</title> + <para>Installing SOAP::Lite enables your Bugzilla installation to be + accessible at a standardized Web Service interface (SOAP/XML-RPC) + by third-party applications via HTTP(S). + </para> + </section> + <section id="install-modules-patchreader"> <title>PatchReader (&min-patchreader-ver;)</title> @@ -582,7 +637,23 @@ </para> </section> - + <section id="using-mod_perl-with-bugzilla"> + <title>Installing Bugzilla on mod_perl</title> + <para>It is now possible to run the Bugzilla software under <literal>mod_perl</literal> on + Apache. <literal>mod_perl</literal> has some additional requirements to that of running + Bugzilla under <literal>mod_cgi</literal> (the standard and previous way).</para> + + <para>Bugzilla requires <literal>mod_perl</literal> to be installed, which can be + obtained from <ulink url="http://perl.apache.org"/> - Bugzilla requires + version &min-mod_perl2-ver; (AKA 2.0.0-RC5) to be installed.</para> + + <para>Bugzilla also requires a more up-to-date version of the CGI + perl module to be installed, version &min-mp-cgi-ver; as opposed to &min-cgi-ver; + </para> + + <para>Finally, Bugzilla also requires <literal>Apache::DBI</literal> + (&min-apache-dbi-ver;) to be installed as well.</para> + </section> </section> @@ -810,13 +881,6 @@ <section id="postgresql"> <title>PostgreSQL</title> - <note> - <para>If you are using PostgreSQL 8.0.1 or higher, then you - will require to use a version of DBD::Pg which is equal to or - greater than version 1.41 - </para> - </note> - <section> <title>Add a User to PostgreSQL</title> @@ -851,28 +915,13 @@ you will need to add a new line to it as follows:</para> <para> - <computeroutput>host all bugs 127.0.0.1 255.255.255.255 md5</computeroutput> + <computeroutput>host all bugs 127.0.0.1 255.255.255.255 md5</computeroutput> </para> - + <para>This means that for TCP/IP (host) connections, allow connections from '127.0.0.1' to 'all' databases on this server from the 'bugs' user, and use password authentication (md5) for that user.</para> - <para>If you are using <emphasis role="bold">versions of PostgreSQL - before version 8</emphasis>, you may also need to edit <filename>postgresql.conf</filename> - , also usually found in the <filename>/var/lib/pgsql/data/</filename> folder. - You will need to make a single line change, changing</para> - - <para> - <computeroutput># tcpip_socket = false</computeroutput> - </para> - - <para>to</para> - - <para> - <computeroutput>tcpip_socket = true</computeroutput> - </para> - <para>Now, you will need to restart PostgreSQL, but you will need to fully stop and start the server rather than just restarting due to the possibility of a change to <filename>postgresql.conf</filename>. After the server has @@ -929,100 +978,208 @@ </para> <section id="http-apache"> - <title>Apache <productname>httpd</productname></title> - - <para> - To configure your Apache web server to work with Bugzilla, - do the following: + <title>Bugzilla using Apache</title> + <para>You have two options for running Bugzilla under Apache - + <link linkend="http-apache-mod_cgi">mod_cgi</link> (the default) and + <link linkend="http-apache-mod_perl">mod_perl</link> (new in Bugzilla + 2.23) </para> - - <procedure> - <step> - <para> - Load <filename>httpd.conf</filename> in your editor. - In Fedora and Red Hat Linux, this file is found in - <filename class="directory">/etc/httpd/conf</filename>. - </para> - </step> - - <step> - <para> - Apache uses <computeroutput><Directory></computeroutput> - directives to permit fine-grained permission setting. Add the - following lines to a directive that applies to the location - of your Bugzilla installation. (If such a section does not - exist, you'll want to add one.) In this example, Bugzilla has - been installed at - <filename class="directory">/var/www/html/bugzilla</filename>. - </para> - - <programlisting> -<Directory /var/www/html/bugzilla> - AddHandler cgi-script .cgi - Options +Indexes +ExecCGI - DirectoryIndex index.cgi - AllowOverride Limit -</Directory> - </programlisting> - + <section id="http-apache-mod_cgi"> + <title>Apache <productname>httpd</productname> with mod_cgi</title> + <para> - These instructions: allow apache to run .cgi files found - within the bugzilla directory; instructs the server to look - for a file called <filename>index.cgi</filename> if someone - only types the directory name into the browser; and allows - Bugzilla's <filename>.htaccess</filename> files to override - global permissions. + To configure your Apache web server to work with Bugzilla while using + mod_cgi, do the following: </para> - + + <procedure> + <step> + <para> + Load <filename>httpd.conf</filename> in your editor. + In Fedora and Red Hat Linux, this file is found in + <filename class="directory">/etc/httpd/conf</filename>. + </para> + </step> + + <step> + <para> + Apache uses <computeroutput><Directory></computeroutput> + directives to permit fine-grained permission setting. Add the + following lines to a directive that applies to the location + of your Bugzilla installation. (If such a section does not + exist, you'll want to add one.) In this example, Bugzilla has + been installed at + <filename class="directory">/var/www/html/bugzilla</filename>. + </para> + + <programlisting> + <Directory /var/www/html/bugzilla> + AddHandler cgi-script .cgi + Options +Indexes +ExecCGI + DirectoryIndex index.cgi + AllowOverride Limit + </Directory> + </programlisting> + + <para> + These instructions: allow apache to run .cgi files found + within the bugzilla directory; instructs the server to look + for a file called <filename>index.cgi</filename> if someone + only types the directory name into the browser; and allows + Bugzilla's <filename>.htaccess</filename> files to override + global permissions. + </para> + + <note> + <para> + It is possible to make these changes globally, or to the + directive controlling Bugzilla's parent directory (e.g. + <computeroutput><Directory /var/www/html/></computeroutput>). + Such changes would also apply to the Bugzilla directory... + but they would also apply to many other places where they + may or may not be appropriate. In most cases, including + this one, it is better to be as restrictive as possible + when granting extra access. + </para> + </note> + </step> + + <step> + <para> + <filename>checksetup.pl</filename> can set tighter permissions + on Bugzilla's files and directories if it knows what group the + webserver runs as. Find the <computeroutput>Group</computeroutput> + line in <filename>httpd.conf</filename>, place the value found + there in the <replaceable>$webservergroup</replaceable> variable + in <filename>localconfig</filename>, then rerun + <filename>checksetup.pl</filename>. + </para> + </step> + + <step> + <para> + Optional: If Bugzilla does not actually reside in the webspace + directory, but instead has been symbolically linked there, you + will need to add the following to the + <computeroutput>Options</computeroutput> line of the Bugzilla + <computeroutput><Directory></computeroutput> directive + (the same one as in the step above): + </para> + + <programlisting> + +FollowSymLinks + </programlisting> + + <para> + Without this directive, Apache will not follow symbolic links + to places outside its own directory structure, and you will be + unable to run Bugzilla. + </para> + </step> + </procedure> + </section> + <section id="http-apache-mod_perl"> + <title>Apache <productname>httpd</productname> with mod_perl</title> + + <para>Some configuration is required to make Bugzilla work with Apache + and mod_perl</para> + + <procedure> + <step> + <para> + Load <filename>httpd.conf</filename> in your editor. + In Fedora and Red Hat Linux, this file is found in + <filename class="directory">/etc/httpd/conf</filename>. + </para> + </step> + + <step> + <para>Add the following information to your httpd.conf file, substituting + where appropriate with your own local paths.</para> + + <note> + <para>This should be used instead of the <Directory> block + shown above. This should also be above any other <literal>mod_perl</literal> + directives within the <filename>httpd.conf</filename> and must be specified + in the order as below.</para> + </note> + <warning> + <para>You should also ensure that you have disabled <literal>KeepAlive</literal> + support in your Apache install when utilizing Bugzilla under mod_perl</para> + </warning> + + <programlisting> + PerlSwitches -I/var/www/html/bugzilla -w -T + PerlConfigRequire /var/www/html/bugzilla/mod_perl.pl + </programlisting> + </step> + + <step> + <para> + <filename>checksetup.pl</filename> can set tighter permissions + on Bugzilla's files and directories if it knows what group the + webserver runs as. Find the <computeroutput>Group</computeroutput> + line in <filename>httpd.conf</filename>, place the value found + there in the <replaceable>$webservergroup</replaceable> variable + in <filename>localconfig</filename>, then rerun + <filename>checksetup.pl</filename>. + </para> + </step> + </procedure> + + <para>On restarting Apache, Bugzilla should now be running within the + mod_perl environment. Please ensure you have run checksetup.pl to set + permissions before you restart Apache.</para> + <note> - <para> - It is possible to make these changes globally, or to the - directive controlling Bugzilla's parent directory (e.g. - <computeroutput><Directory /var/www/html/></computeroutput>). - Such changes would also apply to the Bugzilla directory... - but they would also apply to many other places where they - may or may not be appropriate. In most cases, including - this one, it is better to be as restrictive as possible - when granting extra access. - </para> - </note> - </step> - - <step> - <para> - <filename>checksetup.pl</filename> can set tighter permissions - on Bugzilla's files and directories if it knows what group the - webserver runs as. Find the <computeroutput>Group</computeroutput> - line in <filename>httpd.conf</filename>, place the value found - there in the <replaceable>$webservergroup</replaceable> variable - in <filename>localconfig</filename>, then rerun - <filename>checksetup.pl</filename>. + <para>Please bear the following points in mind when looking at using + Bugzilla under mod_perl: + <itemizedlist> + <listitem> + <para> + mod_perl support in Bugzilla can take up a HUGE amount of RAM. You could be + looking at 30MB per httpd child, easily. Basically, you just need a lot of RAM. + The more RAM you can get, the better. mod_perl is basically trading RAM for + speed. At least 2GB total system RAM is recommended for running Bugzilla under + mod_perl. + </para> + </listitem> + <listitem> + <para> + Under mod_perl, you have to restart Apache if you make any manual change to + any Bugzilla file. You can't just reload--you have to actually + <emphasis>restart</emphasis> the server (as in make sure it stops and starts + again). You <emphasis>can</emphasis> change localconfig and the params file + manually, if you want, because those are re-read every time you load a page. + </para> + </listitem> + <listitem> + <para> + You must run in Apache's Prefork MPM (this is the default). The Worker MPM + may not work--we haven't tested Bugzilla's mod_perl support under threads. + (And, in fact, we're fairly sure it <emphasis>won't</emphasis> work.) + </para> + </listitem> + <listitem> + <para> + Bugzilla generally expects to be the only mod_perl application running on + your entire server. It may or may not work if there are other applications also + running under mod_perl. It does try its best to play nice with other mod_perl + applications, but it still may have conflicts. + </para> + </listitem> + <listitem> + <para> + It is recommended that you have one Bugzilla instance running under mod_perl + on your server. Bugzilla has not been tested with more than one instance running. + </para> + </listitem> + </itemizedlist> </para> - </step> - - <step> - <para> - Optional: If Bugzilla does not actually reside in the webspace - directory, but instead has been symbolically linked there, you - will need to add the following to the - <computeroutput>Options</computeroutput> line of the Bugzilla - <computeroutput><Directory></computeroutput> directive - (the same one as in the step above): - </para> - - <programlisting> - +FollowSymLinks - </programlisting> - - <para> - Without this directive, Apache will not follow symbolic links - to places outside its own directory structure, and you will be - unable to run Bugzilla. - </para> - </step> - </procedure> + </note> + </section> </section> - + <section id="http-iis"> <title>Microsoft <productname>Internet Information Services</productname></title> @@ -1364,16 +1521,18 @@ c:\perl\bin\perl.exe -xc:\bugzilla -wT "%s" %s you need to deal with user ID (e.g assigning a bug) use the email address. The LDAP authentication builds on top of this scheme, rather than replacing it. The initial log in is done with a username and - password for the LDAP directory. This then fetches the email address - from LDAP and authenticates seamlessly in the standard Bugzilla - authentication scheme using this email address. If an account for this - address already exists in your Bugzilla system, it will log in to that - account. If no account for that email address exists, one is created at - the time of login. (In this case, Bugzilla will attempt to use the - "displayName" or "cn" attribute to determine the user's full name.) - After authentication, all other user-related tasks are still handled by - email address, not LDAP username. You still assign bugs by email - address, query on users by email address, etc. + password for the LDAP directory. Bugzilla tries to bind to LDAP using + those credentials, and if successful, try to map this account to a + Bugzilla account. If a LDAP mail attribute is defined, the value of this + attribute is used, otherwise emailsuffix parameter is appended to LDAP + username to form a full email address. If an account for this address + already exists in your Bugzilla system, it will log in to that account. + If no account for that email address exists, one is created at the time + of login. (In this case, Bugzilla will attempt to use the "displayName" + or "cn" attribute to determine the user's full name.) After + authentication, all other user-related tasks are still handled by email + address, not LDAP username. You still assign bugs by email address, query + on users by email address, etc. </para> <caution> @@ -1417,6 +1576,15 @@ c:\perl\bin\perl.exe -xc:\bugzilla -wT "%s" %s <para>Ex. <quote>ldap.company.com</quote> or <quote>ldap.company.com:3268</quote> </para> + <para>You can also specify a LDAP URI, so as to use other + protocols, such as LDAPS or LDAPI. If port was not specified in + the URI, the default is either 389 or 636 for 'LDAP' and 'LDAPS' + schemes respectively. + </para> + <para>Ex. <quote>ldap://ldap.company.com</quote>, + <quote>ldaps://ldap.company.com</quote> or + <quote>ldapi://%2fvar%2flib%2fldap_sock</quote> + </para> </listitem> </varlistentry> diff --git a/docs/xml/introduction.xml b/docs/xml/introduction.xml index 3968702c6..5cf4a5599 100644 --- a/docs/xml/introduction.xml +++ b/docs/xml/introduction.xml @@ -68,7 +68,7 @@ </listitem> <listitem> - <para>Completely customizable and/or localizable web user + <para>Completely customisable and/or localisable web user interface</para> </listitem> diff --git a/docs/xml/modules.xml b/docs/xml/modules.xml index 942ce6b3c..6e325c5a7 100644 --- a/docs/xml/modules.xml +++ b/docs/xml/modules.xml @@ -49,15 +49,6 @@ </para> </note> - <para> - AppConfig: - <literallayout> - CPAN Download Page: <ulink url="http://search.cpan.org/src/ABW/AppConfig-1.56/lib/AppConfig.pm"/> - PPM Download Link: <ulink url="http://landfill.bugzilla.org/ppm/AppConfig.ppd"/> - Documentation: <ulink url="http://search.cpan.org/~abw/AppConfig-1.56/lib/AppConfig.pm"/> - </literallayout> - </para> - <para> CGI: <literallayout> @@ -121,15 +112,6 @@ </literallayout> </para> - <para> - File::Temp: - <literallayout> - CPAN Download Page: <ulink url="http://search.cpan.org/dist/File-Temp/"/> - PPM Download Page: Part of core distribution. - Documentation: <ulink url="http://www.perldoc.com/perl5.8.0/lib/File/Temp.html"/> - </literallayout> - </para> - <para> Template-Toolkit: <literallayout> @@ -139,15 +121,6 @@ </literallayout> </para> - <para> - Text::Wrap: - <literallayout> - CPAN Download Page: <ulink url="http://search.cpan.org/dist/Text-Tabs+Wrap/"/> - PPM Download Link: Part of core distribution. - Documentation: <ulink url="http://www.perldoc.com/perl5.8.0/lib/Text/Wrap.html"/> - </literallayout> - </para> - <para> GD: <literallayout> @@ -166,15 +139,6 @@ </literallayout> </para> - <para> - MIME::Base64: - <literallayout> - CPAN Download Page: <ulink url="http://search.cpan.org/dist/MIME-Base64/"/> - PPM Download Link: <ulink url="http://ppm.activestate.com/PPMPackages/zips/8xx-builds-only/Windows/MIME-Base64-2.20.zip"/> - Documentation: <ulink url="http://search.cpan.org/dist/MIME-Base64/Base64.pm"/> - </literallayout> - </para> - <para> MIME::Parser (part of MIME-tools): <literallayout> diff --git a/docs/xml/patches.xml b/docs/xml/patches.xml index 12efb0ca4..b1d92816f 100644 --- a/docs/xml/patches.xml +++ b/docs/xml/patches.xml @@ -21,7 +21,7 @@ <warning> <para> - These files pre-date the templatization work done as part of the + These files pre-date the templatisation work done as part of the 2.16 release, and have not been updated. </para> </warning> diff --git a/docs/xml/requiredsoftware.xml b/docs/xml/requiredsoftware.xml index 8a8c35774..4a751c0c7 100644 --- a/docs/xml/requiredsoftware.xml +++ b/docs/xml/requiredsoftware.xml @@ -31,10 +31,6 @@ <ulink url="http://www.cpan.org/modules/by-module/DBI/"/> </para> - <para>Data::Dumper module: - <ulink url="http://www.cpan.org/modules/by-module/Data/"/> - </para> - <para>MySQL related Perl modules: <ulink url="http://www.cpan.org/modules/by-module/Mysql/"/> </para> diff --git a/docs/xml/security.xml b/docs/xml/security.xml index 5293f5c3a..751f2edea 100644 --- a/docs/xml/security.xml +++ b/docs/xml/security.xml @@ -1,5 +1,5 @@ <!-- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"> --> -<!-- $Id: security.xml,v 1.8.2.6 2006/11/20 19:50:22 lpsolit%gmail.com Exp $ --> +<!-- $Id: security.xml,v 1.16 2006/11/20 19:48:43 lpsolit%gmail.com Exp $ --> <chapter id="security"> <title>Bugzilla Security</title> diff --git a/docs/xml/troubleshooting.xml b/docs/xml/troubleshooting.xml index 4ad76cddf..019ca010a 100644 --- a/docs/xml/troubleshooting.xml +++ b/docs/xml/troubleshooting.xml @@ -1,5 +1,5 @@ <!-- <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"> --> -<!-- $Id: troubleshooting.xml,v 1.6.2.3 2006/06/07 20:10:30 uid623 Exp $ --> +<!-- $Id: troubleshooting.xml,v 1.12 2006/07/31 22:22:51 mkanat%bugzilla.org Exp $ --> <appendix id="troubleshooting"> <title>Troubleshooting</title> @@ -139,49 +139,6 @@ TEST-OK Webserver is preventing fetch of http://landfill.bugzilla.org/bugzilla-t </para> </section> - <section id="trouble-filetemp"> - <title>Your vendor has not defined Fcntl macro O_NOINHERIT</title> - - <para>This is caused by a bug in the version of - <productname>File::Temp</productname> that is distributed with perl - 5.6.0. Many minor variations of this error have been reported: - </para> - - <programlisting>Your vendor has not defined Fcntl macro O_NOINHERIT, used -at /usr/lib/perl5/site_perl/5.6.0/File/Temp.pm line 208. - -Your vendor has not defined Fcntl macro O_EXLOCK, used -at /usr/lib/perl5/site_perl/5.6.0/File/Temp.pm line 210. - -Your vendor has not defined Fcntl macro O_TEMPORARY, used -at /usr/lib/perl5/site_perl/5.6.0/File/Temp.pm line 233.</programlisting> - - <para>Numerous people have reported that upgrading to version 5.6.1 - or higher solved the problem for them. A less involved fix is to apply - the following patch, which is also - available as a <ulink url="../xml/filetemp.patch">patch file</ulink>. - </para> - - <programlisting><![CDATA[--- File/Temp.pm.orig Thu Feb 6 16:26:00 2003 -+++ File/Temp.pm Thu Feb 6 16:26:23 2003 -@@ -205,6 +205,7 @@ - # eg CGI::Carp - local $SIG{__DIE__} = sub {}; - local $SIG{__WARN__} = sub {}; -+ local *CORE::GLOBAL::die = sub {}; - $bit = &$func(); - 1; - }; -@@ -226,6 +227,7 @@ - # eg CGI::Carp - local $SIG{__DIE__} = sub {}; - local $SIG{__WARN__} = sub {}; -+ local *CORE::GLOBAL::die = sub {}; - $bit = &$func(); - 1; - };]]></programlisting> - </section> - <section id="trbl-relogin-everyone"> <title>Everybody is constantly being forced to relogin</title> diff --git a/docs/xml/using.xml b/docs/xml/using.xml index c4901bec7..dbfed056a 100644 --- a/docs/xml/using.xml +++ b/docs/xml/using.xml @@ -26,39 +26,80 @@ <orderedlist> <listitem> - <para>Click the - <quote>Open a new Bugzilla account</quote> + <para> + On the home page <filename>index.cgi</filename>, click the + <quote>Open a new Bugzilla account</quote> link, or the + <quote>New Account</quote> link available in the footer of pages. + Now enter your email address, then click the <quote>Send</quote> + button. + </para> - link, enter your email address and, optionally, your name in the - spaces provided, then click - <quote>Create Account</quote> + <note> + <para> + If none of these links is available, this means that the + administrator of the installation has disabled self-registration. + This means that only an administrator can create accounts + for other users. One reason could be that this installation is + private. + </para> + </note> - .</para> + <note> + <para> + Also, if only some users are allowed to create an account on + the installation, you may see these links but your registration + may fail if your email address doesn't match the ones accepted + by the installation. This is another way to restrict who can + access and edit bugs in this installation. + </para> + </note> + </listitem> + + <listitem> + <para> + Within moments, and if your registration is accepted, you should + receive an email to the address you provided, which contains your + login name (generally the same as the email address), and two URLs + with a token (a random string generated by the installation) to + confirm, respectively cancel, your registration. This is a way to + prevent users from abusing the generation of user accounts, for + instance by entering inexistent email addresses, or email addresses + which do not belong to them. + </para> </listitem> <listitem> - <para>Within moments, you should receive an email to the address - you provided, which contains your login name (generally the - same as the email address), and a password. - This password is randomly generated, but can be - changed to something more memorable.</para> + <para> + By default, you have 3 days to confirm your registration. Past this + timeframe, the token is invalidated and the registration is + automatically canceled. You can also cancel this registration sooner + by using the appropriate URL in the email you got. + </para> </listitem> <listitem> - <para>Click the - <quote>Log In</quote> - link in the footer at the bottom of the page in your browser, - enter your email address and password into the spaces provided, and - click - <quote>Login</quote>. + <para> + If you confirm your registration, Bugzilla will ask you your real name + (optional, but recommended) and your password, which must be between + 3 and 16 characters long. </para> + </listitem> + <listitem> + <para> + Now all you need to do is to click the <quote>Log In</quote> + link in the footer at the bottom of the page in your browser, + enter your email address and password you just chose into the + login form, and click the <quote>Log in</quote> button. + </para> </listitem> </orderedlist> - <para>You are now logged in. Bugzilla uses cookies to remember you are - logged in so, unless you have cookies disabled or your IP address changes, - you should not have to log in again.</para> + <para> + You are now logged in. Bugzilla uses cookies to remember you are + logged in so, unless you have cookies disabled or your IP address changes, + you should not have to log in again during your session. + </para> </section> <section id="bug_page"> @@ -202,7 +243,7 @@ <listitem> <para> <emphasis>Priority:</emphasis> - The bug assignee uses this field to prioritize his or her bugs. + The bug assignee uses this field to prioritise his or her bugs. It's a good idea not to change this on other people's bugs.</para> </listitem> @@ -287,8 +328,7 @@ You can attach files (e.g. testcases or patches) to bugs. If there are any attachments, they are listed in this section. Attachments are normally stored in the Bugzilla database, unless they are marked as - Big Files, which are stored directly on disk and (unlike attachments - kept in the database) may be deleted at some future time. + Big Files, which are stored directly on disk. </para> </listitem> @@ -351,8 +391,20 @@ returns bugs where the content of the field matches any one of the selected values. If none is selected, then the field can take any value.</para> - <para>Once you've run a search, you can save it as a Saved Search, which - appears in the page footer.</para> + <para> + Once you've run a search, you can save it as a Saved Search, which + appears in the page footer. + On the Saved Searches tab of your User Preferences page (the Prefs link + in Bugzilla's footer), members of the group defined in the + querysharegroup parameter can share such Saved Searches with user groups + so that other users may use them. + At the same place, you can see Saved Searches other users are sharing, and + have them show up in your personal Bugzilla footer along with your own + Saved Searches. + If somebody is sharing a Search with a group she or he is allowed to + <link linkend="groups">assign users to</link>, it will show up in the + group's direct members' footers by default. + </para> <section id="boolean"> <title>Boolean Charts</title> @@ -605,28 +657,31 @@ </section> <section id="individual-buglists"> - <title>Adding individual bugs from bug lists</title> + <title>Adding/removing tags to/from bugs</title> <para> - You can at any time add individual bugs to a special type - of saved searches, known as <quote>lists of bugs</quote>. The distinction - between both types is that saved searches, as described in the previous - section, are stored in the form of a list of matching criteria, while - a list of bugs is an enumerated list of bug numbers. As it is a simple - list of bug numbers, you can easily edit this list by adding - bugs to it. To enable this feature, you have to turn on the - <quote>Add individual bugs to saved searches</quote> user preference, - see <xref linkend="userpreferences" />. + You can add and remove tags from individual bugs, which let you find and + manage them more easily. Creating a new tag automatically generates a saved + search - whose name is the name of the tag - which lists bugs with this tag. + This saved search will be displayed in the footer of pages by default, as + all other saved searches. The main difference between tags and normal saved + searches is that saved searches, as described in the previous section, are + stored in the form of a list of matching criteria, while the saved search + generated by tags is a list of bug numbers. Consequently, you can easily + edit this list by either adding or removing tags from bugs. To enable this + feature, you have to turn on the <quote>Enable tags for bugs</quote> user + preference, see <xref linkend="userpreferences" />. This feature is disabled + by default. </para> <para> This feature is useful when you want to keep track of several bugs, but for different reasons. Instead of adding yourself to the CC list of all these bugs and mixing all these reasons, you can now store these bugs in - different lists, e.g. <quote>Bugs I want to see fixed before the next - release</quote>, <quote>Interesting bugs</quote>, or <quote>Bugs I have - to think about</quote>. One big advantage of this way to manage bug lists - is that you can easily add bugs one by one, which is not possible to do - with saved searches without having to edit the search criteria again. + separate lists, e.g. <quote>Keep in mind</quote>, <quote>Interesting bugs</quote>, + or <quote>Triage</quote>. One big advantage of this way to manage bugs + is that you can easily add or remove bugs one by one, which is not + possible to do with saved searches without having to edit the search + criteria again. </para> </section> </section> @@ -636,7 +691,7 @@ <section id="fillingbugs"> <title>Reporting a New Bug</title> - + <para>Years of bug writing experience has been distilled for your reading pleasure into the <ulink @@ -674,7 +729,7 @@ </para> </listitem> - <listitem> + <listitem> <para> You now see a form where you can specify the component (part of the product which is affected by the bug you discovered; if you have @@ -709,6 +764,23 @@ </note> </listitem> + <listitem> + <para> + As you file the bug, you can also attach a document (testcase, patch, + or screenshot of the problem). + </para> + </listitem> + + <listitem> + <para> + Depending on the Bugzilla installation you are using and the product in + which you are filing the bug, you can also request developers to consider + your bug in different ways (such as requesting review for the patch you + just attached, requesting your bug to block the next release of the + product, and many other product specific requests). + </para> + </listitem> + <listitem> <para> Now is a good time to read your bug report again. Remove all misspellings, @@ -776,12 +848,16 @@ <para> If you have a really large attachment, something that does not need to - be recorded forever (as most attachments are), you can mark your - attachment as a <quote>Big File</quote>, assuming the administrator of the - installation has enabled this feature. Big Files are stored directly on - disk instead of in the database, and can be deleted when it is no longer - needed. The maximum size of a <quote>Big File</quote> is normally larger - than the maximum size of a regular attachment. + be recorded forever (as most attachments are), or something that is too + big for your database, you can mark your attachment as a + <quote>Big File</quote>, assuming the administrator of the installation + has enabled this feature. Big Files are stored directly on disk instead + of in the database. The maximum size of a <quote>Big File</quote> is + normally larger than the maximum size of a regular attachment. Independently + of the storage system used, an administrator can delete these attachments + at any time. Nevertheless, if these files are stored in the database, the + <quote>allow_attachment_deletion</quote> parameter (which is turned off + by default) must be enabled in order to delete them. </para> <para> @@ -988,7 +1064,7 @@ <section id="userpreferences"> <title>User Preferences</title> - <para>Once you have logged in, you can customize various aspects of + <para>Once you have logged in, you can customise various aspects of Bugzilla via the "Edit prefs" link in the page footer. The preferences are split into three tabs:</para> @@ -1500,7 +1576,7 @@ <para> The next step is to specify when the Event is to be run (the Schedule) - and what searches are to be performed (the Queries). + and what searches are to be performed (the Searches). </para> </section> @@ -1562,21 +1638,21 @@ </section> <section id="whining-query"> - <title>Whining Queries</title> + <title>Whining Searches</title> <para> - Each whining event is associated with zero or more queries. A query is - a saved search that is executed on the schedule specified (see above). - You start out with zero queries attached to the event (which means that - the event will not run, as there will never be any results to return). - To add a query, press the "Add a new query" button. + Each whining event is associated with zero or more searches. A search + is any saved search to be run as part of the specified schedule (see + above). You start out without any searches associated with the event + (which means that the event will not run, as there will never be any + results to return). To add a search, press the "Include search" button. </para> <para> - The first field to examine in your new query is the Sort field. Queries - are executed, and results returned, in the order specified by the Sort - field. Queries with lower Sort values will run before queries with - higher Sort values. + The first field to examine in your newly added search is the Sort field. + Searches are run, and results included, in the order specified by the + Sort field. Searches with smaller Sort values will run before searches + with bigger Sort values. </para> <para> diff --git a/duplicates.cgi b/duplicates.cgi index 9eb60c6ac..94b35df97 100755 --- a/duplicates.cgi +++ b/duplicates.cgi @@ -29,12 +29,12 @@ use AnyDBM_File; use lib qw(.); -require "globals.pl"; - use Bugzilla; -use Bugzilla::Search; -use Bugzilla::Config qw(:DEFAULT $datadir); use Bugzilla::Constants; +use Bugzilla::Util; +use Bugzilla::Error; +use Bugzilla::Search; +use Bugzilla::Product; my $cgi = Bugzilla->cgi; @@ -53,8 +53,6 @@ if (defined $cgi->param('ctype') && $cgi->param('ctype') eq "xul") { my $template = Bugzilla->template; my $vars = {}; -GetVersionTable(); - # collectstats.pl uses duplicates.cgi to generate the RDF duplicates stats. # However, this conflicts with requirelogin if it's enabled; so we make # logging-in optional if we are running from the command line. @@ -67,8 +65,6 @@ else { my $dbh = Bugzilla->switch_to_shadow_db(); -use vars qw (@legal_product); - my %dbmcount; my %count; my %before; @@ -76,7 +72,7 @@ my %before; # Get params from URL sub formvalue { my ($name, $default) = (@_); - return $cgi->param($name) || $default || ""; + return Bugzilla->cgi->param($name) || $default || ""; } my $sortby = formvalue("sortby"); @@ -88,13 +84,9 @@ my @query_products = $cgi->param('product'); my $sortvisible = formvalue("sortvisible"); my @buglist = (split(/[:,]/, formvalue("bug_id"))); -my $product_id; +# Make sure all products are valid. foreach my $p (@query_products) { - $product_id = get_product_id($p); - if (!$product_id) { - ThrowUserError("invalid_product_name", - { product => $p }); - } + Bugzilla::Product::check_product($p); } # Small backwards-compatibility hack, dated 2002-04-10. @@ -113,6 +105,8 @@ my $yesterday = days_ago(1); use Errno; use Fcntl; +my $datadir = bz_locations()->{'datadir'}; + if (!tie(%dbmcount, 'AnyDBM_File', "$datadir/duplicates/dupes$today", O_RDONLY, 0644)) { if ($!{ENOENT}) { @@ -137,7 +131,7 @@ if (!tie(%dbmcount, 'AnyDBM_File', "$datadir/duplicates/dupes$today", # Remove all those dupes under the threshold parameter. # We do this, before the sorting, for performance reasons. -my $threshold = Param("mostfreqthreshold"); +my $threshold = Bugzilla->params->{"mostfreqthreshold"}; while (my ($key, $value) = each %count) { delete $count{$key} if ($value < $threshold); diff --git a/editclassifications.cgi b/editclassifications.cgi index ac4ed9fea..0ebfb97fa 100755 --- a/editclassifications.cgi +++ b/editclassifications.cgi @@ -27,19 +27,18 @@ use Bugzilla; use Bugzilla::Constants; use Bugzilla::Util; use Bugzilla::Error; -use Bugzilla::Config qw($datadir); use Bugzilla::Classification; use Bugzilla::Token; -require "globals.pl"; - -my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; +my $cgi = Bugzilla->cgi; my $template = Bugzilla->template; -my $vars = {}; +local our $vars = {}; sub LoadTemplate { my $action = shift; + my $cgi = Bugzilla->cgi; + my $template = Bugzilla->template; $action =~ /(\w+)/; $action = $1; @@ -62,7 +61,8 @@ exists Bugzilla->user->groups->{'editclassifications'} action => "edit", object => "classifications"}); -ThrowUserError("auth_classification_not_enabled") unless Param("useclassification"); +ThrowUserError("auth_classification_not_enabled") + unless Bugzilla->params->{"useclassification"}; # # often used variables @@ -100,6 +100,7 @@ if ($action eq 'add') { if ($action eq 'new') { check_token_data($token, 'add_classification'); + $class_name || ThrowUserError("classification_not_specified"); my $classification = @@ -109,19 +110,24 @@ if ($action eq 'new') { ThrowUserError("classification_already_exists", { name => $classification->name }); } - + my $description = trim($cgi->param('description') || ''); + + my $sortkey = trim($cgi->param('sortkey') || 0); + my $stored_sortkey = $sortkey; + detaint_natural($sortkey) + || ThrowUserError('classification_invalid_sortkey', {'name' => $class_name, + 'sortkey' => $stored_sortkey}); + trick_taint($description); trick_taint($class_name); # Add the new classification. - $dbh->do("INSERT INTO classifications (name, description) - VALUES (?, ?)", undef, ($class_name, $description)); - - # Make versioncache flush - unlink "$datadir/versioncache"; + $dbh->do("INSERT INTO classifications (name, description, sortkey) + VALUES (?, ?, ?)", undef, ($class_name, $description, $sortkey)); $vars->{'classification'} = $class_name; + delete_token($token); LoadTemplate($action); } @@ -147,6 +153,7 @@ if ($action eq 'del') { $vars->{'classification'} = $classification; $vars->{'token'} = issue_session_token('delete_classification'); + LoadTemplate($action); } @@ -156,6 +163,7 @@ if ($action eq 'del') { if ($action eq 'delete') { check_token_data($token, 'delete_classification'); + my $classification = Bugzilla::Classification::check_classification($class_name); @@ -176,9 +184,8 @@ if ($action eq 'delete') { $dbh->bz_unlock_tables(); - unlink "$datadir/versioncache"; - $vars->{'classification'} = $classification; + delete_token($token); LoadTemplate($action); } @@ -196,6 +203,7 @@ if ($action eq 'edit') { $vars->{'classification'} = $classification; $vars->{'token'} = issue_session_token('edit_classification'); + LoadTemplate($action); } @@ -205,14 +213,22 @@ if ($action eq 'edit') { if ($action eq 'update') { check_token_data($token, 'edit_classification'); + $class_name || ThrowUserError("classification_not_specified"); my $class_old_name = trim($cgi->param('classificationold') || ''); - my $description = trim($cgi->param('description') || ''); my $class_old = Bugzilla::Classification::check_classification($class_old_name); + my $description = trim($cgi->param('description') || ''); + + my $sortkey = trim($cgi->param('sortkey') || 0); + my $stored_sortkey = $sortkey; + detaint_natural($sortkey) + || ThrowUserError('classification_invalid_sortkey', {'name' => $class_old->name, + 'sortkey' => $stored_sortkey}); + $dbh->bz_lock_tables('classifications WRITE'); if ($class_name ne $class_old->name) { @@ -225,10 +241,8 @@ if ($action eq 'update') { trick_taint($class_name); $dbh->do("UPDATE classifications SET name = ? WHERE id = ?", undef, ($class_name, $class_old->id)); - - $vars->{'updated_classification'} = 1; - unlink "$datadir/versioncache"; + $vars->{'updated_classification'} = 1; } if ($description ne $class_old->description) { @@ -238,11 +252,18 @@ if ($action eq 'update') { ($description, $class_old->id)); $vars->{'updated_description'} = 1; + } + + if ($sortkey ne $class_old->sortkey) { + $dbh->do("UPDATE classifications SET sortkey = ? + WHERE id = ?", undef, + ($sortkey, $class_old->id)); - unlink "$datadir/versioncache"; + $vars->{'updated_sortkey'} = 1; } $dbh->bz_unlock_tables(); + delete_token($token); LoadTemplate($action); } @@ -284,6 +305,7 @@ if ($action eq 'reclassify') { $vars->{'classifications'} = \@classifications; $vars->{'classification'} = $classification; $vars->{'token'} = issue_session_token('reclassify_classifications'); + LoadTemplate($action); } diff --git a/editcomponents.cgi b/editcomponents.cgi index 70ead70a7..f28a87b7a 100755 --- a/editcomponents.cgi +++ b/editcomponents.cgi @@ -21,6 +21,7 @@ # Contributor(s): Holger Schurig <holgerschurig@nikocity.de> # Terry Weissman <terry@mozilla.org> # Frédéric Buclin <LpSolit@gmail.com> +# Akamai Technologies <bugzilla-dev@akamai.com> # # Direct any questions on this source code to # @@ -29,18 +30,36 @@ use strict; use lib "."; -require "globals.pl"; - +use Bugzilla; use Bugzilla::Constants; -use Bugzilla::Config qw(:DEFAULT $datadir); use Bugzilla::Series; use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::User; -use Bugzilla::Product; use Bugzilla::Component; use Bugzilla::Bug; use Bugzilla::Token; +############### +# Subroutines # +############### + +# Takes an arrayref of login names and returns an arrayref of user ids. +sub check_initial_cc { + my ($user_names) = @_; + + my %cc_ids; + foreach my $cc (@$user_names) { + my $id = login_to_id($cc, THROW_ERROR); + $cc_ids{$id} = 1; + } + return [keys %cc_ids]; +} + +############### +# Main Script # +############### + my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; my $template = Bugzilla->template; @@ -56,6 +75,7 @@ my $whoid = $user->id; print $cgi->header(); $user->in_group('editcomponents') + || scalar(@{$user->get_products_by_permission('editcomponents')}) || ThrowUserError("auth_failure", {group => "editcomponents", action => "edit", object => "components"}); @@ -74,7 +94,13 @@ my $token = $cgi->param('token'); # unless ($product_name) { - $vars->{'products'} = $user->get_selectable_products; + my $selectable_products = $user->get_selectable_products; + # If the user has editcomponents privs for some products only, + # we have to restrict the list of products to display. + unless ($user->in_group('editcomponents')) { + $selectable_products = $user->get_products_by_permission('editcomponents'); + } + $vars->{'products'} = $selectable_products; $vars->{'showbugcounts'} = $showbugcounts; $template->process("admin/components/select-product.html.tmpl", $vars) @@ -82,13 +108,7 @@ unless ($product_name) { exit; } -# First make sure the product name is valid. -my $product = Bugzilla::Product::check_product($product_name); - -# Then make sure the user is allowed to edit properties of this product. -$user->can_see_product($product->name) - || ThrowUserError('product_access_denied', {product => $product->name}); - +my $product = $user->check_can_admin_product($product_name); # # action='' -> Show nice list of components @@ -97,8 +117,7 @@ $user->can_see_product($product->name) unless ($action) { $vars->{'showbugcounts'} = $showbugcounts; - $vars->{'product'} = $product->name; - $vars->{'components'} = $product->components; + $vars->{'product'} = $product; $template->process("admin/components/list.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -114,7 +133,7 @@ unless ($action) { if ($action eq 'add') { $vars->{'token'} = issue_session_token('add_component'); - $vars->{'product'} = $product->name; + $vars->{'product'} = $product; $template->process("admin/components/create.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -133,11 +152,13 @@ if ($action eq 'new') { Bugzilla::User::match_field ($cgi, { 'initialowner' => { 'type' => 'single' }, 'initialqacontact' => { 'type' => 'single' }, + 'initialcc' => { 'type' => 'multi' }, }); my $default_assignee = trim($cgi->param('initialowner') || ''); my $default_qa_contact = trim($cgi->param('initialqacontact') || ''); my $description = trim($cgi->param('description') || ''); + my @initial_cc = $cgi->param('initialcc'); $comp_name || ThrowUserError('component_blank_name'); @@ -147,7 +168,7 @@ if ($action eq 'new') { } my $component = - new Bugzilla::Component({product_id => $product->id, + new Bugzilla::Component({product => $product, name => $comp_name}); if ($component) { @@ -162,12 +183,16 @@ if ($action eq 'new') { {name => $comp_name}); my $default_assignee_id = login_to_id($default_assignee); - my $default_qa_contact_id = Param('useqacontact') ? + my $default_qa_contact_id = Bugzilla->params->{'useqacontact'} ? (login_to_id($default_qa_contact) || undef) : undef; + my $initial_cc_ids = check_initial_cc(\@initial_cc); + trick_taint($comp_name); trick_taint($description); + $dbh->bz_lock_tables('components WRITE', 'component_cc WRITE'); + $dbh->do("INSERT INTO components (product_id, name, description, initialowner, initialqacontact) @@ -175,10 +200,19 @@ if ($action eq 'new') { ($product->id, $comp_name, $description, $default_assignee_id, $default_qa_contact_id)); + $component = new Bugzilla::Component({ product => $product, + name => $comp_name }); + + my $sth = $dbh->prepare("INSERT INTO component_cc + (user_id, component_id) VALUES (?, ?)"); + foreach my $user_id (@$initial_cc_ids) { + $sth->execute($user_id, $component->id); + } + + $dbh->bz_unlock_tables; + # Insert default charting queries for this product. # If they aren't using charting, this won't do any harm. - GetVersionTable(); - my @series; my $prodcomp = "&product=" . url_quote($product->name) . @@ -210,12 +244,10 @@ if ($action eq 'new') { $series->writeToDatabase(); } - # Make versioncache flush - unlink "$datadir/versioncache"; - - $vars->{'name'} = $comp_name; - $vars->{'product'} = $product->name; + $vars->{'comp'} = $component; + $vars->{'product'} = $product; delete_token($token); + $template->process("admin/components/created.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -236,7 +268,7 @@ if ($action eq 'del') { $vars->{'comp'} = Bugzilla::Component::check_component($product, $comp_name); - $vars->{'prod'} = $product; + $vars->{'product'} = $product; $template->process("admin/components/confirm-delete.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -256,9 +288,11 @@ if ($action eq 'delete') { Bugzilla::Component::check_component($product, $comp_name); if ($component->bug_count) { - if (Param("allowbugdeletion")) { + if (Bugzilla->params->{"allowbugdeletion"}) { foreach my $bug_id (@{$component->bug_ids}) { - my $bug = new Bugzilla::Bug($bug_id, $whoid); + # Note: We allow admins to delete bugs even if they can't + # see them, as long as they can see the product. + my $bug = new Bugzilla::Bug($bug_id); $bug->remove_from_db(); } } else { @@ -266,26 +300,25 @@ if ($action eq 'delete') { {nb => $component->bug_count }); } } - - $vars->{'deleted_bug_count'} = $component->bug_count; - - $dbh->bz_lock_tables('components WRITE', 'flaginclusions WRITE', - 'flagexclusions WRITE'); + + $dbh->bz_lock_tables('components WRITE', 'component_cc WRITE', + 'flaginclusions WRITE', 'flagexclusions WRITE'); $dbh->do("DELETE FROM flaginclusions WHERE component_id = ?", undef, $component->id); $dbh->do("DELETE FROM flagexclusions WHERE component_id = ?", undef, $component->id); + $dbh->do("DELETE FROM component_cc WHERE component_id = ?", + undef, $component->id); $dbh->do("DELETE FROM components WHERE id = ?", undef, $component->id); $dbh->bz_unlock_tables(); - unlink "$datadir/versioncache"; - - $vars->{'name'} = $component->name; - $vars->{'product'} = $product->name; + $vars->{'comp'} = $component; + $vars->{'product'} = $product; delete_token($token); + $template->process("admin/components/deleted.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; @@ -301,10 +334,14 @@ if ($action eq 'delete') { if ($action eq 'edit') { $vars->{'token'} = issue_session_token('edit_component'); - $vars->{'comp'} = + my $component = Bugzilla::Component::check_component($product, $comp_name); + $vars->{'comp'} = $component; + + $vars->{'initial_cc_names'} = + join(', ', map($_->login, @{$component->initial_cc})); - $vars->{'prod'} = $product; + $vars->{'product'} = $product; $template->process("admin/components/edit.html.tmpl", $vars) @@ -325,12 +362,14 @@ if ($action eq 'update') { Bugzilla::User::match_field ($cgi, { 'initialowner' => { 'type' => 'single' }, 'initialqacontact' => { 'type' => 'single' }, + 'initialcc' => { 'type' => 'multi' }, }); my $comp_old_name = trim($cgi->param('componentold') || ''); my $default_assignee = trim($cgi->param('initialowner') || ''); my $default_qa_contact = trim($cgi->param('initialqacontact') || ''); my $description = trim($cgi->param('description') || ''); + my @initial_cc = $cgi->param('initialcc'); my $component_old = Bugzilla::Component::check_component($product, $comp_old_name); @@ -344,7 +383,7 @@ if ($action eq 'update') { if ($comp_name ne $component_old->name) { my $component = - new Bugzilla::Component({product_id => $product->id, + new Bugzilla::Component({product => $product, name => $comp_name}); if ($component) { ThrowUserError('component_already_exists', @@ -361,7 +400,9 @@ if ($action eq 'update') { my $default_assignee_id = login_to_id($default_assignee); my $default_qa_contact_id = login_to_id($default_qa_contact) || undef; - $dbh->bz_lock_tables('components WRITE', 'products READ', + my $initial_cc_ids = check_initial_cc(\@initial_cc); + + $dbh->bz_lock_tables('components WRITE', 'component_cc WRITE', 'profiles READ'); if ($comp_name ne $component_old->name) { @@ -370,7 +411,6 @@ if ($action eq 'update') { $dbh->do("UPDATE components SET name = ? WHERE id = ?", undef, ($comp_name, $component_old->id)); - unlink "$datadir/versioncache"; $vars->{'updated_name'} = 1; } @@ -382,7 +422,6 @@ if ($action eq 'update') { undef, ($description, $component_old->id)); $vars->{'updated_description'} = 1; - $vars->{'description'} = $description; } if ($default_assignee ne $component_old->default_assignee->login) { @@ -391,25 +430,43 @@ if ($action eq 'update') { undef, ($default_assignee_id, $component_old->id)); $vars->{'updated_initialowner'} = 1; - $vars->{'initialowner'} = $default_assignee; - } - if (Param('useqacontact') + if (Bugzilla->params->{'useqacontact'} && $default_qa_contact ne $component_old->default_qa_contact->login) { $dbh->do("UPDATE components SET initialqacontact = ? WHERE id = ?", undef, ($default_qa_contact_id, $component_old->id)); $vars->{'updated_initialqacontact'} = 1; - $vars->{'initialqacontact'} = $default_qa_contact; + } + + my @initial_cc_old = map($_->id, @{$component_old->initial_cc}); + my ($removed, $added) = diff_arrays(\@initial_cc_old, $initial_cc_ids); + + foreach my $user_id (@$removed) { + $dbh->do('DELETE FROM component_cc + WHERE component_id = ? AND user_id = ?', undef, + $component_old->id, $user_id); + $vars->{'updated_initialcc'} = 1; + } + + foreach my $user_id (@$added) { + $dbh->do("INSERT INTO component_cc (user_id, component_id) + VALUES (?, ?)", undef, $user_id, $component_old->id); + $vars->{'updated_initialcc'} = 1; } $dbh->bz_unlock_tables(); - $vars->{'name'} = $comp_name; - $vars->{'product'} = $product->name; + my $component = new Bugzilla::Component($component_old->id); + + $vars->{'comp'} = $component; + $vars->{'initial_cc_names'} = + join(', ', map($_->login, @{$component->initial_cc})); + $vars->{'product'} = $product; delete_token($token); + $template->process("admin/components/updated.html.tmpl", $vars) || ThrowTemplateError($template->error()); diff --git a/editfields.cgi b/editfields.cgi new file mode 100644 index 000000000..e57e1952c --- /dev/null +++ b/editfields.cgi @@ -0,0 +1,122 @@ +#!/usr/bin/perl -wT +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + +use strict; +use lib "."; + +use Bugzilla; +use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::Util; +use Bugzilla::Field; +use Bugzilla::Token; + +my $cgi = Bugzilla->cgi; +my $template = Bugzilla->template; +my $vars = {}; + +# Make sure the user is logged in and is an administrator. +my $user = Bugzilla->login(LOGIN_REQUIRED); +$user->in_group('admin') + || ThrowUserError('auth_failure', {group => 'admin', + action => 'edit', + object => 'custom_fields'}); + +my $action = trim($cgi->param('action') || ''); +my $token = $cgi->param('token'); + +print $cgi->header(); + +# List all existing custom fields if no action is given. +if (!$action) { + $template->process('admin/custom_fields/list.html.tmpl', $vars) + || ThrowTemplateError($template->error()); +} +# Interface to add a new custom field. +elsif ($action eq 'add') { + $vars->{'token'} = issue_session_token('add_field'); + + $template->process('admin/custom_fields/create.html.tmpl', $vars) + || ThrowTemplateError($template->error()); +} +elsif ($action eq 'new') { + check_token_data($token, 'add_field'); + + $vars->{'field'} = Bugzilla::Field->create({ + name => scalar $cgi->param('name'), + description => scalar $cgi->param('desc'), + type => scalar $cgi->param('type'), + sortkey => scalar $cgi->param('sortkey'), + mailhead => scalar $cgi->param('new_bugmail'), + enter_bug => scalar $cgi->param('enter_bug'), + obsolete => scalar $cgi->param('obsolete'), + custom => 1, + }); + + delete_token($token); + + $vars->{'message'} = 'custom_field_created'; + + $template->process('admin/custom_fields/list.html.tmpl', $vars) + || ThrowTemplateError($template->error()); +} +elsif ($action eq 'edit') { + my $name = $cgi->param('name') || ThrowUserError('field_missing_name'); + # Custom field names must start with "cf_". + if ($name !~ /^cf_/) { + $name = 'cf_' . $name; + } + my $field = new Bugzilla::Field({'name' => $name}); + $field || ThrowUserError('customfield_nonexistent', {'name' => $name}); + + $vars->{'field'} = $field; + $vars->{'token'} = issue_session_token('edit_field'); + + $template->process('admin/custom_fields/edit.html.tmpl', $vars) + || ThrowTemplateError($template->error()); +} +elsif ($action eq 'update') { + check_token_data($token, 'edit_field'); + my $name = $cgi->param('name'); + + # Validate fields. + $name || ThrowUserError('field_missing_name'); + # Custom field names must start with "cf_". + if ($name !~ /^cf_/) { + $name = 'cf_' . $name; + } + my $field = new Bugzilla::Field({'name' => $name}); + $field || ThrowUserError('customfield_nonexistent', {'name' => $name}); + + $field->set_description($cgi->param('desc')); + $field->set_sortkey($cgi->param('sortkey')); + $field->set_in_new_bugmail($cgi->param('new_bugmail')); + $field->set_enter_bug($cgi->param('enter_bug')); + $field->set_obsolete($cgi->param('obsolete')); + $field->update(); + + delete_token($token); + + $vars->{'field'} = $field; + $vars->{'message'} = 'custom_field_updated'; + + $template->process('admin/custom_fields/list.html.tmpl', $vars) + || ThrowTemplateError($template->error()); +} +else { + ThrowUserError('no_valid_action', {'field' => 'custom_field'}); +} diff --git a/editflagtypes.cgi b/editflagtypes.cgi index 6ed20c47c..0aec0385d 100755 --- a/editflagtypes.cgi +++ b/editflagtypes.cgi @@ -19,6 +19,7 @@ # Rights Reserved. # # Contributor(s): Myk Melez <myk@mozilla.org> +# Frédéric Buclin <LpSolit@gmail.com> ################################################################################ # Script Initialization @@ -28,9 +29,6 @@ use strict; use lib "."; -# Include the Bugzilla CGI and general utility library. -require "globals.pl"; - # Use Bugzilla's flag modules for handling flag types. use Bugzilla; use Bugzilla::Constants; @@ -38,10 +36,16 @@ use Bugzilla::Flag; use Bugzilla::FlagType; use Bugzilla::Group; use Bugzilla::Util; +use Bugzilla::Error; +use Bugzilla::Product; +use Bugzilla::Component; +use Bugzilla::Bug; +use Bugzilla::Attachment; use Bugzilla::Token; -my $template = Bugzilla->template; -my $vars = {}; +local our $cgi = Bugzilla->cgi; +local our $template = Bugzilla->template; +local our $vars = {}; # Make sure the user is logged in and is an administrator. my $user = Bugzilla->login(LOGIN_REQUIRED); @@ -50,13 +54,6 @@ $user->in_group('editcomponents') action => "edit", object => "flagtypes"}); -# Suppress "used only once" warnings. -use vars qw(@legal_product @legal_components %components); - -my $cgi = Bugzilla->cgi; -my $product_id; -my $component_id; - ################################################################################ # Main Body Execution ################################################################################ @@ -77,13 +74,13 @@ if (@categoryActions = grep(/^categoryAction-.+/, $cgi->param())) { } if ($action eq 'list') { list(); } -elsif ($action eq 'enter') { edit(); } -elsif ($action eq 'copy') { edit(); } -elsif ($action eq 'edit') { edit(); } +elsif ($action eq 'enter') { edit($action); } +elsif ($action eq 'copy') { edit($action); } +elsif ($action eq 'edit') { edit($action); } elsif ($action eq 'insert') { insert($token); } elsif ($action eq 'update') { update($token); } elsif ($action eq 'confirmdelete') { confirmDelete(); } -elsif ($action eq 'delete') { deleteType($token); } +elsif ($action eq 'delete') { deleteType(undef, $token); } elsif ($action eq 'deactivate') { deactivate($token); } else { ThrowCodeError("action_unrecognized", { action => $action }); @@ -96,13 +93,55 @@ exit; ################################################################################ sub list { + # Restrict the list to the given product and component, if given. + $vars = get_products_and_components($vars); + + my $product = validateProduct(scalar $cgi->param('product')); + my $component = validateComponent($product, scalar $cgi->param('component')); + my $product_id = $product ? $product->id : 0; + my $component_id = $component ? $component->id : 0; + # Define the variables and functions that will be passed to the UI template. - $vars->{'bug_types'} = - Bugzilla::FlagType::match({ 'target_type' => 'bug', - 'group' => scalar $cgi->param('group') }, 1); - $vars->{'attachment_types'} = - Bugzilla::FlagType::match({ 'target_type' => 'attachment', - 'group' => scalar $cgi->param('group') }, 1); + $vars->{'selected_product'} = $cgi->param('product'); + $vars->{'selected_component'} = $cgi->param('component'); + + my $bug_flagtypes; + my $attach_flagtypes; + + # If a component is given, restrict the list to flag types available + # for this component. + if ($component) { + $bug_flagtypes = $component->flag_types->{'bug'}; + $attach_flagtypes = $component->flag_types->{'attachment'}; + + # Filter flag types if a group ID is given. + $bug_flagtypes = filter_group($bug_flagtypes); + $attach_flagtypes = filter_group($attach_flagtypes); + + } + # If only a product is specified but no component, then restrict the list + # to flag types available in at least one component of that product. + elsif ($product) { + $bug_flagtypes = $product->flag_types->{'bug'}; + $attach_flagtypes = $product->flag_types->{'attachment'}; + + # Filter flag types if a group ID is given. + $bug_flagtypes = filter_group($bug_flagtypes); + $attach_flagtypes = filter_group($attach_flagtypes); + } + # If no product is given, then show all flag types available. + else { + $bug_flagtypes = + Bugzilla::FlagType::match({'target_type' => 'bug', + 'group' => scalar $cgi->param('group')}); + + $attach_flagtypes = + Bugzilla::FlagType::match({'target_type' => 'attachment', + 'group' => scalar $cgi->param('group')}); + } + + $vars->{'bug_types'} = $bug_flagtypes; + $vars->{'attachment_types'} = $attach_flagtypes; # Return the appropriate HTTP response headers. print $cgi->header(); @@ -114,19 +153,19 @@ sub list { sub edit { - $action eq 'enter' ? validateTargetType() : (my $id = validateID()); - my $dbh = Bugzilla->dbh; - - # Get this installation's products and components. - GetVersionTable(); - - # products and components and the function used to modify the components - # menu when the products menu changes; used by the template to populate - # the menus and keep the components menu consistent with the products menu - $vars->{'products'} = \@::legal_product; - $vars->{'components'} = \@::legal_components; - $vars->{'components_by_product'} = \%::components; - + my ($action) = @_; + + my $flag_type; + if ($action eq 'enter') { + validateTargetType(); + } + else { + $flag_type = validateID(); + } + + # Fill $vars with products and components data. + $vars = get_products_and_components($vars); + $vars->{'last_action'} = $cgi->param('action'); if ($cgi->param('action') eq 'enter' || $cgi->param('action') eq 'copy') { $vars->{'action'} = "insert"; @@ -136,20 +175,10 @@ sub edit { $vars->{'action'} = "update"; $vars->{'token'} = issue_session_token('edit_flagtype'); } - + # If copying or editing an existing flag type, retrieve it. if ($cgi->param('action') eq 'copy' || $cgi->param('action') eq 'edit') { - $vars->{'type'} = Bugzilla::FlagType::get($id); - $vars->{'type'}->{'inclusions'} = Bugzilla::FlagType::get_inclusions($id); - $vars->{'type'}->{'exclusions'} = Bugzilla::FlagType::get_exclusions($id); - # Users want to see group names, not IDs - foreach my $group ("grant_gid", "request_gid") { - my $gid = $vars->{'type'}->{$group}; - next if (!$gid); - ($vars->{'type'}->{$group}) = - $dbh->selectrow_array('SELECT name FROM groups WHERE id = ?', - undef, $gid); - } + $vars->{'type'} = $flag_type; } # Otherwise set the target type (the minimal information about the type # that the template needs to know) from the URL parameter and default @@ -161,7 +190,7 @@ sub edit { 'inclusions' => \%inclusions }; } # Get a list of groups available to restrict this flag type against. - my @groups = Bugzilla::Group::get_all_groups(); + my @groups = Bugzilla::Group->get_all; $vars->{'groups'} = \@groups; # Return the appropriate HTTP response headers. print $cgi->header(); @@ -181,15 +210,17 @@ sub processCategoryChange { my @inclusions = $cgi->param('inclusions'); my @exclusions = $cgi->param('exclusions'); if ($categoryAction eq 'include') { - validateProduct(); - validateComponent(); - my $category = ($product_id || 0) . ":" . ($component_id || 0); + my $product = validateProduct(scalar $cgi->param('product')); + my $component = validateComponent($product, scalar $cgi->param('component')); + my $category = ($product ? $product->id : 0) . ":" . + ($component ? $component->id : 0); push(@inclusions, $category) unless grep($_ eq $category, @inclusions); } elsif ($categoryAction eq 'exclude') { - validateProduct(); - validateComponent(); - my $category = ($product_id || 0) . ":" . ($component_id || 0); + my $product = validateProduct(scalar $cgi->param('product')); + my $component = validateComponent($product, scalar $cgi->param('component')); + my $category = ($product ? $product->id : 0) . ":" . + ($component ? $component->id : 0); push(@exclusions, $category) unless grep($_ eq $category, @exclusions); } elsif ($categoryAction eq 'removeInclusion') { @@ -206,19 +237,22 @@ sub processCategoryChange { my %inclusions = clusion_array_to_hash(\@inclusions); my %exclusions = clusion_array_to_hash(\@exclusions); - # Get this installation's products and components. - GetVersionTable(); + # Fill $vars with products and components data. + $vars = get_products_and_components($vars); - # products and components; used by the template to populate the menus - # and keep the components menu consistent with the products menu - $vars->{'products'} = \@::legal_product; - $vars->{'components'} = \@::legal_components; - $vars->{'components_by_product'} = \%::components; - my @groups = Bugzilla::Group::get_all_groups(); + my @groups = Bugzilla::Group->get_all; $vars->{'groups'} = \@groups; $vars->{'action'} = $cgi->param('action'); + my $type = {}; foreach my $key ($cgi->param()) { $type->{$key} = $cgi->param($key) } + # That's what I call a big hack. The template expects to see a group object. + # This script needs some rewrite anyway. + $type->{'grant_group'} = {}; + $type->{'grant_group'}->{'name'} = $cgi->param('grant_group'); + $type->{'request_group'} = {}; + $type->{'request_group'}->{'name'} = $cgi->param('request_group'); + $type->{'inclusions'} = \%inclusions; $type->{'exclusions'} = \%exclusions; $vars->{'type'} = $type; @@ -237,11 +271,21 @@ sub processCategoryChange { sub clusion_array_to_hash { my $array = shift; my %hash; + my %products; + my %components; foreach my $ids (@$array) { trick_taint($ids); my ($product_id, $component_id) = split(":", $ids); - my $product_name = get_product_name($product_id) || "__Any__"; - my $component_name = get_component_name($component_id) || "__Any__"; + my $product_name = "__Any__"; + if ($product_id) { + $products{$product_id} ||= new Bugzilla::Product($product_id); + $product_name = $products{$product_id}->name if $products{$product_id}; + } + my $component_name = "__Any__"; + if ($component_id) { + $components{$component_id} ||= new Bugzilla::Component($component_id); + $component_name = $components{$component_id}->name if $components{$component_id}; + } $hash{"$product_name:$component_name"} = $ids; } return %hash; @@ -269,22 +313,22 @@ sub insert { 'components READ', 'flaginclusions WRITE', 'flagexclusions WRITE'); - # Determine the new flag type's unique identifier. - my $id = $dbh->selectrow_array('SELECT MAX(id) FROM flagtypes') + 1; - # Insert a record for the new flag type into the database. $dbh->do('INSERT INTO flagtypes - (id, name, description, cc_list, target_type, + (name, description, cc_list, target_type, sortkey, is_active, is_requestable, is_requesteeble, is_multiplicable, grant_group_id, request_group_id) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', - undef, ($id, $name, $description, $cc_list, $target_type, + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + undef, ($name, $description, $cc_list, $target_type, $cgi->param('sortkey'), $cgi->param('is_active'), $cgi->param('is_requestable'), $cgi->param('is_requesteeble'), $cgi->param('is_multiplicable'), scalar($cgi->param('grant_gid')), scalar($cgi->param('request_gid')))); + # Get the ID of the new flag type. + my $id = $dbh->bz_last_key('flagtypes', 'id'); + # Populate the list of inclusions/exclusions for this flag type. validateAndSubmit($id); @@ -306,7 +350,8 @@ sub insert { sub update { my $token = shift; check_token_data($token, 'edit_flagtype'); - my $id = validateID(); + my $flag_type = validateID(); + my $id = $flag_type->id; my $name = validateName(); my $description = validateDescription(); my $cc_list = validateCCList(); @@ -319,6 +364,7 @@ sub update { validateGroups(); my $dbh = Bugzilla->dbh; + my $user = Bugzilla->user; $dbh->bz_lock_tables('flagtypes WRITE', 'products READ', 'components READ', 'flaginclusions WRITE', 'flagexclusions WRITE'); @@ -338,10 +384,10 @@ sub update { validateAndSubmit($id); $dbh->bz_unlock_tables(); - + # Clear existing flags for bugs/attachments in categories no longer on # the list of inclusions or that have been added to the list of exclusions. - my $flag_ids = $dbh->selectcol_arrayref('SELECT flags.id + my $flag_ids = $dbh->selectcol_arrayref('SELECT DISTINCT flags.id FROM flags INNER JOIN bugs ON flags.bug_id = bugs.bug_id @@ -352,30 +398,39 @@ sub update { AND (bugs.component_id = i.component_id OR i.component_id IS NULL)) WHERE flags.type_id = ? - AND flags.is_active = 1 AND i.type_id IS NULL', undef, $id); - foreach my $flag_id (@$flag_ids) { - Bugzilla::Flag::clear($flag_id); + my $flags = Bugzilla::Flag->new_from_list($flag_ids); + foreach my $flag (@$flags) { + my $bug = new Bugzilla::Bug($flag->bug_id); + Bugzilla::Flag::clear($flag, $bug, $flag->attachment); } - - $flag_ids = $dbh->selectcol_arrayref('SELECT flags.id + + $flag_ids = $dbh->selectcol_arrayref('SELECT DISTINCT flags.id FROM flags INNER JOIN bugs ON flags.bug_id = bugs.bug_id INNER JOIN flagexclusions AS e ON flags.type_id = e.type_id WHERE flags.type_id = ? - AND flags.is_active = 1 AND (bugs.product_id = e.product_id OR e.product_id IS NULL) AND (bugs.component_id = e.component_id OR e.component_id IS NULL)', undef, $id); - foreach my $flag_id (@$flag_ids) { - Bugzilla::Flag::clear($flag_id); + $flags = Bugzilla::Flag->new_from_list($flag_ids); + foreach my $flag (@$flags) { + my $bug = new Bugzilla::Bug($flag->bug_id); + Bugzilla::Flag::clear($flag, $bug, $flag->attachment); } - + + # Now silently remove requestees from flags which are no longer + # specifically requestable. + if (!$cgi->param('is_requesteeble')) { + $dbh->do('UPDATE flags SET requestee_id = NULL WHERE type_id = ?', + undef, $id); + } + $vars->{'name'} = $cgi->param('name'); $vars->{'message'} = "flag_type_changes_saved"; delete_token($token); @@ -389,18 +444,11 @@ sub update { } -sub confirmDelete -{ - my $id = validateID(); +sub confirmDelete { + my $flag_type = validateID(); - # check if we need confirmation to delete: - - my $count = Bugzilla::Flag::count({ 'type_id' => $id, - 'is_active' => 1 }); - - if ($count > 0) { - $vars->{'flag_type'} = Bugzilla::FlagType::get($id); - $vars->{'flag_count'} = scalar($count); + if ($flag_type->flag_count) { + $vars->{'flag_type'} = $flag_type; $vars->{'token'} = issue_session_token('delete_flagtype'); # Return the appropriate HTTP response headers. print $cgi->header(); @@ -410,25 +458,27 @@ sub confirmDelete || ThrowTemplateError($template->error()); } else { + # We should *always* ask if the admin really wants to delete + # a flagtype, even if there is no flag belonging to this type. my $token = issue_session_token('delete_flagtype'); - deleteType($token); + deleteType($flag_type, $token); } } sub deleteType { + my $flag_type = shift || validateID(); my $token = shift; check_token_data($token, 'delete_flagtype'); - my $id = validateID(); + my $id = $flag_type->id; my $dbh = Bugzilla->dbh; $dbh->bz_lock_tables('flagtypes WRITE', 'flags WRITE', 'flaginclusions WRITE', 'flagexclusions WRITE'); - + # Get the name of the flag type so we can tell users # what was deleted. - ($vars->{'name'}) = $dbh->selectrow_array('SELECT name FROM flagtypes - WHERE id = ?', undef, $id); + $vars->{'name'} = $flag_type->name; $dbh->do('DELETE FROM flags WHERE type_id = ?', undef, $id); $dbh->do('DELETE FROM flaginclusions WHERE type_id = ?', undef, $id); @@ -451,17 +501,17 @@ sub deleteType { sub deactivate { my $token = shift; check_token_data($token, 'delete_flagtype'); - my $id = validateID(); + my $flag_type = validateID(); validateIsActive(); my $dbh = Bugzilla->dbh; $dbh->bz_lock_tables('flagtypes WRITE'); - $dbh->do('UPDATE flagtypes SET is_active = 0 WHERE id = ?', undef, $id); + $dbh->do('UPDATE flagtypes SET is_active = 0 WHERE id = ?', undef, $flag_type->id); $dbh->bz_unlock_tables(); - + $vars->{'message'} = "flag_type_deactivated"; - $vars->{'flag_type'} = Bugzilla::FlagType::get($id); + $vars->{'flag_type'} = $flag_type; delete_token($token); # Return the appropriate HTTP response headers. @@ -472,26 +522,32 @@ sub deactivate { || ThrowTemplateError($template->error()); } +sub get_products_and_components { + my $vars = shift; + + my @products = Bugzilla::Product->get_all; + # We require all unique component names. + my %components; + foreach my $product (@products) { + foreach my $component (@{$product->components}) { + $components{$component->name} = 1; + } + } + $vars->{'products'} = \@products; + $vars->{'components'} = [sort(keys %components)]; + return $vars; +} ################################################################################ # Data Validation / Security Authorization ################################################################################ sub validateID { - my $dbh = Bugzilla->dbh; - # $flagtype_id is destroyed if detaint_natural fails. - my $flagtype_id = $cgi->param('id'); - detaint_natural($flagtype_id) - || ThrowCodeError("flag_type_id_invalid", - { id => scalar $cgi->param('id') }); - - my $flagtype_exists = - $dbh->selectrow_array('SELECT 1 FROM flagtypes WHERE id = ?', - undef, $flagtype_id); - $flagtype_exists - || ThrowCodeError("flag_type_nonexistent", { id => $flagtype_id }); - - return $flagtype_id; + my $id = $cgi->param('id'); + my $flag_type = new Bugzilla::FlagType($id) + || ThrowCodeError('flag_type_nonexistent', { id => $id }); + + return $flag_type; } sub validateName { @@ -535,27 +591,22 @@ sub validateCCList { } sub validateProduct { - return if !$cgi->param('product'); - - $product_id = get_product_id($cgi->param('product')); - - defined($product_id) - || ThrowCodeError("flag_type_product_nonexistent", - { product => $cgi->param('product') }); + my $product_name = shift; + return unless $product_name; + + my $product = Bugzilla::Product::check_product($product_name); + return $product; } sub validateComponent { - return if !$cgi->param('component'); - - $product_id - || ThrowCodeError("flag_type_component_without_product"); - - $component_id = get_component_id($product_id, $cgi->param('component')); + my ($product, $component_name) = @_; + return unless $component_name; + + ($product && $product->id) + || ThrowUserError("flag_type_component_without_product"); - defined($component_id) - || ThrowCodeError("flag_type_component_nonexistent", - { product => $cgi->param('product'), - name => $cgi->param('component') }); + my $component = Bugzilla::Component::check_component($product, $component_name); + return $component; } sub validateSortKey { @@ -593,18 +644,15 @@ sub validateAllowMultiple { sub validateGroups { my $dbh = Bugzilla->dbh; # Convert group names to group IDs - foreach my $col ("grant_gid", "request_gid") { - my $name = $cgi->param($col); - if ($name) { - trick_taint($name); - my $gid = $dbh->selectrow_array('SELECT id FROM groups - WHERE name = ?', undef, $name); - $gid || ThrowUserError("group_unknown", { name => $name }); - $cgi->param($col, $gid); - } - else { - $cgi->delete($col); - } + foreach my $col ('grant', 'request') { + my $name = $cgi->param($col . '_group'); + if ($name) { + trick_taint($name); + my $gid = $dbh->selectrow_array('SELECT id FROM groups + WHERE name = ?', undef, $name); + $gid || ThrowUserError("group_unknown", { name => $name }); + $cgi->param($col . '_gid', $gid); + } } } @@ -616,6 +664,8 @@ sub validateAndSubmit { my ($id) = @_; my $dbh = Bugzilla->dbh; + # Cache product objects. + my %products; foreach my $category_type ("inclusions", "exclusions") { # Will be used several times below. my $sth = $dbh->prepare("INSERT INTO flag$category_type " . @@ -626,18 +676,32 @@ sub validateAndSubmit { foreach my $category ($cgi->param($category_type)) { trick_taint($category); my ($product_id, $component_id) = split(":", $category); - # The product does not exist. - next if ($product_id && !get_product_name($product_id)); + # Does the product exist? + if ($product_id) { + $products{$product_id} ||= new Bugzilla::Product($product_id); + next unless defined $products{$product_id}; + } # A component was selected without a product being selected. next if (!$product_id && $component_id); - # The component does not belong to this product. - next if ($component_id - && !$dbh->selectrow_array("SELECT id FROM components - WHERE id = ? AND product_id = ?", - undef, ($component_id, $product_id))); + # Does the component belong to this product? + if ($component_id) { + my @match = grep {$_->id == $component_id} @{$products{$product_id}->components}; + next unless scalar(@match); + } $product_id ||= undef; $component_id ||= undef; $sth->execute($id, $product_id, $component_id); } } } + +sub filter_group { + my $flag_types = shift; + return $flag_types unless Bugzilla->cgi->param('group'); + + my $gid = scalar $cgi->param('group'); + my @flag_types = grep {($_->grant_group && $_->grant_group->id == $gid) + || ($_->request_group && $_->request_group->id == $gid)} @$flag_types; + + return \@flag_types; +} diff --git a/editgroups.cgi b/editgroups.cgi index 3d228b59b..0c49db698 100755 --- a/editgroups.cgi +++ b/editgroups.cgi @@ -24,18 +24,21 @@ # Vlad Dascalu <jocuri@softhome.net> # Frédéric Buclin <LpSolit@gmail.com> -# Code derived from editowners.cgi and editusers.cgi - use strict; use lib "."; use Bugzilla; use Bugzilla::Constants; -use Bugzilla::Config qw(:DEFAULT :admin); +use Bugzilla::Config qw(:admin); +use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::Group; +use Bugzilla::Product; use Bugzilla::User; use Bugzilla::Token; -require "globals.pl"; + +use constant SPECIAL_GROUPS => ('chartgroup', 'insidergroup', + 'timetrackinggroup', 'querysharegroup'); my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; @@ -54,36 +57,6 @@ $user->in_group('creategroups') my $action = trim($cgi->param('action') || ''); my $token = $cgi->param('token'); -# RederiveRegexp: update user_group_map with regexp-based grants -sub RederiveRegexp -{ - my $regexp = shift; - my $gid = shift; - my $dbh = Bugzilla->dbh; - my $sth = $dbh->prepare("SELECT userid, login_name, group_id - FROM profiles - LEFT JOIN user_group_map - ON user_group_map.user_id = profiles.userid - AND group_id = ? - AND grant_type = ? - AND isbless = 0"); - my $sthadd = $dbh->prepare("INSERT INTO user_group_map - (user_id, group_id, grant_type, isbless) - VALUES (?, ?, ?, 0)"); - my $sthdel = $dbh->prepare("DELETE FROM user_group_map - WHERE user_id = ? AND group_id = ? - AND grant_type = ? and isbless = 0"); - $sth->execute($gid, GRANT_REGEXP); - while (my ($uid, $login, $present) = $sth->fetchrow_array()) { - if (($regexp =~ /\S+/) && ($login =~ m/$regexp/i)) - { - $sthadd->execute($uid, $gid, GRANT_REGEXP) unless $present; - } else { - $sthdel->execute($uid, $gid, GRANT_REGEXP) if $present; - } - } -} - # Add missing entries in bug_group_map for bugs created while # a mandatory group was disabled and which is now enabled again. sub fix_bug_permissions { @@ -178,7 +151,7 @@ sub CheckGroupRegexp { # If no action is specified, get a list of all groups available. unless ($action) { - my @groups = Bugzilla::Group::get_all_groups(); + my @groups = Bugzilla::Group->get_all; $vars->{'groups'} = \@groups; print $cgi->header(); @@ -294,13 +267,12 @@ if ($action eq 'new') { # Add the new group $dbh->do('INSERT INTO groups - (name, description, isbuggroup, - userregexp, isactive, last_changed) - VALUES (?, ?, 1, ?, ?, NOW())', + (name, description, isbuggroup, userregexp, isactive) + VALUES (?, ?, 1, ?, ?)', undef, ($name, $desc, $regexp, $isactive)); my $gid = $dbh->bz_last_key('groups', 'id'); - my $admin = GroupNameToId('admin'); + my $admin = Bugzilla::Group->new({name => 'admin'})->id(); # Since we created a new group, give the "admin" group all privileges # initially. my $sth = $dbh->prepare('INSERT INTO group_group_map @@ -319,7 +291,7 @@ if ($action eq 'new') { SELECT ?, products.id, 0, ?, ?, 0 FROM products', undef, ($gid, CONTROLMAPSHOWN, CONTROLMAPNA)); } - RederiveRegexp($regexp, $gid); + Bugzilla::Group::RederiveRegexp($regexp, $gid); delete_token($token); print $cgi->header(); @@ -347,8 +319,8 @@ if ($action eq 'del') { } # Groups having a special role cannot be deleted. my @special_groups; - foreach my $special_group ('chartgroup', 'insidergroup', 'timetrackinggroup') { - if ($name eq Param($special_group)) { + foreach my $special_group (SPECIAL_GROUPS) { + if ($name eq Bugzilla->params->{$special_group}) { push(@special_groups, $special_group); } } @@ -364,13 +336,19 @@ if ($action eq 'del') { WHERE group_id IN ($grouplist) AND isbless = 0 " . $dbh->sql_limit(1)) || 0; + my ($shared_queries) = + $dbh->selectrow_array('SELECT COUNT(*) + FROM namedquery_group_map + WHERE group_id = ?', + undef, $gid); + my $bug_ids = $dbh->selectcol_arrayref('SELECT bug_id FROM bug_group_map WHERE group_id = ?', undef, $gid); my $hasbugs = scalar(@$bug_ids) ? 1 : 0; my $buglist = join(',', @$bug_ids); - my $hasproduct = get_product_id($name) ? 1 : 0; + my $hasproduct = Bugzilla::Product->new({'name' => $name}) ? 1 : 0; my $hasflags = $dbh->selectrow_array('SELECT 1 FROM flagtypes WHERE grant_group_id = ? @@ -378,15 +356,16 @@ if ($action eq 'del') { $dbh->sql_limit(1), undef, ($gid, $gid)) || 0; - $vars->{'gid'} = $gid; - $vars->{'name'} = $name; - $vars->{'description'} = $desc; - $vars->{'hasusers'} = $hasusers; - $vars->{'hasbugs'} = $hasbugs; - $vars->{'hasproduct'} = $hasproduct; - $vars->{'hasflags'} = $hasflags; - $vars->{'buglist'} = $buglist; - $vars->{'token'} = issue_session_token('delete_group'); + $vars->{'gid'} = $gid; + $vars->{'name'} = $name; + $vars->{'description'} = $desc; + $vars->{'hasusers'} = $hasusers; + $vars->{'hasbugs'} = $hasbugs; + $vars->{'hasproduct'} = $hasproduct; + $vars->{'hasflags'} = $hasflags; + $vars->{'shared_queries'} = $shared_queries; + $vars->{'buglist'} = $buglist; + $vars->{'token'} = issue_session_token('delete_group'); print $cgi->header(); $template->process("admin/groups/delete.html.tmpl", $vars) @@ -413,8 +392,8 @@ if ($action eq 'delete') { } # Groups having a special role cannot be deleted. my @special_groups; - foreach my $special_group ('chartgroup', 'insidergroup', 'timetrackinggroup') { - if ($name eq Param($special_group)) { + foreach my $special_group (SPECIAL_GROUPS) { + if ($name eq Bugzilla->params->{$special_group}) { push(@special_groups, $special_group); } } @@ -444,7 +423,9 @@ if ($action eq 'delete') { $cantdelete = 1; } - if (get_product_id($name) && !defined $cgi->param('unbind')) { + if (Bugzilla::Product->new({'name' => $name}) + && !defined $cgi->param('unbind')) + { $cantdelete = 1; } @@ -468,6 +449,8 @@ if ($action eq 'delete') { $dbh->do('UPDATE flagtypes SET request_group_id = ? WHERE request_group_id = ?', undef, (undef, $gid)); + $dbh->do('DELETE FROM namedquery_group_map WHERE group_id = ?', + undef, $gid); $dbh->do('DELETE FROM user_group_map WHERE group_id = ?', undef, $gid); $dbh->do('DELETE FROM group_group_map @@ -567,9 +550,6 @@ if (($action eq 'remove_all_regexp') || ($action eq 'remove_all')) { push(@users, $user); } } - - $dbh->do('UPDATE groups SET last_changed = NOW() - WHERE id = ?', undef, $gid); $dbh->bz_unlock_tables(); $vars->{'users'} = \@users; @@ -601,7 +581,10 @@ sub doGroupChanges { $dbh->bz_lock_tables('groups WRITE', 'group_group_map WRITE', 'bug_group_map WRITE', 'user_group_map WRITE', 'group_control_map READ', 'bugs READ', 'profiles READ', - 'namedqueries READ', 'whine_queries READ'); + # Due to the way Bugzilla::Config::BugFields::get_param_list() + # works, we need to lock these tables too. + 'priority READ', 'bug_severity READ', 'rep_platform READ', + 'op_sys READ'); # Check that the given group ID and regular expression are valid. # If tests are successful, trimmed values are returned by CheckGroup*. @@ -635,13 +618,13 @@ sub doGroupChanges { # If the group is used by some parameters, we have to update # these parameters too. my $update_params = 0; - foreach my $group ('chartgroup', 'insidergroup', 'timetrackinggroup') { - if ($cgi->param('oldname') eq Param($group)) { + foreach my $group (SPECIAL_GROUPS) { + if ($cgi->param('oldname') eq Bugzilla->params->{$group}) { SetParam($group, $name); $update_params = 1; } } - WriteParams() if $update_params; + write_params() if $update_params; } if ($desc ne $cgi->param('olddesc')) { $chgs = 1; @@ -663,7 +646,7 @@ sub doGroupChanges { $chgs = 1; $dbh->do('UPDATE groups SET userregexp = ? WHERE id = ?', undef, ($regexp, $gid)); - RederiveRegexp($regexp, $gid); + Bugzilla::Group::RederiveRegexp($regexp, $gid); } my $sthInsert = $dbh->prepare('INSERT INTO group_group_map @@ -701,7 +684,7 @@ sub doGroupChanges { } my $cansee = $cgi->param("cansee-$v") || 0; - if (Param("usevisibilitygroups") + if (Bugzilla->params->{"usevisibilitygroups"} && ($cgi->param("oldcansee-$v") != $cansee)) { $chgs = 1; if ($cansee != 0) { @@ -713,12 +696,6 @@ sub doGroupChanges { } } - - if ($chgs) { - # mark the changes - $dbh->do('UPDATE groups SET last_changed = NOW() - WHERE id = ?', undef, $gid); - } $dbh->bz_unlock_tables(); return $gid, $chgs, $name, $regexp; } diff --git a/editkeywords.cgi b/editkeywords.cgi index e008cffc0..3aca22e43 100755 --- a/editkeywords.cgi +++ b/editkeywords.cgi @@ -23,11 +23,11 @@ use strict; use lib "."; -require "globals.pl"; - use Bugzilla; use Bugzilla::Constants; -use Bugzilla::Config qw(:DEFAULT $datadir); +use Bugzilla::Util; +use Bugzilla::Error; +use Bugzilla::Keyword; use Bugzilla::Token; my $cgi = Bugzilla->cgi; @@ -35,34 +35,6 @@ my $dbh = Bugzilla->dbh; my $template = Bugzilla->template; my $vars = {}; -sub Validate { - my ($name, $description) = @_; - if ($name eq "") { - ThrowUserError("keyword_blank_name"); - } - if ($name =~ /[\s,]/) { - ThrowUserError("keyword_invalid_name"); - } - if ($description eq "") { - ThrowUserError("keyword_blank_description"); - } - # It is safe to detaint these values as they are only - # used in placeholders. - trick_taint($name); - $_[0] = $name; - trick_taint($description); - $_[1] = $description; -} - -sub ValidateKeyID { - my $id = shift; - - $id = trim($id || 0); - detaint_natural($id) || ThrowCodeError('invalid_keyword_id'); - return $id; -} - - # # Preliminary checks: # @@ -76,23 +48,15 @@ $user->in_group('editkeywords') action => "edit", object => "keywords"}); -my $action = trim($cgi->param('action') || ''); -my $token = $cgi->param('token'); +my $action = trim($cgi->param('action') || ''); +my $key_id = $cgi->param('id'); +my $token = $cgi->param('token'); + $vars->{'action'} = $action; if ($action eq "") { - my @keywords; - - $vars->{'keywords'} = - $dbh->selectall_arrayref('SELECT keyworddefs.id, keyworddefs.name, - keyworddefs.description, - COUNT(keywords.bug_id) AS bug_count - FROM keyworddefs - LEFT JOIN keywords - ON keyworddefs.id = keywords.keywordid ' . - $dbh->sql_group_by('id', 'name, description') . ' - ORDER BY keyworddefs.name', {'Slice' => {}}); + $vars->{'keywords'} = Bugzilla::Keyword->get_all_with_bug_count(); print $cgi->header(); $template->process("admin/keywords/list.html.tmpl", $vars) @@ -104,6 +68,7 @@ if ($action eq "") { if ($action eq 'add') { $vars->{'token'} = issue_session_token('add_keyword'); + print $cgi->header(); $template->process("admin/keywords/create.html.tmpl", $vars) @@ -115,54 +80,19 @@ if ($action eq 'add') { # # action='new' -> add keyword entered in the 'action=add' screen # - if ($action eq 'new') { check_token_data($token, 'add_keyword'); - # Cleanups and validity checks - - my $name = trim($cgi->param('name') || ''); - my $description = trim($cgi->param('description') || ''); - - Validate($name, $description); - - my $id = $dbh->selectrow_array('SELECT id FROM keyworddefs - WHERE name = ?', undef, $name); - - if ($id) { - $vars->{'name'} = $name; - ThrowUserError("keyword_already_exists", $vars); - } - - - # Pick an unused number. Be sure to recycle numbers that may have been - # deleted in the past. This code is potentially slow, but it happens - # rarely enough, and there really aren't ever going to be that many - # keywords anyway. + my $name = $cgi->param('name') || ''; + my $desc = $cgi->param('description') || ''; - my $existing_ids = - $dbh->selectcol_arrayref('SELECT id FROM keyworddefs ORDER BY id'); + my $keyword = Bugzilla::Keyword->create( + { name => $name, description => $desc }); - my $newid = 1; - - foreach my $oldid (@$existing_ids) { - if ($oldid > $newid) { - last; - } - $newid = $oldid + 1; - } - - # Add the new keyword. - $dbh->do('INSERT INTO keyworddefs - (id, name, description) VALUES (?, ?, ?)', - undef, ($newid, $name, $description)); - - # Make versioncache flush - unlink "$datadir/versioncache"; delete_token($token); print $cgi->header(); - $vars->{'name'} = $name; + $vars->{'name'} = $keyword->name; $template->process("admin/keywords/created.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -178,33 +108,15 @@ if ($action eq 'new') { # if ($action eq 'edit') { - my $id = ValidateKeyID(scalar $cgi->param('id')); - - # get data of keyword - my ($name, $description) = - $dbh->selectrow_array('SELECT name, description FROM keyworddefs - WHERE id = ?', undef, $id); + my $keyword = new Bugzilla::Keyword($key_id) + || ThrowCodeError('invalid_keyword_id', { id => $key_id }); - if (!$name) { - $vars->{'id'} = $id; - ThrowCodeError("invalid_keyword_id", $vars); - } - - my $bugs = $dbh->selectrow_array('SELECT COUNT(*) FROM keywords - WHERE keywordid = ?', - undef, $id); - - $vars->{'keyword_id'} = $id; - $vars->{'name'} = $name; - $vars->{'description'} = $description; - $vars->{'bug_count'} = $bugs; + $vars->{'keyword'} = $keyword; $vars->{'token'} = issue_session_token('edit_keyword'); print $cgi->header(); - $template->process("admin/keywords/edit.html.tmpl", $vars) || ThrowTemplateError($template->error()); - exit; } @@ -215,31 +127,18 @@ if ($action eq 'edit') { if ($action eq 'update') { check_token_data($token, 'edit_keyword'); - my $id = ValidateKeyID(scalar $cgi->param('id')); - - my $name = trim($cgi->param('name') || ''); - my $description = trim($cgi->param('description') || ''); - - Validate($name, $description); + my $keyword = new Bugzilla::Keyword($key_id) + || ThrowCodeError('invalid_keyword_id', { id => $key_id }); - my $tmp = $dbh->selectrow_array('SELECT id FROM keyworddefs - WHERE name = ?', undef, $name); - - if ($tmp && $tmp != $id) { - $vars->{'name'} = $name; - ThrowUserError("keyword_already_exists", $vars); - } + $keyword->set_name($cgi->param('name')); + $keyword->set_description($cgi->param('description')); + $keyword->update(); - $dbh->do('UPDATE keyworddefs SET name = ?, description = ? - WHERE id = ?', undef, ($name, $description, $id)); - - # Make versioncache flush - unlink "$datadir/versioncache"; delete_token($token); print $cgi->header(); - $vars->{'name'} = $name; + $vars->{'keyword'} = $keyword; $template->process("admin/keywords/rebuild-cache.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -248,46 +147,32 @@ if ($action eq 'update') { if ($action eq 'delete') { - my $id = ValidateKeyID(scalar $cgi->param('id')); - - my $name = $dbh->selectrow_array('SELECT name FROM keyworddefs - WHERE id= ?', undef, $id); - - if (!$cgi->param('reallydelete')) { - my $bugs = $dbh->selectrow_array('SELECT COUNT(*) FROM keywords - WHERE keywordid = ?', - undef, $id); - - # We need this token even if there is no bug using this keyword. - $token = issue_session_token('delete_keyword'); + my $keyword = new Bugzilla::Keyword($key_id) + || ThrowCodeError('invalid_keyword_id', { id => $key_id }); - if ($bugs) { - $vars->{'bug_count'} = $bugs; - $vars->{'keyword_id'} = $id; - $vars->{'name'} = $name; - $vars->{'token'} = $token; + $vars->{'keyword'} = $keyword; - print $cgi->header(); + # We need this token even if there is no bug using this keyword. + $token = issue_session_token('delete_keyword'); - $template->process("admin/keywords/confirm-delete.html.tmpl", $vars) - || ThrowTemplateError($template->error()); + if (!$cgi->param('reallydelete') && $keyword->bug_count) { + $vars->{'token'} = $token; - exit; - } + print $cgi->header(); + $template->process("admin/keywords/confirm-delete.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + exit; } # We cannot do this check earlier as we have to check 'reallydelete' first. check_token_data($token, 'delete_keyword'); - $dbh->do('DELETE FROM keywords WHERE keywordid = ?', undef, $id); - $dbh->do('DELETE FROM keyworddefs WHERE id = ?', undef, $id); + $dbh->do('DELETE FROM keywords WHERE keywordid = ?', undef, $keyword->id); + $dbh->do('DELETE FROM keyworddefs WHERE id = ?', undef, $keyword->id); - # Make versioncache flush - unlink "$datadir/versioncache"; delete_token($token); print $cgi->header(); - $vars->{'name'} = $name; $template->process("admin/keywords/rebuild-cache.html.tmpl", $vars) || ThrowTemplateError($template->error()); diff --git a/editmilestones.cgi b/editmilestones.cgi index cd2ce8ab0..17733bdb1 100755 --- a/editmilestones.cgi +++ b/editmilestones.cgi @@ -6,7 +6,7 @@ # the editversions.cgi script, since the two fields were set up in a # very similar fashion. # -# (basically replace each occurance of 'milestone' with 'version', and +# (basically replace each occurrence of 'milestone' with 'version', and # you'll have the original script) # # Matt Masson <matthew@zeroknowledge.com> @@ -19,11 +19,10 @@ use strict; use lib "."; -require "globals.pl"; - +use Bugzilla; use Bugzilla::Constants; -use Bugzilla::Config qw(:DEFAULT $datadir); -use Bugzilla::Product; +use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::Milestone; use Bugzilla::Bug; use Bugzilla::Token; @@ -43,6 +42,7 @@ my $whoid = $user->id; print $cgi->header(); $user->in_group('editcomponents') + || scalar(@{$user->get_products_by_permission('editcomponents')}) || ThrowUserError("auth_failure", {group => "editcomponents", action => "edit", object => "milestones"}); @@ -62,7 +62,13 @@ my $token = $cgi->param('token'); # unless ($product_name) { - $vars->{'products'} = $user->get_selectable_products; + my $selectable_products = $user->get_selectable_products; + # If the user has editcomponents privs for some products only, + # we have to restrict the list of products to display. + unless ($user->in_group('editcomponents')) { + $selectable_products = $user->get_products_by_permission('editcomponents'); + } + $vars->{'products'} = $selectable_products; $vars->{'showbugcounts'} = $showbugcounts; $template->process("admin/milestones/select-product.html.tmpl", $vars) @@ -70,13 +76,7 @@ unless ($product_name) { exit; } -# First make sure the product name is valid. -my $product = Bugzilla::Product::check_product($product_name); - -# Then make sure the user is allowed to edit properties of this product. -$user->can_see_product($product->name) - || ThrowUserError('product_access_denied', {product => $product->name}); - +my $product = $user->check_can_admin_product($product_name); # # action='' -> Show nice list of milestones @@ -85,9 +85,7 @@ $user->can_see_product($product->name) unless ($action) { $vars->{'showbugcounts'} = $showbugcounts; - $vars->{'product'} = $product->name; - $vars->{'milestones'} = $product->milestones; - $vars->{'default_milestone'} = $product->default_milestone; + $vars->{'product'} = $product; $template->process("admin/milestones/list.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -106,7 +104,7 @@ unless ($action) { if ($action eq 'add') { $vars->{'token'} = issue_session_token('add_milestone'); - $vars->{'product'} = $product->name; + $vars->{'product'} = $product; $template->process("admin/milestones/create.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -132,8 +130,8 @@ if ($action eq 'new') { $sortkey = Bugzilla::Milestone::check_sort_key($milestone_name, $sortkey); - my $milestone = new Bugzilla::Milestone($product->id, - $milestone_name); + my $milestone = new Bugzilla::Milestone( + { product => $product, name => $milestone_name }); if ($milestone) { ThrowUserError('milestone_already_exists', @@ -147,12 +145,12 @@ if ($action eq 'new') { VALUES ( ?, ?, ? )', undef, $milestone_name, $product->id, $sortkey); - # Make versioncache flush - unlink "$datadir/versioncache"; + $milestone = new Bugzilla::Milestone( + { product => $product, name => $milestone_name }); delete_token($token); - $vars->{'name'} = $milestone_name; - $vars->{'product'} = $product->name; + $vars->{'milestone'} = $milestone; + $vars->{'product'} = $product; $template->process("admin/milestones/created.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -173,15 +171,13 @@ if ($action eq 'del') { my $milestone = Bugzilla::Milestone::check_milestone($product, $milestone_name); - $vars->{'name'} = $milestone->name; - $vars->{'product'} = $product->name; + $vars->{'milestone'} = $milestone; + $vars->{'product'} = $product; # The default milestone cannot be deleted. if ($product->default_milestone eq $milestone->name) { ThrowUserError("milestone_is_default", $vars); } - - $vars->{'bug_count'} = $milestone->bug_count; $vars->{'token'} = issue_session_token('delete_milestone'); $template->process("admin/milestones/confirm-delete.html.tmpl", $vars) @@ -200,23 +196,21 @@ if ($action eq 'delete') { my $milestone = Bugzilla::Milestone::check_milestone($product, $milestone_name); - $vars->{'name'} = $milestone->name; - $vars->{'product'} = $product->name; + $vars->{'milestone'} = $milestone; + $vars->{'product'} = $product; # The default milestone cannot be deleted. if ($milestone->name eq $product->default_milestone) { ThrowUserError("milestone_is_default", $vars); } - # We don't want to delete bugs when deleting a milestone. - # Bugs concerned are reassigned to the default milestone. - my $bug_ids = - $dbh->selectcol_arrayref("SELECT bug_id FROM bugs - WHERE product_id = ? AND target_milestone = ?", - undef, ($product->id, $milestone->name)); - - my $nb_bugs = scalar(@$bug_ids); - if ($nb_bugs) { + if ($milestone->bug_count) { + # We don't want to delete bugs when deleting a milestone. + # Bugs concerned are reassigned to the default milestone. + my $bug_ids = + $dbh->selectcol_arrayref("SELECT bug_id FROM bugs + WHERE product_id = ? AND target_milestone = ?", + undef, ($product->id, $milestone->name)); my $timestamp = $dbh->selectrow_array("SELECT NOW()"); foreach my $bug_id (@$bug_ids) { $dbh->do("UPDATE bugs SET target_milestone = ?, @@ -231,12 +225,9 @@ if ($action eq 'delete') { } } - $vars->{'bug_count'} = $nb_bugs; - $dbh->do("DELETE FROM milestones WHERE product_id = ? AND value = ?", undef, ($product->id, $milestone->name)); - unlink "$datadir/versioncache"; delete_token($token); $template->process("admin/milestones/deleted.html.tmpl", $vars) @@ -258,10 +249,9 @@ if ($action eq 'edit') { Bugzilla::Milestone::check_milestone($product, $milestone_name); - $vars->{'sortkey'} = $milestone->sortkey; - $vars->{'name'} = $milestone->name; - $vars->{'product'} = $product->name; - $vars->{'token'} = issue_session_token('edit_milestone'); + $vars->{'milestone'} = $milestone; + $vars->{'product'} = $product; + $vars->{'token'} = issue_session_token('edit_milestone'); $template->process("admin/milestones/edit.html.tmpl", $vars) @@ -304,17 +294,15 @@ if ($action eq 'update') { $product->id, $milestone_old->name); - unlink "$datadir/versioncache"; $vars->{'updated_sortkey'} = 1; - $vars->{'sortkey'} = $sortkey; } if ($milestone_name ne $milestone_old->name) { unless ($milestone_name) { ThrowUserError('milestone_blank_name'); } - my $milestone = - new Bugzilla::Milestone($product->id, $milestone_name); + my $milestone = new Bugzilla::Milestone( + { product => $product, name => $milestone_name }); if ($milestone) { ThrowUserError('milestone_already_exists', {'name' => $milestone->name, @@ -350,16 +338,18 @@ if ($action eq 'update') { $product->id, $milestone_old->name); - unlink "$datadir/versioncache"; - $vars->{'updated_name'} = 1; } $dbh->bz_unlock_tables(); + + my $milestone = + Bugzilla::Milestone::check_milestone($product, + $milestone_name); delete_token($token); - $vars->{'name'} = $milestone_name; - $vars->{'product'} = $product->name; + $vars->{'milestone'} = $milestone; + $vars->{'product'} = $product; $template->process("admin/milestones/updated.html.tmpl", $vars) || ThrowTemplateError($template->error()); diff --git a/editparams.cgi b/editparams.cgi index bd1b1f545..ca74df685 100755 --- a/editparams.cgi +++ b/editparams.cgi @@ -25,13 +25,15 @@ use strict; use lib "."; +use Bugzilla; use Bugzilla::Constants; -use Bugzilla::Config qw(:DEFAULT :admin :params $datadir); +use Bugzilla::Config qw(:admin); use Bugzilla::Config::Common; +use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::Token; - -require "globals.pl"; -use vars qw(@parampanels); +use Bugzilla::User; +use Bugzilla::User::Setting; my $user = Bugzilla->login(LOGIN_REQUIRED); my $cgi = Bugzilla->cgi; @@ -51,14 +53,11 @@ my $current_panel = $cgi->param('section') || 'core'; $current_panel =~ /^([A-Za-z0-9_-]+)$/; $current_panel = $1; -GetVersionTable(); - my $current_module; my @panels = (); -foreach my $panel (@parampanels) { - next if ($panel eq 'Common'); - require "Bugzilla/Config/$panel.pm"; - my @module_param_list = "Bugzilla::Config::${panel}"->get_param_list(); +foreach my $panel (Bugzilla::Config::param_panels()) { + eval("require Bugzilla::Config::$panel") || die $@; + my @module_param_list = "Bugzilla::Config::${panel}"->get_param_list(1); my $item = { name => lc($panel), current => ($current_panel eq lc($panel)) ? 1 : 0, param_list => \@module_param_list, @@ -73,8 +72,9 @@ $vars->{panels} = \@panels; if ($action eq 'save' && $current_module) { check_token_data($token, 'edit_parameters'); my @changes = (); - my @module_param_list = "Bugzilla::Config::${current_module}"->get_param_list(); + my @module_param_list = "Bugzilla::Config::${current_module}"->get_param_list(1); + my $update_lang_user_pref = 0; foreach my $i (@module_param_list) { my $name = $i->{'name'}; my $value = $cgi->param($name); @@ -95,7 +95,7 @@ if ($action eq 'save' && $current_module) { my $changed; if ($i->{'type'} eq 'm') { - my @old = sort @{Param($name)}; + my @old = sort @{Bugzilla->params->{$name}}; my @new = sort @$value; if (scalar(@old) != scalar(@new)) { $changed = 1; @@ -110,7 +110,7 @@ if ($action eq 'save' && $current_module) { } } } else { - $changed = ($value eq Param($name))? 0 : 1; + $changed = ($value eq Bugzilla->params->{$name})? 0 : 1; } if ($changed) { @@ -119,19 +119,39 @@ if ($action eq 'save' && $current_module) { if ($ok ne "") { ThrowUserError('invalid_parameter', { name => $name, err => $ok }); } + } elsif ($name eq 'globalwatchers') { + # can't check this as others, as Bugzilla::Config::Common + # can not use Bugzilla::User + foreach my $watcher (split(/[,\s]+/, $value)) { + ThrowUserError( + 'invalid_parameter', + { name => $name, err => "no such user $watcher" } + ) unless login_to_id($watcher); + } } push(@changes, $name); SetParam($name, $value); if (($name eq "shutdownhtml") && ($value ne "")) { $vars->{'shutdown_is_active'} = 1; } + if ($name eq 'languages') { + $update_lang_user_pref = 1; + } } } + if ($update_lang_user_pref) { + # We have to update the list of languages users can choose. + # If some users have selected a language which is no longer available, + # then we delete it (the user pref is reset to the default one). + my @languages = split(/[\s,]+/, Bugzilla->params->{'languages'}); + map {trick_taint($_)} @languages; + add_setting('lang', \@languages, Bugzilla->params->{'defaultlanguage'}, undef, 1); + } + $vars->{'message'} = 'parameters_updated'; $vars->{'param_changed'} = \@changes; - WriteParams(); - unlink "$datadir/versioncache"; + write_params(); delete_token($token); } diff --git a/editproducts.cgi b/editproducts.cgi index 75597f172..b458f60bf 100755 --- a/editproducts.cgi +++ b/editproducts.cgi @@ -33,20 +33,22 @@ use strict; use lib "."; + +use Bugzilla; use Bugzilla::Constants; -require "globals.pl"; +use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::Bug; use Bugzilla::Series; -use Bugzilla::Config qw(:DEFAULT $datadir); +use Bugzilla::Mailer; use Bugzilla::Product; use Bugzilla::Classification; use Bugzilla::Milestone; +use Bugzilla::Group; +use Bugzilla::User; +use Bugzilla::Field; use Bugzilla::Token; -# Shut up misguided -w warnings about "used only once". "use vars" just -# doesn't work for me. -use vars qw(@legal_bug_status @legal_resolution); - # # Preliminary checks: # @@ -62,6 +64,7 @@ my $vars = {}; print $cgi->header(); $user->in_group('editcomponents') + || scalar(@{$user->get_products_by_permission('editcomponents')}) || ThrowUserError("auth_failure", {group => "editcomponents", action => "edit", object => "products"}); @@ -80,7 +83,7 @@ my $token = $cgi->param('token'); # classifications enabled) # -if (Param('useclassification') +if (Bugzilla->params->{'useclassification'} && !$classification_name && !$product_name) { @@ -98,10 +101,11 @@ if (Param('useclassification') # if (!$action && !$product_name) { + my $classification; my $products; - if (Param('useclassification')) { - my $classification = + if (Bugzilla->params->{'useclassification'}) { + $classification = Bugzilla::Classification::check_classification($classification_name); $products = $user->get_selectable_products($classification->id); @@ -110,6 +114,14 @@ if (!$action && !$product_name) { $products = $user->get_selectable_products; } + # If the user has editcomponents privs for some products only, + # we have to restrict the list of products to display. + unless ($user->in_group('editcomponents')) { + $products = $user->get_products_by_permission('editcomponents'); + if (Bugzilla->params->{'useclassification'}) { + @$products = grep {$_->classification_id == $classification->id} @$products; + } + } $vars->{'products'} = $products; $vars->{'showbugcounts'} = $showbugcounts; @@ -128,8 +140,14 @@ if (!$action && !$product_name) { # if ($action eq 'add') { - - if (Param('useclassification')) { + # The user must have the global editcomponents privs to add + # new products. + $user->in_group('editcomponents') + || ThrowUserError("auth_failure", {group => "editcomponents", + action => "add", + object => "products"}); + + if (Bugzilla->params->{'useclassification'}) { my $classification = Bugzilla::Classification::check_classification($classification_name); $vars->{'classification'} = $classification; @@ -148,11 +166,18 @@ if ($action eq 'add') { # if ($action eq 'new') { + # The user must have the global editcomponents privs to add + # new products. + $user->in_group('editcomponents') + || ThrowUserError("auth_failure", {group => "editcomponents", + action => "add", + object => "products"}); + check_token_data($token, 'add_product'); # Cleanups and validity checks my $classification_id = 1; - if (Param('useclassification')) { + if (Bugzilla->params->{'useclassification'}) { my $classification = Bugzilla::Classification::check_classification($classification_name); $classification_id = $classification->id; @@ -169,13 +194,13 @@ if ($action eq 'new') { # Check for exact case sensitive match: if ($product->name eq $product_name) { - ThrowUserError("prod_name_already_in_use", + ThrowUserError("product_name_already_in_use", {'product' => $product->name}); } # Next check for a case-insensitive match: if (lc($product->name) eq lc($product_name)) { - ThrowUserError("prod_name_diff_in_case", + ThrowUserError("product_name_diff_in_case", {'product' => $product_name, 'existing_product' => $product->name}); } @@ -233,25 +258,24 @@ if ($action eq 'new') { # If we're using bug groups, then we need to create a group for this # product as well. -JMR, 2/16/00 - if (Param("makeproductgroups")) { + if (Bugzilla->params->{"makeproductgroups"}) { # Next we insert into the groups table my $productgroup = $product->name; - while (GroupExists($productgroup)) { + while (new Bugzilla::Group({name => $productgroup})) { $productgroup .= '_'; } my $group_description = "Access to bugs in the " . $product->name . " product"; - $dbh->do('INSERT INTO groups - (name, description, isbuggroup, last_changed) - VALUES (?, ?, ?, NOW())', + $dbh->do('INSERT INTO groups (name, description, isbuggroup) + VALUES (?, ?, ?)', undef, ($productgroup, $group_description, 1)); my $gid = $dbh->bz_last_key('groups', 'id'); # If we created a new group, give the "admin" group privileges # initially. - my $admin = GroupNameToId('admin'); + my $admin = Bugzilla::Group->new({name => 'admin'})->id(); my $sth = $dbh->prepare('INSERT INTO group_group_map (member_id, grantor_id, grant_type) @@ -266,15 +290,15 @@ if ($action eq 'new') { (group_id, product_id, entry, membercontrol, othercontrol, canedit) VALUES (?, ?, ?, ?, ?, ?)', - undef, ($gid, $product->id, Param('useentrygroupdefault'), + undef, ($gid, $product->id, + Bugzilla->params->{'useentrygroupdefault'}, CONTROLMAPDEFAULT, CONTROLMAPNA, 0)); } if ($cgi->param('createseries')) { # Insert default charting queries for this product. # If they aren't using charting, this won't do any harm. - GetVersionTable(); - + # # $open_name and $product are sqlquoted by the series code # and never used again here, so we can trick_taint them. my $open_name = $cgi->param('open_name'); @@ -283,19 +307,19 @@ if ($action eq 'new') { my @series; # We do every status, every resolution, and an "opened" one as well. - foreach my $bug_status (@::legal_bug_status) { + foreach my $bug_status (@{get_legal_field_values('bug_status')}) { push(@series, [$bug_status, "bug_status=" . url_quote($bug_status)]); } - foreach my $resolution (@::legal_resolution) { + foreach my $resolution (@{get_legal_field_values('resolution')}) { next if !$resolution; push(@series, [$resolution, "resolution=" .url_quote($resolution)]); } # For localisation reasons, we get the name of the "global" subcategory # and the title of the "open" query from the submitted form. - my @openedstatuses = OpenStates(); + my @openedstatuses = BUG_STATE_OPEN; my $query = join("&", map { "bug_status=" . url_quote($_) } @openedstatuses); push(@series, [$open_name, $query]); @@ -309,12 +333,10 @@ if ($action eq 'new') { $series->writeToDatabase(); } } - # Make versioncache flush - unlink "$datadir/versioncache"; delete_token($token); $vars->{'product'} = $product; - + $template->process("admin/products/created.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; @@ -327,14 +349,9 @@ if ($action eq 'new') { # if ($action eq 'del') { - # First make sure the product name is valid. - my $product = Bugzilla::Product::check_product($product_name); + my $product = $user->check_can_admin_product($product_name); - # Then make sure the user is allowed to edit properties of this product. - $user->can_see_product($product->name) - || ThrowUserError('product_access_denied', {product => $product->name}); - - if (Param('useclassification')) { + if (Bugzilla->params->{'useclassification'}) { my $classification = Bugzilla::Classification::check_classification($classification_name); if ($classification->id != $product->classification_id) { @@ -358,17 +375,12 @@ if ($action eq 'del') { # if ($action eq 'delete') { + my $product = $user->check_can_admin_product($product_name); check_token_data($token, 'delete_product'); - # First make sure the product name is valid. - my $product = Bugzilla::Product::check_product($product_name); - # Then make sure the user is allowed to edit properties of this product. - $user->can_see_product($product->name) - || ThrowUserError('product_access_denied', {product => $product->name}); - $vars->{'product'} = $product; - if (Param('useclassification')) { + if (Bugzilla->params->{'useclassification'}) { my $classification = Bugzilla::Classification::check_classification($classification_name); if ($classification->id != $product->classification_id) { @@ -380,9 +392,11 @@ if ($action eq 'delete') { } if ($product->bug_count) { - if (Param("allowbugdeletion")) { + if (Bugzilla->params->{"allowbugdeletion"}) { foreach my $bug_id (@{$product->bug_ids}) { - my $bug = new Bugzilla::Bug($bug_id, $whoid); + # Note that we allow the user to delete bugs he can't see, + # which is okay, because he's deleting the whole Product. + my $bug = new Bugzilla::Bug($bug_id); $bug->remove_from_db(); } } @@ -420,7 +434,6 @@ if ($action eq 'delete') { $dbh->bz_unlock_tables(); - unlink "$datadir/versioncache"; delete_token($token); $template->process("admin/products/deleted.html.tmpl", $vars) @@ -436,14 +449,9 @@ if ($action eq 'delete') { # if ($action eq 'edit' || (!$action && $product_name)) { - # First make sure the product name is valid. - my $product = Bugzilla::Product::check_product($product_name); - - # Then make sure the user is allowed to edit properties of this product. - $user->can_see_product($product->name) - || ThrowUserError('product_access_denied', {product => $product->name}); + my $product = $user->check_can_admin_product($product_name); - if (Param('useclassification')) { + if (Bugzilla->params->{'useclassification'}) { my $classification; if (!$classification_name) { $classification = @@ -491,13 +499,8 @@ if ($action eq 'edit' || (!$action && $product_name)) { # if ($action eq 'updategroupcontrols') { + my $product = $user->check_can_admin_product($product_name); check_token_data($token, 'edit_group_controls'); - # First make sure the product name is valid. - my $product = Bugzilla::Product::check_product($product_name); - - # Then make sure the user is allowed to edit properties of this product. - $user->can_see_product($product->name) - || ThrowUserError('product_access_denied', {product => $product->name}); my @now_na = (); my @now_mandatory = (); @@ -585,19 +588,23 @@ if ($action eq 'updategroupcontrols') { my $sth_Insert = $dbh->prepare('INSERT INTO group_control_map (group_id, product_id, entry, membercontrol, - othercontrol, canedit) - VALUES (?, ?, ?, ?, ?, ?)'); + othercontrol, canedit, editcomponents, + canconfirm, editbugs) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)'); my $sth_Update = $dbh->prepare('UPDATE group_control_map SET entry = ?, membercontrol = ?, - othercontrol = ?, canedit = ? + othercontrol = ?, canedit = ?, + editcomponents = ?, canconfirm = ?, + editbugs = ? WHERE group_id = ? AND product_id = ?'); my $sth_Delete = $dbh->prepare('DELETE FROM group_control_map WHERE group_id = ? AND product_id = ?'); $groups = $dbh->selectall_arrayref('SELECT id, name, entry, membercontrol, - othercontrol, canedit + othercontrol, canedit, + editcomponents, canconfirm, editbugs FROM groups LEFT JOIN group_control_map ON group_control_map.group_id = id @@ -607,35 +614,60 @@ if ($action eq 'updategroupcontrols') { undef, $product->id); foreach my $group (@$groups) { - my ($groupid, $groupname, $entry, $membercontrol, - $othercontrol, $canedit) = @$group; + my ($groupid, $groupname, $entry, $membercontrol, $othercontrol, + $canedit, $editcomponents, $canconfirm, $editbugs) = @$group; my $newentry = $cgi->param("entry_$groupid") || 0; my $newmembercontrol = $cgi->param("membercontrol_$groupid") || 0; my $newothercontrol = $cgi->param("othercontrol_$groupid") || 0; my $newcanedit = $cgi->param("canedit_$groupid") || 0; + my $new_editcomponents = $cgi->param("editcomponents_$groupid") || 0; + my $new_canconfirm = $cgi->param("canconfirm_$groupid") || 0; + my $new_editbugs = $cgi->param("editbugs_$groupid") || 0; + my $oldentry = $entry; - $entry = $entry || 0; - $membercontrol = $membercontrol || 0; - $othercontrol = $othercontrol || 0; - $canedit = $canedit || 0; + # Set undefined values to 0. + $entry ||= 0; + $membercontrol ||= 0; + $othercontrol ||= 0; + $canedit ||= 0; + $editcomponents ||= 0; + $canconfirm ||= 0; + $editbugs ||= 0; + + # We use them in placeholders only. So it's safe to detaint them. detaint_natural($newentry); detaint_natural($newothercontrol); detaint_natural($newmembercontrol); detaint_natural($newcanedit); - if ((!defined($oldentry)) && - (($newentry) || ($newmembercontrol) || ($newcanedit))) { + detaint_natural($new_editcomponents); + detaint_natural($new_canconfirm); + detaint_natural($new_editbugs); + + if (!defined($oldentry) + && ($newentry || $newmembercontrol || $newcanedit + || $new_editcomponents || $new_canconfirm || $new_editbugs)) + { $sth_Insert->execute($groupid, $product->id, $newentry, - $newmembercontrol, $newothercontrol, $newcanedit); - } elsif (($newentry != $entry) - || ($newmembercontrol != $membercontrol) - || ($newothercontrol != $othercontrol) - || ($newcanedit != $canedit)) { + $newmembercontrol, $newothercontrol, $newcanedit, + $new_editcomponents, $new_canconfirm, $new_editbugs); + } + elsif (($newentry != $entry) + || ($newmembercontrol != $membercontrol) + || ($newothercontrol != $othercontrol) + || ($newcanedit != $canedit) + || ($new_editcomponents != $editcomponents) + || ($new_canconfirm != $canconfirm) + || ($new_editbugs != $editbugs)) + { $sth_Update->execute($newentry, $newmembercontrol, $newothercontrol, - $newcanedit, $groupid, $product->id); + $newcanedit, $new_editcomponents, $new_canconfirm, + $new_editbugs, $groupid, $product->id); } - if (($newentry == 0) && ($newmembercontrol == 0) - && ($newothercontrol == 0) && ($newcanedit == 0)) { + if (!$newentry && !$newmembercontrol && !$newothercontrol + && !$newcanedit && !$new_editcomponents && !$new_canconfirm + && !$new_editbugs) + { $sth_Delete->execute($groupid, $product->id); } } @@ -666,11 +698,12 @@ if ($action eq 'updategroupcontrols') { my $bugs = $dbh->selectall_arrayref($sth_Select, undef, ($groupid, $product->id)); + my ($removed, $timestamp) = + $dbh->selectrow_array($sth_Select2, undef, $groupid); + foreach my $bug (@$bugs) { my ($bugid, $mailiscurrent) = @$bug; $sth_Delete->execute($bugid, $groupid); - my ($removed, $timestamp) = - $dbh->selectrow_array($sth_Select2, undef, $groupid); LogActivityEntry($bugid, "bug_group", $removed, "", $whoid, $timestamp); @@ -683,8 +716,7 @@ if ($action eq 'updategroupcontrols') { } $count++; } - my %group = (name => GroupIdToName($groupid), - bug_count => $count); + my %group = (name => $removed, bug_count => $count); push(@removed_na, \%group); } @@ -709,11 +741,12 @@ if ($action eq 'updategroupcontrols') { my $bugs = $dbh->selectall_arrayref($sth_Select, undef, ($groupid, $product->id)); + my ($added, $timestamp) = + $dbh->selectrow_array($sth_Select2, undef, $groupid); + foreach my $bug (@$bugs) { my ($bugid, $mailiscurrent) = @$bug; $sth_Insert->execute($bugid, $groupid); - my ($added, $timestamp) = - $dbh->selectrow_array($sth_Select2, undef, $groupid); LogActivityEntry($bugid, "bug_group", "", $added, $whoid, $timestamp); @@ -726,8 +759,7 @@ if ($action eq 'updategroupcontrols') { } $count++; } - my %group = (name => GroupIdToName($groupid), - bug_count => $count); + my %group = (name => $added, bug_count => $count); push(@added_mandatory, \%group); } @@ -760,14 +792,9 @@ if ($action eq 'update') { my $checkvotes = 0; - # First make sure the product name is valid. - my $product_old = Bugzilla::Product::check_product($product_old_name); - - # Then make sure the user is allowed to edit properties of this product. - $user->can_see_product($product_old->name) - || ThrowUserError('product_access_denied', {product => $product_old->name}); + my $product_old = $user->check_can_admin_product($product_old_name); - if (Param('useclassification')) { + if (Bugzilla->params->{'useclassification'}) { my $classification; if (!$classification_name) { $classification = @@ -785,55 +812,50 @@ if ($action eq 'update') { } unless ($product_name) { - ThrowUserError('prod_cant_delete_name', + ThrowUserError('product_cant_delete_name', {product => $product_old->name}); } unless ($description) { - ThrowUserError('prod_cant_delete_description', + ThrowUserError('product_cant_delete_description', {product => $product_old->name}); } my $stored_maxvotesperbug = $maxvotesperbug; if (!detaint_natural($maxvotesperbug)) { - ThrowUserError('prod_votes_per_bug_must_be_nonnegative', + ThrowUserError('product_votes_per_bug_must_be_nonnegative', {maxvotesperbug => $stored_maxvotesperbug}); } my $stored_votesperuser = $votesperuser; if (!detaint_natural($votesperuser)) { - ThrowUserError('prod_votes_per_user_must_be_nonnegative', + ThrowUserError('product_votes_per_user_must_be_nonnegative', {votesperuser => $stored_votesperuser}); } my $stored_votestoconfirm = $votestoconfirm; if (!detaint_natural($votestoconfirm)) { - ThrowUserError('prod_votes_to_confirm_must_be_nonnegative', + ThrowUserError('product_votes_to_confirm_must_be_nonnegative', {votestoconfirm => $stored_votestoconfirm}); } - $dbh->bz_lock_tables('products WRITE', - 'versions READ', - 'groups WRITE', - 'group_control_map WRITE', - 'profiles WRITE', - 'milestones READ'); + $dbh->bz_lock_tables('products WRITE', 'milestones READ'); my $testproduct = new Bugzilla::Product({name => $product_name}); if (lc($product_name) ne lc($product_old->name) && $testproduct) { - ThrowUserError('prod_name_already_in_use', + ThrowUserError('product_name_already_in_use', {product => $product_name}); } # Only update milestone related stuff if 'usetargetmilestone' is on. - if (Param('usetargetmilestone')) { - my $milestone = new Bugzilla::Milestone($product_old->id, - $defaultmilestone); + if (Bugzilla->params->{'usetargetmilestone'}) { + my $milestone = new Bugzilla::Milestone( + { product => $product_old, name => $defaultmilestone }); unless ($milestone) { - ThrowUserError('prod_must_define_defaultmilestone', + ThrowUserError('product_must_define_defaultmilestone', {product => $product_old->name, defaultmilestone => $defaultmilestone, classification => $classification_name}); @@ -888,7 +910,6 @@ if ($action eq 'update') { } $dbh->bz_unlock_tables(); - unlink "$datadir/versioncache"; my $product = new Bugzilla::Product({name => $product_name}); @@ -909,10 +930,16 @@ if ($action eq 'update') { foreach my $vote (@$votes) { my ($who, $id) = (@$vote); - RemoveVotes($id, $who, "The rules for voting on this product " . - "has changed;\nyou had too many votes " . - "for a single bug."); - my $name = DBID_to_name($who); + # If some votes are removed, RemoveVotes() returns a list + # of messages to send to voters. + my $msgs = + RemoveVotes($id, $who, "The rules for voting on this product " . + "has changed;\nyou had too many votes " . + "for a single bug."); + foreach my $msg (@$msgs) { + MessageToMTA($msg); + } + my $name = user_id_to_login($who); push(@toomanyvotes_list, {id => $id, name => $name}); @@ -955,11 +982,17 @@ if ($action eq 'update') { undef, ($product->id, $who)); foreach my $bug_id (@$bug_ids) { - RemoveVotes($bug_id, $who, "The rules for voting on this " . - "product has changed; you had " . - "too many\ntotal votes, so all " . - "votes have been removed."); - my $name = DBID_to_name($who); + # RemoveVotes() returns a list of messages to send + # in case some voters had too many votes. + my $msgs = + RemoveVotes($bug_id, $who, "The rules for voting on this " . + "product has changed; you had " . + "too many\ntotal votes, so all " . + "votes have been removed."); + foreach my $msg (@$msgs) { + MessageToMTA($msg); + } + my $name = user_id_to_login($who); push(@toomanytotalvotes_list, {id => $bug_id, name => $name}); @@ -1000,16 +1033,12 @@ if ($action eq 'update') { # if ($action eq 'editgroupcontrols') { - # First make sure the product name is valid. - my $product = Bugzilla::Product::check_product($product_name); - - # Then make sure the user is allowed to edit properties of this product. - $user->can_see_product($product->name) - || ThrowUserError('product_access_denied', {product => $product->name}); + my $product = $user->check_can_admin_product($product_name); # Display a group if it is either enabled or has bugs for this product. my $groups = $dbh->selectall_arrayref( 'SELECT id, name, entry, membercontrol, othercontrol, canedit, + editcomponents, editbugs, canconfirm, isactive, COUNT(bugs.bug_id) AS bugcount FROM groups LEFT JOIN group_control_map @@ -1023,7 +1052,8 @@ if ($action eq 'editgroupcontrols') { WHERE isbuggroup != 0 AND (isactive != 0 OR entry IS NOT NULL OR bugs.bug_id IS NOT NULL) ' . $dbh->sql_group_by('name', 'id, entry, membercontrol, - othercontrol, canedit, isactive'), + othercontrol, canedit, isactive, + editcomponents, canconfirm, editbugs'), {'Slice' => {}}, ($product->id, $product->id)); $vars->{'product'} = $product; diff --git a/editsettings.cgi b/editsettings.cgi index e4579f95a..a4a85710f 100755 --- a/editsettings.cgi +++ b/editsettings.cgi @@ -21,13 +21,13 @@ use lib qw(.); use Bugzilla; use Bugzilla::Constants; +use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::User::Setting; use Bugzilla::Token; -require "globals.pl"; - my $template = Bugzilla->template; -my $vars = {}; +local our $vars = {}; ############################### ### Subroutine Definitions ### diff --git a/editusers.cgi b/editusers.cgi index 36366aad7..b4e3f698e 100755 --- a/editusers.cgi +++ b/editusers.cgi @@ -16,19 +16,21 @@ # Contributor(s): Marc Schumann <wurblzap@gmail.com> # Lance Larsh <lance.larsh@oracle.com> # Frédéric Buclin <LpSolit@gmail.com> +# David Lawrence <dkl@redhat.com> +# Vlad Dascalu <jocuri@softhome.net> +# Gavin Shelley <bugzilla@chimpychompy.org> use strict; use lib "."; -require "globals.pl"; - use Bugzilla; +use Bugzilla::Constants; +use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::User; use Bugzilla::Bug; +use Bugzilla::BugMail; use Bugzilla::Flag; -use Bugzilla::Config; -use Bugzilla::Constants; -use Bugzilla::Util; use Bugzilla::Field; use Bugzilla::Group; use Bugzilla::Token; @@ -37,10 +39,10 @@ my $user = Bugzilla->login(LOGIN_REQUIRED); my $cgi = Bugzilla->cgi; my $template = Bugzilla->template; -my $vars = {}; my $dbh = Bugzilla->dbh; my $userid = $user->id; my $editusers = $user->in_group('editusers'); +local our $vars = {}; # Reject access if there is no sense in continuing. $editusers @@ -71,6 +73,7 @@ if ($action eq 'search') { ########################################################################### } elsif ($action eq 'list') { + my $matchvalue = $cgi->param('matchvalue') || ''; my $matchstr = $cgi->param('matchstr'); my $matchtype = $cgi->param('matchtype'); my $grouprestrict = $cgi->param('grouprestrict') || '0'; @@ -87,7 +90,7 @@ if ($action eq 'search') { $group || ThrowUserError('invalid_group_ID'); } - if (!$editusers && Param('usevisibilitygroups')) { + if (!$editusers && Bugzilla->params->{'usevisibilitygroups'}) { # Show only users in visible groups. $visibleGroups = $user->visible_groups_as_string(); @@ -117,10 +120,22 @@ if ($action eq 'search') { $vars->{'users'} = {}; } else { - # Handle selection by user name. + # Handle selection by login name, real name, or userid. if (defined($matchtype)) { $query .= " $nextCondition "; - my $expr = "profiles.login_name"; + my $expr = ""; + if ($matchvalue eq 'userid') { + if ($matchstr) { + my $stored_matchstr = $matchstr; + detaint_natural($matchstr) + || ThrowUserError('illegal_user_id', {userid => $stored_matchstr}); + } + $expr = "profiles.userid"; + } elsif ($matchvalue eq 'realname') { + $expr = "profiles.realname"; + } else { + $expr = "profiles.login_name"; + } if ($matchtype eq 'regexp') { $query .= $dbh->sql_regexp($expr, '?'); $matchstr = '.' unless $matchstr; @@ -182,40 +197,15 @@ if ($action eq 'search') { object => "users"}); check_token_data($token, 'add_user'); - my $login = $cgi->param('login'); - my $password = $cgi->param('password'); - my $realname = trim($cgi->param('name') || ''); - my $disabledtext = trim($cgi->param('disabledtext') || ''); - # Lock tables during the check+creation session. - $dbh->bz_lock_tables('profiles WRITE', - 'profiles_activity WRITE', - 'groups READ', - 'user_group_map WRITE', - 'email_setting WRITE', - 'namedqueries READ', - 'whine_queries READ', - 'tokens READ'); - - # Validity checks - $login || ThrowUserError('user_login_required'); - validate_email_syntax($login) - || ThrowUserError('illegal_email_address', {addr => $login}); - is_available_username($login) - || ThrowUserError('account_exists', {email => $login}); - ValidatePassword($password); - - # Login and password are validated now, and realname and disabledtext - # are allowed to contain anything - trick_taint($login); - trick_taint($realname); - trick_taint($password); - trick_taint($disabledtext); - - insert_new_user($login, $realname, $password, $disabledtext); - my $new_user_id = $dbh->bz_last_key('profiles', 'userid'); - $dbh->bz_unlock_tables(); - userDataToVars($new_user_id); + my $new_user = Bugzilla::User->create({ + login_name => scalar $cgi->param('login'), + cryptpassword => scalar $cgi->param('password'), + realname => scalar $cgi->param('name'), + disabledtext => scalar $cgi->param('disabledtext'), + disable_mail => scalar $cgi->param('disable_mail')}); + + userDataToVars($new_user->id); delete_token($token); @@ -236,20 +226,14 @@ if ($action eq 'search') { my $otherUser = check_user($otherUserID, $otherUserLogin); $otherUserID = $otherUser->id; - my $logoutNeeded = 0; - my @changedFields; - # Lock tables during the check+update session. $dbh->bz_lock_tables('profiles WRITE', 'profiles_activity WRITE', 'fielddefs READ', - 'namedqueries READ', - 'whine_queries READ', 'tokens WRITE', 'logincookies WRITE', 'groups READ', 'user_group_map WRITE', - 'user_group_map AS ugm READ', 'group_group_map READ', 'group_group_map AS ggm READ'); @@ -258,75 +242,19 @@ if ($action eq 'search') { action => "modify", object => "user"}); - # Cleanups - my $loginold = $cgi->param('loginold') || ''; - my $realnameold = $cgi->param('nameold') || ''; - my $disabledtextold = $cgi->param('disabledtextold') || ''; - - my $login = $cgi->param('login'); - my $password = $cgi->param('password'); - my $realname = trim($cgi->param('name') || ''); - my $disabledtext = trim($cgi->param('disabledtext') || ''); + $vars->{'loginold'} = $otherUser->login; # Update profiles table entry; silently skip doing this if the user # is not authorized. + my %changes; if ($editusers) { - my @values; - - if ($login ne $loginold) { - # Validate, then trick_taint. - $login || ThrowUserError('user_login_required'); - validate_email_syntax($login) - || ThrowUserError('illegal_email_address', {addr => $login}); - is_available_username($login) - || ThrowUserError('account_exists', {email => $login}); - - trick_taint($login); - push(@changedFields, 'login_name'); - push(@values, $login); - $logoutNeeded = 1; - - # Since we change the login, silently delete any tokens. - $dbh->do('DELETE FROM tokens WHERE userid = ?', {}, $otherUserID); - } - if ($realname ne $realnameold) { - # The real name may be anything; we use a placeholder for our - # INSERT, and we rely on displaying code to FILTER html. - trick_taint($realname); - push(@changedFields, 'realname'); - push(@values, $realname); - } - if ($password) { - # Validate, then trick_taint. - ValidatePassword($password) if $password; - trick_taint($password); - push(@changedFields, 'cryptpassword'); - push(@values, bz_crypt($password)); - $logoutNeeded = 1; - } - if ($disabledtext ne $disabledtextold) { - # The disable text may be anything; we use a placeholder for our - # INSERT, and we rely on displaying code to FILTER html. - trick_taint($disabledtext); - push(@changedFields, 'disabledtext'); - push(@values, $disabledtext); - $logoutNeeded = 1; - } - if (@changedFields) { - push (@values, $otherUserID); - $logoutNeeded && Bugzilla->logout_user($otherUser); - $dbh->do('UPDATE profiles SET ' . - join(' = ?,', @changedFields).' = ? ' . - 'WHERE userid = ?', - undef, @values); - # XXX: should create profiles_activity entries. - # - # We create a new user object here because it needs to - # read information that may have changed since this - # script started. - my $newprofile = new Bugzilla::User($otherUserID); - $newprofile->derive_regexp_groups(); - } + $otherUser->set_login($cgi->param('login')); + $otherUser->set_name($cgi->param('name')); + $otherUser->set_password($cgi->param('password')) + if $cgi->param('password'); + $otherUser->set_disabledtext($cgi->param('disabledtext')); + $otherUser->set_disable_mail($cgi->param('disable_mail')); + %changes = %{$otherUser->update()}; } # Update group settings. @@ -404,8 +332,6 @@ if ($action eq 'search') { ($otherUserID, $userid, get_field_id('bug_group'), join(', ', @groupsRemovedFrom), join(', ', @groupsAddedTo))); - $dbh->do('UPDATE profiles SET refreshed_when=? WHERE userid = ?', - undef, ('1900-01-01 00:00:00', $otherUserID)); } # XXX: should create profiles_activity entries for blesser changes. @@ -416,8 +342,7 @@ if ($action eq 'search') { delete_token($token); $vars->{'message'} = 'account_updated'; - $vars->{'loginold'} = $loginold; - $vars->{'changed_fields'} = \@changedFields; + $vars->{'changed_fields'} = [keys %changes]; $vars->{'groups_added_to'} = \@groupsAddedTo; $vars->{'groups_removed_from'} = \@groupsRemovedFrom; $vars->{'groups_granted_rights_to_bless'} = \@groupsGrantedRightsToBless; @@ -433,12 +358,12 @@ if ($action eq 'search') { my $otherUser = check_user($otherUserID, $otherUserLogin); $otherUserID = $otherUser->id; - Param('allowuserdeletion') || ThrowUserError('users_deletion_disabled'); + Bugzilla->params->{'allowuserdeletion'} + || ThrowUserError('users_deletion_disabled'); $editusers || ThrowUserError('auth_failure', {group => "editusers", action => "delete", object => "users"}); $vars->{'otheruser'} = $otherUser; - $vars->{'editcomponents'} = UserInGroup('editcomponents'); # Find other cross references. $vars->{'assignee_or_qa'} = $dbh->selectrow_array( @@ -459,7 +384,7 @@ if ($action eq 'search') { 'SELECT COUNT(*) FROM email_setting WHERE user_id = ?', undef, $otherUserID); $vars->{'flags'}{'requestee'} = $dbh->selectrow_array( - 'SELECT COUNT(*) FROM flags WHERE requestee_id = ? AND is_active = 1', + 'SELECT COUNT(*) FROM flags WHERE requestee_id = ?', undef, $otherUserID); $vars->{'flags'}{'setter'} = $dbh->selectrow_array( 'SELECT COUNT(*) FROM flags WHERE setter_id = ?', @@ -467,9 +392,18 @@ if ($action eq 'search') { $vars->{'longdescs'} = $dbh->selectrow_array( 'SELECT COUNT(*) FROM longdescs WHERE who = ?', undef, $otherUserID); - $vars->{'namedqueries'} = $dbh->selectrow_array( - 'SELECT COUNT(*) FROM namedqueries WHERE userid = ?', + my $namedquery_ids = $dbh->selectcol_arrayref( + 'SELECT id FROM namedqueries WHERE userid = ?', undef, $otherUserID); + $vars->{'namedqueries'} = scalar(@$namedquery_ids); + if (scalar(@$namedquery_ids)) { + $vars->{'namedquery_group_map'} = $dbh->selectrow_array( + 'SELECT COUNT(*) FROM namedquery_group_map WHERE namedquery_id IN' . + ' (' . join(', ', @$namedquery_ids) . ')'); + } + else { + $vars->{'namedquery_group_map'} = 0; + } $vars->{'profile_setting'} = $dbh->selectrow_array( 'SELECT COUNT(*) FROM profile_setting WHERE user_id = ?', undef, $otherUserID); @@ -528,14 +462,14 @@ if ($action eq 'search') { 'profiles_activity WRITE', 'email_setting WRITE', 'profile_setting WRITE', - 'groups READ', 'bug_group_map READ', 'user_group_map WRITE', - 'group_group_map READ', 'flags WRITE', 'flagtypes READ', 'cc WRITE', 'namedqueries WRITE', + 'namedqueries_link_in_footer WRITE', + 'namedquery_group_map WRITE', 'tokens WRITE', 'votes WRITE', 'watch WRITE', @@ -545,7 +479,7 @@ if ($action eq 'search') { 'whine_queries WRITE', 'whine_events WRITE'); - Param('allowuserdeletion') + Bugzilla->params->{'allowuserdeletion'} || ThrowUserError('users_deletion_disabled'); $editusers || ThrowUserError('auth_failure', {group => "editusers", @@ -556,6 +490,10 @@ if ($action eq 'search') { Bugzilla->logout_user($otherUser); + # Get the named query list so we can delete namedquery_group_map entries. + my $namedqueries_as_string = join(', ', @{$dbh->selectcol_arrayref( + 'SELECT id FROM namedqueries WHERE userid = ?', undef, $otherUserID)}); + # Get the timestamp for LogActivityEntry. my $timestamp = $dbh->selectrow_array('SELECT NOW()'); @@ -590,8 +528,7 @@ if ($action eq 'search') { my @new_summaries = Bugzilla::Flag::snapshot($bug_id, $attach_id); # Let update_activity do all the dirty work, including setting # the bug timestamp. - Bugzilla::Flag::update_activity($bug_id, $attach_id, - $dbh->quote($timestamp), + Bugzilla::Flag::update_activity($bug_id, $attach_id, $timestamp, \@old_summaries, \@new_summaries); $updatedbugs{$bug_id} = 1; } @@ -601,6 +538,12 @@ if ($action eq 'search') { $otherUserID); $dbh->do('DELETE FROM logincookies WHERE userid = ?', undef, $otherUserID); $dbh->do('DELETE FROM namedqueries WHERE userid = ?', undef, $otherUserID); + $dbh->do('DELETE FROM namedqueries_link_in_footer WHERE user_id = ?', undef, + $otherUserID); + if ($namedqueries_as_string) { + $dbh->do('DELETE FROM namedquery_group_map WHERE namedquery_id IN ' . + "($namedqueries_as_string)"); + } $dbh->do('DELETE FROM profile_setting WHERE user_id = ?', undef, $otherUserID); $dbh->do('DELETE FROM profiles_activity WHERE userid = ? OR who = ?', undef, @@ -730,9 +673,32 @@ if ($action eq 'search') { # Send mail about what we've done to bugs. # The deleted user is not notified of the changes. foreach (keys(%updatedbugs)) { - Bugzilla::BugMail::Send($_); + Bugzilla::BugMail::Send($_, {'changer' => $user->login} ); } +########################################################################### +} elsif ($action eq 'activity') { + my $otherUser = check_user($otherUserID, $otherUserLogin); + + $vars->{'profile_changes'} = $dbh->selectall_arrayref( + "SELECT profiles.login_name AS who, " . + $dbh->sql_date_format('profiles_activity.profiles_when') . " AS activity_when, + fielddefs.description AS what, + profiles_activity.oldvalue AS removed, + profiles_activity.newvalue AS added + FROM profiles_activity + INNER JOIN profiles ON profiles_activity.who = profiles.userid + INNER JOIN fielddefs ON fielddefs.id = profiles_activity.fieldid + WHERE profiles_activity.userid = ? + ORDER BY profiles_activity.profiles_when", + {'Slice' => {}}, + $otherUser->id); + + $vars->{'otheruser'} = $otherUser; + + $template->process("account/profile-activity.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + ########################################################################### } else { $vars->{'action'} = $action; @@ -758,7 +724,7 @@ sub check_user { $vars->{'user_id'} = $otherUserID; } elsif ($otherUserLogin) { - $otherUser = Bugzilla::User->new_from_login($otherUserLogin); + $otherUser = new Bugzilla::User({ name => $otherUserLogin }); $vars->{'user_login'} = $otherUserLogin; } ($otherUser && $otherUser->id) || ThrowCodeError('invalid_user', $vars); @@ -768,8 +734,9 @@ sub check_user { # Copy incoming list selection values from CGI params to template variables. sub mirrorListSelectionValues { + my $cgi = Bugzilla->cgi; if (defined($cgi->param('matchtype'))) { - foreach ('matchstr', 'matchtype', 'grouprestrict', 'groupid') { + foreach ('matchvalue', 'matchstr', 'matchtype', 'grouprestrict', 'groupid') { $vars->{'listselectionvalues'}{$_} = $cgi->param($_); } } @@ -781,6 +748,7 @@ sub userDataToVars { my $otheruserid = shift; my $otheruser = new Bugzilla::User($otheruserid); my $query; + my $user = Bugzilla->user; my $dbh = Bugzilla->dbh; my $grouplist = $otheruser->groups_as_string; @@ -836,8 +804,10 @@ sub userDataToVars { sub edit_processing { my $otherUser = shift; + my $user = Bugzilla->user; + my $template = Bugzilla->template; - $editusers || $user->can_see_user($otherUser) + $user->in_group('editusers') || $user->can_see_user($otherUser) || ThrowUserError('auth_failure', {reason => "not_visible", action => "modify", object => "user"}); diff --git a/editvalues.cgi b/editvalues.cgi index b03fea609..fe1ad546a 100755 --- a/editvalues.cgi +++ b/editvalues.cgi @@ -21,21 +21,26 @@ use strict; use lib "."; -require "globals.pl"; use Bugzilla; use Bugzilla::Util; use Bugzilla::Error; use Bugzilla::Constants; -use Bugzilla::Config qw(:DEFAULT :admin :locations); +use Bugzilla::Config qw(:admin); use Bugzilla::Token; # List of different tables that contain the changeable field values # (the old "enums.") Keep them in alphabetical order by their # English name from field-descs.html.tmpl. # Format: Array of valid field names. -# Admins may add resolution and bug_status to this list, but they -# do so at their own risk. -our @valid_fields = ('op_sys', 'rep_platform', 'priority', 'bug_severity',); +# Admins may add bug_status to this list, but they do so at their own risk. +our @valid_fields = ('op_sys', 'rep_platform', 'priority', 'bug_severity', + 'resolution'); + +# Add custom select fields. +my @custom_fields = Bugzilla->get_fields({custom => 1, + type => FIELD_TYPE_SINGLE_SELECT}); + +push(@valid_fields, map { $_->name } @custom_fields); ###################################################################### # Subroutines @@ -105,8 +110,8 @@ my $vars = {}; print $cgi->header(); -exists Bugzilla->user->groups->{'editcomponents'} || - ThrowUserError('auth_failure', {group => "editcomponents", +exists Bugzilla->user->groups->{'admin'} || + ThrowUserError('auth_failure', {group => "admin", action => "edit", object => "field_values"}); @@ -127,6 +132,12 @@ $defaults{'rep_platform'} = 'defaultplatform'; $defaults{'priority'} = 'defaultpriority'; $defaults{'bug_severity'} = 'defaultseverity'; +# Alternatively, a list of non-editable values can be specified. +# In this case, only the sortkey can be altered. +my %static; +$static{'resolution'} = ['', 'FIXED', 'MOVED', 'DUPLICATE']; +$static{$_->name} = ['---'] foreach (@custom_fields); + # # field = '' -> Show nice list of fields # @@ -159,9 +170,9 @@ unless ($action) { {Slice =>{}}); $vars->{'field'} = $field; $vars->{'values'} = $fieldvalues; - $vars->{'default'} = Param($defaults{$field}); - $template->process("admin/fieldvalues/list.html.tmpl", - $vars) + $vars->{'default'} = Bugzilla->params->{$defaults{$field}} if defined $defaults{$field}; + $vars->{'static'} = $static{$field} if exists $static{$field}; + $template->process("admin/fieldvalues/list.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; @@ -178,7 +189,6 @@ if ($action eq 'add') { $vars->{'value'} = $value; $vars->{'field'} = $field; $vars->{'token'} = issue_session_token('add_field_value'); - $template->process("admin/fieldvalues/create.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -222,7 +232,6 @@ if ($action eq 'new') { VALUES ( ?, ? )"); $sth->execute($value, $sortkey); - unlink "$datadir/versioncache"; delete_token($token); $vars->{'value'} = $value; @@ -254,6 +263,11 @@ if ($action eq 'del') { $vars->{'value'} = $value; $vars->{'field'} = $field; $vars->{'param_name'} = $defaults{$field}; + + # If the value cannot be deleted, throw an error. + if (lsearch($static{$field}, $value) >= 0) { + ThrowUserError('fieldvalue_not_deletable', $vars); + } $vars->{'token'} = issue_session_token('delete_field_value'); $template->process("admin/fieldvalues/confirm-delete.html.tmpl", @@ -270,11 +284,21 @@ if ($action eq 'del') { if ($action eq 'delete') { check_token_data($token, 'delete_field_value'); ValueMustExist($field, $value); - if ($value eq Param($defaults{$field})) { - ThrowUserError('fieldvalue_is_default', {field => $field, - value => $value, - param_name => $defaults{$field}}) + + $vars->{'value'} = $value; + $vars->{'field'} = $field; + $vars->{'param_name'} = $defaults{$field}; + + if (defined $defaults{$field} + && ($value eq Bugzilla->params->{$defaults{$field}})) + { + ThrowUserError('fieldvalue_is_default', $vars); + } + # If the value cannot be deleted, throw an error. + if (lsearch($static{$field}, $value) >= 0) { + ThrowUserError('fieldvalue_not_deletable', $vars); } + trick_taint($field); trick_taint($value); @@ -295,12 +319,8 @@ if ($action eq 'delete') { $dbh->do("DELETE FROM $field WHERE value = ?", undef, $value); $dbh->bz_unlock_tables(); - - unlink "$datadir/versioncache"; delete_token($token); - $vars->{'value'} = $value; - $vars->{'field'} = $field; $template->process("admin/fieldvalues/deleted.html.tmpl", $vars) || ThrowTemplateError($template->error()); @@ -322,10 +342,10 @@ if ($action eq 'edit') { $vars->{'value'} = $value; $vars->{'field'} = $field; + $vars->{'is_static'} = (lsearch($static{$field}, $value) >= 0) ? 1 : 0; $vars->{'token'} = issue_session_token('edit_field_value'); - $template->process("admin/fieldvalues/edit.html.tmpl", - $vars) + $template->process("admin/fieldvalues/edit.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; @@ -344,9 +364,17 @@ if ($action eq 'update') { trick_taint($field); trick_taint($valueold); + $vars->{'value'} = $value; + $vars->{'field'} = $field; + + # If the value cannot be renamed, throw an error. + if (lsearch($static{$field}, $valueold) >= 0 && $value ne $valueold) { + $vars->{'old_value'} = $valueold; + ThrowUserError('fieldvalue_not_editable', $vars); + } + if (length($value) > 60) { - ThrowUserError('fieldvalue_name_too_long', - {'value' => $value}); + ThrowUserError('fieldvalue_name_too_long', $vars); } $dbh->bz_lock_tables('bugs WRITE', "$field WRITE"); @@ -366,7 +394,6 @@ if ($action eq 'update') { $dbh->do("UPDATE $field SET sortkey = ? WHERE value = ?", undef, $sortkey, $valueold); - unlink "$datadir/versioncache"; $vars->{'updated_sortkey'} = 1; $vars->{'sortkey'} = $sortkey; } @@ -377,9 +404,7 @@ if ($action eq 'update') { ThrowUserError('fieldvalue_undefined'); } if (ValueExists($field, $value)) { - ThrowUserError('fieldvalue_already_exists', - {'value' => $value, - 'field' => $field}); + ThrowUserError('fieldvalue_already_exists', $vars); } trick_taint($value); @@ -389,8 +414,6 @@ if ($action eq 'update') { $dbh->do("UPDATE $field SET value = ? WHERE value = ?", undef, $value, $valueold); - unlink "$datadir/versioncache"; - $vars->{'updated_value'} = 1; } @@ -399,19 +422,17 @@ if ($action eq 'update') { # If the old value was the default value for the field, # update data/params accordingly. # This update is done while tables are unlocked due to the - # annoying call to GetVersionTable in Bugzilla/Config/Common.pm. - if ($value ne $valueold - && $valueold eq Param($defaults{$field})) + # annoying calls in Bugzilla/Config/Common.pm. + if (defined $defaults{$field} + && $value ne $valueold + && $valueold eq Bugzilla->params->{$defaults{$field}}) { SetParam($defaults{$field}, $value); - WriteParams(); - unlink "$datadir/versioncache"; + write_params(); $vars->{'default_value_updated'} = 1; } delete_token($token); - $vars->{'value'} = $value; - $vars->{'field'} = $field; $template->process("admin/fieldvalues/updated.html.tmpl", $vars) || ThrowTemplateError($template->error()); diff --git a/editversions.cgi b/editversions.cgi index 9626c9e9a..7bda6215d 100755 --- a/editversions.cgi +++ b/editversions.cgi @@ -31,11 +31,10 @@ use strict; use lib "."; -require "globals.pl"; - +use Bugzilla; use Bugzilla::Constants; -use Bugzilla::Config qw(:DEFAULT $datadir); -use Bugzilla::Product; +use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::Version; use Bugzilla::Token; @@ -53,6 +52,7 @@ my $user = Bugzilla->login(LOGIN_REQUIRED); print $cgi->header(); $user->in_group('editcomponents') + || scalar(@{$user->get_products_by_permission('editcomponents')}) || ThrowUserError("auth_failure", {group => "editcomponents", action => "edit", object => "versions"}); @@ -71,7 +71,13 @@ my $token = $cgi->param('token'); # unless ($product_name) { - $vars->{'products'} = $user->get_selectable_products; + my $selectable_products = $user->get_selectable_products; + # If the user has editcomponents privs for some products only, + # we have to restrict the list of products to display. + unless ($user->in_group('editcomponents')) { + $selectable_products = $user->get_products_by_permission('editcomponents'); + } + $vars->{'products'} = $selectable_products; $vars->{'showbugcounts'} = $showbugcounts; $template->process("admin/versions/select-product.html.tmpl", $vars) @@ -79,13 +85,7 @@ unless ($product_name) { exit; } -# First make sure the product name is valid. -my $product = Bugzilla::Product::check_product($product_name); - -# Then make sure the user is allowed to edit properties of this product. -$user->can_see_product($product->name) - || ThrowUserError('product_access_denied', {product => $product->name}); - +my $product = $user->check_can_admin_product($product_name); # # action='' -> Show nice list of versions @@ -93,10 +93,8 @@ $user->can_see_product($product->name) unless ($action) { $vars->{'showbugcounts'} = $showbugcounts; - $vars->{'product'} = $product->name; - $vars->{'versions'} = $product->versions; - $template->process("admin/versions/list.html.tmpl", - $vars) + $vars->{'product'} = $product; + $template->process("admin/versions/list.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; @@ -113,9 +111,8 @@ unless ($action) { if ($action eq 'add') { $vars->{'token'} = issue_session_token('add_version'); - $vars->{'product'} = $product->name; - $template->process("admin/versions/create.html.tmpl", - $vars) + $vars->{'product'} = $product; + $template->process("admin/versions/create.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; @@ -129,32 +126,12 @@ if ($action eq 'add') { if ($action eq 'new') { check_token_data($token, 'add_version'); - # Cleanups and validity checks - $version_name || ThrowUserError('version_blank_name'); - - # Remove unprintable characters - $version_name = clean_text($version_name); - - my $version = new Bugzilla::Version($product->id, $version_name); - if ($version) { - ThrowUserError('version_already_exists', - {'name' => $version->name, - 'product' => $product->name}); - } - - # Add the new version - trick_taint($version_name); - $dbh->do("INSERT INTO versions (value, product_id) - VALUES (?, ?)", undef, ($version_name, $product->id)); - - # Make versioncache flush - unlink "$datadir/versioncache"; + my $version = Bugzilla::Version::create($version_name, $product); delete_token($token); - $vars->{'name'} = $version_name; - $vars->{'product'} = $product->name; - $template->process("admin/versions/created.html.tmpl", - $vars) + $vars->{'version'} = $version; + $vars->{'product'} = $product; + $template->process("admin/versions/created.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; @@ -171,17 +148,12 @@ if ($action eq 'new') { if ($action eq 'del') { - my $version = Bugzilla::Version::check_version($product, - $version_name); - my $bugs = $version->bug_count; + my $version = Bugzilla::Version::check_version($product, $version_name); - $vars->{'bug_count'} = $bugs; - $vars->{'name'} = $version->name; - $vars->{'product'} = $product->name; + $vars->{'version'} = $version; + $vars->{'product'} = $product; $vars->{'token'} = issue_session_token('delete_version'); - - $template->process("admin/versions/confirm-delete.html.tmpl", - $vars) + $template->process("admin/versions/confirm-delete.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; @@ -195,27 +167,16 @@ if ($action eq 'del') { if ($action eq 'delete') { check_token_data($token, 'delete_version'); - my $version = Bugzilla::Version::check_version($product, - $version_name); - - # The version cannot be removed if there are bugs - # associated with it. - if ($version->bug_count) { - ThrowUserError("version_has_bugs", - { nb => $version->bug_count }); - } - - $dbh->do("DELETE FROM versions WHERE product_id = ? AND value = ?", - undef, ($product->id, $version->name)); - - unlink "$datadir/versioncache"; + my $version = Bugzilla::Version::check_version($product, $version_name); + $version->remove_from_db; delete_token($token); - $vars->{'name'} = $version->name; - $vars->{'product'} = $product->name; + $vars->{'version'} = $version; + $vars->{'product'} = $product; $template->process("admin/versions/deleted.html.tmpl", $vars) || ThrowTemplateError($template->error()); + exit; } @@ -229,15 +190,13 @@ if ($action eq 'delete') { if ($action eq 'edit') { - my $version = Bugzilla::Version::check_version($product, - $version_name); + my $version = Bugzilla::Version::check_version($product, $version_name); - $vars->{'name'} = $version->name; - $vars->{'product'} = $product->name; + $vars->{'version'} = $version; + $vars->{'product'} = $product; $vars->{'token'} = issue_session_token('edit_version'); - $template->process("admin/versions/edit.html.tmpl", - $vars) + $template->process("admin/versions/edit.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; @@ -251,57 +210,20 @@ if ($action eq 'edit') { if ($action eq 'update') { check_token_data($token, 'edit_version'); - $version_name || ThrowUserError('version_not_specified'); + my $version_old_name = trim($cgi->param('versionold') || ''); + my $version = + Bugzilla::Version::check_version($product, $version_old_name); - # Remove unprintable characters - $version_name = clean_text($version_name); + $dbh->bz_lock_tables('bugs WRITE', 'versions WRITE'); - my $version_old_name = trim($cgi->param('versionold') || ''); - my $version_old = - Bugzilla::Version::check_version($product, - $version_old_name); - - # Note that the order of this tests is important. If you change - # them, be sure to test for WHERE='$version' or WHERE='$versionold' - - $dbh->bz_lock_tables('bugs WRITE', - 'versions WRITE', - 'products READ'); - - if ($version_name ne $version_old->name) { - - my $version = new Bugzilla::Version($product->id, - $version_name); - - if ($version) { - ThrowUserError('version_already_exists', - {'name' => $version->name, - 'product' => $product->name}); - } - - trick_taint($version_name); - $dbh->do("UPDATE bugs - SET version = ? - WHERE version = ? AND product_id = ?", undef, - ($version_name, $version_old->name, $product->id)); - - $dbh->do("UPDATE versions - SET value = ? - WHERE product_id = ? AND value = ?", undef, - ($version_name, $product->id, $version_old->name)); - - unlink "$datadir/versioncache"; - - $vars->{'updated_name'} = 1; - } + $vars->{'updated'} = $version->update($version_name, $product); $dbh->bz_unlock_tables(); delete_token($token); - $vars->{'name'} = $version_name; - $vars->{'product'} = $product->name; - $template->process("admin/versions/updated.html.tmpl", - $vars) + $vars->{'version'} = $version; + $vars->{'product'} = $product; + $template->process("admin/versions/updated.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; diff --git a/editwhines.cgi b/editwhines.cgi index cfa4443f0..ba39b543d 100755 --- a/editwhines.cgi +++ b/editwhines.cgi @@ -28,9 +28,11 @@ use strict; use lib "."; -require "globals.pl"; +use Bugzilla; use Bugzilla::Constants; +use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::User; use Bugzilla::Group; use Bugzilla::Token; @@ -79,13 +81,14 @@ $user->in_group('bz_canusewhines') object => "reports"}); # May this user send mail to other users? -my $can_mail_others = UserInGroup('bz_canusewhineatothers'); +my $can_mail_others = Bugzilla->user->in_group('bz_canusewhineatothers'); # If the form was submitted, we need to look for what needs to be added or # removed, then what was altered. if ($cgi->param('update')) { check_token_data($token, 'edit_whine'); + if ($cgi->param("add_event")) { # we create a new event $sth = $dbh->prepare("INSERT INTO whine_events " . @@ -236,7 +239,7 @@ if ($cgi->param('update')) { if ($can_mail_others && $mailto) { if ($mailto_type == MAILTO_USER) { # detaint - my $emailregexp = Param('emailregexp'); + my $emailregexp = Bugzilla->params->{'emailregexp'}; if ($mailto =~ /($emailregexp)/) { $mailto_id = login_to_id($1); } @@ -446,6 +449,7 @@ $template->process("whine/schedule.html.tmpl", $vars) # the subject and body of each event that user owns sub get_events { my $userid = shift; + my $dbh = Bugzilla->dbh; my $events = {}; my $sth = $dbh->prepare("SELECT DISTINCT id, subject, body " . diff --git a/email_in.pl b/email_in.pl new file mode 100644 index 000000000..40474afaf --- /dev/null +++ b/email_in.pl @@ -0,0 +1,530 @@ +#!/usr/bin/perl -w +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Inbound Email System. +# +# The Initial Developer of the Original Code is Akamai Technologies, Inc. +# Portions created by Akamai are Copyright (C) 2006 Akamai Technologies, +# Inc. All Rights Reserved. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + +use strict; +use warnings; + +# MTAs may call this script from any directory, but it should always +# run from this one so that it can find its modules. +BEGIN { + require File::Basename; + chdir(File::Basename::dirname($0)); +} + +use Data::Dumper; +use Email::Address; +use Email::Reply qw(reply); +use Email::MIME; +use Email::MIME::Attachment::Stripper; +use Getopt::Long qw(:config bundling); +use Pod::Usage; + +use Bugzilla; +use Bugzilla::Bug qw(ValidateBugID); +use Bugzilla::Constants qw(USAGE_MODE_EMAIL); +use Bugzilla::Error; +use Bugzilla::Mailer; +use Bugzilla::User; +use Bugzilla::Util; + +############# +# Constants # +############# + +# This is the USENET standard line for beginning a signature block +# in a message. RFC-compliant mailers use this. +use constant SIGNATURE_DELIMITER => '-- '; + +# These fields must all be defined or post_bug complains. They don't have +# to have values--they just have to be defined. There's not yet any +# way to require custom fields have values, for enter_bug, so we don't +# have to worry about those yet. +use constant REQUIRED_ENTRY_FIELDS => qw( + reporter + short_desc + product + component + version + + assigned_to + rep_platform + op_sys + priority + bug_severity + bug_file_loc +); + +# Fields that must be defined during process_bug. They *do* have to +# have values. The script will grab their values from the current +# bug object, if they're not specified. +use constant REQUIRED_PROCESS_FIELDS => qw( + dependson + blocked + version + product + target_milestone + rep_platform + op_sys + priority + bug_severity + bug_file_loc + component + short_desc + reporter_accessible + cclist_accessible +); + +# $input_email is a global so that it can be used in die_handler. +our ($input_email, %switch); + +#################### +# Main Subroutines # +#################### + +sub parse_mail { + my ($mail_text) = @_; + debug_print('Parsing Email'); + $input_email = Email::MIME->new($mail_text); + + my %fields; + + # Email::Address->parse returns an array + my ($reporter) = Email::Address->parse($input_email->header('From')); + $fields{'reporter'} = $reporter->address; + my $summary = $input_email->header('Subject'); + if ($summary =~ /\[Bug (\d+)\](.*)/i) { + $fields{'bug_id'} = $1; + $summary = trim($2); + } + + my ($body, $attachments) = get_body_and_attachments($input_email); + if (@$attachments) { + $fields{'attachments'} = $attachments; + } + + debug_print("Body:\n" . $body, 3); + + $body = remove_leading_blank_lines($body); + my @body_lines = split("\n", $body); + + # If there are fields specified. + if ($body =~ /^\s*@/s) { + my $current_field; + while (my $line = shift @body_lines) { + # If the sig is starting, we want to keep this in the + # @body_lines so that we don't keep the sig as part of the + # comment down below. + if ($line eq SIGNATURE_DELIMITER) { + unshift(@body_lines, $line); + last; + } + # Otherwise, we stop parsing fields on the first blank line. + $line = trim($line); + last if !$line; + + if ($line =~ /^@(\S+)\s*=\s*(.*)\s*/) { + $current_field = lc($1); + $fields{$current_field} = $2; + } + else { + $fields{$current_field} .= " $line"; + } + } + } + + + # The summary line only affects us if we're doing a post_bug. + # We have to check it down here because there might have been + # a bug_id specified in the body of the email. + if (!$fields{'bug_id'} && !$fields{'short_desc'}) { + $fields{'short_desc'} = $summary; + } + + my $comment = ''; + # Get the description, except the signature. + foreach my $line (@body_lines) { + last if $line eq SIGNATURE_DELIMITER; + $comment .= "$line\n"; + } + $fields{'comment'} = $comment; + + debug_print("Parsed Fields:\n" . Dumper(\%fields), 2); + + return \%fields; +} + +sub post_bug { + my ($fields_in) = @_; + my %fields = %$fields_in; + + debug_print('Posting a new bug...'); + + $fields{'rep_platform'} ||= Bugzilla->params->{'defaultplatform'}; + $fields{'op_sys'} ||= Bugzilla->params->{'defaultopsys'}; + $fields{'priority'} ||= Bugzilla->params->{'defaultpriority'}; + $fields{'bug_severity'} ||= Bugzilla->params->{'defaultseverity'}; + + foreach my $field (REQUIRED_ENTRY_FIELDS) { + $fields{$field} ||= ''; + } + + my $cgi = Bugzilla->cgi; + foreach my $field (keys %fields) { + $cgi->param(-name => $field, -value => $fields{$field}); + } + + $cgi->param(-name => 'inbound_email', -value => 1); + + require 'post_bug.cgi'; +} + +sub process_bug { + my ($fields_in) = @_; + + my %fields = %$fields_in; + + my $bug_id = $fields{'bug_id'}; + $fields{'id'} = $bug_id; + delete $fields{'bug_id'}; + + debug_print("Updating Bug $fields{id}..."); + + ValidateBugID($bug_id); + my $bug = new Bugzilla::Bug($bug_id); + + if ($fields{'assigned_to'}) { + $fields{'knob'} = 'reassign'; + } + if (my $status = $fields{'bug_status'}) { + $fields{'knob'} = 'confirm' if $status =~ /NEW/i; + $fields{'knob'} = 'accept' if $status =~ /ASSIGNED/i; + $fields{'knob'} = 'clearresolution' if $status =~ /REOPENED/i; + $fields{'knob'} = 'verify' if $status =~ /VERIFIED/i; + $fields{'knob'} = 'close' if $status =~ /CLOSED/i; + } + if ($fields{'dup_id'}) { + $fields{'knob'} = 'duplicate'; + } + if ($fields{'resolution'}) { + $fields{'knob'} = 'resolve'; + } + + # Make sure we don't get prompted if we have to change the default + # groups. + if ($fields{'product'}) { + $fields{'addtonewgroup'} = 0; + } + + foreach my $field (REQUIRED_PROCESS_FIELDS) { + my $value = $bug->$field; + if (ref $value) { + $value = join(',', @$value); + } + $fields{$field} ||= $value; + } + + # Make it possible to remove CCs. + if ($fields{'removecc'}) { + $fields{'cc'} = [split(',', $fields{'removecc'})]; + $fields{'removecc'} = 1; + } + + my $cgi = Bugzilla->cgi; + foreach my $field (keys %fields) { + $cgi->param(-name => $field, -value => $fields{$field}); + } + $cgi->param('longdesclength', scalar $bug->longdescs); + + require 'process_bug.cgi'; +} + +###################### +# Helper Subroutines # +###################### + +sub debug_print { + my ($str, $level) = @_; + $level ||= 1; + print STDERR "$str\n" if $level <= $switch{'verbose'}; +} + +sub get_body_and_attachments { + my ($email) = @_; + + my $ct = $email->content_type || 'text/plain'; + debug_print("Splitting Body and Attachments [Type: $ct]..."); + + my $body; + my $attachments = []; + if ($ct =~ /^multipart\/alternative/i) { + $body = get_text_alternative($email); + } + else { + my $stripper = new Email::MIME::Attachment::Stripper( + $email, force_filename => 1); + my $message = $stripper->message; + $body = get_text_alternative($message); + $attachments = [$stripper->attachments]; + } + + return ($body, $attachments); +} + +sub get_text_alternative { + my ($email) = @_; + + my @parts = $email->parts; + my $body; + foreach my $part (@parts) { + my $ct = $part->content_type || 'text/plain'; + debug_print("Part Content-Type: $ct", 2); + if (!$ct || $ct =~ /^text\/plain/i) { + $body = $part->body; + last; + } + } + + if (!defined $body) { + # Note that this only happens if the email does not contain any + # text/plain parts. If the email has an empty text/plain part, + # you're fine, and this message does NOT get thrown. + ThrowUserError('email_no_text_plain'); + } + + return $body; +} + +sub remove_leading_blank_lines { + my ($text) = @_; + $text =~ s/^(\s*\n)+//s; + return $text; +} + +sub html_strip { + my ($var) = @_; + # Trivial HTML tag remover (this is just for error messages, really.) + $var =~ s/<[^>]*>//g; + # And this basically reverses the Template-Toolkit html filter. + $var =~ s/\&/\&/g; + $var =~ s/\</</g; + $var =~ s/\>/>/g; + $var =~ s/\"/\"/g; + $var =~ s/@/@/g; + return $var; +} + + +sub die_handler { + my ($msg) = @_; + + # In Template-Toolkit, [% RETURN %] is implemented as a call to "die". + # But of course, we really don't want to actually *die* just because + # the user-error or code-error template ended. So we don't really die. + return if $msg->isa('Template::Exception') && $msg->type eq 'return'; + + # We can't depend on the MTA to send an error message, so we have + # to generate one properly. + if ($input_email) { + $msg =~ s/at .+ line.*$//ms; + $msg =~ s/^Compilation failed in require.+$//ms; + $msg = html_strip($msg); + my $reply = reply(to => $input_email, top_post => 1, body => "$msg\n"); + MessageToMTA($reply->as_string); + } + print STDERR $msg; + # We exit with a successful value, because we don't want the MTA + # to *also* send a failure notice. + exit; +} + +############### +# Main Script # +############### + +$SIG{__DIE__} = \&die_handler; + +GetOptions(\%switch, 'help|h', 'verbose|v+'); +$switch{'verbose'} ||= 0; + +# Print the help message if that switch was selected. +pod2usage({-verbose => 0, -exitval => 1}) if $switch{'help'}; + +Bugzilla->usage_mode(USAGE_MODE_EMAIL); + + +my @mail_lines = <STDIN>; +my $mail_text = join("", @mail_lines); +my $mail_fields = parse_mail($mail_text); + +my $username = $mail_fields->{'reporter'}; +my $user = Bugzilla::User->new({ name => $username }) + || ThrowUserError('invalid_username', { name => $username }); + +Bugzilla->set_user($user); + +if ($mail_fields->{'bug_id'}) { + process_bug($mail_fields); +} +else { + post_bug($mail_fields); +} + +__END__ + +=head1 NAME + +email_in.pl - The Bugzilla Inbound Email Interface + +=head1 SYNOPSIS + + ./email_in.pl [-vvv] < email.txt + + Reads an email on STDIN (the standard input). + + Options: + --verbose (-v) - Make the script print more to STDERR. + Specify multiple times to print even more. + +=head1 DESCRIPTION + +This script processes inbound email and creates a bug, or appends data +to an existing bug. + +=head2 Creating a New Bug + +The script expects to read an email with the following format: + + From: account@domain.com + Subject: Bug Summary + + @product = ProductName + @component = ComponentName + @version = 1.0 + + This is a bug description. It will be entered into the bug exactly as + written here. + + It can be multiple paragraphs. + + -- + This is a signature line, and will be removed automatically, It will not + be included in the bug description. + +The C<@> labels can be any valid field name in Bugzilla that can be +set on C<enter_bug.cgi>. For the list of field names, see the +C<fielddefs> table in the database. The above example shows the +minimum fields you B<must> specify. + +The values for the fields can be split across multiple lines, but +note that a newline will be parsed as a single space, for the value. +So, for example: + + @short_desc = This is a very long + description + +Will be parsed as "This is a very long description". + +If you specify C<@short_desc>, it will override the summary you specify +in the Subject header. + +C<account@domain.com> must be a valid Bugzilla account. + +Note that signatures must start with '-- ', the standard signature +border. + +=head2 Modifying an Existing Bug + +Bugzilla determines what bug you want to modify in one of two ways: + +=over + +=item * + +Your subject starts with [Bug 123456] -- then it modifies bug 123456. + +=item * + +You include C<@bug_id = 123456> in the first lines of the email. + +=back + +If you do both, C<@bug_id> takes precedence. + +You send your email in the same format as for creating a bug, except +that you only specify the fields you want to change. If the very +first non-blank line of the email doesn't begin with C<@>, then it +will be assumed that you are only adding a comment to the bug. + +Note that when updating a bug, the C<Subject> header is ignored, +except for getting the bug ID. If you want to change the bug's summary, +you have to specify C<@short_desc> as one of the fields to change. + +Please remember not to include any extra text in your emails, as that +text will also be added as a comment. This includes any text that your +email client automatically quoted and included, if this is a reply to +another email. + +=head3 Adding/Removing CCs + +You can't just add CCs to a bug by using the C<@cc> parameter like you +can when you're filing a bug. To add CCs, you can specify them in a +comma-separated list in C<@newcc>. + +To remove CCs, specify them as a comma-separated list in C<@removecc>. + +=head2 Errors + +If your request cannot be completed for any reason, Bugzilla will +send an email back to you. If your request succeeds, Bugzilla will +not send you anything. + +If any part of your request fails, all of it will fail. No partial +changes will happen. The only exception is attachments--one attachment +may succeed, and be inserted into the database, and a later attachment +may fail. + +=head1 CAUTION + +The script does not do any validation that the user is who they say +they are. That is, it accepts I<any> 'From' address, as long as it's +a valid Bugzilla account. So make sure that your MTA validates that +the message is actually coming from who it says it's coming from, +and only allow access to the inbound email system from people you trust. + +=head1 LIMITATIONS + +Note that the email interface has the same limitations as the +normal Bugzilla interface. So, for example, you cannot reassign +a bug and change its status at the same time. + +The email interface only accepts emails that are correctly formatted +perl RFC2822. If you send it an incorrectly formatted message, it +may behave in an unpredictable fashion. + +You cannot send an HTML mail along with attachments. If you do, Bugzilla +will reject your email, saying that it doesn't contain any text. This +is a bug in L<Email::MIME::Attachment::Stripper> that we can't work +around. + +If you send multiple attachments in one email, they will all be attached, +but Bugzilla may not send an email notice out for all of them. + +You cannot modify Flags through the email interface. diff --git a/enter_bug.cgi b/enter_bug.cgi index e4c3bba41..53262b33d 100755 --- a/enter_bug.cgi +++ b/enter_bug.cgi @@ -39,130 +39,131 @@ use lib qw(.); use Bugzilla; use Bugzilla::Constants; +use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::Bug; use Bugzilla::User; +use Bugzilla::Hook; use Bugzilla::Product; -require "globals.pl"; - -use vars qw( - @enterable_products - @legal_opsys - @legal_platform - @legal_priority - @legal_severity - @legal_keywords - %versions - %target_milestone - $proddesc -); - -# If we're using bug groups to restrict bug entry, we need to know who the -# user is right from the start. -Bugzilla->login(LOGIN_REQUIRED) if AnyEntryGroups(); +use Bugzilla::Classification; +use Bugzilla::Keyword; +use Bugzilla::Token; +use Bugzilla::Field; + +my $user = Bugzilla->login(LOGIN_REQUIRED); my $cloned_bug; my $cloned_bug_id; my $cgi = Bugzilla->cgi; +my $dbh = Bugzilla->dbh; my $template = Bugzilla->template; my $vars = {}; -my $product = $cgi->param('product'); - -if (!defined $product || $product eq "") { - GetVersionTable(); - Bugzilla->login(); - - if ( ! Param('useclassification') ) { - # Just use a fake value for the Classification. - $cgi->param(-name => 'classification', - -value => '__all'); - } - - if (!$cgi->param('classification')) { - my $classifications = Bugzilla->user->get_selectable_classifications(); - foreach my $classification (@$classifications) { - my $found = 0; - foreach my $p (@enterable_products) { - if (Bugzilla->user->can_enter_product($p) - && IsInClassification($classification->{name},$p)) { - $found = 1; - } - } - if ($found == 0) { - @$classifications = grep($_->{name} ne $classification->{name}, - @$classifications); +my $product_name = trim($cgi->param('product') || ''); +# Will contain the product object the bug is created in. +my $product; + +if ($product_name eq '') { + # If the user cannot enter bugs in any product, stop here. + my @enterable_products = @{$user->get_enterable_products}; + ThrowUserError('no_products') unless scalar(@enterable_products); + + my $classification = Bugzilla->params->{'useclassification'} ? + scalar($cgi->param('classification')) : '__all'; + + # Unless a real classification name is given, we sort products + # by classification. + my @classifications; + + unless ($classification && $classification ne '__all') { + if (Bugzilla->params->{'useclassification'}) { + my $class; + # Get all classifications with at least one enterable product. + foreach my $product (@enterable_products) { + $class->{$product->classification_id}->{'object'} ||= + new Bugzilla::Classification($product->classification_id); + # Nice way to group products per classification, without querying + # the DB again. + push(@{$class->{$product->classification_id}->{'products'}}, $product); } + @classifications = sort {$a->{'object'}->sortkey <=> $b->{'object'}->sortkey + || lc($a->{'object'}->name) cmp lc($b->{'object'}->name)} + (values %$class); + } + else { + @classifications = ({object => undef, products => \@enterable_products}); } + } - if (scalar(@$classifications) == 0) { - ThrowUserError("no_products"); - } - elsif (scalar(@$classifications) > 1) { - $vars->{'classifications'} = $classifications; + unless ($classification) { + # We know there is at least one classification available, + # else we would have stopped earlier. + if (scalar(@classifications) > 1) { + # We only need classification objects. + $vars->{'classifications'} = [map {$_->{'object'}} @classifications]; $vars->{'target'} = "enter_bug.cgi"; $vars->{'format'} = $cgi->param('format'); - $vars->{'cloned_bug_id'} = $cgi->param('cloned_bug_id'); print $cgi->header(); $template->process("global/choose-classification.html.tmpl", $vars) || ThrowTemplateError($template->error()); - exit; + exit; } - $cgi->param(-name => 'classification', -value => @$classifications[0]->name); + # If we come here, then there is only one classification available. + $classification = $classifications[0]->{'object'}->name; } - my %products; - foreach my $p (@enterable_products) { - if (Bugzilla->user->can_enter_product($p)) { - if (IsInClassification(scalar $cgi->param('classification'),$p) || - $cgi->param('classification') eq "__all") { - $products{$p} = $::proddesc{$p}; - } - } - } - - my $prodsize = scalar(keys %products); - if ($prodsize == 0) { - ThrowUserError("no_products"); - } - elsif ($prodsize > 1) { - my %classifications; - if ( ! Param('useclassification') ) { - @{$classifications{"all"}} = keys %products; + # Keep only enterable products which are in the specified classification. + if ($classification ne "__all") { + my $class = new Bugzilla::Classification({'name' => $classification}); + # If the classification doesn't exist, then there is no product in it. + if ($class) { + @enterable_products + = grep {$_->classification_id == $class->id} @enterable_products; + @classifications = ({object => $class, products => \@enterable_products}); } - elsif ($cgi->param('classification') eq "__all") { - %classifications = %::classifications; - } else { - $classifications{$cgi->param('classification')} = - $::classifications{$cgi->param('classification')}; + else { + @enterable_products = (); } - $vars->{'proddesc'} = \%products; - $vars->{'classifications'} = \%classifications; + } + if (scalar(@enterable_products) == 0) { + ThrowUserError('no_products'); + } + elsif (scalar(@enterable_products) > 1) { + $vars->{'classifications'} = \@classifications; $vars->{'target'} = "enter_bug.cgi"; $vars->{'format'} = $cgi->param('format'); - $vars->{'cloned_bug_id'} = $cgi->param('cloned_bug_id'); - + print $cgi->header(); $template->process("global/choose-product.html.tmpl", $vars) || ThrowTemplateError($template->error()); - exit; + exit; } else { - # Only one product exists - $product = (keys %products)[0]; + # Only one product exists. + $product = $enterable_products[0]; } } +else { + # Do not use Bugzilla::Product::check_product() here, else the user + # could know whether the product doesn't exist or is not accessible. + $product = new Bugzilla::Product({'name' => $product_name}); +} + +# We need to check and make sure that the user has permission +# to enter a bug against this product. +$user->can_enter_product($product ? $product->name : $product_name, THROW_ERROR); ############################################################################## # Useful Subroutines ############################################################################## sub formvalue { my ($name, $default) = (@_); - return $cgi->param($name) || $default || ""; + return Bugzilla->cgi->param($name) || $default || ""; } # Takes the name of a field and a list of possible values for that @@ -186,8 +187,8 @@ sub pickplatform { my @platform; - if (Param('defaultplatform')) { - @platform = Param('defaultplatform'); + if (Bugzilla->params->{'defaultplatform'}) { + @platform = Bugzilla->params->{'defaultplatform'}; } else { # If @platform is a list, this function will return the first # item in the list that is a valid platform choice. If @@ -243,66 +244,68 @@ sub pickos { return formvalue('op_sys'); } - my @os; + my @os = (); - if (Param('defaultopsys')) { - @os = Param('defaultopsys'); + if (Bugzilla->params->{'defaultopsys'}) { + @os = Bugzilla->params->{'defaultopsys'}; } else { # This function will return the first # item in @os that is a valid platform choice. If # no choice is valid, we return "Other". for ($ENV{'HTTP_USER_AGENT'}) { - /\(.*IRIX.*\)/ && do {@os = "IRIX"; last;}; - /\(.*OSF.*\)/ && do {@os = "OSF/1"; last;}; - /\(.*Linux.*\)/ && do {@os = "Linux"; last;}; - /\(.*Solaris.*\)/ && do {@os = "Solaris"; last;}; - /\(.*SunOS 5.*\)/ && do {@os = "Solaris"; last;}; - /\(.*SunOS.*sun4u.*\)/ && do {@os = "Solaris"; last;}; - /\(.*SunOS.*\)/ && do {@os = "SunOS"; last;}; - /\(.*HP-?UX.*\)/ && do {@os = "HP-UX"; last;}; - /\(.*BSD\/(?:OS|386).*\)/ && do {@os = "BSDI"; last;}; - /\(.*FreeBSD.*\)/ && do {@os = "FreeBSD"; last;}; - /\(.*OpenBSD.*\)/ && do {@os = "OpenBSD"; last;}; - /\(.*NetBSD.*\)/ && do {@os = "NetBSD"; last;}; - /\(.*BeOS.*\)/ && do {@os = "BeOS"; last;}; - /\(.*AIX.*\)/ && do {@os = "AIX"; last;}; - /\(.*OS\/2.*\)/ && do {@os = "OS/2"; last;}; - /\(.*QNX.*\)/ && do {@os = "Neutrino"; last;}; - /\(.*VMS.*\)/ && do {@os = "OpenVMS"; last;}; - /\(.*Windows XP.*\)/ && do {@os = "Windows XP"; last;}; - /\(.*Windows NT 5\.2.*\)/ && do {@os = "Windows Server 2003"; last;}; - /\(.*Windows NT 5\.1.*\)/ && do {@os = "Windows XP"; last;}; - /\(.*Windows 2000.*\)/ && do {@os = "Windows 2000"; last;}; - /\(.*Windows NT 5.*\)/ && do {@os = "Windows 2000"; last;}; - /\(.*Win.*9[8x].*4\.9.*\)/ && do {@os = "Windows ME"; last;}; - /\(.*Win(?:dows |)M[Ee].*\)/ && do {@os = "Windows ME"; last;}; - /\(.*Win(?:dows |)98.*\)/ && do {@os = "Windows 98"; last;}; - /\(.*Win(?:dows |)95.*\)/ && do {@os = "Windows 95"; last;}; - /\(.*Win(?:dows |)16.*\)/ && do {@os = "Windows 3.1"; last;}; - /\(.*Win(?:dows[ -]|)NT.*\)/ && do {@os = "Windows NT"; last;}; - /\(.*Windows.*NT.*\)/ && do {@os = "Windows NT"; last;}; - /\(.*32bit.*\)/ && do {@os = "Windows 95"; last;}; - /\(.*16bit.*\)/ && do {@os = "Windows 3.1"; last;}; - /\(.*Mac OS 9.*\)/ && do {@os = "Mac System 9.x"; last;}; - /\(.*Mac OS 8\.6.*\)/ && do {@os = "Mac System 8.6"; last;}; - /\(.*Mac OS 8\.5.*\)/ && do {@os = "Mac System 8.5"; last;}; + /\(.*IRIX.*\)/ && do {push @os, "IRIX"; }; + /\(.*OSF.*\)/ && do {push @os, "OSF/1";}; + /\(.*Linux.*\)/ && do {push @os, "Linux";}; + /\(.*Solaris.*\)/ && do {push @os, "Solaris";}; + /\(.*SunOS 5.*\)/ && do {push @os, "Solaris";}; + /\(.*SunOS.*sun4u.*\)/ && do {push @os, "Solaris";}; + /\(.*SunOS.*\)/ && do {push @os, "SunOS";}; + /\(.*HP-?UX.*\)/ && do {push @os, "HP-UX";}; + /\(.*BSD\/(?:OS|386).*\)/ && do {push @os, "BSDI";}; + /\(.*FreeBSD.*\)/ && do {push @os, "FreeBSD";}; + /\(.*OpenBSD.*\)/ && do {push @os, "OpenBSD";}; + /\(.*NetBSD.*\)/ && do {push @os, "NetBSD";}; + /\(.*BeOS.*\)/ && do {push @os, "BeOS";}; + /\(.*AIX.*\)/ && do {push @os, "AIX";}; + /\(.*OS\/2.*\)/ && do {push @os, "OS/2";}; + /\(.*QNX.*\)/ && do {push @os, "Neutrino";}; + /\(.*VMS.*\)/ && do {push @os, "OpenVMS";}; + /\(.*Windows XP.*\)/ && do {push @os, "Windows XP";}; + /\(.*Windows NT 6\.0.*\)/ && do {push @os, "Windows Vista";}; + /\(.*Windows NT 5\.2.*\)/ && do {push @os, "Windows Server 2003";}; + /\(.*Windows NT 5\.1.*\)/ && do {push @os, "Windows XP";}; + /\(.*Windows 2000.*\)/ && do {push @os, "Windows 2000";}; + /\(.*Windows NT 5.*\)/ && do {push @os, "Windows 2000";}; + /\(.*Win.*9[8x].*4\.9.*\)/ && do {push @os, "Windows ME";}; + /\(.*Win(?:dows |)M[Ee].*\)/ && do {push @os, "Windows ME";}; + /\(.*Win(?:dows |)98.*\)/ && do {push @os, "Windows 98";}; + /\(.*Win(?:dows |)95.*\)/ && do {push @os, "Windows 95";}; + /\(.*Win(?:dows |)16.*\)/ && do {push @os, "Windows 3.1";}; + /\(.*Win(?:dows[ -]|)NT.*\)/ && do {push @os, "Windows NT";}; + /\(.*Windows.*NT.*\)/ && do {push @os, "Windows NT";}; + /\(.*32bit.*\)/ && do {push @os, "Windows 95";}; + /\(.*16bit.*\)/ && do {push @os, "Windows 3.1";}; + /\(.*Mac OS 9.*\)/ && do {push @os, "Mac System 9.x";}; + /\(.*Mac OS 8\.6.*\)/ && do {push @os, "Mac System 8.6";}; + /\(.*Mac OS 8\.5.*\)/ && do {push @os, "Mac System 8.5";}; # Bugzilla doesn't have an entry for 8.1 - /\(.*Mac OS 8\.1.*\)/ && do {@os = "Mac System 8.0"; last;}; - /\(.*Mac OS 8\.0.*\)/ && do {@os = "Mac System 8.0"; last;}; - /\(.*Mac OS 8[^.].*\)/ && do {@os = "Mac System 8.0"; last;}; - /\(.*Mac OS 8.*\)/ && do {@os = "Mac System 8.6"; last;}; - /\(.*Mac OS X.*\)/ && do {@os = "Mac OS X 10.0"; last;}; - /\(.*Darwin.*\)/ && do {@os = "Mac OS X 10.0"; last;}; + /\(.*Mac OS 8\.1.*\)/ && do {push @os, "Mac System 8.0";}; + /\(.*Mac OS 8\.0.*\)/ && do {push @os, "Mac System 8.0";}; + /\(.*Mac OS 8[^.].*\)/ && do {push @os, "Mac System 8.0";}; + /\(.*Mac OS 8.*\)/ && do {push @os, "Mac System 8.6";}; + /\(.*Intel.*Mac OS X.*\)/ && do {push @os, "Mac OS X 10.4";}; + /\(.*Mac OS X.*\)/ && do {push @os, ("Mac OS X 10.3", "Mac OS X 10.0");}; + /\(.*Darwin.*\)/ && do {push @os, "Mac OS X 10.0";}; # Silly - /\(.*Mac.*PowerPC.*\)/ && do {@os = "Mac System 9.x"; last;}; - /\(.*Mac.*PPC.*\)/ && do {@os = "Mac System 9.x"; last;}; - /\(.*Mac.*68k.*\)/ && do {@os = "Mac System 8.0"; last;}; + /\(.*Mac.*PowerPC.*\)/ && do {push @os, "Mac System 9.x";}; + /\(.*Mac.*PPC.*\)/ && do {push @os, "Mac System 9.x";}; + /\(.*Mac.*68k.*\)/ && do {push @os, "Mac System 8.0";}; # Evil - /Amiga/i && do {@os = "Other"; last;}; - /WinMosaic/ && do {@os = "Windows 95"; last;}; - /\(.*PowerPC.*\)/ && do {@os = "Mac System 9.x"; last;}; - /\(.*PPC.*\)/ && do {@os = "Mac System 9.x"; last;}; - /\(.*68K.*\)/ && do {@os = "Mac System 8.0"; last;}; + /Amiga/i && do {push @os, "Other";}; + /WinMosaic/ && do {push @os, "Windows 95";}; + /\(.*PowerPC.*\)/ && do {push @os, "Mac System 9.x";}; + /\(.*PPC.*\)/ && do {push @os, "Mac System 9.x";}; + /\(.*68K.*\)/ && do {push @os, "Mac System 8.0";}; } } @@ -315,7 +318,8 @@ sub pickos { # End of subroutines ############################################################################## -Bugzilla->login(LOGIN_REQUIRED) if (!(AnyEntryGroups())); +my $has_editbugs = $user->in_group('editbugs', $product->id); +my $has_canconfirm = $user->in_group('canconfirm', $product->id); # If a user is trying to clone a bug # Check that the user has authorization to view the parent bug @@ -324,71 +328,46 @@ $cloned_bug_id = $cgi->param('cloned_bug_id'); if ($cloned_bug_id) { ValidateBugID($cloned_bug_id); - $cloned_bug = new Bugzilla::Bug($cloned_bug_id, Bugzilla->user->id); + $cloned_bug = new Bugzilla::Bug($cloned_bug_id); } -# We need to check and make sure -# that the user has permission to enter a bug against this product. -my $prod_obj = new Bugzilla::Product({name => $product}); -# Update the product name to get the correct case. -$product = $prod_obj->name if defined $prod_obj; -Bugzilla->user->can_enter_product($product, 1); - -GetVersionTable(); - -my $product_id = get_product_id($product); - -if (1 == @{$::components{$product}}) { +if (scalar(@{$product->components}) == 1) { # Only one component; just pick it. - $cgi->param('component', $::components{$product}->[0]); -} - -my @components; - -my $dbh = Bugzilla->dbh; -my $sth = $dbh->prepare( - q{SELECT name, description, p1.login_name, p2.login_name - FROM components - LEFT JOIN profiles p1 ON components.initialowner = p1.userid - LEFT JOIN profiles p2 ON components.initialqacontact = p2.userid - WHERE product_id = ? - ORDER BY name}); - -$sth->execute($product_id); -while (my ($name, $description, $owner, $qacontact) - = $sth->fetchrow_array()) { - push @components, { - name => $name, - description => $description, - initialowner => $owner, - initialqacontact => $qacontact || '', - }; + $cgi->param('component', $product->components->[0]->name); } my %default; $vars->{'product'} = $product; -$vars->{'component_'} = \@components; -$vars->{'priority'} = \@legal_priority; -$vars->{'bug_severity'} = \@legal_severity; -$vars->{'rep_platform'} = \@legal_platform; -$vars->{'op_sys'} = \@legal_opsys; +$vars->{'priority'} = get_legal_field_values('priority'); +$vars->{'bug_severity'} = get_legal_field_values('bug_severity'); +$vars->{'rep_platform'} = get_legal_field_values('rep_platform'); +$vars->{'op_sys'} = get_legal_field_values('op_sys'); -$vars->{'use_keywords'} = 1 if (@::legal_keywords); +$vars->{'use_keywords'} = 1 if Bugzilla::Keyword::keyword_count(); $vars->{'assigned_to'} = formvalue('assigned_to'); -$vars->{'assigned_to_disabled'} = !UserInGroup('editbugs'); +$vars->{'assigned_to_disabled'} = !$has_editbugs; $vars->{'cc_disabled'} = 0; $vars->{'qa_contact'} = formvalue('qa_contact'); -$vars->{'qa_contact_disabled'} = !UserInGroup('editbugs'); +$vars->{'qa_contact_disabled'} = !$has_editbugs; $vars->{'cloned_bug_id'} = $cloned_bug_id; +$vars->{'token'} = issue_session_token('createbug:'); + + +my @enter_bug_fields = Bugzilla->get_fields({ custom => 1, obsolete => 0, + enter_bug => 1 }); +foreach my $field (@enter_bug_fields) { + $vars->{$field->name} = formvalue($field->name); +} + if ($cloned_bug_id) { - $default{'component_'} = $cloned_bug->{'component'}; + $default{'component_'} = $cloned_bug->component; $default{'priority'} = $cloned_bug->{'priority'}; $default{'bug_severity'} = $cloned_bug->{'bug_severity'}; $default{'rep_platform'} = $cloned_bug->{'rep_platform'}; @@ -407,6 +386,10 @@ if ($cloned_bug_id) { $vars->{'cc'} = formvalue('cc'); } + foreach my $field (@enter_bug_fields) { + $vars->{$field->name} = $cloned_bug->{$field->name}; + } + # We need to ensure that we respect the 'insider' status of # the first comment, if it has one. Either way, make a note # that this bug was cloned from another bug. @@ -418,8 +401,8 @@ if ($cloned_bug_id) { $vars->{'commentprivacy'} = 0; if ( !($isprivate) || - ( ( Param("insidergroup") ) && - ( UserInGroup(Param("insidergroup")) ) ) + ( ( Bugzilla->params->{"insidergroup"} ) && + ( Bugzilla->user->in_group(Bugzilla->params->{"insidergroup"}) ) ) ) { $vars->{'comment'} = $cloned_bug->{'longdescs'}->[0]->{'body'}; $vars->{'commentprivacy'} = $isprivate; @@ -433,8 +416,8 @@ if ($cloned_bug_id) { else { $default{'component_'} = formvalue('component'); - $default{'priority'} = formvalue('priority', Param('defaultpriority')); - $default{'bug_severity'} = formvalue('bug_severity', Param('defaultseverity')); + $default{'priority'} = formvalue('priority', Bugzilla->params->{'defaultpriority'}); + $default{'bug_severity'} = formvalue('bug_severity', Bugzilla->params->{'defaultseverity'}); $default{'rep_platform'} = pickplatform(); $default{'op_sys'} = pickos(); @@ -466,55 +449,51 @@ else { # # Eventually maybe each product should have a "current version" # parameter. -$vars->{'version'} = $::versions{$product} || []; +$vars->{'version'} = [map($_->name, @{$product->versions})]; if ( ($cloned_bug_id) && - ("$product" eq "$cloned_bug->{'product'}" ) ) { + ($product->name eq $cloned_bug->product ) ) { $default{'version'} = $cloned_bug->{'version'}; } elsif (formvalue('version')) { $default{'version'} = formvalue('version'); -} elsif (defined $cgi->cookie("VERSION-$product") && - lsearch($vars->{'version'}, $cgi->cookie("VERSION-$product")) != -1) { - $default{'version'} = $cgi->cookie("VERSION-$product"); +} elsif (defined $cgi->cookie("VERSION-" . $product->name) && + lsearch($vars->{'version'}, $cgi->cookie("VERSION-" . $product->name)) != -1) { + $default{'version'} = $cgi->cookie("VERSION-" . $product->name); } else { $default{'version'} = $vars->{'version'}->[$#{$vars->{'version'}}]; } -# Only used with placeholders below -trick_taint($product); - # Get list of milestones. -if ( Param('usetargetmilestone') ) { - $vars->{'target_milestone'} = $::target_milestone{$product}; +if ( Bugzilla->params->{'usetargetmilestone'} ) { + $vars->{'target_milestone'} = [map($_->name, @{$product->milestones})]; if (formvalue('target_milestone')) { $default{'target_milestone'} = formvalue('target_milestone'); } else { - $default{'target_milestone'} = - $dbh->selectrow_array('SELECT defaultmilestone FROM products - WHERE name = ?', undef, $product); + $default{'target_milestone'} = $product->default_milestone; } } +# Construct the list of allowable statuses. +# +# * If the product requires votes to confirm: +# users with privs : NEW + ASSI + UNCO +# users with no privs: UNCO +# +# * If the product doesn't require votes to confirm: +# users with privs : NEW + ASSI +# users with no privs: NEW (as these users cannot reassign +# bugs to them, it doesn't make sense +# to let them mark bugs as ASSIGNED) -# List of status values for drop-down. my @status; - -# Construct the list of allowable values. There are three cases: -# -# case values -# product does not have confirmation NEW -# confirmation, user cannot confirm UNCONFIRMED -# confirmation, user can confirm NEW, UNCONFIRMED. - -my $votestoconfirm = $dbh->selectrow_array('SELECT votestoconfirm FROM products - WHERE name = ?', undef, $product); -if ($votestoconfirm) { - if (UserInGroup("editbugs") || UserInGroup("canconfirm")) { - push(@status, "NEW"); - } +if ($has_editbugs || $has_canconfirm) { + @status = ('NEW', 'ASSIGNED'); +} +elsif (!$product->votes_to_confirm) { + @status = ('NEW'); +} +if ($product->votes_to_confirm) { push(@status, 'UNCONFIRMED'); -} else { - push(@status, "NEW"); } $vars->{'bug_status'} = \@status; @@ -535,7 +514,7 @@ my $grouplist = $dbh->selectall_arrayref( LEFT JOIN group_control_map ON group_id = id AND product_id = ? WHERE isbuggroup != 0 AND isactive != 0 - ORDER BY description}, undef, $product_id); + ORDER BY description}, undef, $product->id); my @groups; @@ -547,7 +526,7 @@ foreach my $row (@$grouplist) { || ($membercontrol == CONTROLMAPMANDATORY) || (($othercontrol != CONTROLMAPSHOWN) && ($othercontrol != CONTROLMAPDEFAULT) - && (!UserInGroup($groupname))) + && (!Bugzilla->user->in_group($groupname))) ); my $check; @@ -560,7 +539,7 @@ foreach my $row (@$grouplist) { # set a groups's checkbox based on the group control map # if ( ($cloned_bug_id) && - ("$product" eq "$cloned_bug->{'product'}" ) ) { + ($product->name eq $cloned_bug->product ) ) { foreach my $i (0..(@{$cloned_bug->{'groups'}}-1) ) { if ($cloned_bug->{'groups'}->[$i]->{'bit'} == $id) { $check = $cloned_bug->{'groups'}->[$i]->{'ison'}; @@ -574,7 +553,7 @@ foreach my $row (@$grouplist) { # Checkbox is checked by default if $control is a default state. $check = (($membercontrol == CONTROLMAPDEFAULT) || (($othercontrol == CONTROLMAPDEFAULT) - && (!UserInGroup($groupname)))); + && (!Bugzilla->user->in_group($groupname)))); } my $group = @@ -589,6 +568,8 @@ foreach my $row (@$grouplist) { $vars->{'group'} = \@groups; +Bugzilla::Hook::process("enter_bug-entrydefaultvars", { vars => $vars }); + $vars->{'default'} = \%default; my $format = $template->get_format("bug/create/create", diff --git a/globals.pl b/globals.pl deleted file mode 100644 index e790cbb17..000000000 --- a/globals.pl +++ /dev/null @@ -1,804 +0,0 @@ -# -*- Mode: perl; indent-tabs-mode: nil -*- -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Bugzilla Bug Tracking System. -# -# The Initial Developer of the Original Code is Netscape Communications -# Corporation. Portions created by Netscape are -# Copyright (C) 1998 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): Terry Weissman <terry@mozilla.org> -# Dan Mosedale <dmose@mozilla.org> -# Jacob Steenhagen <jake@bugzilla.org> -# Bradley Baetz <bbaetz@student.usyd.edu.au> -# Christopher Aillon <christopher@aillon.com> -# Joel Peshkin <bugreport@peshkin.net> -# Dave Lawrence <dkl@redhat.com> -# Max Kanat-Alexander <mkanat@bugzilla.org> -# Lance Larsh <lance.larsh@oracle.com> - -# Contains some global variables and routines used throughout bugzilla. - -use strict; - -use Bugzilla::DB qw(:DEFAULT :deprecated); -use Bugzilla::Constants; -use Bugzilla::Util; -# Bring ChmodDataFile in until this is all moved to the module -use Bugzilla::Config qw(:DEFAULT ChmodDataFile $localconfig $datadir); -use Bugzilla::User; -use Bugzilla::Error; - -# Shut up misguided -w warnings about "used only once". For some reason, -# "use vars" chokes on me when I try it here. - -sub globals_pl_sillyness { - my $zz; - $zz = @main::enterable_products; - $zz = %main::keywordsbyname; - $zz = @main::legal_bug_status; - $zz = @main::legal_components; - $zz = @main::legal_keywords; - $zz = @main::legal_opsys; - $zz = @main::legal_platform; - $zz = @main::legal_priority; - $zz = @main::legal_product; - $zz = @main::legal_severity; - $zz = @main::legal_target_milestone; - $zz = @main::legal_versions; - $zz = @main::milestoneurl; - $zz = %main::proddesc; - $zz = @main::prodmaxvotes; -} - -# -# Here are the --LOCAL-- variables defined in 'localconfig' that we'll use -# here -# - -# XXX - Move this to Bugzilla::Config once code which uses these has moved out -# of globals.pl -do $localconfig; - -use DBI; - -use Date::Format; # For time2str(). -use Date::Parse; # For str2time(). - -# Use standard Perl libraries for cross-platform file/directory manipulation. -use File::Spec; - -# Some environment variables are not taint safe -delete @::ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; - -# Cwd.pm in perl 5.6.1 gives a warning if $::ENV{'PATH'} isn't defined -# Set this to '' so that we don't get warnings cluttering the logs on every -# system call -$::ENV{'PATH'} = ''; - -# Ignore SIGTERM and SIGPIPE - this prevents DB corruption. If the user closes -# their browser window while a script is running, the webserver sends these -# signals, and we don't want to die half way through a write. -$::SIG{TERM} = 'IGNORE'; -$::SIG{PIPE} = 'IGNORE'; - -# The following subroutine is for debugging purposes only. -# Uncommenting this sub and the $::SIG{__DIE__} trap underneath it will -# cause any fatal errors to result in a call stack trace to help track -# down weird errors. -#sub die_with_dignity { -# use Carp; # for confess() -# my ($err_msg) = @_; -# print $err_msg; -# confess($err_msg); -#} -#$::SIG{__DIE__} = \&die_with_dignity; - -# XXXX - this needs to go away -sub GenerateVersionTable { - my $dbh = Bugzilla->dbh; - - SendSQL("SELECT versions.value, products.name " . - "FROM versions, products " . - "WHERE products.id = versions.product_id " . - "ORDER BY versions.value"); - my @line; - my %varray; - my %carray; - while (@line = FetchSQLData()) { - my ($v,$p1) = (@line); - if (!defined $::versions{$p1}) { - $::versions{$p1} = []; - } - push @{$::versions{$p1}}, $v; - $varray{$v} = 1; - } - SendSQL("SELECT components.name, products.name " . - "FROM components, products " . - "WHERE products.id = components.product_id " . - "ORDER BY components.name"); - while (@line = FetchSQLData()) { - my ($c,$p) = (@line); - if (!defined $::components{$p}) { - $::components{$p} = []; - } - my $ref = $::components{$p}; - push @$ref, $c; - $carray{$c} = 1; - } - - SendSQL("SELECT products.name, classifications.name " . - "FROM products, classifications " . - "WHERE classifications.id = products.classification_id " . - "ORDER BY classifications.name"); - while (@line = FetchSQLData()) { - my ($p,$c) = (@line); - if (!defined $::classifications{$c}) { - $::classifications{$c} = []; - } - my $ref = $::classifications{$c}; - push @$ref, $p; - } - - my $dotargetmilestone = 1; # This used to check the param, but there's - # enough code that wants to pretend we're using - # target milestones, even if they don't get - # shown to the user. So we cache all the data - # about them anyway. - - my $mpart = $dotargetmilestone ? ", milestoneurl" : ""; - - SendSQL("SELECT name, description, votesperuser, disallownew$mpart " . - "FROM products ORDER BY name"); - while (@line = FetchSQLData()) { - my ($p, $d, $votesperuser, $dis, $u) = (@line); - $::proddesc{$p} = $d; - if (!$dis && scalar($::components{$p})) { - push @::enterable_products, $p; - } - if ($dotargetmilestone) { - $::milestoneurl{$p} = $u; - } - $::prodmaxvotes{$p} = $votesperuser; - } - - @::log_columns = $dbh->bz_table_columns('bugs'); - - foreach my $i ("bug_id", "creation_ts", "delta_ts", "lastdiffed") { - my $w = lsearch(\@::log_columns, $i); - if ($w >= 0) { - splice(@::log_columns, $w, 1); - } - } - @::log_columns = (sort(@::log_columns)); - - @::legal_priority = get_legal_field_values("priority"); - @::legal_severity = get_legal_field_values("bug_severity"); - @::legal_platform = get_legal_field_values("rep_platform"); - @::legal_opsys = get_legal_field_values("op_sys"); - @::legal_bug_status = get_legal_field_values("bug_status"); - @::legal_resolution = get_legal_field_values("resolution"); - - # 'settable_resolution' is the list of resolutions that may be set - # directly by hand in the bug form. Start with the list of legal - # resolutions and remove 'MOVED' and 'DUPLICATE' because setting - # bugs to those resolutions requires a special process. - # - @::settable_resolution = @::legal_resolution; - my $w = lsearch(\@::settable_resolution, "DUPLICATE"); - if ($w >= 0) { - splice(@::settable_resolution, $w, 1); - } - my $z = lsearch(\@::settable_resolution, "MOVED"); - if ($z >= 0) { - splice(@::settable_resolution, $z, 1); - } - - my @list = sort { uc($a) cmp uc($b)} keys(%::versions); - @::legal_product = @list; - - require File::Temp; - my ($fh, $tmpname) = File::Temp::tempfile("versioncache.XXXXX", - DIR => "$datadir"); - - print $fh "#\n"; - print $fh "# DO NOT EDIT!\n"; - print $fh "# This file is automatically generated at least once every\n"; - print $fh "# hour by the GenerateVersionTable() sub in globals.pl.\n"; - print $fh "# Any changes you make will be overwritten.\n"; - print $fh "#\n"; - - require Data::Dumper; - print $fh (Data::Dumper->Dump([\@::log_columns, \%::versions], - ['*::log_columns', '*::versions'])); - - foreach my $i (@list) { - if (!defined $::components{$i}) { - $::components{$i} = []; - } - } - @::legal_versions = sort {uc($a) cmp uc($b)} keys(%varray); - print $fh (Data::Dumper->Dump([\@::legal_versions, \%::components], - ['*::legal_versions', '*::components'])); - @::legal_components = sort {uc($a) cmp uc($b)} keys(%carray); - - print $fh (Data::Dumper->Dump([\@::legal_components, \@::legal_product, - \@::legal_priority, \@::legal_severity, - \@::legal_platform, \@::legal_opsys, - \@::legal_bug_status, \@::legal_resolution], - ['*::legal_components', '*::legal_product', - '*::legal_priority', '*::legal_severity', - '*::legal_platform', '*::legal_opsys', - '*::legal_bug_status', '*::legal_resolution'])); - - print $fh (Data::Dumper->Dump([\@::settable_resolution, \%::proddesc, - \%::classifications, - \@::enterable_products, \%::prodmaxvotes], - ['*::settable_resolution', '*::proddesc', - '*::classifications', - '*::enterable_products', '*::prodmaxvotes'])); - - if ($dotargetmilestone) { - # reading target milestones in from the database - matthew@zeroknowledge.com - SendSQL("SELECT milestones.value, products.name " . - "FROM milestones, products " . - "WHERE products.id = milestones.product_id " . - "ORDER BY milestones.sortkey, milestones.value"); - my @line; - my %tmarray; - @::legal_target_milestone = (); - while(@line = FetchSQLData()) { - my ($tm, $pr) = (@line); - if (!defined $::target_milestone{$pr}) { - $::target_milestone{$pr} = []; - } - push @{$::target_milestone{$pr}}, $tm; - if (!exists $tmarray{$tm}) { - $tmarray{$tm} = 1; - push(@::legal_target_milestone, $tm); - } - } - - print $fh (Data::Dumper->Dump([\%::target_milestone, - \@::legal_target_milestone, - \%::milestoneurl], - ['*::target_milestone', - '*::legal_target_milestone', - '*::milestoneurl'])); - } - - SendSQL("SELECT id, name FROM keyworddefs ORDER BY name"); - while (MoreSQLData()) { - my ($id, $name) = FetchSQLData(); - push(@::legal_keywords, $name); - $name = lc($name); - $::keywordsbyname{$name} = $id; - } - - print $fh (Data::Dumper->Dump([\@::legal_keywords, \%::keywordsbyname], - ['*::legal_keywords', '*::keywordsbyname'])); - - print $fh "1;\n"; - close $fh; - - rename ($tmpname, "$datadir/versioncache") - || die "Can't rename $tmpname to versioncache"; - ChmodDataFile("$datadir/versioncache", 0666); -} - - -sub GetKeywordIdFromName { - my ($name) = (@_); - $name = lc($name); - return $::keywordsbyname{$name}; -} - - -$::VersionTableLoaded = 0; -sub GetVersionTable { - return if $::VersionTableLoaded; - my $file_generated = 0; - if (!-r "$datadir/versioncache") { - GenerateVersionTable(); - $file_generated = 1; - } - require "$datadir/versioncache"; - if (!defined %::versions && !$file_generated) { - GenerateVersionTable(); - do "$datadir/versioncache"; - } - if (!defined %::versions) { - die "Can't generate file $datadir/versioncache"; - } - $::VersionTableLoaded = 1; -} - -# -# This function checks if there are any entry groups defined. -# If called with no arguments, it identifies -# entry groups for all products. If called with a product -# id argument, it checks for entry groups associated with -# one particular product. -sub AnyEntryGroups { - my $product_id = shift; - $product_id = 0 unless ($product_id); - return $::CachedAnyEntryGroups{$product_id} - if defined($::CachedAnyEntryGroups{$product_id}); - my $dbh = Bugzilla->dbh; - PushGlobalSQLState(); - my $query = "SELECT 1 FROM group_control_map WHERE entry != 0"; - $query .= " AND product_id = $product_id" if ($product_id); - $query .= " " . $dbh->sql_limit(1); - SendSQL($query); - if (MoreSQLData()) { - $::CachedAnyEntryGroups{$product_id} = MoreSQLData(); - FetchSQLData(); - PopGlobalSQLState(); - return $::CachedAnyEntryGroups{$product_id}; - } else { - return undef; - } -} -# -# This function checks if there are any default groups defined. -# If so, then groups may have to be changed when bugs move from -# one bug to another. -sub AnyDefaultGroups { - return $::CachedAnyDefaultGroups if defined($::CachedAnyDefaultGroups); - my $dbh = Bugzilla->dbh; - PushGlobalSQLState(); - SendSQL("SELECT 1 FROM group_control_map, groups WHERE " . - "groups.id = group_control_map.group_id " . - "AND isactive != 0 AND " . - "(membercontrol = " . CONTROLMAPDEFAULT . - " OR othercontrol = " . CONTROLMAPDEFAULT . - ") " . $dbh->sql_limit(1)); - $::CachedAnyDefaultGroups = MoreSQLData(); - FetchSQLData(); - PopGlobalSQLState(); - return $::CachedAnyDefaultGroups; -} - -sub IsInClassification { - my ($classification,$productname) = @_; - - if (! Param('useclassification')) { - return 1; - } else { - my $query = "SELECT classifications.name " . - "FROM products,classifications " . - "WHERE products.classification_id=classifications.id "; - $query .= "AND products.name = " . SqlQuote($productname); - PushGlobalSQLState(); - SendSQL($query); - my ($ret) = FetchSQLData(); - PopGlobalSQLState(); - return ($ret eq $classification); - } -} - -sub ValidatePassword { - # Determines whether or not a password is valid (i.e. meets Bugzilla's - # requirements for length and content). - # If a second password is passed in, this function also verifies that - # the two passwords match. - my ($password, $matchpassword) = @_; - - if (length($password) < 3) { - ThrowUserError("password_too_short"); - } elsif (length($password) > 16) { - ThrowUserError("password_too_long"); - } elsif ((defined $matchpassword) && ($password ne $matchpassword)) { - ThrowUserError("passwords_dont_match"); - } - # Having done these checks makes us consider the password untainted. - trick_taint($_[0]); -} - -sub DBID_to_name { - my ($id) = (@_); - return "__UNKNOWN__" if !defined $id; - # $id should always be a positive integer - if ($id =~ m/^([1-9][0-9]*)$/) { - $id = $1; - } else { - $::cachedNameArray{$id} = "__UNKNOWN__"; - } - if (!defined $::cachedNameArray{$id}) { - PushGlobalSQLState(); - SendSQL("SELECT login_name FROM profiles WHERE userid = $id"); - my $r = FetchOneColumn(); - PopGlobalSQLState(); - if (!defined $r || $r eq "") { - $r = "__UNKNOWN__"; - } - $::cachedNameArray{$id} = $r; - } - return $::cachedNameArray{$id}; -} - -sub DBNameToIdAndCheck { - my ($name) = (@_); - my $result = login_to_id($name); - if ($result > 0) { - return $result; - } - - ThrowUserError("invalid_username", { name => $name }); -} - -sub get_product_id { - my ($prod) = @_; - PushGlobalSQLState(); - SendSQL("SELECT id FROM products WHERE name = " . SqlQuote($prod)); - my ($prod_id) = FetchSQLData(); - PopGlobalSQLState(); - return $prod_id; -} - -sub get_product_name { - my ($prod_id) = @_; - die "non-numeric prod_id '$prod_id' passed to get_product_name" - unless ($prod_id =~ /^\d+$/); - PushGlobalSQLState(); - SendSQL("SELECT name FROM products WHERE id = $prod_id"); - my ($prod) = FetchSQLData(); - PopGlobalSQLState(); - return $prod; -} - -sub get_component_id { - my ($prod_id, $comp) = @_; - return undef unless ($prod_id && ($prod_id =~ /^\d+$/)); - PushGlobalSQLState(); - SendSQL("SELECT id FROM components " . - "WHERE product_id = $prod_id AND name = " . SqlQuote($comp)); - my ($comp_id) = FetchSQLData(); - PopGlobalSQLState(); - return $comp_id; -} - -sub get_component_name { - my ($comp_id) = @_; - die "non-numeric comp_id '$comp_id' passed to get_component_name" - unless ($comp_id =~ /^\d+$/); - PushGlobalSQLState(); - SendSQL("SELECT name FROM components WHERE id = $comp_id"); - my ($comp) = FetchSQLData(); - PopGlobalSQLState(); - return $comp; -} - -# This routine quoteUrls contains inspirations from the HTML::FromText CPAN -# module by Gareth Rees <garethr@cre.canon.co.uk>. It has been heavily hacked, -# all that is really recognizable from the original is bits of the regular -# expressions. -# This has been rewritten to be faster, mainly by substituting 'as we go'. -# If you want to modify this routine, read the comments carefully - -sub quoteUrls { - my ($text, $curr_bugid) = (@_); - return $text unless $text; - - # We use /g for speed, but uris can have other things inside them - # (http://foo/bug#3 for example). Filtering that out filters valid - # bug refs out, so we have to do replacements. - # mailto can't contain space or #, so we don't have to bother for that - # Do this by escaping \0 to \1\0, and replacing matches with \0\0$count\0\0 - # \0 is used because its unlikely to occur in the text, so the cost of - # doing this should be very small - # Also, \0 won't appear in the value_quote'd bug title, so we don't have - # to worry about bogus substitutions from there - - # escape the 2nd escape char we're using - my $chr1 = chr(1); - $text =~ s/\0/$chr1\0/g; - - # However, note that adding the title (for buglinks) can affect things - # In particular, attachment matches go before bug titles, so that titles - # with 'attachment 1' don't double match. - # Dupe checks go afterwards, because that uses ^ and \Z, which won't occur - # if it was substituted as a bug title (since that always involve leading - # and trailing text) - - # Because of entities, its easier (and quicker) to do this before escaping - - my @things; - my $count = 0; - my $tmp; - - # non-mailto protocols - my $safe_protocols = join('|', SAFE_PROTOCOLS); - my $protocol_re = qr/($safe_protocols)/i; - - $text =~ s~\b(${protocol_re}: # The protocol: - [^\s<>\"]+ # Any non-whitespace - [\w\/]) # so that we end in \w or / - ~($tmp = html_quote($1)) && - ($things[$count++] = "<a href=\"$tmp\">$tmp</a>") && - ("\0\0" . ($count-1) . "\0\0") - ~egox; - - # We have to quote now, otherwise our html is itsself escaped - # THIS MEANS THAT A LITERAL ", <, >, ' MUST BE ESCAPED FOR A MATCH - - $text = html_quote($text); - - # mailto: - # Use |<nothing> so that $1 is defined regardless - $text =~ s~\b(mailto:|)?([\w\.\-\+\=]+\@[\w\-]+(?:\.[\w\-]+)+)\b - ~<a href=\"mailto:$2\">$1$2</a>~igx; - - # attachment links - handle both cases separately for simplicity - $text =~ s~((?:^Created\ an\ |\b)attachment\s*\(id=(\d+)\)(\s\[edit\])?) - ~($things[$count++] = GetAttachmentLink($2, $1)) && - ("\0\0" . ($count-1) . "\0\0") - ~egmx; - - $text =~ s~\b(attachment\s*\#?\s*(\d+)) - ~($things[$count++] = GetAttachmentLink($2, $1)) && - ("\0\0" . ($count-1) . "\0\0") - ~egmxi; - - # Current bug ID this comment belongs to - my $current_bugurl = $curr_bugid ? "show_bug.cgi?id=$curr_bugid" : ""; - - # This handles bug a, comment b type stuff. Because we're using /g - # we have to do this in one pattern, and so this is semi-messy. - # Also, we can't use $bug_re?$comment_re? because that will match the - # empty string - my $bug_re = qr/bug\s*\#?\s*(\d+)/i; - my $comment_re = qr/comment\s*\#?\s*(\d+)/i; - $text =~ s~\b($bug_re(?:\s*,?\s*$comment_re)?|$comment_re) - ~ # We have several choices. $1 here is the link, and $2-4 are set - # depending on which part matched - (defined($2) ? GetBugLink($2,$1,$3) : - "<a href=\"$current_bugurl#c$4\">$1</a>") - ~egox; - - # Old duplicate markers - $text =~ s~(?<=^\*\*\*\ This\ bug\ has\ been\ marked\ as\ a\ duplicate\ of\ ) - (\d+) - (?=\ \*\*\*\Z) - ~GetBugLink($1, $1) - ~egmx; - - # Now remove the encoding hacks - $text =~ s/\0\0(\d+)\0\0/$things[$1]/eg; - $text =~ s/$chr1\0/\0/g; - - return $text; -} - -# GetAttachmentLink creates a link to an attachment, -# including its title. - -sub GetAttachmentLink { - my ($attachid, $link_text) = @_; - detaint_natural($attachid) || - die "GetAttachmentLink() called with non-integer attachment number"; - - # If we've run GetAttachmentLink() for this attachment before, - # %::attachlink will contain an anonymous array ref of relevant - # values. If not, we need to get the information from the database. - if (! defined $::attachlink{$attachid}) { - # Make sure any unfetched data from a currently running query - # is saved off rather than overwritten - PushGlobalSQLState(); - - SendSQL("SELECT bug_id, isobsolete, description - FROM attachments WHERE attach_id = $attachid"); - - if (MoreSQLData()) { - my ($bugid, $isobsolete, $desc) = FetchSQLData(); - my $title = ""; - my $className = ""; - if (Bugzilla->user->can_see_bug($bugid)) { - $title = $desc; - } - if ($isobsolete) { - $className = "bz_obsolete"; - } - $::attachlink{$attachid} = [value_quote($title), $className]; - } - else { - # Even if there's nothing in the database, we want to save a blank - # anonymous array in the %::attachlink hash so the query doesn't get - # run again next time we're called for this attachment number. - $::attachlink{$attachid} = []; - } - # All done with this sidetrip - PopGlobalSQLState(); - } - - # Now that we know we've got all the information we're gonna get, let's - # return the link (which is the whole reason we were called :) - my ($title, $className) = @{$::attachlink{$attachid}}; - # $title will be undefined if the attachment didn't exist in the database. - if (defined $title) { - $link_text =~ s/ \[details\]$//; - my $linkval = "attachment.cgi?id=$attachid&action="; - # Whitespace matters here because these links are in <pre> tags. - return qq|<span class="$className">| - . qq|<a href="${linkval}view" title="$title">$link_text</a>| - . qq| <a href="${linkval}edit" title="$title">[details]</a>| - . qq|</span>|; - } - else { - return qq{$link_text}; - } -} - -# GetBugLink creates a link to a bug, including its title. -# It takes either two or three parameters: -# - The bug number -# - The link text, to place between the <a>..</a> -# - An optional comment number, for linking to a particular -# comment in the bug - -sub GetBugLink { - my ($bug_num, $link_text, $comment_num) = @_; - if (! defined $bug_num || $bug_num eq "") { - return "<missing bug number>"; - } - my $quote_bug_num = html_quote($bug_num); - detaint_natural($bug_num) || return "<invalid bug number: $quote_bug_num>"; - - # If we've run GetBugLink() for this bug number before, %::buglink - # will contain an anonymous array ref of relevent values, if not - # we need to get the information from the database. - if (! defined $::buglink{$bug_num}) { - # Make sure any unfetched data from a currently running query - # is saved off rather than overwritten - PushGlobalSQLState(); - - SendSQL("SELECT bugs.bug_status, resolution, short_desc " . - "FROM bugs WHERE bugs.bug_id = $bug_num"); - - # If the bug exists, save its data off for use later in the sub - if (MoreSQLData()) { - my ($bug_state, $bug_res, $bug_desc) = FetchSQLData(); - # Initialize these variables to be "" so that we don't get warnings - # if we don't change them below (which is highly likely). - my ($pre, $title, $post) = ("", "", ""); - - $title = $bug_state; - if ($bug_state eq 'UNCONFIRMED') { - $pre = "<i>"; - $post = "</i>"; - } - elsif (! IsOpenedState($bug_state)) { - $pre = '<span class="bz_closed">'; - $title .= " $bug_res"; - $post = '</span>'; - } - if (Bugzilla->user->can_see_bug($bug_num)) { - $title .= " - $bug_desc"; - } - $::buglink{$bug_num} = [$pre, value_quote($title), $post]; - } - else { - # Even if there's nothing in the database, we want to save a blank - # anonymous array in the %::buglink hash so the query doesn't get - # run again next time we're called for this bug number. - $::buglink{$bug_num} = []; - } - # All done with this sidetrip - PopGlobalSQLState(); - } - - # Now that we know we've got all the information we're gonna get, let's - # return the link (which is the whole reason we were called :) - my ($pre, $title, $post) = @{$::buglink{$bug_num}}; - # $title will be undefined if the bug didn't exist in the database. - if (defined $title) { - my $linkval = "show_bug.cgi?id=$bug_num"; - if (defined $comment_num) { - $linkval .= "#c$comment_num"; - } - return qq{$pre<a href="$linkval" title="$title">$link_text</a>$post}; - } - else { - return qq{$link_text}; - } -} - -# Returns a list of all the legal values for a field that has a -# list of legal values, like rep_platform or resolution. -sub get_legal_field_values { - my ($field) = @_; - my $dbh = Bugzilla->dbh; - my $result_ref = $dbh->selectcol_arrayref( - "SELECT value FROM $field - WHERE isactive = ? - ORDER BY sortkey, value", undef, (1)); - return @$result_ref; -} - -sub BugInGroupId { - my ($bugid, $groupid) = (@_); - PushGlobalSQLState(); - SendSQL("SELECT CASE WHEN bug_id != 0 THEN 1 ELSE 0 END - FROM bug_group_map - WHERE bug_id = $bugid - AND group_id = $groupid"); - my $bugingroup = FetchOneColumn(); - PopGlobalSQLState(); - return $bugingroup; -} - -sub GroupExists { - my ($groupname) = (@_); - PushGlobalSQLState(); - SendSQL("SELECT id FROM groups WHERE name=" . SqlQuote($groupname)); - my $id = FetchOneColumn(); - PopGlobalSQLState(); - return $id; -} - -sub GroupNameToId { - my ($groupname) = (@_); - PushGlobalSQLState(); - SendSQL("SELECT id FROM groups WHERE name=" . SqlQuote($groupname)); - my $id = FetchOneColumn(); - PopGlobalSQLState(); - return $id; -} - -sub GroupIdToName { - my ($groupid) = (@_); - PushGlobalSQLState(); - SendSQL("SELECT name FROM groups WHERE id = $groupid"); - my $name = FetchOneColumn(); - PopGlobalSQLState(); - return $name; -} - - -# Determines whether or not a group is active by checking -# the "isactive" column for the group in the "groups" table. -# Note: This function selects groups by id rather than by name. -sub GroupIsActive { - my ($groupid) = (@_); - $groupid ||= 0; - PushGlobalSQLState(); - SendSQL("SELECT isactive FROM groups WHERE id=$groupid"); - my $isactive = FetchOneColumn(); - PopGlobalSQLState(); - return $isactive; -} - -# Determines if the given bug_status string represents an "Opened" bug. This -# routine ought to be parameterizable somehow, as people tend to introduce -# new states into Bugzilla. - -sub IsOpenedState { - my ($state) = (@_); - if (grep($_ eq $state, OpenStates())) { - return 1; - } - return 0; -} - -# This sub will return an array containing any status that -# is considered an open bug. - -sub OpenStates { - return ('NEW', 'REOPENED', 'ASSIGNED', 'UNCONFIRMED'); -} - -############# Live code below here (that is, not subroutine defs) ############# - -use Bugzilla; - -1; diff --git a/images/CVS/Entries b/images/CVS/Entries index 9cb95dae2..80b52bfd6 100644 --- a/images/CVS/Entries +++ b/images/CVS/Entries @@ -1,2 +1,2 @@ -/padlock.png/1.2/Thu Sep 23 18:08:31 2004/-kb/TBUGZILLA-2_22_3 +/padlock.png/1.2/Thu Sep 23 18:08:31 2004/-kb/TBUGZILLA-3_0 D diff --git a/images/CVS/Tag b/images/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/images/CVS/Tag +++ b/images/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/importxml.pl b/importxml.pl index 53478b0e3..6e6f4a619 100755 --- a/importxml.pl +++ b/importxml.pl @@ -22,6 +22,7 @@ # Gregary Hendricks <ghendricks@novell.com> # Vance Baarda <vrb@novell.com> # Guzman Braso <gbn@hqso.net> +# Erik Purins <epurins@day1studios.com> # This script reads in xml bug data from standard input and inserts # a new bug into bugzilla. Everything before the beginning <?xml line @@ -80,11 +81,13 @@ use Bugzilla::Version; use Bugzilla::Component; use Bugzilla::Milestone; use Bugzilla::FlagType; -use Bugzilla::Config qw(:DEFAULT $datadir); use Bugzilla::BugMail; +use Bugzilla::Mailer; use Bugzilla::User; use Bugzilla::Util; use Bugzilla::Constants; +use Bugzilla::Keyword; +use Bugzilla::Field; use MIME::Base64; use MIME::Parser; @@ -93,11 +96,9 @@ use Getopt::Long; use Pod::Usage; use XML::Twig; -require "globals.pl"; - # We want to capture errors and handle them here rather than have the Template # code barf all over the place. -Bugzilla->batch(1); +Bugzilla->usage_mode(Bugzilla::Constants::USAGE_MODE_CMDLINE); my $debug = 0; my $mail = ''; @@ -117,37 +118,24 @@ use constant OK_LEVEL => 3; use constant DEBUG_LEVEL => 2; use constant ERR_LEVEL => 1; -GetVersionTable(); our @logs; our @attachments; our $bugtotal; my $xml; my $dbh = Bugzilla->dbh; +my $params = Bugzilla->params; my ($timestamp) = $dbh->selectrow_array("SELECT NOW()"); ############################################################################### # Helper sub routines # ############################################################################### -# This can go away as soon as data/versioncache is removed. Since we still -# have to use GetVersionTable() though, it stays for now. - -sub sillyness { - my $zz; - $zz = @::legal_bug_status; - $zz = @::legal_opsys; - $zz = @::legal_platform; - $zz = @::legal_priority; - $zz = @::legal_severity; - $zz = @::legal_resolution; -} - sub MailMessage { return unless ($mail); my $subject = shift; my $message = shift; my @recipients = @_; - my $from = Param("moved-from-address"); + my $from = $params->{"moved-from-address"}; $from =~ s/@/\@/g; foreach my $to (@recipients){ @@ -155,7 +143,7 @@ sub MailMessage { $header .= "From: Bugzilla <$from>\n"; $header .= "Subject: $subject\n\n"; my $sendmessage = $header . $message . "\n"; - Bugzilla::BugMail::MessageToMTA($sendmessage); + MessageToMTA($sendmessage); } } @@ -174,34 +162,13 @@ sub Error { my $subject = "Bug import error: $reason"; my $message = "Cannot import these bugs because $reason "; $message .= "\n\nPlease re-open the original bug.\n" if ($errtype); - $message .= "For more info, contact " . Param("maintainer") . ".\n"; - my @to = ( Param("maintainer"), $exporter); + $message .= "For more info, contact " . $params->{"maintainer"} . ".\n"; + my @to = ( $params->{"maintainer"}, $exporter); Debug( $message, ERR_LEVEL ); MailMessage( $subject, $message, @to ); exit; } -# This will be implemented in Bugzilla::Field as soon as bug 31506 lands -sub check_field { - my ($name, $value, $legalsRef, $no_warn) = @_; - my $dbh = Bugzilla->dbh; - - if (!defined($value) - || trim($value) eq "" - || (defined($legalsRef) && lsearch($legalsRef, $value) < 0)) - { - return 0 if $no_warn; # We don't want an error to be thrown; return. - - trick_taint($name); - my ($result) = $dbh->selectrow_array("SELECT description FROM fielddefs - WHERE name = ?", undef, $name); - - my $field = $result || $name; - ThrowCodeError('illegal_field', { field => $field }); - } - return 1; -} - # This subroutine handles flags for process_bug. It is generic in that # it can handle both attachment flags and bug flags. sub flag_handler { @@ -214,7 +181,7 @@ sub flag_handler { my $type = ($attachid) ? "attachment" : "bug"; my $err = ''; - my $setter = Bugzilla::User->new_from_login($setter_login); + my $setter = new Bugzilla::User({ name => $setter_login }); my $requestee; my $requestee_id; @@ -230,7 +197,7 @@ sub flag_handler { } my $setter_id = $setter->id; if ( defined($requestee_login) ) { - $requestee = Bugzilla::User->new_from_login($requestee_login); + $requestee = new Bugzilla::User({ name => $requestee_login }); if ( $requestee ) { if ( !$requestee->can_see_bug($bugid) ) { $err .= "Requestee is not a member of bug group\n"; @@ -259,7 +226,7 @@ sub flag_handler { } ); } else { - my $bug = new Bugzilla::Bug( $bugid, $exporterid ); + my $bug = new Bugzilla::Bug($bugid); $flag_types = $bug->flag_types; } unless ($flag_types){ @@ -273,24 +240,24 @@ sub flag_handler { # If this is the case, we will only match the first one. my $ftype; foreach my $f ( @{$flag_types} ) { - if ( $f->{'name'} eq $name) { + if ( $f->name eq $name) { $ftype = $f; last; } } if ($ftype) { # We found the flag in the list - my $grant_gid = $ftype->{'grant_gid'}; + my $grant_group = $ftype->grant_group; if (( $status eq '+' || $status eq '-' ) - && $grant_gid && !$setter->in_group_id($grant_gid)) { + && $grant_group && !$setter->in_group_id($grant_group->id)) { $err = "Setter $setter_login on $type flag $name "; $err .= "is not in the Grant Group\n"; $err .= " Dropping flag $name\n"; return $err; } - my $request_gid = $ftype->{'request_gid'}; - if ($request_gid - && $status eq '?' && !$setter->in_group_id($request_gid)) { + my $request_group = $ftype->request_group; + if ($request_group + && $status eq '?' && !$setter->in_group_id($request_group->id)) { $err = "Setter $setter_login on $type flag $name "; $err .= "is not in the Request Group\n"; $err .= " Dropping flag $name\n"; @@ -298,22 +265,18 @@ sub flag_handler { } # Take the first flag_type that matches - my $ftypeid = $ftype->{'id'}; - my $is_active = $ftype->{'is_active'}; - unless ($is_active) { + unless ($ftype->is_active) { $err = "Flag $name is not active in this database\n"; $err .= " Dropping flag $name\n"; return $err; } - my ($fid) = $dbh->selectrow_array("SELECT MAX(id) FROM flags") || 0; $dbh->do("INSERT INTO flags - (id, type_id, status, bug_id, attach_id, creation_date, - setter_id, requestee_id, is_active) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", undef, - ++$fid, $ftypeid, $status, $bugid, $attachid, $timestamp, - $setter_id, $requestee_id, 1 - ); + (type_id, status, bug_id, attach_id, creation_date, + setter_id, requestee_id) + VALUES (?, ?, ?, ?, ?, ?, ?)", undef, + ($ftype->id, $status, $bugid, $attachid, $timestamp, + $setter_id, $requestee_id)); } else { $err = "Dropping unknown $type flag: $name\n"; @@ -333,7 +296,7 @@ sub flag_handler { # exporter: email address of the person moving the bugs # maintainer: the maintainer of the bugzilla installation # as set in the parameters file -# urlbase: The urlbase paramter of the installation +# urlbase: The urlbase parameter of the installation # bugs are being moved from # sub init() { @@ -344,33 +307,33 @@ sub init() { my $urlbase = $root->{'att'}->{'urlbase'}; my $xmlversion = $root->{'att'}->{'version'}; - if ($xmlversion ne $Bugzilla::Config::VERSION) { + if ($xmlversion ne BUGZILLA_VERSION) { my $log = "Possible version conflict!\n"; $log .= " XML was exported from Bugzilla version $xmlversion\n"; $log .= " But this installation uses "; - $log .= $Bugzilla::Config::VERSION . "\n"; + $log .= BUGZILLA_VERSION . "\n"; Debug($log, OK_LEVEL); push(@logs, $log); } Error( "no maintainer", "REOPEN", $exporter ) unless ($maintainer); Error( "no exporter", "REOPEN", $exporter ) unless ($exporter); - Error( "bug importing is disabled here", undef, $exporter ) unless ( Param("move-enabled") ); + Error( "bug importing is disabled here", undef, $exporter ) unless ( $params->{"move-enabled"} ); Error( "invalid exporter: $exporter", "REOPEN", $exporter ) if ( !login_to_id($exporter) ); Error( "no urlbase set", "REOPEN", $exporter ) unless ($urlbase); my $def_product = - new Bugzilla::Product( { name => Param("moved-default-product") } ) + new Bugzilla::Product( { name => $params->{"moved-default-product"} } ) || Error("Cannot import these bugs because an invalid default product was defined for the target db." - . Param("maintainer") . " needs to fix the definitions of + . $params->{"maintainer"} . " needs to fix the definitions of moved-default-product. \n", "REOPEN", $exporter); my $def_component = new Bugzilla::Component( { - product_id => $def_product->id, - name => Param("moved-default-component") + product => $def_product, + name => $params->{"moved-default-component"} }) || Error("Cannot import these bugs because an invalid default component was defined for the target db." - . Param("maintainer") . " needs to fix the definitions of + . $params->{"maintainer"} . " needs to fix the definitions of moved-default-component.\n", "REOPEN", $exporter); } @@ -462,7 +425,7 @@ sub process_bug { my $root = $twig->root; my $maintainer = $root->{'att'}->{'maintainer'}; my $exporter_login = $root->{'att'}->{'exporter'}; - my $exporter = Bugzilla::User->new_from_login($exporter_login); + my $exporter = new Bugzilla::User({ name => $exporter_login }); my $urlbase = $root->{'att'}->{'urlbase'}; # We will store output information in this variable. @@ -536,7 +499,7 @@ sub process_bug { $long_desc{'isprivate'} = $comment->{'att'}->{'isprivate'} || 0; # if one of the comments is private we need to set this flag - if ( $long_desc{'isprivate'} && $exporter->in_group(Param('insidergroup'))) { + if ( $long_desc{'isprivate'} && $exporter->in_group($params->{'insidergroup'})) { $private = 1; } my $data = $comment->field('thetext'); @@ -594,7 +557,7 @@ sub process_bug { $comments .= "\n\n--- Bug imported by $exporter_login "; $comments .= time2str( "%Y-%m-%d %H:%M", time ) . " "; - $comments .= Param('timezone'); + $comments .= $params->{'timezone'}; $comments .= " ---\n\n"; $comments .= "This bug was previously known as _bug_ $bug_fields{'bug_id'} at "; $comments .= $urlbase . "show_bug.cgi?id=" . $bug_fields{'bug_id'} . "\n"; @@ -658,11 +621,11 @@ sub process_bug { # Product and Component if there is no valid default product and # component defined in the parameters, we wouldn't be here my $def_product = - new Bugzilla::Product( { name => Param("moved-default-product") } ); + new Bugzilla::Product( { name => $params->{"moved-default-product"} } ); my $def_component = new Bugzilla::Component( { - product_id => $def_product->id, - name => Param("moved-default-component") + product => $def_product, + name => $params->{"moved-default-component"} } ); my $product; @@ -682,8 +645,8 @@ sub process_bug { if ( defined $bug_fields{'component'} ) { $component = new Bugzilla::Component( { - product_id => $product->id, - name => $bug_fields{'component'} + product => $product, + name => $bug_fields{'component'} } ); unless ($component) { @@ -710,8 +673,8 @@ sub process_bug { # Since there is no default version for a product, we check that the one # coming over is valid. If not we will use the first one in @versions # and warn them. - my $version = - new Bugzilla::Version( $product->id, $bug_fields{'version'} ); + my $version = new Bugzilla::Version( + { product => $product, name => $bug_fields{'version'} }); push( @query, "version" ); if ($version) { @@ -730,14 +693,13 @@ sub process_bug { } # Milestone - if ( Param("usetargetmilestone") ) { + if ( $params->{"usetargetmilestone"} ) { my $milestone; - if (defined $bug_fields{'target_milestone'} + if (defined $bug_fields{'target_milestone'} && $bug_fields{'target_milestone'} ne "") { - $milestone = - new Bugzilla::Milestone( $product->id, - $bug_fields{'target_milestone'} ); + $milestone = new Bugzilla::Milestone( + { product => $product, name => $bug_fields{'target_milestone'} }); } if ($milestone) { push( @values, $milestone->name ); @@ -759,73 +721,73 @@ sub process_bug { # imported is valid. If it is not we use the defaults set in the parameters. if (defined( $bug_fields{'bug_severity'} ) && check_field('bug_severity', scalar $bug_fields{'bug_severity'}, - \@::legal_severity, ERR_LEVEL) ) + undef, ERR_LEVEL) ) { push( @values, $bug_fields{'bug_severity'} ); } else { - push( @values, Param('defaultseverity') ); + push( @values, $params->{'defaultseverity'} ); $err .= "Unknown severity "; $err .= ( defined $bug_fields{'bug_severity'} ) ? $bug_fields{'bug_severity'} : "unknown"; $err .= ". Setting to default severity \""; - $err .= Param('defaultseverity') . "\".\n"; + $err .= $params->{'defaultseverity'} . "\".\n"; } push( @query, "bug_severity" ); if (defined( $bug_fields{'priority'} ) && check_field('priority', scalar $bug_fields{'priority'}, - \@::legal_priority, ERR_LEVEL ) ) + undef, ERR_LEVEL ) ) { push( @values, $bug_fields{'priority'} ); } else { - push( @values, Param('defaultpriority') ); + push( @values, $params->{'defaultpriority'} ); $err .= "Unknown priority "; $err .= ( defined $bug_fields{'priority'} ) ? $bug_fields{'priority'} : "unknown"; $err .= ". Setting to default priority \""; - $err .= Param('defaultpriority') . "\".\n"; + $err .= $params->{'defaultpriority'} . "\".\n"; } push( @query, "priority" ); if (defined( $bug_fields{'rep_platform'} ) && check_field('rep_platform', scalar $bug_fields{'rep_platform'}, - \@::legal_platform, ERR_LEVEL ) ) + undef, ERR_LEVEL ) ) { push( @values, $bug_fields{'rep_platform'} ); } else { - push( @values, Param('defaultplatform') ); + push( @values, $params->{'defaultplatform'} ); $err .= "Unknown platform "; $err .= ( defined $bug_fields{'rep_platform'} ) ? $bug_fields{'rep_platform'} : "unknown"; $err .=". Setting to default platform \""; - $err .= Param('defaultplatform') . "\".\n"; + $err .= $params->{'defaultplatform'} . "\".\n"; } push( @query, "rep_platform" ); if (defined( $bug_fields{'op_sys'} ) && check_field('op_sys', scalar $bug_fields{'op_sys'}, - \@::legal_opsys, ERR_LEVEL ) ) + undef, ERR_LEVEL ) ) { push( @values, $bug_fields{'op_sys'} ); } else { - push( @values, Param('defaultopsys') ); + push( @values, $params->{'defaultopsys'} ); $err .= "Unknown operating system "; $err .= ( defined $bug_fields{'op_sys'} ) ? $bug_fields{'op_sys'} : "unknown"; - $err .= ". Setting to default OS \"" . Param('defaultopsys') . "\".\n"; + $err .= ". Setting to default OS \"" . $params->{'defaultopsys'} . "\".\n"; } push( @query, "op_sys" ); # Process time fields - if ( Param("timetrackinggroup") ) { + if ( $params->{"timetrackinggroup"} ) { my $date = format_time( $bug_fields{'deadline'}, "%Y-%m-%d" ) || undef; push( @values, $date ); @@ -905,7 +867,7 @@ sub process_bug { } } - if ( Param("useqacontact") ) { + if ( $params->{"useqacontact"} ) { my $qa_contact; push( @query, "qa_contact" ); if ( ( defined $bug_fields{'qa_contact'}) @@ -926,11 +888,11 @@ sub process_bug { my $has_status = defined($bug_fields{'bug_status'}); my $valid_res = check_field('resolution', scalar $bug_fields{'resolution'}, - \@::legal_resolution, ERR_LEVEL ); + undef, ERR_LEVEL ); my $valid_status = check_field('bug_status', scalar $bug_fields{'bug_status'}, - \@::legal_bug_status, ERR_LEVEL ); - my $is_open = IsOpenedState($bug_fields{'bug_status'}); + undef, ERR_LEVEL ); + my $is_open = is_open_state($bug_fields{'bug_status'}); my $status = $bug_fields{'bug_status'} || undef; my $resolution = $bug_fields{'resolution'} || undef; @@ -1046,6 +1008,27 @@ sub process_bug { push( @query, "bug_status" ); push( @values, $status ); + # Custom fields + foreach my $custom_field (Bugzilla->custom_field_names) { + next unless defined($bug_fields{$custom_field}); + my $field = new Bugzilla::Field({name => $custom_field}); + if ($field->type == FIELD_TYPE_FREETEXT) { + push(@query, $custom_field); + push(@values, clean_text($bug_fields{$custom_field})); + } elsif ($field->type == FIELD_TYPE_SINGLE_SELECT) { + my $is_well_formed = check_field($custom_field, scalar $bug_fields{$custom_field}, + undef, ERR_LEVEL); + if ($is_well_formed) { + push(@query, $custom_field); + push(@values, $bug_fields{$custom_field}); + } else { + $err .= "Skipping illegal value \"$bug_fields{$custom_field}\" in $custom_field.\n" ; + } + } else { + $err .= "Type of custom field $custom_field is an unhandled FIELD_TYPE: " . + $field->type . "\n"; + } + } # For the sake of sanitycheck.cgi we do this. # Update lastdiffed if you do not want to have mail sent @@ -1104,14 +1087,14 @@ sub process_bug { ); foreach my $keyword ( split( /[\s,]+/, $bug_fields{'keywords'} )) { next unless $keyword; - my $i = GetKeywordIdFromName($keyword); - if ( !$i ) { + my $keyword_obj = new Bugzilla::Keyword({name => $keyword}); + if (!$keyword_obj) { $err .= "Skipping unknown keyword: $keyword.\n"; next; } - if ( !$keywordseen{$i} ) { - $key_sth->execute( $id, $i ); - $keywordseen{$i} = 1; + if (!$keywordseen{$keyword_obj->id}) { + $key_sth->execute($id, $keyword_obj->id); + $keywordseen{$keyword_obj->id} = 1; } } my ($keywordarray) = $dbh->selectcol_arrayref( @@ -1143,7 +1126,7 @@ sub process_bug { $err .= "No attachment ID specified, dropping attachment\n"; next; } - if (!$exporter->in_group(Param('insidergroup')) && $att->{'isprivate'}){ + if (!$exporter->in_group($params->{'insidergroup'}) && $att->{'isprivate'}){ $err .= "Exporter not in insidergroup and attachment marked private.\n"; $err .= " Marking attachment public\n"; $att->{'isprivate'} = 0; @@ -1182,7 +1165,7 @@ sub process_bug { # Insert longdesc and append any errors my $worktime = $bug_fields{'actual_time'} || 0.0; - $worktime = 0.0 if (!$exporter->in_group(Param('timetrackinggroup'))); + $worktime = 0.0 if (!$exporter->in_group($params->{'timetrackinggroup'})); $long_description .= "\n" . $comments; if ($err) { $long_description .= "\n$err\n"; @@ -1206,7 +1189,7 @@ sub process_bug { $log .= "Bug ${urlbase}show_bug.cgi?id=$bug_fields{'bug_id'} "; $log .= "imported as bug $id.\n"; - $log .= Param("urlbase") . "show_bug.cgi?id=$id\n\n"; + $log .= $params->{"urlbase"} . "show_bug.cgi?id=$id\n\n"; if ($err) { $log .= "The following problems were encountered while creating bug $id.\n"; $log .= $err; @@ -1227,11 +1210,11 @@ Debug( "Reading xml", DEBUG_LEVEL ); local ($/); $xml = <>; -# If there's anything besides whitespace before <?xml then we guess it's a mail +# If there's anything except whitespace before <?xml then we guess it's a mail # and MIME::Parser should parse it. Else don't. if ($xml =~ m/\S.*<\?xml/s ) { - # If the email was encoded (BugMail::MessageToMTA() does it when using UTF-8), + # If the email was encoded (Mailer::MessageToMTA() does it when using UTF-8), # we have to decode it first, else the XML parsing will fail. my $parser = MIME::Parser->new; $parser->output_to_core(1); @@ -1263,7 +1246,7 @@ my $urlbase = $root->{'att'}->{'urlbase'}; my $log = join("\n\n", @logs); $log .= "\n\nImported $bugtotal bug(s) from $urlbase,\n sent by $exporter.\n"; my $subject = "$bugtotal Bug(s) successfully moved from $urlbase to " - . Param("urlbase"); + . $params->{"urlbase"}; my @to = ($exporter, $maintainer); MailMessage( $subject, $log, @to ); @@ -1304,7 +1287,7 @@ importxml - Import bugzilla bug data from xml. =back =head1 DESCRIPTION - + This script is used to import bugs from another installation of bugzilla. It can be used in two ways. First using the move function of bugzilla @@ -1314,14 +1297,14 @@ importxml - Import bugzilla bug data from xml. run by this script and imported into your database. Run 'newaliases' after adding this alias to your aliases file. Make sure your sendmail installation is configured to allow mail aliases to execute code. - + bugzilla-import: "|/usr/bin/perl /opt/bugzilla/importxml.pl --mail" - + Second it can be run from the command line with any xml file from STDIN that conforms to the bugzilla DTD. In this case you can pass an argument to set whether you want to send the mail that will be sent to the exporter and maintainer normally. - + importxml.pl [options] bugsfile.xml =cut diff --git a/index.cgi b/index.cgi index a35be0726..7d1525b58 100755 --- a/index.cgi +++ b/index.cgi @@ -19,7 +19,7 @@ # Rights Reserved. # # Contributor(s): Jacob Steenhagen <jake@bugzilla.org> -# +# Frédéric Buclin <LpSolit@gmail.com> ############################################################################### # Script Initialization @@ -30,28 +30,43 @@ use strict; # Include the Bugzilla CGI and general utility library. use lib "."; -require "globals.pl"; -# Check whether or not the user is logged in +use Bugzilla; use Bugzilla::Constants; -Bugzilla->login(LOGIN_OPTIONAL); +use Bugzilla::Error; +use Bugzilla::Update; + +# Check whether or not the user is logged in +my $user = Bugzilla->login(LOGIN_OPTIONAL); ############################################################################### # Main Body Execution ############################################################################### my $cgi = Bugzilla->cgi; -# Force to use HTTPS unless Param('ssl') equals 'never'. +# Force to use HTTPS unless Bugzilla->params->{'ssl'} equals 'never'. # This is required because the user may want to log in from here. -if (Param('sslbase') ne '' and Param('ssl') ne 'never') { - $cgi->require_https(Param('sslbase')); +if (Bugzilla->params->{'sslbase'} ne '' and Bugzilla->params->{'ssl'} ne 'never') { + $cgi->require_https(Bugzilla->params->{'sslbase'}); } my $template = Bugzilla->template; +my $vars = {}; # Return the appropriate HTTP response headers. print $cgi->header(); +if ($user->in_group('admin')) { + # If 'urlbase' is not set, display the Welcome page. + unless (Bugzilla->params->{'urlbase'}) { + $template->process('welcome-admin.html.tmpl') + || ThrowTemplateError($template->error()); + exit; + } + # Inform the administrator about new releases, if any. + $vars->{'release'} = Bugzilla::Update::get_notifications(); +} + # Generate and return the UI (HTML page) from the appropriate template. -$template->process("index.html.tmpl") +$template->process("index.html.tmpl", $vars) || ThrowTemplateError($template->error()); diff --git a/js/CVS/Entries b/js/CVS/Entries index fc6f0e802..07157773e 100644 --- a/js/CVS/Entries +++ b/js/CVS/Entries @@ -1,4 +1,6 @@ -/TUI.js/1.1/Tue Jul 12 12:32:16 2005//TBUGZILLA-2_22_3 -/duplicates.js/1.2/Sun Jan 25 18:47:16 2004//TBUGZILLA-2_22_3 -/productform.js/1.2/Fri Aug 20 21:49:18 2004//TBUGZILLA-2_22_3 +/TUI.js/1.1/Tue Jul 12 12:32:16 2005//TBUGZILLA-3_0 +/attachment.js/1.1.2.2/Wed Mar 7 08:00:42 2007//TBUGZILLA-3_0 +/duplicates.js/1.2/Sun Jan 25 18:47:16 2004//TBUGZILLA-3_0 +/expanding-tree.js/1.2/Wed Feb 22 22:02:09 2006//TBUGZILLA-3_0 +/productform.js/1.2/Fri Aug 20 21:49:18 2004//TBUGZILLA-3_0 D diff --git a/js/CVS/Tag b/js/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/js/CVS/Tag +++ b/js/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/js/attachment.js b/js/attachment.js new file mode 100644 index 000000000..eb42ba492 --- /dev/null +++ b/js/attachment.js @@ -0,0 +1,106 @@ +/* The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Bugzilla Bug Tracking System. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): Myk Melez <myk@mozilla.org> + * Joel Peshkin <bugreport@peshkin.net> + * Erik Stambaugh <erik@dasbistro.com> + * Marc Schumann <wurblzap@gmail.com> + */ + +function updateCommentPrivacy(checkbox) { + var text_elem = document.getElementById('comment'); + if (checkbox.checked) { + text_elem.className='bz_private'; + } else { + text_elem.className=''; + } +} + +function setContentTypeDisabledState(form) +{ + var isdisabled = false; + if (form.ispatch.checked) + isdisabled = true; + + for (var i=0 ; i<form.contenttypemethod.length ; i++) + form.contenttypemethod[i].disabled = isdisabled; + + form.contenttypeselection.disabled = isdisabled; + form.contenttypeentry.disabled = isdisabled; +} + +function URLFieldHandler() { + var field_attachurl = document.getElementById("attachurl"); + var greyfields = new Array("data", "ispatch", "autodetect", + "list", "manual", "bigfile", + "contenttypeselection", + "contenttypeentry"); + var i, thisfield; + if (field_attachurl.value.match(/^\s*$/)) { + for (i = 0; i < greyfields.length; i++) { + thisfield = document.getElementById(greyfields[i]); + if (thisfield) { + thisfield.removeAttribute("disabled"); + } + } + } else { + for (i = 0; i < greyfields.length; i++) { + thisfield = document.getElementById(greyfields[i]); + if (thisfield) { + thisfield.setAttribute("disabled", "disabled"); + } + } + } +} + +function DataFieldHandler() { + var field_data = document.getElementById("data"); + var greyfields = new Array("attachurl"); + var i, thisfield; + if (field_data.value.match(/^\s*$/)) { + for (i = 0; i < greyfields.length; i++) { + thisfield = document.getElementById(greyfields[i]); + if (thisfield) { + thisfield.removeAttribute("disabled"); + } + } + } else { + for (i = 0; i < greyfields.length; i++) { + thisfield = document.getElementById(greyfields[i]); + if (thisfield) { + thisfield.setAttribute("disabled", "disabled"); + } + } + } +} + +function clearAttachmentFields() { + var element; + + document.getElementById('data').value = ''; + DataFieldHandler(); + if ((element = document.getElementById('bigfile'))) + element.checked = ''; + if ((element = document.getElementById('attachurl'))) { + element.value = ''; + URLFieldHandler(); + } + document.getElementById('description').value = ''; + document.getElementById('ispatch').checked = ''; + if ((element = document.getElementById('isprivate'))) + element.checked = ''; +} diff --git a/js/expanding-tree.js b/js/expanding-tree.js new file mode 100644 index 000000000..d210a629c --- /dev/null +++ b/js/expanding-tree.js @@ -0,0 +1,157 @@ +/* The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Bugzilla Bug Tracking System. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): Mike Shaver <shaver@mozilla.org> + * Christian Reis <kiko@async.com.br> + * Andr� Batosti <batosti@async.com.br> + */ + +if (!Node) { + // MSIE doesn't define Node, so provide a compatibility object + var Node = { TEXT_NODE: 3 } +} + +if (!highlighted) { + var highlighted = 0; + var highlightedclass = ""; + var highlightedover = 0; +} + +function doToggle(node, event) { + var deep = event.altKey || event.ctrlKey; + + if (node.nodeType == Node.TEXT_NODE) + node = node.parentNode; + + var toggle = node.nextSibling; + while (toggle && toggle.tagName != "UL") + toggle = toggle.nextSibling; + + if (toggle) { + if (deep) { + var direction = toggleDisplay(toggle, node); + changeChildren(toggle, direction); + } else { + toggleDisplay(toggle, node); + } + } + /* avoid problems with default actions on links (mozilla's + * ctrl/shift-click defaults, for instance */ + event.preventBubble(); + event.preventDefault(); + return false; +} + +function changeChildren(node, direction) { + var item = node.firstChild; + while (item) { + /* find the LI inside the UL I got */ + while (item && item.tagName != "LI") + item = item.nextSibling; + if (!item) + return; + + /* got it, now find the first A */ + var child = item.firstChild; + while (child && child.tagName != "A") + child = child.nextSibling; + if (!child) { + return + } + var bullet = child; + + /* and check if it has its own sublist */ + var sublist = item.firstChild; + while (sublist && sublist.tagName != "UL") + sublist = sublist.nextSibling; + if (sublist) { + if (direction && isClosed(sublist)) { + openNode(sublist, bullet); + } else if (!direction && !isClosed(sublist)) { + closeNode(sublist, bullet); + } + changeChildren(sublist, direction) + } + item = item.nextSibling; + } +} + +function openNode(node, bullet) { + node.style.display = "block"; + bullet.className = "b b_open"; +} + +function closeNode(node, bullet) { + node.style.display = "none"; + bullet.className = "b b_closed"; +} + +function isClosed(node) { + /* XXX we should in fact check our *computed* style, not the display + * attribute of the current node, which may be inherited and not + * set. However, this really only matters when changing the default + * appearance of the tree through a parent style. */ + return node.style.display == "none"; +} + +function toggleDisplay(node, bullet) { + if (isClosed(node)) { + openNode(node, bullet); + return true; + } + + closeNode(node, bullet); + return false; +} + +function duplicated(element) { + var allsumm= document.getElementsByTagName("span"); + if (highlighted) { + for (i = 0;i < allsumm.length; i++) { + if (allsumm.item(i).id == highlighted) { + allsumm.item(i).className = highlightedclass; + } + } + if (highlighted == element) { + highlighted = 0; + return; + } + } + highlighted = element; + var elem = document.getElementById(element); + highlightedclass = elem.className; + for (var i = 0;i < allsumm.length; i++) { + if (allsumm.item(i).id == element) { + allsumm.item(i).className = "summ_h"; + } + } +} + +function duplicatedover(element) { + if (!highlighted) { + highlightedover = 1; + duplicated(element); + } +} + +function duplicatedout(element) { + if (highlighted == element && highlightedover) { + highlightedover = 0; + duplicated(element); + } +} + diff --git a/mod_perl.pl b/mod_perl.pl new file mode 100644 index 000000000..cb2f635f9 --- /dev/null +++ b/mod_perl.pl @@ -0,0 +1,114 @@ +#!/usr/bin/perl -wT +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + +package Bugzilla::ModPerl; + +use strict; + +# If you have an Apache2::Status handler in your Apache configuration, +# you need to load Apache2::Status *here*, so that Apache::DBI can +# report information to Apache2::Status. +#use Apache2::Status (); + +# We don't want to import anything into the global scope during +# startup, so we always specify () after using any module in this +# file. + +use Apache::DBI (); +use Apache2::ServerUtil; +use Apache2::SizeLimit; +use ModPerl::RegistryLoader (); +use CGI (); +CGI->compile(qw(:cgi -no_xhtml -oldstyle_urls :private_tempfiles + :unique_headers SERVER_PUSH :push)); +use Template::Config (); +Template::Config->preload(); + +use Bugzilla (); +use Bugzilla::Constants (); +use Bugzilla::CGI (); +use Bugzilla::Mailer (); +use Bugzilla::Template (); +use Bugzilla::Util (); + +# This means that every httpd child will die after processing +# a CGI if it is taking up more than 70MB of RAM all by itself. +$Apache2::SizeLimit::MAX_UNSHARED_SIZE = 70000; + +my $cgi_path = Bugzilla::Constants::bz_locations()->{'cgi_path'}; + +# Set up the configuration for the web server +my $server = Apache2::ServerUtil->server; +my $conf = <<EOT; +<Directory "$cgi_path"> + AddHandler perl-script .cgi + # No need to PerlModule these because they're already defined in mod_perl.pl + PerlResponseHandler Bugzilla::ModPerl::ResponseHandler + PerlCleanupHandler Bugzilla::ModPerl::CleanupHandler + PerlCleanupHandler Apache2::SizeLimit + PerlOptions +ParseHeaders + Options +ExecCGI + AllowOverride Limit + DirectoryIndex index.cgi index.html +</Directory> +EOT + +$server->add_config([split("\n", $conf)]); + +# Have ModPerl::RegistryLoader pre-compile all CGI scripts. +my $rl = new ModPerl::RegistryLoader(); +# Note that $cgi_path will be wrong if somebody puts the libraries +# in a different place than the CGIs. +foreach my $file (glob "$cgi_path/*.cgi") { + Bugzilla::Util::trick_taint($file); + $rl->handler($file, $file); +} + + +package Bugzilla::ModPerl::ResponseHandler; +use strict; +use base qw(ModPerl::Registry); +use Bugzilla; + +sub handler : method { + my $class = shift; + + # $0 is broken under mod_perl before 2.0.2, so we have to set it + # here explicitly or init_page's shutdownhtml code won't work right. + $0 = $ENV{'SCRIPT_FILENAME'}; + Bugzilla::init_page(); + return $class->SUPER::handler(@_); +} + + +package Bugzilla::ModPerl::CleanupHandler; +use strict; +use Apache2::Const -compile => qw(OK); + +sub handler { + my $r = shift; + + # Sometimes mod_perl doesn't properly call DESTROY on all + # the objects in pnotes() + foreach my $key (keys %{$r->pnotes}) { + delete $r->pnotes->{$key}; + } + + return Apache2::Const::OK; +} + +1; diff --git a/page.cgi b/page.cgi index b160cf021..43a826590 100755 --- a/page.cgi +++ b/page.cgi @@ -33,8 +33,7 @@ use strict; use lib "."; use Bugzilla; - -require "globals.pl"; +use Bugzilla::Error; Bugzilla->login(); diff --git a/post_bug.cgi b/post_bug.cgi index d15f7c558..f755934ae 100755 --- a/post_bug.cgi +++ b/post_bug.cgi @@ -22,31 +22,25 @@ # Dan Mosedale <dmose@mozilla.org> # Joe Robins <jmrobins@tgix.com> # Gervase Markham <gerv@gerv.net> +# Marc Schumann <wurblzap@gmail.com> use strict; use lib qw(.); -require "globals.pl"; use Bugzilla; +use Bugzilla::Attachment; +use Bugzilla::BugMail; use Bugzilla::Constants; use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::Bug; use Bugzilla::User; use Bugzilla::Field; - -# Shut up misguided -w warnings about "used only once". For some reason, -# "use vars" chokes on me when I try it here. -sub sillyness { - my $zz; - $zz = %::components; - $zz = %::versions; - $zz = @::legal_opsys; - $zz = @::legal_platform; - $zz = @::legal_priority; - $zz = @::legal_product; - $zz = @::legal_severity; - $zz = %::target_milestone; -} +use Bugzilla::Product; +use Bugzilla::Component; +use Bugzilla::Keyword; +use Bugzilla::Token; +use Bugzilla::Flag; my $user = Bugzilla->login(LOGIN_REQUIRED); @@ -55,44 +49,48 @@ my $dbh = Bugzilla->dbh; my $template = Bugzilla->template; my $vars = {}; +###################################################################### +# Main Script +###################################################################### + +# Detect if the user already used the same form to submit a bug +my $token = trim($cgi->param('token')); +if ($token) { + my ($creator_id, $date, $old_bug_id) = Bugzilla::Token::GetTokenData($token); + unless ($creator_id + && ($creator_id == $user->id) + && ($old_bug_id =~ "^createbug:")) + { + # The token is invalid. + ThrowUserError('token_inexistent'); + } + + $old_bug_id =~ s/^createbug://; + + if ($old_bug_id && (!$cgi->param('ignore_token') + || ($cgi->param('ignore_token') != $old_bug_id))) + { + $vars->{'bugid'} = $old_bug_id; + $vars->{'allow_override'} = defined $cgi->param('ignore_token') ? 0 : 1; + + print $cgi->header(); + $template->process("bug/create/confirm-create-dupe.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + exit; + } +} + # do a match on the fields if applicable &Bugzilla::User::match_field ($cgi, { 'cc' => { 'type' => 'multi' }, 'assigned_to' => { 'type' => 'single' }, 'qa_contact' => { 'type' => 'single' }, + '^requestee_type-(\d+)$' => { 'type' => 'multi' }, }); -# The format of the initial comment can be structured by adding fields to the -# enter_bug template and then referencing them in the comment template. -my $comment; - -my $format = $template->get_format("bug/create/comment", - scalar($cgi->param('format')), "txt"); - -$template->process($format->{'template'}, $vars, \$comment) - || ThrowTemplateError($template->error()); - -ValidateComment($comment); - -# Check that the product exists and that the user -# is allowed to enter bugs into this product. -my $product = $cgi->param('product'); -$user->can_enter_product($product, 1); - -my $product_id = get_product_id($product); - -# Set cookies -if (defined $cgi->param('product')) { - if (defined $cgi->param('version')) { - $cgi->send_cookie(-name => "VERSION-$product", - -value => $cgi->param('version'), - -expires => "Fri, 01-Jan-2038 00:00:00 GMT"); - } -} - if (defined $cgi->param('maketemplate')) { - $vars->{'url'} = $cgi->query_string(); + $vars->{'url'} = $cgi->canonicalise_query('token'); $vars->{'short_desc'} = $cgi->param('short_desc'); print $cgi->header(); @@ -103,389 +101,141 @@ if (defined $cgi->param('maketemplate')) { umask 0; -# Some sanity checking -my $component_id = get_component_id($product_id, - scalar($cgi->param('component'))); -$component_id || ThrowUserError("require_component"); - -# Set the parameter to itself, but cleaned up -$cgi->param('short_desc', clean_text($cgi->param('short_desc'))); - -if (!defined $cgi->param('short_desc') - || $cgi->param('short_desc') eq "") { - ThrowUserError("require_summary"); -} - -# Check that if required a description has been provided -# This has to go somewhere after 'maketemplate' -# or it breaks bookmarks with no comments. -if (Param("commentoncreate") && !trim($cgi->param('comment'))) { - ThrowUserError("description_required"); -} - -# If bug_file_loc is "http://", the default, use an empty value instead. -$cgi->param('bug_file_loc', '') if $cgi->param('bug_file_loc') eq 'http://'; - -my $sql_product = SqlQuote($cgi->param('product')); -my $sql_component = SqlQuote($cgi->param('component')); - -# Default assignee is the component owner. -if (!UserInGroup("editbugs") || $cgi->param('assigned_to') eq "") { - SendSQL("SELECT initialowner FROM components " . - "WHERE id = $component_id"); - $cgi->param(-name => 'assigned_to', -value => FetchOneColumn()); -} else { - $cgi->param(-name => 'assigned_to', - -value => DBNameToIdAndCheck(trim($cgi->param('assigned_to')))); -} - -my @bug_fields = ("version", "rep_platform", - "bug_severity", "priority", "op_sys", "assigned_to", - "bug_status", "everconfirmed", "bug_file_loc", "short_desc", - "target_milestone", "status_whiteboard"); - -if (Param("usebugaliases")) { - my $alias = trim($cgi->param('alias') || ""); - if ($alias ne "") { - ValidateBugAlias($alias); - $cgi->param('alias', $alias); - push (@bug_fields,"alias"); - } -} - -# Retrieve the default QA contact if the field is empty -if (Param("useqacontact")) { - my $qa_contact; - if (!UserInGroup("editbugs") || !defined $cgi->param('qa_contact') - || trim($cgi->param('qa_contact')) eq "") { - SendSQL("SELECT initialqacontact FROM components " . - "WHERE id = $component_id"); - $qa_contact = FetchOneColumn(); - } else { - $qa_contact = DBNameToIdAndCheck(trim($cgi->param('qa_contact'))); - } - - if ($qa_contact) { - $cgi->param(-name => 'qa_contact', -value => $qa_contact); - push(@bug_fields, "qa_contact"); - } -} - -my $votes_to_confirm = $dbh->selectrow_array('SELECT votestoconfirm - FROM products WHERE id = ?', - undef, $product_id); -my $bug_status = 'UNCONFIRMED'; -if ($votes_to_confirm) { - # Default to NEW if the user with privs hasn't selected another status. - if (UserInGroup('editbugs') || UserInGroup('canconfirm')) { - $bug_status = scalar($cgi->param('bug_status')) || 'NEW'; - } -} else { - $bug_status = 'NEW'; -} -$cgi->param(-name => 'bug_status', -value => $bug_status); - -if (!defined $cgi->param('target_milestone')) { - SendSQL("SELECT defaultmilestone FROM products WHERE name=$sql_product"); - $cgi->param(-name => 'target_milestone', -value => FetchOneColumn()); -} +# get current time +my $timestamp = $dbh->selectrow_array(q{SELECT NOW()}); -if (!Param('letsubmitterchoosepriority')) { - $cgi->param(-name => 'priority', -value => Param('defaultpriority')); +# Group Validation +my @selected_groups; +foreach my $group (grep(/^bit-\d+$/, $cgi->param())) { + $group =~ /^bit-(\d+)$/; + push(@selected_groups, $1); } -GetVersionTable(); - -# Some more sanity checking -check_form_field($cgi, 'product', \@::legal_product); -check_form_field($cgi, 'rep_platform', \@::legal_platform); -check_form_field($cgi, 'bug_severity', \@::legal_severity); -check_form_field($cgi, 'priority', \@::legal_priority); -check_form_field($cgi, 'op_sys', \@::legal_opsys); -check_form_field($cgi, 'bug_status', ['UNCONFIRMED', 'NEW']); -check_form_field($cgi, 'version', $::versions{$product}); -check_form_field($cgi, 'component', $::components{$product}); -check_form_field($cgi, 'target_milestone', $::target_milestone{$product}); -check_form_field_defined($cgi, 'assigned_to'); -check_form_field_defined($cgi, 'bug_file_loc'); -check_form_field_defined($cgi, 'comment'); - -my $everconfirmed = ($cgi->param('bug_status') eq 'UNCONFIRMED') ? 0 : 1; -$cgi->param(-name => 'everconfirmed', -value => $everconfirmed); - -my @used_fields; +# The format of the initial comment can be structured by adding fields to the +# enter_bug template and then referencing them in the comment template. +my $comment; +my $format = $template->get_format("bug/create/comment", + scalar($cgi->param('format')), "txt"); +$template->process($format->{'template'}, $vars, \$comment) + || ThrowTemplateError($template->error()); + +# Include custom fields editable on bug creation. +my @custom_bug_fields = Bugzilla->get_fields( + { custom => 1, obsolete => 0, enter_bug => 1 }); + +# Undefined custom fields are ignored to ensure they will get their default +# value (e.g. "---" for custom single select fields). +my @bug_fields = grep { defined $cgi->param($_->name) } @custom_bug_fields; +@bug_fields = map { $_->name } @bug_fields; + +# Custom tables must be locked (required when validating custom fields). +my @custom_tables = grep { $_->type == FIELD_TYPE_SINGLE_SELECT } @custom_bug_fields; +@custom_tables = map { $_->name . ' READ' } @custom_tables; + +push(@bug_fields, qw( + product + component + + assigned_to + qa_contact + + alias + blocked + commentprivacy + bug_file_loc + bug_severity + bug_status + dependson + keywords + short_desc + op_sys + priority + rep_platform + version + target_milestone + status_whiteboard + + estimated_time + deadline +)); +my %bug_params; foreach my $field (@bug_fields) { - if (defined $cgi->param($field)) { - push (@used_fields, $field); - } + $bug_params{$field} = $cgi->param($field); } +$bug_params{'creation_ts'} = $timestamp; +$bug_params{'cc'} = [$cgi->param('cc')]; +$bug_params{'groups'} = \@selected_groups; +$bug_params{'comment'} = $comment; -$cgi->param(-name => 'product_id', -value => $product_id); -push(@used_fields, "product_id"); -$cgi->param(-name => 'component_id', -value => $component_id); -push(@used_fields, "component_id"); - -my %ccids; - -# Create the ccid hash for inserting into the db -# use a hash rather than a list to avoid adding users twice -if (defined $cgi->param('cc')) { - foreach my $person ($cgi->param('cc')) { - next unless $person; - my $ccid = DBNameToIdAndCheck($person); - if ($ccid && !$ccids{$ccid}) { - $ccids{$ccid} = 1; - } - } -} -# Check for valid keywords and create list of keywords to be added to db -# (validity routine copied from process_bug.cgi) -my @keywordlist; -my %keywordseen; - -if ($cgi->param('keywords') && UserInGroup("editbugs")) { - foreach my $keyword (split(/[\s,]+/, $cgi->param('keywords'))) { - if ($keyword eq '') { - next; - } - my $i = GetKeywordIdFromName($keyword); - if (!$i) { - ThrowUserError("unknown_keyword", - { keyword => $keyword }); - } - if (!$keywordseen{$i}) { - push(@keywordlist, $i); - $keywordseen{$i} = 1; - } - } -} - -if (Param("strict_isolation")) { - my @blocked_users = (); - my %related_users = %ccids; - $related_users{$cgi->param('assigned_to')} = 1; - if (Param('useqacontact') && $cgi->param('qa_contact')) { - $related_users{$cgi->param('qa_contact')} = 1; - } - foreach my $pid (keys %related_users) { - my $related_user = Bugzilla::User->new($pid); - if (!$related_user->can_edit_product($product_id)) { - push (@blocked_users, $related_user->login); - } - } - if (scalar(@blocked_users)) { - ThrowUserError("invalid_user_group", - {'users' => \@blocked_users, - 'new' => 1, - 'product' => $product - }); - } -} - -# Check for valid dependency info. -foreach my $field ("dependson", "blocked") { - if (UserInGroup("editbugs") && $cgi->param($field)) { - my @validvalues; - foreach my $id (split(/[\s,]+/, $cgi->param($field))) { - next unless $id; - # $field is not passed to ValidateBugID to prevent adding new - # dependencies on inaccessible bugs. - ValidateBugID($id); - push(@validvalues, $id); - } - $cgi->param(-name => $field, -value => join(",", @validvalues)); - } -} -# Gather the dependency list, and make sure there are no circular refs -my %deps; -if (UserInGroup("editbugs")) { - %deps = Bugzilla::Bug::ValidateDependencies(scalar($cgi->param('dependson')), - scalar($cgi->param('blocked'))); -} - -# get current time -SendSQL("SELECT NOW()"); -my $timestamp = FetchOneColumn(); -my $sql_timestamp = SqlQuote($timestamp); - -# Build up SQL string to add bug. -# creation_ts will only be set when all other fields are defined. -my $sql = "INSERT INTO bugs " . - "(" . join(",", @used_fields) . ", reporter, delta_ts, " . - "estimated_time, remaining_time, deadline) " . - "VALUES ("; - -foreach my $field (@used_fields) { - $sql .= SqlQuote($cgi->param($field)) . ","; -} - -$comment =~ s/\r\n?/\n/g; # Get rid of \r. -$comment = trim($comment); -# If comment is all whitespace, it'll be null at this point. That's -# OK except for the fact that it causes e-mail to be suppressed. -$comment = $comment ? $comment : " "; - -$sql .= $user->id . ", $sql_timestamp, "; - -# Time Tracking -if (UserInGroup(Param("timetrackinggroup")) && - defined $cgi->param('estimated_time')) { - - my $est_time = $cgi->param('estimated_time'); - Bugzilla::Bug::ValidateTime($est_time, 'estimated_time'); - $sql .= SqlQuote($est_time) . "," . SqlQuote($est_time) . ","; -} else { - $sql .= "0, 0, "; -} +my $bug = Bugzilla::Bug->create(\%bug_params); -if ((UserInGroup(Param("timetrackinggroup"))) && ($cgi->param('deadline'))) { - validate_date($cgi->param('deadline')) - || ThrowUserError('illegal_date', {date => $cgi->param('deadline'), - format => 'YYYY-MM-DD'}); - $sql .= SqlQuote($cgi->param('deadline')); -} else { - $sql .= "NULL"; +# Get the bug ID back. +my $id = $bug->bug_id; + +# Set Version cookie, but only if the user actually selected +# a version on the page. +if (defined $cgi->param('version')) { + $cgi->send_cookie(-name => "VERSION-" . $bug->product, + -value => $bug->version, + -expires => "Fri, 01-Jan-2038 00:00:00 GMT"); } -$sql .= ")"; - -# Groups -my @groupstoadd = (); -foreach my $b (grep(/^bit-\d*$/, $cgi->param())) { - if ($cgi->param($b)) { - my $v = substr($b, 4); - detaint_natural($v) - || ThrowUserError("invalid_group_ID"); - if (!GroupIsActive($v)) { - # Prevent the user from adding the bug to an inactive group. - # Should only happen if there is a bug in Bugzilla or the user - # hacked the "enter bug" form since otherwise the UI - # for adding the bug to the group won't appear on that form. - $vars->{'bit'} = $v; - ThrowCodeError("inactive_group"); - } - my ($membercontrol, $othercontrol) = - $dbh->selectrow_array('SELECT membercontrol, othercontrol - FROM group_control_map - WHERE group_id = ? AND product_id = ?', - undef, ($v, $product_id)); - - # If these values are undefined or zero, then this group - # cannot be a valid one for this product. - next unless ($membercontrol || $othercontrol); - - my $permit = ($user->in_group_id($v) - && ($membercontrol == CONTROLMAPSHOWN - || $membercontrol == CONTROLMAPDEFAULT)) - || - (!$user->in_group_id($v) - && ($othercontrol == CONTROLMAPSHOWN - || $othercontrol == CONTROLMAPDEFAULT)); - - if ($permit) { - push(@groupstoadd, $v) +# We don't have to check if the user can see the bug, because a user filing +# a bug can always see it. You can't change reporter_accessible until +# after the bug is filed. + +# Add an attachment if requested. +if (defined($cgi->upload('data')) || $cgi->param('attachurl')) { + $cgi->param('isprivate', $cgi->param('commentprivacy')); + my $attach_id = Bugzilla::Attachment->insert_attachment_for_bug(!THROW_ERROR, + $bug, $user, $timestamp, \$vars); + + if ($attach_id) { + # Update the comment to include the new attachment ID. + # This string is hardcoded here because Template::quoteUrls() + # expects to find this exact string. + my $new_comment = "Created an attachment (id=$attach_id)\n" . + $cgi->param('description') . "\n"; + # We can use $bug->longdescs here because we are sure that the bug + # description is of type CMT_NORMAL. No need to include it if it's + # empty, though. + if ($bug->longdescs->[0]->{'body'} !~ /^\s+$/) { + $new_comment .= "\n" . $bug->longdescs->[0]->{'body'}; } + $bug->update_comment($bug->longdescs->[0]->{'id'}, $new_comment); } -} - -SendSQL("SELECT DISTINCT groups.id, groups.name, " . - "membercontrol, othercontrol, description " . - "FROM groups LEFT JOIN group_control_map " . - "ON group_id = id AND product_id = $product_id " . - " WHERE isbuggroup != 0 AND isactive != 0 ORDER BY description"); -while (MoreSQLData()) { - my ($id, $groupname, $membercontrol, $othercontrol ) = FetchSQLData(); - $membercontrol ||= 0; - $othercontrol ||= 0; - # Add groups required - if (($membercontrol == CONTROLMAPMANDATORY) - || (($othercontrol == CONTROLMAPMANDATORY) - && (!UserInGroup($groupname)))) { - # User had no option, bug needs to be in this group. - push(@groupstoadd, $id) + else { + $vars->{'message'} = 'attachment_creation_failed'; } -} - -# Add the bug report to the DB. -$dbh->bz_lock_tables('bugs WRITE', 'bug_group_map WRITE', 'longdescs WRITE', - 'cc WRITE', 'keywords WRITE', 'dependencies WRITE', - 'bugs_activity WRITE', 'groups READ', - 'user_group_map READ', 'group_group_map READ', - 'keyworddefs READ', 'fielddefs READ'); - -SendSQL($sql); - -# Get the bug ID back. -my $id = $dbh->bz_last_key('bugs', 'bug_id'); - -# Add the group restrictions -foreach my $grouptoadd (@groupstoadd) { - SendSQL("INSERT INTO bug_group_map (bug_id, group_id) - VALUES ($id, $grouptoadd)"); -} - -# Add the initial comment, allowing for the fact that it may be private -my $privacy = 0; -if (Param("insidergroup") && UserInGroup(Param("insidergroup"))) { - $privacy = $cgi->param('commentprivacy') ? 1 : 0; -} - -SendSQL("INSERT INTO longdescs (bug_id, who, bug_when, thetext, isprivate) - VALUES ($id, " . SqlQuote($user->id) . ", $sql_timestamp, " . - SqlQuote($comment) . ", $privacy)"); -# Insert the cclist into the database -foreach my $ccid (keys(%ccids)) { - SendSQL("INSERT INTO cc (bug_id, who) VALUES ($id, $ccid)"); + # Determine if Patch Viewer is installed, for Diff link + eval { + require PatchReader; + $vars->{'patchviewerinstalled'} = 1; + }; } -my @all_deps; -if (UserInGroup("editbugs")) { - foreach my $keyword (@keywordlist) { - SendSQL("INSERT INTO keywords (bug_id, keywordid) - VALUES ($id, $keyword)"); - } - if (@keywordlist) { - # Make sure that we have the correct case for the kw - SendSQL("SELECT name FROM keyworddefs WHERE id IN ( " . - join(',', @keywordlist) . ") ORDER BY name"); - my @list; - while (MoreSQLData()) { - push (@list, FetchOneColumn()); - } - SendSQL("UPDATE bugs SET delta_ts = $sql_timestamp," . - " keywords = " . SqlQuote(join(', ', @list)) . - " WHERE bug_id = $id"); - } - if ($cgi->param('dependson') || $cgi->param('blocked')) { - my $sth_bug_time = $dbh->prepare('UPDATE bugs SET delta_ts = ? WHERE bug_id = ?'); - foreach my $pair (["blocked", "dependson"], ["dependson", "blocked"]) { - my ($me, $target) = @{$pair}; - - foreach my $i (@{$deps{$target}}) { - SendSQL("INSERT INTO dependencies ($me, $target) values " . - "($id, $i)"); - push(@all_deps, $i); # list for mailing dependent bugs - # Log the activity for the other bug: - LogActivityEntry($i, $me, "", $id, $user->id, $timestamp); - $sth_bug_time->execute($timestamp, $i); - } - } - } +# Add flags, if any. To avoid dying if something goes wrong +# while processing flags, we will eval() flag validation. +# This requires errors to die(). +# XXX: this can go away as soon as flag validation is able to +# fail without dying. +my $error_mode_cache = Bugzilla->error_mode; +Bugzilla->error_mode(ERROR_MODE_DIE); +eval { + Bugzilla::Flag::validate($cgi, $id, undef, SKIP_REQUESTEE_ON_ERROR); + Bugzilla::Flag::process($bug, undef, $timestamp, $cgi); +}; +Bugzilla->error_mode($error_mode_cache); +if ($@) { + $vars->{'message'} = 'flag_creation_failed'; + $vars->{'flag_creation_error'} = $@; } -# All fields related to the newly created bug are set. -# The bug can now be made accessible. -$dbh->do("UPDATE bugs SET creation_ts = ? WHERE bug_id = ?", - undef, ($timestamp, $id)); - -$dbh->bz_unlock_tables(); - # Email everyone the details of the new bug $vars->{'mailrecipients'} = {'changer' => $user->login}; $vars->{'id'} = $id; -my $bug = new Bugzilla::Bug($id, $user->id); $vars->{'bug'} = $bug; ThrowCodeError("bug_error", { bug => $bug }) if $bug->error; @@ -496,7 +246,7 @@ push (@{$vars->{'sentmail'}}, { type => 'created', id => $id, }); -foreach my $i (@all_deps) { +foreach my $i (@{$bug->dependson || []}, @{$bug->blocked || []}) { push (@{$vars->{'sentmail'}}, { type => 'dep', id => $i, }); } @@ -505,9 +255,21 @@ if ($cgi->cookie("BUGLIST")) { @bug_list = split(/:/, $cgi->cookie("BUGLIST")); } $vars->{'bug_list'} = \@bug_list; +$vars->{'use_keywords'} = 1 if Bugzilla::Keyword::keyword_count(); -print $cgi->header(); -$template->process("bug/create/created.html.tmpl", $vars) - || ThrowTemplateError($template->error()); +if ($token) { + trick_taint($token); + $dbh->do('UPDATE tokens SET eventdata = ? WHERE token = ?', undef, + ("createbug:$id", $token)); +} +if (Bugzilla->usage_mode == USAGE_MODE_EMAIL) { + Bugzilla::BugMail::Send($id, $vars->{'mailrecipients'}); +} +else { + print $cgi->header(); + $template->process("bug/create/created.html.tmpl", $vars) + || ThrowTemplateError($template->error()); +} +1; diff --git a/process_bug.cgi b/process_bug.cgi index 6d58cfaeb..ffca2fab4 100755 --- a/process_bug.cgi +++ b/process_bug.cgi @@ -26,6 +26,7 @@ # Jeff Hedlund <jeff.hedlund@matrixsi.com> # Frédéric Buclin <LpSolit@gmail.com> # Lance Larsh <lance.larsh@oracle.com> +# Akamai Technologies <bugzilla-dev@akamai.com> # Implementation notes for this file: # @@ -41,49 +42,82 @@ use strict; -my $UserInEditGroupSet = -1; -my $UserInCanConfirmGroupSet = -1; -my $PrivilegesRequired = 0; -my $lastbugid = 0; - use lib qw(.); -require "globals.pl"; use Bugzilla; use Bugzilla::Constants; use Bugzilla::Bug; use Bugzilla::BugMail; +use Bugzilla::Mailer; use Bugzilla::User; use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::Field; - -# Use the Flag module to modify flag data if the user set flags. +use Bugzilla::Product; +use Bugzilla::Component; +use Bugzilla::Keyword; use Bugzilla::Flag; -use Bugzilla::FlagType; - -# Shut up misguided -w warnings about "used only once": - -use vars qw(@legal_product - %versions - %components - %legal_opsys - %legal_platform - %legal_priority - %settable_resolution - %target_milestone - %legal_severity - ); my $user = Bugzilla->login(LOGIN_REQUIRED); -my $whoid = $user->id; +local our $whoid = $user->id; my $grouplist = $user->groups_as_string; my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; my $template = Bugzilla->template; -my $vars = {}; +local our $vars = {}; +$vars->{'use_keywords'} = 1 if Bugzilla::Keyword::keyword_count(); + +my @editable_bug_fields = editable_bug_fields(); my $requiremilestone = 0; +local our $PrivilegesRequired = 0; + +###################################################################### +# Subroutines +###################################################################### + +sub BugInGroupId { + my ($bug_id, $group_id) = @_; + detaint_natural($bug_id); + detaint_natural($group_id); + my ($in_group) = Bugzilla->dbh->selectrow_array( + "SELECT CASE WHEN bug_id != 0 THEN 1 ELSE 0 END + FROM bug_group_map + WHERE bug_id = ? AND group_id = ?", undef, ($bug_id, $group_id)); + return $in_group; +} + +# This function checks if there are any default groups defined. +# If so, then groups may have to be changed when bugs move from +# one bug to another. +sub AnyDefaultGroups { + my $dbh = Bugzilla->dbh; + my $any_default = + $dbh->selectrow_array('SELECT 1 + FROM group_control_map + INNER JOIN groups + ON groups.id = group_control_map.group_id + WHERE isactive != 0 + AND (membercontrol = ? OR othercontrol = ?) ' . + $dbh->sql_limit(1), + undef, (CONTROLMAPDEFAULT, CONTROLMAPDEFAULT)); + return $any_default; +} + +# Used to send email when an update is done. +sub send_results { + my ($bug_id, $vars) = @_; + my $template = Bugzilla->template; + if (Bugzilla->usage_mode == USAGE_MODE_EMAIL) { + Bugzilla::BugMail::Send($bug_id, $vars->{'mailrecipients'}); + } + else { + $template->process("bug/process/results.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + } + $vars->{'header_done'} = 1; +} ###################################################################### # Begin Data/Security Validation @@ -117,6 +151,11 @@ if (defined $cgi->param('id')) { # Make sure there are bugs to process. scalar(@idlist) || ThrowUserError("no_bugs_chosen"); +# Build a bug object using $cgi->param('id') as ID. +# If there are more than one bug changed at once, the bug object will be +# empty, which doesn't matter. +my $bug = new Bugzilla::Bug(scalar $cgi->param('id')); + # Make sure form param 'dontchange' is defined so it can be compared to easily. $cgi->param('dontchange','') unless defined $cgi->param('dontchange'); @@ -133,7 +172,7 @@ foreach my $field ("estimated_time", "work_time", "remaining_time") { } } -if (UserInGroup(Param('timetrackinggroup'))) { +if (Bugzilla->user->in_group(Bugzilla->params->{'timetrackinggroup'})) { my $wk_time = $cgi->param('work_time'); if ($cgi->param('comment') =~ /^\s*$/ && $wk_time && $wk_time != 0) { ThrowUserError('comment_required'); @@ -150,7 +189,6 @@ ValidateComment(scalar $cgi->param('comment')); # during validation. foreach my $field ("dependson", "blocked") { if ($cgi->param('id')) { - my $bug = new Bugzilla::Bug($cgi->param('id'), $user->id); my @old = @{$bug->$field}; my @new; foreach my $id (split(/[\s,]+/, $cgi->param($field))) { @@ -164,16 +202,17 @@ foreach my $field ("dependson", "blocked") { # ValidateBugID is called without $field here so that it will # throw an error if any of the changed bugs are not visible. ValidateBugID($id); - if (Param("strict_isolation")) { - my $deltabug = new Bugzilla::Bug($id, $user->id); + if (Bugzilla->params->{"strict_isolation"}) { + my $deltabug = new Bugzilla::Bug($id); if (!$user->can_edit_product($deltabug->{'product_id'})) { $vars->{'field'} = $field; ThrowUserError("illegal_change_deps", $vars); } } } - if ((@$added || @$removed) - && (!CheckCanChangeField($field, $bug->bug_id, 0, 1))) { + if ((@$added || @$removed) + && !$bug->check_can_change_field($field, 0, 1, \$PrivilegesRequired)) + { $vars->{'privs'} = $PrivilegesRequired; $vars->{'field'} = $field; ThrowUserError("illegal_change", $vars); @@ -188,8 +227,8 @@ foreach my $field ("dependson", "blocked") { # do a match on the fields if applicable -# The order of these function calls is important, as both Flag::validate -# and FlagType::validate assume User::match_field has ensured that the values +# The order of these function calls is important, as Flag::validate +# assumes User::match_field has ensured that the values # in the requestee fields are legitimate user email addresses. &Bugzilla::User::match_field($cgi, { 'qa_contact' => { 'type' => 'single' }, @@ -202,22 +241,21 @@ foreach my $field ("dependson", "blocked") { # Validate flags in all cases. validate() should not detect any # reference to flags if $cgi->param('id') is undefined. Bugzilla::Flag::validate($cgi, $cgi->param('id')); -Bugzilla::FlagType::validate($cgi, $cgi->param('id')); ###################################################################### # End Data/Security Validation ###################################################################### -print $cgi->header(); +print $cgi->header() unless Bugzilla->usage_mode == USAGE_MODE_EMAIL; $vars->{'title_tag'} = "bug_processed"; # Set the title if we can see a mid-air coming. This test may have false # negatives, but never false positives, and should catch the majority of cases. # It only works at all in the single bug case. if (defined $cgi->param('id')) { - SendSQL("SELECT delta_ts FROM bugs WHERE bug_id = " . - $cgi->param('id')); - my $delta_ts = FetchOneColumn(); + my $delta_ts = $dbh->selectrow_array( + q{SELECT delta_ts FROM bugs WHERE bug_id = ?}, + undef, $cgi->param('id')); if (defined $cgi->param('delta_ts') && $cgi->param('delta_ts') ne $delta_ts) { @@ -232,22 +270,16 @@ if ($cgi->cookie("BUGLIST") && defined $cgi->param('id')) { $vars->{'bug_list'} = \@bug_list; } -GetVersionTable(); - -check_form_field_defined($cgi, 'product'); -check_form_field_defined($cgi, 'version'); -check_form_field_defined($cgi, 'component'); - - # This function checks if there is a comment required for a specific # function and tests, if the comment was given. # If comments are required for functions is defined by params. # sub CheckonComment { my ($function) = (@_); + my $cgi = Bugzilla->cgi; # Param is 1 if comment should be added ! - my $ret = Param( "commenton" . $function ); + my $ret = Bugzilla->params->{ "commenton" . $function }; # Allow without comment in case of undefined Params. $ret = 0 unless ( defined( $ret )); @@ -271,20 +303,25 @@ sub CheckonComment { # and bug groups if so. my $oldproduct = ''; if (defined $cgi->param('id')) { - SendSQL("SELECT name FROM products INNER JOIN bugs " . - "ON products.id = bugs.product_id WHERE bug_id = " . - $cgi->param('id')); - $oldproduct = FetchSQLData(); + $oldproduct = $dbh->selectrow_array( + q{SELECT name FROM products INNER JOIN bugs + ON products.id = bugs.product_id WHERE bug_id = ?}, + undef, $cgi->param('id')); } +# At this point, the product must be defined, even if set to "dontchange". +defined($cgi->param('product')) + || ThrowCodeError('undefined_field', { field => 'product' }); + if (((defined $cgi->param('id') && $cgi->param('product') ne $oldproduct) || (!$cgi->param('id') && $cgi->param('product') ne $cgi->param('dontchange'))) && CheckonComment( "reassignbycomponent" )) { # Check to make sure they actually have the right to change the product - if (!CheckCanChangeField('product', scalar $cgi->param('id'), $oldproduct, - $cgi->param('product'))) { + if (!$bug->check_can_change_field('product', $oldproduct, $cgi->param('product'), + \$PrivilegesRequired)) + { $vars->{'oldvalue'} = $oldproduct; $vars->{'newvalue'} = $cgi->param('product'); $vars->{'field'} = 'product'; @@ -293,6 +330,7 @@ if (((defined $cgi->param('id') && $cgi->param('product') ne $oldproduct) } my $prod = $cgi->param('product'); + my $prod_obj = new Bugzilla::Product({name => $prod}); trick_taint($prod); # If at least one bug does not belong to the product we are @@ -320,45 +358,87 @@ if (((defined $cgi->param('id') && $cgi->param('product') ne $oldproduct) # pretty weird case, and not terribly unreasonable behavior, but # worthy of a comment, perhaps. # - my $vok = lsearch($::versions{$prod}, $cgi->param('version')) >= 0; - my $cok = lsearch($::components{$prod}, $cgi->param('component')) >= 0; - - my $mok = 1; # so it won't affect the 'if' statement if milestones aren't used - if ( Param("usetargetmilestone") ) { - check_form_field_defined($cgi, 'target_milestone'); - $mok = lsearch($::target_milestone{$prod}, - $cgi->param('target_milestone')) >= 0; + my @version_names = map($_->name, @{$prod_obj->versions}); + my @component_names = map($_->name, @{$prod_obj->components}); + my $vok = 0; + if (defined $cgi->param('version')) { + $vok = lsearch(\@version_names, $cgi->param('version')) >= 0; + } + my $cok = 0; + if (defined $cgi->param('component')) { + $cok = lsearch(\@component_names, $cgi->param('component')) >= 0; } - # If the product-specific fields need to be verified, or we need to verify - # whether or not to add the bugs to their new product's group, display - # a verification form. - if (!$vok || !$cok || !$mok || (AnyDefaultGroups() - && !defined $cgi->param('addtonewgroup'))) { + my $mok = 1; # so it won't affect the 'if' statement if milestones aren't used + my @milestone_names = (); + if ( Bugzilla->params->{"usetargetmilestone"} ) { + @milestone_names = map($_->name, @{$prod_obj->milestones}); + $mok = 0; + if (defined $cgi->param('target_milestone')) { + $mok = lsearch(\@milestone_names, $cgi->param('target_milestone')) >= 0; + } + } + + # We cannot be sure if the component is the same by only checking $cok; the + # current component name could exist in the new product. So always display + # the form and use the confirm_product_change param to check if that was + # shown. Also show the verification form if the product-specific fields + # somehow still need to be verified, or if we need to verify whether or not + # to add the bugs to their new product's group. + if (!$vok || !$cok || !$mok || !defined $cgi->param('confirm_product_change') + || (AnyDefaultGroups() && !defined $cgi->param('addtonewgroup'))) { + + if (Bugzilla->usage_mode == USAGE_MODE_EMAIL) { + if (!$vok) { + ThrowUserError('version_not_valid', { + version => $cgi->param('version'), + product => $cgi->param('product')}); + } + if (!$cok) { + ThrowUserError('component_not_valid', { + product => $cgi->param('product'), + name => $cgi->param('component')}); + } + if (!$mok) { + ThrowUserError('milestone_not_valid', { + product => $cgi->param('product'), + milestone => $cgi->param('target_milestone')}); + } + } - if (!$vok || !$cok || !$mok) { + if (!$vok || !$cok || !$mok + || !defined $cgi->param('confirm_product_change')) + { $vars->{'verify_fields'} = 1; my %defaults; # We set the defaults to these fields to the old value, - # if its a valid option, otherwise we use the default where + # if it's a valid option, otherwise we use the default where # that's appropriate - $vars->{'versions'} = $::versions{$prod}; + $vars->{'versions'} = \@version_names; if ($vok) { $defaults{'version'} = $cgi->param('version'); } - $vars->{'components'} = $::components{$prod}; + elsif (scalar(@version_names) == 1) { + $defaults{'version'} = $version_names[0]; + } + + $vars->{'components'} = \@component_names; if ($cok) { $defaults{'component'} = $cgi->param('component'); } - if (Param("usetargetmilestone")) { + elsif (scalar(@component_names) == 1) { + $defaults{'component'} = $component_names[0]; + } + + if (Bugzilla->params->{"usetargetmilestone"}) { $vars->{'use_target_milestone'} = 1; - $vars->{'milestones'} = $::target_milestone{$prod}; + $vars->{'milestones'} = \@milestone_names; if ($mok) { $defaults{'target_milestone'} = $cgi->param('target_milestone'); } else { - SendSQL("SELECT defaultmilestone FROM products " . - "WHERE name = " . SqlQuote($prod)); - $defaults{'target_milestone'} = FetchOneColumn(); + $defaults{'target_milestone'} = $dbh->selectrow_array( + q{SELECT defaultmilestone FROM products + WHERE name = ?}, undef, $prod); } } else { @@ -379,178 +459,16 @@ if (((defined $cgi->param('id') && $cgi->param('product') ne $oldproduct) } } - -# Checks that the user is allowed to change the given field. Actually, right -# now, the rules are pretty simple, and don't look at the field itself very -# much, but that could be enhanced. - -my $ownerid; -my $reporterid; -my $qacontactid; - -################################################################################ -# CheckCanChangeField() defines what users are allowed to change what bugs. You -# can add code here for site-specific policy changes, according to the -# instructions given in the Bugzilla Guide and below. Note that you may also -# have to update the Bugzilla::Bug::user() function to give people access to the -# options that they are permitted to change. -# -# CheckCanChangeField() should return true if the user is allowed to change this -# field, and false if they are not. -# -# The parameters to this function are as follows: -# $field - name of the field in the bugs table the user is trying to change -# $bugid - the ID of the bug they are changing -# $oldvalue - what they are changing it from -# $newvalue - what they are changing it to -# -# Note that this function is currently not called for dependency changes -# (bug 141593) or CC changes, which means anyone can change those fields. -# -# Do not change the sections between START DO_NOT_CHANGE and END DO_NOT_CHANGE. -################################################################################ -sub CheckCanChangeField { - # START DO_NOT_CHANGE - my ($field, $bugid, $oldvalue, $newvalue) = (@_); - - $oldvalue = defined($oldvalue) ? $oldvalue : ''; - $newvalue = defined($newvalue) ? $newvalue : ''; - - # Return true if they haven't changed this field at all. - if ($oldvalue eq $newvalue) { - return 1; - } elsif (trim($oldvalue) eq trim($newvalue)) { - return 1; - # numeric fields need to be compared using == - } elsif (($field eq "estimated_time" || $field eq "remaining_time") - && $newvalue ne $cgi->param('dontchange') - && $oldvalue == $newvalue) - { - return 1; - } - - # A resolution change is always accompanied by a status change. So, we - # always OK resolution changes; if they really can't do this, we will - # notice it when status is checked. - if ($field eq "resolution") { - return 1; - } - # END DO_NOT_CHANGE - - # Allow anyone to change comments. - if ($field =~ /^longdesc/) { - return 1; - } - - # Ignore the assigned_to field if the bug is not being reassigned - if ($field eq "assigned_to" - && $cgi->param('knob') ne "reassignbycomponent" - && $cgi->param('knob') ne "reassign") - { - return 1; - } - - # START DO_NOT_CHANGE - # Find out whether the user is a member of the "editbugs" and/or - # "canconfirm" groups. $UserIn*GroupSet are caches of the return value of - # the UserInGroup calls. - if ($UserInEditGroupSet < 0) { - $UserInEditGroupSet = UserInGroup("editbugs"); - } - - if ($UserInCanConfirmGroupSet < 0) { - $UserInCanConfirmGroupSet = UserInGroup("canconfirm"); - } - # END DO_NOT_CHANGE - - # If the user isn't allowed to change a field, we must tell him who can. - # We store the required permission set into the $PrivilegesRequired - # variable which gets passed to the error template. - # - # $PrivilegesRequired = 0 : no privileges required; - # $PrivilegesRequired = 1 : the reporter, assignee or an empowered user; - # $PrivilegesRequired = 2 : the assignee or an empowered user; - # $PrivilegesRequired = 3 : an empowered user. - - # Allow anyone with "editbugs" privs to change anything. - if ($UserInEditGroupSet) { - return 1; - } - - # *Only* users with "canconfirm" privs can confirm bugs. - if ($field eq "canconfirm" - || ($field eq "bug_status" - && $oldvalue eq 'UNCONFIRMED' - && IsOpenedState($newvalue))) - { - $PrivilegesRequired = 3; - return $UserInCanConfirmGroupSet; - } - - # START DO_NOT_CHANGE - # $reporterid, $ownerid and $qacontactid are caches of the results of - # the call to find out the assignee, reporter and qacontact of the current bug. - if ($lastbugid != $bugid) { - SendSQL("SELECT reporter, assigned_to, qa_contact FROM bugs - WHERE bug_id = $bugid"); - ($reporterid, $ownerid, $qacontactid) = (FetchSQLData()); - $lastbugid = $bugid; - } - # END DO_NOT_CHANGE - - # Allow the assignee to change anything else. - if ($ownerid == $whoid) { - return 1; - } - - # Allow the QA contact to change anything else. - if (Param('useqacontact') && $qacontactid && ($qacontactid == $whoid)) { - return 1; - } - - # At this point, the user is either the reporter or an - # unprivileged user. We first check for fields the reporter - # is not allowed to change. - - # The reporter may not: - # - reassign bugs, unless the bugs are assigned to him; - # in that case we will have already returned 1 above - # when checking for the assignee of the bug. - if ($field eq "assigned_to") { - $PrivilegesRequired = 2; - return 0; - } - # - change the QA contact - if ($field eq "qa_contact") { - $PrivilegesRequired = 2; - return 0; - } - # - change the target milestone - if ($field eq "target_milestone") { - $PrivilegesRequired = 2; - return 0; - } - # - change the priority (unless he could have set it originally) - if ($field eq "priority" - && !Param('letsubmitterchoosepriority')) - { - $PrivilegesRequired = 2; - return 0; - } - - # The reporter is allowed to change anything else. - if ($reporterid == $whoid) { - return 1; - } - - # If we haven't returned by this point, then the user doesn't - # have the necessary permissions to change this field. - $PrivilegesRequired = 1; - return 0; -} +# At this point, the component must be defined, even if set to "dontchange". +defined($cgi->param('component')) + || ThrowCodeError('undefined_field', { field => 'component' }); # Confirm that the reporter of the current bug can access the bug we are duping to. sub DuplicateUserConfirm { + my $cgi = Bugzilla->cgi; + my $dbh = Bugzilla->dbh; + my $template = Bugzilla->template; + # if we've already been through here, then exit if (defined $cgi->param('confirm_add_duplicate')) { return; @@ -561,17 +479,24 @@ sub DuplicateUserConfirm { my $dupe = $cgi->param('id'); my $original = $cgi->param('dup_id'); - SendSQL("SELECT reporter FROM bugs WHERE bug_id = $dupe"); - my $reporter = FetchOneColumn(); + my $reporter = $dbh->selectrow_array( + q{SELECT reporter FROM bugs WHERE bug_id = ?}, undef, $dupe); my $rep_user = Bugzilla::User->new($reporter); if ($rep_user->can_see_bug($original)) { $cgi->param('confirm_add_duplicate', '1'); return; } + elsif (Bugzilla->usage_mode == USAGE_MODE_EMAIL) { + # The email interface defaults to the safe alternative, which is + # not CC'ing the user. + $cgi->param('confirm_add_duplicate', 0); + return; + } - SendSQL("SELECT cclist_accessible FROM bugs WHERE bug_id = $original"); - $vars->{'cclist_accessible'} = FetchOneColumn(); + $vars->{'cclist_accessible'} = $dbh->selectrow_array( + q{SELECT cclist_accessible FROM bugs WHERE bug_id = ?}, + undef, $original); # Once in this part of the subroutine, the user has not been auto-validated # and the duper has not chosen whether or not to add to CC list, so let's @@ -595,22 +520,25 @@ if (defined $cgi->param('id')) { # values that have been changed instead of submitting all the new values. # (XXX those error checks need to happen too, but implementing them # is more work in the current architecture of this script...) - # - check_form_field($cgi, 'product', \@::legal_product); - check_form_field($cgi, 'component', - \@{$::components{$cgi->param('product')}}); - check_form_field($cgi, 'version', \@{$::versions{$cgi->param('product')}}); - if ( Param("usetargetmilestone") ) { - check_form_field($cgi, 'target_milestone', - \@{$::target_milestone{$cgi->param('product')}}); - } - check_form_field($cgi, 'rep_platform', \@::legal_platform); - check_form_field($cgi, 'op_sys', \@::legal_opsys); - check_form_field($cgi, 'priority', \@::legal_priority); - check_form_field($cgi, 'bug_severity', \@::legal_severity); - check_form_field_defined($cgi, 'bug_file_loc'); - check_form_field_defined($cgi, 'short_desc'); - check_form_field_defined($cgi, 'longdesclength'); + my $prod_obj = Bugzilla::Product::check_product($cgi->param('product')); + check_field('component', scalar $cgi->param('component'), + [map($_->name, @{$prod_obj->components})]); + check_field('version', scalar $cgi->param('version'), + [map($_->name, @{$prod_obj->versions})]); + if ( Bugzilla->params->{"usetargetmilestone"} ) { + check_field('target_milestone', scalar $cgi->param('target_milestone'), + [map($_->name, @{$prod_obj->milestones})]); + } + check_field('rep_platform', scalar $cgi->param('rep_platform')); + check_field('op_sys', scalar $cgi->param('op_sys')); + check_field('priority', scalar $cgi->param('priority')); + check_field('bug_severity', scalar $cgi->param('bug_severity')); + + # Those fields only have to exist. We don't validate their value here. + foreach my $field_name ('bug_file_loc', 'short_desc', 'longdesclength') { + defined($cgi->param($field_name)) + || ThrowCodeError('undefined_field', { field => $field_name }); + } $cgi->param('short_desc', clean_text($cgi->param('short_desc'))); if (trim($cgi->param('short_desc')) eq "") { @@ -620,8 +548,8 @@ if (defined $cgi->param('id')) { my $action = trim($cgi->param('action') || ''); -if ($action eq Param('move-button-text')) { - Param('move-enabled') || ThrowUserError("move_bugs_disabled"); +if ($action eq Bugzilla->params->{'move-button-text'}) { + Bugzilla->params->{'move-enabled'} || ThrowUserError("move_bugs_disabled"); $user->is_mover || ThrowUserError("auth_failure", {action => 'move', object => 'bugs'}); @@ -637,13 +565,8 @@ if ($action eq Param('move-button-text')) { my $comment = ""; if (defined $cgi->param('comment') && $cgi->param('comment') !~ /^\s*$/) { - $comment = $cgi->param('comment') . "\n\n"; + $comment = $cgi->param('comment'); } - $comment .= "Bug moved to " . Param('move-to-url') . ".\n\n"; - $comment .= "If the move succeeded, " . $user->login . " will receive a mail\n"; - $comment .= "containing the number of the new bug in the other database.\n"; - $comment .= "If all went well, please mark this bug verified, and paste\n"; - $comment .= "in a link to the new bug. Otherwise, reopen this bug.\n"; $dbh->bz_lock_tables('bugs WRITE', 'bugs_activity WRITE', 'duplicates WRITE', 'longdescs WRITE', 'profiles READ', 'groups READ', @@ -656,13 +579,13 @@ if ($action eq Param('move-button-text')) { my @bugs; # First update all moved bugs. foreach my $id (@idlist) { - my $bug = new Bugzilla::Bug($id, $whoid); + my $bug = new Bugzilla::Bug($id); push(@bugs, $bug); $sth->execute($timestamp, $id); $sth2->execute($id); - AppendComment($id, $whoid, $comment, 0, $timestamp); + AppendComment($id, $whoid, $comment, 0, $timestamp, 0, CMT_MOVED_TO, $user->login); if ($bug->bug_status ne 'RESOLVED') { LogActivityEntry($id, 'bug_status', $bug->bug_status, @@ -680,21 +603,18 @@ if ($action eq Param('move-button-text')) { $vars->{'mailrecipients'} = { 'changer' => $user->login }; $vars->{'id'} = $id; $vars->{'type'} = "move"; - - $template->process("bug/process/results.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - $vars->{'header_done'} = 1; + send_results($id, $vars); } # Prepare and send all data about these bugs to the new database - my $to = Param('move-to-address'); + my $to = Bugzilla->params->{'move-to-address'}; $to =~ s/@/\@/; - my $from = Param('moved-from-address'); + my $from = Bugzilla->params->{'moved-from-address'}; $from =~ s/@/\@/; my $msg = "To: $to\n"; $msg .= "From: Bugzilla <" . $from . ">\n"; $msg .= "Subject: Moving bug(s) " . join(', ', @idlist) . "\n\n"; - my @fieldlist = (Bugzilla::Bug::fields(), 'group', 'long_desc', + my @fieldlist = (Bugzilla::Bug->fields, 'group', 'long_desc', 'attachment', 'attachmentdata'); my %displayfields; foreach (@fieldlist) { @@ -707,23 +627,27 @@ if ($action eq Param('move-button-text')) { || ThrowTemplateError($template->error()); $msg .= "\n"; - Bugzilla::BugMail::MessageToMTA($msg); + MessageToMTA($msg); # End the response page. - $template->process("bug/navigate.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - $template->process("global/footer.html.tmpl", $vars) - || ThrowTemplateError($template->error()); + unless (Bugzilla->usage_mode == USAGE_MODE_EMAIL) { + $template->process("bug/navigate.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + $template->process("global/footer.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + } exit; } -$::query = "update bugs\nset"; +$::query = "UPDATE bugs SET"; $::comma = ""; +local our @values; umask(0); sub _remove_remaining_time { - if (UserInGroup(Param('timetrackinggroup'))) { + my $cgi = Bugzilla->cgi; + if (Bugzilla->user->in_group(Bugzilla->params->{'timetrackinggroup'})) { if ( defined $cgi->param('remaining_time') && $cgi->param('remaining_time') > 0 ) { @@ -744,9 +668,12 @@ sub DoComma { # $everconfirmed is used by ChangeStatus() to determine whether we are # confirming the bug or not. -my $everconfirmed; +local our $everconfirmed; sub DoConfirm { - if (CheckCanChangeField("canconfirm", scalar $cgi->param('id'), 0, 1)) { + my $bug = shift; + if ($bug->check_can_change_field("canconfirm", 0, 1, + \$PrivilegesRequired)) + { DoComma(); $::query .= "everconfirmed = 1"; $everconfirmed = 1; @@ -755,6 +682,9 @@ sub DoConfirm { sub ChangeStatus { my ($str) = (@_); + my $cgi = Bugzilla->cgi; + my $dbh = Bugzilla->dbh; + if (!$cgi->param('dontchange') || $str ne $cgi->param('dontchange')) { DoComma(); @@ -762,8 +692,8 @@ sub ChangeStatus { # When reopening, we need to check whether the bug was ever # confirmed or not $::query .= "bug_status = CASE WHEN everconfirmed = 1 THEN " . - SqlQuote($str) . " ELSE 'UNCONFIRMED' END"; - } elsif (IsOpenedState($str)) { + $dbh->quote($str) . " ELSE 'UNCONFIRMED' END"; + } elsif (is_open_state($str)) { # Note that we cannot combine this with the above branch - here we # need to check if bugs.bug_status is open, (since we don't want to # reopen closed bugs when reassigning), while above the whole point @@ -785,16 +715,16 @@ sub ChangeStatus { # - leave it as it was # This is valid only because 'reopen' is the only thing which moves - # from closed to open, and its handled above + # from closed to open, and it's handled above # This also relies on the fact that confirming and accepting have # already called DoConfirm before this is called - my @open_state = map(SqlQuote($_), OpenStates()); + my @open_state = map($dbh->quote($_), BUG_STATE_OPEN); my $open_state = join(", ", @open_state); # If we are changing everconfirmed to 1, we have to take this change # into account and the new bug status is given by $str. - my $cond = SqlQuote($str); + my $cond = $dbh->quote($str); # If we are not setting everconfirmed, the new bug status depends on # the actual value of everconfirmed, which is bug-specific. unless ($everconfirmed) { @@ -804,7 +734,8 @@ sub ChangeStatus { $::query .= "bug_status = CASE WHEN bug_status IN($open_state) THEN " . $cond . " ELSE bug_status END"; } else { - $::query .= "bug_status = " . SqlQuote($str); + $::query .= "bug_status = ?"; + push(@values, $str); } # If bugs are reassigned and their status is "UNCONFIRMED", they # should keep this status instead of "NEW" as suggested here. @@ -814,14 +745,41 @@ sub ChangeStatus { } sub ChangeResolution { - my ($str) = (@_); + my ($bug, $str) = (@_); + my $dbh = Bugzilla->dbh; + my $cgi = Bugzilla->cgi; + if (!$cgi->param('dontchange') || $str ne $cgi->param('dontchange')) { + # Make sure the user is allowed to change the resolution. + # If the user is changing several bugs at once using the UI, + # then he has enough privs to do so. In the case he is hacking + # the URL, we don't care if he reads --UNKNOWN-- as a resolution + # in the error message. + my $old_resolution = '-- UNKNOWN --'; + my $bug_id = $cgi->param('id'); + if ($bug_id) { + $old_resolution = + $dbh->selectrow_array('SELECT resolution FROM bugs WHERE bug_id = ?', + undef, $bug_id); + } + unless ($bug->check_can_change_field('resolution', $old_resolution, $str, + \$PrivilegesRequired)) + { + $vars->{'oldvalue'} = $old_resolution; + $vars->{'newvalue'} = $str; + $vars->{'field'} = 'resolution'; + $vars->{'privs'} = $PrivilegesRequired; + ThrowUserError("illegal_change", $vars); + } + DoComma(); - $::query .= "resolution = " . SqlQuote($str); + $::query .= "resolution = ?"; + trick_taint($str); + push(@values, $str); # We define this variable here so that customized installations - # may set rules based on the resolution in CheckCanChangeField. + # may set rules based on the resolution in Bug::check_can_change_field(). $cgi->param('resolution', $str); } } @@ -836,15 +794,16 @@ sub ChangeResolution { my @groupAdd = (); my @groupDel = (); -SendSQL("SELECT groups.id, isactive FROM groups " . - "WHERE id IN($grouplist) " . - "AND isbuggroup = 1"); -while (my ($b, $isactive) = FetchSQLData()) { +my $groups = $dbh->selectall_arrayref( + qq{SELECT groups.id, isactive FROM groups + WHERE id IN($grouplist) AND isbuggroup = 1}); +foreach my $group (@$groups) { + my ($b, $isactive) = @$group; # The multiple change page may not show all groups a bug is in # (eg product groups when listing more than one product) # Only consider groups which were present on the form. We can't do this # for single bug changes because non-checked checkboxes aren't present. - # All the checkboxes should be shown in that case, though, so its not + # All the checkboxes should be shown in that case, though, so it isn't # an issue there if (defined $cgi->param('id') || defined $cgi->param("bit-$b")) { if (!$cgi->param("bit-$b")) { @@ -862,40 +821,47 @@ foreach my $field ("rep_platform", "priority", "bug_severity", if (!$cgi->param('dontchange') || $cgi->param($field) ne $cgi->param('dontchange')) { DoComma(); - $::query .= "$field = " . SqlQuote(trim($cgi->param($field))); + $::query .= "$field = ?"; + my $value = trim($cgi->param($field)); + trick_taint($value); + push(@values, $value); } } } -my $prod_id; -my $prod_changed = 0; # Used by strict_isolation only. +# Add custom fields data to the query that will update the database. +foreach my $field (Bugzilla->get_fields({custom => 1, obsolete => 0})) { + my $fname = $field->name; + if (defined $cgi->param($fname) + && (!$cgi->param('dontchange') + || $cgi->param($fname) ne $cgi->param('dontchange'))) + { + DoComma(); + $::query .= "$fname = ?"; + my $value = $cgi->param($fname); + check_field($fname, $value) if ($field->type == FIELD_TYPE_SINGLE_SELECT); + trick_taint($value); + push(@values, $value); + } +} + +my $product; +my $prod_changed = 0; my @newprod_ids; if ($cgi->param('product') ne $cgi->param('dontchange')) { - $prod_id = get_product_id($cgi->param('product')); - $prod_id || - ThrowUserError("invalid_product_name", - {product => $cgi->param('product')}); - + $product = Bugzilla::Product::check_product(scalar $cgi->param('product')); + DoComma(); - @newprod_ids = ($prod_id); - $::query .= "product_id = $prod_id"; - if (Param("strict_isolation")) { - # If the bug remains in the same product, leave $prod_changed set to 0. - # Even with 'strict_isolation' turned on, we ignore users who already - # play a role for the bug; else you would never be able to edit it. - # If you want to move the bug to another product, then you first have to - # remove these users from the bug. - if (defined $cgi->param('id')) { - my $curr_product_id = - $dbh->selectrow_array('SELECT product_id FROM bugs WHERE bug_id = ?', - undef, $cgi->param('id')); - if ($curr_product_id != $prod_id) { - $prod_changed = 1; - } - } - else { - $prod_changed = 1; - } + $::query .= "product_id = ?"; + push(@values, $product->id); + @newprod_ids = ($product->id); + # If the bug remains in the same product, leave $prod_changed set to 0. + # Even with 'strict_isolation' turned on, we ignore users who already + # play a role for the bug; else you would never be able to edit it. + # If you want to move the bug to another product, then you first have to + # remove these users from the bug. + unless (defined $cgi->param('id') && $bug->product_id == $product->id) { + $prod_changed = 1; } } else { @newprod_ids = @{$dbh->selectcol_arrayref("SELECT DISTINCT product_id @@ -904,29 +870,28 @@ if ($cgi->param('product') ne $cgi->param('dontchange')) { join(',', @idlist) . ")")}; if (scalar(@newprod_ids) == 1) { - ($prod_id) = @newprod_ids; + $product = new Bugzilla::Product($newprod_ids[0]); } } -my $comp_id; +my $component; if ($cgi->param('component') ne $cgi->param('dontchange')) { if (scalar(@newprod_ids) > 1) { ThrowUserError("no_component_change_for_multiple_products"); } - $comp_id = get_component_id($prod_id, - $cgi->param('component')); - $comp_id || ThrowCodeError("invalid_component", - {name => $cgi->param('component'), - product => $cgi->param('product')}); - - $cgi->param('component_id', $comp_id); + $component = + Bugzilla::Component::check_component($product, scalar $cgi->param('component')); + + # This parameter is required later when checking fields the user can change. + $cgi->param('component_id', $component->id); DoComma(); - $::query .= "component_id = $comp_id"; + $::query .= "component_id = ?"; + push(@values, $component->id); } # If this installation uses bug aliases, and the user is changing the alias, # add this change to the query. -if (Param("usebugaliases") && defined $cgi->param('alias')) { +if (Bugzilla->params->{"usebugaliases"} && defined $cgi->param('alias')) { my $alias = trim($cgi->param('alias')); # Since aliases are unique (like bug numbers), they can only be changed @@ -938,12 +903,12 @@ if (Param("usebugaliases") && defined $cgi->param('alias')) { # Otherwise, if the field contains a value, update the record # with that value. DoComma(); - $::query .= "alias = "; if ($alias ne "") { ValidateBugAlias($alias, $idlist[0]); - $::query .= $dbh->quote($alias); + $::query .= "alias = ?"; + push(@values, $alias); } else { - $::query .= "NULL"; + $::query .= "alias = NULL"; } } } @@ -954,25 +919,28 @@ if (Param("usebugaliases") && defined $cgi->param('alias')) { # and cc list can see the bug even if they are not members of all groups # to which the bug is restricted. if (defined $cgi->param('id')) { - SendSQL("SELECT group_id FROM bug_group_map WHERE bug_id = " . - $cgi->param('id')); - my ($havegroup) = FetchSQLData(); + my ($havegroup) = $dbh->selectrow_array( + q{SELECT group_id FROM bug_group_map WHERE bug_id = ?}, + undef, $cgi->param('id')); if ( $havegroup ) { DoComma(); $cgi->param('reporter_accessible', $cgi->param('reporter_accessible') ? '1' : '0'); - $::query .= 'reporter_accessible = ' . - $cgi->param('reporter_accessible'); + $::query .= "reporter_accessible = ?"; + push(@values, $cgi->param('reporter_accessible')); DoComma(); $cgi->param('cclist_accessible', $cgi->param('cclist_accessible') ? '1' : '0'); - $::query .= 'cclist_accessible = ' . $cgi->param('cclist_accessible'); + $::query .= "cclist_accessible = ?"; + push(@values, $cgi->param('cclist_accessible')); } } -if (defined $cgi->param('id') && - (Param("insidergroup") && UserInGroup(Param("insidergroup")))) { +if ( defined $cgi->param('id') && + (Bugzilla->params->{"insidergroup"} + && Bugzilla->user->in_group(Bugzilla->params->{"insidergroup"})) ) +{ my $sth = $dbh->prepare('UPDATE longdescs SET isprivate = ? WHERE bug_id = ? AND bug_when = ?'); @@ -992,7 +960,7 @@ if (defined $cgi->param('id') && } } -my $duplicate = 0; +my $duplicate; # We need to check the addresses involved in a CC change before we touch any bugs. # What we'll do here is formulate the CC data into two hashes of ID's involved @@ -1023,7 +991,7 @@ if (defined $cgi->param('newcc') if ($cc_add) { $cc_add =~ s/[\s,]+/ /g; # Change all delimiters to a single space foreach my $person ( split(" ", $cc_add) ) { - my $pid = DBNameToIdAndCheck($person); + my $pid = login_to_id($person, THROW_ERROR); $cc_add{$pid} = $person; } } @@ -1033,7 +1001,7 @@ if (defined $cgi->param('newcc') if ($cc_remove) { $cc_remove =~ s/[\s,]+/ /g; # Change all delimiters to a single space foreach my $person ( split(" ", $cc_remove) ) { - my $pid = DBNameToIdAndCheck($person); + my $pid = login_to_id($person, THROW_ERROR); $cc_remove{$pid} = $person; } } @@ -1060,20 +1028,16 @@ if (defined $cgi->param('qa_contact') my $name = trim($cgi->param('qa_contact')); # The QA contact cannot be deleted from show_bug.cgi for a single bug! if ($name ne $cgi->param('dontchange')) { - $qacontact = DBNameToIdAndCheck($name) if ($name ne ""); - if ($qacontact && Param("strict_isolation")) { - my $curr_qa_contact_id = 0; - if (defined $cgi->param('id')) { - $curr_qa_contact_id = $dbh->selectrow_array( - 'SELECT qa_contact FROM bugs WHERE bug_id = ?', - undef, $cgi->param('id')) || 0; - } - if ($qacontact != $curr_qa_contact_id) { + $qacontact = login_to_id($name, THROW_ERROR) if ($name ne ""); + if ($qacontact && Bugzilla->params->{"strict_isolation"} + && !(defined $cgi->param('id') && $bug->qa_contact + && $qacontact == $bug->qa_contact->id)) + { $usercache{$qacontact} ||= Bugzilla::User->new($qacontact); my $qa_user = $usercache{$qacontact}; foreach my $product_id (@newprod_ids) { if (!$qa_user->can_edit_product($product_id)) { - my $product_name = get_product_name($product_id); + my $product_name = Bugzilla::Product->new($product_id)->name; ThrowUserError('invalid_user_group', {'users' => $qa_user->login, 'product' => $product_name, @@ -1082,12 +1046,12 @@ if (defined $cgi->param('qa_contact') }); } } - } } $qacontact_checked = 1; DoComma(); if($qacontact) { - $::query .= "qa_contact = $qacontact"; + $::query .= "qa_contact = ?"; + push(@values, $qacontact); } else { $::query .= "qa_contact = NULL"; @@ -1100,28 +1064,31 @@ SWITCH: for ($cgi->param('knob')) { last SWITCH; }; /^confirm$/ && CheckonComment( "confirm" ) && do { - DoConfirm(); + DoConfirm($bug); ChangeStatus('NEW'); last SWITCH; }; /^accept$/ && CheckonComment( "accept" ) && do { - DoConfirm(); + DoConfirm($bug); ChangeStatus('ASSIGNED'); - if (Param("usetargetmilestone") && Param("musthavemilestoneonaccept")) { + if (Bugzilla->params->{"usetargetmilestone"} + && Bugzilla->params->{"musthavemilestoneonaccept"}) + { $requiremilestone = 1; } last SWITCH; }; /^clearresolution$/ && CheckonComment( "clearresolution" ) && do { - ChangeResolution(''); + ChangeResolution($bug, ''); last SWITCH; }; - /^resolve$/ && CheckonComment( "resolve" ) && do { - # Check here, because its the only place we require the resolution - check_form_field($cgi, 'resolution', \@::settable_resolution); + /^(resolve|change_resolution)$/ && CheckonComment( "resolve" ) && do { + # Check here, because it's the only place we require the resolution + check_field('resolution', scalar $cgi->param('resolution'), + Bugzilla::Bug->settable_resolutions); # don't resolve as fixed while still unresolved blocking bugs - if (Param("noresolveonopenblockers") + if (Bugzilla->params->{"noresolveonopenblockers"} && $cgi->param('resolution') eq 'FIXED') { my @dependencies = Bugzilla::Bug::CountOpenDependencies(@idlist); @@ -1132,29 +1099,43 @@ SWITCH: for ($cgi->param('knob')) { } } - # RESOLVED bugs should have no time remaining; - # more time can be added for the VERIFY step, if needed. - _remove_remaining_time(); + if ($cgi->param('knob') eq 'resolve') { + # RESOLVED bugs should have no time remaining; + # more time can be added for the VERIFY step, if needed. + _remove_remaining_time(); - ChangeStatus('RESOLVED'); - ChangeResolution($cgi->param('resolution')); + ChangeStatus('RESOLVED'); + } + else { + # You cannot use change_resolution if there is at least + # one open bug. + my $open_states = join(',', map {$dbh->quote($_)} BUG_STATE_OPEN); + my $idlist = join(',', @idlist); + my $is_open = + $dbh->selectrow_array("SELECT 1 FROM bugs WHERE bug_id IN ($idlist) + AND bug_status IN ($open_states)"); + + ThrowUserError('resolution_not_allowed') if $is_open; + } + + ChangeResolution($bug, $cgi->param('resolution')); last SWITCH; }; /^reassign$/ && CheckonComment( "reassign" ) && do { if ($cgi->param('andconfirm')) { - DoConfirm(); + DoConfirm($bug); } ChangeStatus('NEW'); DoComma(); if (defined $cgi->param('assigned_to') && trim($cgi->param('assigned_to')) ne "") { - $assignee = DBNameToIdAndCheck(trim($cgi->param('assigned_to'))); - if (Param("strict_isolation")) { + $assignee = login_to_id(trim($cgi->param('assigned_to')), THROW_ERROR); + if (Bugzilla->params->{"strict_isolation"}) { $usercache{$assignee} ||= Bugzilla::User->new($assignee); my $assign_user = $usercache{$assignee}; foreach my $product_id (@newprod_ids) { if (!$assign_user->can_edit_product($product_id)) { - my $product_name = get_product_name($product_id); + my $product_name = Bugzilla::Product->new($product_id)->name; ThrowUserError('invalid_user_group', {'users' => $assign_user->login, 'product' => $product_name, @@ -1167,20 +1148,21 @@ SWITCH: for ($cgi->param('knob')) { } else { ThrowUserError("reassign_to_empty"); } + $::query .= "assigned_to = ?"; + push(@values, $assignee); $assignee_checked = 1; - $::query .= "assigned_to = $assignee"; last SWITCH; }; /^reassignbycomponent$/ && CheckonComment( "reassignbycomponent" ) && do { if ($cgi->param('compconfirm')) { - DoConfirm(); + DoConfirm($bug); } ChangeStatus('NEW'); last SWITCH; }; /^reopen$/ && CheckonComment( "reopen" ) && do { ChangeStatus('REOPENED'); - ChangeResolution(''); + ChangeResolution($bug, ''); last SWITCH; }; /^verify$/ && CheckonComment( "verify" ) && do { @@ -1202,25 +1184,17 @@ SWITCH: for ($cgi->param('knob')) { } # Make sure we can change the original bug (issue A on bug 96085) - check_form_field_defined($cgi, 'dup_id'); + defined($cgi->param('dup_id')) + || ThrowCodeError('undefined_field', { field => 'dup_id' }); + $duplicate = $cgi->param('dup_id'); ValidateBugID($duplicate, 'dup_id'); $cgi->param('dup_id', $duplicate); - # Make sure the bug is not already marked as a dupe - # (may appear in race condition) - my $dupe_of = - $dbh->selectrow_array("SELECT dupe_of FROM duplicates - WHERE dupe = ?", - undef, $cgi->param('id')); - if ($dupe_of) { - ThrowUserError("dupe_entry_found", { dupe_of => $dupe_of }); - } - # Make sure a loop isn't created when marking this bug # as duplicate. my %dupes; - $dupe_of = $duplicate; + my $dupe_of = $duplicate; my $sth = $dbh->prepare('SELECT dupe_of FROM duplicates WHERE dupe = ?'); @@ -1247,11 +1221,7 @@ SWITCH: for ($cgi->param('knob')) { _remove_remaining_time(); ChangeStatus('RESOLVED'); - ChangeResolution('DUPLICATE'); - my $comment = $cgi->param('comment'); - $comment .= "\n\n*** This bug has been marked " . - "as a duplicate of bug $duplicate ***"; - $cgi->param('comment', $comment); + ChangeResolution($bug, 'DUPLICATE'); last SWITCH; }; @@ -1266,14 +1236,14 @@ if (defined $cgi->param('keywords')) { if ($keyword eq '') { next; } - my $i = GetKeywordIdFromName($keyword); - if (!$i) { + my $keyword_obj = new Bugzilla::Keyword({name => $keyword}); + if (!$keyword_obj) { ThrowUserError("unknown_keyword", { keyword => $keyword }); } - if (!$keywordseen{$i}) { - push(@keywordlist, $i); - $keywordseen{$i} = 1; + if (!$keywordseen{$keyword_obj->id}) { + push(@keywordlist, $keyword_obj->id); + $keywordseen{$keyword_obj->id} = 1; } } } @@ -1285,7 +1255,8 @@ if (!grep($keywordaction eq $_, qw(add delete makeexact))) { if ($::comma eq "" && (! @groupAdd) && (! @groupDel) - && (! @::legal_keywords || (0 == @keywordlist && $keywordaction ne "makeexact")) + && (!Bugzilla::Keyword::keyword_count() + || (0 == @keywordlist && $keywordaction ne "makeexact")) && defined $cgi->param('masscc') && ! $cgi->param('masscc') ) { if (!defined $cgi->param('comment') || $cgi->param('comment') =~ /^\s*$/) { @@ -1294,40 +1265,44 @@ if ($::comma eq "" } # Process data for Time Tracking fields -if (UserInGroup(Param('timetrackinggroup'))) { +if (Bugzilla->user->in_group(Bugzilla->params->{'timetrackinggroup'})) { foreach my $field ("estimated_time", "remaining_time") { if (defined $cgi->param($field)) { my $er_time = trim($cgi->param($field)); if ($er_time ne $cgi->param('dontchange')) { DoComma(); - $::query .= "$field = " . SqlQuote($er_time); + $::query .= "$field = ?"; + trick_taint($er_time); + push(@values, $er_time); } } } if (defined $cgi->param('deadline')) { DoComma(); - $::query .= "deadline = "; if ($cgi->param('deadline')) { validate_date($cgi->param('deadline')) || ThrowUserError('illegal_date', {date => $cgi->param('deadline'), format => 'YYYY-MM-DD'}); - $::query .= SqlQuote($cgi->param('deadline')); + $::query .= "deadline = ?"; + my $deadline = $cgi->param('deadline'); + trick_taint($deadline); + push(@values, $deadline); } else { - $::query .= "NULL" ; + $::query .= "deadline = NULL"; } } } my $basequery = $::query; -my $delta_ts; - +local our $delta_ts; sub SnapShotBug { my ($id) = (@_); - SendSQL("SELECT delta_ts, " . join(',', @::log_columns) . - " FROM bugs WHERE bug_id = $id"); - my @row = FetchSQLData(); + my $dbh = Bugzilla->dbh; + my @row = $dbh->selectrow_array(q{SELECT delta_ts, } . + join(',', editable_bug_fields()).q{ FROM bugs WHERE bug_id = ?}, + undef, $id); $delta_ts = shift @row; return @row; @@ -1342,25 +1317,26 @@ sub SnapShotDeps { my $timestamp; -my $bug_changed; +local our $bug_changed; sub LogDependencyActivity { my ($i, $oldstr, $target, $me, $timestamp) = (@_); - my $sql_timestamp = SqlQuote($timestamp); + my $dbh = Bugzilla->dbh; my $newstr = SnapShotDeps($i, $target, $me); if ($oldstr ne $newstr) { # Figure out what's really different... my ($removed, $added) = diff_strings($oldstr, $newstr); LogActivityEntry($i,$target,$removed,$added,$whoid,$timestamp); # update timestamp on target bug so midairs will be triggered - SendSQL("UPDATE bugs SET delta_ts = $sql_timestamp WHERE bug_id = $i"); + $dbh->do(q{UPDATE bugs SET delta_ts = ? WHERE bug_id = ?}, + undef, $timestamp, $i); $bug_changed = 1; return 1; } return 0; } -if (Param("strict_isolation")) { +if (Bugzilla->params->{"strict_isolation"}) { my @blocked_cc = (); foreach my $pid (keys %cc_add) { $usercache{$pid} ||= Bugzilla::User->new($pid); @@ -1379,14 +1355,14 @@ if (Param("strict_isolation")) { } } -if ($prod_changed && Param("strict_isolation")) { +if ($prod_changed && Bugzilla->params->{"strict_isolation"}) { my $sth_cc = $dbh->prepare("SELECT who FROM cc WHERE bug_id = ?"); my $sth_bug = $dbh->prepare("SELECT assigned_to, qa_contact FROM bugs WHERE bug_id = ?"); - my $prod_name = get_product_name($prod_id); + foreach my $id (@idlist) { $sth_cc->execute($id); my @blocked_cc = (); @@ -1394,7 +1370,7 @@ if ($prod_changed && Param("strict_isolation")) { # Ignore deleted accounts. They will never get notification. $usercache{$pid} ||= Bugzilla::User->new($pid) || next; my $cc_user = $usercache{$pid}; - if (!$cc_user->can_edit_product($prod_id)) { + if (!$cc_user->can_edit_product($product->id)) { push (@blocked_cc, $cc_user->login); } } @@ -1402,28 +1378,28 @@ if ($prod_changed && Param("strict_isolation")) { ThrowUserError('invalid_user_group', {'users' => \@blocked_cc, 'bug_id' => $id, - 'product' => $prod_name}); + 'product' => $product->name}); } $sth_bug->execute($id); my ($assignee, $qacontact) = $sth_bug->fetchrow_array; if (!$assignee_checked) { $usercache{$assignee} ||= Bugzilla::User->new($assignee) || next; my $assign_user = $usercache{$assignee}; - if (!$assign_user->can_edit_product($prod_id)) { + if (!$assign_user->can_edit_product($product->id)) { ThrowUserError('invalid_user_group', {'users' => $assign_user->login, 'bug_id' => $id, - 'product' => $prod_name}); + 'product' => $product->name}); } } if (!$qacontact_checked && $qacontact) { $usercache{$qacontact} ||= Bugzilla::User->new($qacontact) || next; my $qa_user = $usercache{$qacontact}; - if (!$qa_user->can_edit_product($prod_id)) { + if (!$qa_user->can_edit_product($product->id)) { ThrowUserError('invalid_user_group', {'users' => $qa_user->login, 'bug_id' => $id, - 'product' => $prod_name}); + 'product' => $product->name}); } } } @@ -1437,48 +1413,62 @@ if ($prod_changed && Param("strict_isolation")) { # foreach my $id (@idlist) { my $query = $basequery; - my $bug_obj = new Bugzilla::Bug($id, $whoid); + my @bug_values = @values; + my $old_bug_obj = new Bugzilla::Bug($id); if ($cgi->param('knob') eq 'reassignbycomponent') { # We have to check whether the bug is moved to another product - # and/or component before reassigning. If $comp_id is defined, + # and/or component before reassigning. If $component is defined, # use it; else use the product/component the bug is already in. - my $new_comp_id = $comp_id || $bug_obj->{'component_id'}; + my $new_comp_id = $component ? $component->id : $old_bug_obj->{'component_id'}; $assignee = $dbh->selectrow_array('SELECT initialowner FROM components WHERE components.id = ?', undef, $new_comp_id); - $query .= ", assigned_to = $assignee"; - if (Param("useqacontact")) { + $query .= ", assigned_to = ?"; + push(@bug_values, $assignee); + if (Bugzilla->params->{"useqacontact"}) { $qacontact = $dbh->selectrow_array('SELECT initialqacontact FROM components WHERE components.id = ?', undef, $new_comp_id); if ($qacontact) { - $query .= ", qa_contact = $qacontact"; + $query .= ", qa_contact = ?"; + push(@bug_values, $qacontact); } else { $query .= ", qa_contact = NULL"; } } + + + + # And add in the Default CC for the Component. + my $comp_obj = $component || new Bugzilla::Component($new_comp_id); + my @new_init_cc = @{$comp_obj->initial_cc}; + foreach my $cc (@new_init_cc) { + # NewCC must be defined or the code below won't insert + # any CCs. + $cgi->param('newcc') || $cgi->param('newcc', []); + $cc_add{$cc->id} = $cc->login; + } } my %dependencychanged; $bug_changed = 0; my $write = "WRITE"; # Might want to make a param to control # whether we do LOW_PRIORITY ... - $dbh->bz_lock_tables("bugs $write", "bugs_activity $write", - "cc $write", "cc AS selectVisible_cc $write", + $dbh->bz_lock_tables("bugs $write", "bugs_activity $write", "cc $write", "profiles READ", "dependencies $write", "votes $write", - "products READ", "components READ", - "keywords $write", "longdescs $write", "fielddefs $write", + "products READ", "components READ", "milestones READ", + "keywords $write", "longdescs $write", "fielddefs READ", "bug_group_map $write", "flags $write", "duplicates $write", "user_group_map READ", "group_group_map READ", "flagtypes READ", "flaginclusions AS i READ", "flagexclusions AS e READ", "keyworddefs READ", "groups READ", "attachments READ", "group_control_map AS oldcontrolmap READ", "group_control_map AS newcontrolmap READ", - "group_control_map READ", "email_setting READ"); + "group_control_map READ", "email_setting READ", "classifications READ"); # It may sound crazy to set %formhash for each bug as $cgi->param() # will not change, but %formhash is modified below and we prefer @@ -1487,12 +1477,13 @@ foreach my $id (@idlist) { my @oldvalues = SnapShotBug($id); my %oldhash; my %formhash; - foreach my $col (@::log_columns) { + foreach my $col (@editable_bug_fields) { # Consider NULL db entries to be equivalent to the empty string $oldvalues[$i] = defined($oldvalues[$i]) ? $oldvalues[$i] : ''; # Convert the deadline taken from the DB into the YYYY-MM-DD format # for consistency with the deadline provided by the user, if any. - # Else CheckCanChangeField() would see them as different in all cases. + # Else Bug::check_can_change_field() would see them as different + # in all cases. if ($col eq 'deadline') { $oldvalues[$i] = format_time($oldvalues[$i], "%Y-%m-%d"); } @@ -1505,7 +1496,7 @@ foreach my $id (@idlist) { # email addresses into their corresponding IDs; # - update $newhash{'bug_status'} to its real state if the bug # is in the unconfirmed state. - $formhash{'qa_contact'} = $qacontact if Param('useqacontact'); + $formhash{'qa_contact'} = $qacontact if Bugzilla->params->{'useqacontact'}; if ($cgi->param('knob') eq 'reassignbycomponent' || $cgi->param('knob') eq 'reassign') { $formhash{'assigned_to'} = $assignee; @@ -1513,20 +1504,29 @@ foreach my $id (@idlist) { $formhash{'bug_status'} = $oldhash{'bug_status'}; } } - foreach my $col (@::log_columns) { + # This hash is required by Bug::check_can_change_field(). + my $cgi_hash = { + 'dontchange' => scalar $cgi->param('dontchange'), + 'knob' => scalar $cgi->param('knob') + }; + foreach my $col (@editable_bug_fields) { + # The 'resolution' field is checked by ChangeResolution(), + # i.e. only if we effectively use it. + next if ($col eq 'resolution'); if (exists $formhash{$col} - && !CheckCanChangeField($col, $id, $oldhash{$col}, $formhash{$col})) + && !$old_bug_obj->check_can_change_field($col, $oldhash{$col}, $formhash{$col}, + \$PrivilegesRequired, $cgi_hash)) { my $vars; if ($col eq 'component_id') { # Display the component name - $vars->{'oldvalue'} = get_component_name($oldhash{$col}); + $vars->{'oldvalue'} = $old_bug_obj->component; $vars->{'newvalue'} = $cgi->param('component'); $vars->{'field'} = 'component'; } elsif ($col eq 'assigned_to' || $col eq 'qa_contact') { # Display the assignee or QA contact email address - $vars->{'oldvalue'} = DBID_to_name($oldhash{$col}); - $vars->{'newvalue'} = DBID_to_name($formhash{$col}); + $vars->{'oldvalue'} = user_id_to_login($oldhash{$col}); + $vars->{'newvalue'} = user_id_to_login($formhash{$col}); $vars->{'field'} = $col; } else { $vars->{'oldvalue'} = $oldhash{$col}; @@ -1540,14 +1540,15 @@ foreach my $id (@idlist) { # When editing multiple bugs, users can specify a list of keywords to delete # from bugs. If the list matches the current set of keywords on those bugs, - # CheckCanChangeField above will fail to check permissions because it thinks - # the list hasn't changed. To fix that, we have to call CheckCanChangeField + # Bug::check_can_change_field will fail to check permissions because it thinks + # the list hasn't changed. To fix that, we have to call Bug::check_can_change_field # again with old!=new if the keyword action is "delete" and old=new. if ($keywordaction eq "delete" && defined $cgi->param('keywords') && length(@keywordlist) > 0 && $cgi->param('keywords') eq $oldhash{keywords} - && !CheckCanChangeField("keywords", $id, "old is not", "equal to new")) + && !$old_bug_obj->check_can_change_field("keywords", "old is not", "equal to new", + \$PrivilegesRequired)) { $vars->{'oldvalue'} = $oldhash{keywords}; $vars->{'newvalue'} = "no keywords"; @@ -1556,7 +1557,7 @@ foreach my $id (@idlist) { ThrowUserError("illegal_change", $vars); } - $oldhash{'product'} = get_product_name($oldhash{'product_id'}); + $oldhash{'product'} = $old_bug_obj->product; if (!Bugzilla->user->can_edit_product($oldhash{'product_id'})) { ThrowUserError("product_edit_denied", { product => $oldhash{'product'} }); @@ -1565,7 +1566,8 @@ foreach my $id (@idlist) { if ($requiremilestone) { # musthavemilestoneonaccept applies only if at least two # target milestones are defined for the current product. - my $nb_milestones = scalar(@{$::target_milestone{$oldhash{'product'}}}); + my $prod_obj = new Bugzilla::Product({'name' => $oldhash{'product'}}); + my $nb_milestones = scalar(@{$prod_obj->milestones}); if ($nb_milestones > 1) { my $value = $cgi->param('target_milestone'); if (!defined $value || $value eq $cgi->param('dontchange')) { @@ -1614,12 +1616,10 @@ foreach my $id (@idlist) { # Start updating the relevant database entries # - SendSQL("select now()"); - $timestamp = FetchOneColumn(); - my $sql_timestamp = SqlQuote($timestamp); + $timestamp = $dbh->selectrow_array(q{SELECT NOW()}); my $work_time; - if (UserInGroup(Param('timetrackinggroup'))) { + if (Bugzilla->user->in_group(Bugzilla->params->{'timetrackinggroup'})) { $work_time = $cgi->param('work_time'); if ($work_time) { # AppendComment (called below) can in theory raise an error, @@ -1630,13 +1630,18 @@ foreach my $id (@idlist) { } } - if ($cgi->param('comment') || $work_time) { + if ($cgi->param('comment') || $work_time || $duplicate) { + my $type = $duplicate ? CMT_DUPE_OF : CMT_NORMAL; + AppendComment($id, $whoid, scalar($cgi->param('comment')), - scalar($cgi->param('commentprivacy')), $timestamp, $work_time); + scalar($cgi->param('commentprivacy')), $timestamp, + $work_time, $type, $duplicate); $bug_changed = 1; } - if (@::legal_keywords && defined $cgi->param('keywords')) { + if (Bugzilla::Keyword::keyword_count() + && defined $cgi->param('keywords')) + { # There are three kinds of "keywordsaction": makeexact, add, delete. # For makeexact, we delete everything, and then add our things. # For add, we delete things we're adding (to make sure we don't @@ -1644,91 +1649,99 @@ foreach my $id (@idlist) { # For delete, we just delete things on the list. my $changed = 0; if ($keywordaction eq "makeexact") { - SendSQL("DELETE FROM keywords WHERE bug_id = $id"); + $dbh->do(q{DELETE FROM keywords WHERE bug_id = ?}, + undef, $id); $changed = 1; } + my $sth_delete = $dbh->prepare(q{DELETE FROM keywords + WHERE bug_id = ? + AND keywordid = ?}); + my $sth_insert = + $dbh->prepare(q{INSERT INTO keywords (bug_id, keywordid) + VALUES (?, ?)}); foreach my $keyword (@keywordlist) { if ($keywordaction ne "makeexact") { - SendSQL("DELETE FROM keywords - WHERE bug_id = $id AND keywordid = $keyword"); + $sth_delete->execute($id, $keyword); $changed = 1; } if ($keywordaction ne "delete") { - SendSQL("INSERT INTO keywords - (bug_id, keywordid) VALUES ($id, $keyword)"); + $sth_insert->execute($id, $keyword); $changed = 1; } } if ($changed) { - SendSQL("SELECT keyworddefs.name - FROM keyworddefs INNER JOIN keywords - ON keyworddefs.id = keywords.keywordid - WHERE keywords.bug_id = $id - ORDER BY keyworddefs.name"); - my @list; - while (MoreSQLData()) { - push(@list, FetchOneColumn()); - } + my $list = $dbh->selectcol_arrayref( + q{SELECT keyworddefs.name + FROM keyworddefs + INNER JOIN keywords + ON keyworddefs.id = keywords.keywordid + WHERE keywords.bug_id = ? + ORDER BY keyworddefs.name}, + undef, $id); $dbh->do("UPDATE bugs SET keywords = ? WHERE bug_id = ?", - undef, join(', ', @list), $id); + undef, join(', ', @$list), $id); } } - $query .= " where bug_id = $id"; - + $query .= " WHERE bug_id = ?"; + push(@bug_values, $id); + if ($::comma ne "") { - SendSQL($query); + $dbh->do($query, undef, @bug_values); } - # Check for duplicates if the bug is [re]open - SendSQL("SELECT resolution FROM bugs WHERE bug_id = $id"); - my $resolution = FetchOneColumn(); - if ($resolution eq '') { - SendSQL("DELETE FROM duplicates WHERE dupe = $id"); - } - - my $newproduct_id = $oldhash{'product_id'}; - if ($cgi->param('product') ne $cgi->param('dontchange')) { - my $newproduct_id = get_product_id($cgi->param('product')); + # Check for duplicates if the bug is [re]open or its resolution is changed. + my $resolution = $dbh->selectrow_array( + q{SELECT resolution FROM bugs WHERE bug_id = ?}, undef, $id); + if ($resolution ne 'DUPLICATE') { + $dbh->do(q{DELETE FROM duplicates WHERE dupe = ?}, undef, $id); } my %groupsrequired = (); my %groupsforbidden = (); - SendSQL("SELECT id, membercontrol - FROM groups LEFT JOIN group_control_map - ON id = group_id - AND product_id = $newproduct_id WHERE isactive != 0"); - while (MoreSQLData()) { - my ($group, $control) = FetchSQLData(); + my $group_controls = + $dbh->selectall_arrayref(q{SELECT id, membercontrol + FROM groups + LEFT JOIN group_control_map + ON id = group_id + AND product_id = ? + WHERE isactive != 0}, + undef, $oldhash{'product_id'}); + foreach my $group_control (@$group_controls) { + my ($group, $control) = @$group_control; $control ||= 0; - unless ($control > &::CONTROLMAPNA) { + unless ($control > CONTROLMAPNA) { $groupsforbidden{$group} = 1; } - if ($control == &::CONTROLMAPMANDATORY) { + if ($control == CONTROLMAPMANDATORY) { $groupsrequired{$group} = 1; } } my @groupAddNames = (); my @groupAddNamesAll = (); + my $sth = $dbh->prepare(q{INSERT INTO bug_group_map (bug_id, group_id) + VALUES (?, ?)}); foreach my $grouptoadd (@groupAdd, keys %groupsrequired) { next if $groupsforbidden{$grouptoadd}; - push(@groupAddNamesAll, GroupIdToName($grouptoadd)); + my $group_obj = new Bugzilla::Group($grouptoadd); + push(@groupAddNamesAll, $group_obj->name); if (!BugInGroupId($id, $grouptoadd)) { - push(@groupAddNames, GroupIdToName($grouptoadd)); - SendSQL("INSERT INTO bug_group_map (bug_id, group_id) - VALUES ($id, $grouptoadd)"); + push(@groupAddNames, $group_obj->name); + $sth->execute($id, $grouptoadd); } } my @groupDelNames = (); my @groupDelNamesAll = (); + $sth = $dbh->prepare(q{DELETE FROM bug_group_map + WHERE bug_id = ? AND group_id = ?}); foreach my $grouptodel (@groupDel, keys %groupsforbidden) { - push(@groupDelNamesAll, GroupIdToName($grouptodel)); + my $group_obj = new Bugzilla::Group($grouptodel); + push(@groupDelNamesAll, $group_obj->name); next if $groupsrequired{$grouptodel}; if (BugInGroupId($id, $grouptodel)) { - push(@groupDelNames, GroupIdToName($grouptodel)); + push(@groupDelNames, $group_obj->name); } - SendSQL("DELETE FROM bug_group_map - WHERE bug_id = $id AND group_id = $grouptodel"); + $sth->execute($id, $grouptodel); } my $groupDelNames = join(',', @groupDelNames); @@ -1747,25 +1760,30 @@ foreach my $id (@idlist) { || defined $cgi->param('masscc')) { # Get the current CC list for this bug my %oncc; - SendSQL("SELECT who FROM cc WHERE bug_id = $id"); - while (MoreSQLData()) { - $oncc{FetchOneColumn()} = 1; + my $cc_list = $dbh->selectcol_arrayref( + q{SELECT who FROM cc WHERE bug_id = ?}, undef, $id); + foreach my $who (@$cc_list) { + $oncc{$who} = 1; } my (@added, @removed) = (); - + + my $sth_insert = $dbh->prepare(q{INSERT INTO cc (bug_id, who) + VALUES (?, ?)}); foreach my $pid (keys %cc_add) { # If this person isn't already on the cc list, add them if (! $oncc{$pid}) { - SendSQL("INSERT INTO cc (bug_id, who) VALUES ($id, $pid)"); + $sth_insert->execute($id, $pid); push (@added, $cc_add{$pid}); $oncc{$pid} = 1; } } + my $sth_delete = $dbh->prepare(q{DELETE FROM cc + WHERE bug_id = ? AND who = ?}); foreach my $pid (keys %cc_remove) { # If the person is on the cc list, remove them if ($oncc{$pid}) { - SendSQL("DELETE FROM cc WHERE bug_id = $id AND who = $pid"); + $sth_delete->execute($id, $pid); push (@removed, $cc_remove{$pid}); $oncc{$pid} = 0; } @@ -1791,12 +1809,16 @@ foreach my $id (@idlist) { my @oldlist = @{$dbh->selectcol_arrayref("SELECT $target FROM dependencies WHERE $me = ? ORDER BY $target", undef, $id)}; - @dependencychanged{@oldlist} = 1; + + # Only bugs depending on the current one should get notification. + # Bugs blocking the current one never get notification, unless they + # are added or removed from the dependency list. This case is treated + # below. + @dependencychanged{@oldlist} = 1 if ($me eq 'dependson'); if (defined $cgi->param($target)) { my %snapshot; my @newlist = sort {$a <=> $b} @{$deps{$target}}; - @dependencychanged{@newlist} = 1; while (0 < @oldlist || 0 < @newlist) { if (@oldlist == 0 || (@newlist > 0 && @@ -1820,15 +1842,22 @@ foreach my $id (@idlist) { my @keys = keys(%snapshot); if (@keys) { my $oldsnap = SnapShotDeps($id, $target, $me); - SendSQL("delete from dependencies where $me = $id"); + $dbh->do(qq{DELETE FROM dependencies WHERE $me = ?}, + undef, $id); + my $sth = + $dbh->prepare(qq{INSERT INTO dependencies ($me, $target) + VALUES (?, ?)}); foreach my $i (@{$deps{$target}}) { - SendSQL("insert into dependencies ($me, $target) values ($id, $i)"); + $sth->execute($id, $i); } foreach my $k (@keys) { LogDependencyActivity($k, $snapshot{$k}, $me, $target, $timestamp); } LogDependencyActivity($id, $oldsnap, $target, $me, $timestamp); $check_dep_bugs = 1; + # All bugs added or removed from the dependency list + # must be notified. + @dependencychanged{@keys} = 1; } } } @@ -1840,9 +1869,8 @@ foreach my $id (@idlist) { # about which can be found in comments within the conditionals below. # Check if the user has changed the product to which the bug belongs; if ($cgi->param('product') ne $cgi->param('dontchange') - && $cgi->param('product') ne $oldhash{'product'} - ) { - $newproduct_id = get_product_id($cgi->param('product')); + && $cgi->param('product') ne $oldhash{'product'}) + { # Depending on the "addtonewgroup" variable, groups with # defaults will change. # @@ -1852,22 +1880,24 @@ foreach my $id (@idlist) { # - The control map value for the new product and this group # - Is the user in this group? # - Is the bug in this group? - SendSQL("SELECT DISTINCT groups.id, isactive, " . - "oldcontrolmap.membercontrol, newcontrolmap.membercontrol, " . - "CASE WHEN groups.id IN ($grouplist) THEN 1 ELSE 0 END, " . - "CASE WHEN bug_group_map.group_id IS NOT NULL " . - "THEN 1 ELSE 0 END " . - "FROM groups " . - "LEFT JOIN group_control_map AS oldcontrolmap " . - "ON oldcontrolmap.group_id = groups.id " . - "AND oldcontrolmap.product_id = " . $oldhash{'product_id'} . - " LEFT JOIN group_control_map AS newcontrolmap " . - "ON newcontrolmap.group_id = groups.id " . - "AND newcontrolmap.product_id = $newproduct_id " . - "LEFT JOIN bug_group_map " . - "ON bug_group_map.group_id = groups.id " . - "AND bug_group_map.bug_id = $id " - ); + my $groups = $dbh->selectall_arrayref( + qq{SELECT DISTINCT groups.id, isactive, + oldcontrolmap.membercontrol, + newcontrolmap.membercontrol, + CASE WHEN groups.id IN ($grouplist) THEN 1 ELSE 0 END, + CASE WHEN bug_group_map.group_id IS NOT NULL + THEN 1 ELSE 0 END + FROM groups + LEFT JOIN group_control_map AS oldcontrolmap + ON oldcontrolmap.group_id = groups.id + AND oldcontrolmap.product_id = ? + LEFT JOIN group_control_map AS newcontrolmap + ON newcontrolmap.group_id = groups.id + AND newcontrolmap.product_id = ? + LEFT JOIN bug_group_map + ON bug_group_map.group_id = groups.id + AND bug_group_map.bug_id = ?}, + undef, $oldhash{'product_id'}, $product->id, $id); my @groupstoremove = (); my @groupstoadd = (); my @defaultstoremove = (); @@ -1875,9 +1905,9 @@ foreach my $id (@idlist) { my @allgroups = (); my $buginanydefault = 0; my $buginanychangingdefault = 0; - while (MoreSQLData()) { - my ($groupid, $isactive, $oldcontrol, $newcontrol, - $useringroup, $bugingroup) = FetchSQLData(); + foreach my $group (@$groups) { + my ($groupid, $isactive, $oldcontrol, $newcontrol, + $useringroup, $bugingroup) = @$group; # An undefined newcontrol is none. $newcontrol = CONTROLMAPNA unless $newcontrol; $oldcontrol = CONTROLMAPNA unless $oldcontrol; @@ -1926,17 +1956,23 @@ foreach my $id (@idlist) { # Now actually update the bug_group_map. my @DefGroupsAdded = (); my @DefGroupsRemoved = (); + my $sth_insert = + $dbh->prepare(q{INSERT INTO bug_group_map (bug_id, group_id) + VALUES (?, ?)}); + my $sth_delete = $dbh->prepare(q{DELETE FROM bug_group_map + WHERE bug_id = ? + AND group_id = ?}); foreach my $groupid (@allgroups) { my $thisadd = grep( ($_ == $groupid), @groupstoadd); my $thisdel = grep( ($_ == $groupid), @groupstoremove); if ($thisadd) { - push(@DefGroupsAdded, GroupIdToName($groupid)); - SendSQL("INSERT INTO bug_group_map (bug_id, group_id) VALUES " . - "($id, $groupid)"); + my $group_obj = new Bugzilla::Group($groupid); + push(@DefGroupsAdded, $group_obj->name); + $sth_insert->execute($id, $groupid); } elsif ($thisdel) { - push(@DefGroupsRemoved, GroupIdToName($groupid)); - SendSQL("DELETE FROM bug_group_map WHERE bug_id = $id " . - "AND group_id = $groupid"); + my $group_obj = new Bugzilla::Group($groupid); + push(@DefGroupsRemoved, $group_obj->name); + $sth_delete->execute($id, $groupid); } } if ((@DefGroupsAdded) || (@DefGroupsRemoved)) { @@ -1951,10 +1987,11 @@ foreach my $id (@idlist) { # and then generate any necessary bug activity entries by seeing # what has changed since before we wrote out the new values. # + my $new_bug_obj = new Bugzilla::Bug($id); my @newvalues = SnapShotBug($id); my %newhash; $i = 0; - foreach my $col (@::log_columns) { + foreach my $col (@editable_bug_fields) { # Consider NULL db entries to be equivalent to the empty string $newvalues[$i] = defined($newvalues[$i]) ? $newvalues[$i] : ''; # Convert the deadline to the YYYY-MM-DD format. @@ -1969,8 +2006,11 @@ foreach my $id (@idlist) { # my $origOwner = ""; my $origQaContact = ""; - - foreach my $c (@::log_columns) { + + # $msgs will store emails which have to be sent to voters, if any. + my $msgs; + + foreach my $c (@editable_bug_fields) { my $col = $c; # We modify it, don't want to modify array # values in place. my $old = shift @oldvalues; @@ -1980,13 +2020,13 @@ foreach my $id (@idlist) { # Products and components are now stored in the DB using ID's # We need to translate this to English before logging it if ($col eq 'product_id') { - $old = get_product_name($old); - $new = get_product_name($new); + $old = $old_bug_obj->product; + $new = $new_bug_obj->product; $col = 'product'; } if ($col eq 'component_id') { - $old = get_component_name($old); - $new = get_component_name($new); + $old = $old_bug_obj->component; + $new = $new_bug_obj->component; $col = 'component'; } @@ -1994,16 +2034,16 @@ foreach my $id (@idlist) { # the old assignee can be notified # if ($col eq 'assigned_to') { - $old = ($old) ? DBID_to_name($old) : ""; - $new = ($new) ? DBID_to_name($new) : ""; + $old = ($old) ? user_id_to_login($old) : ""; + $new = ($new) ? user_id_to_login($new) : ""; $origOwner = $old; } # ditto for the old qa contact # if ($col eq 'qa_contact') { - $old = ($old) ? DBID_to_name($old) : ""; - $new = ($new) ? DBID_to_name($new) : ""; + $old = ($old) ? user_id_to_login($old) : ""; + $new = ($new) ? user_id_to_login($new) : ""; $origQaContact = $old; } @@ -2013,12 +2053,17 @@ foreach my $id (@idlist) { } if ($col eq 'product') { - RemoveVotes($id, 0, - "This bug has been moved to a different product"); + # If some votes have been removed, RemoveVotes() returns + # a list of messages to send to voters. + # We delay the sending of these messages till tables are unlocked. + $msgs = RemoveVotes($id, 0, + "This bug has been moved to a different product"); + + CheckIfVotedConfirmed($id, $whoid); } - + if ($col eq 'bug_status' - && IsOpenedState($old) ne IsOpenedState($new)) + && is_open_state($old) ne is_open_state($new)) { $check_dep_bugs = 1; } @@ -2028,42 +2073,49 @@ foreach my $id (@idlist) { } } # Set and update flags. - Bugzilla::Flag::process($id, undef, $timestamp, $cgi); + Bugzilla::Flag::process($new_bug_obj, undef, $timestamp, $cgi); if ($bug_changed) { - SendSQL("UPDATE bugs SET delta_ts = $sql_timestamp WHERE bug_id = $id"); + $dbh->do(q{UPDATE bugs SET delta_ts = ? WHERE bug_id = ?}, + undef, $timestamp, $id); } $dbh->bz_unlock_tables(); + # Now is a good time to send email to voters. + foreach my $msg (@$msgs) { + MessageToMTA($msg); + } + if ($duplicate) { + # If the bug was already marked as a duplicate, remove + # the existing entry. + $dbh->do('DELETE FROM duplicates WHERE dupe = ?', + undef, $cgi->param('id')); + # Check to see if Reporter of this bug is reporter of Dupe - SendSQL("SELECT reporter FROM bugs WHERE bug_id = " . - $cgi->param('id')); - my $reporter = FetchOneColumn(); - SendSQL("SELECT reporter FROM bugs WHERE bug_id = " . - "$duplicate and reporter = $reporter"); - my $isreporter = FetchOneColumn(); - SendSQL("SELECT who FROM cc WHERE bug_id = " . - " $duplicate and who = $reporter"); - my $isoncc = FetchOneColumn(); + my $reporter = $dbh->selectrow_array( + q{SELECT reporter FROM bugs WHERE bug_id = ?}, undef, $id); + my $isreporter = $dbh->selectrow_array( + q{SELECT reporter FROM bugs WHERE bug_id = ? AND reporter = ?}, + undef, $duplicate, $reporter); + my $isoncc = $dbh->selectrow_array(q{SELECT who FROM cc + WHERE bug_id = ? AND who = ?}, + undef, $duplicate, $reporter); unless ($isreporter || $isoncc || !$cgi->param('confirm_add_duplicate')) { # The reporter is oblivious to the existence of the new bug and is permitted access # ... add 'em to the cc (and record activity) - LogActivityEntry($duplicate,"cc","",DBID_to_name($reporter), + LogActivityEntry($duplicate,"cc","",user_id_to_login($reporter), $whoid,$timestamp); - SendSQL("INSERT INTO cc (who, bug_id) " . - "VALUES ($reporter, $duplicate)"); + $dbh->do(q{INSERT INTO cc (who, bug_id) VALUES (?, ?)}, + undef, $reporter, $duplicate); } - # Bug 171639 - Duplicate notifications do not need to be private. - AppendComment($duplicate, $whoid, - "*** Bug " . $cgi->param('id') . - " has been marked as a duplicate of this bug. ***", - 0, $timestamp); + # Bug 171639 - Duplicate notifications do not need to be private. + AppendComment($duplicate, $whoid, "", 0, $timestamp, 0, + CMT_HAS_DUPE, scalar $cgi->param('id')); - check_form_field_defined($cgi,'comment'); - SendSQL("INSERT INTO duplicates VALUES ($duplicate, " . - $cgi->param('id') . ")"); + $dbh->do(q{INSERT INTO duplicates VALUES (?, ?)}, undef, + $duplicate, $cgi->param('id')); } # Now all changes to the DB have been made. It's time to email @@ -2080,20 +2132,17 @@ foreach my $id (@idlist) { # Let the user know the bug was changed and who did and didn't # receive email about the change. - $template->process("bug/process/results.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - $vars->{'header_done'} = 1; - + send_results($id, $vars); + if ($duplicate) { $vars->{'mailrecipients'} = { 'changer' => Bugzilla->user->login }; $vars->{'id'} = $duplicate; $vars->{'type'} = "dupe"; - # Let the user know a duplication notation was added to the original bug. - $template->process("bug/process/results.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - $vars->{'header_done'} = 1; + # Let the user know a duplication notation was added to the + # original bug. + send_results($duplicate, $vars); } if ($check_dep_bugs) { @@ -2102,12 +2151,11 @@ foreach my $id (@idlist) { $vars->{'id'} = $k; $vars->{'type'} = "dep"; - # Let the user (if he is able to see the bug) know we checked to see - # if we should email notice of this change to users with a relationship - # to the dependent bug and who did and didn't receive email about it. - $template->process("bug/process/results.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - $vars->{'header_done'} = 1; + # Let the user (if he is able to see the bug) know we checked to + # see if we should email notice of this change to users with a + # relationship to the dependent bug and who did and didn't + # receive email about it. + send_results($k, $vars); } } } @@ -2126,7 +2174,10 @@ if (defined $cgi->param('id')) { $action = 'nothing'; } -if ($action eq 'next_bug') { +if (Bugzilla->usage_mode == USAGE_MODE_EMAIL) { + # Do nothing. +} +elsif ($action eq 'next_bug') { my $next_bug; my $cur = lsearch(\@bug_list, $cgi->param("id")); if ($cur >= 0 && $cur < $#bug_list) { @@ -2134,7 +2185,7 @@ if ($action eq 'next_bug') { } if ($next_bug) { if (detaint_natural($next_bug) && Bugzilla->user->can_see_bug($next_bug)) { - my $bug = new Bugzilla::Bug($next_bug, $whoid); + my $bug = new Bugzilla::Bug($next_bug); ThrowCodeError("bug_error", { bug => $bug }) if $bug->error; $vars->{'bugs'} = [$bug]; @@ -2148,7 +2199,7 @@ if ($action eq 'next_bug') { } } elsif ($action eq 'same_bug') { if (Bugzilla->user->can_see_bug($cgi->param('id'))) { - my $bug = new Bugzilla::Bug($cgi->param('id'), $whoid); + my $bug = new Bugzilla::Bug($cgi->param('id')); ThrowCodeError("bug_error", { bug => $bug }) if $bug->error; $vars->{'bugs'} = [$bug]; @@ -2163,7 +2214,11 @@ if ($action eq 'next_bug') { } # End the response page. -$template->process("bug/navigate.html.tmpl", $vars) - || ThrowTemplateError($template->error()); -$template->process("global/footer.html.tmpl", $vars) - || ThrowTemplateError($template->error()); +unless (Bugzilla->usage_mode == USAGE_MODE_EMAIL) { + $template->process("bug/navigate.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + $template->process("global/footer.html.tmpl", $vars) + || ThrowTemplateError($template->error()); +} + +1; diff --git a/query.cgi b/query.cgi index efd407ebc..ce6aefc61 100755 --- a/query.cgi +++ b/query.cgi @@ -28,29 +28,17 @@ use strict; use lib "."; -require "globals.pl"; - +use Bugzilla; +use Bugzilla::Bug; use Bugzilla::Constants; use Bugzilla::Search; use Bugzilla::User; use Bugzilla::Util; - -use vars qw( - @legal_resolution - @legal_bug_status - @legal_components - @legal_keywords - @legal_opsys - @legal_platform - @legal_priority - @legal_product - @legal_severity - @legal_target_milestone - @legal_versions - @log_columns - %versions - %components -); +use Bugzilla::Error; +use Bugzilla::Product; +use Bugzilla::Keyword; +use Bugzilla::Field; +use Bugzilla::Install::Requirements; my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; @@ -58,15 +46,7 @@ my $template = Bugzilla->template; my $vars = {}; my $buffer = $cgi->query_string(); -if ($cgi->param("GoAheadAndLogIn")) { - # We got here from a login page, probably from relogin.cgi. We better - # make sure the password is legit. - Bugzilla->login(LOGIN_REQUIRED); -} else { - Bugzilla->login(); -} - -my $user = Bugzilla->user; +my $user = Bugzilla->login(); my $userid = $user->id; # Backwards compatibility hack -- if there are any of the old QUERY_* @@ -124,13 +104,14 @@ if ($userid) { undef, ($userid, DEFAULT_QUERY_NAME)); } -my %default; +local our %default; # We pass the defaults as a hash of references to arrays. For those # Items which are single-valued, the template should only reference [0] # and ignore any multiple values. sub PrefillForm { my ($buf) = (@_); + $buf = new Bugzilla::CGI($buf); my $foundone = 0; # Nothing must be undef, otherwise the template complains. @@ -152,26 +133,14 @@ sub PrefillForm { "category", "subcategory", "name", "newcategory", "newsubcategory", "public", "frequency") { - # This is a bit of a hack. The default, empty list has - # three entries to accommodate the needs of the email fields - - # we use each position to denote the relevant field. Array - # position 0 is unused for email fields because the form - # parameters historically started at 1. - $default{$name} = ["", "", ""]; + $default{$name} = []; } # Iterate over the URL parameters - foreach my $item (split(/\&/, $buf)) { - my @el = split(/=/, $item); - my $name = $el[0]; - my $value; - if ($#el > 0) { - $value = Bugzilla::Util::url_decode($el[1]); - } else { - $value = ""; - } - + foreach my $name ($buf->param()) { + my @values = $buf->param($name); + # If the name begins with field, type, or value, then it is part of # the boolean charts. Because these are built different than the rest # of the form, we don't need to save a default value. We do, however, @@ -185,119 +154,54 @@ sub PrefillForm { # positions to show the defaults for that number field. elsif ($name =~ m/^(.+)(\d)$/ && defined($default{$1})) { $foundone = 1; - $default{$1}->[$2] = $value; + $default{$1}->[$2] = $values[0]; } - # If there's no default yet, we replace the blank string. - elsif (defined($default{$name}) && $default{$name}->[0] eq "") { + elsif (exists $default{$name}) { $foundone = 1; - $default{$name} = [$value]; - } - # If there's already a default, we push on the new value. - elsif (defined($default{$name})) { - push (@{$default{$name}}, $value); - } - } + push (@{$default{$name}}, @values); + } + } return $foundone; } - if (!PrefillForm($buffer)) { # Ah-hah, there was no form stuff specified. Do it again with the # default query. if ($userdefaultquery) { PrefillForm($userdefaultquery); } else { - PrefillForm(Param("defaultquery")); + PrefillForm(Bugzilla->params->{"defaultquery"}); } } -if ($default{'chfieldto'}->[0] eq "") { +if (!scalar(@{$default{'chfieldto'}}) || $default{'chfieldto'}->[0] eq "") { $default{'chfieldto'} = ["Now"]; } -GetVersionTable(); - # if using groups for entry, then we don't want people to see products they # don't have access to. Remove them from the list. - -my @selectable_product_objects = @{$user->get_selectable_products}; - -my %component_set; -my %version_set; -my %milestone_set; -# extract product names -my @products = map { $_->name } @selectable_product_objects; - -foreach my $prod_name (@products) { - # We build up boolean hashes in the "-set" hashes for each of these things - # before making a list because there may be duplicates names across products. - if ($::components{$prod_name}) { - foreach my $c (@{$::components{$prod_name}}) { - $component_set{$c} = 1; - } - } - foreach my $v (@{$::versions{$prod_name}}) { - $version_set{$v} = 1; - } - foreach my $m (@{$::target_milestone{$prod_name}}) { - $milestone_set{$m} = 1; - } -} - -# @products is now all the products we are ever concerned with, as a list -# %x_set is now a unique "list" of the relevant components/versions/tms -@products = sort { lc($a) cmp lc($b) } @products; +my @selectable_products = sort {lc($a->name) cmp lc($b->name)} + @{$user->get_selectable_products}; # Create the component, version and milestone lists. -my @components = (); -my @versions = (); -my @milestones = (); -foreach my $c (@::legal_components) { - if ($component_set{$c}) { - push @components, $c; - } -} -foreach my $v (@::legal_versions) { - if ($version_set{$v}) { - push @versions, $v; - } -} -foreach my $m (@::legal_target_milestone) { - if ($milestone_set{$m}) { - push @milestones, $m; - } +my %components; +my %versions; +my %milestones; + +foreach my $product (@selectable_products) { + $components{$_->name} = 1 foreach (@{$product->components}); + $versions{$_->name} = 1 foreach (@{$product->versions}); + $milestones{$_->name} = 1 foreach (@{$product->milestones}); } -# Create data structures representing each product. -for (my $i = 0; $i < @products; ++$i) { - my $p = $products[$i]; - - # Bug 190611: band-aid to avoid crashing with no versions defined - if (!defined ($::components{$p})) { - $::components{$p} = []; - } - - # Create hash to hold attributes for each product. - my %product = ( - 'name' => $p, - 'components' => [ sort { lc($a) cmp lc($b) } @{$::components{$p}} ], - 'versions' => [ sort { lc($a) cmp lc($b) } @{$::versions{$p}} ] - ); - - if (Param('usetargetmilestone')) { - # Sorting here is required for ordering multiple selections - # correctly; see bug 97736 for discussion on how to fix this - $product{'milestones'} = - [ sort { lc($a) cmp lc($b) } @{$::target_milestone{$p}} ]; - } - - # Assign hash back to product array. - $products[$i] = \%product; -} -$vars->{'product'} = \@products; +my @components = sort(keys %components); +my @versions = sort { vers_cmp (lc($a), lc($b)) } keys %versions; +my @milestones = sort(keys %milestones); + +$vars->{'product'} = \@selectable_products; # Create data structures representing each classification -if (Param('useclassification')) { +if (Bugzilla->params->{'useclassification'}) { $vars->{'classification'} = $user->get_selectable_classifications; } @@ -306,16 +210,16 @@ $vars->{'component_'} = \@components; $vars->{'version'} = \@versions; -if (Param('usetargetmilestone')) { +if (Bugzilla->params->{'usetargetmilestone'}) { $vars->{'target_milestone'} = \@milestones; } -$vars->{'have_keywords'} = scalar(@::legal_keywords); +$vars->{'have_keywords'} = Bugzilla::Keyword::keyword_count(); -push @::legal_resolution, "---"; # Oy, what a hack. -shift @::legal_resolution; - # Another hack - this array contains "" for some reason. See bug 106589. -$vars->{'resolution'} = \@::legal_resolution; +my $legal_resolutions = get_legal_field_values('resolution'); +push(@$legal_resolutions, "---"); # Oy, what a hack. +# Another hack - this array contains "" for some reason. See bug 106589. +$vars->{'resolution'} = [grep ($_, @$legal_resolutions)]; my @chfields; @@ -323,7 +227,7 @@ push @chfields, "[Bug creation]"; # This is what happens when you have variables whose definition depends # on the DB schema, and then the underlying schema changes... -foreach my $val (@::log_columns) { +foreach my $val (editable_bug_fields()) { if ($val eq 'classification_id') { $val = 'classification'; } elsif ($val eq 'product_id') { @@ -334,7 +238,7 @@ foreach my $val (@::log_columns) { push @chfields, $val; } -if (UserInGroup(Param('timetrackinggroup'))) { +if (Bugzilla->user->in_group(Bugzilla->params->{'timetrackinggroup'})) { push @chfields, "work_time"; } else { @chfields = grep($_ ne "estimated_time", @chfields); @@ -342,16 +246,17 @@ if (UserInGroup(Param('timetrackinggroup'))) { } @chfields = (sort(@chfields)); $vars->{'chfield'} = \@chfields; -$vars->{'bug_status'} = \@::legal_bug_status; -$vars->{'rep_platform'} = \@::legal_platform; -$vars->{'op_sys'} = \@::legal_opsys; -$vars->{'priority'} = \@::legal_priority; -$vars->{'bug_severity'} = \@::legal_severity; +$vars->{'bug_status'} = get_legal_field_values('bug_status'); +$vars->{'rep_platform'} = get_legal_field_values('rep_platform'); +$vars->{'op_sys'} = get_legal_field_values('op_sys'); +$vars->{'priority'} = get_legal_field_values('priority'); +$vars->{'bug_severity'} = get_legal_field_values('bug_severity'); # Boolean charts my @fields; push(@fields, { name => "noop", description => "---" }); push(@fields, $dbh->bz_get_field_defs()); +@fields = sort {lc($a->{'description'}) cmp lc($b->{'description'})} @fields; $vars->{'fields'} = \@fields; # Creating new charts - if the cmd-add value is there, we define the field @@ -413,7 +318,7 @@ if ($cgi->param('order')) { $deforder = $cgi->param('order') } $vars->{'userdefaultquery'} = $userdefaultquery; $vars->{'orders'} = \@orders; -$default{'querytype'} = $deforder || 'Importance'; +$default{'order'} = [$deforder || 'Importance']; if (($cgi->param('query_format') || $cgi->param('format') || "") eq "create-series") { diff --git a/quips.cgi b/quips.cgi index b2fd482bc..bb0e5afff 100755 --- a/quips.cgi +++ b/quips.cgi @@ -27,9 +27,11 @@ use strict; use lib qw(.); -require "globals.pl"; - +use Bugzilla; use Bugzilla::Constants; +use Bugzilla::Util; +use Bugzilla::Error; +use Bugzilla::User; my $user = Bugzilla->login(LOGIN_REQUIRED); @@ -69,12 +71,12 @@ if ($action eq "show") { } if ($action eq "add") { - (Param('quip_list_entry_control') eq "closed") && + (Bugzilla->params->{'quip_list_entry_control'} eq "closed") && ThrowUserError("no_new_quips"); # Add the quip - my $approved = - (Param('quip_list_entry_control') eq "open") || (UserInGroup('admin')) || 0; + my $approved = (Bugzilla->params->{'quip_list_entry_control'} eq "open") + || Bugzilla->user->in_group('admin') || 0; my $comment = $cgi->param("quip"); $comment || ThrowUserError("need_quip"); trick_taint($comment); # Used in a placeholder below @@ -113,7 +115,7 @@ if ($action eq 'approve') { } if ($action eq "delete") { - UserInGroup("admin") + Bugzilla->user->in_group("admin") || ThrowUserError("auth_failure", {group => "admin", action => "delete", object => "quips"}); diff --git a/relogin.cgi b/relogin.cgi index 4dbd33996..5aa187490 100755 --- a/relogin.cgi +++ b/relogin.cgi @@ -25,10 +25,8 @@ use strict; use lib qw(.); -require "globals.pl"; - use Bugzilla; -use Bugzilla::BugMail; +use Bugzilla::Mailer; use Bugzilla::Constants; use Bugzilla::Error; use Bugzilla::Token; @@ -75,8 +73,7 @@ elsif ($action eq 'begin-sudo') { # and password. # We only need to do this for authentication methods that involve Bugzilla # directly obtaining a login (i.e. normal CGI login), as opposed to other - # methods (like Environment vars login). We assume that if a user can log - # out, they can also log in: + # methods (like Environment vars login). # First, record if Bugzilla_login and Bugzilla_password were provided my $credentials_provided; @@ -92,7 +89,7 @@ elsif ($action eq 'begin-sudo') { # At this point, the user is logged in. However, if they used a method # where they could have provided a username/password (i.e. CGI), but they # did not provide a username/password, then throw an error. - if ($user->get_flag('can_logout') && !$credentials_provided) { + if ($user->authorizer->can_login && !$credentials_provided) { ThrowUserError('sudo_password_required', { target_login => $cgi->param('target_login'), reason => $cgi->param('reason')}); @@ -128,7 +125,7 @@ elsif ($action eq 'begin-sudo') { # Get & verify the target user (the user who we will be impersonating) my $target_user = - Bugzilla::User->new_from_login($cgi->param('target_login')); + new Bugzilla::User({ name => $cgi->param('target_login') }); unless (defined($target_user) && $target_user->id && $user->can_see_user($target_user)) @@ -164,7 +161,7 @@ elsif ($action eq 'begin-sudo') { $template->process('email/sudo.txt.tmpl', { reason => $reason }, \$message); - Bugzilla::BugMail::MessageToMTA($message); + MessageToMTA($message); $vars->{'message'} = 'sudo_started'; $vars->{'target'} = $target_user->login; diff --git a/report.cgi b/report.cgi index 98fcb2e7f..10c532163 100755 --- a/report.cgi +++ b/report.cgi @@ -24,12 +24,11 @@ use strict; use lib "."; -require "globals.pl"; - -use vars qw(@legal_opsys @legal_platform @legal_severity); - use Bugzilla; use Bugzilla::Constants; +use Bugzilla::Util; +use Bugzilla::Error; +use Bugzilla::Field; my $cgi = Bugzilla->cgi; my $template = Bugzilla->template; @@ -48,8 +47,6 @@ if (grep(/^cmd-/, $cgi->param())) { use Bugzilla::Search; -GetVersionTable(); - Bugzilla->login(); my $dbh = Bugzilla->switch_to_shadow_db(); @@ -329,12 +326,12 @@ sub get_names { my ($names, $isnumeric, $field) = @_; # These are all the fields we want to preserve the order of in reports. - my %fields = ('priority' => \@::legal_priority, - 'bug_severity' => \@::legal_severity, - 'rep_platform' => \@::legal_platform, - 'op_sys' => \@::legal_opsys, - 'bug_status' => \@::legal_bug_status, - 'resolution' => [' ', @::legal_resolution]); + my %fields = ('priority' => get_legal_field_values('priority'), + 'bug_severity' => get_legal_field_values('bug_severity'), + 'rep_platform' => get_legal_field_values('rep_platform'), + 'op_sys' => get_legal_field_values('op_sys'), + 'bug_status' => get_legal_field_values('bug_status'), + 'resolution' => [' ', @{get_legal_field_values('resolution')}]); my $field_list = $fields{$field}; my @sorted; diff --git a/reports.cgi b/reports.cgi index 731618c0f..2c9f8facc 100755 --- a/reports.cgi +++ b/reports.cgi @@ -30,34 +30,33 @@ # daily stats file, so now works independently of collectstats.pl # version # Added image caching by date and datasets -# Myk Melez <myk@mozilla.org): +# Myk Melez <myk@mozilla.org>: # Implemented form field validation and reorganized code. +# Frédéric Buclin <LpSolit@gmail.com>: +# Templatization. use strict; use lib qw(.); -use Bugzilla::Config qw(:DEFAULT $datadir); - -require "globals.pl"; -use vars qw(@legal_product); # globals from er, globals.pl +use Bugzilla; +use Bugzilla::Constants; +use Bugzilla::Util; +use Bugzilla::Error; eval "use GD"; $@ && ThrowCodeError("gd_not_installed"); eval "use Chart::Lines"; $@ && ThrowCodeError("chart_lines_not_installed"); -my $dir = "$datadir/mining"; -my $graph_dir = "graphs"; - -use Bugzilla; +my $dir = bz_locations()->{'datadir'} . "/mining"; +my $graph_url = 'graphs'; +my $graph_dir = bz_locations()->{'libpath'} . '/' .$graph_url; # If we're using bug groups for products, we should apply those restrictions # to viewing reports, as well. Time to check the login in that case. my $user = Bugzilla->login(); -GetVersionTable(); - Bugzilla->switch_to_shadow_db(); my $cgi = Bugzilla->cgi; @@ -71,11 +70,33 @@ push( @myproducts, "-All-"); push( @myproducts, map { $_->name } @{$user->get_selectable_products} ); if (! defined $cgi->param('product')) { + # Can we do bug charts? + (-d $dir && -d $graph_dir) + || ThrowCodeError('chart_dir_nonexistent', + {dir => $dir, graph_dir => $graph_dir}); + + my %default_sel = map { $_ => 1 } qw/UNCONFIRMED NEW ASSIGNED REOPENED/; - choose_product(@myproducts); - $template->put_footer(); + my @datasets; + my @data = get_data($dir); -} else { + foreach my $dataset (@data) { + my $datasets = {}; + $datasets->{'value'} = $dataset; + $datasets->{'selected'} = $default_sel{$dataset} ? 1 : 0; + push(@datasets, $datasets); + } + + $vars->{'datasets'} = \@datasets; + $vars->{'products'} = \@myproducts; + + print $cgi->header(); + + $template->process('reports/old-charts.html.tmpl', $vars) + || ThrowTemplateError($template->error()); + exit; +} +else { my $product = $cgi->param('product'); # For security and correctness, validate the value of the "product" form variable. @@ -88,94 +109,49 @@ if (! defined $cgi->param('product')) { # This means that is OK to detaint trick_taint($product); - print $cgi->header(-Content_Disposition=>'inline; filename=bugzilla_report.html'); + defined($cgi->param('datasets')) || ThrowUserError('missing_datasets'); - $template->put_header("Bug Charts"); - $vars->{'header_done'} = 1; + my $datasets = join('', $cgi->param('datasets')); - show_chart($product); + my $type = chart_image_type(); + my $data_file = daily_stats_filename($product); + my $image_file = chart_image_name($data_file, $type, $datasets); + my $url_image = correct_urlbase() . "$graph_url/$image_file"; - $template->put_footer(); + if (! -e "$graph_dir/$image_file") { + generate_chart("$dir/$data_file", "$graph_dir/$image_file", $type, + $product, $datasets); + } + + $vars->{'url_image'} = $url_image; + + print $cgi->header(-Content_Disposition=>'inline; filename=bugzilla_report.html'); + + $template->process('reports/old-charts.html.tmpl', $vars) + || ThrowTemplateError($template->error()); + exit; } +##################### +# Subroutines # +##################### -################################## -# user came in with no form data # -################################## +sub get_data { + my $dir = shift; -sub choose_product { - my @myproducts = (@_); - + my @datasets; my $datafile = daily_stats_filename('-All-'); + open(DATA, '<', "$dir/$datafile") + || ThrowCodeError('chart_file_open_fail', {filename => "$dir/$datafile"}); - # Can we do bug charts? - (-d $dir && -d $graph_dir) - || ThrowCodeError("chart_dir_nonexistent", - {dir => $dir, graph_dir => $graph_dir}); - - open(DATA, "$dir/$datafile") - || ThrowCodeError("chart_file_open_fail", {filename => "$dir/$datafile"}); - - print $cgi->header(); - $template->put_header("Bug Charts"); - $vars->{'header_done'} = 1; - - print <<FIN; -<center> -<h1>Welcome to the Bugzilla Charting Kitchen</h1> -<form method=get action=reports.cgi> -<table border=1 cellpadding=5> -<tr> -<td align=center><b>Product:</b></td> -<td align=center> -<select name="product"> -FIN -foreach my $product (@myproducts) { - $product = html_quote($product); - print qq{<option value="$product">$product</option>}; -} -print <<FIN; -</select> -</td> -</tr> -<tr> - <td align=center><b>Chart datasets:</b></td> - <td align=center> - <select name="datasets" multiple size=5> -FIN - - my @datasets = (); - - while (<DATA>) { - if (/^# fields?: (.+)\s*$/) { - @datasets = grep ! /date/i, (split /\|/, $1); - last; - } - } - - close(DATA); - - my %default_sel = map { $_ => 1 } - qw/UNCONFIRMED NEW ASSIGNED REOPENED/; - foreach my $dataset (@datasets) { - my $sel = $default_sel{$dataset} ? ' selected' : ''; - print qq{<option value="$dataset:"$sel>$dataset</option>\n}; - } - - print <<FIN; - </select> - </td> - </tr> -<tr> -<td colspan=2 align=center> -<input type=submit value=Continue> -</td> -</tr> -</table> -</center> -</form> -<p> -FIN + while (<DATA>) { + if (/^# fields?: (.+)\s*$/) { + @datasets = grep ! /date/i, (split /\|/, $1); + last; + } + } + close(DATA); + return @datasets; } sub daily_stats_filename { @@ -184,35 +160,6 @@ sub daily_stats_filename { return $prodname; } -sub show_chart { - my ($product) = @_; - - if (! defined $cgi->param('datasets')) { - ThrowUserError("missing_datasets", $vars); - } - my $datasets = join('', $cgi->param('datasets')); - - print <<FIN; -<center> -FIN - - my $type = chart_image_type(); - my $data_file = daily_stats_filename($product); - my $image_file = chart_image_name($data_file, $type, $datasets); - my $url_image = "$graph_dir/" . url_quote($image_file); - - if (! -e "$graph_dir/$image_file") { - generate_chart("$dir/$data_file", "$graph_dir/$image_file", $type, - $product, $datasets); - } - - print <<FIN; -<img src="$url_image"> -<br clear=left> -<br> -FIN -} - sub chart_image_type { # what chart type should we be generating? my $testimg = Chart::Lines->new(2,2); @@ -229,12 +176,11 @@ sub chart_image_name { # is that we have to check the safety of doing this. We can't just require # that the fields exist, because what stats were collected could change # over time (eg by changing the resolutions available) - # Instead, just require that each field name consists only of letters - # and number + # Instead, just require that each field name consists only of letters, + # numbers, underscores and hyphens. - if ($datasets !~ m/^[A-Za-z0-9:]+$/) { - $vars->{'datasets'} = $datasets; - ThrowUserError('invalid_datasets', $vars); + if ($datasets !~ m/^[A-Za-z0-9:_-]+$/) { + ThrowUserError('invalid_datasets', {'datasets' => $datasets}); } # Since we pass the tests, consider it OK @@ -247,23 +193,14 @@ sub chart_image_name { return "${data_file}_${id}.$type"; } -sub day_of_year { - my ($mday, $month, $year) = (localtime())[3 .. 5]; - $month += 1; - $year += 1900; - my $date = sprintf "%02d%02d%04d", $mday, $month, $year; -} - sub generate_chart { my ($data_file, $image_file, $type, $product, $datasets) = @_; - + if (! open FILE, $data_file) { if ($product eq '-All-') { $product = ''; } - - $vars->{'product'} = $product; - ThrowCodeError("chart_data_not_generated", $vars); + ThrowCodeError('chart_data_not_generated', {'product' => $product}); } my @fields; @@ -278,8 +215,7 @@ sub generate_chart { if (/^# fields?: (.*)\s*$/) { @fields = split /\||\r/, $1; unless ($fields[0] =~ /date/i) { - $vars->{'file'} = $data_file; - ThrowCodeError("chart_datafile_corrupt", $vars); + ThrowCodeError('chart_datafile_corrupt', {'file' => $data_file}); } push @labels, grep($datasets{$_}, @fields); } @@ -287,10 +223,9 @@ sub generate_chart { } unless (@fields) { - $vars->{'file'} = $data_file; - ThrowCodeError("chart_datafile_corrupt", $vars); + ThrowCodeError('chart_datafile_corrupt', {'file' => $data_file}); } - + my @line = split /\|/; my $date = $line[0]; my ($yy, $mm, $dd) = $date =~ /^\d{2}(\d{2})(\d{2})(\d{2})$/; @@ -315,9 +250,9 @@ sub generate_chart { close FILE; if (! @{$data{DATE}}) { - ThrowUserError("insufficient_data_points", $vars); + ThrowUserError('insufficient_data_points'); } - + my $img = Chart::Lines->new (800, 600); my $i = 0; diff --git a/request.cgi b/request.cgi index 0be7174a1..8d514347a 100755 --- a/request.cgi +++ b/request.cgi @@ -19,6 +19,7 @@ # Rights Reserved. # # Contributor(s): Myk Melez <myk@mozilla.org> +# Frédéric Buclin <LpSolit@gmail.com> ################################################################################ # Script Initialization @@ -28,20 +29,19 @@ use strict; use lib qw(.); -require "globals.pl"; + use Bugzilla; +use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::Flag; use Bugzilla::FlagType; use Bugzilla::User; +use Bugzilla::Product; +use Bugzilla::Component; # Make sure the user is logged in. my $user = Bugzilla->login(); -my $userid = $user->id; - my $cgi = Bugzilla->cgi; -my $template = Bugzilla->template; -my $vars = {}; - ################################################################################ # Main Body Execution @@ -68,7 +68,12 @@ exit; sub queue { my $cgi = Bugzilla->cgi; + # There are some user privilege checks to do. We do them against the main DB. my $dbh = Bugzilla->dbh; + my $template = Bugzilla->template; + my $user = Bugzilla->user; + my $userid = $user->id; + my $vars = {}; my $status = validateStatus($cgi->param('status')); my $form_group = validateGroup($cgi->param('group')); @@ -83,7 +88,7 @@ sub queue { flags.attach_id, attachments.description, requesters.realname, requesters.login_name, requestees.realname, requestees.login_name, - " . $dbh->sql_date_format('flags.creation_date', '%Y.%m.%d %H:%i') . + " . $dbh->sql_date_format('flags.modification_date', '%Y.%m.%d %H:%i') . # Use the flags and flagtypes tables for information about the flags, # the bugs and attachments tables for target info, the profiles tables # for setter and requestee info, the products/components tables @@ -120,7 +125,7 @@ sub queue { (ccmap.who IS NOT NULL AND cclist_accessible = 1) OR (bugs.reporter = $userid AND bugs.reporter_accessible = 1) OR (bugs.assigned_to = $userid) " . - (Param('useqacontact') ? "OR + (Bugzilla->params->{'useqacontact'} ? "OR (bugs.qa_contact = $userid))" : ")"); unless ($user->is_insider) { @@ -129,15 +134,14 @@ sub queue { OR attachments.submitter_id = $userid)"; } - # Non-deleted flags only - $query .= " AND flags.is_active = 1 "; - # Limit query to pending requests. $query .= " AND flags.status = '?' " unless $status; # The set of criteria by which we filter records to display in the queue. + # We now move to the shadow DB to query the DB. my @criteria = (); - + $dbh = Bugzilla->switch_to_shadow_db; + # A list of columns to exclude from the report because the report conditions # limit the data being displayed to exact matches for those columns. # In other words, if we are only displaying "pending" , we don't @@ -178,36 +182,26 @@ sub queue { # Filter results by exact product or component. if (defined $cgi->param('product') && $cgi->param('product') ne "") { - my $product_id = get_product_id($cgi->param('product')); - if ($product_id) { - push(@criteria, "bugs.product_id = $product_id"); - push(@excluded_columns, 'product') unless $cgi->param('do_union'); - if (defined $cgi->param('component') && $cgi->param('component') ne "") { - my $component_id = get_component_id($product_id, $cgi->param('component')); - if ($component_id) { - push(@criteria, "bugs.component_id = $component_id"); - push(@excluded_columns, 'component') unless $cgi->param('do_union'); - } - else { ThrowUserError("component_not_valid", { 'product' => $cgi->param('product'), - 'name' => $cgi->param('component') }) } - } + my $product = Bugzilla::Product::check_product(scalar $cgi->param('product')); + push(@criteria, "bugs.product_id = " . $product->id); + push(@excluded_columns, 'product') unless $cgi->param('do_union'); + if (defined $cgi->param('component') && $cgi->param('component') ne "") { + my $component = + Bugzilla::Component::check_component($product, scalar $cgi->param('component')); + push(@criteria, "bugs.component_id = " . $component->id); + push(@excluded_columns, 'component') unless $cgi->param('do_union'); } - else { ThrowUserError("product_doesnt_exist", { 'product' => $cgi->param('product') }) } } - + # Filter results by flag types. my $form_type = $cgi->param('type'); if (defined $form_type && !grep($form_type eq $_, ("", "all"))) { # Check if any matching types are for attachments. If not, don't show # the attachment column in the report. - my $types = Bugzilla::FlagType::match({ 'name' => $form_type }); - my $has_attachment_type = 0; - foreach my $type (@$types) { - if ($type->{'target_type'} eq "attachment") { - $has_attachment_type = 1; - last; - } - } + my $has_attachment_type = + Bugzilla::FlagType::count({ 'name' => $form_type, + 'target_type' => 'attachment' }); + if (!$has_attachment_type) { push(@excluded_columns, 'attachment') } my $quoted_form_type = $dbh->quote($form_type); @@ -230,7 +224,7 @@ sub queue { products.name, components.name, flags.attach_id, attachments.description, requesters.realname, requesters.login_name, requestees.realname, - requestees.login_name, flags.creation_date, + requestees.login_name, flags.modification_date, cclist_accessible, bugs.reporter, bugs.reporter_accessible, bugs.assigned_to'); @@ -253,8 +247,8 @@ sub queue { } # Order the records (within each group). - $query .= " , flags.creation_date"; - + $query .= " , flags.modification_date"; + # Pass the query to the template for use when debugging this script. $vars->{'query'} = $query; $vars->{'debug'} = $cgi->param('debug') ? 1 : 0; @@ -284,7 +278,10 @@ sub queue { my $flagtypes = $dbh->selectcol_arrayref( "SELECT DISTINCT(name) FROM flagtypes ORDER BY name"); push(@types, @$flagtypes); - + + # We move back to the main DB to get the list of products the user can see. + $dbh = Bugzilla->switch_to_main_db; + $vars->{'products'} = $user->get_selectable_products; $vars->{'excluded_columns'} = \@excluded_columns; $vars->{'group_field'} = $form_group; @@ -292,7 +289,7 @@ sub queue { $vars->{'types'} = \@types; # Return the appropriate HTTP response headers. - print Bugzilla->cgi->header(); + print $cgi->header(); # Generate and return the UI (HTML page) from the appropriate template. $template->process("request/queue.html.tmpl", $vars) diff --git a/sanitycheck.cgi b/sanitycheck.cgi index 309a1077c..bf8ba1980 100755 --- a/sanitycheck.cgi +++ b/sanitycheck.cgi @@ -28,9 +28,10 @@ use strict; use lib qw(.); -require "globals.pl"; +use Bugzilla; use Bugzilla::Constants; use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::User; ########################################################################### @@ -78,12 +79,13 @@ Bugzilla->login(LOGIN_REQUIRED); my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; my $template = Bugzilla->template; +my $user = Bugzilla->user; # Make sure the user is authorized to access sanitycheck.cgi. # As this script can now alter the group_control_map table, we no longer # let users with editbugs privs run it anymore. -UserInGroup("editcomponents") - || (UserInGroup('editkeywords') && defined $cgi->param('rebuildkeywordcache')) +$user->in_group("editcomponents") + || ($user->in_group('editkeywords') && defined $cgi->param('rebuildkeywordcache')) || ThrowUserError("auth_failure", {group => "editcomponents", action => "run", object => "sanity_check"}); @@ -92,12 +94,12 @@ print $cgi->header(); my @row; -$template->put_header("Bugzilla Sanity Check"); +$template->put_header("Sanity Check"); ########################################################################### # Users with 'editkeywords' privs only can only check keywords. ########################################################################### -unless (UserInGroup('editcomponents')) { +unless ($user->in_group('editcomponents')) { check_votes_or_keywords('keywords'); Status("Sanity check completed."); $template->put_footer(); @@ -111,16 +113,15 @@ unless (UserInGroup('editcomponents')) { if (defined $cgi->param('rebuildvotecache')) { Status("OK, now rebuilding vote cache."); $dbh->bz_lock_tables('bugs WRITE', 'votes READ'); - SendSQL("UPDATE bugs SET votes = 0"); - SendSQL("SELECT bug_id, SUM(vote_count) FROM votes " . - $dbh->sql_group_by('bug_id')); - my %votes; - while (@row = FetchSQLData()) { - my ($id, $v) = (@row); - $votes{$id} = $v; - } - foreach my $id (keys %votes) { - SendSQL("UPDATE bugs SET votes = $votes{$id} WHERE bug_id = $id"); + $dbh->do(q{UPDATE bugs SET votes = 0}); + my $sth_update = $dbh->prepare(q{UPDATE bugs + SET votes = ? + WHERE bug_id = ?}); + my $sth = $dbh->prepare(q{SELECT bug_id, SUM(vote_count) + FROM votes }. $dbh->sql_group_by('bug_id')); + $sth->execute(); + while (my ($id, $v) = $sth->fetchrow_array) { + $sth_update->execute($v, $id); } $dbh->bz_unlock_tables(); Status("Vote cache has been rebuilt."); @@ -230,22 +231,33 @@ if (defined $cgi->param('rescanallBugMail')) { require Bugzilla::BugMail; Status("OK, now attempting to send unsent mail"); - SendSQL("SELECT bug_id FROM bugs - WHERE (lastdiffed IS NULL OR lastdiffed < delta_ts) AND - delta_ts < now() - " . $dbh->sql_interval(30, 'MINUTE') . - " ORDER BY bug_id"); - my @list; - while (MoreSQLData()) { - push (@list, FetchOneColumn()); - } - - Status(scalar(@list) . ' bugs found with possibly unsent mail.'); - - foreach my $bugid (@list) { - Bugzilla::BugMail::Send($bugid); + my $time = $dbh->sql_interval(30, 'MINUTE'); + + my $list = $dbh->selectcol_arrayref(qq{ + SELECT bug_id + FROM bugs + WHERE (lastdiffed IS NULL + OR lastdiffed < delta_ts) + AND delta_ts < now() - $time + ORDER BY bug_id}); + + Status(scalar(@$list) . ' bugs found with possibly unsent mail.'); + + my $vars = {}; + # We cannot simply look at the bugs_activity table to find who did the + # last change in a given bug, as e.g. adding a comment doesn't add any + # entry to this table. And some other changes may be private + # (such as time-related changes or private attachments or comments) + # and so choosing this user as being the last one having done a change + # for the bug may be problematic. So the best we can do at this point + # is to choose the currently logged in user for email notification. + $vars->{'changer'} = Bugzilla->user->login; + + foreach my $bugid (@$list) { + Bugzilla::BugMail::Send($bugid, $vars); } - if (scalar(@list) > 0) { + if (scalar(@$list) > 0) { Status("Unsent mail has been sent."); } @@ -340,6 +352,7 @@ print "OK, now running sanity checks.<p>\n"; sub CrossCheck { my $table = shift @_; my $field = shift @_; + my $dbh = Bugzilla->dbh; Status("Checking references to $table.$field"); @@ -351,29 +364,32 @@ sub CrossCheck { my %exceptions = map { $_ => 1 } @$exceptions; Status("... from $refertable.$referfield"); - - SendSQL("SELECT DISTINCT $refertable.$referfield" . ($keyname ? ", $refertable.$keyname" : '') . " " . - "FROM $refertable LEFT JOIN $table " . - " ON $refertable.$referfield = $table.$field " . - "WHERE $table.$field IS NULL " . - " AND $refertable.$referfield IS NOT NULL"); + + my $query = qq{SELECT DISTINCT $refertable.$referfield} . + ($keyname ? qq{, $refertable.$keyname } : q{}) . + qq{ FROM $refertable + LEFT JOIN $table + ON $refertable.$referfield = $table.$field + WHERE $table.$field IS NULL + AND $refertable.$referfield IS NOT NULL}; + + my $sth = $dbh->prepare($query); + $sth->execute; my $has_bad_references = 0; - while (MoreSQLData()) { - my ($value, $key) = FetchSQLData(); - if (!$exceptions{$value}) { - my $alert = "Bad value "$value" found in $refertable.$referfield"; - if ($keyname) { - if ($keyname eq 'bug_id') { - $alert .= ' (bug ' . BugLink($key) . ')'; - } - else { - $alert .= " ($keyname == '$key')"; - } + + while (my ($value, $key) = $sth->fetchrow_array) { + next if $exceptions{$value}; + my $alert = "Bad value "$value" found in $refertable.$referfield"; + if ($keyname) { + if ($keyname eq 'bug_id') { + $alert .= ' (bug ' . BugLink($key) . ')'; + } else { + $alert .= " ($keyname == '$key')"; } - Alert($alert); - $has_bad_references = 1; } + Alert($alert); + $has_bad_references = 1; } # References to non existent bugs can be safely removed, bug 288461 if ($table eq 'bugs' && $has_bad_references) { @@ -394,7 +410,7 @@ CrossCheck('classifications', 'id', CrossCheck("keyworddefs", "id", ["keywords", "keywordid"]); -CrossCheck("fielddefs", "fieldid", +CrossCheck("fielddefs", "id", ["bugs_activity", "fieldid"], ['profiles_activity', 'fieldid']); @@ -421,8 +437,14 @@ CrossCheck("groups", "id", ["group_group_map", "grantor_id"], ["group_group_map", "member_id"], ["group_control_map", "group_id"], + ["namedquery_group_map", "group_id"], ["user_group_map", "group_id"]); +CrossCheck("namedqueries", "id", + ["namedqueries_link_in_footer", "namedquery_id"], + ["namedquery_group_map", "namedquery_id"], + ); + CrossCheck("profiles", "userid", ['profiles_activity', 'userid'], ['profiles_activity', 'who'], @@ -441,7 +463,8 @@ CrossCheck("profiles", "userid", ["longdescs", "who", "bug_id"], ["logincookies", "userid"], ["namedqueries", "userid"], - ['series', 'creator', 'series_id', ['0']], + ["namedqueries_link_in_footer", "user_id"], + ['series', 'creator', 'series_id'], ["watch", "watcher"], ["watch", "watched"], ['whine_events', 'owner_userid'], @@ -513,6 +536,7 @@ sub DoubleCrossCheck { my $table = shift @_; my $field1 = shift @_; my $field2 = shift @_; + my $dbh = Bugzilla->dbh; Status("Checking references to $table.$field1 / $table.$field2"); @@ -521,19 +545,22 @@ sub DoubleCrossCheck { my ($refertable, $referfield1, $referfield2, $keyname) = @$ref; Status("... from $refertable.$referfield1 / $refertable.$referfield2"); - - SendSQL("SELECT DISTINCT $refertable.$referfield1, $refertable.$referfield2" . ($keyname ? ", $refertable.$keyname" : '') . " " . - "FROM $refertable LEFT JOIN $table " . - " ON $refertable.$referfield1 = $table.$field1 " . - " AND $refertable.$referfield2 = $table.$field2 " . - "WHERE $table.$field1 IS NULL " . - " AND $table.$field2 IS NULL " . - " AND $refertable.$referfield1 IS NOT NULL " . - " AND $refertable.$referfield2 IS NOT NULL"); - - while (MoreSQLData()) { - my ($value1, $value2, $key) = FetchSQLData(); - + + my $d_cross_check = $dbh->selectall_arrayref(qq{ + SELECT DISTINCT $refertable.$referfield1, + $refertable.$referfield2 } . + ($keyname ? qq{, $refertable.$keyname } : q{}) . + qq{ FROM $refertable + LEFT JOIN $table + ON $refertable.$referfield1 = $table.$field1 + AND $refertable.$referfield2 = $table.$field2 + WHERE $table.$field1 IS NULL + AND $table.$field2 IS NULL + AND $refertable.$referfield1 IS NOT NULL + AND $refertable.$referfield2 IS NOT NULL}); + + foreach my $check (@$d_cross_check) { + my ($value1, $value2, $key) = @$check; my $alert = "Bad values "$value1", "$value2" found in " . "$refertable.$referfield1 / $refertable.$referfield2"; if ($keyname) { @@ -571,9 +598,10 @@ DoubleCrossCheck("milestones", "product_id", "value", Status("Checking profile logins"); -SendSQL("SELECT userid, login_name FROM profiles"); +my $sth = $dbh->prepare(q{SELECT userid, login_name FROM profiles}); +$sth->execute; -while (my ($id,$email) = (FetchSQLData())) { +while (my ($id, $email) = $sth->fetchrow_array) { validate_email_syntax($email) || Alert "Bad profile email address, id=$id, <$email>."; } @@ -763,26 +791,72 @@ sub _check_keywords { } } +########################################################################### +# Check for flags being in incorrect products and components +########################################################################### + +Status('Checking for flags being in the wrong product/component'); + +my $invalid_flags = $dbh->selectall_arrayref( + 'SELECT DISTINCT flags.id, flags.bug_id, flags.attach_id + FROM flags + INNER JOIN bugs + ON flags.bug_id = bugs.bug_id + LEFT JOIN flaginclusions AS i + ON flags.type_id = i.type_id + AND (bugs.product_id = i.product_id OR i.product_id IS NULL) + AND (bugs.component_id = i.component_id OR i.component_id IS NULL) + WHERE i.type_id IS NULL'); + +my @invalid_flags = @$invalid_flags; + +$invalid_flags = $dbh->selectall_arrayref( + 'SELECT DISTINCT flags.id, flags.bug_id, flags.attach_id + FROM flags + INNER JOIN bugs + ON flags.bug_id = bugs.bug_id + INNER JOIN flagexclusions AS e + ON flags.type_id = e.type_id + WHERE (bugs.product_id = e.product_id OR e.product_id IS NULL) + AND (bugs.component_id = e.component_id OR e.component_id IS NULL)'); + +push(@invalid_flags, @$invalid_flags); + +if (scalar(@invalid_flags)) { + if ($cgi->param('remove_invalid_flags')) { + Status("OK, now deleting invalid flags."); + my @flag_ids = map {$_->[0]} @invalid_flags; + $dbh->bz_lock_tables('flags WRITE'); + # Silently delete these flags, with no notification to requesters/setters. + $dbh->do('DELETE FROM flags WHERE id IN (' . join(',', @flag_ids) .')'); + $dbh->bz_unlock_tables(); + Status("Invalid flags deleted."); + } + else { + foreach my $flag (@$invalid_flags) { + my ($flag_id, $bug_id, $attach_id) = @$flag; + Alert("Invalid flag $flag_id for " . + ($attach_id ? "attachment $attach_id in bug " : "bug ") . BugLink($bug_id)); + } + print qq{<a href="sanitycheck.cgi?remove_invalid_flags=1">Click + here to delete invalid flags</a><p>\n}; + } +} + ########################################################################### # General bug checks ########################################################################### sub BugCheck { my ($middlesql, $errortext, $repairparam, $repairtext) = @_; - - SendSQL("SELECT DISTINCT bugs.bug_id " . - "FROM $middlesql " . - "ORDER BY bugs.bug_id"); - - my @badbugs = (); - - while (@row = FetchSQLData()) { - my ($id) = (@row); - push (@badbugs, $id); - } + my $dbh = Bugzilla->dbh; + + my $badbugs = $dbh->selectcol_arrayref(qq{SELECT DISTINCT bugs.bug_id + FROM $middlesql + ORDER BY bugs.bug_id}); - if (@badbugs) { - Alert("$errortext: " . BugListLinks(@badbugs)); + if (scalar(@$badbugs)) { + Alert("$errortext: " . BugListLinks(@$badbugs)); if ($repairparam) { $repairtext ||= 'Repair these bugs'; print qq{<a href="sanitycheck.cgi?$repairparam=1">$repairtext</a>.}, @@ -809,7 +883,7 @@ BugCheck("bugs LEFT JOIN duplicates ON bugs.bug_id = duplicates.dupe WHERE " . Status("Checking statuses/resolutions"); -my @open_states = map(SqlQuote($_), OpenStates()); +my @open_states = map($dbh->quote($_), BUG_STATE_OPEN); my $open_states = join(', ', @open_states); BugCheck("bugs WHERE bug_status IN ($open_states) AND resolution != ''", @@ -823,8 +897,8 @@ BugCheck("bugs WHERE bug_status = 'UNCONFIRMED' AND everconfirmed = 1", "Bugs that are UNCONFIRMED but have everconfirmed set"); # The below list of resolutions is hardcoded because we don't know if future # resolutions will be confirmed, unconfirmed or maybeconfirmed. I suspect -# they will be maybeconfirmed, e.g. ASLEEP and REMIND. This hard-coding should -# disappear when we have customized statuses. +# they will be maybeconfirmed, e.g. ASLEEP and REMIND. This hardcoding should +# disappear when we have customised statuses. BugCheck("bugs WHERE bug_status IN ('NEW', 'ASSIGNED', 'REOPENED') AND everconfirmed = 0", "Bugs with confirmed status but don't have everconfirmed set"); @@ -834,24 +908,6 @@ BugCheck("bugs INNER JOIN products ON bugs.product_id = products.id " . "WHERE everconfirmed = 0 AND votestoconfirm <= votes", "Bugs that have enough votes to be confirmed but haven't been"); -########################################################################### -# Date checks -########################################################################### - -sub DateCheck { - my $table = shift @_; - my $field = shift @_; - Status("Checking dates in $table.$field"); - SendSQL("SELECT COUNT( $field ) FROM $table WHERE $field > NOW()"); - my $c = FetchOneColumn(); - if ($c) { - Alert("Found $c dates in future"); - } -} - -DateCheck("groups", "last_changed"); -DateCheck("profiles", "refreshed_when"); - ########################################################################### # Control Values ########################################################################### @@ -859,18 +915,19 @@ DateCheck("profiles", "refreshed_when"); # Checks for values that are invalid OR # not among the 9 valid combinations Status("Checking for bad values in group_control_map"); -SendSQL("SELECT COUNT(product_id) FROM group_control_map WHERE " . - "membercontrol NOT IN(" . CONTROLMAPNA . "," . CONTROLMAPSHOWN . - "," . CONTROLMAPDEFAULT . "," . CONTROLMAPMANDATORY . ")" . - " OR " . - "othercontrol NOT IN(" . CONTROLMAPNA . "," . CONTROLMAPSHOWN . - "," . CONTROLMAPDEFAULT . "," . CONTROLMAPMANDATORY . ")" . - " OR " . - "( (membercontrol != othercontrol) " . - "AND (membercontrol != " . CONTROLMAPSHOWN . ") " . - "AND ((membercontrol != " . CONTROLMAPDEFAULT . ") " . - "OR (othercontrol = " . CONTROLMAPSHOWN . ")))"); -my $c = FetchOneColumn(); +my $groups = join(", ", (CONTROLMAPNA, CONTROLMAPSHOWN, CONTROLMAPDEFAULT, +CONTROLMAPMANDATORY)); +my $query = qq{ + SELECT COUNT(product_id) + FROM group_control_map + WHERE membercontrol NOT IN( $groups ) + OR othercontrol NOT IN( $groups ) + OR ((membercontrol != othercontrol) + AND (membercontrol != } . CONTROLMAPSHOWN . q{) + AND ((membercontrol != } . CONTROLMAPDEFAULT . q{) + OR (othercontrol = } . CONTROLMAPSHOWN . q{)))}; + +my $c = $dbh->selectrow_array($query); if ($c) { Alert("Found $c bad group_control_map entries"); } @@ -909,21 +966,18 @@ BugCheck("bugs Status("Checking for unsent mail"); -my @badbugs = (); - -SendSQL("SELECT bug_id " . - "FROM bugs WHERE (lastdiffed IS NULL OR lastdiffed < delta_ts) AND " . - "delta_ts < now() - " . $dbh->sql_interval(30, 'MINUTE') . - " ORDER BY bug_id"); +my $time = $dbh->sql_interval(30, 'MINUTE'); +my $badbugs = $dbh->selectcol_arrayref(qq{ + SELECT bug_id + FROM bugs + WHERE (lastdiffed IS NULL OR lastdiffed < delta_ts) + AND delta_ts < now() - $time + ORDER BY bug_id}); -while (@row = FetchSQLData()) { - my ($id) = (@row); - push(@badbugs, $id); -} -if (@badbugs > 0) { +if (scalar(@$badbugs > 0)) { Alert("Bugs that have changes but no mail sent for at least half an hour: " . - BugListLinks(@badbugs)); + BugListLinks(@$badbugs)); print qq{<a href="sanitycheck.cgi?rescanallBugMail=1">Send these mails</a>.<p>\n}; } diff --git a/search_plugin.cgi b/search_plugin.cgi new file mode 100644 index 000000000..e3384fcce --- /dev/null +++ b/search_plugin.cgi @@ -0,0 +1,33 @@ +#!/usr/bin/perl -wT +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + +use strict; +use lib "."; + +use Bugzilla; +use Bugzilla::Error; + +Bugzilla->login(); + +my $cgi = Bugzilla->cgi; +my $template = Bugzilla->template; + +# Return the appropriate HTTP response headers. +print $cgi->header('application/xml'); + +$template->process("search/search-plugin.xml.tmpl") + || ThrowTemplateError($template->error()); diff --git a/show_activity.cgi b/show_activity.cgi index 9b7273a4c..1eff56f3f 100755 --- a/show_activity.cgi +++ b/show_activity.cgi @@ -26,8 +26,8 @@ use strict; use lib qw(.); -require "globals.pl"; - +use Bugzilla; +use Bugzilla::Error; use Bugzilla::Bug; my $cgi = Bugzilla->cgi; diff --git a/show_bug.cgi b/show_bug.cgi index 68c1edc57..bc6faa8a5 100755 --- a/show_bug.cgi +++ b/show_bug.cgi @@ -26,21 +26,16 @@ use lib qw(.); use Bugzilla; use Bugzilla::Constants; +use Bugzilla::Error; use Bugzilla::User; - -require "globals.pl"; - +use Bugzilla::Keyword; use Bugzilla::Bug; my $cgi = Bugzilla->cgi; my $template = Bugzilla->template; my $vars = {}; -if ($cgi->param('GoAheadAndLogIn')) { - Bugzilla->login(LOGIN_REQUIRED); -} else { - Bugzilla->login(); -} +my $user = Bugzilla->login(); # Editable, 'single' HTML bugs are treated slightly specially in a few places my $single = !$cgi->param('format') @@ -57,8 +52,6 @@ if (!$cgi->param('id') && $single) { my $format = $template->get_format("bug/show", scalar $cgi->param('format'), scalar $cgi->param('ctype')); -GetVersionTable(); - my @bugs = (); my %marks; @@ -67,7 +60,7 @@ if ($single) { # Its a bit silly to do the validation twice - that functionality should # probably move into Bug.pm at some point ValidateBugID($id); - push @bugs, new Bugzilla::Bug($id, Bugzilla->user->id); + push @bugs, new Bugzilla::Bug($id); if (defined $cgi->param('mark')) { foreach my $range (split ',', $cgi->param('mark')) { if ($range =~ /^(\d+)-(\d+)$/) { @@ -81,8 +74,18 @@ if ($single) { } } else { foreach my $id ($cgi->param('id')) { - my $bug = new Bugzilla::Bug($id, Bugzilla->user->id); - push @bugs, $bug; + # Be kind enough and accept URLs of the form: id=1,2,3. + my @ids = split(/,/, $id); + foreach (@ids) { + my $bug = new Bugzilla::Bug($_); + # This is basically a backwards-compatibility hack from when + # Bugzilla::Bug->new used to set 'NotPermitted' if you couldn't + # see the bug. + if (!$bug->{error} && !$user->can_see_bug($bug->bug_id)) { + $bug->{error} = 'NotPermitted'; + } + push(@bugs, $bug); + } } } @@ -94,7 +97,10 @@ eval { $vars->{'bugs'} = \@bugs; $vars->{'marks'} = \%marks; -$vars->{'use_keywords'} = 1 if (@::legal_keywords); +$vars->{'use_keywords'} = 1 if Bugzilla::Keyword::keyword_count(); + +my @bugids = map {$_->bug_id} @bugs; +$vars->{'bugids'} = join(", ", @bugids); # Next bug in list (if there is one) my @bug_list; @@ -108,7 +114,7 @@ $vars->{'bug_list'} = \@bug_list; # If no explicit list is defined, we show all fields. We then exclude any # on the exclusion list. This is so you can say e.g. "Everything except # attachments" without listing almost all the fields. -my @fieldlist = (Bugzilla::Bug::fields(), 'group', 'long_desc', +my @fieldlist = (Bugzilla::Bug->fields, 'group', 'long_desc', 'attachment', 'attachmentdata'); my %displayfields; @@ -116,7 +122,7 @@ if ($cgi->param("field")) { @fieldlist = $cgi->param("field"); } -unless (UserInGroup(Param("timetrackinggroup"))) { +unless (Bugzilla->user->in_group(Bugzilla->params->{"timetrackinggroup"})) { @fieldlist = grep($_ !~ /(^deadline|_time)$/, @fieldlist); } diff --git a/showattachment.cgi b/showattachment.cgi index 82fc1ba9a..f535d5c9d 100755 --- a/showattachment.cgi +++ b/showattachment.cgi @@ -34,7 +34,7 @@ my $id = $cgi->param('attach_id'); detaint_natural($id) if defined $id; $id ||= ""; -print $cgi->redirect(-location=>"attachment.cgi?id=$id&action=view", +print $cgi->redirect(-location=>"attachment.cgi?id=$id", -status=>'301 Permanent Redirect'); exit; diff --git a/showdependencygraph.cgi b/showdependencygraph.cgi index 22d1c49f8..77259182f 100755 --- a/showdependencygraph.cgi +++ b/showdependencygraph.cgi @@ -26,13 +26,13 @@ use strict; use lib qw(.); use File::Temp; + use Bugzilla; -use Bugzilla::Config qw(:DEFAULT $webdotdir); +use Bugzilla::Constants; use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::Bug; -require "globals.pl"; - Bugzilla->login(); my $cgi = Bugzilla->cgi; @@ -42,10 +42,7 @@ my $vars = {}; # performance. my $dbh = Bugzilla->switch_to_shadow_db(); -my %seen; -my %edgesdone; -my %bugtitles; # html title attributes for imagemap areas - +local our (%seen, %edgesdone, %bugtitles); # CreateImagemap: This sub grabs a local filename as a parameter, reads the # dot-generated image map datafile residing in that file and turns it into @@ -109,6 +106,8 @@ if (lsearch(\@valid_rankdirs, $rankdir) < 0) { $rankdir = 'LR'; } +my $webdotdir = bz_locations()->{'webdotdir'}; + if (!defined $cgi->param('id') && !defined $cgi->param('doall')) { ThrowCodeError("missing_bug_id"); } @@ -116,7 +115,7 @@ if (!defined $cgi->param('id') && !defined $cgi->param('doall')) { my ($fh, $filename) = File::Temp::tempfile("XXXXXXXXXX", SUFFIX => '.dot', DIR => $webdotdir); -my $urlbase = Param('urlbase'); +my $urlbase = Bugzilla->params->{'urlbase'}; print $fh "digraph G {"; print $fh qq{ @@ -196,7 +195,7 @@ foreach my $k (keys(%seen)) { push(@params, "shape=box"); } - if (IsOpenedState($stat)) { + if (is_open_state($stat)) { push(@params, "color=green"); } @@ -224,7 +223,7 @@ close $fh; chmod 0777, $filename; -my $webdotbase = Param('webdotbase'); +my $webdotbase = Bugzilla->params->{'webdotbase'}; if ($webdotbase =~ /^https?:/) { # Remote dot server @@ -248,6 +247,11 @@ if ($webdotbase =~ /^https?:/) { # On Windows $pngfilename will contain \ instead of / $pngfilename =~ s|\\|/|g if $^O eq 'MSWin32'; + + # Under mod_perl, pngfilename will have an absolute path, and we + # need to make that into a relative path. + my $cgi_root = bz_locations()->{cgi_path}; + $pngfilename =~ s/^\Q$cgi_root\E//; $vars->{'image_url'} = $pngfilename; diff --git a/showdependencytree.cgi b/showdependencytree.cgi index e435f1f4c..1010adcd0 100755 --- a/showdependencytree.cgi +++ b/showdependencytree.cgi @@ -22,15 +22,19 @@ # Andreas Franke <afranke@mathweb.org> # Christian Reis <kiko@async.com.br> # Myk Melez <myk@mozilla.org> +# Frédéric Buclin <LpSolit@gmail.com> use strict; use lib qw(.); -require "globals.pl"; -use Bugzilla::User; + +use Bugzilla; +use Bugzilla::Error; use Bugzilla::Bug; -Bugzilla->login(); +use List::Util qw(max); + +my $user = Bugzilla->login(); my $cgi = Bugzilla->cgi; my $template = Bugzilla->template; @@ -47,29 +51,23 @@ my $dbh = Bugzilla->switch_to_shadow_db(); # bug that the user is authorized to access. my $id = $cgi->param('id') || ThrowUserError('invalid_bug_id_or_alias'); ValidateBugID($id); +my $current_bug = new Bugzilla::Bug($id); -my $hide_resolved = $cgi->param('hide_resolved') ? 1 : 0; +local our $hide_resolved = $cgi->param('hide_resolved') ? 1 : 0; -my $maxdepth = $cgi->param('maxdepth') || 0; +local our $maxdepth = $cgi->param('maxdepth') || 0; if ($maxdepth !~ /^\d+$/) { $maxdepth = 0 }; ################################################################################ # Main Section # ################################################################################ -# The column/value to select as the target milestone for bugs, -# either the target_milestone column or the empty string value -# (for installations that don't use target milestones). Makes -# it easier to query the database for bugs because we don't -# have to embed a conditional statement into each query. -my $milestone_column = Param('usetargetmilestone') ? "target_milestone" : "''"; - -# The greatest depth to which either tree goes. -my $realdepth = 0; +# Stores the greatest depth to which either tree goes. +local our $realdepth = 0; # Generate the tree of bugs that this bug depends on and a list of IDs # appearing in the tree. -my $dependson_tree = { $id => GetBug($id) }; +my $dependson_tree = { $id => $current_bug }; my $dependson_ids = {}; GenerateTree($id, "dependson", 1, $dependson_tree, $dependson_ids); $vars->{'dependson_tree'} = $dependson_tree; @@ -77,7 +75,7 @@ $vars->{'dependson_ids'} = [keys(%$dependson_ids)]; # Generate the tree of bugs that this bug blocks and a list of IDs # appearing in the tree. -my $blocked_tree = { $id => GetBug($id) }; +my $blocked_tree = { $id => $current_bug }; my $blocked_ids = {}; GenerateTree($id, "blocked", 1, $blocked_tree, $blocked_ids); $vars->{'blocked_tree'} = $blocked_tree; @@ -88,7 +86,6 @@ $vars->{'realdepth'} = $realdepth; $vars->{'bugid'} = $id; $vars->{'maxdepth'} = $maxdepth; $vars->{'hide_resolved'} = $hide_resolved; -$vars->{'canedit'} = UserInGroup("editbugs"); print $cgi->header(); $template->process("bug/dependency-tree.html.tmpl", $vars) @@ -101,15 +98,19 @@ $template->process("bug/dependency-tree.html.tmpl", $vars) sub GenerateTree { # Generates a dependency tree for a given bug. Calls itself recursively # to generate sub-trees for the bug's dependencies. - my ($bug_id, $relationship, $depth, $bugs, $ids) = @_; - - # Query the database for bugs with the given dependency relationship. - my @dependencies = GetDependencies($bug_id, $relationship); - + + my @dependencies; + if ($relationship eq 'dependson') { + @dependencies = @{$bugs->{$bug_id}->dependson}; + } + else { + @dependencies = @{$bugs->{$bug_id}->blocked}; + } + # Don't do anything if this bug doesn't have any dependencies. return unless scalar(@dependencies); - + # Record this depth in the global $realdepth variable if it's farther # than we've gone before. $realdepth = max($realdepth, $depth); @@ -119,7 +120,7 @@ sub GenerateTree { # its sub-tree if we haven't already done so (which happens # when bugs appear in dependency trees multiple times). if (!$bugs->{$dep_id}) { - $bugs->{$dep_id} = GetBug($dep_id); + $bugs->{$dep_id} = new Bugzilla::Bug($dep_id); GenerateTree($dep_id, $relationship, $depth+1, $bugs, $ids); } @@ -127,61 +128,15 @@ sub GenerateTree { # if it exists, if we haven't exceeded the maximum depth the user # wants the tree to go, and if the dependency isn't resolved # (if we're ignoring resolved dependencies). - if ($bugs->{$dep_id}->{'exists'} + if (!$bugs->{$dep_id}->{'error'} + && Bugzilla->user->can_see_bug($dep_id) && (!$maxdepth || $depth <= $maxdepth) - && ($bugs->{$dep_id}->{'open'} || !$hide_resolved)) + && ($bugs->{$dep_id}->{'isopened'} || !$hide_resolved)) { - push (@{$bugs->{$bug_id}->{'dependencies'}}, $dep_id); + # Due to AUTOLOAD in Bug.pm, we cannot add 'dependencies' + # as a bug object attribute from here. + push(@{$bugs->{'dependencies'}->{$bug_id}}, $dep_id); $ids->{$dep_id} = 1; } } } - -sub GetBug { - # Retrieves the necessary information about a bug, stores it in the bug cache, - # and returns it to the calling code. - my ($id) = @_; - my $dbh = Bugzilla->dbh; - - my $bug = {}; - if (Bugzilla->user->can_see_bug($id)) { - ($bug->{'exists'}, - $bug->{'status'}, - $bug->{'summary'}, - $bug->{'milestone'}, - $bug->{'assignee_id'}, - $bug->{'assignee_email'}) = $dbh->selectrow_array( - "SELECT 1, - bug_status, - short_desc, - $milestone_column, - assignee.userid, - assignee.login_name - FROM bugs - INNER JOIN profiles AS assignee - ON bugs.assigned_to = assignee.userid - WHERE bugs.bug_id = ?", undef, $id); - } - - $bug->{'open'} = $bug->{'exists'} && IsOpenedState($bug->{'status'}); - $bug->{'dependencies'} = []; - - return $bug; -} - -sub GetDependencies { - # Returns a list of dependencies for a given bug. - my ($id, $relationship) = @_; - my $dbh = Bugzilla->dbh; - - my $bug_type = ($relationship eq "blocked") ? "dependson" : "blocked"; - - my $dependencies = $dbh->selectcol_arrayref( - "SELECT $relationship - FROM dependencies - WHERE $bug_type = ? - ORDER BY $relationship", undef, $id); - - return @$dependencies; -} - diff --git a/sidebar.cgi b/sidebar.cgi index 2f7743ebb..5619d6b40 100755 --- a/sidebar.cgi +++ b/sidebar.cgi @@ -18,10 +18,11 @@ use strict; use lib "."; -require "globals.pl"; -Bugzilla->login(); +use Bugzilla; +use Bugzilla::Error; +Bugzilla->login(); my $cgi = Bugzilla->cgi; my $template = Bugzilla->template; diff --git a/skins/.cvsignore b/skins/.cvsignore new file mode 100644 index 000000000..b98d8c957 --- /dev/null +++ b/skins/.cvsignore @@ -0,0 +1,2 @@ +custom +contrib diff --git a/skins/CVS/Entries b/skins/CVS/Entries index cb47128bc..3eb4430da 100644 --- a/skins/CVS/Entries +++ b/skins/CVS/Entries @@ -1 +1,2 @@ +/.cvsignore/1.1/Fri Sep 8 22:03:35 2006//TBUGZILLA-3_0 D/standard//// diff --git a/skins/CVS/Tag b/skins/CVS/Tag index a828702f4..efdc1ff3e 100644 --- a/skins/CVS/Tag +++ b/skins/CVS/Tag @@ -1 +1 @@ -TBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/skins/standard/CVS/Entries b/skins/standard/CVS/Entries index 455b5415d..db5791fec 100644 --- a/skins/standard/CVS/Entries +++ b/skins/standard/CVS/Entries @@ -1,13 +1,18 @@ -/admin.css/1.3/Wed Oct 26 17:14:31 2005//TBUGZILLA-2_22_3 -/buglist.css/1.9/Mon Apr 11 22:52:50 2005//TBUGZILLA-2_22_3 -/duplicates.css/1.2/Fri Nov 15 22:04:04 2002//TBUGZILLA-2_22_3 -/editusers.css/1.1.6.1/Sat Oct 14 20:30:54 2006//TBUGZILLA-2_22_3 -/global.css/1.16.2.3/Sat Oct 14 22:05:55 2006//TBUGZILLA-2_22_3 -/index.css/1.3/Sat Dec 3 03:17:38 2005//TBUGZILLA-2_22_3 -/panel.css/1.1/Wed Dec 12 22:41:11 2001//TBUGZILLA-2_22_3 -/params.css/1.2/Thu Oct 13 09:18:22 2005//TBUGZILLA-2_22_3 -/show_multiple.css/1.2/Tue Nov 2 22:39:16 2004//TBUGZILLA-2_22_3 -/summarize-time.css/1.1/Mon Feb 28 17:52:57 2005//TBUGZILLA-2_22_3 -/voting.css/1.1/Tue Feb 8 15:49:57 2005//TBUGZILLA-2_22_3 +/IE-fixes.css/1.1/Tue Oct 17 19:58:34 2006//TBUGZILLA-3_0 +/admin.css/1.3/Wed Oct 26 17:14:31 2005//TBUGZILLA-3_0 +/buglist.css/1.11/Wed Nov 15 10:44:15 2006//TBUGZILLA-3_0 +/create_attachment.css/1.1/Sat Jun 17 23:24:35 2006//TBUGZILLA-3_0 +/dependency-tree.css/1.3/Sat Jan 6 19:48:10 2007//TBUGZILLA-3_0 +/duplicates.css/1.2/Fri Nov 15 22:04:04 2002//TBUGZILLA-3_0 +/editusers.css/1.2/Sat Oct 14 20:26:50 2006//TBUGZILLA-3_0 +/global.css/1.31.2.1/Wed Apr 4 21:23:02 2007//TBUGZILLA-3_0 +/index.css/1.6.2.2/Sun Mar 25 02:11:15 2007//TBUGZILLA-3_0 +/panel.css/1.1/Wed Dec 12 22:41:11 2001//TBUGZILLA-3_0 +/params.css/1.2.4.1/Sun Mar 25 02:11:15 2007//TBUGZILLA-3_0 +/release-notes.css/1.1/Thu Feb 22 18:41:29 2007//TBUGZILLA-3_0 +/show_multiple.css/1.4/Sun Jun 18 23:11:59 2006//TBUGZILLA-3_0 +/summarize-time.css/1.1/Mon Feb 28 17:52:57 2005//TBUGZILLA-3_0 +/voting.css/1.1/Tue Feb 8 15:49:57 2005//TBUGZILLA-3_0 +D/dependency-tree//// D/global//// D/index//// diff --git a/skins/standard/CVS/Tag b/skins/standard/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/skins/standard/CVS/Tag +++ b/skins/standard/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/skins/standard/IE-fixes.css b/skins/standard/IE-fixes.css new file mode 100755 index 000000000..b0f34141d --- /dev/null +++ b/skins/standard/IE-fixes.css @@ -0,0 +1,33 @@ +/* The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Bugzilla Bug Tracking System. + * + * Contributor(s): Marc Schumann <wurblzap@gmail.com> + */ + +#footer #useful-links li { + padding-bottom: 0.8ex; +} + +#footer .label { + display: block; + float: left; + width: 8.2em; + padding-bottom: 0.1ex; +} + +#footer #links-actions .label { + padding-top: 0.35em; +} + +#footer .links { + display: inline; +} diff --git a/skins/standard/buglist.css b/skins/standard/buglist.css index 45e4937d9..dc3db0e10 100644 --- a/skins/standard/buglist.css +++ b/skins/standard/buglist.css @@ -21,10 +21,20 @@ .bz_id_column { } +.bz_row_odd { + background-color: #F7F7F7; + color: #000000; +} + +.bz_row_even { + background-color: #FFFFFF; + color: #000000; +} + /* Style bug rows according to severity. */ .bz_blocker { color: red; font-weight: bold; } .bz_critical { color: red; } -.bz_enhancement { color: #888; background-color: white; } +.bz_enhancement { color: #666; background-color: white; } /* Align columns in the "change multiple bugs" form to the right. */ table#form tr th { text-align: right; } diff --git a/skins/standard/create_attachment.css b/skins/standard/create_attachment.css new file mode 100644 index 000000000..dcb19836d --- /dev/null +++ b/skins/standard/create_attachment.css @@ -0,0 +1,36 @@ + /* The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Bugzilla Bug Tracking System. + * + * Contributor(s): Myk Melez <myk@mozilla.org> + * Joel Peshkin <bugreport@peshkin.net> + * Erik Stambaugh <erik@dasbistro.com> + * Marc Schumann <wurblzap@gmail.com> + */ + +table.attachment_entry th { + text-align: right; + vertical-align: baseline; + white-space: nowrap; +} + +table.attachment_entry td { + text-align: left; + vertical-align: baseline; + padding-bottom: 5px; +} + +table#flags th, +table#flags td { + text-align: left; + vertical-align: baseline; + font-size: small; +} diff --git a/skins/standard/dependency-tree.css b/skins/standard/dependency-tree.css new file mode 100644 index 000000000..cab167171 --- /dev/null +++ b/skins/standard/dependency-tree.css @@ -0,0 +1,94 @@ +/* The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Bugzilla Bug Tracking System. + * + * The Initial Developer of the Original Code is Netscape + * Communications + * Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): Christian Reis <kiko@async.com.br> + * Andr� Batosti <batosti@async.com.br> + */ + +ul.tree { + padding-left: 0em; + margin-left: 1em; + display: block; +} + +ul.tree ul { + padding-top: 3px; + display: block; +} + +ul.tree li { + /* see http://www.kryogenix.org/code/browser/aqlists/ for idea */ + padding-top: 3px; + text-indent: -1.2em; + padding-left: 0.5em; + padding-bottom: 3px; + list-style-type: none; + background: url("dependency-tree/bug-item.png") no-repeat; +} + +ul.tree li a.b { + padding-left: 30px; + margin-right: -14px; + text-decoration: none; +} + +ul.tree li a.b_open { + background: url("dependency-tree/tree-open.png") center no-repeat; + cursor: pointer; +} + +ul.tree li a.b_closed { + background: url("dependency-tree/tree-closed.png") center no-repeat; + cursor: pointer; +} + +ul.tree a.tree_link img { + border: 0; +} + +.summ_info { + /* change to inline if you would like to see the full bug details + * displayed in the list */ + display: none; + font-size: 75%; +} + +.hint { + font-size: 90%; + margin: 0.2em; + padding: 0.1em; +} + +.hint h3, .hint ul { + margin-top: 0.1em; + margin-bottom: 0.1em; +} + +.summ A, .summ_deep A { + text-decoration: none; + color: darkblue; +} + +.summ_deep { +} + +.summ_h A { + background-color: #ffffaa; + color: #333; + font-weight: bold; +} diff --git a/skins/standard/dependency-tree/CVS/Entries b/skins/standard/dependency-tree/CVS/Entries new file mode 100644 index 000000000..d28db0859 --- /dev/null +++ b/skins/standard/dependency-tree/CVS/Entries @@ -0,0 +1,5 @@ +/bug-item.png/1.1/Fri Feb 24 01:31:13 2006/-kb/TBUGZILLA-3_0 +/tree-closed.png/1.1/Fri Feb 24 01:31:13 2006/-kb/TBUGZILLA-3_0 +/tree-open.png/1.1/Fri Feb 24 01:31:13 2006/-kb/TBUGZILLA-3_0 +/tree.png/1.1/Tue May 23 00:31:35 2006/-kb/TBUGZILLA-3_0 +D diff --git a/skins/standard/dependency-tree/CVS/Repository b/skins/standard/dependency-tree/CVS/Repository new file mode 100644 index 000000000..0dfc16f1f --- /dev/null +++ b/skins/standard/dependency-tree/CVS/Repository @@ -0,0 +1 @@ +mozilla/webtools/bugzilla/skins/standard/dependency-tree diff --git a/skins/standard/dependency-tree/CVS/Root b/skins/standard/dependency-tree/CVS/Root new file mode 100644 index 000000000..cdb6f4a07 --- /dev/null +++ b/skins/standard/dependency-tree/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot diff --git a/skins/standard/dependency-tree/CVS/Tag b/skins/standard/dependency-tree/CVS/Tag new file mode 100644 index 000000000..efdc1ff3e --- /dev/null +++ b/skins/standard/dependency-tree/CVS/Tag @@ -0,0 +1 @@ +NBUGZILLA-3_0 diff --git a/skins/standard/dependency-tree/bug-item.png b/skins/standard/dependency-tree/bug-item.png new file mode 100644 index 0000000000000000000000000000000000000000..051025d7471ff615fd3678fb4d0d9cd628a4a65a GIT binary patch literal 1279 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rag4mJh`h9g^YtQi;>*pj^6T^Rm@;DWu&Co?cG za29w(7Bet#3xP1>rMq>17#JAXOFVsD*{^a7h*)xLn&&@_fq|vR)5S5w;`G!I?|kV{ z3ER&b=59Q$*=f7X@6w((S1KJ=JH@tkDDjxI=Ivr&-MCQKW2%6VwAlv7r0ekvulm|p zJvh8rLlxErtp3EI*wLZUZ+0};x=_wo&i<J3ypLaPZm6uNocb+iUCH~u=WKtyvy^XU zU$A@k?c)YKz8r<J#}6)UxcB<Op;m4?M}a<erbfNfn=)*azUg=@zij(;*VX)4YWDX3 zQ;(FMFJt(SyWiZ#rsv_qhq7Pa#2pb9-tWHYW>2)%)LF;({d~1m`<wmTI{V*W%ftOr zTc%Ba;>`ShZBI{+#m9<0jf*t0Yijm<3pgSxyYcVOJ(sTEyIgXi?2mHmpMZ=PAsUs% zS-Dd`)_r7e=+-&CYLSLp@y<J34PV=p=Ed)bwXc5Hd!$%j&gz59p5+&pHmsg}efP2T zeWhp5`EW9*EnB|a^{_#dYoHGE0)`#@D*t{gF1PiUuU0L26On)C`hhLCOqr*<**pKA z$T82d=tgO0yQlyEYmot`CQ7Z0VtB`pzz|_=w|?*5xqWW8oqkKru4<oW`}fetkWVJB zmnxf_O^#o|I^FI+<KDfs0xW$}UdNo;C(m6!&8u}f?_myx4e!H$&wmuXJ@4X7pKZ@? zZOwk}=I-9Q#p1GI!46%|=5H*_HuvgY+oYwxSGXh6x=L_++~yzeDxMs;vVQw?Mjgfp zj5&r@r#I;YtqkdSykqjggo3Ys`Qy{sf^*fok4`;Mr`Y!XxZdOA9}AEC`u$)RYsM_U zOt-m@EbSR5+*L3u)7YldEhQt9^TcAEt7hkZ`}#%tdY;~i`~97>y#>VWe~P%X^&blG z?U=cH#VR(F&2BUMoEbzIXWaH=Y><<XSfJv$NK8!Z+V00|buR~ZtN;6#J#Xy`qjUQ| zGd>f0rzj+Lz<@37**gc#&<WE`w<~0(EZ+X+*zsIO<<mwyhZP*{o^Wz6G><&zJ874% zrk9|3{j7t*?){4bt{mJTS|PnBB1-R20IzzvzuKlXVNy~x-P2OnGALLp-MxA7>Bov0 zWr1g0K2Lges*?A9+&q_^4;JjSY}vG^>0@w2%#?r$+AF4<jmoo(=VAG=t-xZ=jSmJ} zmmcqQX-cxqxl(x7Zq~a0k!!E~5?Sf9URV6${0gC2tCS|6YskOXUV4<lF!uVU#1ln^ zXA5IOLu2I__#JKw3Cut5F6bm@%yZYfx@NoS+*9k<XIxyBcJO?$#%d{_qyrb215S%& zoO*p~(jsFX<w~1*i*j!-y<6q8JV;YZu7CH=n7p9%A?m$eZ^fP7n696GwKUe*Y%`CP z*eX>izQowQIj>fq4w|~`rD<DY-i&3HvJG4A9zQeFIQ_zn8!vo(eD18B657e+B^s(7 zUb;9+xg{!ovZ-UnH@3fwy8=R{ad{Q;i7cJD%rbM<Gv4EcVGLKcYcJcjmZw3DA(nwH zVw&fTZI`bVZ?FzCK07H$L+@Svp4PKzo6QuTur(MmT)q43>@$H|IlEXFY)Jf7dV14y zhAnH?d7YiLEHpXRaNhHuj!q}eGaUKdelD)7{B}A+1!KW%#Sg##diFim>RNP$NrQRC r+iAPnk1li1WH{LCzT&_3FLCp!+Tx#{_L?&=Ffe$!`njxgN@xNA*$_|e literal 0 HcmV?d00001 diff --git a/skins/standard/dependency-tree/tree-closed.png b/skins/standard/dependency-tree/tree-closed.png new file mode 100644 index 0000000000000000000000000000000000000000..80f1e2b4d510a1ae6623287e82010920537ceeb9 GIT binary patch literal 1129 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rag4mJh`h9g^YtQi;>*pj^6T^Rm@;DWu&Co?cG za29w(7Bet#3xP1>rMq>17#JAXOFVsD*{^a7^01rD*nH<L0|WCnPZ!4!i_=r5y!Vd| zl{q%Q`2E}W(-@adWm<eeUVEvPlT1g8<nB!K=`;3TNT}JK`AB-P{+FrwJ~hYV7exB> zI4@Rnd%lP}s3Q4<nzK)bcdEd(+0hv<y)<)ozTLTZ@80X?2^t(_=VupBDn9qzM*aEE zy2v>S{l}9NBBxDEjSLPI^;defqqVb>v-$8ti~NldRidtmA6l%wIoQa34`1!IU&Zs< z)2Hv}%qly}d!V2qUPZ`JMaZ&fo;9D1ef|BJ9vo42^YiEa`uO{L{&l&pGtS=Ox4*wn z$-*k`mX&msy{Vnux?eSR%8D+XZi}b39mw0h-FEg}zOvuZ=dOf&uF$j2lHZ#o|0~yU z@5xvD|1uxo?R(s1bAI=vlPO#W9=9Dh%^$w%`nvs+6%QZXyzKw`kFONtJDoG%+}`_q zJtn7P#c)PnSNG$TOMdg7b2D%-ymk4YF28?ub=eQm-yaI*pHE1!&KB*OJvn|+{e{lw z?Cd7K*EW7!dcV5pHfy@8o;E`m;|7K)%JZ+^y?b^?OzgK{U)|cp$>I8Q`1xa>e(9N< zxW*#&{eiRV>s;gG1^C)Kd-y8fGCSL@fBJdn=_x_n4YwS(|F@bqdv-F5;=}nfXYRDK zw0zm|ng7nh#&wEpJ?GLkK6<<To}<pTu5DuCU5nO)YIj|ITs$vs&-P7>39<*o8g?xx zmN~8{!*|<P?Xv3Zv)g_?bkE<Q{BWJOwY8@A?!(>j%kmPfq*}MzbNHTi6!CUh5}IT> zGnJv!*1+~rM4*U~k<q0TqnTFQKL7bE9?$p7Xy#Y5&5kbV?Y!o8e|egfpF4C5RV4C0 zRch4;?O3wPs6m$DQlbXKgaC~r0baIKE``sR{(Rzjo9+9VJyr29B<=V8sFC_ye!W1k zNKpEaR@(CS8+k=!85#7%x-;Dt8@|nW{l|M6k9<xVS6uf^hFube5ASE~>El(Ne9|$0 z4I_h!tJSoOCp}+P?>>Ha^<_zp`FZYjIm=e$rn>$q$!2Vw({(M(n(MafhO{E37ar?5 zSeRNa7wY*PXOVRKyLnIa%C*NYd*r`S5cuGvBc^zS^+f8*h0iwsS2~tpAmF;vEI8`Y z^{h8t5lT0&v~_G+aUjQZVStF@Ns%o}u2|kJuP%stZXv@bJpcT1)yXGYFXdG>z6*PI zsz`V3_2Q*Lo-R%|7?@d~+5|t(x_|RvW$YcM#)eyW?#!7ncW&(zKie=#r+u1JGo2Pq zeQ-<az5bK(ul|;A`Iwhqe?K+XS*hJk%z?WhjzO_6nR)B1TTksDe+*O6)aN*P`u}t; z&xsuqjhp@)x8gp)vq03rx<M~`^4d_5qnnmx#hZVqJl^y@{s7YjW`nn1MZ_FdO$?bM oa`^D{3471n_Ive^{VRV|{FW}E2_JeG7#J8lUHx3vIVCg!0MKCtLjV8( literal 0 HcmV?d00001 diff --git a/skins/standard/dependency-tree/tree-open.png b/skins/standard/dependency-tree/tree-open.png new file mode 100644 index 0000000000000000000000000000000000000000..eeb3e6bc1f969e2b5318ee567401d2ced1db8215 GIT binary patch literal 1130 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rag4mJh`h9g^YtQi;>*pj^6T^Rm@;DWu&Co?cG za29w(7Bet#3xP1>rMq>17#JAXOFVsD*{^a7^00Glzq25Vfr0tEr;B5V#p$V2?)pck z${gSSe5tMNa$ROGZPsJn@nK%2EjyHi(%vk)8<SMF@L<LE%tyT!x%YlLcEtK0)7hjX z87WgkEAiL~PCh(0Q#v>cSMnUHD&lGlipn^hIsfwEmzMW7q#j6kI@_jFZ{G8tPkvX| z>GSkWIR5ydMBBp9P}7pw<ApBrWd=q@hb-rw+Z?uftM_FSspD4`@(Xpg)Tg_@4iq_R zX8*tWw86R(h6ms7ce^d_a9hlNZ*zO&^5yS$P4YZ>;`!&^Wc&X=o}GQw?B|$J|Lf~B z)sr_rojUgNLi_5&hY#;M|9o?R$kL-p8@+rV^zr2vo6Y9l_FLL7v^258*!qRUo+ljt zEoa9ipSk~^_kq;uO|F3=cUOjFi5{r(eem-)w{`fseX<oV|Gb=h{@0&UHr6|{X1?jV zEA_hT{_Ikw8S`e(7Uoo3yGTQfA%LMr`QZH8U;AGE{C8dE@87$2=MHTN(`LEuzTeG% zKDYk2uTpJUNkYZ-rFqY|)^$Z)W6)trV8~#fbp75vzuk9p`-Dq*?>0M6KR>s(MSpYJ zE!WFta|*UR_+`F-@osC5<&&4Q9gcI)-|@M(rtY(n;t{R|zjoYq?_0iXS%#<AFLgDw zb$xw(R>F_=_66ie&tS{l6rEe~eeQRGe*Hx&5B4rvBV{dm_Swgse&_B*Mlf#RNnk!O z&nZ1}nyZRX;Rl=ggL&K6*Zw&fea2zQ+e6o`t=f9?<<b0Pa|5~VgSUlS5_6oUc~9{v z(~#C*!7yoeLeYVZ%QCMVIN%_A{<H4RJr&=dhBxo?N!#i9AZ5$88-;H_>t8T0U|X`n zVal`sJ)sj`twANRtQ%MzZt}A-Xo+xLY!TpBeDYPi&F0n2y7TONj=tfxeSSPVzAyRL zH=%Q`=aXHdjy(AxyR2>5Vups^<B!{pCV5)Vj`|-e`fl-7pM%+=787n-y!)@7Sg=BV z<{7m!)3g{IE>3ao6uY)*`%-J`T|R2Um-V_PS<lv#l8%(ze`khcVz7JiV&>Ku!5#<M z{4f?K#xB#1dDmRnGo$`5-xIr1PyLd|`W!`p4^DbwimECrQkSYdINTA@_gEt|^fjmE z%uM0!3e#7-`L*he-f1Zo>3*lcwnah{CVlNxe9vxIB-81lG5>t}lAx6{FO^lc<%H+0 z&N9t4+q^W$(=8~9k(c+W&0h9R^|CYa8XX+guV3%)=jUhVv3}ia6W7{st;tKAv<@y+ zy%>KYfA;)B%Q-UHX79J<`Y!tRmZyP@A(p{O=QPWz(7k8tPd#3%;T1P2NPK>nXxFj; zv1?80OJ^}EFl4Y?;8}1sE<Jxr>du@O$F`fQybt(rm_vdgjp5HbpF|c%j?Xsx=bnE0 rZ^hPm^S{Mj$vb<yf7ZkP*Y&?=?e;zCld^<?fq}u()z4*}Q$iB}vl<c4 literal 0 HcmV?d00001 diff --git a/skins/standard/dependency-tree/tree.png b/skins/standard/dependency-tree/tree.png new file mode 100644 index 0000000000000000000000000000000000000000..884d3473236ccaba64ce78a7f4790ba30166a528 GIT binary patch literal 961 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7*pj^6T^Rm@;DWu&Co?cG za29w(7Bes~3o|e<`7>&*`n`gIfq}im)7O>#8Vj4Ku<6&A9!nS)7-UOaBTAg}b8}Pk zN*J7rQWHy3QxwWGOEMHfGEx=XJ$(b-r>N#JFfglnx;TbdoGv{Vogot{bNu6d%XB?! z>&@qK^bNI_ncawL-l`HJbaB;Eg$nmAU6ZoDtnKPZa9ERZwY}-bwDyR25m)VwuLr|2 zMUOOvX?~lus8{V^RPyDRvh;Ly>)poB=U5(}?xwwD|MU0%56@><z)--#zP9V8>o?Z* z7uT=*f3`QgbVu$@HMxyfZ}QIF)jzB1`pM9Xy^r@6T|cnnN5*&NGxpOnH?ibYeGxW) zV|7LR!~XZD7kx1k{bBAN$a2^qK$vrnlj6dsm$qAly1y>ZlV96Yr*Uce{VPwr?<BvK zduJ3-(DwS_mDhJNCMlUtC~B>WU|%W{Iq^W5cg9i9u2UE0y?(DLer^BfQ@<yhZrl80 z$JYJN?`)p((Ol|mrn0xOO4FiQ`c9(01xk(DIUmf}joA47M6PZ(U;ey$^3<(|-<;Tc zhBNo85YJA<%p(FVN@s&P<~2o%IcRQKprEiot@Y)M37&mUvE}ZPe;e#R{}p@Z^=tJB z;U!BL{CFZ7nGM)<SweR6PGXpqU2xY)>}q1W<qsd7#g}#c+E?>G)4tg?am}qCcU#)R zEK}wkF7jbHs?_8pcw}P1iniSj59XR4c&3>$tN!B!U1nnzargK4tAYhgzd3z6o3^y) zs8Dl=P+Qmnr-oLMXLFkJr-d4K@u^>_&9nZ!^Vqb8=jvr9o_GIU`Rv;MXY;u)C7ZTy zaCl!3CHABBhjjMA-C?FbT9+Ix&zV#EXl?1|<wonhKI#Wl7M_W@ZLXLf`?zLrfHv=m zh_blNzfR4YdD5QmOL^G2<C`}{7e0SD_qTeTRkG}r<JzfZMUShR^%y^$bTitom&LcQ zN-ImTdexPMIvZT4ocR=6fA-?R1AD77g8gf9zI~p>)4k`e*2##vZ+RW3&q&C;ir$@j zJ8W;&QQo&_ZJqn?^ak$!z3Shg6V(R)#N*gb_;T+Q5Zd=#-bm`rfz1EOwRO*C$lPSE z&GeYQyRKS3<5Jdbw#^|j?teCl@4LJ=x^BTd@e3<g`jus#p2nObeeTJOdRf({%O{8J zdp5nW_|1#{V&OT<r82S}?AM>hx+?uwr-R*;BX1u&tq@)|mo+iMnz13qCd~V-y<SDF V|GX;azYGiv44$rjF6*2UngH{@!W94j literal 0 HcmV?d00001 diff --git a/skins/standard/global.css b/skins/standard/global.css index bc60d6f05..fe5fd8b0b 100644 --- a/skins/standard/global.css +++ b/skins/standard/global.css @@ -19,255 +19,177 @@ * Christian Reis <kiko@async.com.br> * Vitaly Harisov <vitaly@rathedg.com> * Svetlana Harisova <light@rathedg.com> + * Marc Schumann <wurblzap@gmail.com> */ -body -{ - color: #000; - background-color: #fff; -} - -/* banner (begin) */ - #banner - { - text-align: center; - - width: 100%; - background: #fff; +/* global (begin) */ + body { + font-family: sans-serif; + color: #000; + background: #fff url("global/body-back.gif") repeat-x; } +/* global (end) */ - #banner p - { - margin: 0; - margin-bottom: 1px; - padding: 0; +/* header (begin) */ + #header { + margin-bottom: 1em; + padding-bottom: 2px; } - #banner-name - { - font-size: 0px; - height: 48px; - background: transparent no-repeat url(global/header.png); + #header form { + font-size: 85%; + display: inline; } - #banner-version - { - font-family: sans-serif; - font-size: 75%; - background: #fff; + #header .btn, + #header .txt { + font-size: 80%; } - /* hide from NN4 */ - p#banner-version - { + #header .links { font-size: 85%; - } -/* banner (end) */ - -/* header (begin) */ - #header - { - width: 100%; + border-left: 1px solid silver; + border-right: 1px solid silver; + border-bottom: 1px solid silver; + -moz-border-radius-bottomleft: 5px; + -moz-border-radius-bottomright: 5px; + padding: 0.5em; } - #header * - { - margin: 0; - padding: 0; + #message { + border: 1px solid red; + margin: 0.3em 0em; + padding: 0.3em; + color: green; } - /* hide from MSIE and NN4 */ - [id]#header - { - display: table; - } +/* header (end) */ - /* IE hack for float content*/ - * html #header - { - height: 1%; +/* banner (begin) */ + #banner { } - /* hide from NN4 */ - div#header h1 - { - float: left; - } +/* banner (end) */ - #header h1 - { - font-family: serif; - font-weight: bold; +/* titles (begin) */ + #titles { + width: 100%; + background-color: #404D6C; + color: #fff; + -moz-border-radius-topleft: 5px; + -moz-border-radius-topright: 5px; font-size: 110%; - padding: 0.2em 1em 0.1em 0.2em; - } - - /* hide from MSIE and NN4 */ - [id]#header h1 - { - float: none; - display: table-cell; - - vertical-align: top; + margin: 0; + padding: 0.5em; + vertical-align: bottom; } - /* hide from NN4 */ - div#header h2 - { - float: left; - width: 70%; - - text-align: center; - padding: 0.2em 1em 0.1em 0.1em; + #titles a { + color: #fff; } - #header h2 - { - font-family: serif; - font-weight: normal; - font-size: 100%; + #titles p { + margin: 0; + padding: 0; } - /* hide from MSIE and NN4 */ - [id]#header h2 - { - float: none; - width: auto; - - text-align: left; - vertical-align: top; + #titles #title { + font-weight: bold; + white-space: nowrap; } - #header h3 - { - font-family: serif; + #titles #subtitle { font-weight: normal; - font-size: 100%; - - padding: 0.2em 0.2em 0.1em 0.1em; - float: right; + width: 100%; + text-align: center; } - /* hide from MSIE and NN4 */ - [id]#header h3 - { - display: table-cell; - float: none; - + #titles #information { + font-weight: normal; text-align: right; - vertical-align: top; + font-size: 90%; + white-space: nowrap; } - #message - { - border: 1px solid red; - - padding: 0.3em; - color: green; - } -/* header (end) */ +/* titles (end) */ /* footer (begin) */ - #footer - { - float: left; + #footer { margin-top: 5px; width: 100%; - font-family: sans-serif; background: #edf2f2; border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; } - #footer form - { + #footer form { display: inline; } - #footer span - { - display: block; - } - - #footer .btn, #footer .txt - { - font-size: 0.8em; - } - - #footer #useful-links - { - padding: 0.3em; + #footer .btn, + #footer .txt { + font-size: 80%; } - /* hide from MSIE and NN4 */ - [id]#footer #useful-links - { - margin: 0.3em; + #footer #useful-links { display: table; + padding-left: 1ex; + padding-right: 1ex; } #footer #links-actions, #footer #links-edit, #footer #links-saved, - #footer #links-special - { + #footer #links-special { display: table-row; + list-style-type: none; } - #footer .label - { - width: 8.2em; - display: block; - float: left; - - vertical-align: baseline; - - padding: 0.1em 0.2em; - } - - #footer #links-actions .label - { - padding-top: 0.45em; + #footer .label { + display: table-cell; + white-space: nowrap; + vertical-align: top; } - /* hide from MSIE and NN4 */ - [id]#footer .label - { + #footer .links { display: table-cell; - float: none; - width: auto; - - padding-top: 0; + vertical-align: top; } +/* footer (end) */ - #footer .links - { - display: table-cell; +/* link lists (begin) */ + ul.links { + margin: 0; + padding: 0; + list-style-type: none; + } - padding: 0.1em 0.2em; + ul.links li { + display: inline; + white-space: nowrap; } +/* link lists (end) */ - /* hide from MSIE and NN4 */ - [id]#footer .links - { - padding-top: 0; +/* tabs (begin) */ + .tabs td { + background: #eee; + text-align: center; + border-style: solid; + border-color: black; + border-width: 0px 0px 2px 0px; + } - vertical-align: baseline; + .tabs td.selected { + background: white; + border-width: 2px 2px 0px 2px; } - /* hide from MSIE and NN4 */ - #footer+* - { - clear: both; + .tabs td.spacer { + background: white; } -/* footer (end) */ +/* tabs (end) */ /* generic (begin) */ - body - { - background: #fff url("global/body-back.gif") repeat-x; - } - :link { color: #039; } @@ -283,59 +205,64 @@ body :link:active, :link:active { color: #000; } + + .clickable_area { + cursor: pointer; + } /* generic (end) */ -.bz_obsolete { text-decoration: line-through; } -.bz_inactive { text-decoration: line-through; } +div#docslinks { + float: right; + border: 1px solid black; + padding: 1ex; + font-size: 80%; +} + +#docslinks h2 { + margin: 0; +} + +.bz_obsolete { + text-decoration: line-through; +} +.bz_inactive { + text-decoration: line-through; +} .bz_closed, .bz_CLOSED td { text-decoration: line-through; } -.bz_private { color: darkred ; background : #f3eeee ; } -.bz_disabled { color: #a0a0a0 ; } - -.bz_row_odd -{ - background-color: #F7F7F7; - color: #000000; +.bz_private { + color: darkred; + background: #f3eeee; +} +.bz_disabled { + color: #a0a0a0; } -.bz_row_even -{ - background-color: #FFFFFF; - color: #000000; +.bz_comment { + margin-bottom: 2em; } -.bz_comment { background-color: #e0e0e0; } -.bz_comment_hilite pre -{ +.bz_comment_head { + background-color: #e0e0e0; +} +.bz_comment_hilite pre { background-color: lightgreen; margin: 0; padding: 1em 0; } -td.tab -{ - background: #eee; - text-align: center; - border-style: solid; - border-color: black; - border-width: 0px 0px 2px 0px; -} - -td.tab.selected -{ - background: white; - border-width: 2px 2px 0px 2px; +span.quote { + color: #65379c; } -td.tab.spacer -{ - background: white; +table#flags th, +table#flags td { + vertical-align: baseline; + text-align: left; } -table#flags th, table#flags td { vertical-align: baseline; text-align: left; } - .throw_error { background-color: #ff0000; color: black; @@ -343,3 +270,75 @@ table#flags th, table#flags td { vertical-align: baseline; text-align: left; } margin: 1em; padding: 0.5em 1em; } + +dt { + font-weight: bolder; +} +body > dl > dt { + border-top: dotted gray thin; +} +dl dl > dt { + border-top: none; +} + +/* Style of the attachment table */ +#attachment_table { + border-collapse: collapse; + width: 40em; + border: 1px solid #333333; +} + +#attachment_table th, .bz_attach_footer { + background-color: #E0E0E0; + color: black; +} + +#attachment_table td { + border: 1px solid #333333; +} + +.bz_attach_extra_info { + font-size: smaller; +} + +.bz_attach_flags, .bz_attach_footer { + white-space: nowrap; +} + +.bz_attach_view_hide { + float: right; + padding-left: 1em; +} + +div.user_match { + margin-bottom: 1em; +} + +.box { + border: 1px solid black; + color: black; + background-color: #ffc; + margin: 1em; + padding: 0.5em 1em; +} + +/* Rules specific for printing */ +@media print { + #header, #footer { + display: none; + } + + body { + background-image: none; + background-color: #fff; + } +} + +.field_label { + text-align: right; + vertical-align: top; + font-weight: bold; +} +.field_value { + vertical-align: top; +} diff --git a/skins/standard/global/CVS/Entries b/skins/standard/global/CVS/Entries index 11d4993f9..671a12075 100644 --- a/skins/standard/global/CVS/Entries +++ b/skins/standard/global/CVS/Entries @@ -1,3 +1,3 @@ -/body-back.gif/1.1/Fri Mar 11 03:07:18 2005/-kb/TBUGZILLA-2_22_3 -/header.png/1.1/Thu Feb 3 19:23:17 2005/-kb/TBUGZILLA-2_22_3 +/body-back.gif/1.1/Fri Mar 11 03:07:18 2005/-kb/TBUGZILLA-3_0 +/header.png/1.1/Thu Feb 3 19:23:17 2005/-kb/TBUGZILLA-3_0 D diff --git a/skins/standard/global/CVS/Tag b/skins/standard/global/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/skins/standard/global/CVS/Tag +++ b/skins/standard/global/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/skins/standard/index.css b/skins/standard/index.css index fe801e1d3..2b021f349 100644 --- a/skins/standard/index.css +++ b/skins/standard/index.css @@ -27,6 +27,11 @@ padding: 0; } + #page-index ul + { + padding-bottom: 1em; + } + #page-index li { list-style: none; @@ -34,7 +39,7 @@ #page-index p { - padding-bottom: 1em; + padding-bottom: 0.5em; } /* Hide from NN4 */ @@ -46,7 +51,6 @@ margin-top: 2.3em; margin-right: 2.3em; float: right; - background: transparent no-repeat url(index/front.png); } @@ -60,10 +64,22 @@ padding-top: 1em; } - /* Hide from MSIE6- */ - #page-index [id]#sidebar + #new_release { - padding: 1em 0; + border: 2px solid red; + padding: 0.5em 1em; + margin: 1em; + font-weight: bold; } + #new_release .notice + { + font-size: 80%; + font-weight: normal; + } + + #welcome-admin a + { + font-weight: bold; + } /* index page (end) */ diff --git a/skins/standard/index/CVS/Entries b/skins/standard/index/CVS/Entries index 3fbdca846..88cea8633 100644 --- a/skins/standard/index/CVS/Entries +++ b/skins/standard/index/CVS/Entries @@ -1,2 +1,2 @@ -/front.png/1.1/Thu Feb 3 19:23:17 2005/-kb/TBUGZILLA-2_22_3 +/front.png/1.1/Thu Feb 3 19:23:17 2005/-kb/TBUGZILLA-3_0 D diff --git a/skins/standard/index/CVS/Tag b/skins/standard/index/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/skins/standard/index/CVS/Tag +++ b/skins/standard/index/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/skins/standard/params.css b/skins/standard/params.css index 0390c50e3..8d34d0e05 100644 --- a/skins/standard/params.css +++ b/skins/standard/params.css @@ -47,3 +47,9 @@ dt { dd { margin-bottom: 1.5em; } + +.contribute { + border: 1px dotted black; + padding: .5em; + font-size: small; +} diff --git a/skins/standard/release-notes.css b/skins/standard/release-notes.css new file mode 100644 index 000000000..51159ae20 --- /dev/null +++ b/skins/standard/release-notes.css @@ -0,0 +1,35 @@ +/* The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Initial Developer of the Original Code is Everything Solved. + * Portions created by Everything Solved are Copyright (C) 2006 + * Everything Solved. All Rights Reserved. + * + * The Original Code is the Bugzilla Bug Tracking System. + * + * Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + */ + +#bugzilla-body { + padding: 0 1em; +} + +.req_new { + color: red; +} + +.req_table { + border-collapse: collapse; +} + +.req_table td, .req_table th { + border: 1px solid black; + padding: .25em; +} diff --git a/skins/standard/show_multiple.css b/skins/standard/show_multiple.css index fd418a82e..50875382d 100644 --- a/skins/standard/show_multiple.css +++ b/skins/standard/show_multiple.css @@ -1,3 +1,52 @@ hr {margin: 20px auto 40px} .bz_private { color:darkred } + +h1 { + font-size: 2em; + margin-bottom: 10px; +} + +/* bugfields is table of all fields and values */ +.bugfields { + font-size: small; + background: #eee; + padding: 5px; + border: 1px solid silver; + width: 100%; +} + +.bugfields tr { + vertical-align: top; +} + +.bugfields th { + width: 10em; + text-align: left; + font-weight: normal; + line-height: 150%; +} + +.bugfields td { + font-weight: bold; + line-height: 150%; +} + +.bugfields .rightcell { + padding-left: 10px; +} + +/* set line-height to normal for nested tables of bugfields table */ +.bugfields table th, .bugfields table td { + line-height: 100%; + width: auto; +} + +.bugfields table.timetracking th, .bugfields table.timetracking td { + width: 10em; +} + +.error { + color: red; + font-weight: bold; +} diff --git a/summarize_time.cgi b/summarize_time.cgi index 66396741a..26cc04725 100755 --- a/summarize_time.cgi +++ b/summarize_time.cgi @@ -23,17 +23,16 @@ use lib qw(.); use Date::Parse; # strptime use Date::Format; # strftime +use Bugzilla; +use Bugzilla::Constants; # LOGIN_* use Bugzilla::Bug; # EmitDependList use Bugzilla::Util; # trim -use Bugzilla::Constants; # LOGIN_* -use Bugzilla::User; # UserInGroup -require "globals.pl"; +use Bugzilla::Error; +use Bugzilla::User; # Bugzilla->user->in_group my $template = Bugzilla->template; my $vars = {}; -GetVersionTable(); - # # Date handling # @@ -361,7 +360,7 @@ sub get_inactive_bugs { WHERE longdescs.bug_id IN ($buglist) $date_bits } . $dbh->sql_group_by('longdescs.bug_id', - 'bugs.short_desc, bugs.bug_status, + 'bugs.short_desc, bugs.bug_status, longdescs.bug_when') . qq{ ORDER BY longdescs.bug_when}; $sth = $dbh->prepare($q); @@ -405,7 +404,7 @@ my $cgi = Bugzilla->cgi; Bugzilla->switch_to_shadow_db(); -UserInGroup(Param("timetrackinggroup")) +Bugzilla->user->in_group(Bugzilla->params->{"timetrackinggroup"}) || ThrowUserError("auth_failure", {group => "time-tracking", action => "access", object => "timetracking_summaries"}); @@ -522,7 +521,6 @@ $vars->{'do_report'} = $do_report; $vars->{'do_depends'} = $do_depends; $vars->{'check_time'} = \&check_time; $vars->{'sort_bug_keys'} = \&sort_bug_keys; -$vars->{'GetBugLink'} = \&GetBugLink; my $format = $template->get_format("bug/summarize-time", undef, $ctype); diff --git a/t/001compile.t b/t/001compile.t index 5ea849ac1..7d0bc0181 100644 --- a/t/001compile.t +++ b/t/001compile.t @@ -36,11 +36,11 @@ use Test::More tests => scalar(@Support::Files::testitems); use DBI; my @DBI_drivers = DBI->available_drivers; -# Bugzilla requires Perl 5.6.1 now. Checksetup will tell you this if you run it, but +# Bugzilla requires Perl 5.8.0 now. Checksetup will tell you this if you run it, but # it tests it in a polite/passive way that won't make it fail at compile time. We'll -# slip in a compile-time failure if it's missing here so a tinderbox on 5.00503 won't -# pass and mistakenly let people think Bugzilla works on 5.00503 -require 5.006_001; +# slip in a compile-time failure if it's missing here so a tinderbox on < 5.8 won't +# pass and mistakenly let people think Bugzilla works on any perl below 5.8. +require 5.008; # Capture the TESTOUT from Test::More or Test::Builder for printing errors. # This will handle verbosity for us automatically. @@ -65,6 +65,12 @@ foreach my $file (@testitems) { $file =~ s/\s.*$//; # nuke everything after the first space (#comment) next if (!$file); # skip null entries + # Skip mod_perl.pl in all cases. It doesn't compile correctly from the command line. + if ($file eq 'mod_perl.pl') { + ok(1, "Skipping mod_perl.pl"); + next; + } + # Check that we have a DBI module to support the DB, if this is a database # module (but not Schema) if ($file =~ m#Bugzilla/DB/([^/]+)\.pm$# && $file ne "Bugzilla/DB/Schema.pm") { diff --git a/t/004template.t b/t/004template.t index 9cbfadf6e..034031c0b 100644 --- a/t/004template.t +++ b/t/004template.t @@ -86,7 +86,7 @@ foreach my $include_path (@include_paths) { INCLUDE_PATH => $include_path , # Need to define filters used in the codebase, they don't # actually have to function in this test, just be defined. - # See globals.pl for the actual codebase definitions. + # See Template.pm for the actual codebase definitions. # Initialize templates (f.e. by loading plugins like Hook). PRE_PROCESS => "global/initialize.none.tmpl", diff --git a/t/007util.t b/t/007util.t index 02069dcc1..5f2c998d1 100644 --- a/t/007util.t +++ b/t/007util.t @@ -28,18 +28,16 @@ use lib 't'; use Support::Files; BEGIN { - use Test::More tests => 14; + use Test::More tests => 13; + use_ok(Bugzilla); use_ok(Bugzilla::Util); } -# We need to override the the Param() function so we can get an expected -# value when Bugzilla::Utim::format_time calls asks for Param('timezone'). +# We need to override Bugzilla->params so we can get an expected value when +# Bugzilla::Util::format_time() calls ask for the 'timezone' parameter. # This will also prevent the tests from failing on site that do not have a -# data/params file containing Param('timezone') yet. -sub myParam { - return "TEST" if $_[0] eq 'timezone'; -} -*::Param = *myParam; +# data/params file containing 'timezone' yet. +Bugzilla->params->{'timezone'} = "TEST"; # we don't test the taint functions since that's going to take some more work. # XXX: test taint functions @@ -59,11 +57,6 @@ is(lsearch(\@list,'pear'),1,'lsearch 1'); is(lsearch(\@list,'<"\\%'),3,'lsearch 2'); is(lsearch(\@list,'kiwi'),-1,'lsearch 3 (missing item)'); -#max() and min(): -@list = (7,27,636,2); -is(max(@list),636,'max()'); -is(min(@list),2,'min()'); - #trim(): is(trim(" fg<*\$%>+=~~ "),'fg<*$%>+=~~','trim()'); diff --git a/t/008filter.t b/t/008filter.t index cd351525a..d4053461e 100644 --- a/t/008filter.t +++ b/t/008filter.t @@ -176,7 +176,7 @@ sub directive_ok { return 1 if $directive =~ /^(IF|END|UNLESS|FOREACH|PROCESS|INCLUDE| BLOCK|USE|ELSE|NEXT|LAST|DEFAULT|FLUSH| ELSIF|SET|SWITCH|CASE|WHILE|RETURN|STOP| - TRY|CATCH|FINAL|THROW|CLEAR)/x; + TRY|CATCH|FINAL|THROW|CLEAR|MACRO)/x; # ? : if ($directive =~ /.+\?(.+):(.+)/) { @@ -208,7 +208,7 @@ sub directive_ok { return 1 if $directive =~ /^Hook.process\(/; # Other functions guaranteed to return OK output - return 1 if $directive =~ /^(time2str|GetBugLink|url)\(/; + return 1 if $directive =~ /^(time2str|url)\(/; # Safe Template Toolkit virtual methods return 1 if $directive =~ /\.(length$|size$|push\()/; @@ -225,7 +225,7 @@ sub directive_ok { return 1 if $directive =~ /FILTER\ (html|csv|js|base64|url_quote|css_class_quote| ics|quoteUrls|time|uri|xml|lower|html_light| obsolete|inactive|closed|unitconvert| - none)\b/x; + txt|none)\b/x; return 0; } diff --git a/t/009bugwords.t b/t/009bugwords.t index 9249ba4ac..bf3d91f26 100644 --- a/t/009bugwords.t +++ b/t/009bugwords.t @@ -77,9 +77,9 @@ foreach my $file (@testitems) { } # "Bugzilla" - if (grep /Bugzilla[^_]/, $text) { - # Exclude JS comments, hyperlinks, USE and variable assignment. - unless (grep /(\/\/.*|org.*>|USE |= )Bugzilla/, $text) { + if (grep /(?<!X\-)Bugzilla(?!_|::|->|\.pm)/, $text) { + # Exclude JS comments, hyperlinks, USE, and variable assignment. + unless (grep /(\/\/.*|(org|api).*>|USE |= )Bugzilla/, $text) { push(@errors, [$lineno, $text]); next; } diff --git a/t/010dependencies.t b/t/010dependencies.t new file mode 100644 index 000000000..977c8aa67 --- /dev/null +++ b/t/010dependencies.t @@ -0,0 +1,108 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code are the Bugzilla Tests. +# +# Contributor(s): David Miller <justdave@bugzilla.org> +# Frédéric Buclin <LpSolit@gmail.com> + + +################## +#Bugzilla Test 10# +## dependencies ## + +use strict; + +use lib 't'; + +use Support::Files; +use Test::More qw(no_plan); + +my %mods; +my %deps; + +# Extract all Perl modules. +foreach my $file (@Support::Files::testitems) { + if ($file =~ /^(.*)\.pm$/) { + my $module = $1; + $module =~ s#/#::#g; + $mods{$module} = $file; + } +} + +foreach my $module (keys %mods) { + my $reading = 1; + my @use; + + open(SOURCE, $mods{$module}); + while (my $line = <SOURCE>) { + last if ($line =~ /^__END__/); + if ($line =~ /^=cut/) { + $reading = 1; + next; + } + next unless $reading; + if ($line =~ /^=(head|over|item|back|pod|begin|end|for)/) { + $reading = 0; + next; + } + if ($line =~ /^package\s+([^;]);/) { + $module = $1; + } + elsif ($line =~ /^\s*(?:use|^require) *"?(Bugzilla.*?)"?(?:;|\s+qw[\(\{]|\s+\(\))/) { + my $used = $1; + $used =~ s#/#::#g; + $used =~ s#\.pm$##; + $used =~ s#\$module#[^:]+#; + $used =~ s#\${[^}]+}#[^:]+#; + $used =~ s#[" ]##g; + my $exclude = ""; + if ($used eq 'Bugzilla::Auth::Login::[^:]+' ) { $exclude = 'Bugzilla::Auth::Login::Stack' } + elsif ($used eq 'Bugzilla::Auth::Verify::[^:]+') { $exclude = 'Bugzilla::Auth::Verify::Stack' } + elsif ($used eq 'Bugzilla::Config::[^:]+' ) { $exclude = 'Bugzilla::Config::Common' } + push(@use, grep(/^$used$/, grep(!/^$exclude$/, keys %mods))); + } + } + close (SOURCE); + + foreach my $u (@use) { + if (!grep {$_ eq $u} @{$deps{$module}}) { + push(@{$deps{$module}}, $u); + } + } +} + +sub creates_loop { + my ($module, $used_module) = @_; + my @list = ($used_module); + my %seen; + while (my $next = shift @list) { + if ($module eq $next) { + ok(0, "Dependency on $used_module from $module causes loop. --ERROR"); + return; + } + if (!$seen{$next}) { + push(@list, @{$deps{$next}}) if defined $deps{$next}; + } + $seen{$next} = 1; + } + ok(1, "No dependency loop between $module and $used_module"); +} + + +foreach my $module (keys %deps) { + foreach my $used_module (@{$deps{$module}}) { + creates_loop($module, $used_module); + } +} + +exit 0; diff --git a/t/012throwables.t b/t/012throwables.t index 2c7a5998b..b846ab907 100644 --- a/t/012throwables.t +++ b/t/012throwables.t @@ -19,6 +19,7 @@ # Rights Reserved. # # Contributor(s): Dennis Melentyev <dennis.melentyev@infopulse.com.ua> +# Max Kanat-Alexander <mkanat@bugzilla.org> @@ -30,6 +31,8 @@ use strict; use lib 't'; +use Bugzilla::WebService::Constants; + use File::Spec; use Support::Files; use Support::Templates; @@ -63,8 +66,8 @@ foreach my $include_path (@include_paths) { } } -# Count the tests -my $tests = (scalar keys %test_modules) + (scalar keys %test_templates); +# Count the tests. The +1 is for checking the WS_ERROR_CODE errors. +my $tests = (scalar keys %test_modules) + (scalar keys %test_templates) + 1; exit 0 if !$tests; # Set requested tests counter. @@ -113,9 +116,18 @@ foreach my $file (keys %test_modules) { last if $line =~ /^__END__/; # skip the POD (at least in # Bugzilla/Error.pm) $lineno++; - if ($line =~ /^[^#]*Throw(Code|User)Error\s*\(\s*["'](.*?)['"]/) { - my $errtype = lc($1); - my $errtag = $2; + if ($line =~ +/^[^#]*(Throw(Code|User)Error|error\s+=>)\s*\(?\s*["'](.*?)['"]/) { + my $errtype; + # If it's a normal ThrowCode/UserError + if ($2) { + $errtype = lc($2); + } + # If it's an AUTH_ERROR tag + else { + $errtype = 'code'; + } + my $errtag = $3; push @{$Errors{$errtype}{$errtag}{used_in}{$file}}, $lineno; } } @@ -153,11 +165,27 @@ foreach my $errtype (keys %Errors) { } } +# And make sure that everything defined in WS_ERROR_CODE +# is actually a valid error. +foreach my $err_name (keys %{WS_ERROR_CODE()}) { + if (!defined $Errors{'code'}{$err_name} + && !defined $Errors{'user'}{$err_name}) + { + Register(\%test_modules, 'WS_ERROR_CODE', + "Error tag '$err_name' is used in WS_ERROR_CODE in" + . " Bugzilla/WebService/Constants.pm" + . " but not defined in any template, and not used in any code."); + } +} + # Now report modules results foreach my $file (sort keys %test_modules) { Report($file, @{$test_modules{$file}}); } +# And report WS_ERROR_CODE results +Report('WS_ERROR_CODE', @{$test_modules{'WS_ERROR_CODE'}}); + # Now report templates results foreach my $file (sort keys %test_templates) { Report($file, @{$test_templates{$file}}); diff --git a/t/CVS/Entries b/t/CVS/Entries index 382e491ee..acf70984b 100644 --- a/t/CVS/Entries +++ b/t/CVS/Entries @@ -1,12 +1,13 @@ -/001compile.t/1.13/Thu May 26 20:07:35 2005//TBUGZILLA-2_22_3 -/002goodperl.t/1.15/Wed Sep 8 22:46:34 2004//TBUGZILLA-2_22_3 -/003safesys.t/1.6/Sun Dec 5 14:13:27 2004//TBUGZILLA-2_22_3 -/004template.t/1.37/Wed Sep 7 12:05:12 2005//TBUGZILLA-2_22_3 -/005no_tabs.t/1.13/Fri Aug 5 23:47:27 2005//TBUGZILLA-2_22_3 -/006spellcheck.t/1.5/Wed Feb 2 16:06:51 2005//TBUGZILLA-2_22_3 -/007util.t/1.6/Tue May 10 20:30:13 2005//TBUGZILLA-2_22_3 -/008filter.t/1.21.2.2/Sat Oct 14 20:30:54 2006//TBUGZILLA-2_22_3 -/009bugwords.t/1.3/Fri Aug 5 23:47:27 2005//TBUGZILLA-2_22_3 -/011pod.t/1.1/Tue Jul 26 14:23:50 2005//TBUGZILLA-2_22_3 -/012throwables.t/1.1.2.4/Sun May 14 18:51:26 2006//TBUGZILLA-2_22_3 +/001compile.t/1.15/Fri Aug 18 18:29:41 2006//TBUGZILLA-3_0 +/002goodperl.t/1.15/Wed Sep 8 22:46:34 2004//TBUGZILLA-3_0 +/003safesys.t/1.6/Sun Dec 5 14:13:27 2004//TBUGZILLA-3_0 +/004template.t/1.38/Wed Jun 21 00:44:48 2006//TBUGZILLA-3_0 +/005no_tabs.t/1.13/Fri Aug 5 23:47:27 2005//TBUGZILLA-3_0 +/006spellcheck.t/1.5/Wed Feb 2 16:06:51 2005//TBUGZILLA-3_0 +/007util.t/1.8/Tue Jun 27 10:54:05 2006//TBUGZILLA-3_0 +/008filter.t/1.26/Sat Oct 14 20:26:50 2006//TBUGZILLA-3_0 +/009bugwords.t/1.5/Thu Feb 22 18:41:29 2007//TBUGZILLA-3_0 +/010dependencies.t/1.1/Tue Sep 5 17:02:45 2006//TBUGZILLA-3_0 +/011pod.t/1.1/Tue Jul 26 14:23:50 2005//TBUGZILLA-3_0 +/012throwables.t/1.5/Wed Oct 4 20:20:59 2006//TBUGZILLA-3_0 D/Support//// diff --git a/t/CVS/Tag b/t/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/t/CVS/Tag +++ b/t/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/t/Support/CVS/Entries b/t/Support/CVS/Entries index 4adf8e463..c6cbdd009 100644 --- a/t/Support/CVS/Entries +++ b/t/Support/CVS/Entries @@ -1,4 +1,4 @@ -/Files.pm/1.21/Tue Jan 10 23:53:10 2006//TBUGZILLA-2_22_3 -/Systemexec.pm/1.2/Fri Oct 19 22:39:51 2001//TBUGZILLA-2_22_3 -/Templates.pm/1.14.2.1/Tue Jul 4 22:27:42 2006//TBUGZILLA-2_22_3 +/Files.pm/1.22/Mon Feb 5 23:15:36 2007//TBUGZILLA-3_0 +/Systemexec.pm/1.2/Fri Oct 19 22:39:51 2001//TBUGZILLA-3_0 +/Templates.pm/1.15/Tue Jul 4 22:25:47 2006//TBUGZILLA-3_0 D diff --git a/t/Support/CVS/Tag b/t/Support/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/t/Support/CVS/Tag +++ b/t/Support/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/t/Support/Files.pm b/t/Support/Files.pm index 4f1b619b4..8fc334567 100644 --- a/t/Support/Files.pm +++ b/t/Support/Files.pm @@ -32,6 +32,8 @@ use File::Find; %exclude_deps = ( 'XML::Twig' => ['importxml.pl'], 'Net::LDAP' => ['Bugzilla/Auth/Verify/LDAP.pm'], + 'Email::Reply' => ['email_in.pl'], + 'Email::MIME::Attachment::Stripper' => ['email_in.pl'] ); diff --git a/template/CVS/Entries b/template/CVS/Entries index 87c12736b..953db0bb3 100644 --- a/template/CVS/Entries +++ b/template/CVS/Entries @@ -1,2 +1,2 @@ -/.cvsignore/1.3/Tue May 7 21:33:53 2002//TBUGZILLA-2_22_3 +/.cvsignore/1.3/Tue May 7 21:33:53 2002//TBUGZILLA-3_0 D/en//// diff --git a/template/CVS/Tag b/template/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/CVS/Tag +++ b/template/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/CVS/Entries b/template/en/CVS/Entries index 63a51e632..4702fc947 100644 --- a/template/en/CVS/Entries +++ b/template/en/CVS/Entries @@ -1,3 +1,3 @@ -/.cvsignore/1.1/Wed Apr 24 07:29:49 2002//TBUGZILLA-2_22_3 +/.cvsignore/1.1/Wed Apr 24 07:29:49 2002//TBUGZILLA-3_0 D/default//// D/extension//// diff --git a/template/en/CVS/Tag b/template/en/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/CVS/Tag +++ b/template/en/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/CVS/Entries b/template/en/default/CVS/Entries index 3fcf0db7e..69939696e 100644 --- a/template/en/default/CVS/Entries +++ b/template/en/default/CVS/Entries @@ -1,8 +1,9 @@ -/config.js.tmpl/1.6/Fri Sep 2 21:12:08 2005//TBUGZILLA-2_22_3 -/config.rdf.tmpl/1.6/Fri Sep 2 21:12:08 2005//TBUGZILLA-2_22_3 -/filterexceptions.pl/1.61.2.6/Thu Aug 23 15:36:56 2007//TBUGZILLA-2_22_3 -/index.html.tmpl/1.24/Sun Aug 21 18:16:42 2005//TBUGZILLA-2_22_3 -/sidebar.xul.tmpl/1.18.2.2/Tue Dec 26 20:19:06 2006//TBUGZILLA-2_22_3 +/config.js.tmpl/1.7/Mon Jul 3 08:53:26 2006//TBUGZILLA-3_0 +/config.rdf.tmpl/1.7/Mon Jul 3 08:53:26 2006//TBUGZILLA-3_0 +/filterexceptions.pl/1.95/Sat Feb 10 21:55:22 2007//TBUGZILLA-3_0 +/index.html.tmpl/1.33.2.3/Wed Apr 18 00:15:14 2007//TBUGZILLA-3_0 +/sidebar.xul.tmpl/1.22/Tue Dec 26 20:17:26 2006//TBUGZILLA-3_0 +/welcome-admin.html.tmpl/1.2/Thu Sep 14 14:57:02 2006//TBUGZILLA-3_0 D/account//// D/admin//// D/attachment//// diff --git a/template/en/default/CVS/Tag b/template/en/default/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/CVS/Tag +++ b/template/en/default/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/account/CVS/Entries b/template/en/default/account/CVS/Entries index 42d969a47..29b4473b7 100644 --- a/template/en/default/account/CVS/Entries +++ b/template/en/default/account/CVS/Entries @@ -1,7 +1,7 @@ -/cancel-token.txt.tmpl/1.8/Wed Mar 16 21:58:55 2005//TBUGZILLA-2_22_3 -/create.html.tmpl/1.8/Sun Jan 18 18:39:11 2004//TBUGZILLA-2_22_3 -/created.html.tmpl/1.6/Sat Mar 12 21:51:16 2005//TBUGZILLA-2_22_3 -/exists.html.tmpl/1.7/Sun Jan 18 18:39:11 2004//TBUGZILLA-2_22_3 +/cancel-token.txt.tmpl/1.11.2.1/Mon Mar 26 08:00:22 2007//TBUGZILLA-3_0 +/create.html.tmpl/1.10/Sat Aug 19 18:12:00 2006//TBUGZILLA-3_0 +/created.html.tmpl/1.7/Sat Aug 19 18:12:00 2006//TBUGZILLA-3_0 +/profile-activity.html.tmpl/1.2/Sun Jan 7 23:51:09 2007//TBUGZILLA-3_0 D/auth//// D/email//// D/password//// diff --git a/template/en/default/account/CVS/Tag b/template/en/default/account/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/account/CVS/Tag +++ b/template/en/default/account/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/account/auth/CVS/Entries b/template/en/default/account/auth/CVS/Entries index fb8e0d046..e81fdfe97 100644 --- a/template/en/default/account/auth/CVS/Entries +++ b/template/en/default/account/auth/CVS/Entries @@ -1,4 +1,3 @@ -/ldap-error.html.tmpl/1.3/Thu Mar 18 16:10:17 2004//TBUGZILLA-2_22_3 -/login-small.html.tmpl/1.2.2.1/Mon Jun 19 18:31:17 2006//TBUGZILLA-2_22_3 -/login.html.tmpl/1.13/Tue Apr 12 17:23:01 2005//TBUGZILLA-2_22_3 +/login-small.html.tmpl/1.8/Tue Dec 19 03:59:21 2006//TBUGZILLA-3_0 +/login.html.tmpl/1.18/Wed Jan 17 22:27:10 2007//TBUGZILLA-3_0 D diff --git a/template/en/default/account/auth/CVS/Tag b/template/en/default/account/auth/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/account/auth/CVS/Tag +++ b/template/en/default/account/auth/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/account/auth/ldap-error.html.tmpl b/template/en/default/account/auth/ldap-error.html.tmpl deleted file mode 100644 index c719563c8..000000000 --- a/template/en/default/account/auth/ldap-error.html.tmpl +++ /dev/null @@ -1,50 +0,0 @@ -[%# 1.0@bugzilla.org %] -[%# The contents of this file are subject to the Mozilla Public - # License Version 1.1 (the "License"); you may not use this file - # except in compliance with the License. You may obtain a copy of - # the License at http://www.mozilla.org/MPL/ - # - # Software distributed under the License is distributed on an "AS - # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - # implied. See the License for the specific language governing - # rights and limitations under the License. - # - # The Original Code is the Bugzilla Bug Tracking System. - # - # The Initial Developer of the Original Code is Netscape Communications - # Corporation. Portions created by Netscape are - # Copyright (C) 1998 Netscape Communications Corporation. All - # Rights Reserved. - # - # Contributor(s): Bradley Baetz <bbaetz@acm.org> - #%] - -[%# INTERFACE: - # auth_err_tag: string. The tag for the error - # info: hash. Additional variables which may be used when printing details - # of the error. - #%] - -[% PROCESS global/variables.none.tmpl %] - -[% SWITCH auth_err_tag %] - [% CASE "cannot_retreive_attr" %] - The specified LDAP attribute [% info.attr FILTER html %] was not found. - - [% CASE "connect_failed" %] - An error occurred while trying to connect to the LDAP server. - [% IF info.errstr %] - The error from the server was: <tt>[% info.errstr FILTER html %]</tt>. - [% END %] - - [% CASE "no_userid" %] - [% terms.Bugzilla %] created a new account for you, but then could not find the - new userid. - - [% CASE "server_not_defined" %] - The LDAP server for authentication has not been defined. - - [% CASE %] - Unhandled authentication error: <tt>[% auth_err_tag FILTER html %]</tt> - -[% END %] diff --git a/template/en/default/account/auth/login-small.html.tmpl b/template/en/default/account/auth/login-small.html.tmpl index 9d42fa581..0ea4df3e9 100644 --- a/template/en/default/account/auth/login-small.html.tmpl +++ b/template/en/default/account/auth/login-small.html.tmpl @@ -34,51 +34,51 @@ [% END %] <form name="login" action="[% script_name FILTER html %]" method="POST"> - <table> + <table id="login-small"> <tr> - <td align="right"><b>Login:</b></td> - <td><input size="20" name="Bugzilla_login"></td> + <th align="right"><label for="Bugzilla_login">Login:</label></th> + <td><input size="20" id="Bugzilla_login" name="Bugzilla_login"> + [% Param('emailsuffix') FILTER html %]</td> </tr> <tr> - <td align="right"><b>Password:</b></td> - <td><input type="password" size="20" name="Bugzilla_password"></td> + <th align="right"><label for="Bugzilla_password">Password:</label></th> + <td> + <input type="password" size="20" id="Bugzilla_password" name="Bugzilla_password"> + </td> </tr> [% IF Param('rememberlogin') == 'defaulton' || Param('rememberlogin') == 'defaultoff' %] <tr> - <td> </td> + <th> </th> <td> - <input type="checkbox" name="Bugzilla_remember" value="on" + <input type="checkbox" id="Bugzilla_remember" name="Bugzilla_remember" value="on" [% "checked" IF Param('rememberlogin') == "defaulton" %]> - Remember my Login + <label for="Bugzilla_remember">Remember my Login</label> </td> </tr> [% END %] [% IF Param('loginnetmask') < 32 %] <tr> - <td align="right"> - <b> - Restrict this session<br> - to this IP address: - </b> - </td> + <th> </th> <td> - <input type="checkbox" name="Bugzilla_restrictlogin" + <input type="checkbox" id="Bugzilla_restrictlogin" name="Bugzilla_restrictlogin" checked="checked"> - (Using this option improves security) + <label for="Bugzilla_restrictlogin">Restrict this session to this IP address + (using this option improves security)</label> </td> </tr> [% END %] <tr> - <td><input type="submit" name="GoAheadAndLogIn" value="Login"></td> + <td><input type="submit" name="GoAheadAndLogIn" value="Login" + id="log_in"></td> [%# For now, password change requests only apply to the DB # verification method #%] - [% IF has_db != 0 %] + [% IF user.authorizer.can_change_password %] <td>[ <a href="index.cgi?GoAheadAndLogIn=1#forgot">Forgot my Password</a> ]</td> [% END %] </tr> diff --git a/template/en/default/account/auth/login.html.tmpl b/template/en/default/account/auth/login.html.tmpl index 37c79e1ec..f57efc113 100644 --- a/template/en/default/account/auth/login.html.tmpl +++ b/template/en/default/account/auth/login.html.tmpl @@ -22,7 +22,6 @@ [%# INTERFACE: # target: string. URL to go to after login. - # has_db: true if DB is one of the available authentication mechanisms #%] [% PROCESS global/variables.none.tmpl %] @@ -32,53 +31,49 @@ onload = "document.forms['login'].Bugzilla_login.focus()" %] +[% USE Bugzilla %] + <p> I need a legitimate login and password to continue. </p> -<form name="login" action="[% target FILTER html %]" method="POST"> +<form name="login" action="[% target FILTER html %]" method="POST" +[%- IF Bugzilla.cgi.param("data") %] enctype="multipart/form-data"[% END %]> <table> <tr> - <td align="right"> - <b>Login:</b> - </td> + <th align="right"><label for="Bugzilla_login">Login:</label></th> <td> - <input size="35" name="Bugzilla_login"> + <input size="35" id="Bugzilla_login" name="Bugzilla_login"> + [% Param('emailsuffix') FILTER html %] </td> </tr> <tr> - <td align="right"> - <b>Password:</b> - </td> + <th align="right"><label for="Bugzilla_password">Password:</label></th> <td> - <input type="password" size="35" name="Bugzilla_password"> + <input type="password" size="35" id="Bugzilla_password" name="Bugzilla_password"> </td> </tr> [% IF Param('rememberlogin') == 'defaulton' || Param('rememberlogin') == 'defaultoff' %] <tr> - <td> </td> + <th> </th> <td> - <input type="checkbox" name="Bugzilla_remember" value="on" + <input type="checkbox" id="Bugzilla_remember" name="Bugzilla_remember" value="on" [% "checked" IF Param('rememberlogin') == "defaulton" %]> - Remember my Login + <label for="Bugzilla_remember">Remember my Login</label> </td> </tr> [% END %] [% IF Param('loginnetmask') < 32 %] <tr> - <td align="right"> - <b> - Restrict this session<br> - to this IP address: - </b> - </td> + <th> </th> <td> - <input type="checkbox" name="Bugzilla_restrictlogin" + <input type="checkbox" id="Bugzilla_restrictlogin" name="Bugzilla_restrictlogin" checked="checked"> - (Using this option improves security) + <label for="Bugzilla_restrictlogin">Restrict this session to this IP address + (using this option improves security)</label> </td> </tr> [% END %] @@ -87,7 +82,7 @@ [% PROCESS "global/hidden-fields.html.tmpl" exclude="^Bugzilla_(login|password|restrictlogin)$" %] - <input type="submit" name="GoAheadAndLogIn" value="Log in"> + <input type="submit" name="GoAheadAndLogIn" value="Log in" id="log_in"> <p> (Note: you should make sure cookies are enabled for this site. @@ -99,9 +94,7 @@ # their password, assuming that our auth method allows that. #%] -[% IF caneditaccount %] - - [% IF Param("createemailregexp") %] + [% IF Param("createemailregexp") && user.authorizer.user_can_create_account %] <hr> <p> @@ -110,10 +103,7 @@ </p> [% END %] - [%# For now, password change requests only apply to the DB - # verification method #%] - - [% IF has_db != 0 %] + [% IF user.authorizer.can_change_password %] <hr> <a name="forgot"></a> @@ -123,12 +113,8 @@ enter your login name below and submit a request to change your password.<br> <input size="35" name="loginname"> - <input type="submit" value="Submit Request"> + <input type="submit" id="request" value="Submit Request"> </form> - [% END %] - <hr> -[% END %] - [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/account/cancel-token.txt.tmpl b/template/en/default/account/cancel-token.txt.tmpl index de2278419..db54663a8 100644 --- a/template/en/default/account/cancel-token.txt.tmpl +++ b/template/en/default/account/cancel-token.txt.tmpl @@ -22,11 +22,12 @@ [% PROCESS global/variables.none.tmpl %] -From: bugzilla-admin-daemon +From: [% Param('mailfrom') %] To: [% emailaddress %] Subject: [% PROCESS subject %] +X-Bugzilla-Type: admin -A request was cancelled from [% remoteaddress %]. +A request was canceled from [% remoteaddress %]. If you did not request this, it could be either an honest mistake or someone attempting to break into your [% terms.Bugzilla %] account. @@ -39,16 +40,17 @@ to [% maintainer %] if you suspect foul play. User: [% emailaddress %] Issue Date: [% issuedate %] Event Data: [% eventdata %] -Cancelled Because: -[% PROCESS cancelactionmessage %] +Canceled Because: [% PROCESS cancelactionmessage %] [% BLOCK subject %] - [% IF tokentype == 'password' %] - Password change request cancelled + [% IF tokentype == 'new_account' %] + User account creation request canceled + [% ELSIF tokentype == 'password' %] + Password change request canceled [% ELSIF tokentype == 'emailnew' OR tokentype == 'emailold' %] - Email change request cancelled + Email change request canceled [% ELSE %] - [% tokentype %] token cancelled + [% tokentype %] token canceled [% END %] [% END %] @@ -59,20 +61,24 @@ Cancelled Because: [% ELSIF cancelaction == 'email_change_cancelled' %] The request to change the email address for the [% old_email %] account to [% new_email %] has - been cancelled. + been canceled. [% ELSIF cancelaction == 'email_change_cancelled_reinstated' %] The request to change the email address for your account - to [% new_email %] has been cancelled. Your old account + to [% new_email %] has been canceled. Your old account settings have been reinstated. [% ELSIF cancelaction == 'emailold_change_cancelled' %] The request to change the email address for your account - to [% new_email %] has been cancelled. + to [% new_email %] has been canceled. [% ELSIF cancelaction == 'password_change_cancelled' %] You have requested cancellation. + [% ELSIF cancelaction == 'account_creation_cancelled' %] + The creation of the user account [% emailaddress %] + has been canceled. + [% ELSIF cancelaction == 'user_logged_in' %] You have logged in. @@ -85,6 +91,9 @@ Cancelled Because: [% ELSIF cancelaction == 'wrong_token_for_confirming_email_change' %] You have tried to use the token to confirm the email address change. + [% ELSIF cancelaction == 'wrong_token_for_creating_account' %] + You have tried to use the token to create a user account. + [% ELSE %] [%# Give sensible error if the cancel-token function is used incorrectly. #%] diff --git a/template/en/default/account/create.html.tmpl b/template/en/default/account/create.html.tmpl index 8ffe6470c..2e8739b79 100644 --- a/template/en/default/account/create.html.tmpl +++ b/template/en/default/account/create.html.tmpl @@ -29,47 +29,37 @@ [% PROCESS global/variables.none.tmpl %] [% title = BLOCK %] -Create a new [% terms.Bugzilla %] account + Create a new [% terms.Bugzilla %] account [% END %] -[% PROCESS global/header.html.tmpl %] + +[% PROCESS global/header.html.tmpl + title = title + onload = "document.forms['account_creation_form'].login.focus();" %] <p> - To create a [% terms.Bugzilla %] account, all you need to do is - enter a legitimate e-mail address. The account will be created, and - its password will be mailed to you. <b>You will not be able to log - in until you receive the password.</b> If it doesn't arrive within a + To create a [% terms.Bugzilla %] account, all you need to do is to enter + a legitimate e-mail address. You will receive an email at this address + to confirm the creation of your account. <b>You will not be able to log + in until you receive the email.</b> If it doesn't arrive within a reasonable amount of time, you can contact the maintainer of this [% terms.Bugzilla %] installation at <a href="mailto:[% Param("maintainer") %]">[% Param("maintainer") %]</a>. </p> -<p> - Optionally you may enter your real name as well. -</p> - -<form method="get" action="createaccount.cgi"> +<form id="account_creation_form" method="get" action="createaccount.cgi"> <table> <tr> <td align="right"> <b>E-mail address:</b> </td> <td> - <input size="35" name="login"> + <input size="35" id="login" name="login"> [% Param('emailsuffix') FILTER html %] </td> </tr> - - <tr> - <td align="right"> - <b>Real name:</b> - </td> - <td> - <input size="35" name="realname"> - </td> - </tr> </table> <br> - <input type="submit" value="Create Account"> + <input type="submit" id="send" value="Send"> </form> [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/account/created.html.tmpl b/template/en/default/account/created.html.tmpl index 2d507b4cf..58064f24c 100644 --- a/template/en/default/account/created.html.tmpl +++ b/template/en/default/account/created.html.tmpl @@ -17,26 +17,26 @@ # Rights Reserved. # # Contributor(s): Gervase Markham <gerv@gerv.net> + # Frédéric Buclin <LpSolit@gmail.com> #%] [%# INTERFACE: # login: string. The user's Bugzilla login email address. #%] -[% PROCESS global/header.html.tmpl - title = "Account Created" -%] +[% PROCESS global/variables.none.tmpl %] -<p> - A new account, - <tt>[% login FILTER html %]</tt>, - has been created and a randomly-generated password has been e-mailed - to that address. -</p> +[% title = BLOCK %] + Request for new user account '[% login FILTER html %]' submitted +[% END %] + +[% PROCESS global/header.html.tmpl title = title %] <p> - When the e-mail arrives, - <a href="index.cgi?GoAheadAndLogIn=1">log in here</a>. + To confirm the creation of the user account <tt>[% login FILTER html %]</tt>, + use the URL given in the email you will receive. If you take no action in the + next [% constants.MAX_TOKEN_AGE FILTER html %] days, this request will + automatically be canceled. </p> [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/account/email/CVS/Entries b/template/en/default/account/email/CVS/Entries index 07d9a403f..7d544022b 100644 --- a/template/en/default/account/email/CVS/Entries +++ b/template/en/default/account/email/CVS/Entries @@ -1,4 +1,6 @@ -/change-new.txt.tmpl/1.8/Wed Mar 16 21:58:55 2005//TBUGZILLA-2_22_3 -/change-old.txt.tmpl/1.9/Wed Mar 16 21:58:55 2005//TBUGZILLA-2_22_3 -/confirm.html.tmpl/1.9/Thu Mar 18 16:08:52 2004//TBUGZILLA-2_22_3 +/change-new.txt.tmpl/1.10/Fri Dec 15 12:30:02 2006//TBUGZILLA-3_0 +/change-old.txt.tmpl/1.11/Fri Dec 15 12:30:02 2006//TBUGZILLA-3_0 +/confirm-new.html.tmpl/1.2.2.1/Mon Mar 26 08:00:22 2007//TBUGZILLA-3_0 +/confirm.html.tmpl/1.10/Wed Jul 12 12:21:37 2006//TBUGZILLA-3_0 +/request-new.txt.tmpl/1.3/Fri Dec 15 12:30:02 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/account/email/CVS/Tag b/template/en/default/account/email/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/account/email/CVS/Tag +++ b/template/en/default/account/email/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/account/email/change-new.txt.tmpl b/template/en/default/account/email/change-new.txt.tmpl index 7113504d8..d3494e62a 100644 --- a/template/en/default/account/email/change-new.txt.tmpl +++ b/template/en/default/account/email/change-new.txt.tmpl @@ -22,9 +22,10 @@ [% PROCESS global/variables.none.tmpl %] [% expiration_ts = token_ts + (max_token_age * 86400) %] -From: bugzilla-admin-daemon +From: [% Param('mailfrom') %] To: [% emailaddress %] Subject: [% terms.Bugzilla %] Change Email Address Request +X-Bugzilla-Type: admin [%+ terms.Bugzilla %] has received a request to change the email address for the account [% oldemailaddress %] to your address. @@ -38,5 +39,5 @@ this request, visit the following link: [%+ Param('urlbase') %]token.cgi?t=[% token FILTER url_quote %]&a=cxlem -If you do nothing, the request will lapse after [%+ max_token_age %] days -(at precisely [%+ time2str("%H:%M on the %o of %B, %Y", expiration_ts) %]). +If you do nothing, the request will lapse after [%+ max_token_age %] days +(on [%+ time2str("%B %o, %Y at %H:%M %Z", expiration_ts) %]). diff --git a/template/en/default/account/email/change-old.txt.tmpl b/template/en/default/account/email/change-old.txt.tmpl index 272f6d4e5..b50cbfa1b 100644 --- a/template/en/default/account/email/change-old.txt.tmpl +++ b/template/en/default/account/email/change-old.txt.tmpl @@ -27,12 +27,13 @@ [% PROCESS global/variables.none.tmpl %] [% expiration_ts = token_ts + (max_token_age * 86400) %] -From: bugzilla-admin-daemon +From: [% Param('mailfrom') %] To: [% emailaddress %] Subject: [% terms.Bugzilla %] Change Email Address Request Importance: High X-MSMail-Priority: High X-Priority: 1 +X-Bugzilla-Type: admin [%+ terms.Bugzilla %] has received a request to change the email address for your account to [%+ newemailaddress %]. @@ -42,6 +43,6 @@ this request, visit the following link: [%+ Param('urlbase') %]token.cgi?t=[% token FILTER url_quote %]&a=cxlem -If you do nothing, and [%+ newemailaddress %] confirms this request, the -change will be made permanent after [%+ max_token_age %] days (at precisely -[%+ time2str("%H:%M on the %o of %B, %Y", expiration_ts) %]). +If you do nothing, and [%+ newemailaddress %] confirms this request, +the change will be made permanent after [%+ max_token_age %] days +(on [%+ time2str("%B %o, %Y at %H:%M %Z", expiration_ts) %]). diff --git a/template/en/default/account/email/confirm-new.html.tmpl b/template/en/default/account/email/confirm-new.html.tmpl new file mode 100644 index 000000000..45c12b8f5 --- /dev/null +++ b/template/en/default/account/email/confirm-new.html.tmpl @@ -0,0 +1,64 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + #%] + +[%# INTERFACE: + # token: string. The token to be used in the user account creation. + # email: email address of the user account. + # date: creation date of the token. + #%] + +[% title = BLOCK %]Create a new user account for '[% email FILTER html %]'[% END %] +[% PROCESS "global/header.html.tmpl" + title = title + onload = "document.forms['confirm_account_form'].realname.focus();" %] + +[% expiration_ts = date + (constants.MAX_TOKEN_AGE * 86400) %] +<div> + To complete the creation of your user account, you must choose a password in the + form below. You can also enter your real name, which is optional.<p> + If you don't fill this form before + <u>[%+ time2str("%B %o, %Y at %H:%M %Z", expiration_ts) %]</u>, + the creation of this account will be automatically canceled. +</div> + +<form id="confirm_account_form" method="post" action="token.cgi"> + <input type="hidden" name="t" value="[% token FILTER html %]"> + <input type="hidden" name="a" value="confirm_new_account"> + <table> + <tr> + <th align="right">Email Address:</th> + <td>[% email FILTER html %]</td> + </tr> + <tr> + <th align="right"><label for="realname">Real Name</label>:</th> + <td><input type="text" id="realname" name="realname" value=""></td> + </tr> + <tr> + <th align="right"><label for="passwd1">Type your password</label>:</th> + <td><input type="password" id="passwd1" name="passwd1" value=""></td> + </tr> + <tr> + <th align="right"><label for="passwd1">Re-type your password</label>:</th> + <td><input type="password" id="passwd2" name="passwd2" value=""></td> + </tr> + <tr> + <th align="right"> </th> + <td><input type="submit" id="confirm" value="Send"></td> + </tr> + </table> +</form> + +[% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/account/email/confirm.html.tmpl b/template/en/default/account/email/confirm.html.tmpl index 232d8b3b7..5bf79f058 100644 --- a/template/en/default/account/email/confirm.html.tmpl +++ b/template/en/default/account/email/confirm.html.tmpl @@ -40,7 +40,7 @@ </tr> <tr> <th align="right"> </th> - <td><input type="submit" value="Submit"></td> + <td><input type="submit" id="confirm" value="Submit"></td> </tr> </table> </form> diff --git a/template/en/default/account/email/request-new.txt.tmpl b/template/en/default/account/email/request-new.txt.tmpl new file mode 100644 index 000000000..3fcdddfd1 --- /dev/null +++ b/template/en/default/account/email/request-new.txt.tmpl @@ -0,0 +1,45 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + #%] + +[%# INTERFACE: + # token: random string used to authenticate the transaction. + # token_ts: creation date of the token. + # email: email address of the new account. + #%] + +[% PROCESS global/variables.none.tmpl %] + +[% expiration_ts = token_ts + (constants.MAX_TOKEN_AGE * 86400) %] +From: [% Param('mailfrom') %] +To: [% email %] +Subject: [% terms.Bugzilla %]: confirm account creation +X-Bugzilla-Type: admin + +[%+ terms.Bugzilla %] has received a request to create a user account +using your email address ([% email %]). + +To confirm that you want to create an account using that email address, +visit the following link: + +[%+ Param('urlbase') %]token.cgi?t=[% token FILTER url_quote %]&a=request_new_account + +If you are not the person who made this request, or you wish to cancel +this request, visit the following link: + +[%+ Param('urlbase') %]token.cgi?t=[% token FILTER url_quote %]&a=cancel_new_account + +If you do nothing, the request will lapse after [%+ constants.MAX_TOKEN_AGE %] days +(on [%+ time2str("%B %o, %Y at %H:%M %Z", expiration_ts) %]). diff --git a/template/en/default/account/password/CVS/Entries b/template/en/default/account/password/CVS/Entries index b1bca7d12..4b713f81e 100644 --- a/template/en/default/account/password/CVS/Entries +++ b/template/en/default/account/password/CVS/Entries @@ -1,3 +1,3 @@ -/forgotten-password.txt.tmpl/1.7/Wed Mar 16 21:58:55 2005//TBUGZILLA-2_22_3 -/set-forgotten-password.html.tmpl/1.6/Sun Jan 18 18:39:13 2004//TBUGZILLA-2_22_3 +/forgotten-password.txt.tmpl/1.8/Fri Oct 20 21:22:55 2006//TBUGZILLA-3_0 +/set-forgotten-password.html.tmpl/1.7/Wed Jul 12 12:21:37 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/account/password/CVS/Tag b/template/en/default/account/password/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/account/password/CVS/Tag +++ b/template/en/default/account/password/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/account/password/forgotten-password.txt.tmpl b/template/en/default/account/password/forgotten-password.txt.tmpl index 5ac3ed75c..75720e7c8 100644 --- a/template/en/default/account/password/forgotten-password.txt.tmpl +++ b/template/en/default/account/password/forgotten-password.txt.tmpl @@ -22,9 +22,10 @@ [% PROCESS global/variables.none.tmpl %] [% expiration_ts = token_ts + (max_token_age * 86400) %] -From: bugzilla-admin-daemon +From: [% Param('mailfrom') %] To: [% emailaddress %] Subject: [% terms.Bugzilla %] Change Password Request +X-Bugzilla-Type: admin You have (or someone impersonating you has) requested to change your [%+ terms.Bugzilla %] password. To complete the change, visit the following link: diff --git a/template/en/default/account/password/set-forgotten-password.html.tmpl b/template/en/default/account/password/set-forgotten-password.html.tmpl index 147bc4bfa..89d3dd01e 100644 --- a/template/en/default/account/password/set-forgotten-password.html.tmpl +++ b/template/en/default/account/password/set-forgotten-password.html.tmpl @@ -47,7 +47,7 @@ <tr> <th align="right"> </th> <td> - <input type="submit" value="Submit"> + <input type="submit" id="update" value="Submit"> </td> </tr> </table> diff --git a/template/en/default/account/prefs/CVS/Entries b/template/en/default/account/prefs/CVS/Entries index 211f42a27..2f3c65a00 100644 --- a/template/en/default/account/prefs/CVS/Entries +++ b/template/en/default/account/prefs/CVS/Entries @@ -1,7 +1,7 @@ -/account.html.tmpl/1.6/Thu Mar 18 16:11:27 2004//TBUGZILLA-2_22_3 -/email.html.tmpl/1.24.2.1/Thu Jul 13 18:52:14 2006//TBUGZILLA-2_22_3 -/permissions.html.tmpl/1.8.2.1/Sat Oct 14 20:30:55 2006//TBUGZILLA-2_22_3 -/prefs.html.tmpl/1.21.2.1/Fri Jun 9 12:15:54 2006//TBUGZILLA-2_22_3 -/saved-searches.html.tmpl/1.8.2.1/Thu May 10 11:15:29 2007//TBUGZILLA-2_22_3 -/settings.html.tmpl/1.3.2.2/Sun Jul 22 22:25:17 2007//TBUGZILLA-2_22_3 +/account.html.tmpl/1.7/Fri May 12 02:41:16 2006//TBUGZILLA-3_0 +/email.html.tmpl/1.28/Thu Dec 28 17:51:35 2006//TBUGZILLA-3_0 +/permissions.html.tmpl/1.11/Sun Jan 7 23:51:30 2007//TBUGZILLA-3_0 +/prefs.html.tmpl/1.27/Sun Jan 7 23:58:21 2007//TBUGZILLA-3_0 +/saved-searches.html.tmpl/1.11.2.1/Mon Feb 26 16:22:59 2007//TBUGZILLA-3_0 +/settings.html.tmpl/1.4/Sat Oct 14 20:26:51 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/account/prefs/CVS/Tag b/template/en/default/account/prefs/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/account/prefs/CVS/Tag +++ b/template/en/default/account/prefs/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/account/prefs/account.html.tmpl b/template/en/default/account/prefs/account.html.tmpl index dc936d43c..e914ecf6c 100644 --- a/template/en/default/account/prefs/account.html.tmpl +++ b/template/en/default/account/prefs/account.html.tmpl @@ -42,20 +42,21 @@ <tr> <td colspan="2"><hr></td> </tr> + [% IF user.authorizer.can_change_password %] + <tr> + <th align="right">New password:</th> + <td> + <input type="password" name="new_password1"> + </td> + </tr> - <tr> - <th align="right">New password:</th> - <td> - <input type="password" name="new_password1"> - </td> - </tr> - - <tr> - <th align="right">Re-enter new password:</th> - <td> - <input type="password" name="new_password2"> - </td> - </tr> + <tr> + <th align="right">Re-enter new password:</th> + <td> + <input type="password" name="new_password2"> + </td> + </tr> + [% END %] <tr> <th align="right">Your real name (optional, but encouraged):</th> @@ -64,7 +65,7 @@ </td> </tr> - [% IF Param('allowemailchange') %] + [% IF user.authorizer.can_change_email && Param('allowemailchange') %] [% IF login_change_date %] [% IF new_login_name %] <tr> diff --git a/template/en/default/account/prefs/email.html.tmpl b/template/en/default/account/prefs/email.html.tmpl index c95fe3954..1aa4dae76 100644 --- a/template/en/default/account/prefs/email.html.tmpl +++ b/template/en/default/account/prefs/email.html.tmpl @@ -261,15 +261,31 @@ document.write('<input type="button" value="Disable All Mail" onclick="SetCheckb If you watch a user, it is as if you are standing in their shoes for the purposes of getting email. Email is sent or not according to <u>your</u> preferences for <u>their</u> relationship to the [% terms.bug %] -(e.g. Assignee). You are watching anyone on the following comma-separated list: +(e.g. Assignee). </p> -<p>Users to watch: - <input size="60" name="watchedusers" - value="[% watchedusers FILTER html %]"> +<p> +[% IF watchedusers.size %] +You are watching everyone in the following list: + </p> + <p> + <select id="watched_by_you" name="watched_by_you" multiple="multiple" size="5"> + [% FOREACH w = watchedusers %] + <option value="[% w FILTER html %]">[% w FILTER html %]</option> + [% END %] + </select> <br /> + <input type="checkbox" id="remove_watched_users" name="remove_watched_users"> + <label for="remove_watched_users">Remove selected users from my watch list</label> +[% ELSE %] +You are currently not watching any users. +[% END %] +</p> + +<p><a name="new_watched_by_you" id="new_watched_by_you">Add users to my watch list (comma separated list)</a>: + <input size="60" name="new_watchedusers" value=""> </p> -<p>Users watching you:<br> +<p><a name="watching_you" id="watching_you">Users watching you</a>:<br> [% IF watchers.size %] [% FOREACH watcher = watchers %] [% watcher FILTER html %] <br> diff --git a/template/en/default/account/prefs/permissions.html.tmpl b/template/en/default/account/prefs/permissions.html.tmpl index 77dda1ce4..38bbfba5f 100644 --- a/template/en/default/account/prefs/permissions.html.tmpl +++ b/template/en/default/account/prefs/permissions.html.tmpl @@ -37,8 +37,6 @@ <td> [% IF has_bits.size %] You have the following permission [% terms.bits %] set on your account: - <p> - <br> <table align="center"> [% FOREACH bit_description = has_bits %] <tr> @@ -47,6 +45,23 @@ </tr> [% END %] </table> + + [% FOREACH privs = ["editcomponents", "canconfirm", "editbugs"] %] + [% SET products = ${"local_$privs"} %] + [% IF products && products.size %] + <br> + <p> + You also have local '[% privs FILTER html %]' privileges + for the following products: + </p> + <p> + [% FOREACH product = products %] + [% product.name FILTER html %]<br> + [% END %] + </p> + [% END %] + [% END %] + [% ELSE %] There are no permission [% terms.bits %] set on your account. [% END %] @@ -59,7 +74,6 @@ <br> And you can turn on or off the following [% terms.bits %] for <a href="editusers.cgi">other users</a>: - <p> <table align="center"> [% FOREACH bit_description = set_bits %] <tr> @@ -68,9 +82,8 @@ </tr> [% END %] </table> - </p> [% END %] - + [% IF user.groups.bz_sudoers %] <br> You are a member of the <b>bz_sudoers</b> group, so you can diff --git a/template/en/default/account/prefs/prefs.html.tmpl b/template/en/default/account/prefs/prefs.html.tmpl index 9cb66f7bd..da1b489e8 100644 --- a/template/en/default/account/prefs/prefs.html.tmpl +++ b/template/en/default/account/prefs/prefs.html.tmpl @@ -23,7 +23,7 @@ [%# INTERFACE: # tabs: List of hashes. May not be empty. Each hash has three members: # name: string. Name of the tab (used internally.) - # description: string. Description of the tab (used in tab title.) + # description: string. Description of the tab (used in tab title). # saveable: boolean. True if tab has a form which can be submitted. # True if user is not receiving self-generated mail. # Note: For each tab name, a template "prefs/${tab.name}.tmpl" must exist, @@ -39,18 +39,18 @@ [% filtered_login = user.login FILTER html %] [% PROCESS global/header.html.tmpl title = "User Preferences" - h2 = filtered_login + subheader = filtered_login style_urls = ['skins/standard/admin.css'] %] -[% tabs = [ { name => "account", label => "Account Preferences", - link => "userprefs.cgi?tab=account", saveable => "1" }, - { name => "settings", label => "General Preferences", +[% tabs = [{ name => "settings", label => "General Preferences", link => "userprefs.cgi?tab=settings", saveable => "1" }, { name => "email", label => "Email Preferences", link => "userprefs.cgi?tab=email", saveable => "1" }, { name => "saved-searches", label => "Saved Searches", link => "userprefs.cgi?tab=saved-searches", saveable => "1" }, + { name => "account", label => "Name and Password", + link => "userprefs.cgi?tab=account", saveable => "1" }, { name => "permissions", label => "Permissions", link => "userprefs.cgi?tab=permissions", saveable => "0" } ] %] @@ -61,21 +61,22 @@ [% END %] [% END %] -[% PROCESS global/tabs.html.tmpl %] +[% WRAPPER global/tabs.html.tmpl + tabs = tabs + current_tab = current_tab +%] [% IF changes_saved %] - <p> - <font color="red"> - The changes to your - [% current_tab.label FILTER lower %] have been saved. - </font> - </p> - [% IF email_changes_saved %] - <p> - An email has been sent to both old and new email - addresses to confirm the change of email address. - </p> - [% END %] + <div id="message"> + The changes to your [% current_tab.label FILTER lower %] have been saved. + + [% IF email_changes_saved %] + <p> + An email has been sent to both old and new email + addresses to confirm the change of email address. + </p> + [% END %] + </div> [% END %] <h3>[% current_tab.label %]</h3> @@ -96,7 +97,7 @@ <tr> <td width="150"> </td> <td> - <input type="submit" value="Submit Changes"> + <input type="submit" id="update" value="Submit Changes"> </td> </tr> </table> @@ -104,4 +105,6 @@ </form> [% END %] +[% END %] + [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/account/prefs/saved-searches.html.tmpl b/template/en/default/account/prefs/saved-searches.html.tmpl index 35d09e023..399f31b17 100644 --- a/template/en/default/account/prefs/saved-searches.html.tmpl +++ b/template/en/default/account/prefs/saved-searches.html.tmpl @@ -19,6 +19,11 @@ # Contributor(s): Gervase Markham <gerv@gerv.net> #%] +[%# INTERFACE: + # queryshare_groups: list of groups the user may share queries with + # (id, name). + #%] + <p>Your saved searches are as follows:</p> <blockquote> @@ -40,9 +45,15 @@ Show in Footer </th> + [% may_share = user.in_group(Param('querysharegroup')) && queryshare_groups.size %] + [% IF may_share %] + <th> + Share With a Group + </th> + [% END %] </tr> <tr> - <td>My [% terms.Bugs %]</td> + <td>My Bugs</td> <td> [% filtered_username = user.login FILTER url_quote %] <a href="[% Param('mybugstemplate').replace('%userid%', filtered_username) %]">Run</a> @@ -59,18 +70,24 @@ value="1" [% " checked" IF user.showmybugslink %]> </td> + [% IF may_share %] + <td> + — + </td> + [% END %] </tr> - [% FOREACH q = queries %] + [% FOREACH q = user.queries %] <tr> <td>[% q.name FILTER html %]</td> <td> <a href="buglist.cgi?cmdtype=runnamed&namedcmd=[% q.name FILTER url_quote %]">Run</a> </td> <td> - <a href="query.cgi?[% q.query FILTER html %]&known_name=[% q.name FILTER url_quote %]">Edit</a> + <a href="query.cgi?[% q.edit_link FILTER html %]&known_name= + [% q.name FILTER url_quote %]">Edit</a> </td> <td> - [% IF q.usedinwhine %] + [% IF q.used_in_whine %] Remove from <a href="editwhines.cgi">whining</a> first [% ELSE %] <a href="buglist.cgi?cmdtype=dorem&remaction=forget&namedcmd= @@ -79,9 +96,72 @@ </td> <td align="center"> <input type="checkbox" - name="linkinfooter_[% q.name FILTER html %]" + name="link_in_footer_[% q.id FILTER html %]" + value="1" + alt="[% q.name FILTER html %]" + [% " checked" IF q.link_in_footer %]> + </td> + [% IF may_share %] + <td> + <select name="share_[% q.id FILTER html %]"> + <option value="">Don't share</option> + [% FOREACH group = queryshare_groups %] + <option value="[% group.id %]" + [% ' selected="selected"' + IF q.shared_with_group.id == group.id %] + >[% group.name FILTER html %]</option> + [% END %] + </select> + </td> + [% END %] + </tr> + [% END %] + </table> +</blockquote> + +<p>You may use these searches saved and shared by others:</p> + +<blockquote> + <table border="1" cellpadding="3"> + <tr> + <th> + Search + </th> + <th> + Shared By + </th> + <th> + Run + </th> + <th> + Show in + Footer + </th> + </tr> + [% found_shared_query = 0 %] + [% FOREACH q = user.queries_available %] + [% found_shared_query = 1 %] + <tr> + <td>[% q.name FILTER html %]</td> + <td>[% q.user.identity FILTER html %]</td> + <td> + <a href="buglist.cgi?cmdtype=dorem&remaction=run&namedcmd= + [% q.name FILTER url_quote %]&sharer_id= + [% q.user.id FILTER url_quote %]">Run</a> + </td> + <td align="center"> + <input type="checkbox" + name="link_in_footer_[% q.id FILTER html %]" value="1" - [% " checked" IF q.linkinfooter %]> + alt="[% q.name FILTER html %]" + [% " checked" IF q.link_in_footer %]> + </td> + </tr> + [% END %] + [% IF !found_shared_query %] + <tr> + <td colspan="4" style="text-align: center"> + <None> </td> </tr> [% END %] diff --git a/template/en/default/account/prefs/settings.html.tmpl b/template/en/default/account/prefs/settings.html.tmpl index c47615dd9..568dac0cb 100644 --- a/template/en/default/account/prefs/settings.html.tmpl +++ b/template/en/default/account/prefs/settings.html.tmpl @@ -35,7 +35,7 @@ <p class="criticalmessages"> All user preferences have been disabled by the <a href="mailto:[% Param("maintainer") %]">maintainer</a> - of this installation, and so you cannot customize any. + of this installation, and so you cannot customise any. </p> [% END %] diff --git a/template/en/default/account/profile-activity.html.tmpl b/template/en/default/account/profile-activity.html.tmpl new file mode 100644 index 000000000..fe8f9fb20 --- /dev/null +++ b/template/en/default/account/profile-activity.html.tmpl @@ -0,0 +1,86 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # The Initial Developer of the Original Code is Netscape Communications + # Corporation. Portions created by Netscape are + # Copyright (C) 1998 Netscape Communications Corporation. All + # Rights Reserved. + # + # Contributor(s): Vlad Dascalu <jocuri@softhome.net> + # Gavin Shelley <bugzilla@chimpychompy.org> + #%] + +[%# INTERFACE: + # otheruser: Bugzilla User Object; The user whose profile activity + # we are viewing. + # + # listselectionvalues: selection values to recreate the current user list. + # + # profile_changes: An array of hashes containing the following fields: + # + # who: string; login name of who made the change + # activity_when: string; when the change was made + # what: string; the description of the field which was changed + # removed: string; the removed value (maybe empty string) + # added: string; the added value (maybe empty string) + #%] + +[% title = BLOCK %] + View User Account Log for '[% otheruser.login FILTER html %]' +[% END %] + + +[% PROCESS global/header.html.tmpl + title = title +%] + +[% PROCESS admin/users/listselectvars.html.tmpl + listselectionvalues = listselectionvalues +%] + +[% columns = + [{name => 'who' + heading => 'Who' + } + {name => 'activity_when' + heading => 'When' + } + {name => 'what' + heading => 'What' + } + {name => 'removed' + heading => 'Removed' + } + {name => 'added' + heading => 'Added' + } + ] +%] + +[% PROCESS admin/table.html.tmpl + columns = columns + data = profile_changes +%] + +<p><a href="editusers.cgi?action=edit&userid= + [%- otheruser.id FILTER url_quote %]" + title="Edit user '[% otheruser.login FILTER html %]'">Edit this user</a> or + <a title="Search For Users" href="editusers.cgi">find other accounts</a> + [% IF listselectionvalues.matchtype != 'exact' %] + or go <a title="Return to the user list" + href="editusers.cgi?action=list[% INCLUDE listselectionurlparams %]">back + to the user list</a> + [% END %] +</p> + +[% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/admin/CVS/Entries b/template/en/default/admin/CVS/Entries index e0b56b71f..f1c178dfb 100644 --- a/template/en/default/admin/CVS/Entries +++ b/template/en/default/admin/CVS/Entries @@ -1,8 +1,9 @@ -/confirm-action.html.tmpl/1.1.2.1/Sat Oct 14 22:05:55 2006//TBUGZILLA-2_22_3 -/sudo.html.tmpl/1.3/Sun Nov 20 01:31:36 2005//TBUGZILLA-2_22_3 -/table.html.tmpl/1.6.2.2/Sat Oct 14 20:30:55 2006//TBUGZILLA-2_22_3 +/confirm-action.html.tmpl/1.1/Sat Oct 14 22:02:10 2006//TBUGZILLA-3_0 +/sudo.html.tmpl/1.5/Tue Oct 17 19:58:35 2006//TBUGZILLA-3_0 +/table.html.tmpl/1.8/Sat Oct 14 20:26:51 2006//TBUGZILLA-3_0 D/classifications//// D/components//// +D/custom_fields//// D/fieldvalues//// D/flag-type//// D/groups//// diff --git a/template/en/default/admin/CVS/Tag b/template/en/default/admin/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/admin/CVS/Tag +++ b/template/en/default/admin/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/admin/classifications/CVS/Entries b/template/en/default/admin/classifications/CVS/Entries index e0a982aae..07d4909e9 100644 --- a/template/en/default/admin/classifications/CVS/Entries +++ b/template/en/default/admin/classifications/CVS/Entries @@ -1,9 +1,9 @@ -/add.html.tmpl/1.1.10.1/Sat Oct 14 22:05:56 2006//TBUGZILLA-2_22_3 -/del.html.tmpl/1.3.2.2/Sat Oct 14 22:05:56 2006//TBUGZILLA-2_22_3 -/delete.html.tmpl/1.2/Thu Oct 13 23:42:43 2005//TBUGZILLA-2_22_3 -/edit.html.tmpl/1.6.2.2/Sat Oct 14 22:05:56 2006//TBUGZILLA-2_22_3 -/new.html.tmpl/1.2/Mon Dec 27 09:58:29 2004//TBUGZILLA-2_22_3 -/reclassify.html.tmpl/1.4.2.2/Sat Oct 14 22:05:56 2006//TBUGZILLA-2_22_3 -/select.html.tmpl/1.5.2.1/Sat Oct 14 20:30:55 2006//TBUGZILLA-2_22_3 -/update.html.tmpl/1.1/Fri Aug 20 21:49:18 2004//TBUGZILLA-2_22_3 +/add.html.tmpl/1.4/Sat Oct 14 22:02:10 2006//TBUGZILLA-3_0 +/del.html.tmpl/1.7/Sun Jan 7 23:51:53 2007//TBUGZILLA-3_0 +/delete.html.tmpl/1.2/Thu Oct 13 23:42:43 2005//TBUGZILLA-3_0 +/edit.html.tmpl/1.10/Sat Oct 14 22:02:10 2006//TBUGZILLA-3_0 +/new.html.tmpl/1.2/Mon Dec 27 09:58:29 2004//TBUGZILLA-3_0 +/reclassify.html.tmpl/1.7/Sat Oct 14 22:02:10 2006//TBUGZILLA-3_0 +/select.html.tmpl/1.7/Sat Oct 14 20:26:51 2006//TBUGZILLA-3_0 +/update.html.tmpl/1.2/Sun Jul 16 23:23:33 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/admin/classifications/CVS/Tag b/template/en/default/admin/classifications/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/admin/classifications/CVS/Tag +++ b/template/en/default/admin/classifications/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/admin/classifications/add.html.tmpl b/template/en/default/admin/classifications/add.html.tmpl index a2134e52b..d549bbc79 100644 --- a/template/en/default/admin/classifications/add.html.tmpl +++ b/template/en/default/admin/classifications/add.html.tmpl @@ -31,7 +31,19 @@ </tr> <tr> <th align="right">Description:</th> - <td><textarea rows=4 cols=64 wrap=virtual name="description"></textarea></td> + <td> + [% INCLUDE global/textarea.html.tmpl + name = 'description' + minrows = 4 + cols = 64 + wrap = 'virtual' + %] + </td> + </tr> + <tr> + <th align="right"><label for="sortkey">Sortkey:</label></th> + <td><input id="sortkey" size="20" maxlength="20" name="sortkey" + value=""></td> </tr> </table> <hr> diff --git a/template/en/default/admin/classifications/del.html.tmpl b/template/en/default/admin/classifications/del.html.tmpl index 9fc1b0cf5..9b726a880 100644 --- a/template/en/default/admin/classifications/del.html.tmpl +++ b/template/en/default/admin/classifications/del.html.tmpl @@ -42,12 +42,16 @@ [% END %] </td> +</tr><tr> + <td valign="top">Sortkey:</td> + <td valign="top">[% classification.sortkey FILTER html %]</td> + </tr> </table> <h2>Confirmation</h2> -<p>Do you really want to delete this classification?<p> +<p>Do you really want to delete this classification?</p> <form method=post action="editclassifications.cgi"> <input type=submit value="Yes, delete"> <input type=hidden name="action" value="delete"> @@ -56,6 +60,6 @@ </form> <p>Back to the <a href="./">main [% terms.bugs %] page</a> -or <a href="editclassifications.cgi"> edit</a> more classifications. +or <a href="editclassifications.cgi"> edit</a> more classifications.</p> [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/admin/classifications/edit.html.tmpl b/template/en/default/admin/classifications/edit.html.tmpl index 77af7f8a9..923a79f5e 100644 --- a/template/en/default/admin/classifications/edit.html.tmpl +++ b/template/en/default/admin/classifications/edit.html.tmpl @@ -32,10 +32,20 @@ </tr> <tr> <th align="right">Description:</th> - <td><textarea rows=4 cols=64 name="description"> - [% classification.description FILTER html %]</textarea> + <td> + [% INCLUDE global/textarea.html.tmpl + name = 'description' + minrows = 4 + cols = 64 + defaultcontent = classification.description + %] </td> </tr> + <tr> + <th align="right"><label for="sortkey">Sortkey:</label></th> + <td><input id="sortkey" size="20" maxlength="20" name="sortkey" value=" + [%- classification.sortkey FILTER html %]"></td> + </tr> <tr valign=top> <th align="right"> <a href="editproducts.cgi?classification=[% classification.name FILTER url_quote %]"> diff --git a/template/en/default/admin/classifications/reclassify.html.tmpl b/template/en/default/admin/classifications/reclassify.html.tmpl index 830a01ad6..113c6f630 100644 --- a/template/en/default/admin/classifications/reclassify.html.tmpl +++ b/template/en/default/admin/classifications/reclassify.html.tmpl @@ -39,6 +39,10 @@ [% END %] </td> + </tr><tr> + <td valign="top">Sortkey:</td> + <td valign="top" colspan=3>[% classification.sortkey FILTER html %]</td> + </tr><tr> <td valign="top">Products:</td> <td valign="top">Products</td> diff --git a/template/en/default/admin/classifications/select.html.tmpl b/template/en/default/admin/classifications/select.html.tmpl index 616f8445b..fd3aaf45d 100644 --- a/template/en/default/admin/classifications/select.html.tmpl +++ b/template/en/default/admin/classifications/select.html.tmpl @@ -27,6 +27,7 @@ <tr bgcolor="#6666ff"> <th align="left">Edit Classification ...</th> <th align="left">Description</th> + <th align="left">Sortkey</th> <th align="left">Products</th> <th align="left">Action</th> </tr> @@ -41,6 +42,7 @@ <font color="red">none</font> [% END %] </td> + <td valign="top">[% cl.sortkey FILTER html %]</td> [% IF (cl.id == 1) %] <td valign="top">[% cl.product_count FILTER html %]</td> [% ELSE %] @@ -57,7 +59,7 @@ [% END %] <tr> - <td valign="top" colspan=3>Add a new classification</td> + <td valign="top" colspan=4>Add a new classification</td> <td valign="top" align="center"><a href="editclassifications.cgi?action=add">Add</a></td> </tr> </table> diff --git a/template/en/default/admin/classifications/update.html.tmpl b/template/en/default/admin/classifications/update.html.tmpl index 3ad7bbc69..68ce27755 100644 --- a/template/en/default/admin/classifications/update.html.tmpl +++ b/template/en/default/admin/classifications/update.html.tmpl @@ -23,6 +23,10 @@ title = "Update classification" %] +[% IF updated_sortkey %] + Updated sortkey.<br> +[% END %] + [% IF updated_description %] Updated description.<br> [% END %] diff --git a/template/en/default/admin/components/CVS/Entries b/template/en/default/admin/components/CVS/Entries index be351c94d..dca3d1af1 100644 --- a/template/en/default/admin/components/CVS/Entries +++ b/template/en/default/admin/components/CVS/Entries @@ -1,10 +1,10 @@ -/confirm-delete.html.tmpl/1.4.2.2/Sat Oct 14 22:05:56 2006//TBUGZILLA-2_22_3 -/create.html.tmpl/1.4.2.1/Sat Oct 14 22:05:56 2006//TBUGZILLA-2_22_3 -/created.html.tmpl/1.1/Fri Jul 30 22:16:38 2004//TBUGZILLA-2_22_3 -/deleted.html.tmpl/1.3/Wed Apr 6 00:19:54 2005//TBUGZILLA-2_22_3 -/edit.html.tmpl/1.5.2.2/Thu May 10 11:15:30 2007//TBUGZILLA-2_22_3 -/footer.html.tmpl/1.1/Fri Jul 30 22:16:38 2004//TBUGZILLA-2_22_3 -/list.html.tmpl/1.4/Tue Sep 27 22:08:13 2005//TBUGZILLA-2_22_3 -/select-product.html.tmpl/1.2/Tue Sep 27 22:08:13 2005//TBUGZILLA-2_22_3 -/updated.html.tmpl/1.2.4.1/Sat Oct 14 20:30:55 2006//TBUGZILLA-2_22_3 +/confirm-delete.html.tmpl/1.9/Sun Jan 7 23:52:12 2007//TBUGZILLA-3_0 +/create.html.tmpl/1.11/Thu Dec 28 18:20:07 2006//TBUGZILLA-3_0 +/created.html.tmpl/1.2/Wed Mar 1 22:10:23 2006//TBUGZILLA-3_0 +/deleted.html.tmpl/1.4/Wed Mar 1 22:10:23 2006//TBUGZILLA-3_0 +/edit.html.tmpl/1.11/Thu Dec 28 18:20:07 2006//TBUGZILLA-3_0 +/footer.html.tmpl/1.3/Sun Jan 7 23:52:36 2007//TBUGZILLA-3_0 +/list.html.tmpl/1.5/Wed Mar 1 22:10:23 2006//TBUGZILLA-3_0 +/select-product.html.tmpl/1.3/Sun Jan 7 23:59:50 2007//TBUGZILLA-3_0 +/updated.html.tmpl/1.7/Sun Jan 7 23:53:03 2007//TBUGZILLA-3_0 D diff --git a/template/en/default/admin/components/CVS/Tag b/template/en/default/admin/components/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/admin/components/CVS/Tag +++ b/template/en/default/admin/components/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/admin/components/confirm-delete.html.tmpl b/template/en/default/admin/components/confirm-delete.html.tmpl index 4ec8d9bf5..4ba73d08b 100644 --- a/template/en/default/admin/components/confirm-delete.html.tmpl +++ b/template/en/default/admin/components/confirm-delete.html.tmpl @@ -22,11 +22,11 @@ [%# INTERFACE: # comp: object; Bugzilla::Component object representing the component the # user wants to delete. - # prod: object; Bugzilla::Product object representing the product to + # product: object; Bugzilla::Product object representing the product to # which the component belongs. #%] -[% title = BLOCK %]Delete Component of Product '[% prod.name FILTER html %]' +[% title = BLOCK %]Delete Component of Product '[% product.name FILTER html %]' [% END %] [% PROCESS global/header.html.tmpl @@ -60,13 +60,13 @@ </tr> <tr> <td valign="top">Component of Product:</td> - <td valign="top">[% prod.name FILTER html %]</td> + <td valign="top">[% product.name FILTER html %]</td> -[% IF prod.description %] +[% IF product.description %] </tr> <tr> <td valign="top">Product Description:</td> - <td valign="top">[% prod.description FILTER html_light %]</td> + <td valign="top">[% product.description FILTER html_light %]</td> [% END %] [% IF Param('usetargetmilestone') %] @@ -74,8 +74,8 @@ <tr> <td valign="top">Product Milestone URL:</td> <td valign="top"> - <a href="[% prod.milestone_url FILTER uri %]"> - [% prod.milestone_url FILTER html %] + <a href="[% product.milestone_url FILTER uri %]"> + [% product.milestone_url FILTER html %] </a> </td> [% END %] @@ -83,7 +83,7 @@ </tr> <tr> <TD VALIGN="top">Closed for [% terms.bugs %]:</TD> - <TD VALIGN="top">[% IF prod.disallow_new %]Yes[% ELSE %]No[% END %]</td> + <TD VALIGN="top">[% IF product.disallow_new %]Yes[% ELSE %]No[% END %]</td> </tr> <tr> <td valign="top">[% terms.Bugs %]:</td> @@ -91,7 +91,7 @@ [% IF comp.bug_count %] <a title="List of [% terms.bugs %] for component '[% comp.name FILTER html %]'" href="buglist.cgi?component=[% comp.name FILTER url_quote %]&product= - [%- prod.name FILTER url_quote %]">[% comp.bug_count %]</a> + [%- product.name FILTER url_quote %]">[% comp.bug_count %]</a> [% ELSE %] None [% END %] @@ -104,7 +104,7 @@ [% IF comp.bug_count %] [% IF !Param("allowbugdeletion") %] - + <p> Sorry, there [% IF comp.bug_count > 1 %] @@ -122,7 +122,7 @@ [% END %] to another component before you can delete this one. - + </p> [% ELSE %] <table border="0" cellpadding="20" width="70%" bgcolor="red"><tr><td> @@ -143,21 +143,18 @@ [% IF comp.bug_count == 0 || Param('allowbugdeletion') %] - <p>Do you really want to delete this component?<p> + <p>Do you really want to delete this component?</p> <form method="post" action="editcomponents.cgi"> - <input type="submit" value="Yes, delete"> + <input type="submit" id="delete" value="Yes, delete"> <input type="hidden" name="action" value="delete"> - <input type="hidden" name="product" value="[% prod.name FILTER html %]"> + <input type="hidden" name="product" value="[% product.name FILTER html %]"> <input type="hidden" name="component" value="[% comp.name FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]"> </form> [% END %] -[% PROCESS admin/components/footer.html.tmpl - name = comp.name - product = prod.name -%] +[% PROCESS admin/components/footer.html.tmpl %] [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/admin/components/create.html.tmpl b/template/en/default/admin/components/create.html.tmpl index 0e5c924b4..5b376bc79 100644 --- a/template/en/default/admin/components/create.html.tmpl +++ b/template/en/default/admin/components/create.html.tmpl @@ -17,18 +17,20 @@ # Rights Reserved. # # Contributor(s): Gavin Shelley <bugzilla@chimpychompy.org> + # Akamai Technologies <bugzilla-dev@akamai.com> #%] [%# INTERFACE: - # product: string; name of product + # product: object; Bugzilla::Product object representing the product to + # which the component belongs. #%] -[% title = BLOCK %]Add component to Product '[% product FILTER html %]'[% END %] -[% h2 = BLOCK %]This page allows you to add a new component to product - '[% product FILTER html %]'.[% END %] +[% title = BLOCK %]Add component to Product '[% product.name FILTER html %]'[% END %] +[% subheader = BLOCK %]This page allows you to add a new component to product + '[% product.name FILTER html %]'.[% END %] [% PROCESS global/header.html.tmpl title = title - h2 = h2 + subheader = subheader %] <form method="post" action="editcomponents.cgi"> @@ -40,8 +42,12 @@ <tr> <th align="right">Description:</th> <td> - <textarea rows="4" cols="64" wrap="virtual" - name="description"></textarea> + [% INCLUDE global/textarea.html.tmpl + name = 'description' + minrows = 4 + cols = 64 + wrap = 'virtual' + %] </td> </tr> <tr> @@ -71,13 +77,31 @@ </td> </tr> [% END %] + <tr> + <th align="right"> + <label for="initialcc">Default CC List:</label> + </th> + <td> + [% INCLUDE global/userselect.html.tmpl + name => "initialcc" + id => "initialcc" + value => "" + size => 64 + multiple => 5 + %] + <br> + [% IF !Param("usemenuforusers") %] + <em>Enter user names for the CC list as a comma-separated list.</em> + [% END %] + </td> + </tr> </table> <hr> - <input type="submit" value="Add"> + <input type="submit" id="create" value="Add"> <input type="hidden" name="action" value="new"> <input type="hidden" name='open_name' value='All Open'> <input type="hidden" name='nonopen_name' value='All Closed'> - <input type="hidden" name='product' value="[% product FILTER html %]"> + <input type="hidden" name='product' value="[% product.name FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]"> </form> diff --git a/template/en/default/admin/components/created.html.tmpl b/template/en/default/admin/components/created.html.tmpl index 54963065d..090cfd87e 100644 --- a/template/en/default/admin/components/created.html.tmpl +++ b/template/en/default/admin/components/created.html.tmpl @@ -20,20 +20,21 @@ #%] [%# INTERFACE: - # name: string; the name of the newly created component - # - # product: string; the name of the product the component belongs to + # comp: object; Bugzilla::Component object representing the component the + # user created. + # product: object; Bugzilla::Product object representing the product to + # which the component belongs. #%] [% title = BLOCK %]Adding new Component of Product - '[% product FILTER html %]'[% END %] + '[% product.name FILTER html %]'[% END %] [% PROCESS global/header.html.tmpl title = title %] <p>The component '<a href="editcomponents.cgi?action=edit&product= - [%- product FILTER url_quote %]&component=[% name FILTER url_quote %]"> - [%- name FILTER html %]</a>' has been created.</p> + [%- product.name FILTER url_quote %]&component=[% comp.name FILTER url_quote %]"> + [%- comp.name FILTER html %]</a>' has been created.</p> [% PROCESS admin/components/footer.html.tmpl %] diff --git a/template/en/default/admin/components/deleted.html.tmpl b/template/en/default/admin/components/deleted.html.tmpl index 83c006869..2b89ac0f3 100644 --- a/template/en/default/admin/components/deleted.html.tmpl +++ b/template/en/default/admin/components/deleted.html.tmpl @@ -20,27 +20,25 @@ #%] [%# INTERFACE: - # name: string; the name of the deleted component. - # - # product: string; the name of the product the component belonged to - # - # deleted_bug_count: number; the number of bugs which were deleted - # (if bug deletion is allowed) + # comp: object; Bugzilla::Component object representing the component the + # user deleted. + # product: object; Bugzilla::Product object representing the product to + # which the component belongs. #%] -[% title = BLOCK %]Deleted Component '[% name FILTER html %]' from Product - '[% product FILTER html %]'[% END %] +[% title = BLOCK %]Deleted Component '[% comp.name FILTER html %]' from Product + '[% product.name FILTER html %]'[% END %] [% PROCESS global/header.html.tmpl title = title %] <p> -[% IF deleted_bug_count %] - [% deleted_bug_count %] - [%- IF deleted_bug_count > 1 %] - [% terms.bugs %] +[% IF comp.bug_count %] + [% comp.bug_count FILTER none %] + [%- IF comp.bug_count > 1 %] + [%+ terms.bugs %] [% ELSE %] - [% terms.bug %] + [%+ terms.bug %] [% END %] deleted. </p><p> @@ -52,7 +50,7 @@ <p>Flag inclusions and exclusions deleted.</p> -<p>Component '[% name FILTER html %]' deleted.</p> +<p>Component '[% comp.name FILTER html %]' deleted.</p> [% PROCESS admin/components/footer.html.tmpl no_edit_component_link = 1 diff --git a/template/en/default/admin/components/edit.html.tmpl b/template/en/default/admin/components/edit.html.tmpl index d2ae789ca..e7bd96355 100644 --- a/template/en/default/admin/components/edit.html.tmpl +++ b/template/en/default/admin/components/edit.html.tmpl @@ -17,12 +17,13 @@ # Rights Reserved. # # Contributor(s): Gavin Shelley <bugzilla@chimpychompy.org> + # Akamai Technologies <bugzilla-dev@akamai.com> #%] [%# INTERFACE: # comp: object; Bugzilla::Component object representing the component the # user wants to edit. - # prod: object; Bugzilla::Product object representing the product to + # product: object; Bugzilla::Product object representing the product to # which the component belongs. #%] @@ -43,8 +44,14 @@ </tr> <tr> <td valign="top">Component Description:</td> - <td><textarea rows="4" cols="64" wrap="virtual" - name="description">[% comp.description FILTER html %]</textarea> + <td> + [% INCLUDE global/textarea.html.tmpl + name = 'description' + minrows = 4 + cols = 64 + wrap = 'virtual' + defaultcontent = comp.description + %] </td> </tr> <tr> @@ -75,14 +82,32 @@ [% END %] </tr> + <tr> + <td valign="top"> + <label for="initialcc">Default CC List:</label> + </td> + <td> + [% INCLUDE global/userselect.html.tmpl + name => "initialcc" + id => "initialcc" + value => initial_cc_names + size => 64 + multiple => 5 + %] + <br> + [% IF !Param("usemenuforusers") %] + <em>Enter user names for the CC list as a comma-separated list.</em> + [% END %] + </td> + </tr> <tr> <td>[% terms.Bugs %]:</td> <td> [% IF comp.bug_count > 0 %] - <a title="[% terms.Bugs %] in component '[% comp.name FILTER html %]'" + <a title="Bugs in component '[% comp.name FILTER html %]'" href="buglist.cgi?component= [%- comp.name FILTER url_quote %]&product= - [%- prod.name FILTER url_quote %]">[% comp.bug_count %]</a> + [%- product.name FILTER url_quote %]">[% comp.bug_count %]</a> [% ELSE %] None [% END %] @@ -93,19 +118,17 @@ <input type="hidden" name="action" value="update"> <input type="hidden" name="componentold" value="[% comp.name FILTER html %]"> - <input type="hidden" name="product" value="[% prod.name FILTER html %]"> + <input type="hidden" name="product" value="[% product.name FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]"> - <input type="submit" value="Update"> or <a + <input type="submit" value="Update" id="update"> or <a href="editcomponents.cgi?action=del&product= - [%- prod.name FILTER url_quote %]&component= + [%- product.name FILTER url_quote %]&component= [%- comp.name FILTER url_quote %]">Delete</a> this component. </form> [% PROCESS admin/components/footer.html.tmpl no_edit_component_link = 1 - name = comp.name - product = prod.name %] [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/admin/components/footer.html.tmpl b/template/en/default/admin/components/footer.html.tmpl index 1f58622ae..c5fd789ce 100644 --- a/template/en/default/admin/components/footer.html.tmpl +++ b/template/en/default/admin/components/footer.html.tmpl @@ -20,37 +20,36 @@ #%] [%# INTERFACE: - # name: string; the name of the component - # - # product: string; the name of the product which the component - # belongs/belonged to + # comp: object; Bugzilla::Component object representing the component + # product: object; Bugzilla::Product object representing the product to + # which the component belongs. #%] - -<p> <hr> + +<p> Edit -[% IF name && !no_edit_component_link %] +[% IF comp && !no_edit_component_link %] component <a - title="Edit Component '[% name FILTER html %]'" + title="Edit Component '[% comp.name FILTER html %]'" href="editcomponents.cgi?action=edit&product= - [%- product FILTER url_quote %]&component=[% name FILTER url_quote %]"> - '[% name FILTER html %]'</a> + [%- product.name FILTER url_quote %]&component=[% comp.name FILTER url_quote %]"> + '[% comp.name FILTER html %]'</a> or edit [% END %] [% IF !no_edit_other_components_link %] other components of product <a - title="Choose a component from product '[% product FILTER html %]' to edit" + title="Choose a component from product '[% product.name FILTER html %]' to edit" href="editcomponents.cgi?product= - [%- product FILTER url_quote %]">'[% product FILTER html %]'</a>, + [%- product.name FILTER url_quote %]">'[% product.name FILTER html %]'</a>, or edit [% END %] product <a - title="Edit Product '[% product FILTER html %]'" + title="Edit Product '[% product.name FILTER html %]'" href="editproducts.cgi?action=edit&product= - [%- product FILTER url_quote %]">'[% product FILTER html %]'</a>. + [%- product.name FILTER url_quote %]">'[% product.name FILTER html %]'</a>. </p> diff --git a/template/en/default/admin/components/list.html.tmpl b/template/en/default/admin/components/list.html.tmpl index 0b4998679..c0862eb73 100644 --- a/template/en/default/admin/components/list.html.tmpl +++ b/template/en/default/admin/components/list.html.tmpl @@ -21,25 +21,25 @@ #%] [%# INTERFACE: - # components: array of component objects # showbugcounts: if defined, then bug counts should be included in the table - # product: string; the name of the product we are editing components for + # product: object; Bugzilla::Product object representing the product to + # which the component belongs. #%] [% PROCESS global/variables.none.tmpl %] [% title = BLOCK %]Select component of product - '[% product FILTER html %]'[% END %] + '[% product.name FILTER html %]'[% END %] [% PROCESS global/header.html.tmpl title = title %] [% edit_contentlink = BLOCK %]editcomponents.cgi?action=edit&product= - [%- product FILTER url_quote %]&component=%%name%%[% END %] + [%- product.name FILTER url_quote %]&component=%%name%%[% END %] [% delete_contentlink = BLOCK %]editcomponents.cgi?action=del&product= - [%- product FILTER url_quote %]&component=%%name%%[% END %] + [%- product.name FILTER url_quote %]&component=%%name%%[% END %] [% bug_count_contentlink = BLOCK %]buglist.cgi?component=%%name%%&product= - [%- product FILTER url_quote %][% END %] + [%- product.name FILTER url_quote %][% END %] [% columns = [ @@ -90,7 +90,7 @@ [% overrides.initialowner = [] %] [% overrides.initialqacontact = [] %] -[% FOREACH component = components %] +[% FOREACH component = product.components %] [% overrides.initialowner.push({ match_value => component.name match_field => 'name' @@ -109,16 +109,16 @@ [% PROCESS admin/table.html.tmpl columns = columns - data = components + data = product.components overrides = overrides %] -<p><a href="editcomponents.cgi?action=add&product=[% product FILTER url_quote %]">Add</a> - a new component to product '[% product FILTER html %]'</p> +<p><a href="editcomponents.cgi?action=add&product=[% product.name FILTER url_quote %]">Add</a> + a new component to product '[% product.name FILTER html %]'</p> [% IF ! showbugcounts %] - <p><a href="editcomponents.cgi?product=[% product FILTER url_quote %]&showbugcounts=1"> + <p><a href="editcomponents.cgi?product=[% product.name FILTER url_quote %]&showbugcounts=1"> Redisplay table with [% terms.bug %] counts (slower)</a></p> [% END %] diff --git a/template/en/default/admin/components/select-product.html.tmpl b/template/en/default/admin/components/select-product.html.tmpl index ea9342dcd..5be48fec8 100644 --- a/template/en/default/admin/components/select-product.html.tmpl +++ b/template/en/default/admin/components/select-product.html.tmpl @@ -68,6 +68,4 @@ Redisplay table with [% terms.bug %] counts (slower)</a></p> [% END %] -<p> - [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/admin/components/updated.html.tmpl b/template/en/default/admin/components/updated.html.tmpl index e4501a850..3a07a7728 100644 --- a/template/en/default/admin/components/updated.html.tmpl +++ b/template/en/default/admin/components/updated.html.tmpl @@ -17,50 +17,57 @@ # Rights Reserved. # # Contributor(s): Gavin Shelley <bugzilla@chimpychompy.org> + # Akamai Technologies <bugzilla-dev@akamai.com> + # Max Kanat-Alexander <mkanat@bugzilla.org> #%] [%# INTERFACE: # # 'updated_XXX' variables are booleans, and are defined if the # 'XXX' field was updated during the edit just being handled. - # Variables called just 'XXX' are strings, and are the _new_ contents - # of the fields. # - # name & updated_name: the name of the component + # updated_name: the name of the component updated # - # description & updated_description: the component description + # updated_description: the component description updated # - # initialowner & updated_initialowner: the default assignee + # updated_initialowner: the default assignee updated # - # initialqacontact & updated_initialqacontact: the default qa contact + # updated_initialqacontact: the default qa contact updated # - # product: string; the name of the product the component belongs to + # updated_initialcc: the default initial cc list + # + # comp: object; Bugzilla::Component object representing the component + # user updated. + # product: object; Bugzilla::Product object representing the product to + # which the component belongs. + # + # initial_cc_names: a comma-separated list of the login names of + # the Initial CC, if it was updated. #%] -[% title = BLOCK %]Updating Component '[% name FILTER html %]' of Product - '[% product FILTER html %]'[% END %] +[% title = BLOCK %]Updating Component '[% comp.name FILTER html %]' of Product + '[% product.name FILTER html %]'[% END %] [% PROCESS global/header.html.tmpl title = title %] [% IF updated_description %] - <p> <table> <tr> <td>Updated description to:</td> - <td>'[% description FILTER html_light %]'</td> + <td>'[% comp.description FILTER html_light %]'</td> </tr> </table> [% END %] [% IF updated_initialowner %] - <p>Updated Default Assignee to: '[% initialowner FILTER html %]'.</p> + <p>Updated Default Assignee to: '[% comp.default_assignee.login FILTER html %]'.</p> [% END %] [% IF updated_initialqacontact %] <p> - [% IF initialqacontact %] - Updated Default QA Contact to '[% initialqacontact FILTER html %]'. + [% IF comp.default_qa_contact.id %] + Updated Default QA Contact to '[% comp.default_qa_contact.login FILTER html %]'. [% ELSE %] Removed Default QA Contact. [% END %] @@ -68,14 +75,23 @@ [% END %] [% IF updated_name %] - <p>Updated Component name to: '[% name FILTER html %]'.</p> + <p>Updated Component name to: '[% comp.name FILTER html %]'.</p> +[% END %] + +[% IF updated_initialcc %] + [% IF initial_cc_names %] + <p>Updated Default CC list to: + '[% initial_cc_names FILTER html %]'.</p> + [% ELSE %] + <p>Removed the Default CC list.</p> + [% END %] [% END %] [% UNLESS updated_description || updated_initialowner || - updated_initialqacontact || updated_name %] - <p>Nothing changed for component '[% name FILTER html %]'. + updated_initialqacontact || updated_name || + updated_initialcc %] + <p>Nothing changed for component '[% comp.name FILTER html %]'.</p> [% END %] - [% PROCESS admin/components/footer.html.tmpl %] diff --git a/template/en/default/admin/custom_fields/CVS/Entries b/template/en/default/admin/custom_fields/CVS/Entries new file mode 100644 index 000000000..cb7870532 --- /dev/null +++ b/template/en/default/admin/custom_fields/CVS/Entries @@ -0,0 +1,4 @@ +/create.html.tmpl/1.6/Tue Dec 26 18:01:07 2006//TBUGZILLA-3_0 +/edit.html.tmpl/1.4/Sat Oct 14 22:02:10 2006//TBUGZILLA-3_0 +/list.html.tmpl/1.3/Tue Nov 14 01:18:37 2006//TBUGZILLA-3_0 +D diff --git a/template/en/default/admin/custom_fields/CVS/Repository b/template/en/default/admin/custom_fields/CVS/Repository new file mode 100644 index 000000000..9252b96af --- /dev/null +++ b/template/en/default/admin/custom_fields/CVS/Repository @@ -0,0 +1 @@ +mozilla/webtools/bugzilla/template/en/default/admin/custom_fields diff --git a/template/en/default/admin/custom_fields/CVS/Root b/template/en/default/admin/custom_fields/CVS/Root new file mode 100644 index 000000000..cdb6f4a07 --- /dev/null +++ b/template/en/default/admin/custom_fields/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot diff --git a/template/en/default/admin/custom_fields/CVS/Tag b/template/en/default/admin/custom_fields/CVS/Tag new file mode 100644 index 000000000..efdc1ff3e --- /dev/null +++ b/template/en/default/admin/custom_fields/CVS/Tag @@ -0,0 +1 @@ +NBUGZILLA-3_0 diff --git a/template/en/default/admin/custom_fields/create.html.tmpl b/template/en/default/admin/custom_fields/create.html.tmpl new file mode 100644 index 000000000..3fdb20f43 --- /dev/null +++ b/template/en/default/admin/custom_fields/create.html.tmpl @@ -0,0 +1,114 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + #%] + +[%# INTERFACE: + # none + #%] + +[% PROCESS "global/field-descs.none.tmpl" %] + +[% PROCESS global/header.html.tmpl + title = "Add a new Custom Field" + onload = "document.getElementById('new_bugmail').disabled = true;" %] + +<script type="text/javascript"> + <!-- + // Disable a checkbox based on the state of another one. + function toggleCheckbox(this_checkbox, other_checkbox_id) { + var other_checkbox = document.getElementById(other_checkbox_id); + other_checkbox.disabled = !this_checkbox.checked; + } + //--> +</script> + +<p> + Adding custom fields can make the interface of [% terms.Bugzilla %] very + complicated. Many admins who are new to [% terms.Bugzilla %] start off + adding many custom fields, and then their users complain that the interface + is "too complex". Please think carefully before adding any custom fields. + It may be the case that [% terms.Bugzilla %] already does what you need, + and you just haven't enabled the correct feature yet. +</p> + +<ul> + <li>Custom field names must begin with "cf_" to distinguish them from + standard fields. If you omit "cf_" from the beginning of the name, it + will be added for you.</li> + <li>Descriptions are a very short string describing the field and will be + used as the label for this field in the user interface.</li> +</ul> + +<form id="add_field" action="editfields.cgi" method="GET"> + <table border="0" cellspacing="0" cellpadding="5"> + <tr> + <th align="right"><label for="name">Name:</label></th> + <td> + <input type="text" id="name" name="name" value="cf_" size="40" maxlength="64"> + </td> + + <th align="right"> + <label for="enter_bug">Can be set on [% terms.bug %] creation:</label> + </th> + <td> + <input type="checkbox" id="enter_bug" name="enter_bug" value="1" + onchange="toggleCheckbox(this, 'new_bugmail');"> + </td> + </tr> + <tr> + <th align="right"><label for="desc">Description:</label></th> + <td><input type="text" id="desc" name="desc" value="" size="40"></td> + + <th align="right"> + <label for="new_bugmail">Displayed in bugmail for new [% terms.bugs %]:</label> + </th> + <td><input type="checkbox" id="new_bugmail" name="new_bugmail" value="1"></td> + </tr> + <tr> + <th align="right"><label for="type">Type:</label></th> + <td> + <select id="type" name="type"> + [% FOREACH type = field_types.keys %] + [% NEXT IF type == constants.FIELD_TYPE_UNKNOWN %] + <option value="[% type FILTER html %]">[% field_types.$type FILTER html %]</option> + [% END %] + </select> + </td> + + <th align="right"><label for="obsolete">Is obsolete:</label></th> + <td><input type="checkbox" id="obsolete" name="obsolete" value="1"></td> + </tr> + <tr> + <th align="right"><label for="sortkey">Sortkey:</label></th> + <td> + <input type="text" id="sortkey" name="sortkey" size="6" maxlength="6"> + </td> + + <th> </th> + <td> </td> + </tr> + </table> + <p> + <input type="hidden" name="action" value="new"> + <input type="hidden" name="token" value="[% token FILTER html %]"> + <input type="submit" id="create" value="Create"> + </p> +</form> + +<p> + <a href="editfields.cgi">Back to the list of existing custom fields</a> +</p> + +[% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/admin/custom_fields/edit.html.tmpl b/template/en/default/admin/custom_fields/edit.html.tmpl new file mode 100644 index 000000000..2165ac323 --- /dev/null +++ b/template/en/default/admin/custom_fields/edit.html.tmpl @@ -0,0 +1,109 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + #%] + +[%# INTERFACE: + # none + #%] + +[% PROCESS "global/field-descs.none.tmpl" %] + +[% title = BLOCK %] + Edit the Custom Field '[% field.name FILTER html %]' ([% field.description FILTER html %]) +[% END %] + +[% PROCESS global/header.html.tmpl + title = title + onload = "toggleCheckbox(document.getElementById('enter_bug'), 'new_bugmail');" %] + +<script type="text/javascript"> + <!-- + // Disable a checkbox based on the state of another one. + function toggleCheckbox(this_checkbox, other_checkbox_id) { + var other_checkbox = document.getElementById(other_checkbox_id); + other_checkbox.disabled = !this_checkbox.checked; + } + //--> +</script> + +<p> + Descriptions are a very short string describing the field and will be used as + the label for this field in the user interface. +</p> + +<form id="edit_field" action="editfields.cgi" method="GET"> + <table border="0" cellspacing="0" cellpadding="5"> + <tr> + <th align="right">Name:</th> + <td>[% field.name FILTER html %]</td> + + <th align="right"> + <label for="enter_bug">Can be set on [% terms.bug %] creation:</label> + </th> + <td><input type="checkbox" id="enter_bug" name="enter_bug" value="1" + [%- " checked" IF field.enter_bug %] + onchange="toggleCheckbox(this, 'new_bugmail');"></td> + </tr> + <tr> + <th align="right"><label for="desc">Description:</label></th> + <td><input type="text" id="desc" name="desc" size="40" + value="[% field.description FILTER html %]"></td> + + <th align="right"> + <label for="new_bugmail">Displayed in bugmail for new [% terms.bugs %]:</label> + </th> + <td><input type="checkbox" id="new_bugmail" name="new_bugmail" value="1" + [%- " checked" IF field.mailhead %]></td> + </tr> + <tr> + <th align="right">Type:</th> + <td>[% field_types.${field.type} FILTER html %]</td> + + <th align="right"><label for="obsolete">Is obsolete:</label></th> + <td><input type="checkbox" id="obsolete" name="obsolete" value="1" + [%- " checked" IF field.obsolete %]></td> + </tr> + <tr> + <th align="right"><label for="sortkey">Sortkey:</label></th> + <td> + <input type="text" id="sortkey" name="sortkey" size="6" maxlength="6" + value="[% field.sortkey FILTER html %]"> + </td> + + <th> </th> + <td> </td> + </tr> + [% IF field.type == constants.FIELD_TYPE_SINGLE_SELECT %] + <tr> + <th> </th> + <td colspan="3"> + <a href="editvalues.cgi?field=[% field.name FILTER url_quote %]">Edit + legal values for this field</a>. + </td> + </tr> + [% END %] + </table> + <br> + <input type="hidden" name="action" value="update"> + <input type="hidden" name="name" value="[% field.name FILTER html %]"> + <input type="hidden" name="token" value="[% token FILTER html %]"> + <input type="submit" id="edit" value="Submit"> +</form> + +<p> + <a href="editfields.cgi">Back to the list of existing custom fields</a> +</p> + +[% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/admin/custom_fields/list.html.tmpl b/template/en/default/admin/custom_fields/list.html.tmpl new file mode 100644 index 000000000..befd15753 --- /dev/null +++ b/template/en/default/admin/custom_fields/list.html.tmpl @@ -0,0 +1,84 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + #%] + +[%# INTERFACE: + # custom_fields: a list of Bugzilla::Field objects, representing custom fields. + #%] + +[% PROCESS "global/field-descs.none.tmpl" %] + +[% PROCESS global/header.html.tmpl title = "Custom Fields" %] + +[% columns = [ + { + name => "name" + heading => "Edit custom field..." + contentlink => "editfields.cgi?action=edit&name=%%name%%" + }, + { + name => "description" + heading => "Description" + }, + { + name => "sortkey" + heading => "Sortkey" + }, + { + name => "type" + heading => "Type" + }, + { + name => "enter_bug" + heading => "Editable on Bug Creation" + }, + { + name => "mailhead" + heading => "In Bugmail on Bug Creation" + }, + { + name => "obsolete" + heading => "Is Obsolete" + } + ] +%] + +[% USE Bugzilla %] +[% custom_fields = Bugzilla.get_fields({ custom => 1 }) %] + +[%# We want to display the type name of fields, not their type ID. %] +[% overrides.type = [] %] + +[% FOREACH field_type = field_types.keys %] + [% overrides.type.push({ + match_value => field_type + match_field => 'type' + override_content => 1 + content => field_types.${field_type} + }) + %] +[% END %] + +[% PROCESS admin/table.html.tmpl + columns = columns + overrides = overrides + data = custom_fields +%] + +<p> + <a href="editfields.cgi?action=add">Add a new custom field</a> +</p> + +[% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/admin/fieldvalues/CVS/Entries b/template/en/default/admin/fieldvalues/CVS/Entries index 46f8d4cf3..f544de94b 100644 --- a/template/en/default/admin/fieldvalues/CVS/Entries +++ b/template/en/default/admin/fieldvalues/CVS/Entries @@ -1,10 +1,10 @@ -/confirm-delete.html.tmpl/1.4.2.1/Sat Oct 14 22:05:56 2006//TBUGZILLA-2_22_3 -/create.html.tmpl/1.2.4.1/Sat Oct 14 22:05:56 2006//TBUGZILLA-2_22_3 -/created.html.tmpl/1.3/Wed Jun 15 03:55:00 2005//TBUGZILLA-2_22_3 -/deleted.html.tmpl/1.2/Wed Jun 15 03:55:00 2005//TBUGZILLA-2_22_3 -/edit.html.tmpl/1.3.2.1/Sat Oct 14 22:05:56 2006//TBUGZILLA-2_22_3 -/footer.html.tmpl/1.3/Wed Jun 15 03:55:00 2005//TBUGZILLA-2_22_3 -/list.html.tmpl/1.3/Wed Oct 19 22:21:05 2005//TBUGZILLA-2_22_3 -/select-field.html.tmpl/1.2/Wed Jun 15 03:55:00 2005//TBUGZILLA-2_22_3 -/updated.html.tmpl/1.3/Wed Oct 19 22:21:05 2005//TBUGZILLA-2_22_3 +/confirm-delete.html.tmpl/1.7/Sat Oct 14 22:02:11 2006//TBUGZILLA-3_0 +/create.html.tmpl/1.6/Mon Jan 8 00:00:23 2007//TBUGZILLA-3_0 +/created.html.tmpl/1.4/Mon Jan 8 00:00:45 2007//TBUGZILLA-3_0 +/deleted.html.tmpl/1.3/Mon Jan 8 00:01:04 2007//TBUGZILLA-3_0 +/edit.html.tmpl/1.7/Sun Jan 7 23:46:37 2007//TBUGZILLA-3_0 +/footer.html.tmpl/1.4/Sun Jan 7 23:47:13 2007//TBUGZILLA-3_0 +/list.html.tmpl/1.6/Sun Jan 7 23:53:50 2007//TBUGZILLA-3_0 +/select-field.html.tmpl/1.3/Sun Jan 7 23:54:10 2007//TBUGZILLA-3_0 +/updated.html.tmpl/1.4/Sun Jan 7 23:54:33 2007//TBUGZILLA-3_0 D diff --git a/template/en/default/admin/fieldvalues/CVS/Tag b/template/en/default/admin/fieldvalues/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/admin/fieldvalues/CVS/Tag +++ b/template/en/default/admin/fieldvalues/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/admin/fieldvalues/confirm-delete.html.tmpl b/template/en/default/admin/fieldvalues/confirm-delete.html.tmpl index 7ee946d37..4cd001476 100644 --- a/template/en/default/admin/fieldvalues/confirm-delete.html.tmpl +++ b/template/en/default/admin/fieldvalues/confirm-delete.html.tmpl @@ -61,13 +61,13 @@ <h2>Confirmation</h2> -[% IF (Param(param_name) == value) || bug_count || (value_count == 1) %] +[% IF (param_name.defined && Param(param_name) == value) || bug_count || (value_count == 1) %] <p>Sorry, but the '[% value FILTER html %]' value cannot be deleted from the '[% field FILTER html %]' field for the following reason(s):</p> <ul class="warningmessages"> - [% IF Param(param_name) == value %] + [% IF param_name.defined && Param(param_name) == value %] <li>'[% value FILTER html %]' is the default value for the '[% field FILTER html %]' field. [% IF user.groups.tweakparams %] @@ -107,7 +107,7 @@ <p>Do you really want to delete this value?</p> <form method="post" action="editvalues.cgi"> - <input type="submit" value="Yes, delete"> + <input type="submit" value="Yes, delete" id="delete"> <input type="hidden" name="action" value="delete"> <input type="hidden" name="field" value="[% field FILTER html %]"> <input type="hidden" name="value" value="[% value FILTER html %]"> diff --git a/template/en/default/admin/fieldvalues/create.html.tmpl b/template/en/default/admin/fieldvalues/create.html.tmpl index 0bec8c28b..29bf85778 100644 --- a/template/en/default/admin/fieldvalues/create.html.tmpl +++ b/template/en/default/admin/fieldvalues/create.html.tmpl @@ -19,11 +19,11 @@ #%] [% title = BLOCK %]Add Value for the '[% field FILTER html %]' field[% END %] -[% h2 = BLOCK %]This page allows you to add a new value for the +[% subheader = BLOCK %]This page allows you to add a new value for the '[% field FILTER html %]' field.[% END %] [% PROCESS global/header.html.tmpl title = title - h2 = h2 + subheader = subheader %] <form method="post" action="editvalues.cgi"> @@ -39,14 +39,12 @@ value=""></td> </tr> </table> - <input type="submit" value="Add"> + <input type="submit" id="create" value="Add"> <input type="hidden" name="action" value="new"> <input type="hidden" name='field' value="[% field FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]"> </form> -<p> - [% PROCESS admin/fieldvalues/footer.html.tmpl no_add_link = 1 %] diff --git a/template/en/default/admin/fieldvalues/created.html.tmpl b/template/en/default/admin/fieldvalues/created.html.tmpl index d4e4734bb..218477103 100644 --- a/template/en/default/admin/fieldvalues/created.html.tmpl +++ b/template/en/default/admin/fieldvalues/created.html.tmpl @@ -32,8 +32,6 @@ [%- value FILTER html %]</a>' has been added as a valid choice for the '[% field FILTER html %]' field.</p> -<p> - [% PROCESS admin/fieldvalues/footer.html.tmpl %] [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/admin/fieldvalues/deleted.html.tmpl b/template/en/default/admin/fieldvalues/deleted.html.tmpl index d5483bcc0..c966897f6 100644 --- a/template/en/default/admin/fieldvalues/deleted.html.tmpl +++ b/template/en/default/admin/fieldvalues/deleted.html.tmpl @@ -29,8 +29,6 @@ <p>Field Value '[% value FILTER html %]' deleted.</p> -<p> - [% PROCESS admin/fieldvalues/footer.html.tmpl no_edit_link = 1 %] diff --git a/template/en/default/admin/fieldvalues/edit.html.tmpl b/template/en/default/admin/fieldvalues/edit.html.tmpl index 145f6a8a5..e19b7c0b5 100644 --- a/template/en/default/admin/fieldvalues/edit.html.tmpl +++ b/template/en/default/admin/fieldvalues/edit.html.tmpl @@ -33,8 +33,15 @@ <tr> <th valign="top"><label for="value">Field Value:</label></th> - <td><input id="value" size="20" maxlength="60" name="value" value=" - [%- value FILTER html %]"></td> + <td> + [% IF is_static %] + <input type="hidden" name="value" value="[% value FILTER html %]"> + [% value FILTER html %] + [% ELSE %] + <input id="value" size="20" maxlength="60" name="value" value=" + [%- value FILTER html %]"> + [% END %] + </td> </tr> <tr> <th align="right"><label for="sortkey">Sortkey:</label></th> @@ -49,11 +56,9 @@ <input type="hidden" name="action" value="update"> <input type="hidden" name="field" value="[% field FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]"> - <input type="submit" value="Update"> + <input type="submit" id="update" value="Update"> </form> -<p> - [% PROCESS admin/fieldvalues/footer.html.tmpl no_edit_link = 1 %] diff --git a/template/en/default/admin/fieldvalues/footer.html.tmpl b/template/en/default/admin/fieldvalues/footer.html.tmpl index f7b522f28..27428f66d 100644 --- a/template/en/default/admin/fieldvalues/footer.html.tmpl +++ b/template/en/default/admin/fieldvalues/footer.html.tmpl @@ -26,11 +26,11 @@ # no_edit_other_link # no_add_link #%] - -<p> <hr> +<p> + [% UNLESS no_add_link %] <a title="Add a value for the '[% field FILTER html %]' field." href="editvalues.cgi?action=add&field= @@ -50,7 +50,7 @@ Edit other values for the <a href="editvalues.cgi?field= [%- field FILTER url_quote %]">'[% field FILTER html %]'</a> field. - + [% END %] </p> diff --git a/template/en/default/admin/fieldvalues/list.html.tmpl b/template/en/default/admin/fieldvalues/list.html.tmpl index d25adf2b1..9e3da3c64 100644 --- a/template/en/default/admin/fieldvalues/list.html.tmpl +++ b/template/en/default/admin/fieldvalues/list.html.tmpl @@ -21,6 +21,7 @@ # displayed to the user in a list. # # field: string; the name of the field we are editing values for. + # static: array; list of values which cannot be renamed nor deleted. #%] [% USE Bugzilla %] @@ -58,15 +59,35 @@ } ] %] -[% overrides.action = [ { - match_value => "$default" - match_field => 'name' - override_content => 1 - content => "(Default value)" - override_contentlink => 1 - contentlink => undef - } ] -%] +[% IF default.defined %] + [% overrides.action = [ { + match_value => "$default" + match_field => 'name' + override_content => 1 + content => "(Default value)" + override_contentlink => 1 + contentlink => undef + } ] + %] +[% END %] + +[% IF static.size %] + [% UNLESS overrides.action.size %] + [% overrides.action = [] %] + [% END %] + + [% FOREACH static_value = static %] + [% overrides.action.push({ + match_value => "$static_value" + match_field => 'name' + override_content => 1 + content => "(Non-deletable value)" + override_contentlink => 1 + contentlink => undef + }) + %] + [% END %] +[% END %] [% PROCESS admin/table.html.tmpl columns = columns @@ -74,8 +95,6 @@ overrides = overrides %] -<p> - [% PROCESS admin/fieldvalues/footer.html.tmpl no_edit_other_link = 1 %] diff --git a/template/en/default/admin/fieldvalues/select-field.html.tmpl b/template/en/default/admin/fieldvalues/select-field.html.tmpl index f4ffcdf6d..fa9f82af7 100644 --- a/template/en/default/admin/fieldvalues/select-field.html.tmpl +++ b/template/en/default/admin/fieldvalues/select-field.html.tmpl @@ -45,6 +45,4 @@ data = fields %] -<p> - [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/admin/fieldvalues/updated.html.tmpl b/template/en/default/admin/fieldvalues/updated.html.tmpl index c7f676e67..7b76abb63 100644 --- a/template/en/default/admin/fieldvalues/updated.html.tmpl +++ b/template/en/default/admin/fieldvalues/updated.html.tmpl @@ -47,10 +47,8 @@ [% END %] [% UNLESS (updated_sortkey || updated_value) %] - <p>Nothing changed for field value '[% value FILTER html %]'. + <p>Nothing changed for field value '[% value FILTER html %]'.</p> [% END %] - -<p> [% PROCESS admin/fieldvalues/footer.html.tmpl %] diff --git a/template/en/default/admin/flag-type/CVS/Entries b/template/en/default/admin/flag-type/CVS/Entries index 4decc09a1..9576794b6 100644 --- a/template/en/default/admin/flag-type/CVS/Entries +++ b/template/en/default/admin/flag-type/CVS/Entries @@ -1,4 +1,4 @@ -/confirm-delete.html.tmpl/1.5.12.1/Sat Oct 14 22:05:56 2006//TBUGZILLA-2_22_3 -/edit.html.tmpl/1.14.2.3/Sat Oct 14 22:05:56 2006//TBUGZILLA-2_22_3 -/list.html.tmpl/1.10.6.1/Sat Oct 14 22:05:56 2006//TBUGZILLA-2_22_3 +/confirm-delete.html.tmpl/1.7/Sat Oct 14 22:02:11 2006//TBUGZILLA-3_0 +/edit.html.tmpl/1.22/Sat Oct 14 22:02:11 2006//TBUGZILLA-3_0 +/list.html.tmpl/1.16/Sat Oct 14 22:02:11 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/admin/flag-type/CVS/Tag b/template/en/default/admin/flag-type/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/admin/flag-type/CVS/Tag +++ b/template/en/default/admin/flag-type/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/admin/flag-type/confirm-delete.html.tmpl b/template/en/default/admin/flag-type/confirm-delete.html.tmpl index e67412a1c..0af9fb5a2 100644 --- a/template/en/default/admin/flag-type/confirm-delete.html.tmpl +++ b/template/en/default/admin/flag-type/confirm-delete.html.tmpl @@ -26,7 +26,7 @@ [% PROCESS global/header.html.tmpl title = title %] <p> - There are [% flag_count %] flags of type [% flag_type.name FILTER html %]. + There are [% flag_type.flag_count %] flags of type [% flag_type.name FILTER html %]. If you delete this type, those flags will also be deleted. Note that instead of deleting the type you can <a href="editflagtypes.cgi?action=deactivate&id=[% flag_type.id %]&token= @@ -44,7 +44,7 @@ <tr> <td> <a href="editflagtypes.cgi?action=delete&id=[% flag_type.id %]&token= - [%- token FILTER html %]">Yes, delete + [%- token FILTER html %]">Yes, delete </a> </td> <td align="right"> diff --git a/template/en/default/admin/flag-type/edit.html.tmpl b/template/en/default/admin/flag-type/edit.html.tmpl index e0abf0df5..e78c83643 100644 --- a/template/en/default/admin/flag-type/edit.html.tmpl +++ b/template/en/default/admin/flag-type/edit.html.tmpl @@ -22,17 +22,7 @@ [% PROCESS global/variables.none.tmpl %] -[%# The javascript block gets used in header.html.tmpl. %] -[% javascript = BLOCK %] - var usetms = 0; // do we have target milestone? - var first_load = 1; // is this the first time we load the page? - var last_sel = []; // caches last selection - var cpts = new Array(); - [% FOREACH p = products %] - cpts['[% p FILTER js %]'] = [ - [%- FOREACH item = components_by_product.$p %]'[% item FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; - [% END %] -[% END %] +[% PROCESS "global/js-products.html.tmpl" %] [% IF type.target_type == "bug" %] [% title = BLOCK %]Create Flag Type for [% terms.Bugs %][% END %] @@ -90,7 +80,12 @@ <th>Description:</th> <td> a comprehensive description of this type<br> - <textarea name="description" rows="4" cols="80">[% type.description FILTER html %]</textarea> + [% INCLUDE global/textarea.html.tmpl + name = 'description' + minrows = 4 + cols = 80 + defaultcontent = type.description + %] </td> </tr> @@ -107,18 +102,18 @@ <b>Product/Component:</b><br> <select name="product" onchange="selectProduct(this.form, 'product', 'component', '__Any__');"> <option value="">__Any__</option> - [% FOREACH item = products %] - <option value="[% item FILTER html %]" - [% "selected" IF type.product.name == item %]> - [% item FILTER html %]</option> + [% FOREACH prod = products %] + <option value="[% prod.name FILTER html %]" + [% "selected" IF type.product.name == prod.name %]> + [% prod.name FILTER html %]</option> [% END %] </select><br> <select name="component"> <option value="">__Any__</option> - [% FOREACH item = components %] - <option value="[% item FILTER html %]" - [% "selected" IF type.component.name == item %]> - [% item FILTER html %]</option> + [% FOREACH comp = components %] + <option value="[% comp FILTER html %]" + [% "selected" IF type.component.name == comp %]> + [% comp FILTER html %]</option> [% END %] </select><br> <input type="submit" name="categoryAction-include" value="Include"> @@ -202,7 +197,7 @@ <td> the group allowed to grant/deny flags of this type (to allow all users to grant/deny these flags, select no group)<br> - [% PROCESS select selname = "grant_gid" %] + [% PROCESS select selname = "grant_group" %] </td> </tr> @@ -212,14 +207,14 @@ if flags of this type are requestable, the group allowed to request them (to allow all users to request these flags, select no group)<br> Note that the request group alone has no effect if the grant group is not defined!<br> - [% PROCESS select selname = "request_gid" %] + [% PROCESS select selname = "request_group" %] </td> </tr> <tr> <th></th> <td> - <input type="submit" value=" + <input type="submit" id="save" value=" [%- IF (last_action == "enter" || last_action == "copy") %]Create [%- ELSE %]Save Changes [%- END %]"> @@ -242,7 +237,8 @@ <option value="">(no group)</option> [% FOREACH group = groups %] <option value="[% group.name FILTER html %]" - [% " selected" IF type.${selname} == group.name %]>[% group.name FILTER html %] + [% " selected" IF (type.${selname} && type.${selname}.name == group.name) %]> + [%- group.name FILTER html %] </option> [% END %] </select> diff --git a/template/en/default/admin/flag-type/list.html.tmpl b/template/en/default/admin/flag-type/list.html.tmpl index a94e59c9e..3346f9570 100644 --- a/template/en/default/admin/flag-type/list.html.tmpl +++ b/template/en/default/admin/flag-type/list.html.tmpl @@ -21,12 +21,18 @@ [% PROCESS global/variables.none.tmpl %] +[% PROCESS "global/js-products.html.tmpl" %] + [% PROCESS global/header.html.tmpl title = 'Administer Flag Types' style = " - table#flag_types tr th { text-align: left; } + table#flag_types_bugs tr th, + table#flag_types_attachments tr th { text-align: left; } .inactive { color: #787878; } + .multiplicable { display: block; } " + onload="selectProduct(document.forms[0], 'product', 'component', '__All__');" + javascript_urls=["productmenu.js"] %] <p> @@ -43,9 +49,45 @@ depending on whether the patch passed or failed review. </p> +<p> + You can restrict the list of flag types to those available for a given product + and component. If a product is selected with no component, only flag types + which are available to at least one component of the product are shown. +</p> + +<form action="editflagtypes.cgi" method="get"> + <table> + <tr> + <th><label for="product">Product:</label></th> + <td> + <select name="product" onchange="selectProduct(this.form, 'product', 'component', '__Any__');"> + <option value="">__Any__</option> + [% FOREACH prod = products %] + <option value="[% prod.name FILTER html %]" + [% " selected" IF selected_product == prod.name %]> + [% prod.name FILTER html %]</option> + [% END %] + </select> + </td> + <th><label for="component">Component:</label></th> + <td> + <select name="component"> + <option value="">__Any__</option> + [% FOREACH comp = components %] + <option value="[% comp FILTER html %]" + [% " selected" IF selected_component == comp %]> + [% comp FILTER html %]</option> + [% END %] + </select> + </td> + <td><input type="submit" id="submit" value="Filter"></td> + </tr> + </table> +</form> + <h3>Flag Types for [% terms.Bugs %]</h3> -[% PROCESS display_flag_types types=bug_types %] +[% PROCESS display_flag_types types=bug_types types_id='bugs' %] <p> <a href="editflagtypes.cgi?action=enter&target_type=bug">Create Flag Type for [% terms.Bugs %]</a> @@ -53,7 +95,7 @@ <h3>Flag Types for Attachments</h3> -[% PROCESS display_flag_types types=attachment_types %] +[% PROCESS display_flag_types types=attachment_types types_id='attachments' %] <p> <a href="editflagtypes.cgi?action=enter&target_type=attachment">Create Flag Type For Attachments</a> @@ -63,11 +105,15 @@ [% BLOCK display_flag_types %] - <table id="flag_types" cellspacing="0" cellpadding="4" border="1"> + <table id="flag_types_[% types_id FILTER html %]" cellspacing="0" cellpadding="4" border="1"> <tr> <th>Edit name ...</th> <th>Description</th> + <th>Sortkey</th> + <th>Properties</th> + <th>Grant group</th> + <th>Request group</th> <th>Actions</th> </tr> @@ -76,6 +122,20 @@ <tr class="[% IF type.is_active %]active[% ELSE %]inactive[% END %]"> <td><a href="editflagtypes.cgi?action=edit&id=[% type.id %]">[% type.name FILTER html FILTER no_break %]</a></td> <td>[% type.description FILTER html %]</td> + <td align="right">[% type.sortkey FILTER html %]</td> + <td> + [% IF type.is_requestable %] + <span class="requestable">requestable</span> + [% END %] + [% IF type.is_requestable && type.is_requesteeble %] + <span class="requesteeble">(specifically)</span> + [% END %] + [% IF type.is_multiplicable %] + <span class="multiplicable">multiplicable</span> + [% END %] + </td> + <td>[% IF type.grant_group %][% type.grant_group.name FILTER html %][% END %]</td> + <td>[% IF type.request_group %][% type.request_group.name FILTER html %][% END %]</td> <td> <a href="editflagtypes.cgi?action=copy&id=[% type.id %]">Copy</a> | <a href="editflagtypes.cgi?action=confirmdelete&id=[% type.id %]">Delete</a> diff --git a/template/en/default/admin/groups/CVS/Entries b/template/en/default/admin/groups/CVS/Entries index 85287af01..a8dc04377 100644 --- a/template/en/default/admin/groups/CVS/Entries +++ b/template/en/default/admin/groups/CVS/Entries @@ -1,9 +1,9 @@ -/change.html.tmpl/1.1.10.1/Mon Jun 19 18:27:25 2006//TBUGZILLA-2_22_3 -/create.html.tmpl/1.4.10.1/Sat Oct 14 22:05:57 2006//TBUGZILLA-2_22_3 -/created.html.tmpl/1.1/Tue Jul 13 05:12:32 2004//TBUGZILLA-2_22_3 -/delete.html.tmpl/1.6.2.2/Sat Oct 14 22:05:57 2006//TBUGZILLA-2_22_3 -/deleted.html.tmpl/1.2.2.1/Fri Sep 29 20:05:27 2006//TBUGZILLA-2_22_3 -/edit.html.tmpl/1.5.6.3/Sat Oct 14 22:05:57 2006//TBUGZILLA-2_22_3 -/list.html.tmpl/1.4.2.4/Mon Oct 30 23:51:53 2006//TBUGZILLA-2_22_3 -/remove.html.tmpl/1.1.10.1/Sat Oct 14 20:50:43 2006//TBUGZILLA-2_22_3 +/change.html.tmpl/1.2/Mon Jun 19 18:27:04 2006//TBUGZILLA-3_0 +/create.html.tmpl/1.8/Tue Oct 17 19:58:36 2006//TBUGZILLA-3_0 +/created.html.tmpl/1.1/Tue Jul 13 05:12:32 2004//TBUGZILLA-3_0 +/delete.html.tmpl/1.10/Sat Oct 14 22:02:11 2006//TBUGZILLA-3_0 +/deleted.html.tmpl/1.3/Wed Mar 8 23:53:56 2006//TBUGZILLA-3_0 +/edit.html.tmpl/1.11/Sun Jan 7 23:54:59 2007//TBUGZILLA-3_0 +/list.html.tmpl/1.11/Mon Oct 30 23:49:48 2006//TBUGZILLA-3_0 +/remove.html.tmpl/1.2/Sat Oct 14 20:48:47 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/admin/groups/CVS/Tag b/template/en/default/admin/groups/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/admin/groups/CVS/Tag +++ b/template/en/default/admin/groups/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/admin/groups/create.html.tmpl b/template/en/default/admin/groups/create.html.tmpl index 18c08fc48..fb255304c 100644 --- a/template/en/default/admin/groups/create.html.tmpl +++ b/template/en/default/admin/groups/create.html.tmpl @@ -28,7 +28,7 @@ [% PROCESS global/header.html.tmpl title = "Add group" - h2 = "This page allows you to define a new user group." + subheader = "This page allows you to define a new user group." %] <form method="post" action="editgroups.cgi"> @@ -47,15 +47,16 @@ <input type="checkbox" name="insertnew" value="1" [% IF Param("makeproductgroups") %] checked[% END %]> Insert new group into all existing products.<p> - <input type="submit" value="Add"> + <input type="submit" id="create" value="Add"> <input type="hidden" name="action" value="new"> <input type="hidden" name="token" value="[% token FILTER html %]"> </form> -<p><b>Name</b> is what is used with the UserInGroup() function in any -customized cgi files you write that use a given group. It can also be used -by people submitting [% terms.bugs %] by email to limit [% terms.abug %] to -a certain set of groups. It may not contain any spaces.</p> +<p><b>Name</b> is what is used with the B<!-- blah -->ugzilla->user->in_group() +function in any customized cgi files you write that use a given group. +It can also be used by people submitting [% terms.bugs %] by email to +limit [% terms.abug %] to a certain set of groups. It may not contain +any spaces.</p> <p><b>Description</b> is what will be shown in the [% terms.bug %] reports to members of the group where they can choose whether diff --git a/template/en/default/admin/groups/delete.html.tmpl b/template/en/default/admin/groups/delete.html.tmpl index 24c051987..22701407a 100644 --- a/template/en/default/admin/groups/delete.html.tmpl +++ b/template/en/default/admin/groups/delete.html.tmpl @@ -30,6 +30,7 @@ # hasbugs: boolean int. True if the group includes bugs in it. # hasproduct: boolean int. True if the group is binded to a product. # hasflags: boolean int. True if the group is used by a flag type. + # shared_queries: int. Number of saved searches being shared with this group. # buglist: string. The list of bugs included in this group. #%] @@ -92,6 +93,25 @@ flag types from this group for me.</p> [% END %] + [% IF shared_queries %] + <p> + <b>There + [% IF shared_queries > 1 %] + are [% shared_queries %] saved searches + [% ELSE %] + is a saved search + [% END %] + being shared with this group.</b> + If you delete this group, + [% IF shared_queries > 1 %] + these saved searches + [% ELSE %] + this saved search + [% END %] + will fall back to being private again. + </p> + [% END %] + <h2>Confirmation</h2> <p>Do you really want to delete this group?</p> @@ -100,7 +120,7 @@ indicated problems first before you can proceed.</b></p> [% END %] - <p><input type="submit" value="Yes, delete"> + <p><input type="submit" id="delete" value="Yes, delete"> <input type="hidden" name="action" value="delete"> <input type="hidden" name="group" value="[% gid FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]"> diff --git a/template/en/default/admin/groups/edit.html.tmpl b/template/en/default/admin/groups/edit.html.tmpl index f323c600e..6f333f5c3 100644 --- a/template/en/default/admin/groups/edit.html.tmpl +++ b/template/en/default/admin/groups/edit.html.tmpl @@ -100,8 +100,7 @@ [% END %] </table> - <p> - Users become members of this group in one of three ways: + <p>Users become members of this group in one of three ways:</p> <ul> <li> by being explicity included when the user is edited. <li> by matching the user regexp above. @@ -153,6 +152,11 @@ <input type="checkbox" name="grp-[% group.grpid FILTER html %]" [% group.grpmember ? "checked " : "" %]value="1"> <input type="hidden" name="oldgrp-[% group.grpid FILTER html %]" value="[% group.grpmember FILTER html %]"> </td> + <td align="left" class="groupname"> + <a href="[% "editgroups.cgi?action=changeform&group=${group.grpid}" FILTER html %]"> + [% group.grpnam FILTER html %] + </a> + </td> [% ELSE %] <td> <input type="hidden" name="oldbless-[% group.grpid FILTER html %]" value="0"> @@ -160,18 +164,18 @@ <td> <input type="hidden" name="oldgrp-[% group.grpid FILTER html %]" value="0"> </td> + <td align="left" class="groupname"> + <em> + [% group.grpnam FILTER html %] + </em> + </td> [% END %] - <td align="left" class="groupname"> - <a href="[% "editgroups.cgi?action=changeform&group=${group.grpid}" FILTER html %]"> - [% group.grpnam FILTER html %] - </a> - </td> <td align="left" class="groupdesc">[% group.grpdesc FILTER html_light %]</td> </tr> [% END %] </table> - - <input type="submit" value="Save Changes"> + + <input type="submit" id="update" value="Save Changes"> <br> <dl> [% IF usevisibility %] @@ -197,7 +201,7 @@ <td> <h4>Conversion of groups created with [% terms.Bugzilla %] versions 2.16 and prior:</h4> - + <ul> <li>Remove all explicit memberships from this group: <input name="remove_explicit_members" type="submit" id="remove_explicit_members" value="Remove Memberships"> @@ -217,6 +221,6 @@ <input type="hidden" name="token" value="[% token FILTER html %]"> </form> -Back to the <a href="editgroups.cgi">group list</a>. +<p>Back to the <a href="editgroups.cgi">group list</a>.</p> [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/admin/groups/list.html.tmpl b/template/en/default/admin/groups/list.html.tmpl index 82bd592fd..617bbd3c1 100644 --- a/template/en/default/admin/groups/list.html.tmpl +++ b/template/en/default/admin/groups/list.html.tmpl @@ -34,7 +34,7 @@ [% PROCESS global/header.html.tmpl title = "Edit Groups" - h2 = "This lets you edit the groups available to put users in." + subheader = "This lets you edit the groups available to put users in." %] [% edit_contentlink = "editgroups.cgi?action=changeform&group=%%id%%" %] @@ -102,6 +102,12 @@ override_content => 1 content => "(used as the 'timetrackinggroup')" }, + { + match_value => Param("querysharegroup") + match_field => 'name' + override_content => 1 + content => "(used as the 'querysharegroup')" + }, { match_value => "1" match_field => 'isbuggroup' @@ -133,10 +139,10 @@ <p><a href="editgroups.cgi?action=add">Add Group</a></p> <p> - <b>Name</b> is what is used with the UserInGroup() function in any -customized cgi files you write that use a given group. It can also be used -by people submitting [% terms.bugs %] by email to limit [% terms.abug %] -to a certain set of groups. + <b>Name</b> is what is used with the B<!-- blah -->ugzilla->user->in_group() +function in any customized cgi files you write that use a given group. +It can also be used by people submitting [% terms.bugs %] by email to +limit [% terms.abug %] to a certain set of groups. </p> <p> diff --git a/template/en/default/admin/groups/remove.html.tmpl b/template/en/default/admin/groups/remove.html.tmpl index b79d7e68b..8c41333e4 100644 --- a/template/en/default/admin/groups/remove.html.tmpl +++ b/template/en/default/admin/groups/remove.html.tmpl @@ -42,7 +42,7 @@ [% END %] [% END %] -[% PROCESS global/header.html.tmpl title = title %] +[% PROCESS global/header.html.tmpl %] [% IF remove_all %] <p><b>Removing explicit membership</b></p> diff --git a/template/en/default/admin/keywords/CVS/Entries b/template/en/default/admin/keywords/CVS/Entries index f42357c13..51e90351a 100644 --- a/template/en/default/admin/keywords/CVS/Entries +++ b/template/en/default/admin/keywords/CVS/Entries @@ -1,7 +1,7 @@ -/confirm-delete.html.tmpl/1.3.12.1/Sat Oct 14 22:05:57 2006//TBUGZILLA-2_22_3 -/create.html.tmpl/1.4.12.1/Sat Oct 14 22:05:57 2006//TBUGZILLA-2_22_3 -/created.html.tmpl/1.2/Sun Jan 18 18:39:15 2004//TBUGZILLA-2_22_3 -/edit.html.tmpl/1.4.2.1/Sat Oct 14 22:05:57 2006//TBUGZILLA-2_22_3 -/list.html.tmpl/1.7.2.2/Thu May 10 11:15:30 2007//TBUGZILLA-2_22_3 -/rebuild-cache.html.tmpl/1.3/Sun Jan 18 18:39:15 2004//TBUGZILLA-2_22_3 +/confirm-delete.html.tmpl/1.6/Sat Oct 14 22:02:11 2006//TBUGZILLA-3_0 +/create.html.tmpl/1.8/Tue Oct 17 19:58:36 2006//TBUGZILLA-3_0 +/created.html.tmpl/1.2/Sun Jan 18 18:39:15 2004//TBUGZILLA-3_0 +/edit.html.tmpl/1.8/Sat Oct 14 22:02:11 2006//TBUGZILLA-3_0 +/list.html.tmpl/1.9/Sat Oct 14 20:26:52 2006//TBUGZILLA-3_0 +/rebuild-cache.html.tmpl/1.4/Tue Sep 5 19:18:26 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/admin/keywords/CVS/Tag b/template/en/default/admin/keywords/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/admin/keywords/CVS/Tag +++ b/template/en/default/admin/keywords/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/admin/keywords/confirm-delete.html.tmpl b/template/en/default/admin/keywords/confirm-delete.html.tmpl index 3329a5473..0d68524d7 100755 --- a/template/en/default/admin/keywords/confirm-delete.html.tmpl +++ b/template/en/default/admin/keywords/confirm-delete.html.tmpl @@ -18,12 +18,11 @@ # # Contributor(s): Terry Weissman <terry@mozilla.org> # Vlad Dascalu <jocuri@softhome.net> + # Max Kanat-Alexander <mkanat@bugzilla.org> #%] [%# INTERFACE: - # name: string. The name of the keyword. - # keyword_id: number. The ID of the keyword. - # bug_count: number. The number of bugs with the keyword. + # keyword: A Bugzilla::Keyword object. #%] [% PROCESS global/header.html.tmpl @@ -31,23 +30,24 @@ %] <p> - [% IF bug_count == 1 %] + [% IF keyword.bug_count == 1 %] There is one [% terms.bug %] with this keyword set. [% ELSE %] - There are [% bug_count %] [%+terms.bugs %] with + There are [% keyword.bug_count FILTER html %] [%+ terms.bugs %] with this keyword set. [% END %] Are you <b>sure</b> you want to delete - the <code>[% name FILTER html %]</code> keyword? + the <code>[% keyword.name FILTER html %]</code> keyword? </p> <form method="post" action="editkeywords.cgi"> - <input type="hidden" name="id" value="[% keyword_id %]"> + <input type="hidden" name="id" value="[% keyword.id FILTER html %]"> <input type="hidden" name="action" value="delete"> <input type="hidden" name="reallydelete" value="1"> <input type="hidden" name="token" value="[% token FILTER html %]"> - <input type="submit" value="Yes, really delete the keyword"> + <input type="submit" id="delete" + value="Yes, really delete the keyword"> </form> <p><a href="editkeywords.cgi">Edit other keywords</a>.</p> diff --git a/template/en/default/admin/keywords/create.html.tmpl b/template/en/default/admin/keywords/create.html.tmpl index 861c6f1e9..944014548 100755 --- a/template/en/default/admin/keywords/create.html.tmpl +++ b/template/en/default/admin/keywords/create.html.tmpl @@ -26,7 +26,7 @@ [% PROCESS global/header.html.tmpl title = "Add keyword" - h2 = "This page allows you to add a new keyword." + subheader = "This page allows you to add a new keyword." %] <form method="post" action="editkeywords.cgi"> @@ -38,14 +38,18 @@ <tr> <th align="right">Description:</th> <td> - <textarea rows="4" cols="64" wrap="virtual" - name="description"></textarea> + [% INCLUDE global/textarea.html.tmpl + name = 'description' + minrows = 4 + cols = 64 + wrap = 'virtual' + %] </td> </tr> </table> <hr> <input type="hidden" name="id" value="-1"> - <input type="submit" value="Add"> + <input type="submit" id="create" value="Add"> <input type="hidden" name="action" value="new"> <input type="hidden" name="token" value="[% token FILTER html %]"> </form> diff --git a/template/en/default/admin/keywords/edit.html.tmpl b/template/en/default/admin/keywords/edit.html.tmpl index 16b31da89..81f072b8b 100755 --- a/template/en/default/admin/keywords/edit.html.tmpl +++ b/template/en/default/admin/keywords/edit.html.tmpl @@ -18,13 +18,11 @@ # # Contributor(s): Terry Weissman <terry@mozilla.org> # Vlad Dascalu <jocuri@softhome.net> + # Max Kanat-Alexander <mkanat@bugzilla.org> #%] [%# INTERFACE: - # keyword_id: number. The ID of the keyword. - # name: string. The name of the keyword. - # description: string. The description of the keyword. - # bug_count: number. The number of bugs with the keyword. + # keyword: A Bugzilla::Keyword object. #%] [% PROCESS global/variables.none.tmpl %] @@ -37,21 +35,27 @@ <table border="0" cellpadding="4" cellspacing="0"> <tr> <th align="right">Name:</th> - <td><input size="64" maxlength="64" name="name" value="[% name FILTER html %]"></td> + <td><input size="64" maxlength="64" name="name" + value="[% keyword.name FILTER html %]"></td> </tr> <tr> <th align="right">Description:</th> <td> - <textarea rows="4" cols="64" wrap="virtual" - name="description">[% description FILTER html %]</textarea> + [% INCLUDE global/textarea.html.tmpl + name = 'description' + minrows = 4 + cols = 64 + wrap = 'virtual' + defaultcontent = keyword.description + %] </td> </tr> <tr> <th align="right">[% terms.Bugs %]:</th> <td> - [% IF bug_count > 0 %] - <a href="buglist.cgi?keywords=[% name FILTER url_quote %]"> - [% bug_count %]</a> + [% IF keyword.bug_count > 0 %] + <a href="buglist.cgi?keywords=[% keyword.name FILTER url_quote %]"> + [% keyword.bug_count FILTER html %]</a> [% ELSE %] none [% END %] @@ -59,9 +63,9 @@ </tr> </table> - <input type="submit" value="Update"> + <input type="submit" id="update" value="Update"> <input type="hidden" name="action" value="update"> - <input type="hidden" name="id" value="[% keyword_id %]"> + <input type="hidden" name="id" value="[% keyword.id FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]"> </form> diff --git a/template/en/default/admin/keywords/list.html.tmpl b/template/en/default/admin/keywords/list.html.tmpl index 085333273..1ffa0f27d 100755 --- a/template/en/default/admin/keywords/list.html.tmpl +++ b/template/en/default/admin/keywords/list.html.tmpl @@ -22,7 +22,7 @@ #%] [%# INTERFACE: - # keywords: array of hashes having the properties: + # keywords: array keyword objects having the properties: # - id: number. The ID of the keyword. # - name: string. The name of the keyword. # - description: string. The description of the keyword. @@ -48,7 +48,7 @@ }, { name => "bug_count" - heading => "$terms.Bugs" + heading => "Bugs" align => "right" contentlink => "buglist.cgi?keywords=%%name%%" }, diff --git a/template/en/default/admin/keywords/rebuild-cache.html.tmpl b/template/en/default/admin/keywords/rebuild-cache.html.tmpl index 84b7a7efa..f9f6f31c0 100755 --- a/template/en/default/admin/keywords/rebuild-cache.html.tmpl +++ b/template/en/default/admin/keywords/rebuild-cache.html.tmpl @@ -18,11 +18,12 @@ # # Contributor(s): Terry Weissman <terry@mozilla.org> # Vlad Dascalu <jocuri@softhome.net> + # Max Kanat-Alexander <mkanat@bugzilla.org> #%] [%# INTERFACE: # action: string; the current action (either "update" or "delete"). - # name: string; the name of the current keyword. + # keyword: A Bugzilla::Keyword object #%] [% IF action == "update" %] @@ -35,7 +36,7 @@ [% PROCESS global/header.html.tmpl %] -Keyword [% name FILTER html %] [%+status FILTER html %]. +Keyword [% keyword.name FILTER html %] [%+ status FILTER html %]. <p> <b>After you have finished deleting or modifying keywords, diff --git a/template/en/default/admin/milestones/CVS/Entries b/template/en/default/admin/milestones/CVS/Entries index 418287e81..2fefcbb1f 100644 --- a/template/en/default/admin/milestones/CVS/Entries +++ b/template/en/default/admin/milestones/CVS/Entries @@ -1,10 +1,10 @@ -/confirm-delete.html.tmpl/1.4.2.1/Sat Oct 14 22:05:57 2006//TBUGZILLA-2_22_3 -/create.html.tmpl/1.2.2.1/Sat Oct 14 22:05:57 2006//TBUGZILLA-2_22_3 -/created.html.tmpl/1.1/Sat Sep 11 06:48:14 2004//TBUGZILLA-2_22_3 -/deleted.html.tmpl/1.3/Sun May 22 14:48:16 2005//TBUGZILLA-2_22_3 -/edit.html.tmpl/1.3.2.1/Sat Oct 14 22:05:57 2006//TBUGZILLA-2_22_3 -/footer.html.tmpl/1.1/Sat Sep 11 06:48:14 2004//TBUGZILLA-2_22_3 -/list.html.tmpl/1.3/Tue Sep 27 22:08:14 2005//TBUGZILLA-2_22_3 -/select-product.html.tmpl/1.3/Tue Sep 27 22:08:14 2005//TBUGZILLA-2_22_3 -/updated.html.tmpl/1.1/Sat Sep 11 06:48:14 2004//TBUGZILLA-2_22_3 +/confirm-delete.html.tmpl/1.7/Sat Oct 14 22:02:12 2006//TBUGZILLA-3_0 +/create.html.tmpl/1.7/Sun Jan 7 23:47:47 2007//TBUGZILLA-3_0 +/created.html.tmpl/1.3/Sun Jan 7 23:48:25 2007//TBUGZILLA-3_0 +/deleted.html.tmpl/1.5/Sun Jan 7 23:48:54 2007//TBUGZILLA-3_0 +/edit.html.tmpl/1.7/Sun Jan 7 23:49:19 2007//TBUGZILLA-3_0 +/footer.html.tmpl/1.3/Sun Jan 7 23:49:40 2007//TBUGZILLA-3_0 +/list.html.tmpl/1.5/Mon Jan 8 01:31:23 2007//TBUGZILLA-3_0 +/select-product.html.tmpl/1.4/Mon Jan 8 00:49:53 2007//TBUGZILLA-3_0 +/updated.html.tmpl/1.3/Mon Jan 8 00:50:12 2007//TBUGZILLA-3_0 D diff --git a/template/en/default/admin/milestones/CVS/Tag b/template/en/default/admin/milestones/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/admin/milestones/CVS/Tag +++ b/template/en/default/admin/milestones/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/admin/milestones/confirm-delete.html.tmpl b/template/en/default/admin/milestones/confirm-delete.html.tmpl index 1eb4e0fa9..b1f893ffd 100644 --- a/template/en/default/admin/milestones/confirm-delete.html.tmpl +++ b/template/en/default/admin/milestones/confirm-delete.html.tmpl @@ -21,15 +21,13 @@ #%] [%# INTERFACE: - # name: string; The name of the milestone - # - # bug_count: number; The number of bugs targetted at the milestone - # - # product: string; The name of the product - # + # product: object; Bugzilla::Product object representing the product to + # which the milestone belongs. + # milestone: object; Bugzilla::Milestone object representing the + # milestone the user wants to delete. #%] -[% title = BLOCK %]Delete Milestone of Product '[% product FILTER html %]' +[% title = BLOCK %]Delete Milestone of Product '[% product.name FILTER html %]' [% END %] [% PROCESS global/header.html.tmpl @@ -43,20 +41,21 @@ </tr> <tr> <td valign="top">Milestone:</td> - <td valign="top">[% name FILTER html %]</td> + <td valign="top">[% milestone.name FILTER html %]</td> </tr> <tr> <td valign="top">Milestone of Product:</td> - <td valign="top">[% product FILTER html %]</td> + <td valign="top">[% product.name FILTER html %]</td> </tr> <tr> <td valign="top">[% terms.Bugs %]:</td> <td valign="top"> -[% IF bug_count %] +[% IF milestone.bug_count %] <a title="List of [% terms.bugs %] targetted at milestone ' - [% name FILTER html %]'" - href="buglist.cgi?target_milestone=[% name FILTER url_quote %]&product= - [%- product FILTER url_quote %]">[% bug_count %]</a> + [% milestone.name FILTER html %]'" + href="buglist.cgi?target_milestone=[% milestone.name FILTER url_quote %]&product= + [%- product.name FILTER url_quote %]"> + [% milestone.bug_count FILTER none %]</a> [% ELSE %] None [% END %] @@ -66,13 +65,13 @@ <h2>Confirmation</h2> -[% IF bug_count %] +[% IF milestone.bug_count %] <table border="0" cellpadding="20" width="70%" bgcolor="red"> <tr><td> There - [% IF bug_count > 1 %] - are [% bug_count %] [%+ terms.bugs %] + [% IF milestone.bug_count > 1 %] + are [% milestone.bug_count FILTER none %] [%+ terms.bugs %] [% ELSE %] is 1 [% terms.bug %] [% END %] @@ -87,10 +86,10 @@ <p>Do you really want to delete this milestone?<p> <form method="post" action="editmilestones.cgi"> - <input type="submit" value="Yes, delete"> + <input type="submit" id="delete" value="Yes, delete"> <input type="hidden" name="action" value="delete"> - <input type="hidden" name="product" value="[% product FILTER html %]"> - <input type="hidden" name="milestone" value="[% name FILTER html %]"> + <input type="hidden" name="product" value="[% product.name FILTER html %]"> + <input type="hidden" name="milestone" value="[% milestone.name FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]"> </form> diff --git a/template/en/default/admin/milestones/create.html.tmpl b/template/en/default/admin/milestones/create.html.tmpl index 6e3b4b252..44e958d5b 100644 --- a/template/en/default/admin/milestones/create.html.tmpl +++ b/template/en/default/admin/milestones/create.html.tmpl @@ -20,15 +20,16 @@ #%] [%# INTERFACE: - # product: string; name of the product the milestone is being created for + # product: object; Bugzilla::Product object representing the product to + # which the milestone belongs. #%] -[% title = BLOCK %]Add Milestone to Product '[% product FILTER html %]'[% END %] -[% h2 = BLOCK %]This page allows you to add a new milestone to product - '[% product FILTER html %]'.[% END %] +[% title = BLOCK %]Add Milestone to Product '[% product.name FILTER html %]'[% END %] +[% subheader = BLOCK %]This page allows you to add a new milestone to product + '[% product.name FILTER html %]'.[% END %] [% PROCESS global/header.html.tmpl title = title - h2 = h2 + subheader = subheader onload = "document.forms['f'].milestone.focus()" %] @@ -45,14 +46,12 @@ value=""></td> </tr> </table> - <input type="submit" value="Add"> + <input type="submit" id="create" value="Add"> <input type="hidden" name="action" value="new"> - <input type="hidden" name='product' value="[% product FILTER html %]"> + <input type="hidden" name='product' value="[% product.name FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]"> </form> -<p> - [% PROCESS admin/milestones/footer.html.tmpl no_add_milestone_link = 1 %] diff --git a/template/en/default/admin/milestones/created.html.tmpl b/template/en/default/admin/milestones/created.html.tmpl index 87e08cebe..9342e5051 100644 --- a/template/en/default/admin/milestones/created.html.tmpl +++ b/template/en/default/admin/milestones/created.html.tmpl @@ -20,24 +20,24 @@ #%] [%# INTERFACE: - # name: string; the name of the newly created milestone + # milestone: object; Bugzilla::Milestone object representing the + # milestone the user created. # - # product: string; the name of the product the milestone belongs to + # product: object; Bugzilla::Product object representing the product to + # which the milestone belongs. #%] [% title = BLOCK %]Adding new Milestone of Product - '[% product FILTER html %]'[% END %] + '[% product.name FILTER html %]'[% END %] [% PROCESS global/header.html.tmpl title = title %] -<p>The milestone '<a title="Edit milestone '[% name FILTER html %]' of - product '[% product FILTER html %]'" +<p>The milestone '<a title="Edit milestone '[% milestone.name FILTER html %]' of + product '[% product.name FILTER html %]'" href="editmilestones.cgi?action=edit&product= - [%- product FILTER url_quote %]&milestone=[% name FILTER url_quote %]"> - [%- name FILTER html %]</a>' has been created.</p> - -<p> + [%- product.name FILTER url_quote %]&milestone=[% milestone.name FILTER url_quote %]"> + [%- milestone.name FILTER html %]</a>' has been created.</p> [% PROCESS admin/milestones/footer.html.tmpl %] diff --git a/template/en/default/admin/milestones/deleted.html.tmpl b/template/en/default/admin/milestones/deleted.html.tmpl index 8db9b8943..8d20407ab 100644 --- a/template/en/default/admin/milestones/deleted.html.tmpl +++ b/template/en/default/admin/milestones/deleted.html.tmpl @@ -21,25 +21,23 @@ #%] [%# INTERFACE: - # name: string; the name of the deleted milestone. - # - # product: string; the name of the product the milestone belonged to - # - # bug_count: number; the number of bugs which were reassigned to - # the default milestone. + # product: object; Bugzilla::Product object representing the product to + # which the milestone belongs. + # milestone: object; Bugzilla::Milestone object representing the + # milestone the user deleted. #%] -[% title = BLOCK %]Deleted Milestone '[% name FILTER html %]' of Product - '[% product FILTER html %]'[% END %] +[% title = BLOCK %]Deleted Milestone '[% milestone.name FILTER html %]' of Product + '[% product.name FILTER html %]'[% END %] [% PROCESS global/header.html.tmpl title = title %] <p> -[% IF bug_count %] +[% IF milestone.bug_count %] - [% bug_count %] - [% IF bug_count > 1 %] + [% milestone.bug_count FILTER none %] + [% IF milestone.bug_count > 1 %] [%+ terms.bugs %] [% ELSE %] [%+ terms.bug %] @@ -51,9 +49,7 @@ [% END %] </p> -<p>Milestone '[% name FILTER html %]' deleted.</p> - -<p> +<p>Milestone '[% milestone.name FILTER html %]' deleted.</p> [% PROCESS admin/milestones/footer.html.tmpl no_edit_milestone_link = 1 diff --git a/template/en/default/admin/milestones/edit.html.tmpl b/template/en/default/admin/milestones/edit.html.tmpl index 3daf0765a..fbe0dd879 100644 --- a/template/en/default/admin/milestones/edit.html.tmpl +++ b/template/en/default/admin/milestones/edit.html.tmpl @@ -20,17 +20,16 @@ #%] [%# INTERFACE: - # name: string; The name of the milestone - # - # sortkey: number; milestone sortkey - # - # product: string; The product the milestone belongs to + # product: object; Bugzilla::Product object representing the product to + # which the milestone belongs. + # milestone: object; Bugzilla::Milestone object representing the + # milestone the user wants to edit. #%] [% PROCESS global/variables.none.tmpl %] -[% title = BLOCK %]Edit Milestone '[% name FILTER html %]' of product ' - [%- product FILTER html %]'[% END %] +[% title = BLOCK %]Edit Milestone '[% milestone.name FILTER html %]' of product ' + [%- product.name FILTER html %]'[% END %] [% PROCESS global/header.html.tmpl title = title onload = "document.forms['f'].milestone.select()" @@ -42,25 +41,23 @@ <tr> <th valign="top"><label for="milestone">Milestone:</label></th> <td><input id="milestone" size="20" maxlength="20" name="milestone" value=" - [%- name FILTER html %]"></td> + [%- milestone.name FILTER html %]"></td> </tr> <tr> <th align="right"><label for="sortkey">Sortkey:</label></th> <td><input id="sortkey" size="20" maxlength="20" name="sortkey" value=" - [%- sortkey FILTER html %]"></td> + [%- milestone.sortkey FILTER html %]"></td> </tr> </table> - <input type="hidden" name="milestoneold" value="[% name FILTER html %]"> + <input type="hidden" name="milestoneold" value="[% milestone.name FILTER html %]"> <input type="hidden" name="action" value="update"> - <input type="hidden" name="product" value="[% product FILTER html %]"> - <input type="submit" value="Update"> + <input type="hidden" name="product" value="[% product.name FILTER html %]"> + <input type="submit" id="update" value="Update"> <input type="hidden" name="token" value="[% token FILTER html %]"> </form> -<p> - [% PROCESS admin/milestones/footer.html.tmpl no_edit_milestone_link = 1 %] diff --git a/template/en/default/admin/milestones/footer.html.tmpl b/template/en/default/admin/milestones/footer.html.tmpl index 8980d642e..774223e3b 100644 --- a/template/en/default/admin/milestones/footer.html.tmpl +++ b/template/en/default/admin/milestones/footer.html.tmpl @@ -20,10 +20,11 @@ #%] [%# INTERFACE: - # name: string; the name of the milestone + # product: object; Bugzilla::Product object representing the product to + # which the milestone belongs. # - # product: string; the name of the product which the milestone - # belongs/belonged to + # milestone: object; Bugzilla::Milestone object representing the + # milestone. # # no_XXX_link: boolean; if defined, then don't show the corresponding # link. Supported parameters are: @@ -32,35 +33,36 @@ # no_edit_other_milestones_link # no_add_milestone_link #%] - -<p> <hr> +<p> + [% UNLESS no_add_milestone_link %] - <a title="Add a milestone to product '[% product FILTER html %]'" + <a title="Add a milestone to product '[% product.name FILTER html %]'" href="editmilestones.cgi?action=add&product= - [%- product FILTER url_quote %]">Add</a> a milestone. + [%- product.name FILTER url_quote %]">Add</a> a milestone. [% END %] -[% IF name && !no_edit_milestone_link %] +[% IF milestone.name && !no_edit_milestone_link %] Edit milestone <a - title="Edit Milestone '[% name FILTER html %]' of product ' - [%- product FILTER html %]'" + title="Edit Milestone '[% milestone.name FILTER html %]' of product ' + [%- product.name FILTER html %]'" href="editmilestones.cgi?action=edit&product= - [%- product FILTER url_quote %]&milestone=[% name FILTER url_quote %]"> - '[% name FILTER html %]'</a>. + [%- product.name FILTER url_quote %]&milestone= + [%- milestone.name FILTER url_quote %]"> + '[% milestone.name FILTER html %]'</a>. [% END %] [% UNLESS no_edit_other_milestones_link %] Edit other milestones of product <a href="editmilestones.cgi?product= - [%- product FILTER url_quote %]">'[% product FILTER html %]'</a>. - + [%- product.name FILTER url_quote %]">'[% product.name FILTER html %]'</a>. + [% END %] Edit product <a href="editproducts.cgi?action=edit&product= - [%- product FILTER url_quote %]">'[% product FILTER html %]'</a>. + [%- product.name FILTER url_quote %]">'[% product.name FILTER html %]'</a>. </p> diff --git a/template/en/default/admin/milestones/list.html.tmpl b/template/en/default/admin/milestones/list.html.tmpl index b9311fc1a..01e705eff 100644 --- a/template/en/default/admin/milestones/list.html.tmpl +++ b/template/en/default/admin/milestones/list.html.tmpl @@ -21,9 +21,9 @@ #%] [%# INTERFACE: - # milestones: array of milestone objects + # product: object; Bugzilla::Product object representing the product to + # which the milestones belongs. # showbugcounts: if defined, then bug counts should be included in the table - # product: string; the name of the product we are editing milestones for #%] [% USE Bugzilla %] @@ -32,17 +32,17 @@ [% PROCESS global/variables.none.tmpl %] [% title = BLOCK %]Select milestone of product - '[% product FILTER html %]'[% END %] + '[% product.name FILTER html %]'[% END %] [% PROCESS global/header.html.tmpl title = title %] [% edit_contentlink = BLOCK %]editmilestones.cgi?action=edit&product= - [%- product FILTER url_quote %]&milestone=%%name%%[% END %] + [%- product.name FILTER url_quote %]&milestone=%%name%%[% END %] [% delete_contentlink = BLOCK %]editmilestones.cgi?action=del&product= - [%- product FILTER url_quote %]&milestone=%%name%%[% END %] + [%- product.name FILTER url_quote %]&milestone=%%name%%[% END %] [% bug_count_contentlink = BLOCK %]buglist.cgi?target_milestone=%%name%%&product= - [%- product FILTER url_quote %][% END %] + [%- product.name FILTER url_quote %][% END %] [% columns = [ @@ -81,7 +81,7 @@ [%# We want to override the usual 'Delete' link for the default milestone %] [% overrides.action = [ { - match_value => "$default_milestone" + match_value => product.default_milestone match_field => 'name' override_content => 1 content => "(Default milestone)" @@ -92,15 +92,13 @@ [% PROCESS admin/table.html.tmpl columns = columns - data = milestones + data = product.milestones overrides = overrides %] -<p> - [% IF ! showbugcounts %] - <p><a href="editmilestones.cgi?product=[% product FILTER url_quote %]&showbugcounts=1"> + <p><a href="editmilestones.cgi?product=[% product.name FILTER url_quote %]&showbugcounts=1"> Redisplay table with [% terms.bug %] counts (slower)</a></p> [% END %] diff --git a/template/en/default/admin/milestones/select-product.html.tmpl b/template/en/default/admin/milestones/select-product.html.tmpl index 508af6881..a9e53d396 100644 --- a/template/en/default/admin/milestones/select-product.html.tmpl +++ b/template/en/default/admin/milestones/select-product.html.tmpl @@ -68,6 +68,4 @@ Redisplay table with [% terms.bug %] counts (slower)</a></p> [% END %] -<p> - [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/admin/milestones/updated.html.tmpl b/template/en/default/admin/milestones/updated.html.tmpl index bfc09e210..f55985534 100644 --- a/template/en/default/admin/milestones/updated.html.tmpl +++ b/template/en/default/admin/milestones/updated.html.tmpl @@ -20,38 +20,31 @@ #%] [%# INTERFACE: + # product: object; Bugzilla::Product object representing the product to + # which the milestone belongs. # # 'updated_XXX' variables are booleans, and are defined if the # 'XXX' field was updated during the edit just being handled. - # Variables called just 'XXX' are strings, and are the _new_ contents - # of the fields. - # - # name & updated_name: the name of the milestone - # - # sortkey & updated_sortkey: the milestone sortkey - # - # product: string; the name of the product the milestone belongs to #%] - -[% title = BLOCK %]Updating Milestone '[% name FILTER html %]' of Product - '[% product FILTER html %]'[% END %] + +[% title = BLOCK %]Updating Milestone '[% milestone.name FILTER html %]' of Product + '[% product.name FILTER html %]'[% END %] [% PROCESS global/header.html.tmpl title = title %] [% IF updated_name %] - <p>Updated Milestone name to: '[% name FILTER html %]'.</p> + <p>Updated Milestone name to: '[% milestone.name FILTER html %]'.</p> [% END %] [% IF updated_sortkey %] - <p>Updated Milestone sortkey to: '[% sortkey FILTER html %]'.</p> + <p>Updated Milestone sortkey to: '[% milestone.sortkey FILTER html %]'.</p> [% END %] [% UNLESS updated_sortkey || updated_name %] - <p>Nothing changed for milestone '[% name FILTER html %]'. + <p>Nothing changed for milestone '[% milestone.name FILTER html %]'.</p> + [% END %] - -<p> [% PROCESS admin/milestones/footer.html.tmpl %] diff --git a/template/en/default/admin/params/CVS/Entries b/template/en/default/admin/params/CVS/Entries index 38e4d3af1..c7be978c2 100644 --- a/template/en/default/admin/params/CVS/Entries +++ b/template/en/default/admin/params/CVS/Entries @@ -1,20 +1,20 @@ -/admin.html.tmpl/1.2.2.1/Mon Nov 27 18:11:02 2006//TBUGZILLA-2_22_3 -/attachment.html.tmpl/1.2/Wed Oct 19 20:16:14 2005//TBUGZILLA-2_22_3 -/auth.html.tmpl/1.1/Wed Oct 12 08:51:54 2005//TBUGZILLA-2_22_3 -/bugchange.html.tmpl/1.2.2.1/Thu Jul 20 23:34:10 2006//TBUGZILLA-2_22_3 -/bugfields.html.tmpl/1.2.2.1/Thu Jul 20 23:34:10 2006//TBUGZILLA-2_22_3 -/bugmove.html.tmpl/1.1.2.1/Thu Jul 20 23:34:10 2006//TBUGZILLA-2_22_3 -/common.html.tmpl/1.3/Mon Feb 6 09:16:16 2006//TBUGZILLA-2_22_3 -/core.html.tmpl/1.1/Wed Oct 12 08:51:54 2005//TBUGZILLA-2_22_3 -/dependencygraph.html.tmpl/1.1/Wed Oct 12 08:51:54 2005//TBUGZILLA-2_22_3 -/editparams.html.tmpl/1.2.2.1/Sat Oct 14 22:05:57 2006//TBUGZILLA-2_22_3 -/groupsecurity.html.tmpl/1.3/Sat Oct 22 13:07:06 2005//TBUGZILLA-2_22_3 -/index.html.tmpl/1.1/Thu Oct 13 09:18:24 2005//TBUGZILLA-2_22_3 -/l10n.html.tmpl/1.1/Wed Oct 12 08:51:54 2005//TBUGZILLA-2_22_3 -/ldap.html.tmpl/1.1/Wed Oct 12 08:51:54 2005//TBUGZILLA-2_22_3 -/mta.html.tmpl/1.2/Fri Jan 27 11:31:41 2006//TBUGZILLA-2_22_3 -/patchviewer.html.tmpl/1.1/Wed Oct 12 08:51:54 2005//TBUGZILLA-2_22_3 -/query.html.tmpl/1.1/Wed Oct 12 08:51:54 2005//TBUGZILLA-2_22_3 -/shadowdb.html.tmpl/1.1/Wed Oct 12 08:51:54 2005//TBUGZILLA-2_22_3 -/usermatch.html.tmpl/1.2/Sat Nov 12 10:09:44 2005//TBUGZILLA-2_22_3 +/admin.html.tmpl/1.3/Mon Nov 27 18:09:14 2006//TBUGZILLA-3_0 +/attachment.html.tmpl/1.3/Mon Apr 17 20:19:36 2006//TBUGZILLA-3_0 +/auth.html.tmpl/1.1/Wed Oct 12 08:51:54 2005//TBUGZILLA-3_0 +/bugchange.html.tmpl/1.3/Thu Jul 20 23:32:09 2006//TBUGZILLA-3_0 +/bugfields.html.tmpl/1.3/Thu Jul 20 23:32:09 2006//TBUGZILLA-3_0 +/bugmove.html.tmpl/1.2/Thu Jul 20 23:32:09 2006//TBUGZILLA-3_0 +/common.html.tmpl/1.3/Mon Feb 6 09:16:16 2006//TBUGZILLA-3_0 +/core.html.tmpl/1.5.2.1/Wed Apr 18 00:15:14 2007//TBUGZILLA-3_0 +/dependencygraph.html.tmpl/1.1/Wed Oct 12 08:51:54 2005//TBUGZILLA-3_0 +/editparams.html.tmpl/1.4.2.1/Sun Mar 25 02:11:16 2007//TBUGZILLA-3_0 +/groupsecurity.html.tmpl/1.4/Thu Jul 13 20:08:00 2006//TBUGZILLA-3_0 +/index.html.tmpl/1.1/Thu Oct 13 09:18:24 2005//TBUGZILLA-3_0 +/l10n.html.tmpl/1.1/Wed Oct 12 08:51:54 2005//TBUGZILLA-3_0 +/ldap.html.tmpl/1.5/Tue Jul 11 00:42:58 2006//TBUGZILLA-3_0 +/mta.html.tmpl/1.9/Mon Nov 13 23:32:29 2006//TBUGZILLA-3_0 +/patchviewer.html.tmpl/1.2/Wed Jan 3 00:32:06 2007//TBUGZILLA-3_0 +/query.html.tmpl/1.1/Wed Oct 12 08:51:54 2005//TBUGZILLA-3_0 +/shadowdb.html.tmpl/1.1/Wed Oct 12 08:51:54 2005//TBUGZILLA-3_0 +/usermatch.html.tmpl/1.2/Sat Nov 12 10:09:44 2005//TBUGZILLA-3_0 D diff --git a/template/en/default/admin/params/CVS/Tag b/template/en/default/admin/params/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/admin/params/CVS/Tag +++ b/template/en/default/admin/params/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/admin/params/attachment.html.tmpl b/template/en/default/admin/params/attachment.html.tmpl index ef89c4af0..785d91822 100644 --- a/template/en/default/admin/params/attachment.html.tmpl +++ b/template/en/default/admin/params/attachment.html.tmpl @@ -25,9 +25,13 @@ %] [% param_descs = { + allow_attachment_deletion => "If this option is on, administrators will be able to delete " _ + "the content of attachments.", + allow_attach_url => "If this option is on, it will be possible to " _ "specify a URL when creating an attachment and " _ "treat the URL itself as if it were an attachment.", + maxpatchsize => "The maximum size (in kilobytes) of patches. $terms.Bugzilla will not " _ "accept patches greater than this number of kilobytes in size. " _ "To accept patches of any size (subject to the limitations of " _ diff --git a/template/en/default/admin/params/core.html.tmpl b/template/en/default/admin/params/core.html.tmpl index adf527c33..9ad312cfb 100644 --- a/template/en/default/admin/params/core.html.tmpl +++ b/template/en/default/admin/params/core.html.tmpl @@ -32,6 +32,12 @@ urlbase => "The URL that is the common initial leading part of all $terms.Bugzilla " _ "URLs.", + docs_urlbase => "The URL that is the common initial leading part of all " _ + "$terms.Bugzilla documentation URLs. " _ + "It may be an absolute URL, or a URL relative to urlbase " _ + "above. " _ + "Leave this empty to suppress links to the documentation.", + sslbase => "The URL that is the common initial leading part of all HTTPS " _ "(SSL) $terms.Bugzilla URLs.", @@ -58,11 +64,48 @@ utf8 => "Use UTF-8 (Unicode) encoding for all text in ${terms.Bugzilla}. New " _ "installations should set this to true to avoid character encoding " _ - "problems. Existing databases should set this to true only after " _ - "the data has been converted from existing legacy character " _ - "encodings to UTF-8.", + "problems. <strong>Existing databases should set this to true " _ + " only after the data has been converted from existing legacy " _ + " character encodings to UTF-8, using the " _ + " <kbd>contrib/recode.pl</kbd> script</strong>. <br><br> Note " _ + " that if you turn this parameter from "off" to " _ + " "on", you must re-run checksetup.pl immediately " _ + " afterward.", shutdownhtml => "If this field is non-empty, then $terms.Bugzilla will be completely " _ "disabled and this text will be displayed instead of all the " _ - "$terms.Bugzilla pages." } -%] \ No newline at end of file + "$terms.Bugzilla pages.", + + announcehtml => "If this field is non-empty, then $terms.Bugzilla will " _ + "display whatever is in this field at the top of every " _ + "HTML page. The HTML you put in this field is not " _ + "wrapped or enclosed in anything; you might want to " _ + "wrap it inside a <tt><div></tt>. Give the div " _ + "<em>id=message</em> to get green text inside a " _ + "red box, or <em>class=bz_private</em> for dark " _ + "red on a red background. Anything defined in " _ + "<tt>skins/standard/global.css</tt> or " _ + "<tt>skins/custom/global.css</tt> will work. To get " _ + "centered text, use <em>style=\"text-align: " _ + "center;\"</em>.", + + proxy_url => "$terms.Bugzilla may have to access the web to get notifications about new " _ + "releases, see the <tt>upgrade_notification</tt> parameter. In case you are " _ + "behind a proxy, it may be necessary to enter its URL if the web server " _ + "group cannot access the HTTP_PROXY environment variable.", + + upgrade_notification => "<p>$terms.Bugzilla can inform you when a new release is available. " _ + "The notification will appear on the $terms.Bugzilla homepage, " _ + "for administrators only.</p>" _ + "<ul><li>'development_snapshot' notifies you about the latest " _ + "release on the trunk, i.e. development snapshots.</li>" _ + "<li>'latest_stable_release' notifies you about the most recent release " _ + "available on the most recent stable branch. This branch may be " _ + "different from the branch your installation is based on.</li>" _ + "<li>'stable_branch_release' notifies you only about new releases " _ + "corresponding to the branch your installation is based on. " _ + "If you are running a release candidate, you will get " _ + "a notification for newer release candidates too.</li>" _ + "<li>'disabled' will never notify you about new releases and no " _ + "connection will be established to a remote server.</li></ul>" } +%] diff --git a/template/en/default/admin/params/editparams.html.tmpl b/template/en/default/admin/params/editparams.html.tmpl index 5d309067c..2a9b785a6 100644 --- a/template/en/default/admin/params/editparams.html.tmpl +++ b/template/en/default/admin/params/editparams.html.tmpl @@ -46,9 +46,9 @@ [% title = BLOCK %] [% IF curpanel == -1 %] - [% terms.Bugzilla FILTER html %] Parameters: Index + Parameters: Index [% ELSE %] - [% terms.Bugzilla FILTER html %] Configuration: + Configuration: [%+ current_panel.title FILTER html %] [% END %] [% END %] @@ -89,11 +89,21 @@ [% IF curpanel == -1 %] [% PROCESS admin/params/index.html.tmpl panels = panels %] [% ELSE %] + + <div class="contribute"><strong>Note:</strong> + [%+ terms.Bugzilla %] is developed entirely by volunteers. The + best way to give back to the [% terms.Bugzilla %] project is + to <a href="http://www.bugzilla.org/contribute/">contribute</a> + yourself! You don't have to be a programmer to contribute, there are + lots of things that we need. + </div> + <p> This lets you edit the basic operating parameters of [% terms.Bugzilla %]. Be careful!<br> Any item you check "Reset" on will get reset to its default value. </p> + [%# CONTENT PANEL %] <form method="post" action="editparams.cgi"> [% PROCESS admin/params/common.html.tmpl panel = current_panel %] diff --git a/template/en/default/admin/params/groupsecurity.html.tmpl b/template/en/default/admin/params/groupsecurity.html.tmpl index 9016a7038..630777998 100644 --- a/template/en/default/admin/params/groupsecurity.html.tmpl +++ b/template/en/default/admin/params/groupsecurity.html.tmpl @@ -46,6 +46,9 @@ timetrackinggroup => "The name of the group of users who can see/change time tracking " _ "information.", + querysharegroup => "The name of the group of users who can share their " _ + "saved searches with others.", + usevisibilitygroups => "Do you wish to restrict visibility of users to members of " _ "specific groups?", diff --git a/template/en/default/admin/params/ldap.html.tmpl b/template/en/default/admin/params/ldap.html.tmpl index 6e7068796..a3c7e4643 100644 --- a/template/en/default/admin/params/ldap.html.tmpl +++ b/template/en/default/admin/params/ldap.html.tmpl @@ -26,7 +26,14 @@ [% param_descs = { LDAPserver => "The name (and optionally port) of your LDAP server " _ - "(e.g. ldap.company.com, or ldap.company.com:portnum).", + "(e.g. ldap.company.com, or ldap.company.com:portnum). " _ + "URI syntax can also be used, such as "_ + "ldaps://ldap.company.com (for a secure connection) or " _ + "ldapi://%2fvar%2flib%2fldap_sock (for a socket-based " _ + "local connection.", + + LDAPstartls => "Whether to require encrypted communication once normal " _ + "LDAP connection achieved with the server.", LDAPbinddn => "If your LDAP server requires that you use a binddn and password " _ "instead of binding anonymously, enter it here " _ @@ -38,8 +45,12 @@ LDAPuidattribute => "The name of the attribute containing the user's login name.", - LDAPmailattribute => "The name of the attribute of a user in your directory that " _ - "contains the email address.", + LDAPmailattribute => "The name of the attribute of a user in your " _ + "directory that contains the email address, to be " _ + "used as $terms.Bugzilla username. If this parameter " _ + "is empty, $terms.Bugzilla will use the LDAP username"_ + " as the $terms.Bugzilla username. You may also want" _ + " to set the \"emailsuffix\" parameter, in this case.", LDAPfilter => "LDAP filter to AND with the <tt>LDAPuidattribute</tt> for " _ "filtering the list of valid users." } diff --git a/template/en/default/admin/params/mta.html.tmpl b/template/en/default/admin/params/mta.html.tmpl index 37d1d8e86..778f81d0a 100644 --- a/template/en/default/admin/params/mta.html.tmpl +++ b/template/en/default/admin/params/mta.html.tmpl @@ -28,14 +28,13 @@ mail_delivery_method => "Defines how email is sent, or if it is sent at all.<br> <ul> <li> - 'sendmail', 'smtp' and 'qmail' are all MTAs. + 'Sendmail', 'SMTP' and 'Qmail' are all MTAs. You need to install a third-party sendmail replacement if you want to use sendmail on Windows. </li> <li> - 'testfile' is useful for debugging: all email is stored - in 'data/mailer.testfile' instead of being sent. For more - information, see the Mail::Mailer manual. + 'Test' is useful for debugging: all email is stored + in 'data/mailer.testfile' instead of being sent. </li> <li> 'none' will completely disable email. $terms.Bugzilla continues @@ -44,6 +43,9 @@ </li> </ul>", + mailfrom => "The email address of the $terms.Bugzilla mail daemon. Some email systems " _ + "require this to be a valid email address.", + sendmailnow => "Sites using anything older than version 8.12 of 'sendmail' " _ "can achieve a significant performance increase in the " _ "UI -- at the cost of delaying the sending of mail -- by " _ @@ -54,56 +56,11 @@ smtpserver => "The SMTP server address (if using SMTP for mail delivery).", - passwordmail => "The email that gets sent to people to tell them their password. " _ - "Within this text, %mailaddress% gets replaced by the person's " _ - "email address, %login% gets replaced by the person's login " _ - "(usually the same thing), and %password% gets replaced by their " _ - "password. %<i>anythingelse</i>% gets replaced by the " _ - "definition of that parameter (as defined on this page).", - - newchangedmail => "The email that gets sent to people when a $terms.bug changes. Within " _ - "this text, %to% gets replaced with the e-mail address of the " _ - "person receiving the mail. %bugid% gets replaced by the $terms.bug " _ - "number. %diffs% gets replaced with what has changed. " _ - "%neworchanged% is 'New:' if this mail is reporting a new $terms.bug or " _ - "empty if changes were made to an existing one. %summary% gets " _ - "replaced by the summary of this ${terms.bug}. %reasonsheader% is " _ - "replaced by an abbreviated list of reasons why the user is " _ - "getting the email, suitable for use in an email header (such " _ - "as X-Bugzilla-Reason). %reasonsbody% is replaced by text that " _ - "explains why the user is getting the email in more user " _ - "friendly text than %reasonsheader%. " _ - "%threadingmarker% will become either a Message-ID line (for " _ - "new-${terms.bug} messages) or a In-Reply-To line (for ${terms.bug}-change " _ - "messages). " _ - "%<i>anythingelse</i>% gets " _ - "replaced by the definition of that parameter (as defined on " _ - "this page).", - whinedays => "The number of days that we'll let a $terms.bug sit untouched in a NEW " _ "state before our cronjob will whine at the owner.<br> " _ "Set to 0 to disable whining.", - whinemail => "The email that gets sent to anyone who has a NEW or REOPENED " _ - "$terms.bug that hasn't been touched for more than <b>whinedays</b>. " _ - "Within this text, %email% gets replaced by the offender's " _ - "email address. %userid% gets replaced by the offender's " _ - "$terms.Bugzilla login (which, in most installations, is the same as " _ - "the email address.) %<i>anythingelse</i>% gets replaced by the " _ - "definition of that parameter (as defined on this page).<p> " _ - "It is a good idea to make sure this message has a valid From: " _ - "address, so that if the mail bounces, a real person can know " _ - "that there are $terms.bugs assigned to an invalid address.", + globalwatchers => "A comma-separated list of users who should receive a " _ + "copy of every notification mail the system sends." } - voteremovedmail => "This is a mail message to send to anyone who gets a vote removed " _ - "from $terms.abug for any reason. %to% gets replaced by the person who " _ - "used to be voting for this ${terms.bug}. %bugid% gets replaced by the " _ - "$terms.bug number. %reason% gets replaced by a short reason describing " _ - "why the vote(s) were removed. %votesremoved%, %votesold% and " _ - "%votesnew% is the number of votes removed, before and after " _ - "respectively. %votesremovedtext%, %votesoldtext% and " _ - "%votesnewtext% are these as sentences, e.g. 'You had 2 votes on " _ - "this ${terms.bug}.' %count% is also supported for backwards " _ - "compatibility. %<i>anythingelse</i>% gets replaced by the " _ - "definition of that parameter (as defined on this page)." } %] diff --git a/template/en/default/admin/params/patchviewer.html.tmpl b/template/en/default/admin/params/patchviewer.html.tmpl index f3dd6d4a1..ad15262ff 100644 --- a/template/en/default/admin/params/patchviewer.html.tmpl +++ b/template/en/default/admin/params/patchviewer.html.tmpl @@ -29,12 +29,12 @@ "users of your system will be using for 'cvs diff'. Used in " _ "Patch Viewer ('Diff' option on patches) to figure out where " _ "patches are rooted even if users did the 'cvs diff' from " _ - "different places in the directory structure (NOTE: if your " _ + "different places in the directory structure. (NOTE: if your " _ "CVS repository is remote and requires a password, you must " _ "either ensure the $terms.Bugzilla user has done a 'cvs login' or " _ "specify the password " _ "<a href=\"http://www.cvshome.org/docs/manual/cvs_2.html#SEC26\">as " _ - "part of the CVS root.</a>). Leave this blank if you have no " _ + "part of the CVS root</a>.) Leave this blank if you have no " _ "CVS repository.", cvsroot_get => "The CVS root $terms.Bugzilla will be using to get patches from. " _ diff --git a/template/en/default/admin/products/CVS/Entries b/template/en/default/admin/products/CVS/Entries index ec8a1fb2b..cd325a73a 100644 --- a/template/en/default/admin/products/CVS/Entries +++ b/template/en/default/admin/products/CVS/Entries @@ -1,11 +1,11 @@ -/confirm-delete.html.tmpl/1.3.2.2/Sat Oct 14 22:05:58 2006//TBUGZILLA-2_22_3 -/create.html.tmpl/1.3.2.1/Sat Oct 14 22:05:58 2006//TBUGZILLA-2_22_3 -/created.html.tmpl/1.2/Mon Oct 17 21:43:41 2005//TBUGZILLA-2_22_3 -/deleted.html.tmpl/1.3/Mon Oct 17 21:43:41 2005//TBUGZILLA-2_22_3 -/edit-common.html.tmpl/1.4.2.1/Sat Oct 14 20:30:56 2006//TBUGZILLA-2_22_3 -/edit.html.tmpl/1.5.2.2/Sat Oct 14 22:05:58 2006//TBUGZILLA-2_22_3 -/footer.html.tmpl/1.6/Mon Oct 17 21:43:41 2005//TBUGZILLA-2_22_3 -/list-classifications.html.tmpl/1.1/Thu Mar 17 14:47:06 2005//TBUGZILLA-2_22_3 -/list.html.tmpl/1.3/Sun Oct 30 21:42:13 2005//TBUGZILLA-2_22_3 -/updated.html.tmpl/1.2.2.2/Sat Oct 14 20:30:56 2006//TBUGZILLA-2_22_3 +/confirm-delete.html.tmpl/1.7/Mon Jan 8 00:51:01 2007//TBUGZILLA-3_0 +/create.html.tmpl/1.4/Sat Oct 14 22:02:12 2006//TBUGZILLA-3_0 +/created.html.tmpl/1.2/Mon Oct 17 21:43:41 2005//TBUGZILLA-3_0 +/deleted.html.tmpl/1.3/Mon Oct 17 21:43:41 2005//TBUGZILLA-3_0 +/edit-common.html.tmpl/1.7/Tue Oct 17 19:58:36 2006//TBUGZILLA-3_0 +/edit.html.tmpl/1.8/Fri Nov 10 16:51:29 2006//TBUGZILLA-3_0 +/footer.html.tmpl/1.9.2.1/Sat Mar 10 19:20:40 2007//TBUGZILLA-3_0 +/list-classifications.html.tmpl/1.2/Mon Jan 8 00:52:17 2007//TBUGZILLA-3_0 +/list.html.tmpl/1.4/Mon Jan 8 00:51:52 2007//TBUGZILLA-3_0 +/updated.html.tmpl/1.5/Mon Jan 8 00:52:36 2007//TBUGZILLA-3_0 D/groupcontrol//// diff --git a/template/en/default/admin/products/CVS/Tag b/template/en/default/admin/products/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/admin/products/CVS/Tag +++ b/template/en/default/admin/products/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/admin/products/confirm-delete.html.tmpl b/template/en/default/admin/products/confirm-delete.html.tmpl index 5e2cdddb9..8e5fbb11f 100644 --- a/template/en/default/admin/products/confirm-delete.html.tmpl +++ b/template/en/default/admin/products/confirm-delete.html.tmpl @@ -156,6 +156,7 @@ [% ELSE %] Versions: [% END %] + </td> <td> [% IF product.versions.size > 0 %] [% FOREACH v = product.versions %] @@ -215,7 +216,7 @@ [% IF !Param("allowbugdeletion") %] - Sorry, there + <p>Sorry, there [% IF product.bug_count > 1 %] are [% product.bug_count FILTER html %] [%+ terms.bugs %] @@ -231,7 +232,7 @@ that [% terms.bug %] [% END %] - to another product before you can delete this one. + to another product before you can delete this one.</p> [% ELSE %] @@ -257,10 +258,10 @@ [% IF product.bug_count == 0 || Param('allowbugdeletion') %] - <p>Do you really want to delete this product?<p> + <p>Do you really want to delete this product?</p> <form method="post" action="editproducts.cgi"> - <input type="submit" value="Yes, delete"> + <input type="submit" id="delete" value="Yes, delete"> <input type="hidden" name="action" value="delete"> <input type="hidden" name="product" value="[% product.name FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]"> diff --git a/template/en/default/admin/products/edit-common.html.tmpl b/template/en/default/admin/products/edit-common.html.tmpl index 64dd960a5..1a1ecab3f 100644 --- a/template/en/default/admin/products/edit-common.html.tmpl +++ b/template/en/default/admin/products/edit-common.html.tmpl @@ -53,8 +53,19 @@ </tr> <tr> <th align="right">Default milestone:</th> - <td><input type="text" size="20" maxlength="20" name="defaultmilestone" - value="[% product.defaultmilestone FILTER html %]"> + <td> + [% IF product.milestones.size %] + <select name="defaultmilestone"> + [% FOREACH m = product.milestones %] + <option value="[% m.name FILTER html %]" + [% " selected=\"selected\"" IF m.name == product.defaultmilestone %]> + [%- m.name FILTER html -%]</option> + [% END %] + </select> + [% ELSE %] + <input type="text" size="20" maxlength="20" name="defaultmilestone" + value="[% product.defaultmilestone FILTER html %]"> + [% END %] </td> </tr> [% END %] @@ -91,12 +102,14 @@ </tr> <tr [% IF !Param('usevotes') %]class="param_disabled" [% END %]> <th align="right"> - Number of votes [% terms.abug %] in this product needs to + Confirmation threshold: + </th> + <td> + Enter the number of votes [% terms.abug %] in this product needs to automatically get out of the <a href="page.cgi?id=fields.html#status">[% status_descs.UNCONFIRMED FILTER html %]</a> - state: - </th> - <td><input size="5" maxlength="5" name="votestoconfirm" - value="[% product.votestoconfirm FILTER html %]"> + state.<br> + <input size="5" maxlength="5" name="votestoconfirm" + value="[% product.votestoconfirm FILTER html %]"> </td> </tr> diff --git a/template/en/default/admin/products/edit.html.tmpl b/template/en/default/admin/products/edit.html.tmpl index 0371e3343..72a5532aa 100644 --- a/template/en/default/admin/products/edit.html.tmpl +++ b/template/en/default/admin/products/edit.html.tmpl @@ -112,6 +112,9 @@ versions:</a> [% g.othercontrol FILTER html %] [% IF g.entry %], ENTRY[% END %] [% IF g.canedit %], CANEDIT[% END %] + [% IF g.editcomponents %], editcomponents[% END %] + [% IF g.canconfirm %], canconfirm[% END %] + [% IF g.editbugs %], editbugs[% END %] [% ELSE %] DISABLED [% END %] diff --git a/template/en/default/admin/products/footer.html.tmpl b/template/en/default/admin/products/footer.html.tmpl index 480868abd..d13f78c60 100644 --- a/template/en/default/admin/products/footer.html.tmpl +++ b/template/en/default/admin/products/footer.html.tmpl @@ -40,12 +40,11 @@ of classification '[% classification.name FILTER html %]' [% END %] [% END %] - -<p> <hr> -[% UNLESS no_add_product_link %] +<p> +[% UNLESS no_add_product_link || !user.in_group("editcomponents") %] <a title="Add a product" href="editproducts.cgi?action=add">Add</a> a product[% -%] [%# Strictly speaking, we should not have to check for a @@ -55,8 +54,7 @@ [%- classification.name FILTER html %]'" href="editproducts.cgi?action=add [%- classification_url_part %]">to - classification '[% classification.name FILTER html %]' - </a>) + classification '[% classification.name FILTER html %]'</a>) [% END %]. [% END %] @@ -77,7 +75,7 @@ href="editproducts.cgi? [%- classification_url_part_start FILTER none %]">other products [% classification_text %]</a>. - + [% END %] [% IF Param('useclassification') && classification %] diff --git a/template/en/default/admin/products/groupcontrol/CVS/Entries b/template/en/default/admin/products/groupcontrol/CVS/Entries index ac0bb72b2..9623a15cf 100644 --- a/template/en/default/admin/products/groupcontrol/CVS/Entries +++ b/template/en/default/admin/products/groupcontrol/CVS/Entries @@ -1,4 +1,4 @@ -/confirm-edit.html.tmpl/1.7/Mon Jan 9 21:49:59 2006//TBUGZILLA-2_22_3 -/edit.html.tmpl/1.6.2.1/Sat Oct 14 22:05:58 2006//TBUGZILLA-2_22_3 -/updated.html.tmpl/1.2/Mon Oct 17 21:43:42 2005//TBUGZILLA-2_22_3 +/confirm-edit.html.tmpl/1.8/Wed Jul 12 12:21:39 2006//TBUGZILLA-3_0 +/edit.html.tmpl/1.9/Mon Jan 8 00:50:39 2007//TBUGZILLA-3_0 +/updated.html.tmpl/1.2/Mon Oct 17 21:43:42 2005//TBUGZILLA-3_0 D diff --git a/template/en/default/admin/products/groupcontrol/CVS/Tag b/template/en/default/admin/products/groupcontrol/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/admin/products/groupcontrol/CVS/Tag +++ b/template/en/default/admin/products/groupcontrol/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/admin/products/groupcontrol/confirm-edit.html.tmpl b/template/en/default/admin/products/groupcontrol/confirm-edit.html.tmpl index 6d0bfe3bb..e21567624 100644 --- a/template/en/default/admin/products/groupcontrol/confirm-edit.html.tmpl +++ b/template/en/default/admin/products/groupcontrol/confirm-edit.html.tmpl @@ -48,7 +48,7 @@ be removed.[% END %] return to the previous page. <p> <input type="hidden" name="confirmed" value="confirmed"> - <input type="submit" value="Continue"> + <input type="submit" id="update" value="Continue"> </p> </form> diff --git a/template/en/default/admin/products/groupcontrol/edit.html.tmpl b/template/en/default/admin/products/groupcontrol/edit.html.tmpl index 32b5e9d8c..819c8e54b 100644 --- a/template/en/default/admin/products/groupcontrol/edit.html.tmpl +++ b/template/en/default/admin/products/groupcontrol/edit.html.tmpl @@ -42,6 +42,9 @@ <th>MemberControl</th> <th>OtherControl</th> <th>Canedit</th> + <th>editcomponents</th> + <th>canconfirm</th> + <th>editbugs</th> <th>[% terms.Bugs %]</th> </tr> [% FOREACH group = groups %] @@ -50,7 +53,7 @@ <td> [% group.name FILTER html %] </td> - <td align="center" colspan=4> + <td align="center" colspan=7> Disabled </td> <td> @@ -118,6 +121,18 @@ <input type=checkbox value=1 name=canedit_[% group.id %] [% " checked=\"checked\"" IF group.canedit %]> </td> + <td> + <input type=checkbox value=1 name=editcomponents_[% group.id %] + [% " checked=\"checked\"" IF group.editcomponents %]> + </td> + <td> + <input type=checkbox value=1 name=canconfirm_[% group.id %] + [% " checked=\"checked\"" IF group.canconfirm %]> + </td> + <td> + <input type=checkbox value=1 name=editbugs_[% group.id %] + [% " checked=\"checked\"" IF group.editbugs %]> + </td> <td> [% group.bugcount %] </td> @@ -135,21 +150,44 @@ <p> These settings control the relationship of the groups to this product. +</p> <p> If any group has <b>Entry</b> selected, then this product will restrict [% terms.bug %] entry to only those users who are members of all the groups with entry selected. +</p> <p> If any group has <b>Canedit</b> selected, then this product will be read-only for any users who are not members of all of the groups with Canedit selected. ONLY users who are members of all the canedit groups will be able to edit. This is an additional restriction that further restricts what can be edited by a user. +</p> +<p> +The following settings control let you choose privileges on a <b>per-product basis</b>. +This is a convenient way to give privileges to some users for some products +only, without having to give them global privileges which would affect all +products: +</p> +<p> +Any group having <b>editcomponents</b> selected allows users who are +in this group to edit all aspects of this product, including components, +milestones and versions. +</p> +<p> +Any group having <b>canconfirm</b> selected allows users who are +in this group to confirm [% terms.bugs %] in this product. +</p> +<p> +Any group having <b>editbugs</b> selected allows users who are +in this group to edit all fields of [% terms.bugs %] in this product. +</p> <p> The <b>MemberControl</b> and <b>OtherControl</b> fields indicate which [% terms.bugs %] will be placed in this group according to the following definitions. -<br> +</p> + <table border=1> <tr> <th> diff --git a/template/en/default/admin/products/list-classifications.html.tmpl b/template/en/default/admin/products/list-classifications.html.tmpl index 7a30bcd66..444cb5204 100644 --- a/template/en/default/admin/products/list-classifications.html.tmpl +++ b/template/en/default/admin/products/list-classifications.html.tmpl @@ -64,8 +64,6 @@ data = classifications %] -<p> - [%# No need for the standard edit products footer, as we have an 'add' link in the table %] diff --git a/template/en/default/admin/products/list.html.tmpl b/template/en/default/admin/products/list.html.tmpl index ee76a3b0a..0992de273 100644 --- a/template/en/default/admin/products/list.html.tmpl +++ b/template/en/default/admin/products/list.html.tmpl @@ -33,7 +33,7 @@ in classification '[% classification.name FILTER html %]' [% END %] [% END %] - + [% PROCESS global/header.html.tmpl title = "Select product $classification_title" %] @@ -120,8 +120,6 @@ data = products %] -<p> - [% IF !showbugcounts %] <p><a href="editproducts.cgi?showbugcounts=1[% classification_url_part %]"> diff --git a/template/en/default/admin/products/updated.html.tmpl b/template/en/default/admin/products/updated.html.tmpl index 8a0790d6e..372f15805 100644 --- a/template/en/default/admin/products/updated.html.tmpl +++ b/template/en/default/admin/products/updated.html.tmpl @@ -67,13 +67,14 @@ <a href="editproducts.cgi?action=edit&product= [%- product.name FILTER url_quote %] [%- classification_url_part FILTER none %]">[% product.name FILTER html %]</a>. + </p> [% updated = 1 %] [% END %] [% IF product.description != old_product.description %] <p> - Updated description to:</p> + Updated description to: </p> <p style="margin: 1em 3em 1em 3em">[% product.description FILTER html_light %]</p> [% updated = 1 %] @@ -88,6 +89,7 @@ open for [% END %] new [% terms.bugs %]. + </p> [% updated = 1 %] [% END %] @@ -122,6 +124,7 @@ Updated votes per user from [%+ old_product.votes_per_user FILTER html %] to [%+ product.votes_per_user FILTER html %]. + </p> [% updated = 1 %] [% END %] @@ -130,6 +133,7 @@ Updated maximum votes per [% terms.bug %] from [%+ old_product.max_votes_per_bug FILTER html %] to [%+ product.max_votes_per_bug FILTER html %]. + </p> [% updated = 1 %] [% END %] @@ -138,11 +142,12 @@ Updated number of votes needed to confirm a [% terms.bug %] from [%+ old_product.votes_to_confirm FILTER html %] to [%+ product.votes_to_confirm FILTER html %]. + </p> [% updated = 1 %] [% END %] [% UNLESS updated %] - <p>Nothing changed for product '[% product.name FILTER html %]'. + <p>Nothing changed for product '[% product.name FILTER html %]'.</p> [% END %] [%# Note that this display of changed votes and/or confirmed bugs is @@ -164,6 +169,7 @@ [% ELSE %] →there were none. [% END %] + </p> <p>Checking existing votes in this product for anybody who now has too many total votes...<br> @@ -176,6 +182,7 @@ [% ELSE %] →there were none. [% END %] + </p> <p>Checking unconfirmed [% terms.bugs %] in this product for any which now have sufficient votes...<br> @@ -194,6 +201,7 @@ [% ELSE %] →there were none. [% END %] + </p> [% END %] diff --git a/template/en/default/admin/settings/CVS/Entries b/template/en/default/admin/settings/CVS/Entries index 8ab63e3f3..672ee296d 100644 --- a/template/en/default/admin/settings/CVS/Entries +++ b/template/en/default/admin/settings/CVS/Entries @@ -1,3 +1,3 @@ -/edit.html.tmpl/1.3.4.2/Sat Oct 14 22:05:58 2006//TBUGZILLA-2_22_3 -/updated.html.tmpl/1.2/Mon Jun 20 21:14:43 2005//TBUGZILLA-2_22_3 +/edit.html.tmpl/1.7/Tue Oct 17 19:58:36 2006//TBUGZILLA-3_0 +/updated.html.tmpl/1.2/Mon Jun 20 21:14:43 2005//TBUGZILLA-3_0 D diff --git a/template/en/default/admin/settings/CVS/Tag b/template/en/default/admin/settings/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/admin/settings/CVS/Tag +++ b/template/en/default/admin/settings/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/admin/settings/edit.html.tmpl b/template/en/default/admin/settings/edit.html.tmpl index b0b5e55ee..08a370c6a 100644 --- a/template/en/default/admin/settings/edit.html.tmpl +++ b/template/en/default/admin/settings/edit.html.tmpl @@ -55,7 +55,7 @@ page, and the Default Value will automatically apply to everyone. <th>Preference Text</th> <th>Default Value</th> <th>Enabled</th> - <tr> + </tr> [% FOREACH name = setting_names %] [% checkbox_name = name _ '-enabled' %] @@ -90,7 +90,7 @@ page, and the Default Value will automatically apply to everyone. <tr> <td width="150"></td> <td> - <input type="submit" value="Submit Changes"> + <input type="submit" id="update" value="Submit Changes"> </td> </tr> </table> diff --git a/template/en/default/admin/sudo.html.tmpl b/template/en/default/admin/sudo.html.tmpl index 4e781796c..4b7b607e9 100644 --- a/template/en/default/admin/sudo.html.tmpl +++ b/template/en/default/admin/sudo.html.tmpl @@ -48,8 +48,9 @@ [% ELSE %] enter the login of [% END %] - the <u>u</u>ser to impersonate: + <label for="target_login">the <u>u</u>ser to impersonate</label>: [% INCLUDE global/userselect.html.tmpl + id => "target_login" name => "target_login" value => "$target_login_default" accesskey => "u" @@ -65,9 +66,10 @@ [% END %] <p> - Next, please take a moment to explain why you are doing this:<br> - <input type="text" name="reason" size="80" maxlength="200" value=" - [%- reason_default FILTER html %]"> + Next, please take a moment to explain <label for="reason">why you are doing + this:<br> + <input type="text" id="reason" name="reason" size="80" maxlength="200" + value="[% reason_default FILTER html %]"> </p> <p> @@ -76,12 +78,14 @@ are impersonating them. </p> - [% IF user.get_flag("can_logout") %] + [% IF user.authorizer.can_login %] <p> - Finally, enter your [% terms.Bugzilla %] password: + Finally, enter <label for="Bugzilla_password">your [% terms.Bugzilla %] + password</label>: <input type="hidden" name="Bugzilla_login" value=" [%- user.login FILTER html %]"> - <input type="password" name="Bugzilla_password" maxlength="20" size="20"> + <input type="password" id="Bugzilla_password" name="Bugzilla_password" + maxlength="20" size="20"> <br> This is done for two reasons. First of all, it is done to reduce the chances of someone doing large amounts of damage using your diff --git a/template/en/default/admin/users/CVS/Entries b/template/en/default/admin/users/CVS/Entries index a8b360d3c..2ae15e277 100644 --- a/template/en/default/admin/users/CVS/Entries +++ b/template/en/default/admin/users/CVS/Entries @@ -1,8 +1,8 @@ -/confirm-delete.html.tmpl/1.7.2.4/Sat Oct 14 22:05:58 2006//TBUGZILLA-2_22_3 -/create.html.tmpl/1.1.6.1/Sat Oct 14 22:05:58 2006//TBUGZILLA-2_22_3 -/edit.html.tmpl/1.2.2.3/Sat Oct 14 22:05:58 2006//TBUGZILLA-2_22_3 -/list.html.tmpl/1.1.6.1/Sat Oct 14 20:30:57 2006//TBUGZILLA-2_22_3 -/listselectvars.html.tmpl/1.1/Mon Feb 28 20:41:45 2005//TBUGZILLA-2_22_3 -/search.html.tmpl/1.2/Sun Sep 4 18:45:11 2005//TBUGZILLA-2_22_3 -/userdata.html.tmpl/1.5/Sun Dec 18 07:09:38 2005//TBUGZILLA-2_22_3 +/confirm-delete.html.tmpl/1.15/Fri Nov 10 16:51:29 2006//TBUGZILLA-3_0 +/create.html.tmpl/1.3/Sat Oct 14 22:02:13 2006//TBUGZILLA-3_0 +/edit.html.tmpl/1.8/Fri Oct 20 09:53:06 2006//TBUGZILLA-3_0 +/list.html.tmpl/1.3/Sat Oct 14 20:26:53 2006//TBUGZILLA-3_0 +/listselectvars.html.tmpl/1.1/Mon Feb 28 20:41:45 2005//TBUGZILLA-3_0 +/search.html.tmpl/1.4/Wed Jul 12 12:21:40 2006//TBUGZILLA-3_0 +/userdata.html.tmpl/1.8/Fri Aug 25 08:33:19 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/admin/users/CVS/Tag b/template/en/default/admin/users/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/admin/users/CVS/Tag +++ b/template/en/default/admin/users/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/admin/users/confirm-delete.html.tmpl b/template/en/default/admin/users/confirm-delete.html.tmpl index c52b1a267..0fd4aafa7 100644 --- a/template/en/default/admin/users/confirm-delete.html.tmpl +++ b/template/en/default/admin/users/confirm-delete.html.tmpl @@ -19,7 +19,6 @@ # listselectionvalues: selection values to recreate the current user # list. # editusers: is viewing user member of editusers? - # editcomponents: is viewing user member of editcomponents? # otheruser: Bugzilla::User object of the viewed user. # reporter: number of bugs reported by the user # assignee_or_qa: number of bugs the user is either the assignee @@ -32,7 +31,8 @@ # flags.setter: number of flags the viewed user has set # longdescs: number of bug comments the viewed user has written # namedqueries: number of named queries the user has created - # profiles_activity: number of named queries the user has created + # namedquery_group_map: number of named queries the user has shared + # profiles_activity: number of changes made to other users' profiles # series: number of series the viewed user has created # votes: number of bugs the viewed user has voted on # watch.watched: number of users the viewed user is being watched @@ -56,8 +56,8 @@ %] [% responsibilityterms = { - 'initialowner' => 'Default Assignee', - 'initialqacontact' => 'Default QA Contact' + 'default_assignee' => 'Default Assignee', + 'default_qa_contact' => 'Default QA Contact' } %] @@ -92,21 +92,21 @@ [% FOREACH component = otheruser.product_responsibilities %] <li> [% andstring = '' %] - [% FOREACH responsibility = ['initialowner', 'initialqacontact'] %] - [% IF component.$responsibility == otheruser.id %] + [% FOREACH responsibility = ['default_assignee', 'default_qa_contact'] %] + [% IF component.${responsibility}.id == otheruser.id %] [% andstring %] [% responsibilityterms.$responsibility %] [% andstring = ' and ' %] [% END %] [% END %] for - [% IF editcomponents %] + [% IF user.in_group("editcomponents", component.product_id) %] <a href="editcomponents.cgi?action=edit&product= - [% component.productname FILTER url_quote %]&component= - [% component.componentname FILTER url_quote %]"> + [% component.product.name FILTER url_quote %]&component= + [% component.name FILTER url_quote %]"> [% END %] - [%+ component.productname FILTER html %]: - [% component.componentname FILTER html %] - [% IF editcomponents %] + [%+ component.product.name FILTER html %]: + [% component.name FILTER html %] + [% IF user.in_group("editcomponents", component.product_id) %] </a> [% END %] </li> @@ -124,7 +124,7 @@ one product. </p> <p> - [% IF editcomponents %] + [% IF user.in_group("editcomponents", component.product_id) %] Change this by clicking the product editing links above, [% ELSE %] For now, you can @@ -304,16 +304,34 @@ <li> [% otheruser.login FILTER html %] has [% IF namedqueries == 1 %] - a named query + a [% 'shared' IF namedquery_group_map %] named search [% ELSE %] - [%+ namedqueries %] named queries + [%+ namedqueries FILTER html %] named searches [% END %]. [% IF namedqueries == 1 %] - This named query + This named search [% ELSE %] - These named queries + These named searches [% END %] will be deleted along with the user account. + [% IF namedquery_group_map %] + [% IF namedqueries > 1 %] + Of these, + [% IF namedquery_group_map > 1 %] + [%+ namedquery_group_map FILTER html %] are + [% ELSE %] + one is + [% END %] + shared. + [% END %] + Other users will not be able to use + [% IF namedquery_group_map > 1 %] + these shared named searches + [% ELSE %] + this shared named search + [% END %] + any more. + [% END %] </li> [% END %] [% IF profile_setting %] @@ -426,7 +444,7 @@ <form method="post" action="editusers.cgi"> <p> - <input type="submit" value="Yes, delete" /> + <input type="submit" id="delete" value="Yes, delete"/> <input type="hidden" name="action" value="delete" /> <input type="hidden" name="userid" value="[% otheruser.id %]" /> <input type="hidden" name="token" value="[% token FILTER html %]"> diff --git a/template/en/default/admin/users/create.html.tmpl b/template/en/default/admin/users/create.html.tmpl index ffff303d7..66cdd91e0 100644 --- a/template/en/default/admin/users/create.html.tmpl +++ b/template/en/default/admin/users/create.html.tmpl @@ -39,7 +39,7 @@ %] </table> <p> - <input type="submit" value="Add" /> + <input type="submit" id="add" value="Add"/> <input type="hidden" name="action" value="new" /> <input type="hidden" name="token" value="[% token FILTER html %]"> [% INCLUDE listselectionhiddenfields %] diff --git a/template/en/default/admin/users/edit.html.tmpl b/template/en/default/admin/users/edit.html.tmpl index 2d19a0660..abc124616 100644 --- a/template/en/default/admin/users/edit.html.tmpl +++ b/template/en/default/admin/users/edit.html.tmpl @@ -25,7 +25,7 @@ # canbless) for viewed user. #%] -[% title = BLOCK %]Edit user [% otheruser.login FILTER html %][% END %] +[% title = BLOCK %]Edit user [% otheruser.identity FILTER html %][% END %] [% PROCESS global/header.html.tmpl title = title @@ -103,11 +103,15 @@ </table> <p> - <input type="submit" value="Update" /> + <input type="submit" id="update" value="Update" /> <input type="hidden" name="userid" value="[% otheruser.id %]" /> <input type="hidden" name="action" value="update" /> <input type="hidden" name="token" value="[% token FILTER html %]"> [% INCLUDE listselectionhiddenfields %] + + or <a href="editusers.cgi?action=activity&userid=[% otheruser.id %]" + title="View the account log for user ' + [%- otheruser.login FILTER html %]'">View this user's account log</a> </p> </form> <p> @@ -127,7 +131,7 @@ [% IF Param('allowuserdeletion') && editusers %] <form method="post" action="editusers.cgi"> <p> - <input type="submit" value="Delete User" /> + <input type="submit" id="delete" value="Delete User" /> <input type="hidden" name="action" value="del" /> <input type="hidden" name="userid" value="[% otheruser.id %]" /> [% INCLUDE listselectionhiddenfields %] diff --git a/template/en/default/admin/users/list.html.tmpl b/template/en/default/admin/users/list.html.tmpl index 227671d4f..41c5016f8 100644 --- a/template/en/default/admin/users/list.html.tmpl +++ b/template/en/default/admin/users/list.html.tmpl @@ -42,6 +42,12 @@ {name => 'realname' heading => 'Real name' } + {heading => 'User Account Log' + content => 'View' + contentlink => 'editusers.cgi?action=activity' _ + '&userid=%%userid%%' _ + listselectionurlparams + } ] %] diff --git a/template/en/default/admin/users/search.html.tmpl b/template/en/default/admin/users/search.html.tmpl index 4cb51ca94..ae37bd10d 100644 --- a/template/en/default/admin/users/search.html.tmpl +++ b/template/en/default/admin/users/search.html.tmpl @@ -12,6 +12,7 @@ # The Original Code is the Bugzilla Bug Tracking System. # # Contributor(s): Marc Schumann <wurblzap@gmail.com> + # David Lawrence <dkl@redhat.com> #%] [%# INTERFACE: @@ -35,7 +36,13 @@ <form name="f" method="get" action="editusers.cgi"> <input type="hidden" name="action" value="list" /> -<p><label for="matchstr">List users with login name matching</label> +<p><label for="matchvalue">List users with</label> +<select id="matchvalue" name="matchvalue"> + <option value="login_name">login name</option> + <option value="realname">real name</option> + <option value="userid">user id</option> +</select> +<label for="matchstr">matching</label> <input size="32" name="matchstr" id="matchstr" /> <select name="matchtype"> <option value="substr" selected="selected">case-insensitive substring</option> @@ -43,7 +50,7 @@ <option value="notregexp">not (case-insensitive regexp)</option> <option value="exact">exact (find this user)</option> </select> -<input type="submit" value="Search" /></p> +<input type="submit" id="search" value="Search" /></p> [% IF restrictablegroups.size %] <p><input type="checkbox" name="grouprestrict" value="1" id="grouprestrict" /> diff --git a/template/en/default/admin/users/userdata.html.tmpl b/template/en/default/admin/users/userdata.html.tmpl index 672e180bf..f495eb0f1 100644 --- a/template/en/default/admin/users/userdata.html.tmpl +++ b/template/en/default/admin/users/userdata.html.tmpl @@ -28,8 +28,6 @@ <input size="64" maxlength="255" name="login" id="login" value="[% otheruser.login FILTER html %]" /> [% IF editform %] - <input type="hidden" name="loginold" - value="[% otheruser.login FILTER html %]" /> [% IF !otheruser.groups.bz_sudo_protect %] <br /> <a href="relogin.cgi?action=prepare-sudo&target_login= @@ -48,10 +46,6 @@ <input size="64" maxlength="255" name="name" autocomplete="off" id="name" value="[% otheruser.name FILTER html %]" /> - [% IF editform %] - <input type="hidden" name="nameold" - value="[% otheruser.name FILTER html %]" /> - [% END %] [% ELSE %] [% otheruser.name FILTER html %] [% END %] @@ -69,18 +63,29 @@ [% END %] </td> </tr> + <tr> + <th><label for="disable_mail">Bugmail Disabled:</label></th> + <td> + <input type="checkbox" name="disable_mail" id="disable_mail" value="1" + [% IF otheruser.email_disabled %] checked="checked" [% END %] /> + (This affects bugmail and whinemail, not password-reset or other + non-bug-related emails) + </td> + </tr> <tr> <th><label for="disabledtext">Disable text:</label></th> <td> - <textarea name="disabledtext" rows="10" - id="disabledtext" - cols="60">[% otheruser.disabledtext FILTER html %]</textarea><br /> + [% INCLUDE global/textarea.html.tmpl + name = 'disabledtext' + id = 'disabledtext' + minrows = 2 + maxrows = 10 + defaultrows = 10 + cols = 60 + defaultcontent = otheruser.disabledtext + %]<br> (If non-empty, then the account will be disabled, and this text should explain why.) - [% IF editform %] - <input type="hidden" name="disabledtextold" - value="[% otheruser.disabledtext FILTER html %]" /> - [% END %] </td> </tr> [% END %] diff --git a/template/en/default/admin/versions/CVS/Entries b/template/en/default/admin/versions/CVS/Entries index 11558972a..fa56029b6 100644 --- a/template/en/default/admin/versions/CVS/Entries +++ b/template/en/default/admin/versions/CVS/Entries @@ -1,10 +1,10 @@ -/confirm-delete.html.tmpl/1.3.4.1/Sat Oct 14 22:05:58 2006//TBUGZILLA-2_22_3 -/create.html.tmpl/1.1.8.1/Sat Oct 14 22:05:58 2006//TBUGZILLA-2_22_3 -/created.html.tmpl/1.1/Sun Jan 16 13:56:40 2005//TBUGZILLA-2_22_3 -/deleted.html.tmpl/1.2/Wed Apr 6 00:19:55 2005//TBUGZILLA-2_22_3 -/edit.html.tmpl/1.1.8.1/Sat Oct 14 22:05:58 2006//TBUGZILLA-2_22_3 -/footer.html.tmpl/1.1/Sun Jan 16 13:56:40 2005//TBUGZILLA-2_22_3 -/list.html.tmpl/1.2/Tue Sep 27 22:08:14 2005//TBUGZILLA-2_22_3 -/select-product.html.tmpl/1.2/Tue Sep 27 22:08:14 2005//TBUGZILLA-2_22_3 -/updated.html.tmpl/1.1/Sun Jan 16 13:56:40 2005//TBUGZILLA-2_22_3 +/confirm-delete.html.tmpl/1.7/Mon Jan 8 00:52:53 2007//TBUGZILLA-3_0 +/create.html.tmpl/1.6/Mon Jan 8 00:53:14 2007//TBUGZILLA-3_0 +/created.html.tmpl/1.3/Mon Jan 8 00:53:32 2007//TBUGZILLA-3_0 +/deleted.html.tmpl/1.4/Mon Jan 8 00:53:59 2007//TBUGZILLA-3_0 +/edit.html.tmpl/1.5/Mon Jan 8 00:54:19 2007//TBUGZILLA-3_0 +/footer.html.tmpl/1.3/Mon Jan 8 00:54:38 2007//TBUGZILLA-3_0 +/list.html.tmpl/1.4/Mon Jan 8 00:54:55 2007//TBUGZILLA-3_0 +/select-product.html.tmpl/1.3/Mon Jan 8 00:55:10 2007//TBUGZILLA-3_0 +/updated.html.tmpl/1.4/Mon Jan 8 00:55:28 2007//TBUGZILLA-3_0 D diff --git a/template/en/default/admin/versions/CVS/Tag b/template/en/default/admin/versions/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/admin/versions/CVS/Tag +++ b/template/en/default/admin/versions/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/admin/versions/confirm-delete.html.tmpl b/template/en/default/admin/versions/confirm-delete.html.tmpl index 27e89361c..a621359ad 100644 --- a/template/en/default/admin/versions/confirm-delete.html.tmpl +++ b/template/en/default/admin/versions/confirm-delete.html.tmpl @@ -21,15 +21,13 @@ #%] [%# INTERFACE: - # name: string; The name of the version - # - # bug_count: number; The number of bugs targetted at the version - # - # product: string; The name of the product - # + # product: object; Bugzilla::Product object representing the product to + # which the version belongs. + # version: object; Bugzilla::Version object representing the + # version the user wants to delete. #%] -[% title = BLOCK %]Delete Version of Product '[% product FILTER html %]' +[% title = BLOCK %]Delete Version of Product '[% product.name FILTER html %]' [% END %] [% PROCESS global/header.html.tmpl @@ -43,20 +41,21 @@ </tr> <tr> <td valign="top">Version:</td> - <td valign="top">[% name FILTER html %]</td> + <td valign="top">[% version.name FILTER html %]</td> </tr> <tr> <td valign="top">Version of Product:</td> - <td valign="top">[% product FILTER html %]</td> + <td valign="top">[% product.name FILTER html %]</td> </tr> <tr> <td valign="top">[% terms.Bugs %]:</td> <td valign="top"> -[% IF bug_count %] +[% IF version.bug_count %] <a title="List of [% terms.bugs %] targetted at version ' - [% name FILTER html %]'" - href="buglist.cgi?version=[% name FILTER url_quote %]&product= - [%- product FILTER url_quote %]">[% bug_count %]</a> + [%- version.name FILTER html %]'" + href="buglist.cgi?version=[% version.name FILTER url_quote %]&product= + [%- product.name FILTER url_quote %]"> + [%- version.bug_count FILTER none %]</a> [% ELSE %] None [% END %] @@ -65,34 +64,34 @@ </table> <h2>Confirmation</h2> - -[% IF bug_count %] +[% IF version.bug_count %] + <p> Sorry, there - [% IF bug_count > 1 %] - are [% bug_count %] [%+ terms.bugs %] + [% IF version.bug_count > 1 %] + are [% version.bug_count FILTER none %] [%+ terms.bugs %] [% ELSE %] - is [% bug_count %] [%+ terms.bug %] + is [% version.bug_count FILTER none %] [%+ terms.bug %] [% END %] outstanding for this version. You must move - [% IF bug_count > 1 %] + [% IF version.bug_count > 1 %] those [% terms.bugs %] [% ELSE %] that [% terms.bug %] [% END %] to another version before you can delete this one. - + </p> [% ELSE %] - <p>Do you really want to delete this version?<p> + <p>Do you really want to delete this version?</p> <form method="post" action="editversions.cgi"> - <input type="submit" value="Yes, delete"> + <input type="submit" id="delete" value="Yes, delete"> <input type="hidden" name="action" value="delete"> - <input type="hidden" name="product" value="[% product FILTER html %]"> - <input type="hidden" name="version" value="[% name FILTER html %]"> + <input type="hidden" name="product" value="[% product.name FILTER html %]"> + <input type="hidden" name="version" value="[% version.name FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]"> </form> diff --git a/template/en/default/admin/versions/create.html.tmpl b/template/en/default/admin/versions/create.html.tmpl index 63f6784f7..57ff20022 100644 --- a/template/en/default/admin/versions/create.html.tmpl +++ b/template/en/default/admin/versions/create.html.tmpl @@ -20,15 +20,16 @@ #%] [%# INTERFACE: - # product: string; name of the product the version is being created for + # product: object; Bugzilla::Product object representing the product to + # which the version is being created for #%] -[% title = BLOCK %]Add Version to Product '[% product FILTER html %]'[% END %] -[% h2 = BLOCK %]This page allows you to add a new version to product - '[% product FILTER html %]'.[% END %] +[% title = BLOCK %]Add Version to Product '[% product.name FILTER html %]'[% END %] +[% subheader = BLOCK %]This page allows you to add a new version to product + '[% product.name FILTER html %]'.[% END %] [% PROCESS global/header.html.tmpl title = title - h2 = h2 + subheader = subheader %] <form method="post" action="editversions.cgi"> @@ -39,14 +40,12 @@ value=""></td> </tr> </table> - <input type="submit" value="Add"> + <input type="submit" id="create" value="Add"> <input type="hidden" name="action" value="new"> - <input type="hidden" name='product' value="[% product FILTER html %]"> + <input type="hidden" name='product' value="[% product.name FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]"> </form> -<p> - [% PROCESS admin/versions/footer.html.tmpl no_add_version_link = 1 %] diff --git a/template/en/default/admin/versions/created.html.tmpl b/template/en/default/admin/versions/created.html.tmpl index 84445cccd..a0ce2912e 100644 --- a/template/en/default/admin/versions/created.html.tmpl +++ b/template/en/default/admin/versions/created.html.tmpl @@ -20,24 +20,23 @@ #%] [%# INTERFACE: - # name: string; the name of the newly created version - # - # product: string; the name of the product the version belongs to + # product: object; Bugzilla::Product object representing the product to + # which the version belongs. + # version: object; Bugzilla::Version object representing the + # newly created version #%] [% title = BLOCK %]Adding new Version of Product - '[% product FILTER html %]'[% END %] + '[% product.name FILTER html %]'[% END %] [% PROCESS global/header.html.tmpl title = title %] -<p>The version '<a title="Edit version '[% name FILTER html %]' of product ' - [%- product FILTER html %]'" +<p>The version '<a title="Edit version '[% version.name FILTER html %]' of product ' + [%- product.name FILTER html %]'" href="editversions.cgi?action=edit&product= - [%- product FILTER url_quote %]&version=[% name FILTER url_quote %]"> - [%- name FILTER html %]</a>' has been created.</p> - -<p> + [%- product.name FILTER url_quote %]&version=[% version.name FILTER url_quote %]"> + [%- version.name FILTER html %]</a>' has been created.</p> [% PROCESS admin/versions/footer.html.tmpl %] diff --git a/template/en/default/admin/versions/deleted.html.tmpl b/template/en/default/admin/versions/deleted.html.tmpl index 2ec3ebe10..38232a9bd 100644 --- a/template/en/default/admin/versions/deleted.html.tmpl +++ b/template/en/default/admin/versions/deleted.html.tmpl @@ -20,21 +20,19 @@ #%] [%# INTERFACE: - # name: string; the name of the deleted version. - # - # product: string; the name of the product the version belonged to - # + # product: object; Bugzilla::Product object representing the product to + # which the version belongs. + # version: object; Bugzilla::Version object representing the + # version the user deleted. #%] -[% title = BLOCK %]Deleted Version '[% name FILTER html %]' of Product - '[% product FILTER html %]'[% END %] +[% title = BLOCK %]Deleted Version '[% version.name FILTER html %]' of Product + '[% product.name FILTER html %]'[% END %] [% PROCESS global/header.html.tmpl title = title %] -<p>Version '[% name FILTER html %]' deleted.</p> - -<p> +<p>Version '[% version.name FILTER html %]' deleted.</p> [% PROCESS admin/versions/footer.html.tmpl no_edit_version_link = 1 diff --git a/template/en/default/admin/versions/edit.html.tmpl b/template/en/default/admin/versions/edit.html.tmpl index f5f645375..632c7a5e7 100644 --- a/template/en/default/admin/versions/edit.html.tmpl +++ b/template/en/default/admin/versions/edit.html.tmpl @@ -20,15 +20,16 @@ #%] [%# INTERFACE: - # name: string; The name of the version - # - # product: string; The product the version belongs to + # product: object; Bugzilla::Product object representing the product to + # which the version belongs. + # version: object; Bugzilla::Version object representing the + # version the user wants to edit. #%] [% PROCESS global/variables.none.tmpl %] -[% title = BLOCK %]Edit Version '[% name FILTER html %]' of product ' - [%- product FILTER html %]'[% END %] +[% title = BLOCK %]Edit Version '[% version.name FILTER html %]' of product ' + [%- product.name FILTER html %]'[% END %] [% PROCESS global/header.html.tmpl title = title %] @@ -39,20 +40,18 @@ <tr> <th valign="top"><label for="version">Version:</label></th> <td><input id="version" size="64" maxlength="64" name="version" value=" - [%- name FILTER html %]"></td> + [%- version.name FILTER html %]"></td> </tr> </table> - <input type="hidden" name="versionold" value="[% name FILTER html %]"> + <input type="hidden" name="versionold" value="[% version.name FILTER html %]"> <input type="hidden" name="action" value="update"> - <input type="hidden" name="product" value="[% product FILTER html %]"> + <input type="hidden" name="product" value="[% product.name FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]"> - <input type="submit" value="Update"> + <input type="submit" id="update" value="Update"> </form> -<p> - [% PROCESS admin/versions/footer.html.tmpl no_edit_version_link = 1 %] diff --git a/template/en/default/admin/versions/footer.html.tmpl b/template/en/default/admin/versions/footer.html.tmpl index 252005697..5d3f259a2 100644 --- a/template/en/default/admin/versions/footer.html.tmpl +++ b/template/en/default/admin/versions/footer.html.tmpl @@ -20,10 +20,9 @@ #%] [%# INTERFACE: - # name: string; the name of the version - # - # product: string; the name of the product which the version - # belongs/belonged to + # product: object; Bugzilla::Product object representing the product to + # which the version belongs. + # version: object; Bugzilla::Version object representing the version # # no_XXX_link: boolean; if defined, then don't show the corresponding # link. Supported parameters are: @@ -32,35 +31,36 @@ # no_edit_other_versions_link # no_add_version_link #%] - -<p> <hr> +<p> + [% UNLESS no_add_version_link %] - <a title="Add a version to product '[% product FILTER html %]'" + <a title="Add a version to product '[% product.name FILTER html %]'" href="editversions.cgi?action=add&product= - [%- product FILTER url_quote %]">Add</a> a version. + [%- product.name FILTER url_quote %]">Add</a> a version. [% END %] -[% IF name && !no_edit_version_link %] +[% IF version.name && !no_edit_version_link %] Edit version <a - title="Edit Version '[% name FILTER html %]' of product ' - [%- product FILTER html %]'" + title="Edit Version '[% version.name FILTER html %]' of product ' + [%- product.name FILTER html %]'" href="editversions.cgi?action=edit&product= - [%- product FILTER url_quote %]&version=[% name FILTER url_quote %]"> - '[% name FILTER html %]'</a>. + [%- product.name FILTER url_quote %]&version= + [%- version.name FILTER url_quote %]"> + '[% version.name FILTER html %]'</a>. [% END %] [% UNLESS no_edit_other_versions_link %] Edit other versions of product <a href="editversions.cgi?product= - [%- product FILTER url_quote %]">'[% product FILTER html %]'</a>. - + [%- product.name FILTER url_quote %]">'[% product.name FILTER html %]'</a>. + [% END %] Edit product <a href="editproducts.cgi?action=edit&product= - [%- product FILTER url_quote %]">'[% product FILTER html %]'</a>. + [%- product.name FILTER url_quote %]">'[% product.name FILTER html %]'</a>. </p> diff --git a/template/en/default/admin/versions/list.html.tmpl b/template/en/default/admin/versions/list.html.tmpl index b2ed2c343..0df94b8de 100644 --- a/template/en/default/admin/versions/list.html.tmpl +++ b/template/en/default/admin/versions/list.html.tmpl @@ -21,25 +21,24 @@ #%] [%# INTERFACE: - # versions: array of version objects - # showbugcounts: if defined, then bug counts should be included in the table - # product: string; the name of the product we are editing versions for + # product: object; Bugzilla::Product object representing the product to + # which the versions belongs. #%] [% PROCESS global/variables.none.tmpl %] [% title = BLOCK %]Select version of product - '[% product FILTER html %]'[% END %] + '[% product.name FILTER html %]'[% END %] [% PROCESS global/header.html.tmpl title = title %] [% edit_contentlink = BLOCK %]editversions.cgi?action=edit&product= - [%- product FILTER url_quote %]&version=%%name%%[% END %] + [%- product.name FILTER url_quote %]&version=%%name%%[% END %] [% delete_contentlink = BLOCK %]editversions.cgi?action=del&product= - [%- product FILTER url_quote %]&version=%%name%%[% END %] + [%- product.name FILTER url_quote %]&version=%%name%%[% END %] [% bug_count_contentlink = BLOCK %]buglist.cgi?version=%%name%%&product= - [%- product FILTER url_quote %][% END %] + [%- product.name FILTER url_quote %][% END %] [% columns = [ @@ -72,14 +71,12 @@ [% PROCESS admin/table.html.tmpl columns = columns - data = versions + data = product.versions %] -<p> - [% IF ! showbugcounts %] - <p><a href="editversions.cgi?product=[% product FILTER url_quote %]&showbugcounts=1"> + <p><a href="editversions.cgi?product=[% product.name FILTER url_quote %]&showbugcounts=1"> Redisplay table with [% terms.bug %] counts (slower)</a></p> [% END %] diff --git a/template/en/default/admin/versions/select-product.html.tmpl b/template/en/default/admin/versions/select-product.html.tmpl index cba4bab4e..f98d1d123 100644 --- a/template/en/default/admin/versions/select-product.html.tmpl +++ b/template/en/default/admin/versions/select-product.html.tmpl @@ -68,6 +68,4 @@ Redisplay table with [% terms.bug %] counts (slower)</a></p> [% END %] -<p> - [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/admin/versions/updated.html.tmpl b/template/en/default/admin/versions/updated.html.tmpl index 04851adae..851fd638b 100644 --- a/template/en/default/admin/versions/updated.html.tmpl +++ b/template/en/default/admin/versions/updated.html.tmpl @@ -20,29 +20,25 @@ #%] [%# INTERFACE: + # product: object; Bugzilla::Product object representing the product to + # which the version belongs. + # version: object; Bugzilla::Version object representing the + # version the user updated. # - # updated_name: boolean; defined if the 'name' field was updated - # - # name: string; the new name of the version - # - # product: string; the name of the product the version belongs to + # updated: boolean; defined if the 'name' field was updated #%] -[% title = BLOCK %]Updating Version '[% name FILTER html %]' of Product - '[% product FILTER html %]'[% END %] +[% title = BLOCK %]Updating Version '[% version.name FILTER html %]' of Product + '[% product.name FILTER html %]'[% END %] [% PROCESS global/header.html.tmpl title = title %] -[% IF updated_name %] - <p>Updated Version name to: '[% name FILTER html %]'.</p> -[% END %] - -[% UNLESS updated_name %] - <p>Nothing changed for version '[% name FILTER html %]'. +[% IF updated %] + <p>Updated Version name to: '[% version.name FILTER html %]'.</p> +[% ELSE %] + <p>Nothing changed for version '[% version.name FILTER html %]'.</p> [% END %] - -<p> [% PROCESS admin/versions/footer.html.tmpl %] diff --git a/template/en/default/attachment/CVS/Entries b/template/en/default/attachment/CVS/Entries index df5845908..741202c79 100644 --- a/template/en/default/attachment/CVS/Entries +++ b/template/en/default/attachment/CVS/Entries @@ -1,12 +1,15 @@ -/choose.html.tmpl/1.3/Mon Aug 23 15:34:30 2004//TBUGZILLA-2_22_3 -/content-types.html.tmpl/1.5/Sun Feb 27 10:07:52 2005//TBUGZILLA-2_22_3 -/create.html.tmpl/1.22.2.3/Wed Mar 8 22:18:42 2006//TBUGZILLA-2_22_3 -/created.html.tmpl/1.11.2.1/Tue Feb 21 16:02:25 2006//TBUGZILLA-2_22_3 -/diff-file.html.tmpl/1.5/Fri Feb 25 15:27:24 2005//TBUGZILLA-2_22_3 -/diff-footer.html.tmpl/1.2/Sun Jan 18 18:39:16 2004//TBUGZILLA-2_22_3 -/diff-header.html.tmpl/1.12.2.1/Tue Feb 21 16:02:25 2006//TBUGZILLA-2_22_3 -/edit.html.tmpl/1.30.2.2/Fri Jun 16 13:27:58 2006//TBUGZILLA-2_22_3 -/list.html.tmpl/1.25.2.2/Sat Oct 14 21:07:19 2006//TBUGZILLA-2_22_3 -/show-multiple.html.tmpl/1.15.12.2/Sat Oct 14 21:07:19 2006//TBUGZILLA-2_22_3 -/updated.html.tmpl/1.11/Mon Feb 2 21:57:29 2004//TBUGZILLA-2_22_3 +/choose.html.tmpl/1.5/Mon Jan 8 20:33:35 2007//TBUGZILLA-3_0 +/confirm-delete.html.tmpl/1.4/Mon Jan 8 00:55:46 2007//TBUGZILLA-3_0 +/content-types.html.tmpl/1.5/Sun Feb 27 10:07:52 2005//TBUGZILLA-3_0 +/create.html.tmpl/1.31/Fri Nov 10 16:51:29 2006//TBUGZILLA-3_0 +/created.html.tmpl/1.13/Thu Oct 19 19:23:16 2006//TBUGZILLA-3_0 +/createformcontents.html.tmpl/1.1/Sat Jun 17 23:24:35 2006//TBUGZILLA-3_0 +/delete_reason.txt.tmpl/1.1/Mon Apr 17 20:19:36 2006//TBUGZILLA-3_0 +/diff-file.html.tmpl/1.5/Fri Feb 25 15:27:24 2005//TBUGZILLA-3_0 +/diff-footer.html.tmpl/1.2/Sun Jan 18 18:39:16 2004//TBUGZILLA-3_0 +/diff-header.html.tmpl/1.15/Tue Oct 17 19:58:37 2006//TBUGZILLA-3_0 +/edit.html.tmpl/1.41.2.1/Fri Mar 2 06:56:45 2007//TBUGZILLA-3_0 +/list.html.tmpl/1.37/Tue Jan 23 19:04:27 2007//TBUGZILLA-3_0 +/show-multiple.html.tmpl/1.22/Fri Dec 22 19:41:45 2006//TBUGZILLA-3_0 +/updated.html.tmpl/1.12/Thu Oct 19 19:23:16 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/attachment/CVS/Tag b/template/en/default/attachment/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/attachment/CVS/Tag +++ b/template/en/default/attachment/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/attachment/choose.html.tmpl b/template/en/default/attachment/choose.html.tmpl index 2f7b86f19..bce392fbf 100644 --- a/template/en/default/attachment/choose.html.tmpl +++ b/template/en/default/attachment/choose.html.tmpl @@ -29,15 +29,15 @@ <form name="choose-id" method="get" action="attachment.cgi"> <p>Access an attachment by entering its ID into the form below:</p> <p>Attachment ID: <input name="id" size="6"> - <button name="action" value="edit"> Edit </button> - <button name="action" value="view">View</button> + <button name="action" value="edit" id="edit">Details</button> + <button name="action" value="view" id="view">View</button> </p> </form> <form method="get" action="show_bug.cgi"> <p>Or, access it from the list of attachments in its associated [% terms.bug %] report:</p> <p>[% terms.Bug %] ID: <input name="id" size="6"> - <input type="submit" name="action" value="View"> + <input type="submit" name="action" value="View" id="action"> </p> </form> diff --git a/template/en/default/attachment/confirm-delete.html.tmpl b/template/en/default/attachment/confirm-delete.html.tmpl new file mode 100644 index 000000000..0b8bc291a --- /dev/null +++ b/template/en/default/attachment/confirm-delete.html.tmpl @@ -0,0 +1,91 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + #%] + +[%# INTERFACE: + # a: attachment object; attachment the user wants to delete. + # token: string; The token used to identify the session. + #%] + +[% PROCESS global/variables.none.tmpl %] + +[% title = BLOCK %] + Delete Attachment [% a.id FILTER html %] of + [%+ "$terms.Bug " _ a.bug_id FILTER bug_link(a.bug_id) FILTER none %] +[% END %] + +[% PROCESS global/header.html.tmpl title = title %] + +<table border="1" cellpadding="4" cellspacing="0"> + <tr bgcolor="#6666FF"> + <th valign="top" align="left">Field</th> + <th valign="top" align="left">Value</th> + </tr> + <tr> + <td valign="top">Attachment ID:</td> + <td valign="top"> + <a href="attachment.cgi?id=[% a.id FILTER html %]">[% a.id FILTER html %]</a> + </td> + </tr> + <tr> + <td valign="top">File name:</td> + <td valign="top">[% a.filename FILTER html %]</td> + </tr> + <tr> + <td valign="top">Description:</td> + <td valign="top">[% a.description FILTER html %]</td> + </tr> + <tr> + <td valign="top">Contained in [% terms.Bug %]:</td> + <td valign="top">[% a.bug_id FILTER bug_link(a.bug_id) FILTER none %]</td> + </tr> + <tr> + <td valign="top">Creator:</td> + <td valign="top">[% a.attacher.identity FILTER html %]</td> + </tr> + <tr> + <td valign="top">Creation Date:</td> + <td valign="top">[% a.attached FILTER time %]</td> + </tr> +</table> + +<h2>Confirmation</h2> + +<table border="0" cellpadding="20" width="70%" bgcolor="red"> + <tr> + <td> + The content of this attachment will be deleted in an <b>irreversible</b> way. + </td> + </tr> +</table> + +<p>Do you really want to delete this attachment?</p> + +<form action="attachment.cgi" method="POST"> + <label for="reason">Reason of the deletion:</label> + <input type="text" id="reason" name="reason" value="" size="80" maxlength="200"> + <br> + <input type="submit" value="Yes, delete" id="delete"> + <input type="hidden" name="action" value="delete"> + <input type="hidden" name="id" value="[% a.id FILTER html %]"> + <input type="hidden" name="token" value="[% token FILTER html %]"> +</form> + +<p> + No, cancel this deletion and return to + [%+ "$terms.bug " _ a.bug_id FILTER bug_link(a.bug_id) FILTER none %]. +</p> + +[% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/attachment/create.html.tmpl b/template/en/default/attachment/create.html.tmpl index aceb3fc97..381c75901 100644 --- a/template/en/default/attachment/create.html.tmpl +++ b/template/en/default/attachment/create.html.tmpl @@ -19,182 +19,34 @@ # Contributor(s): Myk Melez <myk@mozilla.org> # Joel Peshkin <bugreport@peshkin.net> # Erik Stambaugh <erik@dasbistro.com> + # Marc Schumann <wurblzap@gmail.com> #%] [% PROCESS global/variables.none.tmpl %] [%# Define strings that will serve as the title and header of this page %] -[% title = BLOCK %]Create New Attachment for [% terms.Bug %] #[% bugid %][% END %] -[% h1 = BLOCK %]Create New Attachment for - [%+ GetBugLink(bugid, "$terms.Bug $bugid") %][% END %] -[% h2 = BLOCK %][% bugsummary FILTER html %][% END %] +[% title = BLOCK %]Create New Attachment for [% terms.Bug %] #[% bug.bug_id %][% END %] +[% header = BLOCK %]Create New Attachment for + [%+ "$terms.Bug $bug.bug_id" FILTER bug_link(bug.bug_id) FILTER none %][% END %] +[% subheader = BLOCK %][% bug.short_desc FILTER html %][% END %] [% PROCESS global/header.html.tmpl title = title - h1 = h1 - h2 = h2 - style = " - table.attachment_entry th { - text-align: right; - vertical-align: baseline; - white-space: nowrap; - } - - table.attachment_entry td { - text-align: left; - vertical-align: baseline; - padding-bottom: 5px; - } - - table#flags th, table#flags td { - text-align: left; - vertical-align: baseline; - font-size: small; - } - " - onload="setContentTypeDisabledState();" + header = header + subheader = subheader + onload="setContentTypeDisabledState(document.entryform);" + style_urls = [ 'skins/standard/create_attachment.css' ] + javascript_urls = [ "js/attachment.js" ] %] -[% IF Param("allow_attach_url") %] - <script type="text/javascript"> - - function URLFieldHandler() { - var field_attachurl = document.getElementById("attachurl"); - var greyfields = new Array("data", "ispatch", "autodetect", - "list", "manual", "bigfile", - "contenttypeselection", - "contenttypeentry"); - var i; - if (field_attachurl.value.match(/^\s*$/)) { - for (i = 0; i < greyfields.length; i++) { - thisfield = document.getElementById(greyfields[i]); - if (thisfield) { - thisfield.removeAttribute("disabled"); - } - } - } else { - for (i = 0; i < greyfields.length; i++) { - thisfield = document.getElementById(greyfields[i]); - if (thisfield) { - thisfield.setAttribute("disabled", "disabled"); - } - } - } - } - - function DataFieldHandler() { - var field_data = document.getElementById("data"); - var greyfields = new Array("attachurl"); - if (field_data.value.match(/^\s*$/)) { - var i; - for (i = 0; i < greyfields.length; i++) { - thisfield = document.getElementById(greyfields[i]); - if (thisfield) { - thisfield.removeAttribute("disabled"); - } - } - } else { - for (i = 0; i < greyfields.length; i++) { - thisfield = document.getElementById(greyfields[i]); - if (thisfield) { - thisfield.setAttribute("disabled", "disabled"); - } - } - } - } - - </script> -[% END %] - - <form name="entryform" method="post" action="attachment.cgi" enctype="multipart/form-data"> - <input type="hidden" name="bugid" value="[% bugid %]"> + <input type="hidden" name="bugid" value="[% bug.bug_id %]"> <input type="hidden" name="action" value="insert"> <table class="attachment_entry"> - <tr> - <th><label for="data">File:</label></th> - <td> - <em>Enter the path to the file on your computer.</em><br> - <input type="file" id="data" name="data" size="50" - [% IF Param("allow_attach_url") %] - onchange="DataFieldHandler()" - [% END %] - > - </td> - </tr> - [% IF Param("maxlocalattachment") %] - <tr> - <th>BigFile:</th> - <td> - <input type="checkbox" id="bigfile" - name="bigfile" value="bigfile"> - <label for="bigfile"> - Big File - Stored locally and may be purged - </label> - </td> - </tr> - [% END %] - [% IF Param("allow_attach_url") %] - <tr> - <th><label for="attachurl">AttachURL:</label></th> - <td> - <em>URL to be attached instead.</em><br> - <input type="text" id="attachurl" name="attachurl" size="60" - maxlength="2000" - onkeyup="URLFieldHandler()" onblur="URLFieldHandler()"> - </td> - </tr> - [% END %] - <tr> - <th><label for="description">Description:</label></th> - <td> - <em>Describe the attachment briefly.</em><br> - <input type="text" id="description" name="description" size="60" maxlength="200"> - </td> - </tr> - <tr> - <th></th> - <td> - </td> - </tr> - <tr> - <th>Content Type:</th> - <td> - <em>If the attachment is a patch, check the box below.</em><br> - <input type="checkbox" id="ispatch" name="ispatch" value="1" - onchange="setContentTypeDisabledState();"> - <label for="ispatch">patch</label><br><br> + [% PROCESS attachment/createformcontents.html.tmpl %] - <em>Otherwise, choose a method for determining the content type.</em><br> - <input type="radio" id="autodetect" - name="contenttypemethod" value="autodetect" checked="checked"> - <label for="autodetect">auto-detect</label><br> - <input type="radio" id="list" - name="contenttypemethod" value="list"> - <label for="list">select from list:</label> - <select name="contenttypeselection" id="contenttypeselection" - onchange="this.form.contenttypemethod[1].checked = true;"> - [% PROCESS "attachment/content-types.html.tmpl" %] - </select><br> - <input type="radio" id="manual" - name="contenttypemethod" value="manual"> - <label for="manual">enter manually:</label> - <input type="text" name="contenttypeentry" id="contenttypeentry" - size="30" maxlength="200" - onchange="if (this.value) this.form.contenttypemethod[2].checked = true;"> - </td> - </tr> - [% IF (Param("insidergroup") && UserInGroup(Param("insidergroup"))) %] - <tr> - <th>Privacy:</th> - <td> - <em>If the attachment is private, check the box below.</em><br> - <input type="checkbox" name="isprivate" id="isprivate" value="1"> - <label for="isprivate">Private</label> - </td> - </tr> - [% END %] + [%# Additional fields for attachments on existing bugs: %] <tr> <th>Obsoletes:</th> <td> @@ -202,7 +54,7 @@ [% IF attachments.size %] [% FOREACH attachment = attachments %] [% IF ((attachment.isprivate == 0) || (Param("insidergroup") - && UserInGroup(Param("insidergroup")))) %] + && user.in_group(Param("insidergroup")))) %] <input type="checkbox" id="[% attachment.id %]" name="obsolete" value="[% attachment.id %]"> <a href="attachment.cgi?id=[% attachment.id %]&action=edit">[% attachment.id %]: [% attachment.description FILTER html %]</a><br> @@ -214,7 +66,7 @@ </td> </tr> - [% IF (user.id != bugassignee_id) AND user.groups.editbugs %] + [% IF (user.id != bug.assigned_to.id) AND user.in_group("editbugs", bug.product_id) %] <tr> <th>Reassignment:</th> <td> @@ -225,46 +77,37 @@ </td> </tr> [% END %] - <tr> - <td> </td> - <td> - [% IF flag_types.size > 0 %] - [% PROCESS "flag/list.html.tmpl" bug_id=bugid attach_id=attachid %]<br> - [% END %] - </td> - </tr> <tr> <th><label for="comment">Comment:</label></th> <td> <em>(optional) Add a comment about this attachment to the [% terms.bug %].</em><br> - <textarea wrap="soft" id="comment" name="comment" rows="6" cols="[% constants.COMMENT_COLS FILTER none %]"></textarea> + [% INCLUDE global/textarea.html.tmpl + name = 'comment' + id = 'comment' + minrows = 6 + maxrows = 15 + cols = constants.COMMENT_COLS + wrap = 'soft' + %] </td> </tr> + [% IF (Param("insidergroup") && user.in_group(Param("insidergroup"))) %] + <tr> + <th>Privacy:</th> + <td> + <em>If the attachment is private, check the box below.</em><br> + <input type="checkbox" name="isprivate" id="isprivate" + value="1" onClick="updateCommentPrivacy(this)"> + <label for="isprivate">Private</label> + </td> + </tr> + [% END %] <tr> <th> </th> - <td><input type="submit" value="Submit"></td> + <td><input type="submit" id="create" value="Submit"></td> </tr> </table> </form> -<script type="text/javascript"> - <!-- - function setContentTypeDisabledState() - { - var entryform = document.entryform; - - var isdisabled = false; - if (entryform.ispatch.checked) - isdisabled = true; - - for (var i=0 ; i<entryform.contenttypemethod.length ; i++) - entryform.contenttypemethod[i].disabled = isdisabled; - - entryform.contenttypeselection.disabled = isdisabled; - entryform.contenttypeentry.disabled = isdisabled; - } - //--> -</script> - [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/attachment/created.html.tmpl b/template/en/default/attachment/created.html.tmpl index 3114b2963..e6037bcba 100644 --- a/template/en/default/attachment/created.html.tmpl +++ b/template/en/default/attachment/created.html.tmpl @@ -32,38 +32,34 @@ [% PROCESS global/header.html.tmpl title = "Changes Submitted" - style = "th { text-align: left; }" %] -<table border="1"> - <tr> - <td> - <h2> - <a title="[% description FILTER html %]" href="attachment.cgi?id=[% attachid %]&action=edit">Attachment #[% attachid %]</a> - to <a href="show_bug.cgi?id=[% bugid %]">[% terms.Bug %] #[% bugid %]</a> Created - </h2> +<dl> + <dt> + <a title="[% description FILTER html %]" href="attachment.cgi?id=[% attachid %]&action=edit">Attachment #[% attachid %]</a> + to [% "$terms.bug $bugid" FILTER bug_link(bugid) %] created + </dt> + <dd> + [% PROCESS "bug/process/bugmail.html.tmpl" mailing_bugid = bugid %] + [% IF convertedbmp %] + <p> + <b>Note:</b> [% terms.Bugzilla %] automatically converted your BMP image file to a + compressed PNG format. + </p> + [% END %] + [% IF contenttypemethod == 'autodetect' %] + <p> + <b>Note:</b> [% terms.Bugzilla %] automatically detected the content type + <em>[% contenttype %]</em> for this attachment. If this is + incorrect, correct the value by + editing the attachment's <a href="attachment.cgi?id=[% attachid %]&action=edit">details</a>. + </p> + [% END %] - [% PROCESS "bug/process/bugmail.html.tmpl" mailing_bugid = bugid %] - [% IF convertedbmp %] - <p> - <b>Note:</b> [% terms.Bugzilla %] automatically converted your BMP image file to a - compressed PNG format. - </p> - [% END %] - [% IF contenttypemethod == 'autodetect' %] - <p> - <b>Note:</b> [% terms.Bugzilla %] automatically detected the content type - <em>[% contenttype %]</em> for this attachment. If this is - incorrect, correct the value by - editing the attachment's <a href="attachment.cgi?id=[% attachid %]&action=edit">details</a>. - </p> - [% END %] - </td> - <td> - <a href="show_bug.cgi?id=[% bugid %]">Go back to [% terms.bug %] #[% bugid %]</a> - </td> - </tr> -</table> + [%# Links to more information about the changed bug. %] + [% Hook.process("links") %] + </dd> +</dl> <p> <a href="attachment.cgi?bugid=[% bugid %]&action=enter">Create diff --git a/template/en/default/attachment/createformcontents.html.tmpl b/template/en/default/attachment/createformcontents.html.tmpl new file mode 100644 index 000000000..2056490c9 --- /dev/null +++ b/template/en/default/attachment/createformcontents.html.tmpl @@ -0,0 +1,100 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # The Initial Developer of the Original Code is Netscape Communications + # Corporation. Portions created by Netscape are + # Copyright (C) 1998 Netscape Communications Corporation. All + # Rights Reserved. + # + # Contributor(s): Myk Melez <myk@mozilla.org> + # Joel Peshkin <bugreport@peshkin.net> + # Erik Stambaugh <erik@dasbistro.com> + # Marc Schumann <wurblzap@gmail.com> + #%] + +<tr> + <th><label for="data">File</label>:</th> + <td> + <em>Enter the path to the file on your computer.</em><br> + <input type="file" id="data" name="data" size="50" + [% IF Param("allow_attach_url") %] + onchange="DataFieldHandler()" + [% END %] + > + </td> +</tr> +[% IF Param("maxlocalattachment") %] +<tr> + <th>BigFile:</th> + <td> + <input type="checkbox" id="bigfile" + name="bigfile" value="bigfile"> + <label for="bigfile"> + Big File - Stored locally and may be purged + </label> + </td> +</tr> +[% END %] +[% IF Param("allow_attach_url") %] +<tr> + <th><label for="attachurl">AttachURL</label>:</th> + <td> + <em>URL to be attached instead.</em><br> + <input type="text" id="attachurl" name="attachurl" size="60" + maxlength="2000" + onkeyup="URLFieldHandler()" onblur="URLFieldHandler()"> + </td> +</tr> +[% END %] +<tr> + <th><label for="description">Description</label>:</th> + <td> + <em>Describe the attachment briefly.</em><br> + <input type="text" id="description" name="description" size="60" maxlength="200"> + </td> +</tr> +<tr> + <th>Content Type:</th> + <td> + <em>If the attachment is a patch, check the box below.</em><br> + <input type="checkbox" id="ispatch" name="ispatch" value="1" + onchange="setContentTypeDisabledState(this.form);"> + <label for="ispatch">patch</label><br><br> + + <em>Otherwise, choose a method for determining the content type.</em><br> + <input type="radio" id="autodetect" + name="contenttypemethod" value="autodetect" checked="checked"> + <label for="autodetect">auto-detect</label><br> + <input type="radio" id="list" + name="contenttypemethod" value="list"> + <label for="list">select from list</label>: + <select name="contenttypeselection" id="contenttypeselection" + onchange="this.form.contenttypemethod[1].checked = true;"> + [% PROCESS "attachment/content-types.html.tmpl" %] + </select><br> + <input type="radio" id="manual" + name="contenttypemethod" value="manual"> + <label for="manual">enter manually</label>: + <input type="text" name="contenttypeentry" id="contenttypeentry" + size="30" maxlength="200" + onchange="if (this.value) this.form.contenttypemethod[2].checked = true;"> + </td> +</tr> +<tr> + <td> </td> + <td> + [% IF flag_types && flag_types.size > 0 %] + [% PROCESS "flag/list.html.tmpl" bug_id=bugid attach_id=attachid %]<br> + [% END %] + </td> +</tr> diff --git a/template/en/default/attachment/delete_reason.txt.tmpl b/template/en/default/attachment/delete_reason.txt.tmpl new file mode 100644 index 000000000..45879f6ca --- /dev/null +++ b/template/en/default/attachment/delete_reason.txt.tmpl @@ -0,0 +1,33 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + #%] + +[%# INTERFACE: + # attachid: ID of the attachment the user wants to delete. + # reason: string; The reason provided by the user. + # date: the date when the request to delete the attachment was made. + #%] + +The content of attachment [% attachid %] has been deleted by + [%+ user.identity %] +[% IF reason %] +who provided the following reason: + +[%+ reason %] +[% ELSE %] +without providing any reason. +[% END %] + +The token used to delete this attachment was generated at [% date FILTER time %]. diff --git a/template/en/default/attachment/diff-header.html.tmpl b/template/en/default/attachment/diff-header.html.tmpl index 45bf202a9..97a6d0527 100644 --- a/template/en/default/attachment/diff-header.html.tmpl +++ b/template/en/default/attachment/diff-header.html.tmpl @@ -207,7 +207,7 @@ tbody.file pre:empty { [% BLOCK diffurl %][% PROCESS viewurl %]&action=diff[% END %] [% IF headers %] - [% h1 = BLOCK %] + [% header = BLOCK %] [% IF attachid %] Attachment #[% attachid %]: [% description FILTER html %] [% ELSE %] @@ -218,7 +218,7 @@ tbody.file pre:empty { [% END %] for <a href="show_bug.cgi?id=[% bugid %]">[% terms.bug %] #[% bugid %]</a> [% END %] - [% h2 = BLOCK %] + [% subheader = BLOCK %] [% bugsummary FILTER html %] [% END %] [% PROCESS global/header.html.tmpl %] @@ -257,7 +257,7 @@ tbody.file pre:empty { [% END %] </select> and this patch - <input type="submit" value="Diff"> + <input type="submit" id="diff" value="Diff"> <input type="hidden" name="action" value="interdiff"> <input type="hidden" name="newid" value="[% attachid %]"> <input type="hidden" name="headers" value="[% headers FILTER html %]"> diff --git a/template/en/default/attachment/edit.html.tmpl b/template/en/default/attachment/edit.html.tmpl index f34c4593e..94581ab56 100644 --- a/template/en/default/attachment/edit.html.tmpl +++ b/template/en/default/attachment/edit.html.tmpl @@ -26,16 +26,16 @@ [% title = BLOCK %] Attachment [% attachment.id %] Details for [% terms.Bug %] [%+ attachment.bug_id %] [% END %] -[% h1 = BLOCK %] +[% header = BLOCK %] Attachment [% attachment.id %] Details for - [%+ GetBugLink(attachment.bug_id, "$terms.Bug ${attachment.bug_id}") %] + [%+ "$terms.Bug ${attachment.bug_id}" FILTER bug_link(attachment.bug_id) FILTER none %] [% END %] -[% h2 = BLOCK %][% bugsummary FILTER html %][% END %] +[% subheader = BLOCK %][% bugsummary FILTER html %][% END %] [% PROCESS global/header.html.tmpl title = title - h1 = h1 - h2 = h2 + header = header + subheader = subheader style = " table.attachment_info th { text-align: right; vertical-align: top; } table.attachment_info td { text-align: left; vertical-align: top; } @@ -82,8 +82,7 @@ // Copy the contents of the diff into the textarea var editFrame = document.getElementById('editFrame'); - editFrame.value = theContent; - editFrame.value += "\n\n"; + editFrame.value = theContent + "\n\n"; has_edited = 1; } @@ -211,23 +210,35 @@ <tr> <td width="25%"> <small> - <b>Description:</b><br> - <textarea rows="3" cols="25" name="description" wrap="soft"> - [%- attachment.description FILTER html %]</textarea><br> + <b><label for="description">Description</label>:</b><br> + [% INCLUDE global/textarea.html.tmpl + id = 'description' + name = 'description' + minrows = 3 + cols = 25 + wrap = 'soft' + defaultcontent = attachment.description + %]<br> [% IF attachment.isurl %] <input type="hidden" name="filename" - value="[% attachment.filename FILTER html %]"><br> + value="[% attachment.filename FILTER html %]"> <input type="hidden" name="contenttypeentry" - value="[% attachment.contenttype FILTER html %]"><br> + value="[% attachment.contenttype FILTER html %]"> [% ELSE %] - <b>Filename:</b><br> - <input type="text" size="20" name="filename" + <b><label for="filename">Filename</label>:</b><br> + <input type="text" size="20" id="filename" name="filename" value="[% attachment.filename FILTER html %]"><br> - <b>Size: </b>[% attachment.datasize FILTER unitconvert %]<br> - - <b>MIME Type:</b><br> - <input type="text" size="20" name="contenttypeentry" + <b>Size:</b> + [% IF attachment.datasize %] + [%+ attachment.datasize FILTER unitconvert %] + [% ELSE %] + <em>deleted</em> + [% END %]<br> + + <b><label for="contenttypeentry">MIME Type</label>:</b><br> + <input type="text" size="20" + id="contenttypeentry" name="contenttypeentry" value="[% attachment.contenttype FILTER html %]"><br> <input type="checkbox" id="ispatch" name="ispatch" value="1" @@ -236,12 +247,13 @@ [% END %] <input type="checkbox" id="isobsolete" name="isobsolete" value="1" [% 'checked="checked"' IF attachment.isobsolete %]> - <label for="isobsolete">obsolete</label><br> - [% IF (Param("insidergroup") && UserInGroup(Param("insidergroup"))) %] - <input type="checkbox" name="isprivate" value="1" - [% " checked" IF attachment.isprivate %]> private<br><br> - [% ELSE %]<br> + <label for="isobsolete">obsolete</label> + [% IF (Param("insidergroup") && user.in_group(Param("insidergroup"))) %] + <input type="checkbox" id="isprivate" name="isprivate" value="1" + [% " checked" IF attachment.isprivate %]> + <label for="isprivate">private</label><br> [% END %] + <br> [% IF flag_types.size > 0 %] [% PROCESS "flag/list.html.tmpl" bug_id = attachment.bug_id @@ -249,23 +261,43 @@ [% END %] <div id="smallCommentFrame"> - <b>Comment (on the [% terms.bug %]):</b><br> - <textarea name="comment" rows="5" cols="25" wrap="soft"></textarea><br> + <b><label for="comment">Comment</label> (on the + [%+ terms.bug %]):</b><br> + [% INCLUDE global/textarea.html.tmpl + id = 'comment' + name = 'comment' + minrows = 5 + cols = 25 + wrap = 'soft' + %]<br> </div> - <input type="submit" value="Submit"><br><br> + <input type="submit" value="Submit" id="update"><br><br> <strong>Actions:</strong> <a href="attachment.cgi?id=[% attachment.id %]">View</a> [% IF attachment.ispatch && patchviewerinstalled %] - | <a href="attachment.cgi?id=[% attachment.id %]&action=diff">Diff</a> + | <a href="attachment.cgi?id=[% attachment.id %]&action=diff">Diff</a> + [% END %] + [% IF Param("allow_attachment_deletion") + && user.groups.admin + && attachment.datasize > 0 %] + | <a href="attachment.cgi?id=[% attachment.id %]&action=delete">Delete</a> [% END %] </small> </td> - [% IF isviewable %] + [% IF !attachment.datasize %] + <td width="75%"><b>The content of this attachment has been deleted.</b></td> + [% ELSIF isviewable %] <td width="75%"> - <textarea id="editFrame" name="comment" wrap="soft" cols="80" - style="height: 400px; width: 100%; display: none;"></textarea> + [% INCLUDE global/textarea.html.tmpl + id = 'editFrame' + name = 'comment' + style = 'height: 400px; width: 100%; display: none' + minrows = 10 + cols = 80 + wrap = 'soft' + %] <iframe id="viewFrame" src="attachment.cgi?id=[% attachment.id %]" style="height: 400px; width: 100%;"> <b>You cannot view the attachment while viewing its details because your browser does not support IFRAMEs. <a href="attachment.cgi?id=[% attachment.id %]">View the attachment on a separate page</a>.</b> @@ -319,7 +351,7 @@ Attachments on this [% terms.Bug %]: [% FOREACH a = attachments %] [% IF a == attachment.id %] - [% a %] + [%+ a %] [% ELSE %] <a href="attachment.cgi?id=[% a %]&action=edit">[% a %]</a> [% END %] diff --git a/template/en/default/attachment/list.html.tmpl b/template/en/default/attachment/list.html.tmpl index 598fbb1b1..99f51064d 100644 --- a/template/en/default/attachment/list.html.tmpl +++ b/template/en/default/attachment/list.html.tmpl @@ -17,55 +17,99 @@ # Rights Reserved. # # Contributor(s): Myk Melez <myk@mozilla.org> + # Frédéric Buclin <LpSolit@gmail.com> #%] +<script type="text/javascript"> + <!-- + function toggle_display(link) { + var table = document.getElementById("attachment_table"); + var rows = table.getElementsByTagName("tr"); + var originalHeight = table.offsetHeight; // Store current height for scrolling + + var toggle; + if (link.innerHTML == "Show Obsolete") { + toggle = ""; // This should be 'table-row', but IE 6 doesn't understand it. + link.innerHTML = "Hide Obsolete"; + } + else { + toggle = "none"; + link.innerHTML = "Show Obsolete"; + } + + for (var i = 0; i < rows.length; i++) { + if (rows[i].className.match('bz_tr_obsolete')) + rows[i].style.display = toggle; + } + + var newHeight = table.offsetHeight; + window.scrollBy(0, newHeight - originalHeight); + + return false; + } + //--> +</script> + <br> -<table cellspacing="0" cellpadding="4" border="1"> +<table id="attachment_table" cellspacing="0" cellpadding="4"> <tr> - <th bgcolor="#cccccc" align="left">Attachment</th> - <th bgcolor="#cccccc" align="left">Type</th> - <th bgcolor="#cccccc" align="left">Creator</th> - <th bgcolor="#cccccc" align="left">Created</th> - <th bgcolor="#cccccc" align="left">Size</th> - [% IF show_attachment_flags %] - <th bgcolor="#cccccc" align="left">Flags</th> - [% END %] - <th bgcolor="#cccccc" align="left">Actions</th> + <th colspan="[% show_attachment_flags ? 3 : 2 %]" align="left"> + <a name="a0" id="a0">Attachments</a> + </th> </tr> + + [% count = 0 %] + [% obsolete_attachments = 0 %] + [% FOREACH attachment = attachments %] + [% count = count + 1 %] [% IF !attachment.isprivate || user.is_insider || attachment.attacher.id == user.id %] - <tr [% "class=\"bz_private\"" IF attachment.isprivate %]> - <td valign="top"> - <a href="attachment.cgi?id=[% attachment.id %]">[% attachment.description FILTER html FILTER obsolete(attachment.isobsolete) %]</a> - </td> - + [% IF attachment.isobsolete %] + [% obsolete_attachments = obsolete_attachments + 1 %] + [% END %] + <tr class="[% "bz_private" IF attachment.isprivate %][%-%] + [%+ "bz_tr_obsolete" IF attachment.isobsolete %]"> <td valign="top"> - [% IF attachment.ispatch %] - <i>patch</i> - [% ELSIF attachment.isurl %] - <i>url</i> - [% ELSE %] - [% attachment.contenttype FILTER html %] + [% IF attachment.datasize %] + <a name="a[% count %]" href="attachment.cgi?id=[% attachment.id %]" + title="View the content of the attachment"> [% END %] - </td> + <b>[% attachment.description FILTER html FILTER obsolete(attachment.isobsolete) %]</b> + [% "</a>" IF attachment.datasize %] - <td valign="top"> - <a href="mailto:[% attachment.attacher.email FILTER html %]"> - [% attachment.attacher.name || attachment.attacher.login FILTER html %] - </a> + <span class="bz_attach_extra_info"> + [% IF attachment.datasize %] + ([% attachment.datasize FILTER unitconvert %], + [% IF attachment.ispatch %] + patch) + [% ELSIF attachment.isurl %] + url) + [% ELSE %] + [%+ attachment.contenttype FILTER html %]) + [% END %] + [% ELSE %] + (<em>deleted</em>) + [% END %] + + <br> + <a href="#attach_[% attachment.id %]" + title="Go to the comment associated with the attachment"> + [%- attachment.attached FILTER time %]</a>, + + <a href="mailto:[% attachment.attacher.email FILTER html %]" + title="Write an email to the creator of the attachment"> + [% attachment.attacher.name || attachment.attacher.login FILTER html %] + </a> + </span> </td> - <td valign="top">[% attachment.attached FILTER time %]</td> - <td valign="top">[% attachment.datasize FILTER unitconvert %]</td> [% IF show_attachment_flags %] - <td valign="top"> + <td class="bz_attach_flags" valign="top"> [% IF attachment.flags.size == 0 %] - <i>none</i> + <i>no flags</i> [% ELSE %] [% FOREACH flag = attachment.flags %] - [% IF flag.setter %] - [% flag.setter.nick FILTER html %]: - [% END %] + [% flag.setter.nick FILTER html %]: [%+ flag.type.name FILTER html FILTER no_break %][% flag.status %] [%+ IF flag.status == "?" && flag.requestee %] ([% flag.requestee.nick FILTER html %]) @@ -86,19 +130,19 @@ [% END %] [% END %] - <tr> - <td colspan="[% show_attachment_flags ? 6 : 5 %]"> - <a href="attachment.cgi?bugid=[% bugid %]&action=enter">Create a New Attachment</a> (proposed patch, testcase, etc.) + <tr class="bz_attach_footer"> + <td colspan="[% show_attachment_flags ? 3 : 2 %]"> + [% IF attachments.size %] + <span class="bz_attach_view_hide"> + [% IF obsolete_attachments %] + <a href="#a0" onClick="return toggle_display(this);">Hide Obsolete</a> ([% obsolete_attachments %]) | + [% END %] + <a href="attachment.cgi?bugid=[% bugid %]&action=viewall">View All</a> + </span> + [% END %] + <a href="attachment.cgi?bugid=[% bugid %]&action=enter">Add an attachment</a> + (proposed patch, testcase, etc.) </td> - [% IF attachments.size %] - <td> - <a href="attachment.cgi?bugid=[% bugid %]&action=viewall">View All</a> - </td> - [% ELSE %] - <td class="bz_disabled"> - View All - </td> - [% END %] </tr> </table> <br> diff --git a/template/en/default/attachment/show-multiple.html.tmpl b/template/en/default/attachment/show-multiple.html.tmpl index 0fa07f374..9c0fc57b0 100644 --- a/template/en/default/attachment/show-multiple.html.tmpl +++ b/template/en/default/attachment/show-multiple.html.tmpl @@ -21,12 +21,17 @@ [% PROCESS global/variables.none.tmpl %] [% filtered_summary = bugsummary FILTER html %] -[% h1 = BLOCK %]View All Attachments for - [%+ GetBugLink(bugid, "$terms.Bug $bugid") %][% END %] +[% header = BLOCK %]View All Attachments for + [%+ "$terms.Bug $bug.bug_id" FILTER bug_link(bug.bug_id) FILTER none %][% END %] + +[% title = BLOCK %] + View All Attachments for [% terms.Bug %] [%+ bug.bug_id FILTER html %] +[% END %] + [% PROCESS global/header.html.tmpl - title = "View All Attachments for $terms.Bug #$bugid" - h1 = h1 - h2 = filtered_summary + title = title + header = header + subheader = filtered_summary style = " table.attachment_info th { text-align: right; vertical-align: top; } table.attachment_info td { text-align: left; vertical-align: top; } @@ -65,9 +70,7 @@ <i>no flags</i> [% ELSE %] [% FOREACH flag = a.flags %] - [% IF flag.setter %] - [% flag.setter.nick FILTER html %]: - [% END %] + [% flag.setter.nick FILTER html %]: [%+ flag.type.name FILTER html %][% flag.status %] [% IF flag.status == "?" && flag.requestee %] ([% flag.requestee.nick FILTER html %]) @@ -84,14 +87,14 @@ </table> [% IF a.isviewable %] - <iframe src="attachment.cgi?id=[% a.id %]&action=view" width="75%" height="350"> + <iframe src="attachment.cgi?id=[% a.id %]" width="75%" height="350"> <b>You cannot view the attachment on this page because your browser does not support IFRAMEs. - <a href="attachment.cgi?id=[% a.id %]&action=view">View the attachment on a separate page</a>.</b> + <a href="attachment.cgi?id=[% a.id %]">View the attachment on a separate page</a>.</b> </iframe> [% ELSE %] <p><b> Attachment cannot be viewed because its MIME type is not text/*, image/*, or application/vnd.mozilla.*. - <a href="attachment.cgi?id=[% a.id %]&action=view">Download the attachment instead</a>. + <a href="attachment.cgi?id=[% a.id %]">Download the attachment instead</a>. </b></p> [% END %] </div> diff --git a/template/en/default/attachment/updated.html.tmpl b/template/en/default/attachment/updated.html.tmpl index de56341e0..a66b74e17 100644 --- a/template/en/default/attachment/updated.html.tmpl +++ b/template/en/default/attachment/updated.html.tmpl @@ -29,25 +29,18 @@ [% PROCESS global/header.html.tmpl title = "Changes Submitted" - style = "th { text-align: left; }" %] -<hr> - -<table border="1"> - <tr> - <td> - <h2>Changes to - <a href="attachment.cgi?id=[% attachid %]&action=edit">attachment [% attachid %]</a> - of [% terms.bug %] [%+ bugid %] submitted - </h2> - [% PROCESS "bug/process/bugmail.html.tmpl" mailing_bugid = bugid %] - </td> - - <td> - <a href="show_bug.cgi?id=[% bugid %]">Back to [% terms.Bug %] #[% bugid %]</a> - </td> - </tr> -</table> +<dl> + <dt>Changes to + <a href="attachment.cgi?id=[% attachid %]&action=edit">attachment [% attachid %]</a> + of [% "$terms.bug $bugid" FILTER bug_link(bugid) %] submitted + </dt> + <dd> + [% PROCESS "bug/process/bugmail.html.tmpl" mailing_bugid = bugid %] + [%# Links to more information about the changed bug. %] + [% Hook.process("links") %] + </dd> +</dl> [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/bug/CVS/Entries b/template/en/default/bug/CVS/Entries index 1f7656d47..eabc23733 100644 --- a/template/en/default/bug/CVS/Entries +++ b/template/en/default/bug/CVS/Entries @@ -1,15 +1,16 @@ -/choose.html.tmpl/1.6/Sun Jan 18 18:39:17 2004//TBUGZILLA-2_22_3 -/comments.html.tmpl/1.25/Mon Jan 9 18:59:54 2006//TBUGZILLA-2_22_3 -/dependency-graph.html.tmpl/1.10/Wed Oct 12 01:04:30 2005//TBUGZILLA-2_22_3 -/dependency-tree.html.tmpl/1.18/Sun Dec 18 22:19:54 2005//TBUGZILLA-2_22_3 -/edit.html.tmpl/1.69.2.5/Wed Dec 27 01:01:43 2006//TBUGZILLA-2_22_3 -/knob.html.tmpl/1.19.2.1/Wed Dec 27 01:01:43 2006//TBUGZILLA-2_22_3 -/navigate.html.tmpl/1.7/Mon Jun 20 19:30:29 2005//TBUGZILLA-2_22_3 -/show-multiple.html.tmpl/1.26/Mon Jan 2 20:45:31 2006//TBUGZILLA-2_22_3 -/show.html.tmpl/1.11.2.1/Sat Oct 14 20:50:44 2006//TBUGZILLA-2_22_3 -/show.xml.tmpl/1.11/Mon Nov 7 20:32:27 2005//TBUGZILLA-2_22_3 -/summarize-time.html.tmpl/1.3/Mon Jan 9 21:49:59 2006//TBUGZILLA-2_22_3 -/time.html.tmpl/1.2/Sun Jan 18 18:39:23 2004//TBUGZILLA-2_22_3 +/choose.html.tmpl/1.7/Wed Jul 12 12:21:40 2006//TBUGZILLA-3_0 +/comments.html.tmpl/1.28/Tue Oct 17 19:58:37 2006//TBUGZILLA-3_0 +/dependency-graph.html.tmpl/1.12/Tue Oct 17 19:58:37 2006//TBUGZILLA-3_0 +/dependency-tree.html.tmpl/1.25/Wed Dec 27 01:28:15 2006//TBUGZILLA-3_0 +/edit.html.tmpl/1.97/Wed Dec 27 00:55:23 2006//TBUGZILLA-3_0 +/field.html.tmpl/1.8/Wed Sep 27 20:37:15 2006//TBUGZILLA-3_0 +/knob.html.tmpl/1.28.2.2/Tue Apr 10 19:02:34 2007//TBUGZILLA-3_0 +/navigate.html.tmpl/1.8/Sat Oct 28 10:25:43 2006//TBUGZILLA-3_0 +/show-multiple.html.tmpl/1.34/Tue Dec 26 16:38:34 2006//TBUGZILLA-3_0 +/show.html.tmpl/1.17/Sun Nov 5 00:18:59 2006//TBUGZILLA-3_0 +/show.xml.tmpl/1.19/Sat Jan 6 23:51:56 2007//TBUGZILLA-3_0 +/summarize-time.html.tmpl/1.8/Sun Jan 7 23:59:20 2007//TBUGZILLA-3_0 +/time.html.tmpl/1.2/Sun Jan 18 18:39:23 2004//TBUGZILLA-3_0 D/activity//// D/create//// D/process//// diff --git a/template/en/default/bug/CVS/Tag b/template/en/default/bug/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/bug/CVS/Tag +++ b/template/en/default/bug/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/bug/activity/CVS/Entries b/template/en/default/bug/activity/CVS/Entries index 75c8155f0..56fb3e562 100644 --- a/template/en/default/bug/activity/CVS/Entries +++ b/template/en/default/bug/activity/CVS/Entries @@ -1,3 +1,3 @@ -/show.html.tmpl/1.7/Mon Feb 2 21:57:29 2004//TBUGZILLA-2_22_3 -/table.html.tmpl/1.10/Mon Dec 12 02:13:05 2005//TBUGZILLA-2_22_3 +/show.html.tmpl/1.8/Tue Oct 17 19:58:37 2006//TBUGZILLA-3_0 +/table.html.tmpl/1.13/Thu Jul 13 18:00:41 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/bug/activity/CVS/Tag b/template/en/default/bug/activity/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/bug/activity/CVS/Tag +++ b/template/en/default/bug/activity/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/bug/activity/show.html.tmpl b/template/en/default/bug/activity/show.html.tmpl index 91743247a..2acaf3af8 100644 --- a/template/en/default/bug/activity/show.html.tmpl +++ b/template/en/default/bug/activity/show.html.tmpl @@ -30,8 +30,8 @@ [% PROCESS global/header.html.tmpl title = "Changes made to $terms.bug $bug_id" - h1 = "Activity log" - h2 = "$terms.Bug <a href=\"show_bug.cgi?id=$bug_id\">$bug_id</a>" + header = "Activity log" + subheader = "$terms.Bug <a href=\"show_bug.cgi?id=$bug_id\">$bug_id</a>" %] <br> diff --git a/template/en/default/bug/activity/table.html.tmpl b/template/en/default/bug/activity/table.html.tmpl index 48fafe847..5bfb79f37 100644 --- a/template/en/default/bug/activity/table.html.tmpl +++ b/template/en/default/bug/activity/table.html.tmpl @@ -17,6 +17,7 @@ # Rights Reserved. # # Contributor(s): Gervase Markham <gerv@gerv.net> + # David D. Kilzer <ddkilzer@kilzer.net> #%] [%# INTERFACE: @@ -70,7 +71,7 @@ [% "</tr><tr>" IF loop.index > 0 %] <td> [% IF change.attachid %] - <a href="attachment.cgi?id=[% change.attachid %]&action=view"> + <a href="attachment.cgi?id=[% change.attachid %]"> Attachment #[% change.attachid %]</a> [% END %] [% change.field %] @@ -84,7 +85,10 @@ [% ELSIF change.fieldname == 'bug_status' %] [% status_descs.${change.removed} FILTER html %] [% ELSIF change.fieldname == 'resolution' %] - [% resolution_descs.${change.removed} FILTER html %] + [% get_resolution(change.removed) FILTER html %] + [% ELSIF change.fieldname == 'blocked' || + change.fieldname == 'dependson' %] + [% change.removed FILTER bug_list_link FILTER none %] [% ELSE %] [% change.removed FILTER html %] [% END %] @@ -101,7 +105,10 @@ [% ELSIF change.fieldname == 'bug_status' %] [% status_descs.${change.added} FILTER html %] [% ELSIF change.fieldname == 'resolution' %] - [% resolution_descs.${change.added} FILTER html %] + [% get_resolution(change.added) FILTER html %] + [% ELSIF change.fieldname == 'blocked' || + change.fieldname == 'dependson' %] + [% change.added FILTER bug_list_link FILTER none %] [% ELSE %] [% change.added FILTER html %] [% END %] diff --git a/template/en/default/bug/choose.html.tmpl b/template/en/default/bug/choose.html.tmpl index c3c2c59b5..65b260bb4 100644 --- a/template/en/default/bug/choose.html.tmpl +++ b/template/en/default/bug/choose.html.tmpl @@ -29,7 +29,7 @@ <p> You may find a single [% terms.bug %] by entering its [% terms.bug %] id here: <input name="id" size="6"> - <input type="submit" value="Show Me This [% terms.Bug %]"> + <input type="submit" id="show" value="Show Me This [% terms.Bug %]"> </p> </form> diff --git a/template/en/default/bug/comments.html.tmpl b/template/en/default/bug/comments.html.tmpl index 1ccf9904c..5add6d54f 100644 --- a/template/en/default/bug/comments.html.tmpl +++ b/template/en/default/bug/comments.html.tmpl @@ -26,11 +26,15 @@ <script type="text/javascript"> <!-- function updateCommentPrivacy(checkbox, id) { - var text_elem = document.getElementById('comment_text_'+id); + var comment_elem = document.getElementById('comment_text_'+id).parentNode; if (checkbox.checked) { - text_elem.parentNode.className='bz_private'; - } else { - text_elem.parentNode.className=''; + if (!comment_elem.className.match('bz_private')) { + comment_elem.className = comment_elem.className.concat(' bz_private'); + } + } + else { + comment_elem.className = + comment_elem.className.replace(/(\s*|^)bz_private(\s*|$)/, '$2'); } } //--> @@ -38,7 +42,7 @@ [% DEFAULT start_at = 0 mode = "show" %] -[% isinsider = Param("insidergroup") && UserInGroup(Param("insidergroup")) %] +[% isinsider = Param("insidergroup") && user.in_group(Param("insidergroup")) %] [% sort_order = user.settings.comment_sort_order.value %] [%# NOTE: (start_at > 0) means we came here from a midair collision, @@ -85,12 +89,12 @@ [% BLOCK a_comment %] [% IF NOT comment.isprivate || isinsider %] - <div [% "class=\"bz_private\" " IF comment.isprivate %] - [% "class=\"bz_comment_hilite\" " IF marks.$count %]> + <div class="bz_comment[% " bz_private" IF comment.isprivate %] + [% " bz_comment_hilite" IF marks.$count %]"> [% IF count == description %] <table> <tr> - <td align="left"> + <th align="left"> <b><a name="c0" href="show_bug.cgi?id=[% bug.bug_id %]#c0"> Description</a>:</b> [% IF mode == "edit" %] @@ -98,16 +102,15 @@ addReplyLink(0); //--></script> [% END %] - </td> + </th> <td align="left" width="30%"> <b>Opened:</b> [% bug.creation_ts FILTER time %] </td> </tr> </table> [% ELSE %] - <br> - <span class="bz_comment"> - ------- <i>Comment + <span class="bz_comment_head"> + <span class="comment_rule">-------</span> <i>Comment <a name="c[% count %]" href="show_bug.cgi?id=[% bug.bug_id %]#c[% count %]"> #[% count %]</a> From <a href="mailto:[% comment.email FILTER html %]"> @@ -118,7 +121,7 @@ <script type="text/javascript"><!-- addReplyLink([% count %]); //--></script> [% END %] - ------- + <span class="comment_rule">-------</span> </span> [% END %] @@ -130,10 +133,11 @@ <input type="checkbox" name="isprivate-[% count %]" value="1" onClick="updateCommentPrivacy(this, [% count %])" id="isprivate-[% count %]" - [% " checked=\"checked\"" IF comment.isprivate %]> Private + [% " checked=\"checked\"" IF comment.isprivate %]> + <label for="isprivate-[% count %]">Private</label> </i> [% END %] - [% IF UserInGroup(Param('timetrackinggroup')) && + [% IF user.in_group(Param('timetrackinggroup')) && (comment.work_time > 0 || comment.work_time < 0) %] <br> Additional hours worked: diff --git a/template/en/default/bug/create/CVS/Entries b/template/en/default/bug/create/CVS/Entries index 90cfec8c2..bc26c241b 100644 --- a/template/en/default/bug/create/CVS/Entries +++ b/template/en/default/bug/create/CVS/Entries @@ -1,8 +1,9 @@ -/comment-guided.txt.tmpl/1.4/Thu Apr 7 23:59:59 2005//TBUGZILLA-2_22_3 -/comment.txt.tmpl/1.3.6.1/Tue Feb 21 15:19:56 2006//TBUGZILLA-2_22_3 -/create-guided.html.tmpl/1.26.4.5/Thu Aug 23 15:36:57 2007//TBUGZILLA-2_22_3 -/create.html.tmpl/1.54.2.3/Sat Oct 14 20:30:57 2006//TBUGZILLA-2_22_3 -/created.html.tmpl/1.9/Wed Jul 27 20:51:33 2005//TBUGZILLA-2_22_3 -/make-template.html.tmpl/1.8/Tue Dec 13 20:43:49 2005//TBUGZILLA-2_22_3 -/user-message.html.tmpl/1.4/Sun Mar 7 23:27:31 2004//TBUGZILLA-2_22_3 +/comment-guided.txt.tmpl/1.5/Sat Feb 10 21:23:59 2007//TBUGZILLA-3_0 +/comment.txt.tmpl/1.4/Tue Feb 21 15:20:14 2006//TBUGZILLA-3_0 +/confirm-create-dupe.html.tmpl/1.3/Wed Jan 17 22:27:10 2007//TBUGZILLA-3_0 +/create-guided.html.tmpl/1.36.2.1/Mon Apr 23 15:27:45 2007//TBUGZILLA-3_0 +/create.html.tmpl/1.75/Wed Jan 24 00:56:31 2007//TBUGZILLA-3_0 +/created.html.tmpl/1.9/Wed Jul 27 20:51:33 2005//TBUGZILLA-3_0 +/make-template.html.tmpl/1.9/Tue Oct 17 19:58:38 2006//TBUGZILLA-3_0 +/user-message.html.tmpl/1.4/Sun Mar 7 23:27:31 2004//TBUGZILLA-3_0 D diff --git a/template/en/default/bug/create/CVS/Tag b/template/en/default/bug/create/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/bug/create/CVS/Tag +++ b/template/en/default/bug/create/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/bug/create/comment-guided.txt.tmpl b/template/en/default/bug/create/comment-guided.txt.tmpl index 2d2182681..23dec73cb 100644 --- a/template/en/default/bug/create/comment-guided.txt.tmpl +++ b/template/en/default/bug/create/comment-guided.txt.tmpl @@ -37,7 +37,7 @@ Build Identifier: [%+ cgi.param("buildid") %] Reproducible: [%+ cgi.param("reproducible") %] [% END %] -[% IF !(cgi.param("reproduce_steps").match('^1\.\s+2\.\s+3\.\s+$') || cgi.param("reproduce_steps").match('^\s+$')) %] +[% IF !(cgi.param("reproduce_steps").match('^1\.\s+2\.\s+3\.\s+$') || cgi.param("reproduce_steps").match('^\s*$')) %] Steps to Reproduce: [%+ cgi.param("reproduce_steps") %] [% END %] diff --git a/template/en/default/bug/create/confirm-create-dupe.html.tmpl b/template/en/default/bug/create/confirm-create-dupe.html.tmpl new file mode 100644 index 000000000..9c2b3dbc2 --- /dev/null +++ b/template/en/default/bug/create/confirm-create-dupe.html.tmpl @@ -0,0 +1,58 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # The Initial Developer of the Original Code is Olav Vitters. + # + # Contributor(s): Olav Vitters <olav@bkor.dhs.org> + #%] + +[%# INTERFACE: + # bugid: integer. ID of the bug previously used to create a bug. + # allow_override: boolean int. Is 1 if the user may submit the bug again. + #%] + +[% PROCESS "global/field-descs.none.tmpl" %] + +[% PROCESS global/header.html.tmpl + title = "Already filed $terms.bug" +%] + +[% USE Bugzilla %] + +<table cellpadding="20"> + <tr> + <td bgcolor="#ff0000"> + <font size="+2"> + You already used the form to file [% "$terms.bug $bugid" FILTER bug_link(bugid) FILTER none %]. + </font> + </td> + </tr> +</table> + +<p><font size="big">You are highly encouraged to visit [% "$terms.bug $bugid" +FILTER bug_link(bugid) FILTER none %].</font></p> + +[% IF allow_override %] + <p>If you are sure you used the same form to submit a new [% terms.bug %], + click 'File [% terms.bug %] again'.<p> + + <form name="create" id="create" method="post" action="post_bug.cgi" + [%- IF Bugzilla.cgi.param("data") %] enctype="multipart/form-data"[% END %]> + [% PROCESS "global/hidden-fields.html.tmpl" + exclude="^(Bugzilla_login|Bugzilla_password|ignore_token)$" %] + <input type="hidden" name="ignore_token" value="[% bugid FILTER html %]"> + <input type="submit" value="File [% terms.bug %] again" id="file_bug_again"> + </form> +[% END %] + +[% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/bug/create/create-guided.html.tmpl b/template/en/default/bug/create/create-guided.html.tmpl index 59a644844..3bc459d70 100644 --- a/template/en/default/bug/create/create-guided.html.tmpl +++ b/template/en/default/bug/create/create-guided.html.tmpl @@ -32,7 +32,7 @@ [% PROCESS global/header.html.tmpl title = "Enter $terms.ABug" onload = "PutDescription()" - style = "body, html { height: 100% }" + style = "#somebugs { width: 100%; height: 500px }" %] <p> @@ -52,7 +52,7 @@ [%# This script displays the descriptions for selected components. %] <script type="text/javascript"> var descriptions = [ -[% FOREACH c = component_ %] +[% FOREACH c = product.components %] '[% c.description FILTER js %]', [% END %] ]; @@ -113,12 +113,12 @@ function PutDescription() { </p> [%# Include other products if sensible %] -[% IF product == "Firefox" %] +[% IF product.name == "Firefox" %] [% productstring = "product=Mozilla%20Application%20Suite&product=Firefox" %] -[% ELSIF product == "Thunderbird" %] +[% ELSIF product.name == "Thunderbird" %] [% productstring = "product=Mozilla%20Application%20Suite&product=Thunderbird" %] [% ELSE %] - [% productstring = BLOCK %]product=[% product FILTER url_quote %][% END %] + [% productstring = BLOCK %]product=[% product.name FILTER url_quote %][% END %] [% END %] <p> @@ -126,7 +126,7 @@ function PutDescription() { <a href="duplicates.cgi?[% productstring %]&format=simple&sortby=delta&reverse=1&maxrows=100&changedsince=14" target="somebugs">Hot in the last two weeks</a> </p> -<iframe name="somebugs" width="100%" height="80%" +<iframe name="somebugs" id="somebugs" style="border: 2px black solid" src="duplicates.cgi?[% productstring %]&format=simple"> </iframe> @@ -143,11 +143,11 @@ function PutDescription() { <input type="hidden" name="format" value="simple"> <input type="hidden" name="order" value="relevance desc"> <input type="hidden" name="bug_status" value="__all__"> - <input type="hidden" name="product" value="[% product FILTER html %]"> - [% IF product == "Firefox" OR - product == "Thunderbird" OR - product == "Mozilla Application Suite" OR - product == "Camino" %] + <input type="hidden" name="product" value="[% product.name FILTER html %]"> + [% IF product.name == "Firefox" OR + product.name == "Thunderbird" OR + product.name == "Mozilla Application Suite" OR + product.name == "Camino" %] <input type="hidden" name="product" value="Core"> <input type="hidden" name="product" value="Toolkit"> <input type="hidden" name="product" value="PSM"> @@ -158,7 +158,7 @@ function PutDescription() { <input type="hidden" name="chfieldto" value="Now"> <input type="hidden" name="chfield" value="[Bug creation]"> <input type="text" name="content" size="40"> - <input type="submit" value="Search"> + <input type="submit" id="search" value="Search"> </form> <p> @@ -186,6 +186,7 @@ function PutDescription() { value="[% default.priority FILTER html %]"> <input type="hidden" name="version" value="[% default.version FILTER html %]"> + <input type="hidden" name="token" value="[% token FILTER html %]"> <table valign="top" cellpadding="5" cellspacing="5" border="0"> @@ -194,8 +195,8 @@ function PutDescription() { <b>Product</b> </td> <td valign="top"> - <input type="hidden" name="product" value="[% product FILTER html %]"> - [% product FILTER html %] + <input type="hidden" name="product" value="[% product.name FILTER html %]"> + [% product.name FILTER html %] </td> </tr> @@ -209,7 +210,7 @@ function PutDescription() { <td valign="top"> <select name="component" id="component" size="5" onchange="PutDescription()"> - [% FOREACH c = component_ %] + [% FOREACH c = product.components %] <option value="[% c.name FILTER html %]" [% " selected=\"selected\"" IF c.name == default.component_ %]> [% c.name FILTER html %] @@ -236,7 +237,7 @@ function PutDescription() { To pick the right component, you could use the same one as similar [% terms.bugs %] you found in your search, or read the full list of <a target="_blank" href="describecomponents.cgi?product= - [% product FILTER url_quote %]">component + [% product.name FILTER url_quote %]">component descriptions</a> (opens in new window) if you need more help. </p> </td> @@ -268,24 +269,29 @@ function PutDescription() { </td> </tr> - [% matches = cgi.user_agent('Gecko/(\d+)') %] - [% buildid = cgi.user_agent() IF matches %] + [% IF product.name.match("Firefox|Camino|Mozilla Application Suite") %] + [% matches = cgi.user_agent('Gecko/(\d+)') %] + [% buildid = cgi.user_agent() IF matches %] + [% END %] + + [%# Accept URL parameter build ID for non-browser products %] + [% IF cgi.param("buildid") %] + [% buildid = cgi.param("buildid") %] + [% END %] <tr bgcolor="[% tablecolour %]"> <td align="right" valign="top"> - <b>Build Identifier<br>(User Agent)</b> + <b>Build Identifier</b> </td> <td valign="top"> - <input type="text" size="80" name="buildid" value="[% buildid FILTER html %]"> + <input type="text" size="80" name="buildid" value="[% buildid %]"> <p> - This identifies exactly the version of the product you were using. - If reporting [% terms.abug %] in Mozilla or Firefox, - this is the line beginning <tt>"Mozilla/5.0"</tt> in - <tt>Help | About</tt>. - If you are using the problematic software to file the bug, this - field will already be filled in correctly. - If the product won't start, just enter the complete URL you - downloaded it from. + This should identify the exact version of the product you were using. + If the above field is blank or you know it is incorrect, copy the + version text from the product's Help | + About menu (for browsers this will begin with "Mozilla/5.0..."). + If the product won't start, instead paste the complete URL you downloaded + it from. </p> </td> </tr> @@ -297,11 +303,10 @@ function PutDescription() { <td valign="top"> <input type="text" size="80" name="bug_file_loc" value="http://"> <p> - URL that demonstrates the problem you are seeing (optional.) - <!-- - <b>IMPORTANT</b>: problems with broken web pages go - <a href="http://write-this-webtool/">in this form instead</a>. - --> + URL that demonstrates the problem you are seeing (optional).<br> + <b>IMPORTANT</b>: if the problem is with a broken web page, you need + to report it + <a href="https://bugzilla.mozilla.org/page.cgi?id=broken-website.html">a different way</a>. </p> </td> </tr> @@ -311,7 +316,8 @@ function PutDescription() { <b>Summary</b> </td> <td valign="top"> - <input type="text" size="80" name="short_desc" id="short_desc"> + <input type="text" size="80" name="short_desc" id="short_desc" + maxlength="255"> <p> A sentence which summarises the problem. Please be descriptive and use lots of keywords. @@ -334,7 +340,11 @@ function PutDescription() { <b>Details</b> </td> <td valign="top"> - <textarea rows="6" cols="[% constants.COMMENT_COLS FILTER none %]" name="comment"></textarea> + [% INCLUDE global/textarea.html.tmpl + name = 'comment' + minrows = 6 + cols = constants.COMMENT_COLS + %] <p> Expand on the Summary. Please be as specific as possible about what is wrong. @@ -382,11 +392,12 @@ function PutDescription() { <b>Steps to Reproduce</b> </td> <td valign="top"> -<textarea rows="4" cols="[% constants.COMMENT_COLS FILTER none %]" name="reproduce_steps"> -1. -2. -3. -</textarea> + [% INCLUDE global/textarea.html.tmpl + name = 'reproduce_steps' + minrows = 4 + cols = constants.COMMENT_COLS + defaultcontent = "1.\n2.\n3." + %] <p> Describe how to reproduce the problem, step by step. Include any special setup steps. @@ -399,7 +410,11 @@ function PutDescription() { <b>Actual Results</b> </td> <td valign="top"> - <textarea rows="4" cols="[% constants.COMMENT_COLS FILTER none %]" name="actual_results"></textarea> + [% INCLUDE global/textarea.html.tmpl + name = 'actual_results' + minrows = 4 + cols = constants.COMMENT_COLS + %] <p> What happened after you performed the steps above? </p> @@ -411,7 +426,11 @@ function PutDescription() { <b>Expected Results</b> </td> <td valign="top"> - <textarea rows="4" cols="[% constants.COMMENT_COLS FILTER none %]" name="expected_results"></textarea> + [% INCLUDE global/textarea.html.tmpl + name = 'expected_results' + minrows = 4 + cols = constants.COMMENT_COLS + %] <p> What should the software have done instead? </p> @@ -423,7 +442,11 @@ function PutDescription() { <b>Additional Information</b> </td> <td valign="top"> - <textarea rows="8" cols="[% constants.COMMENT_COLS FILTER none %]" name="additional_info"></textarea> + [% INCLUDE global/textarea.html.tmpl + name = 'additional_info' + minrows = 8 + cols = constants.COMMENT_COLS + %] <p> Add any additional information you feel may be relevant to this [% terms.bug %], such as the <b>theme</b> you were @@ -485,7 +508,7 @@ function PutDescription() { <h3>Step 3 of 3 - submit the [% terms.bug %] report</h3> <p> - <input type="submit" value=" Submit [% terms.Bug %] Report " + <input type="submit" id="report" value=" Submit [% terms.Bug %] Report " onclick="if (this.form.comment.value == '') { alert('Please enter some details about this [% terms.bug %].'); this.form.comment.focus(); diff --git a/template/en/default/bug/create/create.html.tmpl b/template/en/default/bug/create/create.html.tmpl index 18ac4ec05..fc6024a9e 100644 --- a/template/en/default/bug/create/create.html.tmpl +++ b/template/en/default/bug/create/create.html.tmpl @@ -19,42 +19,64 @@ # Contributor(s): Gervase Markham <gerv@gerv.net> # Ville Skyttä <ville.skytta@iki.fi> # Shane H. W. Travis <travis@sedsystems.ca> + # Marc Schumann <wurblzap@gmail.com> + # Akamai Technologies <bugzilla-dev@akamai.com> + # Max Kanat-Alexander <mkanat@bugzilla.org> #%] -[% PROCESS global/variables.none.tmpl %] [% PROCESS "global/field-descs.none.tmpl" %] -[% product_name = product FILTER html %] +[% title = BLOCK %]Enter [% terms.Bug %]: [% product.name FILTER html %][% END %] + [% PROCESS global/header.html.tmpl - title = "Enter $terms.Bug: $product_name" - onload="set_assign_to();" + title = title + style_urls = [ 'skins/standard/create_attachment.css' ] + javascript_urls = [ "js/attachment.js" ] %] -[% USE Bugzilla %] <script type="text/javascript"> <!-- -var initialowners = new Array([% component_.size %]); +var initialowners = new Array([% product.components.size %]); var last_initialowner; -var components = new Array([% component_.size %]); +var initialccs = new Array([% product.components.size %]); +var components = new Array([% product.components.size %]); +var flags = new Array([% product.components.size %]); [% IF Param("useqacontact") %] - var initialqacontacts = new Array([% component_.size %]); + var initialqacontacts = new Array([% product.components.size %]); var last_initialqacontact; [% END %] [% count = 0 %] -[%- FOREACH c = component_ %] +[%- FOREACH c = product.components %] components[[% count %]] = "[% c.name FILTER js %]"; - initialowners[[% count %]] = "[% c.initialowner FILTER js %]"; + initialowners[[% count %]] = "[% c.default_assignee.login FILTER js %]"; + [% flag_list = [] %] + [% FOREACH f = c.flag_types.bug %] + [% NEXT UNLESS f.is_active %] + [% flag_list.push(f.id) %] + [% END %] + [% FOREACH f = c.flag_types.attachment %] + [% NEXT UNLESS f.is_active %] + [% flag_list.push(f.id) %] + [% END %] + flags[[% count %]] = [[% flag_list.join(",") FILTER js %]]; [% IF Param("useqacontact") %] - initialqacontacts[[% count %]] = "[% c.initialqacontact FILTER js %]"; + initialqacontacts[[% count %]] = "[% c.default_qa_contact.login FILTER js %]"; + [% END %] + + [% SET initial_cc_list = [] %] + [% FOREACH cc_user = c.initial_cc %] + [% initial_cc_list.push(cc_user.login) %] [% END %] + initialccs[[% count %]] = "[% initial_cc_list.join(', ') FILTER js %]"; + [% count = count + 1 %] [%- END %] function set_assign_to() { // Based on the selected component, fill the "Assign To:" field - // with the default component owner, and the the "QA Contact:" field - // with the default QA Contact. + // with the default component owner, and the "QA Contact:" field + // with the default QA Contact. It also selectively enables flags. var form = document.Create; var assigned_to = form.assigned_to.value; @@ -78,6 +100,9 @@ function set_assign_to() { form.assigned_to.value = owner; last_initialowner = owner; } + + document.getElementById('initial_cc').innerHTML = initialccs[index]; + [% IF Param("useqacontact") %] var contact = initialqacontacts[index]; if (qa_contact == last_initialqacontact @@ -87,22 +112,59 @@ function set_assign_to() { last_initialqacontact = contact; } [% END %] + + // First, we disable all flags. Then we re-enable those + // which are available for the selected component. + var inputElements = document.getElementsByTagName("select"); + var inputElement, flagField; + for ( var i=0 ; i<inputElements.length ; i++ ) { + inputElement = inputElements.item(i); + if (inputElement.name.search(/^flag_type-(\d+)$/) != -1) { + var id = inputElement.name.replace(/^flag_type-(\d+)$/, "$1"); + inputElement.disabled = true; + // Also disable the requestee field, if it exists. + inputElement = document.getElementById("requestee_type-" + id); + if (inputElement) inputElement.disabled = true; + } + } + // Now enable flags available for the selected component. + for (var i = 0; i < flags[index].length; i++) { + flagField = document.getElementById("flag_type-" + flags[index][i]); + // Do not enable flags the user cannot set nor request. + if (flagField && flagField.options.length > 1) { + flagField.disabled = false; + // Re-enabling the requestee field depends on the status + // of the flag. + toggleRequesteeField(flagField, 1); + } + } + } +} + +function handleWantsAttachment(wants_attachment) { + if (wants_attachment) { + document.getElementById('attachment_false').style.display = 'none'; + document.getElementById('attachment_true').style.display = 'block'; + } + else { + document.getElementById('attachment_false').style.display = 'block'; + document.getElementById('attachment_true').style.display = 'none'; + clearAttachmentFields(); } } + --> </script> -<form name="Create" id="Create" method="post" action="post_bug.cgi"> -<input type="hidden" name="product" value="[% product FILTER html %]"> +<form name="Create" id="Create" method="post" action="post_bug.cgi" + enctype="multipart/form-data"> +<input type="hidden" name="product" value="[% product.name FILTER html %]"> +<input type="hidden" name="token" value="[% token FILTER html %]"> <table cellspacing="2" cellpadding="0" border="0"> <tr> - <td><br></td> - </tr> - - <tr> - <td></td> + <td> </td> <td colspan="3"> [%# Migration note: The following file corresponds to the old Param # 'entryheaderhtml' @@ -112,15 +174,16 @@ function set_assign_to() { </tr> <tr> - <td><br></td> + <td> </td> + <td colspan="3"> </td> </tr> <tr> <td align="right" valign="top"><strong>Reporter:</strong></td> - <td valign="top">[% Bugzilla.user.login FILTER html %]</td> + <td valign="top">[% user.login FILTER html %]</td> <td align="right" valign="top"><strong>Product:</strong></td> - <td valign="top">[% product FILTER html %]</td> + <td valign="top">[% product.name FILTER html %]</td> </tr> [%# We can't use the select block in these two cases for various reasons. %] @@ -140,13 +203,13 @@ function set_assign_to() { <td align="right" valign="top"> <strong> - <a href="describecomponents.cgi?product=[% product FILTER url_quote %]"> + <a href="describecomponents.cgi?product=[% product.name FILTER url_quote %]"> Component</a>: </strong> </td> <td> <select name="component" onchange="set_assign_to();" size="5"> - [%- FOREACH c = component_ %] + [%- FOREACH c = product.components %] <option value="[% c.name FILTER html %]" [% " selected=\"selected\"" IF c.name == default.component_ %]> [% c.name FILTER html -%] @@ -158,41 +221,42 @@ function set_assign_to() { <tr> <td> </td> - <td colspan="3"></td> + <td colspan="3"> </td> </tr> <tr> - [% sel = { description => 'Platform', name => 'rep_platform' } %] + [% sel = { description => 'Severity', name => 'bug_severity' } %] [% INCLUDE select %] - [% sel = { description => 'OS', name => 'op_sys' } %] + [% sel = { description => 'Platform', name => 'rep_platform' } %] [% INCLUDE select %] </tr> <tr> - [% IF Param('letsubmitterchoosepriority') %] - [% sel = { description => 'Priority', name => 'priority' } %] - [% INCLUDE select %] - [% ELSE %] - <input type="hidden" name="priority" - value="[% default.priority FILTER html %]"> - [% END %] + [% IF Param('letsubmitterchoosepriority') %] + [% sel = { description => 'Priority', name => 'priority' } %] + [% INCLUDE select %] + [% ELSE %] + <td colspan="2"> + <input type="hidden" name="priority" value="[% default.priority FILTER html %]"> + </td> + [% END %] - [% sel = { description => 'Severity', name => 'bug_severity' } %] - [% INCLUDE select %] + [% sel = { description => 'OS', name => 'op_sys' } %] + [% INCLUDE select %] </tr> [% IF Param('usetargetmilestone') && Param('letsubmitterchoosemilestone') %] <tr> - [% sel = { description => 'Target Milestone', name => 'target_milestone' } %] - [% INCLUDE select %] - <td colspan="2"></td> + [% sel = { description => 'Target Milestone', name => 'target_milestone' } %] + [% INCLUDE select %] + <td colspan="2"> </td> </tr> [% END %] <tr> <td> </td> - <td colspan="3"></td> + <td colspan="3"> </td> </tr> <tr> @@ -205,7 +269,20 @@ function set_assign_to() { [% sel = { description => 'Initial State', name => 'bug_status' } %] [% INCLUDE select %] [% END %] - <td colspan="2"></td> + <td> </td> + [%# Calculate the number of rows we can use for flags %] + [% num_rows = 6 + (Param("useqacontact") ? 1 : 0) + + (user.in_group(Param('timetrackinggroup')) ? 3 : 0) + + (Param("usebugaliases") ? 1 : 0) + %] + <td rowspan="[% num_rows FILTER html %]" valign="top"> + [% IF product.flag_types.bug.size > 0 %] + [% PROCESS "flag/list.html.tmpl" flag_types = product.flag_types.bug + any_flags_requesteeble = 1 + flag_table_id = "bug_flags" + %] + [% END %] + </td> </tr> <tr> @@ -214,7 +291,7 @@ function set_assign_to() { <a href="page.cgi?id=fields.html#assigned_to">Assign To</a>: </strong> </td> - <td colspan="3"> + <td colspan="2"> [% INCLUDE global/userselect.html.tmpl name => "assigned_to" value => assigned_to @@ -229,7 +306,7 @@ function set_assign_to() { [% IF Param("useqacontact") %] <tr> <td align="right"><strong>QA Contact:</strong></td> - <td colspan="3"> + <td colspan="2"> [% INCLUDE global/userselect.html.tmpl name => "qa_contact" value => qa_contact @@ -244,7 +321,7 @@ function set_assign_to() { <tr> <td align="right"><strong>Cc:</strong></td> - <td colspan="3"> + <td colspan="2"> [% INCLUDE global/userselect.html.tmpl name => "cc" value => cc @@ -254,22 +331,34 @@ function set_assign_to() { %] </td> </tr> + + <tr> + <th align="right">Default CC:</th> + <td colspan="2"> + <div id="initial_cc"> + <!-- This has to happen after everything above renders, + and onload doesn't work. So this is as good a place + as any to put it. --> + <script type="text/javascript">set_assign_to();</script> + </div> + </td> + </tr> <tr> <td> </td> - <td colspan="3"></td> + <td colspan="2"></td> </tr> -[% IF UserInGroup(Param('timetrackinggroup')) %] +[% IF user.in_group(Param('timetrackinggroup')) %] <tr> <td align="right"><strong>Estimated Hours:</strong></td> - <td colspan="3"> + <td colspan="2"> <input name="estimated_time" size="6" maxlength="6" value="0.0"> </td> </tr> <tr> <td align="right"><strong>Deadline:</strong></td> - <td colspan="3"> + <td colspan="2"> <input name="deadline" size="10" maxlength="10" value="[% deadline FILTER html %]"> <small>(YYYY-MM-DD)</small> </td> @@ -277,14 +366,14 @@ function set_assign_to() { <tr> <td> </td> - <td colspan="3"></td> + <td colspan="2"></td> </tr> [% END %] [% IF Param("usebugaliases") %] <tr> <td align="right"><strong>Alias:</strong></td> - <td colspan="3"> + <td colspan="2"> <input name="alias" size="20"> </td> </tr> @@ -292,33 +381,54 @@ function set_assign_to() { <tr> <td align="right"><strong>URL:</strong></td> - <td colspan="3"> + <td colspan="2"> <input name="bug_file_loc" size="60" value="[% bug_file_loc FILTER html %]"> </td> </tr> + [% USE Bugzilla %] + [% FOREACH field = Bugzilla.get_fields({ obsolete => 0, custom => 1, + enter_bug => 1 }) %] + [% SET value = ${field.name} IF ${field.name}.defined %] + <tr> + [% PROCESS bug/field.html.tmpl editable=1 value_span=2 %] + </tr> + [% END %] + <tr> <td align="right"><strong>Summary:</strong></td> - <td colspan="3"> - <input name="short_desc" size="60" value="[% short_desc FILTER html %]"> + <td colspan="2"> + <input name="short_desc" size="60" value="[% short_desc FILTER html %]" + maxlength="255"> </td> </tr> <tr><td align="right" valign="top"><strong>Description:</strong></td> <td colspan="3"> - <textarea name="comment" rows="10" cols="[% constants.COMMENT_COLS FILTER none %]"> + [% defaultcontent = BLOCK %] [% IF cloned_bug_id %] +++ This [% terms.bug %] was initially created as a clone of [% terms.Bug %] #[% cloned_bug_id %] +++ [% END %] - [% comment FILTER html %]</textarea> + [%-# We are within a BLOCK. The comment will be correctly HTML-escaped + # by global/textarea.html.tmpl. So we must not escape the comment here. %] + [% comment FILTER none %] + [%- END %] + [% INCLUDE global/textarea.html.tmpl + name = 'comment' + id = 'comment' + minrows = 10 + maxrows = 25 + cols = constants.COMMENT_COLS + defaultcontent = defaultcontent + %] <br> </td> </tr> - [% IF Param("insidergroup") && UserInGroup(Param("insidergroup")) %] + [% IF Param("insidergroup") && user.in_group(Param("insidergroup")) %] <tr> <td></td> <td colspan="3"> @@ -330,11 +440,44 @@ function set_assign_to() { </label> </td> </tr> - [% ELSE %] - <input type="hidden" name="commentprivacy" value="0"> [% END %] - [% IF UserInGroup('editbugs') %] + <tr> + <th align="right" valign="top">Attachment:</th> + <td colspan="3"> + <script type="text/javascript"> + <!-- + document.write( '<div id="attachment_false">' + + '<input type="button" value="Add an attachment" ' + + 'onClick="handleWantsAttachment(true)"> ' + + '<em style="display: none">This button has no ' + + 'functionality for you because your browser does ' + + 'not support CSS or does not use it.<\/em>' + + '<\/div>' + + '<div id="attachment_true" style="display: none">' + + '<input type="button" ' + + 'value="Don\'t add an attachment " ' + + 'onClick="handleWantsAttachment(false)">'); + //--> + </script> + <fieldset> + <legend>Add an attachment</legend> + <table class="attachment_entry"> + [% PROCESS attachment/createformcontents.html.tmpl + flag_types = product.flag_types.attachment + any_flags_requesteeble = 1 + flag_table_id ="attachment_flags" %] + </table> + </fieldset> + <script type="text/javascript"> + <!-- + document.write('<\/div>'); + //--> + </script> + </td> + </tr> + + [% IF user.in_group('editbugs', product.id) %] [% IF use_keywords %] <tr> <td align="right" valign="top"> @@ -399,12 +542,12 @@ function set_assign_to() { <tr> <td></td> <td colspan="3"> - <input type="submit" value=" Commit " + <input type="submit" id="commit" value=" Commit " onclick="if (this.form.short_desc.value == '') { alert('Please enter a summary sentence for this [% terms.bug %].'); return false; } return true;"> - <input type="submit" name="maketemplate" + <input type="submit" name="maketemplate" id="maketemplate" value="Remember values as bookmarkable template"> </td> </tr> diff --git a/template/en/default/bug/create/make-template.html.tmpl b/template/en/default/bug/create/make-template.html.tmpl index bf1e743c0..6a7ea6a3b 100644 --- a/template/en/default/bug/create/make-template.html.tmpl +++ b/template/en/default/bug/create/make-template.html.tmpl @@ -29,7 +29,7 @@ [% PROCESS global/header.html.tmpl title = "Bookmarks are your friend" - h1 = "Template constructed" + header = "Template constructed" %] <p> diff --git a/template/en/default/bug/dependency-graph.html.tmpl b/template/en/default/bug/dependency-graph.html.tmpl index 4db034ea2..5c1eb8471 100644 --- a/template/en/default/bug/dependency-graph.html.tmpl +++ b/template/en/default/bug/dependency-graph.html.tmpl @@ -35,14 +35,14 @@ [% PROCESS global/variables.none.tmpl %] [% title = "Dependency Graph" - h1 = title + header = title %] [% IF NOT multiple_bugs AND NOT doall %] [% filtered_desc = short_desc FILTER html %] [% title = "$title for $terms.bug $bug_id" - h1 = "$h1 for $terms.bug <a href=\"show_bug.cgi?id=$bug_id\">$bug_id</a>" - h2 = filtered_desc + header = "$header for $terms.bug <a href=\"show_bug.cgi?id=$bug_id\">$bug_id</a>" + subheader = filtered_desc %] [% END %] @@ -104,7 +104,7 @@ </td> </tr> </table> - <input type="submit" value="Change Parameters"> + <input type="submit" id="change" value="Change Parameters"> </form> [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/bug/dependency-tree.html.tmpl b/template/en/default/bug/dependency-tree.html.tmpl index 8b5ecd59c..20940d663 100644 --- a/template/en/default/bug/dependency-tree.html.tmpl +++ b/template/en/default/bug/dependency-tree.html.tmpl @@ -19,143 +19,152 @@ # Contributor(s): Tobias Burnus <burnus@net-b.de> # Ville Skyttä <ville.skytta@iki.fi> # Myk Melez <myk@mozilla.org> + # André Batosti <batosti@async.com.br> #%] [% PROCESS global/variables.none.tmpl %] -[% filtered_desc = blocked_tree.$bugid.summary FILTER html %] +[% filtered_desc = blocked_tree.$bugid.short_desc FILTER html %] [% PROCESS global/header.html.tmpl - title = "Dependency tree for $terms.Bug $bugid" - h1 = "Dependency tree for <a href=\"show_bug.cgi?id=$bugid\">$terms.Bug $bugid</a>" - h2 = filtered_desc + title = "Dependency tree for $terms.Bug $bugid" + header = "Dependency tree for + <a href=\"show_bug.cgi?id=$bugid\">$terms.Bug $bugid</a>" + javascript_urls = ["js/expanding-tree.js"] + style_urls = ["skins/standard/dependency-tree.css"] + subheader = filtered_desc %] [% PROCESS depthControlToolbar %] - -[%# Display the tree of bugs that this bug depends on. %] -<h3> - [% IF hide_resolved %] - Open [% terms.bugs %] - [% ELSE %] - [% terms.Bugs %] - [% END %] - that <a href="show_bug.cgi?id=[% bugid %]">[% terms.bug %] [%+ bugid %]</a> - depends on</h3> -[% IF dependson_ids.size > 0 %] - ( - [% IF maxdepth -%]Up to [% maxdepth %] level[% "s" IF maxdepth > 1 %] deep | [% END %] - <a href="buglist.cgi?bug_id=[% dependson_ids.join(",") %]">view as [% terms.bug %] list</a> - [% IF canedit && dependson_ids.size > 1 %] - | <a href="buglist.cgi?bug_id=[% dependson_ids.join(",") %]&tweak=1">change several</a> - [% END %]) - [% INCLUDE display_tree tree=dependson_tree bug_id=bugid %] -[% ELSE %] - </h3> - <p>None</p> -[% END %] - -[%# Display the tree of bugs that this bug blocks. %] -<h3> - [% IF hide_resolved %] - Open [% terms.bugs %] - [% ELSE %] - [% terms.Bugs %] - [% END %] - that <a href="show_bug.cgi?id=[% bugid %]">[% terms.bug %] [%+ bugid %]</a> - blocks</h3> -[% IF blocked_ids.size > 0 %] - ( - [% IF maxdepth -%]Up to [% maxdepth %] level[% "s" IF maxdepth > 1 %] deep | [% END %] - <a href="buglist.cgi?bug_id=[% blocked_ids.join(",") %]">view as [% terms.bug %] list</a> - [% IF canedit && blocked_ids.size > 1 %] - | <a href="buglist.cgi?bug_id=[% blocked_ids.join(",") %]&tweak=1">change several</a> - [% END %]) - [% INCLUDE display_tree tree=blocked_tree bug_id=bugid %] -[% ELSE %] - </h3> - <p>None</p> -[% END %] + +[% INCLUDE tree_section ids=dependson_ids type=1 %] + +[% INCLUDE tree_section ids=blocked_ids type=2 %] [% PROCESS depthControlToolbar %] +[% PROCESS global/footer.html.tmpl %] + [%###########################################################################%] -[%# Block to display a tree #%] +[%# Tree-drawing blocks #%] [%###########################################################################%] -[% BLOCK display_tree %] -[% tree.$bug_id.seen = 1 %] -<ul> - [% FOREACH dep_id = tree.$bug_id.dependencies %] - [% dep = tree.$dep_id %] - <li> - [% "<script>document.write('<a href=\"#\" class=\"toggle\" onclick=\"listToggle(event); return false\">[-]</a>')</script>" - IF dep.dependencies.size > 0 && !dep.seen %] - [% isclosed = !dep.open %] - [% FILTER closed(isclosed) %] - <a href="show_bug.cgi?id=[% dep_id %]">[% dep_id %] - [[% IF dep.milestone %][% dep.milestone FILTER html %], [% END %] - [% dep.assignee_email FILTER html %]] - - [% IF dep.seen %] - <i>This [% terms.bug %] appears elsewhere in this tree.</i></a> +[% BLOCK tree_section %] + [%# INTERFACE + # - ids: a list of bug IDs to be displayed as children + # - type: the type of tree. 1 = depends on, 2 = blockeds + # GLOBALS + # - seen: Maintains a global hash of bugs that have been displayed + #%] + [% global.seen = {} %] + [%# Display the tree of bugs that this bug depends on. %] + <h3> + <a href="show_bug.cgi?id=[% bugid %]">[% terms.Bug %] [%+ bugid %]</a> + [% IF type == 1 %] + [% tree_name = "dependson_tree" %] + [% IF ids.size %] + depends on [% ELSE %] - [%+ dep.summary FILTER html %].</a> + does not depend on any [% terms.bugs %]. + [% END %] + [% ELSIF type == 2 %] + [% tree_name = "blocked_tree" %] + [% IF ids.size %] + blocks + [% ELSE %] + does not block any [% terms.bugs %]. + [% END %] + [% END %] + [% IF ids.size %] + [%+ (ids.size == 1) ? "one" : ids.size %] + [%+ IF hide_resolved %]open[% END %] + [%+ (ids.size == 1) ? terms.bug : terms.bugs %]: + [% END %] + </h3> + [% IF ids.size %] + ([% IF maxdepth -%]Up to [% maxdepth %] level[% "s" IF maxdepth > 1 %] deep | [% END -%] + <a href="buglist.cgi?bug_id=[% ids.join(",") %]">view as [% terms.bug %] list</a> + [% IF user.groups.editbugs && ids.size > 1 %] + | <a href="buglist.cgi?bug_id=[% ids.join(",") %]&tweak=1">change several</a> + [% END %]) + <ul class="tree"> + [% INCLUDE display_tree tree=$tree_name %] + </ul> + [% END %] +[% END %] + + +[% BLOCK display_tree %] + [%# INTERFACE + # - bugid: the ID of the bug being displayed + # - tree: a hash of bug objects and of bug dependencies + #%] + [% bug = tree.$bugid %] + <li> + [%- INCLUDE bullet bugid=bugid tree=tree -%] + <span class="summ[% "_deep" IF tree.dependencies.$bugid.size %]" + id="[% bugid FILTER html %]" + [% IF global.seen.$bugid %] + onMouseover="duplicatedover('[% bugid FILTER html %]')" + onMouseout="duplicatedout('[% bugid FILTER html %]')" + [% END %]> + [%- INCLUDE buglink bug=bug bugid=bugid %] + </span> + [% IF global.seen.$bugid %] + <b><a title="Already displayed above; click to locate" + onclick="duplicated('[% bugid FILTER html %]')" + href="#b[% bugid %]">(*)</a></b> + [% ELSIF tree.dependencies.$bugid.size %] + <ul> + [% FOREACH depid = tree.dependencies.$bugid %] + [% INCLUDE display_tree bugid=depid %] [% END %] - [% END %] - [% INCLUDE display_tree bug_id=dep_id - IF dep.dependencies.size > 0 && !dep.seen %] - </li> + </ul> + [% END %] + </li> + [% global.seen.$bugid = 1 %] +[% END %] + +[% BLOCK bullet %] + [% IF tree.dependencies.$bugid.size && ! global.seen.$bugid %] + [% extra_class = " b_open" %] + [% extra_args = 'onclick="return doToggle(this, event)"' %] [% END %] -</ul> + <a name="b[% bugid %]" + class="b [%+ extra_class FILTER none %]" + title="Click to expand or contract this portion of the tree. Hold down the Ctrl key while clicking to expand or contract all subtrees." + [% extra_args FILTER none %]> </a> [% END %] -<script type="text/javascript"> -if (typeof Node == 'undefined') { - /* MSIE doesn't define Node, so provide a compatibility object */ - window.Node = { - TEXT_NODE: 3 - }; -} - -function toggleDisplay(node) -{ - var display = node.style.display; - if (display == "none") { - node.style.display = - ("oldDisplay" in node) ? node.oldDisplay : "block"; - return true; - } - - node.oldDisplay = display; - node.style.display = "none"; - return false; -} - -function listToggle(event) -{ - var node = event.target; - if (!node) - node = event.srcElement; - if (node.nodeType == Node.TEXT_NODE) - node = node.parentNode; - var toggle = node.nextSibling; - while (toggle && toggle.tagName != "UL") - toggle = toggle.nextSibling; - if (toggle) { - node.firstChild.data = toggleDisplay(toggle) ? "[-]" : "[+]"; - } -} - -</script> +[% BLOCK buglink %] + [% isclosed = !bug.isopened %] + [% FILTER closed(isclosed) -%] + <a title="[% INCLUDE buginfo bug=bug %]" + href="show_bug.cgi?id=[% bugid %]"> + <b>[%- bugid %]:</b> + <span class="summ_text">[%+ bug.short_desc FILTER html %]</span> + <span class="summ_info">[[% INCLUDE buginfo %]]</span> + </a> + <a href="showdependencytree.cgi?id=[% bugid FILTER uri %]" + class="tree_link"> + <img src="skins/standard/dependency-tree/tree.png" + title="See dependency tree for [% terms.bug %] [%+ bugid FILTER uri %]"> + </a> + [% END %] +[% END %] -[% PROCESS global/footer.html.tmpl %] +[% BLOCK buginfo %] + [% bug.bug_status FILTER html -%] [%+ bug.resolution FILTER html %]; + [%-%] assigned to [% bug.assigned_to.login FILTER html %] + [%-%][% "; Target: " _ bug.target_milestone IF bug.target_milestone %] +[% END %] [%###########################################################################%] [%# Block for depth control toolbar #%] [%###########################################################################%] [% BLOCK depthControlToolbar %] - <table cellpadding="3" border="0" cellspacing="0" bgcolor="#d0d0d0"> - <tr> + <table cellpadding="3" border="0" cellspacing="0" bgcolor="#e0e0e0"> + <tr> [%# Hide/show resolved button Swaps text depending on the state of hide_resolved %] <td align="center"> @@ -166,7 +175,7 @@ function listToggle(event) <input name="maxdepth" type="hidden" value="[% maxdepth %]"> [% END %] <input type="hidden" name="hide_resolved" value="[% hide_resolved ? 0 : 1 %]"> - <input type="submit" + <input type="submit" id="toggle_visibility" value="[% IF hide_resolved %]Show[% ELSE %]Hide[% END %] Resolved"> </form> </td> @@ -183,7 +192,8 @@ function listToggle(event) <form method="get" action="showdependencytree.cgi" style="display: inline; margin: 0px;"> [%# set to one form %] - <input type="submit" value=" 1 " + <input type="submit" id="change_maxdepth" + value=" 1 " [% "disabled" IF realdepth < 2 || maxdepth == 1 %]> <input name="id" type="hidden" value="[% bugid %]"> <input name="maxdepth" type="hidden" value="1"> @@ -202,7 +212,7 @@ function listToggle(event) : ( maxdepth ? maxdepth - 1 : realdepth - 1 ) %]"> <input name="hide_resolved" type="hidden" value="[% hide_resolved %]"> - <input type="submit" value=" < " + <input type="submit" id="decrease_depth" value=" < " [% "disabled" IF realdepth < 2 || ( maxdepth && maxdepth < 2 ) %]> </form> </td> @@ -218,7 +228,8 @@ function listToggle(event) <input name="id" type="hidden" value="[% bugid %]"> <input name="hide_resolved" type="hidden" value="[% hide_resolved %]"> <noscript> - <input type="submit" value="Change" [% "disabled" IF realdepth < 2 %]> + <input type="submit" id="change_depth" value="Change" + [% "disabled" IF realdepth < 2 %]> </noscript> </form> </td> @@ -233,9 +244,8 @@ function listToggle(event) <input name="maxdepth" type="hidden" value="[% maxdepth + 1 %]"> [% END %] <input name="hide_resolved" type="hidden" value="[% hide_resolved %]"> - <input type="submit" value=" > " - [% "disabled" IF realdepth < 2 || !maxdepth || maxdepth >= realdepth %] - %]> + <input type="submit" id="increase_depth" value=" > " + [% "disabled" IF realdepth < 2 || !maxdepth || maxdepth >= realdepth %]> </form> </td> @@ -245,7 +255,8 @@ function listToggle(event) [%# Unlimited button %] <input name="id" type="hidden" value="[% bugid %]"> <input name="hide_resolved" type="hidden" value="[% hide_resolved %]"> - <input type="submit" value=" Unlimited " + <input type="submit" id="remove_limit" + value=" Unlimited " [% "disabled" IF maxdepth == 0 || maxdepth == realdepth %]> </form> </td> diff --git a/template/en/default/bug/edit.html.tmpl b/template/en/default/bug/edit.html.tmpl index 3aaf43818..5389af666 100644 --- a/template/en/default/bug/edit.html.tmpl +++ b/template/en/default/bug/edit.html.tmpl @@ -18,6 +18,9 @@ # # Contributor(s): Gervase Markham <gerv@gerv.net> # Vaskin Kissoyan <vkissoyan@yahoo.com> + # Max Kanat-Alexander <mkanat@bugzilla.org> + # Frédéric Buclin <LpSolit@gmail.com> + # Olav Vitters <olav@bkor.dhs.org> #%] [% PROCESS global/variables.none.tmpl %] @@ -56,7 +59,7 @@ replytext = "(In reply to comment #" + id + ")\n" + replytext + "\n"; - [% IF Param("insidergroup") && UserInGroup(Param("insidergroup")) %] + [% IF Param("insidergroup") && user.in_group(Param("insidergroup")) %] if (document.getElementById('isprivate-'+id).checked) { document.getElementById('newcommentprivacy').checked = 'checked'; } @@ -96,7 +99,7 @@ return text; } -[% IF UserInGroup(Param('timetrackinggroup')) %] +[% IF user.in_group(Param('timetrackinggroup')) %] var fRemainingTime = [% bug.remaining_time %]; // holds the original value function adjustRemainingTime() { // subtracts time spent from remaining time @@ -134,315 +137,182 @@ <input type="hidden" name="longdesclength" value="[% bug.longdescs.size %]"> <input type="hidden" name="id" value="[% bug.bug_id %]"> -[%# *** Hardware Reporter Product OS AddCC *** %] - + [%# That's the main table, which contains all editable fields. %] <table> - <tr> <td valign="top"> - <table cellspacing="1" cellpadding="1"> - <tr> - <td align="right"> - [% IF Param('useclassification') && bug.classification_id != 1 %] - <b>[[% bug.classification FILTER html %]]</b> - [% END %] - <b>[% terms.Bug %]#:</b> - </td> - <td> - <a href="[% Param('urlbase') %]show_bug.cgi?id=[% bug.bug_id %]"> - [% bug.bug_id %]</a> - </td> - </tr> - - [% IF Param("usebugaliases") %] + <fieldset> + <legend>Details</legend> + <table> + + [%# *** Summary *** %] <tr> <td align="right"> - <b>Alias:</b> - </td> - <td> - <label for="alias" title="a name for the [% terms.bug %] that can be used in place of its ID number, f.e. when adding it to a list of dependencies"> - <input id="alias" name="alias" value="[% bug.alias FILTER html %]" - size="20" maxlength="20"> - </label> + <label for="short_desc" accesskey="s"><b><u>S</u>ummary</b></label>: </td> + [% PROCESS input inputname => "short_desc" size => "60" colspan => 2 + maxlength => 255 %] </tr> - [% END %] - <tr> - <td align="right"> - <b><u>P</u>roduct:</b> - </td> - [% PROCESS select selname => "product" accesskey => "p" %] - </tr> - - [%# *** Component Version CC Priority Severity AssignedTo Milestone *** %] - - <tr> - <td align="right"> - <b> - <a href="describecomponents.cgi?product=[% bug.product FILTER url_quote %]"> - Co<u>m</u>ponent</a>: - </b> - </td> - [% PROCESS select selname => "component" accesskey => "m" %] - </tr> - - <tr> - <td align="right"> - <b> - <a href="page.cgi?id=fields.html#status">Status</a>: - </b> - </td> - <td>[% status_descs.${bug.bug_status} FILTER html %]</td> - </tr> - - <tr> - <td align="right"> - <b> - <a href="page.cgi?id=fields.html#resolution">Resolution</a>: - </b> - </td> - <td> - [% resolution_descs.${bug.resolution} FILTER html %] - [% IF bug.resolution == "DUPLICATE" %] - of [% terms.bug %] [%+ "${bug.dup_id}" FILTER bug_link(bug.dup_id) FILTER none %] - [% END %] - </td> - </tr> - - <tr> - <td align="right"> - <b> - <a href="page.cgi?id=fields.html#assigned_to">Assigned To</a>: - </b> - </td> - <td>[% bug.assigned_to.identity FILTER html %]</td> - </tr> + <tr> + <td colspan="3"> + <table> + <tr> + [%# *** ID, product, component, status and resolution *** %] + <td valign="top">[% PROCESS section_details1 %]</td> + + [%# *** Platform, OS, severity, priority, version and milestone *** %] + <td valign="top">[% PROCESS section_details2 %]</td> + </tr> + </table> + </td> + </tr> - </table> + <tr> + <td colspan="3"><hr size="1"></td> + </tr> - </td> - <td valign="top"> + [%# *** URL Whiteboard Keywords *** %] - <table cellspacing="1" cellpadding="1"> - - <tr> - <td align="right"> - <b><u>H</u>ardware:</b> - </td> - [% PROCESS select selname => "rep_platform" accesskey => "h" %] - </tr> - - <tr> - <td align="right"> - <b><u>O</u>S:</b> - </td> - [% PROCESS select selname => "op_sys" accesskey => "o" %] - </tr> - - <tr> - <td align="right"> - <b>Version:</b> - </td> - [% PROCESS select selname => "version" %] - </tr> - - <tr> - <td align="right"> - <b><a href="page.cgi?id=fields.html#priority">Pr<u>i</u>ority</a>:</b> - </td> - [% PROCESS select selname => "priority" accesskey => "i" %] - </tr> - - <tr> - <td align="right"> - <b><a href="page.cgi?id=fields.html#bug_severity">Severity</a>:</b> - </td> - [% PROCESS select selname = "bug_severity" %] - </tr> - - [% IF Param("usetargetmilestone") && bug.target_milestone %] <tr> <td align="right"> - <b> - [% IF bug.milestoneurl %] - <a href="[% bug.milestoneurl FILTER html %]"> + <label for="bug_file_loc" accesskey="u"><b> + [% IF bug.bug_file_loc + AND NOT bug.bug_file_loc.match("^(javascript|data)") %] + <a href="[% bug.bug_file_loc FILTER html %]"><u>U</u>RL</a> + [% ELSE %] + <u>U</u>RL [% END %] - Target Milestone[% "</a>" IF bug.milestoneurl %]: - </b> + [%%]</b></label>: </td> - [% PROCESS select selname = "target_milestone" %] + [% PROCESS input inputname => "bug_file_loc" size => "60" colspan => 2 %] </tr> - [% END %] - </table> - </td> + [% IF Param('usestatuswhiteboard') %] + <tr> + <td align="right"> + <label for="status_whiteboard" accesskey="w"><b><u>W</u>hiteboard</b></label>: + </td> + [% PROCESS input inputname => "status_whiteboard" size => "60" colspan => 2 %] + </tr> + [% END %] - <td valign="top"> + [% IF use_keywords %] + <tr> + <td align="right"> + <label for="keywords" accesskey="k"> + <b><a href="describekeywords.cgi"><u>K</u>eywords</a></b></label>: + </td> + [% PROCESS input inputname => "keywords" size => 60 colspan => 2 + value => bug.keywords.join(', ') %] + </tr> + [% END %] - <table cellpadding="1" cellspacing="1"> - - <tr> - <td align="right"> - <b>Reporter:</b> - </td> - <td> - <a href="mailto:[% bug.reporter.email FILTER html %]"> - [% bug.reporter.identity FILTER html %]</a> - </td> - </tr> - - <tr> - <td align="right" valign="top"> - <b><u>A</u>dd CC:</b> - </td> - <td> - [% INCLUDE global/userselect.html.tmpl - id => "newcc" - name => "newcc" - value => "" - accesskey => "a" - size => 30 - multiple => 5 - %] - </td> - </tr> - - <tr> - <td align="right" valign="top"> - <b>CC:</b> - </td> - <td valign="top"> - [% IF bug.cc %] - <select name="cc" multiple="multiple" size="5"> - [% FOREACH c = bug.cc %] - <option value="[% c FILTER html %]">[% c FILTER html %]</option> + [%# *** Custom Fields *** %] + + [% USE Bugzilla %] + [% fields = Bugzilla.get_fields({ obsolete => 0, custom => 1 }) %] + [% IF fields %] + [% FOREACH field = fields %] + <tr> + [% PROCESS bug/field.html.tmpl value=bug.${field.name} + editable = bug.check_can_change_field(field.name, 0, 1) + value_span = 2 %] + </tr> [% END %] - </select> - <br> - <input type="checkbox" name="removecc">Remove selected CCs - <br> - [% ELSE %] - <input type="hidden" name="cc" value=""> [% END %] - </td> - </tr> - </table> + [%# *** Dependencies *** %] - </td> - </tr> + <tr> + [% PROCESS dependencies + dep = { title => "Depends on", fieldname => "dependson" } %] + </tr> - <tr> - <td colspan="2"> - <table cellspacing="1" cellpadding="1"> - - [%# *** QAContact URL Requests Summary Whiteboard Keywords *** %] - - [% IF Param('useqacontact') %] - <tr> - <td align="right"> - <b><u>Q</u>A Contact:</b> - </td> - <td colspan="7"> - [% INCLUDE global/userselect.html.tmpl - id => "qa_contact" - name => "qa_contact" - value => bug.qa_contact.login - accesskey => "q" - size => 60 - emptyok => 1 - %] - </td> - </tr> - [% END %] - - <tr> - <td align="right"> - <b> - [% IF bug.bug_file_loc - AND NOT bug.bug_file_loc.match("^(javascript|data)") %] - <a href="[% bug.bug_file_loc FILTER html %]"><u>U</u>RL</a>: - [% ELSE %] - <u>U</u>RL: - [% END %] - </b> - </td> - <td colspan="5"> - <input name="bug_file_loc" accesskey="u" - value="[% bug.bug_file_loc FILTER html %]" size="60"> - </td> - </tr> - - <tr> - <td align="right"> - <b><u>S</u>ummary:</b> - </td> - <td colspan="5"> - <input name="short_desc" accesskey="s" - value="[% bug.short_desc FILTER html %]" size="60"> - </td> - </tr> - - [% IF Param('usestatuswhiteboard') %] <tr> - <td align="right"> - <b>Status <u>W</u>hiteboard:</b> - </td> - <td colspan="5"> - <input name="status_whiteboard" accesskey="w" - value="[% bug.status_whiteboard FILTER html %]" size="60"> - </td> + [% PROCESS dependencies accesskey = "b" + dep = { title => "<u>B</u>locks", fieldname => "blocked" } %] </tr> - [% END %] - [% IF bug.use_keywords %] <tr> - <td align="right"> - <b> - <a href="describekeywords.cgi"><u>K</u>eywords</a>: - </b> - <td colspan="5"> - <input name="keywords" accesskey="k" - value="[% bug.keywords.join(', ') FILTER html %]" size="60"> + <th> </th> + + <td colspan="2"> + <a href="showdependencytree.cgi?id=[% bug.bug_id %]&hide_resolved=1">Show + dependency tree</a> + + [% IF Param('webdotbase') %] + - <a href="showdependencygraph.cgi?id=[% bug.bug_id %]">Show + dependency graph</a> + [% END %] </td> </tr> - [% END %] - - </table> + </table> + </fieldset> </td> <td valign="top"> - <table cellspacing="1" cellpadding="1"> - <tr> - <td colspan="2" valign="top"> - [% IF bug.flag_types.size > 0 %] - [% PROCESS "flag/list.html.tmpl" - flag_types = bug.flag_types - any_flags_requesteeble = bug.any_flags_requesteeble %] - [% END %] - </td> - </tr> - </table> + [%# *** Reporter, owner and QA contact *** %] + <fieldset> + <legend>People</legend> + [% PROCESS section_people %] + </fieldset> + + [%# *** Flags *** %] + [% show_bug_flags = 0 %] + [% FOREACH type = bug.flag_types %] + [% IF (type.flags && type.flags.size > 0) || (user.id && type.is_active) %] + [% show_bug_flags = 1 %] + [% LAST %] + [% END %] + [% END %] + [% IF show_bug_flags %] + <fieldset> + <legend>Flags</legend> + <table cellspacing="1" cellpadding="1"> + <tr> + <td colspan="2" valign="top"> + [% IF user.id %] + [% IF bug.flag_types.size > 0 %] + [% PROCESS "flag/list.html.tmpl" flag_no_header = 1 + flag_types = bug.flag_types + any_flags_requesteeble = bug.any_flags_requesteeble %] + [% END %] + [% ELSE %] + [% FOREACH type = bug.flag_types %] + [% FOREACH flag = type.flags %] + [% flag.setter.nick FILTER html %]: + [%+ type.name FILTER html FILTER no_break %][% flag.status %] + [%+ IF flag.requestee %] + ([% flag.requestee.nick FILTER html %]) + [% END %]<br> + [% END %] + [% END %] + [% END %] + </td> + </tr> + </table> + </fieldset> + [% END %] </td> </tr> </table> - [% IF UserInGroup(Param('timetrackinggroup')) %] + [% IF user.in_group(Param('timetrackinggroup')) %] <br> <table cellspacing="0" cellpadding="4" border="1"> <tr> <th align="center" bgcolor="#cccccc"> - Orig. Est. + <label for="estimated_time">Orig. Est.</label> </th> <th align="center" bgcolor="#cccccc"> Current Est. </th> <th align="center" bgcolor="#cccccc"> - Hours Worked + <label for="work_time">Hours Worked</label> </th> <th align="center" bgcolor="#cccccc"> - Hours Left + <label for="remaining_time">Hours Left</label> </th> <th align="center" bgcolor="#cccccc"> %Complete @@ -451,12 +321,12 @@ Gain </th> <th align="center" bgcolor="#cccccc"> - Deadline + <label for="deadline">Deadline</label> </th> </tr> <tr> <td align="center"> - <input name="estimated_time" + <input name="estimated_time" id="estimated_time" value="[% PROCESS formattimeunit time_unit=bug.estimated_time %]" size="6" maxlength="6"> @@ -467,11 +337,12 @@ </td> <td align="center"> [% PROCESS formattimeunit time_unit=bug.actual_time %] + - <input name="work_time" value="0" size="3" maxlength="6" + <input name="work_time" id="work_time" + value="0" size="3" maxlength="6" onchange="adjustRemainingTime();"> </td> <td align="center"> - <input name="remaining_time" + <input name="remaining_time" id="remaining_time" value="[% PROCESS formattimeunit time_unit=bug.remaining_time %]" size="6" maxlength="6" onchange="updateRemainingTime();"> @@ -484,14 +355,14 @@ [% PROCESS formattimeunit time_unit=bug.estimated_time - (bug.actual_time + bug.remaining_time) %] </td> <td align="center"> - <input name="deadline" value="[% bug.deadline %]" + <input name="deadline" id="deadline" value="[% bug.deadline %]" size="10" maxlength="10"><br /> <small>(YYYY-MM-DD)</small> </td> </tr> <tr> <td colspan="7" align="right"> - <a href="summarize_time.cgi?id=[% bug.bug_id %]&do_depends=1"> + <a href="summarize_time.cgi?id=[% bug.bug_id %]&do_depends=1"> Summarize time (including time for [% terms.bugs %] blocking this [% terms.bug %])</a> </td> @@ -508,68 +379,87 @@ show_attachment_flags = bug.show_attachment_flags %] -[%# *** Dependencies Votes *** %] - <table> - <tr> - [% PROCESS dependencies - dep = { title => "depends on", fieldname => "dependson" } %] - <td rowspan="2"> - <a href="showdependencytree.cgi?id=[% bug.bug_id %]">Show - dependency tree</a> +[%# *** Comments Groups *** %] - [% IF Param('webdotbase') %] + <br> + <table cellpadding="1" cellspacing="1"> + <tr> + <td> + [% IF user.id %] + <label for="comment" accesskey="c"><b>Additional <u>C</u>omments</b></label>: + [% IF Param("insidergroup") && user.in_group(Param("insidergroup")) %] + <input type="checkbox" name="commentprivacy" value="1" + id="newcommentprivacy" + onClick="updateCommentTagControl(this, form)"> + <label for="newcommentprivacy">Private</label> + [% END %] <br> - <a href="showdependencygraph.cgi?id=[% bug.bug_id %]">Show - dependency graph</a> + <a name="add_comment"></a> + [% INCLUDE global/textarea.html.tmpl + name = 'comment' + id = 'comment' + minrows = 10 + maxrows = 25 + cols = constants.COMMENT_COLS + %] + + [% IF NOT bug.cc || NOT bug.cc.contains(user.login) %] + [% has_role = bug.user.isreporter + || bug.assigned_to.id == user.id + || (Param('useqacontact') + && bug.qa_contact + && bug.qa_contact.id == user.id) %] + + <br> + <input type="checkbox" id="addselfcc" name="addselfcc" + [% " checked=\"checked\"" + IF user.settings.state_addselfcc.value == 'always' + || (!has_role + && user.settings.state_addselfcc.value == 'cc_unless_role') %]> + <label for="addselfcc">Add [% user.identity FILTER html %] to CC list</label> + [% END %] + [% ELSE %] + <fieldset> + <legend>Note</legend> + <p> + You need to + <a href="show_bug.cgi?id=[% bug.bug_id %]&GoAheadAndLogIn=1">log in</a> + before you can comment on or make changes to this [% terms.bug %]. + </p> + </fieldset> [% END %] </td> - </tr> - <tr> - [% PROCESS dependencies accesskey = "b" - dep = { title => "<u>b</u>locks", fieldname => "blocked" } %] - </tr> - </table> + <td valign="top"> + <fieldset> + <legend>Related actions</legend> + <ul> + <li><a href="show_activity.cgi?id=[% bug.bug_id %]">View [% terms.Bug %] Activity</a></li> + <li><a href="show_bug.cgi?format=multiple&id=[% bug.bug_id %]">Format For Printing</a></li> + <li><a href="show_bug.cgi?ctype=xml&id=[% bug.bug_id %]">XML</a></li> + <li><a href="enter_bug.cgi?cloned_bug_id=[% bug.bug_id %]">Clone This [% terms.Bug %]</a></li> + </ul> + + [% IF bug.use_votes %] + <br> + <b><a href="page.cgi?id=voting.html">Votes</a></b>: [% bug.votes %] + <ul> + [% IF bug.votes %] + <li><a href="votes.cgi?action=show_bug&bug_id=[% bug.bug_id %]">Show + votes for this [% terms.bug %]</a></li> + [% END %] + <li><a href="votes.cgi?action=show_user&bug_id=[% bug.bug_id %]#vote_[% bug.bug_id %]">Vote + for this [% terms.bug %]</a></li> + </ul> + [% END %] - [% IF bug.use_votes %] - <table> - <tr> - <th> - <a href="page.cgi?id=voting.html">Votes</a>: - </th> - <td> - [% bug.votes %] - <a href="votes.cgi?action=show_bug&bug_id=[% bug.bug_id %]">Show - votes for this [% terms.bug %]</a> - <a href="votes.cgi?action=show_user&bug_id=[% bug.bug_id %]#vote_[% bug.bug_id %]">Vote - for this [% terms.bug %]</a> + [%# Links to more things users can do with this bug. %] + [% Hook.process("links") %] + </fieldset> </td> </tr> </table> - [% END %] - -[%# *** Comments Groups *** %] - - <br> - <b>Additional <u>C</u>omments:</b> - [% IF Param("insidergroup") && UserInGroup(Param("insidergroup")) %] - <input type="checkbox" name="commentprivacy" value="1" - id="newcommentprivacy" - onClick="updateCommentTagControl(this, form)"> Private - [% END %] - <br> - <a name="add_comment"></a> - <textarea name="comment" id="comment" rows="10" cols="[% constants.COMMENT_COLS FILTER none %]" - accesskey="c"></textarea> - - [% IF NOT bug.cc || NOT bug.cc.contains(user.login) %] - <br> - <label for="addselfcc"> - <input type="checkbox" id="addselfcc" name="addselfcc"> - Add [% user.login FILTER html %] to CC list - </label> - [% END %] <br> [% IF bug.groups.size > 0 %] @@ -593,10 +483,11 @@ [% END %] - <input type="checkbox" name="bit-[% group.bit %]" value="1" - [% " checked=\"checked\"" IF group.ison %] - [% " disabled=\"disabled\"" IF NOT group.ingroup %]> - [% group.description FILTER html_light %] + <input type="checkbox" value="1" + name="bit-[% group.bit %]" id="bit-[% group.bit %]" + [% " checked=\"checked\"" IF group.ison %] + [% " disabled=\"disabled\"" IF NOT group.ingroup %]> + <label for="bit-[% group.bit %]">[% group.description FILTER html_light %]</label> <br> [% END %] [% END %] @@ -624,41 +515,274 @@ </p> <p> - <input type="checkbox" name="reporter_accessible" value="1" - [% " checked" IF bug.reporter_accessible %]>Reporter - <input type="checkbox" name="cclist_accessible" value="1" - [% " checked" IF bug.cclist_accessible %]>CC List + <input type="checkbox" value="1" + name="reporter_accessible" id="reporter_accessible" + [% " checked" IF bug.reporter_accessible %]> + <label for="reporter_accessible">Reporter</label> + <input type="checkbox" value="1" + name="cclist_accessible" id="cclist_accessible" + [% " checked" IF bug.cclist_accessible %]> + <label for="cclist_accessible">CC List</label> </p> [% END %] [% END %] -[% PROCESS bug/knob.html.tmpl %] +[% PROCESS bug/knob.html.tmpl IF user.id %] [%# *** Additional Comments *** %] <hr> +<div id="comments"> [% PROCESS bug/comments.html.tmpl comments = bug.longdescs - mode = "edit" + mode = user.id ? "edit" : "show" %] +</div> </form> +[%############################################################################%] +[%# Block for the first table in the "Details" section #%] +[%############################################################################%] + +[% BLOCK section_details1 %] + <table cellspacing="1" cellpadding="1"> + <tr> + <td align="right"> + [% IF Param('useclassification') && bug.classification_id != 1 %] + <b>[[% bug.classification FILTER html %]]</b> + [% END %] + <b>[% terms.Bug %]#</b>: + </td> + <td> + <a href="[% Param('urlbase') %]show_bug.cgi?id=[% bug.bug_id %]"> + [% bug.bug_id %]</a> + </td> + </tr> + + [% IF Param("usebugaliases") %] + <tr> + <td align="right"> + <label for="alias" title="a name for the [% terms.bug %] that can be used in place of its ID number, f.e. when adding it to a list of dependencies"><b>Alias</b></label>: + </td> + [% PROCESS input inputname => "alias" size => "20" maxlength => "20" %] + </tr> + [% END %] + + <tr> + <td align="right"> + <label for="product" accesskey="p"><b><u>P</u>roduct</b></label>: + </td> + [% PROCESS select selname => "product" %] + </tr> + + <tr> + <td align="right"> + <label for="component" accesskey="m"><b><a href="describecomponents.cgi?product=[% bug.product FILTER url_quote %]">Co<u>m</u>ponent</a></b></label>: + </td> + [% PROCESS select selname => "component" %] + </tr> + + <tr> + <td align="right"> + <b><a href="page.cgi?id=fields.html#status">Status</a></b>: + </td> + <td>[% status_descs.${bug.bug_status} FILTER html %]</td> + </tr> + + <tr> + <td align="right"> + <b><a href="page.cgi?id=fields.html#resolution">Resolution</a></b>: + </td> + <td> + [% get_resolution(bug.resolution) FILTER html %] + [% IF bug.resolution == "DUPLICATE" %] + of [% terms.bug %] [%+ "${bug.dup_id}" FILTER bug_link(bug.dup_id) FILTER none %] + [% END %] + </td> + </tr> + </table> +[% END %] + +[%############################################################################%] +[%# Block for the second table in the "Details" section #%] +[%############################################################################%] + +[% BLOCK section_details2 %] + <table cellspacing="1" cellpadding="1"> + <tr> + <td align="right"> + <label for="rep_platform" accesskey="h"><b><u>H</u>ardware</b></label>: + </td> + [% PROCESS select selname => "rep_platform" %] + </tr> + + <tr> + <td align="right"> + <label for="op_sys" accesskey="o"><b><u>O</u>S</b></label>: + </td> + [% PROCESS select selname => "op_sys" %] + </tr> + + <tr> + <td align="right"> + <label for="version"><b>Version</b></label>: + </td> + [% PROCESS select selname => "version" %] + </tr> + + <tr> + <td align="right"> + <label for="priority" accesskey="i"><b><a href="page.cgi?id=fields.html#priority">Pr<u>i</u>ority</a></b></label>: + </td> + [% PROCESS select selname => "priority" %] + </tr> + + <tr> + <td align="right"> + <label for="bug_severity"><b><a href="page.cgi?id=fields.html#bug_severity">Severity</a></b></label>: + </td> + [% PROCESS select selname = "bug_severity" %] + </tr> + + [% IF Param("usetargetmilestone") && bug.target_milestone %] + <tr> + <td align="right"> + <label for="target_milestone"><b> + [% IF bug.milestoneurl %] + <a href="[% bug.milestoneurl FILTER html %]"> + [% END %] + Target Milestone[% "</a>" IF bug.milestoneurl %] + [%%]</b></label>: + </td> + [% PROCESS select selname = "target_milestone" %] + </tr> + [% END %] + </table> +[% END %] + +[%############################################################################%] +[%# Block for the table in the "People" section #%] +[%############################################################################%] + +[% BLOCK section_people %] + <table cellpadding="1" cellspacing="1"> + <tr> + <td align="right"> + <b>Reporter</b>: + </td> + <td> + <a href="mailto:[% bug.reporter.email FILTER html %]"> + [% bug.reporter.identity FILTER html %]</a> + </td> + </tr> + + <tr> + <td align="right"> + <b><a href="page.cgi?id=fields.html#assigned_to">Assigned To</a></b>: + </td> + <td> + <a href="mailto:[% bug.assigned_to.email FILTER html %]"> + [% bug.assigned_to.identity FILTER html %]</a> + </td> + </tr> + + [% IF Param('useqacontact') %] + <tr> + <td align="right"> + <label for="qa_contact" accesskey="q"><b><u>Q</u>A Contact</b></label>: + </td> + <td colspan="7"> + [% IF bug.check_can_change_field("qa_contact", 0, 1) %] + [% INCLUDE global/userselect.html.tmpl + id => "qa_contact" + name => "qa_contact" + value => bug.qa_contact.login + size => 30 + emptyok => 1 + %] + [% ELSE %] + <input type="hidden" name="qa_contact" id="qa_contact" + value="[% bug.qa_contact.login FILTER html %]"> + <a href="mailto:[% bug.qa_contact.email FILTER html %]"> + [% IF bug.qa_contact.login && bug.qa_contact.login.length > 30 %] + <span title="[% bug.qa_contact.login FILTER html %]"> + [% bug.qa_contact.identity FILTER truncate(30) FILTER html %] + </span> + [% ELSE %] + [% bug.qa_contact.identity FILTER html %] + [% END %] + </a> + [% END %] + </td> + </tr> + [% END %] + + [% IF user.id %] + <tr> + <td align="right" valign="top"> + <label for="newcc" accesskey="a"><b><u>A</u>dd CC</b></label>: + </td> + <td> + [% INCLUDE global/userselect.html.tmpl + id => "newcc" + name => "newcc" + value => "" + size => 30 + multiple => 5 + %] + </td> + </tr> + [% END %] + + <tr> + [% IF bug.cc %] + <td align="right" valign="top"> + <label for="cc"><b>CC</b></label>: + </td> + <td valign="top"> + <select id="cc" name="cc" multiple="multiple" size="5"> + [% FOREACH c = bug.cc %] + <option value="[% c FILTER html %]">[% c FILTER html %]</option> + [% END %] + </select> + [% IF user.id %] + <br> + <input type="checkbox" id="removecc" name="removecc"> + [%%]<label for="removecc">Remove selected CCs</label> + <br> + [% END %] + </td> + [% ELSE %] + <td colspan="2"><input type="hidden" name="cc" value=""></td> + [% END %] + </tr> + </table> +[% END %] + [%############################################################################%] [%# Block for dependencies #%] [%############################################################################%] [% BLOCK dependencies %] - <th align="right">[% terms.Bug %] [%+ bug.bug_id %] [%+ dep.title %]:</th> + <th align="right"> + <label for="[% dep.fieldname %]"[% " accesskey=\"$accesskey\"" IF accesskey %]> + [% dep.title %]</label>: + </th> <td> [% FOREACH depbug = bug.${dep.fieldname} %] [% depbug FILTER bug_link(depbug) FILTER none %][% " " %] [% END %] </td> <td> - <input name="[% dep.fieldname %]" [% " accesskey=\"$accesskey\"" IF accesskey %] - value="[% bug.${dep.fieldname}.join(', ') %]"> + [% IF bug.check_can_change_field(dep.fieldname, 0, 1) %] + <input name="[% dep.fieldname %]" id="[% dep.fieldname %]" + value="[% bug.${dep.fieldname}.join(', ') %]"> + [% ELSE %] + <input type="hidden" id="[% dep.fieldname %]" name="[% dep.fieldname %]" + value="[% bug.${dep.fieldname}.join(', ') %]"> + [% END %] </td> [% accesskey = undef %] [% END %] @@ -670,15 +794,46 @@ [% BLOCK select %] <td> - <label for="[% selname %]"[% " accesskey=\"$accesskey\"" IF accesskey %]> - <select name="[% selname %]" id="[% selname %]"> + [% IF bug.check_can_change_field(selname, 0, 1) AND bug.choices.${selname}.size > 1 %] + <select id="[% selname %]" name="[% selname %]"> [% FOREACH x = bug.choices.${selname} %] <option value="[% x FILTER html %]" [% " selected" IF x == bug.${selname} %]>[% x FILTER html %] </option> [% END %] </select> - </label> + [% ELSE %] + <input type="hidden" id="[% selname %]" name="[% selname %]" value="[% bug.${selname} FILTER html %]"> + [% bug.${selname} FILTER html %] + [% END %] </td> - [% accesskey = undef %] +[% END %] + +[%############################################################################%] +[%# Block for INPUT fields #%] +[%############################################################################%] + +[% BLOCK input %] + <td[% " colspan=\"$colspan\"" IF colspan %]> + [% val = value ? value : bug.$inputname %] + [% IF bug.check_can_change_field(inputname, 0, 1) %] + <input id="[% inputname %]" name="[% inputname %]" + value="[% val FILTER html %]"[% " size=\"$size\"" IF size %] + [% " maxlength=\"$maxlength\"" IF maxlength %]> + [% ELSE %] + <input type="hidden" name="[% inputname %]" id="[% inputname %]" + value="[% val FILTER html %]"> + [% IF size && val.length > size %] + <span title="[% val FILTER html %]"> + [% val FILTER truncate(size) FILTER html %] + </span> + [% ELSE %] + [% val FILTER html %] + [% END %] + [% END %] + </td> + [% maxlength = 0 %] + [% colspan = 0 %] + [% size = 0 %] + [% value = undef %] [% END %] diff --git a/template/en/default/bug/field.html.tmpl b/template/en/default/bug/field.html.tmpl new file mode 100644 index 000000000..07617f19a --- /dev/null +++ b/template/en/default/bug/field.html.tmpl @@ -0,0 +1,63 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # The Initial Developer of the Original Code is Netscape Communications + # Corporation. Portions created by Netscape are + # Copyright (C) 1998 Netscape Communications Corporation. All + # Rights Reserved. + # + # Contributor(s): Myk Melez <myk@mozilla.org> + # Max Kanat-Alexander <mkanat@bugzilla.org> + #%] + +[%# INTERFACE: + # field: a Bugzilla::Field object + # value: The value of the field for this bug. + # editable: Whether the field should be displayed as an editable + # <input> or as just the plain text of its value. + # allow_dont_change: display the --do_not_change-- option for select fields. + # value_span: A colspan for the table cell containing + # the field value. + #%] + +<th class="field_label"> + [% IF editable %] + <label for="[% field.name FILTER html %]"> + [% END %] + [% field_descs.${field.name} FILTER html %]: + [% '</label>' IF editable %] +</th> + +<td class="field_value" [% "colspan=\"$value_span\"" FILTER none IF value_span %]> +[% IF editable %] + [% SWITCH field.type %] + [% CASE constants.FIELD_TYPE_FREETEXT %] + <input name="[% field.name FILTER html %]" value="[% value FILTER html %]" size="60"> + [% CASE constants.FIELD_TYPE_SINGLE_SELECT %] + <select id="[% field.name FILTER html %]" name="[% field.name FILTER html %]"> + [% IF allow_dont_change %] + <option value="[% dontchange FILTER html %]"> + [% dontchange FILTER html %] + </option> + [% END %] + [% FOREACH legal_value = field.legal_values %] + <option value="[% legal_value FILTER html %]" + [%- " selected=\"selected\"" IF value == legal_value %]> + [%- legal_value FILTER html %]</option> + [% END %] + </select> + [% END %] +[% ELSE %] + [% value FILTER html %] +[% END %] +</td> diff --git a/template/en/default/bug/knob.html.tmpl b/template/en/default/bug/knob.html.tmpl index ac82550d3..9eeeb4223 100644 --- a/template/en/default/bug/knob.html.tmpl +++ b/template/en/default/bug/knob.html.tmpl @@ -24,17 +24,15 @@ [%# *** Knob *** %] - <br> - <input type="radio" id="knob-leave" name="knob" value="none" checked="checked"> - <label for="knob-leave"> - Leave as <b>[% status_descs.${bug.bug_status} FILTER html %] - [% resolution_descs.${bug.resolution} FILTER html %]</b> - </label> - <br> +<br> +<div id="knob"> + <div id="knob-options"> [% knum = 1 %] + [% initial_action_shown = 0 %] [% IF bug.isunconfirmed && bug.user.canconfirm %] + [% PROCESS initial_action %] <input type="radio" id="knob-confirm" name="knob" value="confirm"> <label for="knob-confirm"> Confirm [% terms.bug %] (change status to <b>[% status_descs.NEW FILTER html %]</b>) @@ -45,6 +43,7 @@ [% IF bug.isopened && bug.bug_status != "ASSIGNED" && bug.user.canedit && (!bug.isunconfirmed || bug.user.canconfirm) %] + [% PROCESS initial_action %] <input type="radio" id="knob-accept" name="knob" value="accept"> <label for="knob-accept"> Accept [% terms.bug %] ( @@ -58,38 +57,25 @@ [% IF bug.user.canedit || bug.user.isreporter %] [% IF bug.isopened %] [% IF bug.resolution %] + [% PROCESS initial_action %] <input type="radio" id="knob-clear" name="knob" value="clearresolution"> <label for="knob-clear"> Clear the resolution (remove the current resolution of - <b>[% status_descs.${bug.resolution} FILTER html %]</b>) + <b>[% get_resolution(bug.resolution) FILTER html %]</b>) </label> <br> [% knum = knum + 1 %] [% END %] + [% PROCESS initial_action %] <input type="radio" id="knob-resolve" name="knob" value="resolve"> <label for="knob-resolve"> Resolve [% terms.bug %], changing <a href="page.cgi?id=fields.html#resolution">resolution</a> to </label> - <select name="resolution" - onchange="document.changeform.knob[[% knum %]].checked=true"> - [% FOREACH r = bug.choices.resolution %] - <option value="[% r FILTER html %]">[% resolution_descs.${r} FILTER html %]</option> - [% END %] - </select> - <br> - [% knum = knum + 1 %] - - <input type="radio" id="knob-duplicate" name="knob" value="duplicate"> - <label for="knob-duplicate"> - Resolve [% terms.bug %], mark it as duplicate of [% terms.bug %] # - </label> - <input name="dup_id" size="6" - onchange="if (this.value != '') - {document.changeform.knob[[% knum %]].checked=true}"> - <br> - [% knum = knum + 1 %] + [% PROCESS select_resolution %] + + [% PROCESS duplicate %] [% IF bug.user.canedit %] <input type="radio" id="knob-reassign" name="knob" value="reassign"> @@ -120,8 +106,8 @@ <input type="radio" id="knob-reassign-cmp" name="knob" value="reassignbycomponent"> <label for="knob-reassign-cmp"> Reassign [% terms.bug %] to default assignee - [% " and QA contact" IF Param('useqacontact') %] - of selected component + [% " and QA contact," IF Param('useqacontact') %] + and add Default CC of selected component </label> <br> [% IF bug.isunconfirmed && bug.user.canconfirm %] @@ -136,6 +122,15 @@ [% ELSE %] [% IF bug.resolution != "MOVED" || (bug.resolution == "MOVED" && bug.user.canmove) %] + [% PROCESS initial_action %] + <input type="radio" id="knob-change-resolution" name="knob" value="change_resolution"> + <label for="knob-change-resolution"> + Change <a href="page.cgi?id=fields.html#resolution">resolution</a> to + </label> + [% PROCESS select_resolution %] + + [% PROCESS duplicate %] + <input type="radio" id="knob-reopen" name="knob" value="reopen"> <label for="knob-reopen"> Reopen [% terms.bug %] @@ -144,6 +139,7 @@ [% knum = knum + 1 %] [% END %] [% IF bug.bug_status == "RESOLVED" %] + [% PROCESS initial_action %] <input type="radio" id="knob-verify" name="knob" value="verify"> <label for="knob-verify"> Mark [% terms.bug %] as <b>[% status_descs.VERIFIED FILTER html %]</b> @@ -152,6 +148,7 @@ [% knum = knum + 1 %] [% END %] [% IF bug.bug_status != "CLOSED" %] + [% PROCESS initial_action %] <input type="radio" id="knob-close" name="knob" value="close"> <label for="knob-close"> Mark [% terms.bug %] as <b>[% status_descs.CLOSED FILTER html %]</b> @@ -161,29 +158,51 @@ [% END %] [% END %] [% END %] + </div> - <input type="submit" value="Commit"> - <input type="hidden" name="form_name" value="process_bug"> - <p> - <font size="+1"> - <b> - <a href="show_activity.cgi?id=[% bug.bug_id %]">View [% terms.Bug %] Activity</a> - | - <a href="show_bug.cgi?format=multiple&id=[% bug.bug_id %]">Format For Printing</a> - | - <a href="show_bug.cgi?ctype=xml&id=[% bug.bug_id %]">XML</a> - | - <a href="enter_bug.cgi?cloned_bug_id=[% bug.bug_id %]">Clone This [% terms.Bug %]</a> - - [%# Links to more things users can do with this bug. %] - [% Hook.process("links") %] - </b> - </font> - + <div id="knob-buttons"> + <input type="submit" value="Commit" id="commit"> [% IF bug.user.canmove %] <font size="+1"><b> | </b></font> - <input type="submit" name="action" + <input type="submit" name="action" id="action" value="[% Param("move-button-text") %]"> [% END %] - </p> + </div> +</div> + +[%# Common actions %] +[% BLOCK initial_action %] + [%# Only show 'Leave as' action in combination with another knob %] + [% IF !initial_action_shown %] + <input type="radio" id="knob-leave" name="knob" value="none" checked="checked"> + <label for="knob-leave"> + Leave as <b>[% status_descs.${bug.bug_status} FILTER html %] + [% get_resolution(bug.resolution) FILTER html %]</b> + </label> + <br> + [% initial_action_shown = 1 %] + [% END %] +[% END %] + +[% BLOCK select_resolution %] + <select name="resolution" + onchange="document.changeform.knob[[% knum %]].checked=true"> + [% FOREACH r = bug.choices.resolution %] + <option value="[% r FILTER html %]">[% get_resolution(r) FILTER html %]</option> + [% END %] + </select> + <br> + [% knum = knum + 1 %] +[% END %] + +[% BLOCK duplicate %] + <input type="radio" id="knob-duplicate" name="knob" value="duplicate"> + <label for="knob-duplicate"> + Mark the [% terms.bug %] as duplicate of [% terms.bug %] # + </label> + <input name="dup_id" size="6" + onchange="if (this.value != '') {document.changeform.knob[[% knum %]].checked=true}"> + <br> + [% knum = knum + 1 %] +[% END %] diff --git a/template/en/default/bug/navigate.html.tmpl b/template/en/default/bug/navigate.html.tmpl index 0263f6535..b6e1351ee 100644 --- a/template/en/default/bug/navigate.html.tmpl +++ b/template/en/default/bug/navigate.html.tmpl @@ -66,6 +66,3 @@ <i><font color="#777777">No search results available</font></i> [% END %] - - <a href="query.cgi">Search page</a> - <a href="enter_bug.cgi">Enter new [% terms.bug %]</a> diff --git a/template/en/default/bug/process/CVS/Entries b/template/en/default/bug/process/CVS/Entries index cdb076be8..40ae985c1 100644 --- a/template/en/default/bug/process/CVS/Entries +++ b/template/en/default/bug/process/CVS/Entries @@ -1,7 +1,7 @@ -/bugmail.html.tmpl/1.6/Mon Oct 10 16:56:28 2005//TBUGZILLA-2_22_3 -/confirm-duplicate.html.tmpl/1.9/Fri Apr 8 00:45:47 2005//TBUGZILLA-2_22_3 -/header.html.tmpl/1.3.12.1/Fri Oct 13 13:01:57 2006//TBUGZILLA-2_22_3 -/midair.html.tmpl/1.15.2.2/Mon Mar 6 23:03:27 2006//TBUGZILLA-2_22_3 -/results.html.tmpl/1.10/Sun Aug 21 17:36:50 2005//TBUGZILLA-2_22_3 -/verify-new-product.html.tmpl/1.16/Tue Jul 12 22:25:11 2005//TBUGZILLA-2_22_3 +/bugmail.html.tmpl/1.7/Thu Oct 19 19:23:16 2006//TBUGZILLA-3_0 +/confirm-duplicate.html.tmpl/1.11/Tue Nov 14 18:30:53 2006//TBUGZILLA-3_0 +/header.html.tmpl/1.5/Sun Feb 4 15:11:41 2007//TBUGZILLA-3_0 +/midair.html.tmpl/1.19/Tue Nov 14 18:30:53 2006//TBUGZILLA-3_0 +/results.html.tmpl/1.11/Thu Oct 19 19:23:16 2006//TBUGZILLA-3_0 +/verify-new-product.html.tmpl/1.20/Mon Jan 8 00:56:00 2007//TBUGZILLA-3_0 D diff --git a/template/en/default/bug/process/CVS/Tag b/template/en/default/bug/process/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/bug/process/CVS/Tag +++ b/template/en/default/bug/process/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/bug/process/bugmail.html.tmpl b/template/en/default/bug/process/bugmail.html.tmpl index 557f091a1..670c2b04e 100644 --- a/template/en/default/bug/process/bugmail.html.tmpl +++ b/template/en/default/bug/process/bugmail.html.tmpl @@ -40,32 +40,29 @@ [% mail = SendBugMail(mailing_bugid, mailrecipients) %] +<dl> [% PROCESS emails description = "Email sent to" names = mail.sent %] -<br> + [% PROCESS emails description = "Excluding" names = mail.excluded %] -<br> -<center> - If you wish to tweak the kinds of mail [% terms.Bugzilla %] sends you, you can - <a href="userprefs.cgi?tab=email">change your preferences</a>. -</center> - +</dl> [%############################################################################%] [%# Block for a set of email addresses #%] [%############################################################################%] [% BLOCK emails %] - <b>[% description FILTER html %]:</b> + <dt>[% description FILTER html %]:</dt> + <dd> [% IF user.can_see_bug(mailing_bugid) %] [% IF names.size > 0 %] [%+ FOREACH name = names %] - [% name FILTER html %][% ", " UNLESS loop.last() %] + <code>[% name FILTER html %]</code>[% ", " UNLESS loop.last() %] [% END %] [% ELSE %] no one @@ -73,4 +70,5 @@ [% ELSE %] (list of e-mails not available) [% END %] + </dd> [% END %] diff --git a/template/en/default/bug/process/confirm-duplicate.html.tmpl b/template/en/default/bug/process/confirm-duplicate.html.tmpl index 815b3d43c..eb3b82b4f 100644 --- a/template/en/default/bug/process/confirm-duplicate.html.tmpl +++ b/template/en/default/bug/process/confirm-duplicate.html.tmpl @@ -29,19 +29,19 @@ #%] [% PROCESS global/variables.none.tmpl %] - [% PROCESS global/header.html.tmpl title="Duplicate Warning" %] +[% orig_bug = "$terms.bug $original_bug_id" + FILTER bug_link(original_bug_id) %] <p> When marking [% terms.abug %] as a duplicate, the reporter of the duplicate is normally added to the CC list of the original. The permissions - on [% terms.bug %] [%+ original_bug_id %] (the original) are currently set + on [% orig_bug FILTER none %] (the original) are currently set such that the reporter would not normally be able to see it. </p> <p> - <b>Adding the reporter to the CC list of [% terms.bug %] - [%+ original_bug_id %] + <b>Adding the reporter to the CC list of [% orig_bug FILTER none %] [% IF cclist_accessible %] will immediately [% ELSE %] @@ -57,18 +57,18 @@ <p> <input type="radio" name="confirm_add_duplicate" value="1"> - Yes, add the reporter to CC list on [% terms.bug %] [%+ original_bug_id %] + Yes, add the reporter to CC list on [% orig_bug FILTER none %] </p> <p> <input type="radio" name="confirm_add_duplicate" value="0" checked="checked"> - No, do not add the reporter to CC list on [% terms.bug %] - [%+ original_bug_id %] + No, do not add the reporter to CC list on [% orig_bug FILTER none %] </p> <p> - <a href="show_bug.cgi?id=[% duplicate_bug_id %]">Throw away my changes, - and revisit [% terms.bug %] [%+ duplicate_bug_id %]</a> + [% "Throw away my changes, and revisit $terms.bug $duplicate_bug_id" + FILTER bug_link(duplicate_bug_id) FILTER none %] +</p> <p> - <input type="submit" value="Submit"> + <input type="submit" id="process" value="Submit"> </p> </form> diff --git a/template/en/default/bug/process/header.html.tmpl b/template/en/default/bug/process/header.html.tmpl index 6a9581cb3..f15648c7d 100644 --- a/template/en/default/bug/process/header.html.tmpl +++ b/template/en/default/bug/process/header.html.tmpl @@ -25,8 +25,17 @@ [% PROCESS global/variables.none.tmpl %] +[% USE Bugzilla %] + [% IF title_tag == "bug_processed" %] - [% title = "$terms.Bug processed" %] + [% title = BLOCK %] + [% IF Bugzilla.cgi.param('id') %] + [% terms.Bug %] [%+ id FILTER html %] + [% ELSE %] + [% terms.Bugs %] + [% END %] + processed + [% END %] [% ELSIF title_tag == "mid_air" %] [% title = "Mid-air collision!" %] [% ELSIF title_tag == "change_votes" %] diff --git a/template/en/default/bug/process/midair.html.tmpl b/template/en/default/bug/process/midair.html.tmpl index aa587a4ca..b66be2ca7 100644 --- a/template/en/default/bug/process/midair.html.tmpl +++ b/template/en/default/bug/process/midair.html.tmpl @@ -45,7 +45,9 @@ <h1>Mid-air collision detected!</h1> <p> - Someone else has made changes to this [% terms.bug %] at the same time you were trying to. + Someone else has made changes to + [%+ "$terms.bug $bug_id" FILTER bug_link(bug_id) FILTER none %] + at the same time you were trying to. The changes made were: </p> @@ -77,14 +79,14 @@ You have the following choices: <li> <form method="post" action="process_bug.cgi"> [% PROCESS "global/hidden-fields.html.tmpl" exclude="^Bugzilla_(login|password)$" %] - <input type="submit" value="Submit my changes anyway"> + <input type="submit" id="process" value="Submit my changes anyway"> This will cause all of the above changes to be overwritten [% ", except for the added comment(s)" IF comments.size > start_at %]. </form> </li> <li> - <a href="show_bug.cgi?id=[% bug_id %]">Throw away my changes, - and revisit [% terms.bug %] [%+ bug_id %]</a> + Throw away my changes, and + [%+ "revisit $terms.bug $bug_id" FILTER bug_link(bug_id) FILTER none %] </li> </ul> diff --git a/template/en/default/bug/process/results.html.tmpl b/template/en/default/bug/process/results.html.tmpl index a21858792..9265a44dc 100644 --- a/template/en/default/bug/process/results.html.tmpl +++ b/template/en/default/bug/process/results.html.tmpl @@ -37,36 +37,25 @@ [% DEFAULT type="bug" %] +[% Link = BLOCK %][% "$terms.Bug $id" FILTER bug_link(id) %][% END %] +[% link = BLOCK %][% "$terms.bug $id" FILTER bug_link(id) %][% END %] + [% title = { - 'bug' => "Changes submitted for $terms.bug $id" , - 'dupe' => "Duplicate notation added to $terms.bug $id" , - 'dep' => "Checking for dependency changes on $terms.bug $id" , - 'votes' => "$terms.Bug $id confirmed by number of votes" , - 'created' => "$terms.Bug $id has been added to the database" , - 'move' => "$terms.Bug $id has been moved to another database" , - } - - linktext = { - 'bug' => "Back To $terms.Bug $id" , - 'dupe' => "Go To $terms.Bug $id" , - 'dep' => "Go To $terms.Bug $id" , - 'votes' => "Go To $terms.Bug $id" , - 'created' => "Go To $terms.Bug $id" , - 'move' => "Back To $terms.Bug $id" , + 'bug' => "Changes submitted for $link" , + 'dupe' => "Duplicate notation added to $link" , + 'dep' => "Checking for dependency changes on $link" , + 'votes' => "$Link confirmed by number of votes" , + 'created' => "$Link has been added to the database" , + 'move' => "$Link has been moved to another database" , } %] -<table border="1"> - <tr> - <td> - <h2>[% title.$type %]</h2> - [% PROCESS "bug/process/bugmail.html.tmpl" mailing_bugid = id %] - </td> - <td> - <a href="show_bug.cgi?id=[% id %]">[% linktext.$type %]</a> - [%# Links to more information about the changed bug. %] - [% Hook.process("links") %] - </td> - </tr> -</table> +<dl> + <dt>[% title.$type %]</dt> + <dd> + [% PROCESS "bug/process/bugmail.html.tmpl" mailing_bugid = id %] + [%# Links to more information about the changed bug. %] + [% Hook.process("links") %] + </dd> +</dl> diff --git a/template/en/default/bug/process/verify-new-product.html.tmpl b/template/en/default/bug/process/verify-new-product.html.tmpl index 7e21f88ae..b3ec73241 100644 --- a/template/en/default/bug/process/verify-new-product.html.tmpl +++ b/template/en/default/bug/process/verify-new-product.html.tmpl @@ -47,6 +47,7 @@ [% PROCESS "global/hidden-fields.html.tmpl" exclude=(verify_fields ? "^version|component|target_milestone$" : "") %] +<input type="hidden" name="confirm_product_change" value="1"> [%# Verify the version, component, and target milestone fields. %] [% IF verify_fields %] <h3>Verify Version, Component[% ", Target Milestone" IF use_target_milestone %]</h3> @@ -63,22 +64,34 @@ and the version and component fields are no longer correct. Please set the correct version and component now: [% END %] - <p> + </p> <table> <tr> <td> <b>Version:</b><br> - [% PROCESS "global/select-menu.html.tmpl" name="version" options=versions default=defaults.version %] + [% PROCESS "global/select-menu.html.tmpl" + name="version" + options=versions + default=defaults.version + size=10 %] </td> <td> <b>Component:</b><br> - [% PROCESS "global/select-menu.html.tmpl" name="component" options=components default=defaults.component %] + [% PROCESS "global/select-menu.html.tmpl" + name="component" + options=components + default=defaults.component + size=10 %] </td> [% IF use_target_milestone %] <td> <b>Target Milestone:</b><br> - [% PROCESS "global/select-menu.html.tmpl" name="target_milestone" options=milestones default=defaults.target_milestone %] + [% PROCESS "global/select-menu.html.tmpl" + name="target_milestone" + options=milestones + default=defaults.target_milestone + size=10 %] </td> [% END %] </tr> @@ -101,11 +114,20 @@ </p> [% END %] -<input type="submit" value="Commit"> +<input type="submit" id="change_product" value="Commit"> </form> <hr> -<a href="query.cgi">Cancel and Return to the Search Page</a> + +[%# If 'id' is defined, then we are editing a single bug. + # Else we are editing several bugs at once. %] + +[% IF cgi.param('id') AND cgi.param('id').match('^\d+$') %] + [% id = cgi.param('id') %] + [% "Cancel and Return to $terms.bug $id" FILTER bug_link(id) FILTER none %] +[% ELSE %] + <a href="buglist.cgi?regetlastlist=1">Cancel and Return to the last search results</a> +[% END %] [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/bug/show-multiple.html.tmpl b/template/en/default/bug/show-multiple.html.tmpl index c1eb27c75..d9dc627d2 100644 --- a/template/en/default/bug/show-multiple.html.tmpl +++ b/template/en/default/bug/show-multiple.html.tmpl @@ -18,13 +18,18 @@ # # Contributor(s): Terry Weissman <terry@mozilla.org> # Gervase Markham <gerv@gerv.net> + # Toms Baugis <toms@myrealbox.com> + # Olav Vitters <olav@bkor.dhs.org> + # Max Kanat-Alexander <mkanat@bugzilla.org> #%] [% PROCESS "global/field-descs.none.tmpl" %] [% PROCESS global/header.html.tmpl title = "Full Text $terms.Bug Listing" - style_urls = [ "skins/standard/show_multiple.css" ] + h1 = "" + style_urls = ["skins/standard/show_multiple.css", + "skins/standard/buglist.css"] %] [% PROCESS bug/time.html.tmpl %] [% IF bugs.first %] @@ -46,154 +51,228 @@ [%###########################################################################%] [% BLOCK bug_display %] - <div align="center"> - <b> - <font size="+3">[% terms.Bug %] [%+ bug.bug_id %] - [% bug.short_desc FILTER html %]</font> - </b> - </div> + <h1> + [% terms.Bug %] + <a href="show_bug.cgi?id=[% bug.bug_id %]">[% bug.bug_id %]</a> + [% IF Param("usebugaliases") AND bug.alias AND NOT bug.error %] + ([% bug.alias FILTER html %]) + [% END %] + </h1> - <table width="100%"> + <table class="bugfields"> + [% IF bug.error %] <tr> - <td> - <b>[% terms.Bug %]#:</b> - <a href="show_bug.cgi?id=[% bug.bug_id %]">[% bug.bug_id %]</a> - [% IF Param("usebugaliases") AND bug.alias %] - ([% bug.alias FILTER html %]) + <td class="error"> + [% IF bug.error == "InvalidBugId" %] + '[%+ bug.bug_id FILTER html %]' is not a valid [% terms.bug %] number + [%- IF Param("usebugaliases") %] nor a known [% terms.bug %] alias[% END %]. + [% ELSIF bug.error == "NotPermitted" %] + You are not allowed to view this [% terms.bug %]. + [% ELSIF bug.error == "NotFound" %] + This [% terms.bug %] cannot be found. + [% ELSE %] + [%+ bug.error FILTER html %] [% END %] </td> + </tr> + [% ELSE %] + [%# The rightcell block (also called by the row block) automatically shows + # the fields from rightcells %] + [% rightcells = ['reporter', 'assigned_to'] %] + [% IF Param('useqacontact') %] + [% rightcells.push('qa_contact') %] + [% END %] + [% rightcells.push('') %] + [% IF bug.cc %] + [% rightcells.push('cc') %] + [% END %] + [% IF bug.keywords %] + [% rightcells.push('keywords') %] + [% END %] + + [%# Determine if the bug has a flag %] + [% FOREACH type = bug.flag_types %] + [% IF type.flags.size %] + [% rightcells.push('flags') %] + [% LAST %] + [% END %] + [% END %] + + [% PROCESS row cell = "short_desc" fullrow = 1 %] + + <tr> + <th>[% field_descs.product FILTER html %]:</th> <td> - <b> Product: </b> - [% IF Param("useclassification") %] + [% IF Param("useclassification") && bug.classification_id != 1 %] [[% bug.classification FILTER html %]] [% END %] [% bug.product FILTER html %] </td> - [% PROCESS cell attr = { description => "Version", - name => "version" } %] - [% PROCESS cell attr = { description => "Platform", - name => "rep_platform" } %] + [% PROCESS rightcell %] </tr> + [% PROCESS row cell = "component" %] + <tr> - [% PROCESS cell attr = { description => "OS/Version", - name => "op_sys" } %] + <th>[% field_descs.bug_status FILTER html %]:</th> <td> - <b>Status:</b> [% status_descs.${bug.bug_status} FILTER html %] + [%+ get_resolution(bug.resolution) FILTER html %] </td> - [% PROCESS cell attr = { description => "Severity", - name => "bug_severity" } %] - [% PROCESS cell attr = { description => "Priority", - name => "priority" } %] - </tr> - <tr> - <td> - <b>Resolution:</b> - [% resolution_descs.${bug.resolution} FILTER html %] - </td> - <td> - <b>Assigned To:</b> - [% bug.assigned_to.login FILTER html %] - </td> - <td> - <b>Reported By:</b> - [% bug.reporter.login FILTER html %] - </td> - [% IF Param('useqacontact') %] - <td> - <b>QA Contact:</b> - [% bug.qa_contact.login FILTER html %] - </td> - [% END %] + [% PROCESS rightcell %] </tr> <tr> - <td colspan="2"> - <b>Component:</b> - [% bug.component FILTER html %] + <th>[% field_descs.bug_severity FILTER html %]:</th> + <td class="bz_[% bug.bug_severity FILTER css_class_quote -%]"> + [% bug.bug_severity FILTER html %] </td> - <td colspan="2"> - [% IF Param('usetargetmilestone') %] - <b>Target Milestone:</b> - [% bug.target_milestone FILTER html %] - [% END %] - </td> - </tr> - - <tr> - <td colspan="4"> - <b>URL:</b> - [% IF bug.bug_file_loc - AND NOT bug.bug_file_loc.match("^(javascript|data)") %] - <a href="[% bug.bug_file_loc FILTER html %]"> - [% bug.bug_file_loc FILTER html %]</a> - [% ELSE %] - [% bug.bug_file_loc FILTER html %] - [% END %] + [% PROCESS rightcell %] </tr> <tr> - <td colspan="4"> - <b>Summary:</b> [% bug.short_desc FILTER html %] + <th>[% field_descs.priority FILTER html %]:</th> + <td class="bz_[% bug.priority FILTER css_class_quote -%]"> + [% bug.priority FILTER html %] </td> + + [% PROCESS rightcell %] </tr> - [% IF use_keywords %] + [% PROCESS row cell = "version" %] + [% PROCESS row cell = "target_milestone" IF Param('usetargetmilestone') %] + [% PROCESS row cell = "rep_platform" %] + [% PROCESS row cell = "op_sys" %] + + [% IF bug.bug_file_loc %] <tr> - <td colspan="4"> - <b>Keywords: </b> [% bug.keywords FILTER html %] + <th>[% field_descs.bug_file_loc FILTER html %]:</th> + <td colspan="3"> + [% IF bug.bug_file_loc.match("^(javascript|data)") %] + [% bug.bug_file_loc FILTER html %] + [% ELSE %] + <a href="[% bug.bug_file_loc FILTER html %]"> + [% bug.bug_file_loc FILTER html %]</a> + [% END %] </td> </tr> [% END %] [% IF Param("usestatuswhiteboard") %] + [% PROCESS row cell = "status_whiteboard" fullrow = 1 %] + [% END %] + + [% USE Bugzilla %] + [% field_counter = 0 %] + [% FOREACH field = Bugzilla.get_fields({ obsolete => 0, custom => 1 }) %] + [% field_counter = field_counter + 1 %] + [%# Odd-numbered fields get an opening <tr> %] + [% '<tr>' IF field_counter % 2 %] + [% PROCESS bug/field.html.tmpl value=bug.${field.name} editable=0 %] + [%# Even-numbered fields get a closing <tr> %] + [% '</tr>' IF !(field_counter % 2) %] + [% END %] + [%# And we have to finish the row if we ended on an odd number. %] + [% '<th></th><td></td></tr>' IF field_counter % 2 %] + + [% IF (bug.dependson.size || bug.blocked.size) %] + [% PROCESS dependencies name = "dependson" %] + [% PROCESS dependencies name = "blocked" %] + [% END %] + + [% IF user.in_group(Param("timetrackinggroup")) %] <tr> - <td colspan="4"> - <b>Status Whiteboard:</b> - [% bug.status_whiteboard FILTER html %] + <th>Time tracking:</th> + <td colspan="3"> + <table class="timetracking"> + <tr> + <th>[% field_descs.estimated_time FILTER html %]</th> + <th>[% field_descs.actual_time FILTER html %]</th> + <th>[% field_descs.work_time FILTER html %]</th> + <th>[% field_descs.remaining_time FILTER html %]</th> + <th>[% field_descs.percentage_complete FILTER html %]</th> + <th>Gain</th> + </tr> + <tr> + <td> + [% PROCESS formattimeunit time_unit = bug.estimated_time %] + </td> + <td> + [% PROCESS formattimeunit + time_unit=(bug.remaining_time + bug.actual_time) %] + </td> + <td>[% PROCESS formattimeunit time_unit = bug.actual_time %]</td> + <td> + [% PROCESS formattimeunit time_unit = bug.remaining_time %] + </td> + <td> + [% PROCESS calculatepercentage act = bug.actual_time + rem = bug.remaining_time %] + </td> + <td> + [% PROCESS formattimeunit + time_unit=bug.estimated_time - + (bug.actual_time + bug.remaining_time) %] + </td> + </tr> + </table> </td> </tr> + [% PROCESS row cell="deadline" %] [% END %] - [% IF UserInGroup(Param("timetrackinggroup")) %] + [% IF bug.attachments.size %] <tr> - <td colspan="4"> - <b>Orig. Est.:</b> - [% PROCESS formattimeunit time_unit=bug.estimated_time %] - - <b>Current Est.:</b> - [% PROCESS formattimeunit - time_unit=(bug.remaining_time + bug.actual_time) %] - - <b>Hours Worked:</b> - [% PROCESS formattimeunit time_unit=bug.actual_time %] - <b>Hours Left:</b> - [% PROCESS formattimeunit time_unit=bug.remaining_time %] - - <b>Percentage Complete:</b> - [% PROCESS calculatepercentage act=bug.actual_time - rem=bug.remaining_time %] - <b>Gain</b> - [% PROCESS formattimeunit - time_unit=bug.estimated_time - (bug.actual_time + bug.remaining_time) %] - - <b>Deadline:</b> - [% bug.deadline %] + <th>Attachments:</th> + <td colspan="3"> + [% IF bug.show_attachment_flags %] + <table> + <tr> + <th>Description</th> + <th>Flags</th> + </tr> + [% FOREACH attachment = bug.attachments %] + <tr> + <td> + <a href="attachment.cgi?id=[% attachment.id %]"> + [% attachment.description FILTER html %] + </a>[% "<br>" IF not loop.last() %] + </td> + <td> + [% IF attachment.flags.size == 0 %] + <i>none</i> + [% ELSE %] + [% FOREACH flag = attachment.flags %] + [% flag.setter.nick FILTER html %]: + [%+ flag.type.name FILTER html FILTER no_break %][% flag.status %] + [% IF flag.status == "?" && flag.requestee %] + ([% flag.requestee.nick FILTER html %]) + [% END %][% ", " IF not loop.last() %] + [% END %] + [% END %] + </td> + </tr> + [% END %] + </table> + [% ELSE %] + [% FOREACH attachment = bug.attachments %] + <a href="attachment.cgi?id=[% attachment.id %]"> + [% attachment.description FILTER html %] + </a>[% "<br>" IF not loop.last() %] + [% END %] + [% END %] </td> </tr> [% END %] - - <tr> - <td colspan="4"> - <b>Opened:</b> - [% bug.creation_ts FILTER time %] - </td> - </tr> + [% END %] </table> + + <br> + [% PROCESS bug/comments.html.tmpl comments = bug.longdescs %] @@ -202,12 +281,72 @@ [%###########################################################################%] -[%# Block for standard table cells #%] +[%# Block for standard table rows #%] [%###########################################################################%] -[% BLOCK cell %] - <td> - <b>[% attr.description FILTER html %]:</b> - [% bug.${attr.name} FILTER html %] - </td> +[% BLOCK row %] + <tr> + <th>[% field_descs.${cell} FILTER html %]:</th> + <td[% " colspan=3" IF fullrow %]>[% bug.${cell} FILTER html %]</td> + [% PROCESS rightcell IF !fullrow %] + </tr> + [% fullrow = 0 %] +[% END %] + + +[%############################################################################%] +[%# Block for dependencies #%] +[%############################################################################%] + +[% BLOCK dependencies %] + <tr> + <th>[% terms.Bug %] [%+ field_descs.${name} FILTER html %]:</th> + <td> + [% FOREACH depbug = bug.${name} %] + [% depbug FILTER bug_link(depbug) FILTER none %][% ", " IF not loop.last() %] + [% END %] + </td> + + [% PROCESS rightcell %] + </tr> +[% END %] + +[%############################################################################%] +[%# Block for cells shown right of the table #%] +[%############################################################################%] + +[% BLOCK rightcell %] + [% IF rightcells %] + [% name = rightcells.shift %] + [% IF name == "cc" %] + <th class="rightcell">[% field_descs.cc FILTER html %]:</th> + <td> + [% FOREACH c = bug.cc %] + [% c FILTER html %][% ", " IF not loop.last() %] + [% END %] + [% ELSIF name == "reporter" || name == "assigned_to" + || name == "qa_contact" %] + <th class="rightcell">[% field_descs.${name} FILTER html %]:</th> + <td>[% bug.${name}.identity FILTER html %]</td> + [% ELSIF name == "flags" %] + <th class="rightcell">Flags:</th> + <td> + [% FOREACH type = bug.flag_types %] + [% FOREACH flag = type.flags %] + [% flag.setter.nick FILTER html %]: + [%+ flag.type.name FILTER html FILTER no_break %][% flag.status %] + [%+ IF flag.status == "?" && flag.requestee %] + ([% flag.requestee.nick FILTER html %]) + [% END %]<br> + [% END %] + [% END %] + </td> + [% ELSIF name != "" %] + <th class="rightcell">[% field_descs.${name} FILTER html %]:</th> + <td>[% bug.${name} FILTER html %]</td> + [% ELSE %] + <td> </td> + <td> </td> + [% END %] + [% END %] [% END %] diff --git a/template/en/default/bug/show.html.tmpl b/template/en/default/bug/show.html.tmpl index faf7b965c..c652773e8 100644 --- a/template/en/default/bug/show.html.tmpl +++ b/template/en/default/bug/show.html.tmpl @@ -19,6 +19,7 @@ # Contributor(s): Gervase Markham <gerv@gerv.net> # Vaskin Kissoyan <vkissoyan@yahoo.com> # Bradley Baetz <bbaetz@student.usyd.edu.au> + # Max Kanat-Alexander <mkanat@bugzilla.org> #%] [% PROCESS global/variables.none.tmpl %] @@ -30,10 +31,10 @@ [% filtered_desc = bug.short_desc FILTER html %] [% filtered_timestamp = bug.delta_ts FILTER time %] [% PROCESS global/header.html.tmpl - title = "$terms.Bug $bug.bug_id - $filtered_desc" - h1 = "$terms.Bugzilla $terms.Bug $bug.bug_id" - h2 = filtered_desc - h3 = "Last modified: $filtered_timestamp" + title = "$terms.Bug $bug.bug_id – $filtered_desc" + header = "$terms.Bug $bug.bug_id" + subheader = filtered_desc + header_addl_info = "Last modified: $filtered_timestamp" bodyclasses = ['bz_bug', "bz_status_$bug.bug_status", "bz_component_$bug.component", diff --git a/template/en/default/bug/show.xml.tmpl b/template/en/default/bug/show.xml.tmpl index 6fe3f3180..61b597f72 100644 --- a/template/en/default/bug/show.xml.tmpl +++ b/template/en/default/bug/show.xml.tmpl @@ -17,12 +17,14 @@ # Rights Reserved. # # Contributor(s): Bradley Baetz <bbaetz@student.usyd.edu.au> + # Colin Ogilvie <mozilla@colinogilvie.co.uk> # #%] +[% PROCESS bug/time.html.tmpl %] <?xml version="1.0" [% IF Param('utf8') %]encoding="UTF-8" [% END %]standalone="yes" ?> <!DOCTYPE bugzilla SYSTEM "[% Param('urlbase') %]bugzilla.dtd"> -<bugzilla version="[% VERSION %]" +<bugzilla version="[% constants.BUGZILLA_VERSION %]" urlbase="[% Param('urlbase') %]" maintainer="[% Param('maintainer') FILTER xml %]" [% IF user.id %] @@ -65,10 +67,13 @@ [% END %] [% IF displayfields.long_desc %] [% FOREACH c = bug.longdescs %] - [% NEXT IF c.isprivate && !UserInGroup(Param("insidergroup")) %] + [% NEXT IF c.isprivate && !user.in_group(Param("insidergroup")) %] <long_desc isprivate="[% c.isprivate FILTER xml %]"> - <who>[% c.email FILTER xml %]</who> + <who name="[% c.name FILTER xml %]">[% c.email FILTER xml %]</who> <bug_when>[% c.time FILTER time FILTER xml %]</bug_when> + [% IF user.in_group(Param('timetrackinggroup')) && (c.work_time - 0 != 0) %] + <work_time>[% PROCESS formattimeunit time_unit = c.work_time FILTER xml %]</work_time> + [% END %] <thetext>[% c.body FILTER xml %]</thetext> </long_desc> [% END %] @@ -76,7 +81,7 @@ [% IF displayfields.attachment %] [% FOREACH a = bug.attachments %] - [% NEXT IF a.isprivate && !UserInGroup(Param("insidergroup")) %] + [% NEXT IF a.isprivate && !user.in_group(Param("insidergroup")) %] <attachment isobsolete="[% a.isobsolete FILTER xml %]" ispatch="[% a.ispatch FILTER xml %]" @@ -87,6 +92,7 @@ <desc>[% a.description FILTER xml %]</desc> <filename>[% a.filename FILTER xml %]</filename> <type>[% a.contenttype FILTER xml %]</type> + <size>[% a.datasize FILTER xml %]</size> [% IF displayfields.attachmentdata %] <data encoding="base64">[% a.data FILTER base64 %]</data> [% END %] @@ -94,9 +100,7 @@ [% FOREACH flag = a.flags %] <flag name="[% flag.type.name FILTER xml %]" status="[% flag.status FILTER xml %]" - [% IF flag.setter %] - setter="[% flag.setter.email FILTER xml %]" - [% END %] + setter="[% flag.setter.email FILTER xml %]" [% IF flag.status == "?" && flag.requestee %] requestee="[% flag.requestee.email FILTER xml %]" [% END %] @@ -116,12 +120,14 @@ [%# We need to handle some fields differently. This should become # nicer once we have custfields, and a type attribute for the fields #%] + [% name = '' %] [% IF field == 'reporter' OR field == 'assigned_to' OR field == 'qa_contact' %] + [% name = val.name %] [% val = val.email %] [% ELSIF field == 'creation_ts' OR field == 'delta_ts' %] [% val = val FILTER time %] [% END %] - <[% field %]>[% val FILTER xml %]</[% field %]> + <[% field %][% IF name != '' %] name="[% name FILTER xml %]"[% END -%]>[% val FILTER xml %]</[% field %]> [% END %] [% END %] diff --git a/template/en/default/bug/summarize-time.html.tmpl b/template/en/default/bug/summarize-time.html.tmpl index 5761b24cf..76a3858fb 100644 --- a/template/en/default/bug/summarize-time.html.tmpl +++ b/template/en/default/bug/summarize-time.html.tmpl @@ -21,25 +21,23 @@ [% title = "Time Summary " %] [% IF do_depends %] [% title = title _ "for " %] - [% h1 = title _ GetBugLink(ids.0, "$terms.Bug $ids.0") %] + [% header = title _ "$terms.Bug $ids.0" FILTER bug_link(ids.0) FILTER none %] [% title = title _ "$terms.Bug $ids.0: " %] - [% h1 = (h1 _ " (and $terms.bugs blocking it)") IF do_depends %] + [% header = (header _ " (and $terms.bugs blocking it)") IF do_depends %] [% ELSE %] - [% title = title _ "($ids.size $terms.bugs selected)" %] - [% h1 = title %] + [% title = title _ "($ids.size $terms.bugs selected)" %] + [% header = title %] [% END %] [% PROCESS global/header.html.tmpl title = title - h1 = h1 + header = header style_urls = ["skins/standard/summarize-time.css"] %] -<p> - [% IF ids.size == 0 %] - No [% terms.bugs %] specified or visible. + <p>No [% terms.bugs %] specified or visible.</p> [% ELSE %] @@ -49,7 +47,6 @@ [% global.grand_total = 0 %] - <p> [% FOREACH workdata = part_list %] [% part = parts.shift %] <div align="right"> @@ -66,7 +63,6 @@ [% ELSE %] [% INCLUDE owner_report %] [% END %] - <p> [% END %] [% IF monthly %] @@ -76,15 +72,13 @@ [% IF null.keys.size > 0 %] [% INCLUDE inactive_report %] - <p> - <h4 style="margin: 0">Total of [% null.keys.size %] + <h4 style="margin: 0">Total of [% null.keys.size %] inactive [% terms.bugs %]</h4> [% END %] [% END %] [% END %] -<p> [% PROCESS global/footer.html.tmpl %] @@ -258,8 +252,8 @@ <table> <tr> <td align="right"> - <b>Period <label accesskey="s" - for="start_date"><u>s</u>tarting</label></b>: + <b><label accesskey="s" + for="start_date">Period <u>s</u>tarting</label></b>: </td><td colspan="3"> <input type="text" id="start_date" name="start_date" size="11" align="right" value="[% start_date FILTER html %]" maxlength="10"> @@ -268,7 +262,7 @@ <input type="text" name="end_date" size="11" id="end_date" align="right" value ="[% end_date FILTER html %]" maxlength="10"> </td><td align="right"> - <input type="submit" value="Summarize"> + <input type="submit" id="summarize" value="Summarize"> </td></tr> <tr> <td> </td><td colspan="4"> @@ -286,26 +280,24 @@ %]><label for="owner" accesskey="d"><u>D</u>eveloper</label> </td><td colspan="2"> - <b>Format</b>: <select name="ctype"> + <label for="ctype"><b>Format</b></label>: <select name="ctype" id="ctype"> <option value="html">HTML Report</option> </select> </td></tr><tr> <td> </td><td colspan="4"> - <label for="monthly" accesskey="m"> <input type="checkbox" name="monthly" [% 'checked="checked"' IF monthly %] id="monthly"> - Split by <u>m</u>onth</label> + <label for="monthly" accesskey="m">Split by <u>m</u>onth</label> [%# XXX: allow splitting by other intervals %] - <label for="detailed" accesskey="t"> <input type="checkbox" name="detailed" [% 'checked="checked"' IF detailed %] id="detailed"> - De<u>t</u>ailed summaries</label> + <label for="detailed" accesskey="t">De<u>t</u>ailed summaries</label> - <label for="inactive" accesskey="i"> <input type="checkbox" name="inactive" [% 'checked="checked"' IF inactive %] id="inactive"> - Also show <u>i</u>nactive [% terms.bugs %]</label> + <label for="inactive" accesskey="i">Also show <u>i</u>nactive + [%+ terms.bugs %]</label> </td> </tr></table> diff --git a/template/en/default/bug/votes/CVS/Entries b/template/en/default/bug/votes/CVS/Entries index 11f1a14b6..d3273219a 100644 --- a/template/en/default/bug/votes/CVS/Entries +++ b/template/en/default/bug/votes/CVS/Entries @@ -1,4 +1,4 @@ -/delete-all.html.tmpl/1.6/Sun Jan 18 18:39:26 2004//TBUGZILLA-2_22_3 -/list-for-bug.html.tmpl/1.10/Fri Sep 2 21:33:36 2005//TBUGZILLA-2_22_3 -/list-for-user.html.tmpl/1.21/Mon Dec 12 02:23:44 2005//TBUGZILLA-2_22_3 +/delete-all.html.tmpl/1.7/Wed Jul 12 12:21:41 2006//TBUGZILLA-3_0 +/list-for-bug.html.tmpl/1.11/Tue Oct 17 19:58:38 2006//TBUGZILLA-3_0 +/list-for-user.html.tmpl/1.25/Tue Oct 17 19:58:38 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/bug/votes/CVS/Tag b/template/en/default/bug/votes/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/bug/votes/CVS/Tag +++ b/template/en/default/bug/votes/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/bug/votes/delete-all.html.tmpl b/template/en/default/bug/votes/delete-all.html.tmpl index 4c1173d54..ffede1db1 100644 --- a/template/en/default/bug/votes/delete-all.html.tmpl +++ b/template/en/default/bug/votes/delete-all.html.tmpl @@ -45,7 +45,7 @@ No, go back and review my votes </p> <p> - <input type="submit" value="Submit"> + <input type="submit" id="vote" value="Submit"> </p> </form> diff --git a/template/en/default/bug/votes/list-for-bug.html.tmpl b/template/en/default/bug/votes/list-for-bug.html.tmpl index 4b4514a90..d23205f1e 100644 --- a/template/en/default/bug/votes/list-for-bug.html.tmpl +++ b/template/en/default/bug/votes/list-for-bug.html.tmpl @@ -30,7 +30,7 @@ [% PROCESS global/header.html.tmpl title = "Show Votes" - h2 = "$terms.Bug <a href=\"show_bug.cgi?id=$bug_id\">$bug_id</a>" + subheader = "$terms.Bug <a href=\"show_bug.cgi?id=$bug_id\">$bug_id</a>" %] [% total = 0 %] diff --git a/template/en/default/bug/votes/list-for-user.html.tmpl b/template/en/default/bug/votes/list-for-user.html.tmpl index 85d25f9a2..6a0e90ebb 100644 --- a/template/en/default/bug/votes/list-for-user.html.tmpl +++ b/template/en/default/bug/votes/list-for-user.html.tmpl @@ -39,7 +39,7 @@ [% PROCESS global/variables.none.tmpl %] [% IF !header_done %] - [% h2 = voting_user.login FILTER html %] + [% subheader = voting_user.login FILTER html %] [% IF canedit %] [% title = "Change Votes" %] [% IF bug_id %] @@ -121,14 +121,11 @@ [% END %] </a></td> <td align="center"> - [% isclosed = !bug.opened %] - <a href="show_bug.cgi?id=[% bug.id %]"> - [% bug.id FILTER closed(isclosed) %]</a> + [% bug.id FILTER bug_link(bug.id) FILTER none %] </td> <td> - <a href="votes.cgi?action=show_bug&bug_id=[% bug.id %]"> - [% bug.summary FILTER html %] - </a> + [% bug.summary FILTER html %] + (<a href="votes.cgi?action=show_bug&bug_id=[% bug.id %]">Voters</a>) </td> </tr> [% END %] @@ -146,7 +143,7 @@ </table> [% IF canedit %] - <input type="submit" value="Change My Votes"> + <input type="submit" value="Change My Votes" id="change"> <br> <br> To change your votes, diff --git a/template/en/default/config.js.tmpl b/template/en/default/config.js.tmpl index 00ba58983..2427c8748 100644 --- a/template/en/default/config.js.tmpl +++ b/template/en/default/config.js.tmpl @@ -27,7 +27,7 @@ // the global bugzilla url var installation = { base_url : '[% Param('urlbase') FILTER js %]', - install_version : '[% VERSION FILTER js %]', + install_version : '[% constants.BUGZILLA_VERSION FILTER js %]', maintainer : '[% Param('maintainer') FILTER js %]' }; diff --git a/template/en/default/config.rdf.tmpl b/template/en/default/config.rdf.tmpl index 4c1047f50..32e94cbca 100644 --- a/template/en/default/config.rdf.tmpl +++ b/template/en/default/config.rdf.tmpl @@ -28,7 +28,7 @@ xmlns:bz="http://www.bugzilla.org/rdf#"> <bz:installation rdf:about="[% Param('urlbase') FILTER html %]"> - <bz:install_version>[% VERSION FILTER html %]</bz:install_version> + <bz:install_version>[% constants.BUGZILLA_VERSION FILTER html %]</bz:install_version> <bz:maintainer>[% Param('maintainer') FILTER html %]</bz:maintainer> <bz:status> diff --git a/template/en/default/email/CVS/Entries b/template/en/default/email/CVS/Entries index 264470014..74d318b56 100644 --- a/template/en/default/email/CVS/Entries +++ b/template/en/default/email/CVS/Entries @@ -1,2 +1,5 @@ -/sudo.txt.tmpl/1.1/Fri Nov 4 16:11:38 2005//TBUGZILLA-2_22_3 +/newchangedmail.txt.tmpl/1.6/Fri Dec 29 23:23:35 2006//TBUGZILLA-3_0 +/sudo.txt.tmpl/1.2/Fri Oct 20 21:22:56 2006//TBUGZILLA-3_0 +/votes-removed.txt.tmpl/1.2/Fri Oct 20 21:22:56 2006//TBUGZILLA-3_0 +/whine.txt.tmpl/1.3/Fri Oct 20 21:22:56 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/email/CVS/Tag b/template/en/default/email/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/email/CVS/Tag +++ b/template/en/default/email/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/email/newchangedmail.txt.tmpl b/template/en/default/email/newchangedmail.txt.tmpl new file mode 100644 index 000000000..cbe162ed3 --- /dev/null +++ b/template/en/default/email/newchangedmail.txt.tmpl @@ -0,0 +1,77 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # The Initial Developer of the Original Code is Netscape Communications + # Corporation. Portions created by Netscape are + # Copyright (C) 1998 Netscape Communications Corporation. All + # Rights Reserved. + # + # Contributor(s): André Batosti <batosti@async.com.br> + #%] + +[% PROCESS "global/variables.none.tmpl" %] +From: [% Param('mailfrom') %] +To: [% to %] +Subject: [[% terms.Bug %] [%+ bugid %]] [% neworchanged %][%+ summary %] +X-Bugzilla-Reason: [% reasonsheader %] +X-Bugzilla-Type: newchanged +X-Bugzilla-Watch-Reason: [% reasonswatchheader %] +X-Bugzilla-Product: [% product %] +X-Bugzilla-Component: [% comp %] +X-Bugzilla-Keywords: [% keywords %] +X-Bugzilla-Severity: [% severity %] +X-Bugzilla-Who: [% changer %] +X-Bugzilla-Status: [% status %] +X-Bugzilla-Priority: [% priority %] +X-Bugzilla-Assigned-To: [% assignedto %] +X-Bugzilla-Target-Milestone: [% targetmilestone %] +X-Bugzilla-Changed-Fields: [% changedfields %] +[%+ threadingmarker %] + +[%+ Param('urlbase') %]show_bug.cgi?id=[% bugid %] + +[%+ diffs %] + +-- +Configure bugmail: [% Param('urlbase') %]userprefs.cgi?tab=email +------- You are receiving this mail because: ------- +[% FOREACH relationship = reasons %] + [% SWITCH relationship %] + [% CASE constants.REL_ASSIGNEE %] +You are the assignee for the [% terms.bug %]. + [% CASE constants.REL_REPORTER %] +You reported the [% terms.bug %]. + [% CASE constants.REL_QA %] +You are the QA contact for the [% terms.bug %]. + [% CASE constants.REL_CC %] +You are on the CC list for the [% terms.bug %]. + [% CASE constants.REL_VOTER %] +You are a voter for the [% terms.bug %]. + [% CASE constants.REL_GLOBAL_WATCHER %] +You are watching all [% terms.bug %] changes. + [% END %] +[% END %] +[% FOREACH relationship = reasons_watch %] + [% SWITCH relationship %] + [% CASE constants.REL_ASSIGNEE %] +You are watching the assignee of the [% terms.bug %]. + [% CASE constants.REL_REPORTER %] +You are watching the reporter. + [% CASE constants.REL_QA %] +You are watching the QA contact of the [% terms.bug %]. + [% CASE constants.REL_CC %] +You are watching someone on the CC list of the [% terms.bug %]. + [% CASE constants.REL_VOTER %] +You are watching a voter for the [% terms.bug %]. + [% END %] +[% END %] diff --git a/template/en/default/email/sudo.txt.tmpl b/template/en/default/email/sudo.txt.tmpl index 06026cf39..758c67b02 100644 --- a/template/en/default/email/sudo.txt.tmpl +++ b/template/en/default/email/sudo.txt.tmpl @@ -22,10 +22,11 @@ [% PROCESS global/variables.none.tmpl %] Content-Type: text/plain -From: [% Param("maintainer") %] +From: [% Param('mailfrom') %] To: [% user.email %] Subject: [[% terms.Bugzilla %]] Your account [% user.login -%] is being impersonated +X-Bugzilla-Type: admin [%+ sudoer.identity %] has used the 'sudo' feature to access [%+ terms.Bugzilla %] using your account. diff --git a/template/en/default/account/exists.html.tmpl b/template/en/default/email/votes-removed.txt.tmpl similarity index 57% rename from template/en/default/account/exists.html.tmpl rename to template/en/default/email/votes-removed.txt.tmpl index 57baa13bb..6bf2afd8c 100644 --- a/template/en/default/account/exists.html.tmpl +++ b/template/en/default/email/votes-removed.txt.tmpl @@ -16,25 +16,24 @@ # Copyright (C) 1998 Netscape Communications Corporation. All # Rights Reserved. # - # Contributor(s): Gervase Markham <gerv@gerv.net> - #%] - -[%# INTERFACE: - # login: string. The user's Bugzilla login email address. + # Contributor(s): Emmanuel Seyman <eseyman@linagora.com> #%] [% PROCESS global/variables.none.tmpl %] -[% PROCESS global/header.html.tmpl - title = "Account Exists" -%] +From: [% Param('mailfrom') %] +To: [% to %] +Subject: [% terms.Bug %] [%+ bugid %] Some or all of your votes have been removed. +X-Bugzilla-Type: voteremoved + +Some or all of your votes have been removed from [% terms.bug %] [%+ bugid %]. + +[% votesoldtext %] + +[% votesnewtext %] + +Reason: [% reason %] + -<form method="get" action="token.cgi"> - <input type="hidden" name="a" value="reqpw"> - <input type="hidden" name="loginname" value="[% login FILTER html %]"> - A [% terms.Bugzilla %] account for <tt>[% login FILTER html %]</tt> already exists. If you - are the account holder and have forgotten your password, - <input type="submit" value="submit a request to change it">. -</form> +[% Param("urlbase") %]show_bug.cgi?id=[% bugid %] -[% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/email/whine.txt.tmpl b/template/en/default/email/whine.txt.tmpl new file mode 100644 index 000000000..e50964e8a --- /dev/null +++ b/template/en/default/email/whine.txt.tmpl @@ -0,0 +1,66 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # The Initial Developer of the Original Code is Netscape Communications + # Corporation. Portions created by Netscape are + # Copyright (C) 1998 Netscape Communications Corporation. All + # Rights Reserved. + # + # Contributor(s): Emmanuel Seyman <eseyman@linagora.com> + #%] + +[% PROCESS "global/field-descs.none.tmpl" %] +From: [% Param("mailfrom") %] +To: [% email %][% Param("emailsuffix") %] +Subject: Your [% terms.Bugzilla %] buglist needs attention. +X-Bugzilla-Type: whine + +[This e-mail has been automatically generated.] + +You have one or more [% terms.bugs %] assigned to you in the [% terms.Bugzilla %] +[% terms.bug %] tracking system ([% Param("urlbase") %]) that require +attention. + +All of these [% terms.bugs %] are in the [% status_descs.NEW %] or +[% status_descs.REOPENED %] state, and have not been +touched in [% Param("whinedays") %] days or more. +You need to take a look at them, and decide on an initial action. + +Generally, this means one of three things: + +(1) You decide this [% terms.bug %] is really quick to deal with (like, it's [% get_resolution("INVALID") %]), + and so you get rid of it immediately. +(2) You decide the [% terms.bug %] doesn't belong to you, and you reassign it to + someone else. (Hint: if you don't know who to reassign it to, make + sure that the Component field seems reasonable, and then use the + "Reassign [% terms.bug %] to default assignee of selected component" option.) +(3) You decide the [% terms.bug %] belongs to you, but you can't solve it this moment. + Just use the "Accept [% terms.bug %]" command. + +To get a list of all [% status_descs.NEW %]/[% status_descs.REOPENED %] [%+ terms.bugs %], you can use this URL (bookmark +it if you like!): + + [% Param("urlbase") %]buglist.cgi?bug_status=NEW&bug_status=REOPENED&assigned_to=[% email %] + +Or, you can use the general query page, at +[%+ Param("urlbase") %]query.cgi + +Appended below are the individual URLs to get to all of your [% status_descs.NEW %] [%+ terms.bugs %] +that haven't been touched for a week or more. + +You will get this message once a day until you've dealt with these [% terms.bugs %]! + +[% FOREACH bug = bugs %] + [%+ bug.summary %] + -> [% Param("urlbase") %]show_bug.cgi?id=[% bug.id %] +[% END %] diff --git a/template/en/default/filterexceptions.pl b/template/en/default/filterexceptions.pl index c66e80134..3a25da7ae 100644 --- a/template/en/default/filterexceptions.pl +++ b/template/en/default/filterexceptions.pl @@ -29,7 +29,7 @@ # Simple literals - [% " selected" ... # Values always used for numbers - [% (i|j|k|n|count) %] # Params - [% Param(... -# Safe functions - [% (time2str|GetBugLink)... +# Safe functions - [% (time2str)... # Safe vmethods - [% foo.size %] [% foo.length %] # [% foo.push() %] # TT loop variables - [% loop.count %] @@ -51,10 +51,6 @@ 'bug.bug_id', ], -'sidebar.xul.tmpl' => [ - 'template_version', -], - 'flag/list.html.tmpl' => [ 'flag.id', 'flag.status', @@ -83,13 +79,16 @@ 'field.description', 'field.accesskey', 'sel.name', - 'sel.accesskey', ], 'search/search-specific.html.tmpl' => [ 'status.name', ], +'search/tabs.html.tmpl' => [ + 'content', +], + 'request/queue.html.tmpl' => [ 'column_headers.$group_field', 'column_headers.$column', @@ -105,7 +104,6 @@ 'reports/duplicates-table.html.tmpl' => [ 'column.name', 'column.description', - 'bug.id', 'bug.count', 'bug.delta', ], @@ -118,7 +116,7 @@ ], 'reports/keywords.html.tmpl' => [ - 'keyword.bugcount', + 'keyword.bug_count', ], 'reports/report-table.csv.tmpl' => [ @@ -127,7 +125,6 @@ ], 'reports/report-table.html.tmpl' => [ - 'buglistbase', '"&$tbl_vals" IF tbl_vals', '"&$col_vals" IF col_vals', '"&$row_vals" IF row_vals', @@ -140,7 +137,6 @@ ], 'reports/report.html.tmpl' => [ - 'imagebase', 'width', 'height', 'imageurl', @@ -172,7 +168,6 @@ 'reports/series-common.html.tmpl' => [ 'sel.name', - 'sel.accesskey', '"onchange=\"$sel.onchange\"" IF sel.onchange', ], @@ -226,10 +221,6 @@ 'h.html', ], -'global/banner.html.tmpl' => [ - 'VERSION', -], - 'global/choose-product.html.tmpl' => [ 'target', ], @@ -245,9 +236,9 @@ 'style', 'onload', 'title', - 'h1', - 'h2', - 'h3', + '" – $header" IF header', + 'subheader', + 'header_addl_info', 'message', ], @@ -256,13 +247,17 @@ 'series.frequency * 2', ], +'global/per-bug-queries.html.tmpl' => [ + '" value=\"$bugids\"" IF bugids', +], + 'global/select-menu.html.tmpl' => [ 'options', 'size', ], -'global/useful-links.html.tmpl' => [ - 'email', +'global/tabs.html.tmpl' => [ + 'content', ], # You are not permitted to add any values here. Everything in this file should @@ -301,10 +296,8 @@ 'bug/dependency-tree.html.tmpl' => [ 'bugid', 'maxdepth', - 'dependson_ids.join(",")', - 'blocked_ids.join(",")', - 'dep_id', 'hide_resolved', + 'ids.join(",")', 'maxdepth + 1', 'maxdepth > 0 && maxdepth <= realdepth ? maxdepth : ""', 'maxdepth == 1 ? 1 @@ -320,13 +313,17 @@ 'group.bit', 'dep.title', 'dep.fieldname', - '" accesskey=\"$accesskey\"" IF accesskey', 'bug.${dep.fieldname}.join(\', \')', 'selname', + '" accesskey=\"$accesskey\"" IF accesskey', + 'inputname', + '" colspan=\"$colspan\"" IF colspan', + '" size=\"$size\"" IF size', + '" maxlength=\"$maxlength\"" IF maxlength', + 'flag.status', ], 'bug/knob.html.tmpl' => [ - 'bug.bug_id', 'knum', ], @@ -339,7 +336,8 @@ 'bug/show-multiple.html.tmpl' => [ 'bug.bug_id', - 'bug.deadline', + 'attachment.id', + 'flag.status', ], 'bug/show.html.tmpl' => [ @@ -347,7 +345,7 @@ ], 'bug/show.xml.tmpl' => [ - 'VERSION', + 'constants.BUGZILLA_VERSION', 'a.id', 'field', ], @@ -380,31 +378,23 @@ 'product.maxvotes', ], -'bug/process/confirm-duplicate.html.tmpl' => [ - 'original_bug_id', - 'duplicate_bug_id', -], - -'bug/process/midair.html.tmpl' => [ - 'bug_id', -], - 'bug/process/results.html.tmpl' => [ 'title.$type', - 'id', - 'linktext.$type', + '"$terms.Bug $id" FILTER bug_link(id)', + '"$terms.bug $id" FILTER bug_link(id)', ], 'bug/create/create.html.tmpl' => [ 'g.bit', 'sel.name', 'sel.description', - 'cloned_bug_id' + 'cloned_bug_id', ], 'bug/create/create-guided.html.tmpl' => [ 'matches.0', 'tablecolour', + 'buildid', 'sel', 'productstring', ], @@ -419,7 +409,7 @@ ], 'attachment/create.html.tmpl' => [ - 'bugid', + 'bug.bug_id', 'attachment.id', ], @@ -427,6 +417,7 @@ 'attachid', 'bugid', 'contenttype', + '"$terms.bug $bugid" FILTER bug_link(bugid)', ], 'attachment/edit.html.tmpl' => [ @@ -439,6 +430,7 @@ 'attachment.id', 'flag.status', 'bugid', + 'obsolete_attachments', ], 'attachment/show-multiple.html.tmpl' => [ @@ -448,7 +440,7 @@ 'attachment/updated.html.tmpl' => [ 'attachid', - 'bugid', + '"$terms.bug $bugid" FILTER bug_link(bugid)', ], 'attachment/diff-header.html.tmpl' => [ @@ -501,18 +493,8 @@ 'classification_text', ], -'admin/keywords/edit.html.tmpl' => [ - 'keyword_id', - 'bug_count', -], - -'admin/keywords/confirm-delete.html.tmpl' => [ - 'keyword_id', - 'bug_count', -], - 'admin/flag-type/confirm-delete.html.tmpl' => [ - 'flag_count', + 'flag_type.flag_count', 'flag_type.id', ], @@ -535,8 +517,8 @@ 'comp.bug_count' ], -'admin/components/deleted.html.tmpl' => [ - 'deleted_bug_count' +'admin/groups/delete.html.tmpl' => [ + 'shared_queries' ], 'admin/users/confirm-delete.html.tmpl' => [ @@ -548,7 +530,6 @@ 'flags.requestee', 'flags.setter', 'longdescs', - 'namedqueries', 'votes', 'series', 'watch.watched', @@ -569,18 +550,6 @@ 'comp.bug_count' ], -'admin/milestones/confirm-delete.html.tmpl' => [ - 'bug_count' -], - -'admin/milestones/deleted.html.tmpl' => [ - 'bug_count' -], - -'admin/versions/confirm-delete.html.tmpl' => [ - 'bug_count' -], - 'account/login.html.tmpl' => [ 'target', ], @@ -596,4 +565,8 @@ 'current_tab.name', ], +'account/prefs/saved-searches.html.tmpl' => [ + 'group.id', +], + ); diff --git a/template/en/default/flag/CVS/Entries b/template/en/default/flag/CVS/Entries index 649f6278a..4cb9b26fc 100644 --- a/template/en/default/flag/CVS/Entries +++ b/template/en/default/flag/CVS/Entries @@ -1,2 +1,2 @@ -/list.html.tmpl/1.19/Sun Aug 21 21:01:33 2005//TBUGZILLA-2_22_3 +/list.html.tmpl/1.27/Sun Jan 14 20:37:57 2007//TBUGZILLA-3_0 D diff --git a/template/en/default/flag/CVS/Tag b/template/en/default/flag/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/flag/CVS/Tag +++ b/template/en/default/flag/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/flag/list.html.tmpl b/template/en/default/flag/list.html.tmpl index 83992617a..6b75b088c 100644 --- a/template/en/default/flag/list.html.tmpl +++ b/template/en/default/flag/list.html.tmpl @@ -21,10 +21,9 @@ <script type="text/javascript"> <!-- - var stored_onload = window.onload; // Enables or disables a requestee field depending on whether or not // the user is requesting the corresponding flag. - function toggleRequesteeField(flagField) + function toggleRequesteeField(flagField, no_focus) { // Convert the ID of the flag field into the ID of its corresponding // requestee field and then use the ID to get the field. @@ -36,7 +35,7 @@ // of the flag field. if (flagField.value == "?") { requesteeField.disabled = false; - requesteeField.focus(); + if (!no_focus) requesteeField.focus(); } else requesteeField.disabled = true; } @@ -60,9 +59,6 @@ inputElement.disabled = true; } } - if (stored_onload) { - stored_onload(); - } } window.onload = disableRequesteeFields; // --> @@ -76,17 +72,21 @@ # on a single bug/attachment). #%] -<table id="flags"> - <tr> - <th colspan="3"> - Flags: - </th> - [% IF any_flags_requesteeble %] - <th> - Requestee: +[% DEFAULT flag_table_id = "flags" %] + +<table id="[% flag_table_id FILTER html %]"> + [% UNLESS flag_no_header %] + <tr> + <th colspan="3"> + Flags: </th> - [% END %] - </tr> + [% IF any_flags_requesteeble %] + <th> + Requestee: + </th> + [% END %] + </tr> + [% END %] [%# Step 1: Display every flag type (except inactive types with no flags). %] [% FOREACH type = flag_types %] @@ -98,20 +98,28 @@ [% flag.setter.nick FILTER html %]: </td> <td> - <label title="[% type.description FILTER html %]"> - [%- type.name FILTER html FILTER no_break %]</label> + <label title="[% type.description FILTER html %]" + for="flag-[% flag.id %]"> + [%- type.name FILTER html FILTER no_break -%]</label> </td> <td> <select id="flag-[% flag.id %]" name="flag-[% flag.id %]" title="[% type.description FILTER html %]" onchange="toggleRequesteeField(this);"> - <option value="X"></option> + [%# Only display statuses the user is allowed to set. %] + [% IF user.can_request_flag(type) %] + <option value="X"></option> + [% END %] [% IF type.is_active %] - <option value="+" [% "selected" IF flag.status == "+" %]>+</option> - <option value="-" [% "selected" IF flag.status == "-" %]>-</option> - [% IF type.is_requestable || flag.status == "?" %] + [% IF (type.is_requestable && user.can_request_flag(type)) || flag.status == "?" %] <option value="?" [% "selected" IF flag.status == "?" %]>?</option> [% END %] + [% IF user.can_set_flag(type) || flag.status == "+" %] + <option value="+" [% "selected" IF flag.status == "+" %]>+</option> + [% END %] + [% IF user.can_set_flag(type) || flag.status == "-" %] + <option value="-" [% "selected" IF flag.status == "-" %]>-</option> + [% END %] [% ELSE %] <option value="[% flag.status %]" selected="selected">[% flag.status %]</option> [% END %] @@ -140,19 +148,23 @@ <tr> <td> </td> <td> - <label title="[% type.description FILTER html %]"> + <label title="[% type.description FILTER html %]" + for="flag_type-[% type.id %]"> [%- type.name FILTER html FILTER no_break %]</label> </td> <td> <select id="flag_type-[% type.id %]" name="flag_type-[% type.id %]" title="[% type.description FILTER html %]" + [% " disabled=\"disabled\"" UNLESS user.can_request_flag(type) %] onchange="toggleRequesteeField(this);"> <option value="X"></option> - <option value="+">+</option> - <option value="-">-</option> - [% IF type.is_requestable %] + [% IF type.is_requestable && user.can_request_flag(type) %] <option value="?">?</option> [% END %] + [% IF user.can_set_flag(type) %] + <option value="+">+</option> + <option value="-">-</option> + [% END %] </select> </td> [% IF any_flags_requesteeble %] @@ -179,19 +191,23 @@ [% END %] <tr> <td colspan="2"> - addl. <label title="[% type.description FILTER html %]"> + addl. <label title="[% type.description FILTER html %]" + for="flag_type-[% type.id %]"> [%- type.name FILTER html FILTER no_break %]</label> </td> <td> <select id="flag_type-[% type.id %]" name="flag_type-[% type.id %]" title="[% type.description FILTER html %]" + [% " disabled=\"disabled\"" UNLESS user.can_request_flag(type) %] onchange="toggleRequesteeField(this);"> <option value="X"></option> - <option value="+">+</option> - <option value="-">-</option> - [% IF type.is_requestable %] + [% IF type.is_requestable && user.can_request_flag(type) %] <option value="?">?</option> [% END %] + [% IF user.can_set_flag(type) %] + <option value="+">+</option> + <option value="-">-</option> + [% END %] </select> </td> [% IF any_flags_requesteeble %] diff --git a/template/en/default/global/CVS/Entries b/template/en/default/global/CVS/Entries index ef7b5a6e5..9dd3b0607 100644 --- a/template/en/default/global/CVS/Entries +++ b/template/en/default/global/CVS/Entries @@ -1,25 +1,29 @@ -/banner.html.tmpl/1.8/Tue Jun 22 21:07:38 2004//TBUGZILLA-2_22_3 -/choose-classification.html.tmpl/1.6.2.1/Sat Oct 14 20:30:58 2006//TBUGZILLA-2_22_3 -/choose-product.html.tmpl/1.13.2.1/Sat Oct 14 20:30:58 2006//TBUGZILLA-2_22_3 -/code-error.html.tmpl/1.62.2.3/Thu Aug 24 21:49:38 2006//TBUGZILLA-2_22_3 -/confirm-user-match.html.tmpl/1.13/Tue Dec 20 05:26:01 2005//TBUGZILLA-2_22_3 -/field-descs.none.tmpl/1.12/Thu Aug 11 06:19:24 2005//TBUGZILLA-2_22_3 -/footer.html.tmpl/1.12/Tue Jun 22 21:07:38 2004//TBUGZILLA-2_22_3 -/header.html.tmpl/1.40.2.1/Sat Oct 14 20:50:44 2006//TBUGZILLA-2_22_3 -/help-header.html.tmpl/1.6/Wed Aug 10 01:30:41 2005//TBUGZILLA-2_22_3 -/help.html.tmpl/1.4/Wed Aug 10 01:30:41 2005//TBUGZILLA-2_22_3 -/hidden-fields.html.tmpl/1.9/Thu Apr 7 23:37:56 2005//TBUGZILLA-2_22_3 -/initialize.none.tmpl/1.1/Sun Jan 11 17:12:14 2004//TBUGZILLA-2_22_3 -/message.html.tmpl/1.7/Sun Jan 18 18:39:28 2004//TBUGZILLA-2_22_3 -/message.txt.tmpl/1.2/Thu Jul 14 06:05:45 2005//TBUGZILLA-2_22_3 -/messages.html.tmpl/1.34/Thu Oct 13 23:58:26 2005//TBUGZILLA-2_22_3 -/per-bug-queries.html.tmpl/1.2/Thu Nov 17 07:56:01 2005//TBUGZILLA-2_22_3 -/select-menu.html.tmpl/1.4/Sun Jan 18 18:39:28 2004//TBUGZILLA-2_22_3 -/setting-descs.none.tmpl/1.6/Tue Oct 25 17:55:13 2005//TBUGZILLA-2_22_3 -/site-navigation.html.tmpl/1.17.2.1/Tue Dec 26 20:19:06 2006//TBUGZILLA-2_22_3 -/tabs.html.tmpl/1.2/Sat Jul 30 01:01:54 2005//TBUGZILLA-2_22_3 -/useful-links.html.tmpl/1.43.2.1/Tue Dec 26 20:19:06 2006//TBUGZILLA-2_22_3 -/user-error.html.tmpl/1.145.2.19/Sun Jul 22 22:25:17 2007//TBUGZILLA-2_22_3 -/userselect.html.tmpl/1.5/Thu Mar 17 15:50:45 2005//TBUGZILLA-2_22_3 -/variables.none.tmpl/1.3/Tue Apr 12 18:19:57 2005//TBUGZILLA-2_22_3 +/banner.html.tmpl/1.10/Tue Jun 27 13:58:55 2006//TBUGZILLA-3_0 +/choose-classification.html.tmpl/1.9/Tue Dec 19 08:32:04 2006//TBUGZILLA-3_0 +/choose-product.html.tmpl/1.17/Tue Dec 19 08:32:04 2006//TBUGZILLA-3_0 +/code-error.html.tmpl/1.92.2.1/Sun Apr 15 01:34:59 2007//TBUGZILLA-3_0 +/common-links.html.tmpl/1.7/Thu Dec 28 16:48:06 2006//TBUGZILLA-3_0 +/confirm-user-match.html.tmpl/1.16.2.1/Wed Apr 4 21:23:03 2007//TBUGZILLA-3_0 +/docslinks.html.tmpl/1.1/Wed Feb 22 14:58:41 2006//TBUGZILLA-3_0 +/field-descs.none.tmpl/1.18/Fri Sep 8 23:11:41 2006//TBUGZILLA-3_0 +/footer.html.tmpl/1.13/Tue Oct 17 19:58:38 2006//TBUGZILLA-3_0 +/header.html.tmpl/1.49/Sat Feb 10 21:55:22 2007//TBUGZILLA-3_0 +/help-header.html.tmpl/1.6/Wed Aug 10 01:30:41 2005//TBUGZILLA-3_0 +/help.html.tmpl/1.4/Wed Aug 10 01:30:41 2005//TBUGZILLA-3_0 +/hidden-fields.html.tmpl/1.10/Wed Jan 17 22:27:10 2007//TBUGZILLA-3_0 +/initialize.none.tmpl/1.1/Sun Jan 11 17:12:14 2004//TBUGZILLA-3_0 +/js-products.html.tmpl/1.1/Wed Jun 14 21:20:53 2006//TBUGZILLA-3_0 +/message.html.tmpl/1.7/Sun Jan 18 18:39:28 2004//TBUGZILLA-3_0 +/message.txt.tmpl/1.3/Thu Sep 21 23:19:04 2006//TBUGZILLA-3_0 +/messages.html.tmpl/1.49.2.2/Sun Apr 15 01:34:59 2007//TBUGZILLA-3_0 +/per-bug-queries.html.tmpl/1.11/Sat Feb 10 21:55:22 2007//TBUGZILLA-3_0 +/select-menu.html.tmpl/1.5/Sun Nov 5 00:27:10 2006//TBUGZILLA-3_0 +/setting-descs.none.tmpl/1.11/Mon Dec 18 19:08:35 2006//TBUGZILLA-3_0 +/site-navigation.html.tmpl/1.22/Tue Dec 26 20:17:26 2006//TBUGZILLA-3_0 +/tabs.html.tmpl/1.3/Tue Oct 17 19:58:38 2006//TBUGZILLA-3_0 +/textarea.html.tmpl/1.1.2.1/Mon May 7 15:52:42 2007//TBUGZILLA-3_0 +/useful-links.html.tmpl/1.56.2.1/Thu Apr 19 17:32:42 2007//TBUGZILLA-3_0 +/user-error.html.tmpl/1.204.2.2/Mon Mar 26 08:00:22 2007//TBUGZILLA-3_0 +/userselect.html.tmpl/1.5/Thu Mar 17 15:50:45 2005//TBUGZILLA-3_0 +/variables.none.tmpl/1.4/Sat Feb 25 23:10:45 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/global/CVS/Tag b/template/en/default/global/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/global/CVS/Tag +++ b/template/en/default/global/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/global/banner.html.tmpl b/template/en/default/global/banner.html.tmpl index 42ccce1aa..620233afa 100644 --- a/template/en/default/global/banner.html.tmpl +++ b/template/en/default/global/banner.html.tmpl @@ -23,16 +23,5 @@ [%# Migration note: this file corresponds to the old Param 'bannerhtml' %] -[% PROCESS global/variables.none.tmpl %] - - <div id="banner"> - <div class="intro"></div> - <p id="banner-name"> - <span>This is [% terms.Bugzilla %]</span> - </p> - <p id="banner-version"> - <a href="http://www.bugzilla.org/"><span>Bugzilla</span></a> - <span>Version [% VERSION %]</span> - </p> - <div class="outro"></div> - </div> + <div id="banner"> + </div> diff --git a/template/en/default/global/choose-classification.html.tmpl b/template/en/default/global/choose-classification.html.tmpl index df0c37911..7f5a5bcad 100644 --- a/template/en/default/global/choose-classification.html.tmpl +++ b/template/en/default/global/choose-classification.html.tmpl @@ -23,7 +23,7 @@ [% IF target == "enter_bug.cgi" %] [% title = "Select Classification" %] - [% h2 = "Please select the classification." %] + [% subheader = "Please select the classification." %] [% END %] [% DEFAULT title = "Choose the classification" %] @@ -33,20 +33,23 @@ [% IF Param('showallproducts') %] <tr> - <th align="right" valign="center" height=50> + <th align="right"> <a href="[% target FILTER url_quote %]?classification=__all [% IF cloned_bug_id %]&cloned_bug_id=[% cloned_bug_id FILTER url_quote %][% END -%] [%- IF format %]&format=[% format FILTER url_quote %][% END %]"> All</a>: </th> - <td valign="center"> Show all products</td> - </tr> + <td valign="top"> Show all products</td> + </tr> + <tr> + <th colspan="2"> </th> + </tr> [% END %] [% FOREACH class = classifications %] <tr> - <th align="right" valign="top"> + <th align="right"> <a href="[% target FILTER url_quote %]?classification=[% class.name FILTER url_quote -%] [%- IF cloned_bug_id %]&cloned_bug_id=[% cloned_bug_id FILTER url_quote %][% END -%] [%- IF format %]&format=[% format FILTER url_quote %][% END %]"> diff --git a/template/en/default/global/choose-product.html.tmpl b/template/en/default/global/choose-product.html.tmpl index c9c5941d1..a24ca61c1 100644 --- a/template/en/default/global/choose-product.html.tmpl +++ b/template/en/default/global/choose-product.html.tmpl @@ -20,18 +20,22 @@ #%] [%# INTERFACE: - # proddesc: hash. May be empty. The hash keys are the products, and the values - # are their descriptions. + # classifications: array of hashes, with an 'object' key representing a + # classification object and 'products' the list of + # product objects the user can enter bugs into. + # target: the script that displays this template. + # cloned_bug_id: ID of the bug being cloned. + # format: the desired format to display the target. #%] [% PROCESS global/variables.none.tmpl %] [% IF target == "enter_bug.cgi" %] [% title = "Enter $terms.Bug" %] - [% h2 = BLOCK %]First, you must pick a product on which to enter [% terms.abug %]. [% END %] + [% subheader = BLOCK %]First, you must pick a product on which to enter [% terms.abug %]. [% END %] [% ELSIF target == "describecomponents.cgi" %] [% title = "$terms.Bugzilla Component Descriptions" %] - [% h2 = "Please specify the product whose components you want described." %] + [% subheader = "Please specify the product whose components you want described." %] [% END %] [% DEFAULT title = "Choose a Product" %] @@ -39,18 +43,29 @@ <table> -[% FOREACH p = proddesc.keys.sort %] +[% FOREACH c = classifications %] + [% IF c.object %] + <tr> + <th colspan="2" align="left">[% c.object.name FILTER html %]: + [%+ c.object.description FILTER html_light %]</th> + </tr> + [% END %] + + [% FOREACH p = c.products %] + <tr> + <th align="right" valign="top"> + <a href="[% target %]?product=[% p.name FILTER url_quote -%] + [%- IF cloned_bug_id %]&cloned_bug_id=[% cloned_bug_id FILTER url_quote %][% END -%] + [%- IF format %]&format=[% format FILTER url_quote %][% END %]"> + [% p.name FILTER html FILTER no_break %]</a>: + </th> + + <td valign="top">[% p.description FILTER html_light %]</td> + </tr> + [% END %] + <tr> - <th align="right" valign="top"> - <a href="[% target %]?product=[% p FILTER url_quote -%] - [%- IF cloned_bug_id %]&cloned_bug_id=[% cloned_bug_id FILTER url_quote %][% END -%] - [%- IF format %]&format=[% format FILTER url_quote %][% END %]"> - [% p FILTER html %]</a>: - </th> - - [% IF proddesc.$p %] - <td valign="top">[% proddesc.$p FILTER html_light %]</td> - [% END %] + <th colspan="2"> </th> </tr> [% END %] diff --git a/template/en/default/global/code-error.html.tmpl b/template/en/default/global/code-error.html.tmpl index d2b496ca2..a4a9df9b9 100644 --- a/template/en/default/global/code-error.html.tmpl +++ b/template/en/default/global/code-error.html.tmpl @@ -39,6 +39,8 @@ [% error_message = BLOCK %] [% IF error == "action_unrecognized" %] + [% docslinks = {'query.html' => "Searching for $terms.bugs", + 'list.html' => "$terms.Bug lists"} %] I don't recognize the value (<em>[% action FILTER html %]</em>) of the <em>action</em> variable. @@ -46,15 +48,23 @@ Attachment #[% attach_id FILTER html %] ([% description FILTER html %]) is already obsolete. - [% ELSIF error == "auth_err" %] - [% title = "Internal Authentication Error" %] - [%# Authentication errors are in a template depending on the auth method, - for pluggability. - #%] - [% INCLUDE "account/auth/$authmethod-error.html.tmpl" %] + [% ELSIF error == "auth_invalid_email" %] + [% title = "Invalid Email Address" %] + We received an email address (<b>[% addr FILTER html %]</b>) + that didn't pass our syntax checking for a legal email address, + when trying to create or update your account. + [% IF default %] + A legal address must contain exactly one '@', + and at least one '.' after the @. + [% ELSE %] + [%+ Param('emailregexpdesc') %] + [% END %] + It must also not contain any of these special characters: + <tt>\ ( ) & < > , ; : " [ ]</tt>, or any whitespace. [% ELSIF error == "authres_unhandled" %] - An authorization handler return value was not handled by the login code. + The result value of [% value FILTER html %] was not handled by + the login code. [% ELSIF error == "bad_page_cgi_id" %] [% title = "Invalid Page ID" %] @@ -70,6 +80,7 @@ the error [% bug.error FILTER html %]. [% ELSIF error == "chart_data_not_generated" %] + [% admindocslinks = {'extraconfig.html' => 'Setting up Charting'} %] [% IF product %] Charts for the <em>[% product FILTER html %]</em> product are not available yet because no charting data has been collected for it since it @@ -93,17 +104,54 @@ Unable to open the chart datafile <tt>[% filename FILTER html %]</tt>. [% ELSIF error == "chart_lines_not_installed" %] + [% admindocslinks = {'installation.html#install-perlmodules' => 'Installing Perl modules necessary for Charting'} %] Charts will not work without the Chart::Lines Perl module being installed. Run checksetup.pl for installation instructions. + [% ELSIF error == "column_not_null_without_default" %] + Failed adding the column [% name FILTER html %]: + You cannot add a NOT NULL column with no default to an existing table + unless you specify something for the <code>$init_value</code> argument. + + [% ELSIF error == "column_not_null_no_default_alter" %] + You cannot alter the [% name FILTER html %] column to be NOT NULL + without specifying a default or something for $set_nulls_to, because + there are NULL values currently in it. + + [% ELSIF error == "db_rename_conflict" %] + Name conflict: Cannot rename [% old FILTER html %] to + [% new FILTER html %] because [% new FILTER html %] already exists. + [% ELSIF error == "cookies_need_value" %] Every cookie must have a value. + [% ELSIF error == "env_no_email" %] + [% terms.Bugzilla %] did not receive an email address from the + environment. + [% IF Param("auth_env_email") %] + This means that the '[% Param("auth_env_email") FILTER html %]' + environment variable was empty or did not exist. + [% ELSE %] + You need to set the "auth_env_email" environment variable to + the name of the environment variable that will contain the + user's email address. + [% END %] + + [% ELSIF error == "extension_invalid" %] + An error occurred processing hook [% name FILTER html %] in + extension [% extension FILTER html %]: [% errstr FILTER html %] + + [% ELSIF error == "extern_id_conflict" %] + The external ID '[% extern_id FILTER html %]' already exists + in the database for '[% username FILTER html %]', but your + account source says that '[% extern_user FILTER html %]' has that ID. + [% ELSIF error == "field_type_mismatch" %] Cannot seem to handle <code>[% field FILTER html %]</code> and <code>[% type FILTER html %]</code> together. [% ELSIF error == "gd_not_installed" %] + [% admindocslinks = {'installation.html#install-perlmodules' => 'Installing Perl modules necessary for Charting'} %] Charts will not work without the GD Perl module being installed. Run checksetup.pl for installation instructions. @@ -118,8 +166,8 @@ A legal [% field FILTER html %] was not set. [% ELSIF error == "inactive_group" %] - Attempted to add [% terms.bug %] to an inactive group, identified by the bit - '[% bit FILTER html %]'. + Attempted to add [% terms.bug %] to the '[% name FILTER html %]' + group, which is not used for [% terms.bugs %]. [% ELSIF error == "invalid_attach_id_to_obsolete" %] The attachment number of one of the attachments you wanted to obsolete, @@ -135,12 +183,11 @@ [% title = "Invalid Column Name" %] The custom sort order specified in your form submission contains an invalid column name <em>[% fragment FILTER html %]</em>. - - [% ELSIF error == "invalid_component" %] - [% title = "Invalid Component" %] - The [% name FILTER html %] component doesn't exist in the - [% product FILTER html %] product. - + + [% ELSIF error == "invalid_customfield_type" %] + [% title = "Invalid Field Type" %] + The type <em>[% type FILTER html %]</em> is not a valid field type. + [% ELSIF error == "invalid_dimensions" %] [% title = "Invalid Dimensions" %] The width or height specified is not a positive integer. @@ -154,16 +201,15 @@ [%+ terms.bug %] [%+ bug_id FILTER html %]. [% END %] - [% ELSIF error == "invalid_numeric_argument" %] - [% title = "Invalid number argument" %] - The argument <code>[% argument FILTER html %] = [% value FILTER html %]</code> - of <code>[% function FILTER html %]</code> is not a natural number. - [% ELSIF error == "invalid_series_id" %] [% title = "Invalid Series" %] The series_id [% series_id FILTER html %] is not valid. It may be that this series has been deleted. + [% ELSIF error == "invalid_webservergroup" %] + There is no such group: [% group FILTER html %]. Check your $webservergroup + setting in [% constants.bz_locations.localconfig FILTER html %]. + [% ELSIF error == "list_comparison_error" %] Unexpected error in list comparing code. @@ -172,9 +218,6 @@ is attached to [% terms.bug %] [%+ attach_bug_id FILTER html %], but you tried to flag it as obsolete while creating a new attachment to [% terms.bug %] [%+ my_bug_id FILTER html %]. - - [% ELSIF error == "flag_nonexistent" %] - There is no flag with ID #[% id FILTER html %]. [% ELSIF error == "flags_not_available" %] [% title = "Flag Editing not Allowed" %] @@ -197,17 +240,6 @@ for flag ID #[% id FILTER html %] [% END %] is invalid. - - [% ELSIF error == "flag_type_component_nonexistent" %] - The component <em>[% name FILTER html %]</em> does not exist - in the product <em>[% product FILTER html %]</em>. - - [% ELSIF error == "flag_type_component_without_product" %] - A component was selected without a product being selected. - - [% ELSIF error == "flag_type_id_invalid" %] - The flag type ID <em>[% id FILTER html %]</em> is not - a positive integer. [% ELSIF error == "flag_type_inactive" %] [% title = "Inactive Flag Type" %] @@ -216,10 +248,7 @@ [% ELSIF error == "flag_type_nonexistent" %] There is no flag type with the ID <em>[% id FILTER html %]</em>. - - [% ELSIF error == "flag_type_product_nonexistent" %] - The product <em>[% product FILTER html %]</em> does not exist. - + [% ELSIF error == "flag_type_target_type_invalid" %] The target type was neither <em>[% terms.bug %]</em> nor <em>attachment</em> but rather <em>[% target_type FILTER html %]</em>. @@ -242,6 +271,32 @@ given. [% END %] + [% ELSIF error == "ldap_bind_failed" %] + Failed to bind to the LDAP server. The error message was: + <code>[% errstr FILTER html %]</code> + + [% ELSIF error == "ldap_cannot_retreive_attr" %] + The specified LDAP attribute [% attr FILTER html %] was not found. + + [% ELSIF error == "ldap_connect_failed" %] + Could not connect to the LDAP server <code>[% server FILTER html %]</code>. + + [% ELSIF error == "ldap_start_tls_failed" %] + Could not start TLS with LDAP server: <code>[% error FILTER html %]</code>. + + [% ELSIF error == "ldap_search_error" %] + An error occurred while trying to search LDAP for + "[% username FILTER html %]": + <code>[% errstr FILTER html %]</code> + + [% ELSIF error == "ldap_server_not_defined" %] + The LDAP server for authentication has not been defined. + + [% ELSIF error == "mail_send_error" %] + There was an error sending mail from '[% mail.header('From') FILTER html %]' + to '[% mail.header('To') FILTER html %]': + [% msg FILTER html %] + [% ELSIF error == "missing_bug_id" %] No [% terms.bug %] ID was given. @@ -259,6 +314,29 @@ Invalid parameter passed to [% function FILTER html %]. It must be numeric. + [% ELSIF error == "param_required" %] + [% title = "Missing Parameter" %] + The function <code>[% function FILTER html %]</code> requires + a <code>[% param FILTER html %]</code> argument, and that + argument was not set. + + [% ELSIF error == "protection_violation" %] + The function <code>[% function FILTER html %]</code> was called + + [% IF argument %] + with the argument <code>[% argument FILTER html %]</code> + [% END %] + + from + + [% IF caller %] + <code>[%+ caller FILTER html %]</code>, which is + [% END %] + + outside the package. This function may only be called from + a subclass of <code>[% superclass FILTER html %]</code>. + + [% ELSIF error == "unknown_comparison_type" %] Specified comparison type is not supported. @@ -281,16 +359,29 @@ option. Setting names must begin with a letter, and contain only letters, digits, or the symbols '_', '-', '.', or ':'. + [% ELSIF error == "setting_subclass_invalid" %] + There is no such Setting subclass as + <code>[% subclass FILTER html %]</code>. + [% ELSIF error == "setting_value_invalid" %] The value "<code>[% value FILTER html %]</code>" is not in the list of legal values for the <em>[% name FILTER html %]</em> setting. + [% ELSIF error == "soap_not_installed" %] + [% admindocslinks = {'installation.html#install-perlmodules' => 'Installing Perl modules'} %] + The XMLRPC interface will not work without the SOAP::Lite Perl module being + installed. + Run checksetup.pl for installation instructions. + [% ELSIF error == "token_generation_error" %] Something is seriously wrong with the token generation system. [% ELSIF error == "template_error" %] [% template_error_msg FILTER html %] + [% ELSIF error == "template_invalid" %] + Template with invalid file name found in hook call: [% name FILTER html %]. + [% ELSIF error == "unable_to_retrieve_password" %] I was unable to retrieve your old password from the database. @@ -308,6 +399,9 @@ I could not figure out what you wanted to do. [% END %] + [% ELSIF error == "usage_mode_invalid" %] + '[% invalid_usage_mode FILTER html %]' is not a valid usage mode. + [% ELSIF error == "must_be_patch" %] [% title = "Attachment Must Be Patch" %] Attachment #[% attach_id FILTER html %] must be a patch. @@ -344,10 +438,26 @@ [% END %] [% END %] +[%# We only want HTML error messages for ERROR_MODE_WEBPAGE %] +[% USE Bugzilla %] +[% IF Bugzilla.error_mode != constants.ERROR_MODE_WEBPAGE %] + [% IF Bugzilla.usage_mode == constants.USAGE_MODE_BROWSER %] + [% error_message FILTER none %] + [% ELSE %] + [% error_message FILTER txt %] + [% END %] + [% RETURN %] +[% END %] + [% UNLESS header_done %] [% PROCESS global/header.html.tmpl %] [% END %] +[% PROCESS global/docslinks.html.tmpl + docslinks = docslinks + admindocslinks = admindocslinks +%] + <tt> <p> [% terms.Bugzilla %] has suffered an internal error. Please save this page and send diff --git a/template/en/default/global/common-links.html.tmpl b/template/en/default/global/common-links.html.tmpl new file mode 100644 index 000000000..dca5d7262 --- /dev/null +++ b/template/en/default/global/common-links.html.tmpl @@ -0,0 +1,105 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # The Initial Developer of the Original Code is Netscape Communications + # Corporation. Portions created by Netscape are + # Copyright (C) 1998 Netscape Communications Corporation. All + # Rights Reserved. + # + # Contributor(s): Gervase Markham <gerv@gerv.net> + # Svetlana Harisova <light@rathedg.com> + #%] + +[% DEFAULT btn_id = "find" %] + +<ul class="links"> + <li><a href="./">Home</a></li> + <li><span class="separator">| </span><a href="enter_bug.cgi">New</a></li> + <li><span class="separator">| </span><a href="query.cgi">Search</a></li> + + <li class="form"> + <span class="separator">| </span> + <form action="buglist.cgi" method="get" + onsubmit="if (this.quicksearch.value == '') + { alert('Please enter one or more search terms first.'); + return false; } return true;"> + <input class="txt" type="text" name="quicksearch"> + <input class="btn" type="submit" value="Find" id="[% btn_id FILTER html %]"> + [%-# Work around FF bug: keep this on one line %]</form></li> + + <li><span class="separator">| </span><a href="report.cgi">Reports</a></li> + + <li> + <span class="separator">| </span> + [% IF user.id %] + <a href="request.cgi?requester=[% user.login FILTER url_quote %]&requestee= + [% user.login FILTER url_quote %]&do_union=1&group=type">My Requests</a> + [% ELSE %] + <a href="request.cgi">Requests</a> + [% END %] + [%-# Work around FF bug: keep this on one line %]</li> + + [% IF user.id && Param('usevotes') %] + <li><span class="separator">| </span><a href="votes.cgi?action=show_user">My Votes</a></li> + [% END %] + + [% IF user.login %] + <li><span class="separator">| </span><a href="userprefs.cgi">Preferences</a></li> + <li> + <span class="separator">| </span> + [% IF user.authorizer.can_logout %] + <a href="relogin.cgi">Log out</a> + [% ELSE %] + Logged in as + [% END %] + [% IF sudoer %] + [%+ sudoer.login FILTER html %] (<b>impersonating + [%+ user.login FILTER html %]</b> + <a href="relogin.cgi?action=end-sudo">end session</a>) + [% ELSE %] + [%+ user.login FILTER html %] + [% END %] + [%-# Work around FF bug: keep this on one line %]</li> + [% ELSE %] + [% IF Param('createemailregexp') + && user.authorizer.user_can_create_account %] + <li><span class="separator">| </span><a href="createaccount.cgi">New Account</a></li> + [% END %] + [% IF user.authorizer.can_login %] + [%# Use the current script name. If an empty name is returned, + # then we are accessing the home page. %] + + [% script_name = cgi.url(Relative => 1) %] + + [% IF cgi.request_method == "POST" OR script_name.match("relogin") %] + [% script_name = "" %] + [% END %] + + [%# If SSL is in use, use 'sslbase', else use 'urlbase'. %] + [% IF Param("sslbase") != "" && Param("ssl") != "never" %] + [% script_name = Param("sslbase") _ script_name %] + [% ELSE %] + [% script_name = Param("urlbase") _ script_name %] + [% END %] + + [% IF cgi.request_method == "GET" AND cgi.query_string %] + [% script_name = script_name _ "?" _ cgi.query_string %] + [% script_name = script_name _ "&GoAheadAndLogIn=1" IF !cgi.query_string.match("GoAheadAndLogIn") %] + [% ELSE %] + [% script_name = script_name _ "?GoAheadAndLogIn=1" %] + [% END %] + + <li><span class="separator">| </span><a href="[% script_name FILTER html %]">Log In</a></li> + [% END %] + [% END %] +</ul> diff --git a/template/en/default/global/confirm-user-match.html.tmpl b/template/en/default/global/confirm-user-match.html.tmpl index 17a812c21..38ac8dd59 100644 --- a/template/en/default/global/confirm-user-match.html.tmpl +++ b/template/en/default/global/confirm-user-match.html.tmpl @@ -42,10 +42,15 @@ [% IF matchsuccess == 1 %] [% PROCESS global/header.html.tmpl title="Confirm Match" %] +[% USE Bugzilla %] + <form method="post" [% IF script -%] action="[% script %]" [%- END -%] + [% IF Bugzilla.cgi.param("data") %] + enctype="multipart/form-data" + [% END %] > <p> @@ -64,7 +69,6 @@ </p> [% END %] -<p> <table border="0"> <tr> <td colspan="2"> @@ -81,6 +85,7 @@ </td> <td align="left" valign="top"> [% FOREACH query = field.value %] + <div class="user_match"> <b>[% query.key FILTER html %]</b> [% IF query.value.users.size %] [% IF query.value.users.size > 1 %] @@ -119,7 +124,6 @@ [% ELSE %] matched <b>[% query.value.users.0.identity FILTER html %]</b> - <br> [% END %] [% ELSE %] [% IF (query.key.length < 3) && !(Param('emailsuffix')) @@ -130,7 +134,7 @@ <font color="#FF0000">did not match anything</font> [% END %] [% END %] - <p> + </div> [% END %] </td> </tr> @@ -143,14 +147,12 @@ </table> -</p> - [% IF matchsuccess == 1 %] [% PROCESS "global/hidden-fields.html.tmpl" exclude="^Bugzilla_(login|password)$" %] <p> - <input type="submit" value="Continue"> + <input type="submit" id="continue" value="Continue"> </p> </form> diff --git a/template/en/default/global/docslinks.html.tmpl b/template/en/default/global/docslinks.html.tmpl new file mode 100644 index 000000000..56c020637 --- /dev/null +++ b/template/en/default/global/docslinks.html.tmpl @@ -0,0 +1,53 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # Contributor(s): Marc Schumann <wurblzap@gmail.com> + #%] + +[%# INTERFACE: + # docslinks: hash. Hash keys will be used as text of the documentation links, + # hash values will be used as links to the document, relative to + # the main Bugzilla documentation directory. + # Example: If you want a 'FAQ' link to point to, the "faq-general" + # named anchor on faq.html, assign + # { 'FAQ' => "faq.html#faq-general" } + # to docslinks. + # You may only link to sections by their given ID; it is not allowed + # to link to a section which is not given an ID (thus getting + # assigned an automatically generated ID). Otherwise, the link + # would break on a recompilation of the documentation. + # admindocslinks: hash. Same as docslinks, but will only be displayed to + # members of the admin group. + #%] + +[% IF Param('docs_urlbase') && + docslinks.keys.size || (admindocslinks.keys.size && user.in_group('admin')) %] + <div id="docslinks"> + <h2>Related documentation</h2> + <ul> + [% IF user.in_group('admin') %] + [% PROCESS docslinkslist docstype = admindocslinks %] + [% END %] + [% PROCESS docslinkslist docstype = docslinks %] + </ul> + </div> +[% END %] + +[% BLOCK docslinkslist %] + [% FOREACH docslink = docstype.keys %] + <li> + <a href="[% Param('docs_urlbase') %] + [% docslink FILTER none %]">[% docstype.$docslink FILTER html %]</a> + </li> + [% END %] +[% END %] diff --git a/template/en/default/global/field-descs.none.tmpl b/template/en/default/global/field-descs.none.tmpl index 8014fe255..94ba948d6 100644 --- a/template/en/default/global/field-descs.none.tmpl +++ b/template/en/default/global/field-descs.none.tmpl @@ -69,6 +69,21 @@ "votes" => "Votes", "work_time" => "Hours Worked"} %] +[%# Also include any custom fields or fields which don't have a + Description here, by copying their Description from the + database. If you want to override this for your language + or your installation, just use a hook. %] + +[% USE Bugzilla %] +[% FOREACH bz_field = Bugzilla.get_fields() %] + [% SET field_descs.${bz_field.name} = bz_field.description + IF !field_descs.${bz_field.name}.defined %] +[% END %] + +[% field_types = { ${constants.FIELD_TYPE_UNKNOWN} => "Unknown Type", + ${constants.FIELD_TYPE_FREETEXT} => "Free Text", + ${constants.FIELD_TYPE_SINGLE_SELECT} => "Drop Down" } %] + [% status_descs = { "UNCONFIRMED" => "UNCONFIRMED", "NEW" => "NEW", "ASSIGNED" => "ASSIGNED", @@ -80,12 +95,12 @@ [% resolution_descs = { "FIXED" => "FIXED", "INVALID" => "INVALID", "WONTFIX" => "WONTFIX", - "LATER" => "LATER", - "REMIND" => "REMIND", "DUPLICATE" => "DUPLICATE", "WORKSFORME" => "WORKSFORME", "MOVED" => "MOVED", "---" => "---", " " => " " } %] +[% MACRO get_resolution(res) GET resolution_descs.$res || res %] + [% Hook.process("end") %] diff --git a/template/en/default/global/footer.html.tmpl b/template/en/default/global/footer.html.tmpl index fc1016621..7de84aa70 100644 --- a/template/en/default/global/footer.html.tmpl +++ b/template/en/default/global/footer.html.tmpl @@ -27,6 +27,8 @@ [% INCLUDE "global/help.html.tmpl" %] +</div> + [%# Migration note: below this point, this file corresponds to the old Param # 'footerhtml' #%] @@ -45,3 +47,4 @@ </body> </html> + diff --git a/template/en/default/global/header.html.tmpl b/template/en/default/global/header.html.tmpl index ae83e0875..ec906f3e6 100644 --- a/template/en/default/global/header.html.tmpl +++ b/template/en/default/global/header.html.tmpl @@ -25,9 +25,9 @@ [%# INTERFACE: # (All the below interface elements are optional.) # title: string. Page title. - # h1: string. Main page header. - # h2: string. Page subheader. - # h3: string. Right-aligned subheader. + # header: string. Main page header. + # subheader: string. Page subheader. + # header_addl_info: string. Additional header information. # bodyclasses: array of extra CSS classes for the <body> # onload: string. JavaScript code to run when the page finishes loading. # javascript: string. Javascript to go in the header. @@ -43,19 +43,20 @@ [% END %] [% DEFAULT - h2 = "" - h3 = "" + subheader = "" + header_addl_info = "" onload = "" + style_urls = [] %] -[%# We should be able to set the default value of the h1 variable +[%# We should be able to set the default value of the header variable # to the value of the title variable using the DEFAULT directive, - # but that doesn't work if a caller sets h1 to the empty string - # to avoid h1 inheriting the value of title, since DEFAULT - # mistakenly treats empty strings as undefined and gives h1 the + # but that doesn't work if a caller sets header to the empty string + # to avoid header inheriting the value of title, since DEFAULT + # mistakenly treats empty strings as undefined and gives header the # value of title anyway. To get around that problem we explicitly - # set h1's default value here only if it is undefined. %] -[% IF !h1.defined %][% h1 = title %][% END %] + # set header's default value here only if it is undefined. %] +[% IF !header.defined %][% header = title %][% END %] <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> @@ -67,6 +68,8 @@ [% PROCESS "global/site-navigation.html.tmpl" %] + [% PROCESS 'global/setting-descs.none.tmpl' %] + [% IF javascript %] <script type="text/javascript"> [% javascript %] @@ -81,32 +84,135 @@ [%+ INCLUDE "global/help-header.html.tmpl" %] - <link href="skins/standard/global.css" rel="stylesheet" type="text/css"> - <link href="skins/custom/global.css" rel="stylesheet" type="text/css"> + [%# Set up the skin CSS cascade: + # 1. Standard Bugzilla stylesheet set (persistent) + # 2. Standard Bugzilla stylesheet set (selectable) + # 3. All third-party "skin" stylesheet sets (selectable) + # 4. Page-specific styles + # 5. Custom Bugzilla stylesheet set (persistent) + # "Selectable" skin file sets may be either preferred or alternate. + # Exactly one is preferred, determined by the "skin" user preference. + #%] + [% IF user.settings.skin.value != 'standard' %] + [% user_skin = user.settings.skin.value %] + [% END %] + [% style_urls.unshift('skins/standard/global.css') %] + + [%# CSS cascade, part 1: Standard Bugzilla stylesheet set (persistent). + # Always present. + #%] + [% FOREACH style_url = style_urls %] + <link href="[% style_url FILTER html %]" + rel="stylesheet" + type="text/css"> + [% END %] + <!--[if IE]> + [%# Internet Explorer treats [if IE] HTML comments as uncommented. + # Use it to import CSS fixes so that Bugzilla looks decent on IE, too. + #%] + <link href="skins/standard/IE-fixes.css" + rel="stylesheet" + type="text/css"> + <![endif]--> + + [%# CSS cascade, part 2: Standard Bugzilla stylesheet set (selectable) + # Present if skin selection is enabled. + #%] + [% IF user.settings.skin.is_enabled %] + [% FOREACH style_url = style_urls %] + <link href="[% style_url FILTER html %]" + rel="[% 'alternate ' IF user_skin %]stylesheet" + title="[% setting_descs.standard FILTER html %]" + type="text/css"> + [% END %] + <!--[if IE]> + [%# Internet Explorer treats [if IE] HTML comments as uncommented. + # Use it to import CSS fixes so that Bugzilla looks decent on IE, + # too. + #%] + <link href="skins/standard/IE-fixes.css" + rel="[% 'alternate ' IF user_skin %]stylesheet" + title="[% setting_descs.standard FILTER html %]" + type="text/css"> + <![endif]--> + [% END %] + + [%# CSS cascade, part 3: Third-party stylesheet set (selectable). + # All third-party skins are present if skin selection is enabled. + # The admin-selected skin is always present. + #%] + [% FOREACH contrib_skin = user.settings.skin.legal_values %] + [% NEXT IF contrib_skin == 'standard' %] + [% NEXT UNLESS contrib_skin == user_skin + OR user.settings.skin.is_enabled %] + [% contrib_skin = contrib_skin FILTER url_quote %] + [% IF contrib_skin.match('\.css$') %] + [%# 1st skin variant: single-file stylesheet %] + <link href="[% "skins/contrib/$contrib_skin" %]" + rel="[% 'alternate ' UNLESS contrib_skin == user_skin %]stylesheet" + title="[% contrib_skin FILTER html %]" + type="text/css"> + [% ELSE %] + [%# 2nd skin variant: stylesheet set %] + [% FOREACH style_url = style_urls %] + [% IF style_url.match('^skins/standard/') %] + <link href="[% style_url.replace('^skins/standard/', + "skins/contrib/$contrib_skin/") %]" + rel="[% 'alternate ' UNLESS contrib_skin == user_skin %]stylesheet" + title="[% contrib_skin FILTER html %]" + type="text/css"> + [% END %] + [% END %] + <!--[if IE]> + [%# Internet Explorer treats [if IE] HTML comments as uncommented. + # Use it to import CSS fixes so that Bugzilla looks decent on IE, + # too. + #%] + <link href="skins/contrib/[% contrib_skin FILTER html %]/IE-fixes.css" + rel="[% 'alternate ' UNLESS contrib_skin == user_skin %]stylesheet" + title="[% contrib_skin FILTER html %]" + type="text/css"> + <![endif]--> + [% END %] + [% END %] + [%# CSS cascade, part 4: page-specific styles. + #%] [% IF style %] <style type="text/css"> [% style %] </style> [% END %] - [% IF style_urls %] - [% FOREACH style_url = style_urls %] - <link href="[% style_url FILTER html %]" rel="stylesheet" type="text/css"> - [% IF style_url.match('^skins/standard/') %] - <link href="[% style_url.replace('^skins/standard/', 'skins/custom/') - FILTER html %]" rel="stylesheet" type="text/css"> - [% END %] + [%# CSS cascade, part 5: Custom Bugzilla stylesheet set (persistent). + # Always present. Site administrators may override all other style + # definitions, including skins, using custom stylesheets. + #%] + [% FOREACH style_url = style_urls %] + [% IF style_url.match('^skins/standard/') %] + <link href="[% style_url.replace('^skins/standard/', "skins/custom/") + FILTER html %]" rel="stylesheet" type="text/css"> [% END %] [% END %] + <!--[if IE]> + [%# Internet Explorer treats [if IE] HTML comments as uncommented. + # Use it to import CSS fixes so that Bugzilla looks decent on IE, too. + #%] + <link href="skins/custom/IE-fixes.css" + rel="stylesheet" + type="text/css"> + <![endif]--> [%# this puts the live bookmark up on firefox for the Atom feed %] [% IF atomlink %] <link rel="alternate" type="application/atom+xml" title="Atom feed" - href="[% atomlink FILTER html %]" /> + href="[% atomlink FILTER html %]"> [% END %] + [%# Required for the 'Autodiscovery' feature in Firefox 2 and IE 7. %] + <link rel="search" type="application/opensearchdescription+xml" + title="[% terms.Bugzilla %]" href="./search_plugin.cgi"> </head> [%# Migration note: contents of the old Param 'bodyhtml' go in the body tag, @@ -123,22 +229,42 @@ # 'bannerhtml' #%] -[% INCLUDE global/banner.html.tmpl %] <div id="header"> - [% IF h1 %] - <h1>[% h1 %]</h1> - [% END %] - [% IF h2 %] - <h2>[% h2 %]</h2> +[% INCLUDE global/banner.html.tmpl %] + +<table border="0" cellspacing="0" cellpadding="0" id="titles"> +<tr> + <td id="title"> + <p>[% terms.Bugzilla %] + [% " – $header" IF header %]</p> + </td> + + [% IF subheader %] + <td id="subtitle"> + <p class="subheader">[% subheader %]</p> + </td> [% END %] - [% IF h3 %] - <h3>[% h3 %]</h3> + [% IF header_addl_info %] + <td id="information"> + <p class="header_addl_info">[% header_addl_info %]</p> + </td> [% END %] +</tr> +</table> + +[% PROCESS "global/common-links.html.tmpl" btn_id = "find_top" %] + </div> +<div id="bugzilla-body"> + +[% IF Param('announcehtml') %] +[% Param('announcehtml') FILTER none %] +[% END %] + [% IF message %] <div id="message">[% message %]</div> [% END %] diff --git a/template/en/default/global/hidden-fields.html.tmpl b/template/en/default/global/hidden-fields.html.tmpl index 7327e43cf..063cdd33b 100644 --- a/template/en/default/global/hidden-fields.html.tmpl +++ b/template/en/default/global/hidden-fields.html.tmpl @@ -34,8 +34,26 @@ [%# The '.slice(0)' bit is here to force the 'param(field)' to be evaluated in a list context, so we can avoid extra code checking for single valued or empty fields %] - [% FOREACH mvalue = cgi.param(field).slice(0) %] - <input type="hidden" name="[% field FILTER html %]" + [% IF field == "data" && cgi.param("data") %] + <div class="box"> + <p> + We were unable to store the file you uploaded because of incomplete information + in the form you just submitted. Because we are unable to retain the file between + form submissions, you must re-attach the file in addition to completing the + remaining missing information above. + </p> + <p> + Please re-attach the file <b>[% cgi.param(field) FILTER html %]</b> in + the field below: + </p> + <p> + <input type="file" id="data" name="data" size="50"> + </p> + </div> + [% ELSE %] + [% FOREACH mvalue = cgi.param(field).slice(0) %] + <input type="hidden" name="[% field FILTER html %]" value="[% mvalue FILTER html FILTER html_linebreak %]"> [% END %] + [% END %] [% END %] diff --git a/template/en/default/global/js-products.html.tmpl b/template/en/default/global/js-products.html.tmpl new file mode 100644 index 000000000..57126f004 --- /dev/null +++ b/template/en/default/global/js-products.html.tmpl @@ -0,0 +1,33 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # The Initial Developer of the Original Code is Netscape Communications + # Corporation. Portions created by Netscape are + # Copyright (C) 1998 Netscape Communications Corporation. All + # Rights Reserved. + # + # Contributor(s): Myk Melez <myk@mozilla.org> + # Frédéric Buclin <LpSolit@gmail.com> + #%] + +[%# The javascript block gets used in header.html.tmpl. %] +[% javascript = BLOCK %] + var usetms = 0; // do we have target milestone? + var first_load = 1; // is this the first time we load the page? + var last_sel = []; // caches last selection + var cpts = new Array(); + [% FOREACH prod = products %] + cpts['[% prod.name FILTER js %]'] = [ + [%- FOREACH comp = prod.components %]'[% comp.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; + [% END %] +[% END %] diff --git a/template/en/default/global/message.txt.tmpl b/template/en/default/global/message.txt.tmpl index fc0ec1977..e8ec1e510 100644 --- a/template/en/default/global/message.txt.tmpl +++ b/template/en/default/global/message.txt.tmpl @@ -23,4 +23,4 @@ [%# Yes, this may show some HTML. But it's the best we # can do at the moment. %] [% PROCESS global/messages.html.tmpl %] -[% message %] +[% message FILTER txt %] diff --git a/template/en/default/global/messages.html.tmpl b/template/en/default/global/messages.html.tmpl index 6730e8835..ad56a3556 100644 --- a/template/en/default/global/messages.html.tmpl +++ b/template/en/default/global/messages.html.tmpl @@ -38,6 +38,15 @@ [% IF groups.size %] You may want to edit the group settings now, using the form below. [% END %] + [% IF login_info %] + You can now go to the <a href="index.cgi">Log In</a> page to enter + this [% terms.Bugzilla %] installation. + [% END %] + + [% ELSIF message_tag == "account_creation_cancelled" %] + [% title = "User Account Creation Canceled" %] + The creation of the user account [% account FILTER html %] has been + canceled. [% ELSIF message_tag == "account_updated" %] [% IF changed_fields.size @@ -57,6 +66,12 @@ A new password has been set. [% ELSIF field == 'disabledtext' %] The disable text has been modified. + [% ELSIF field == 'disable_mail' %] + [% IF otheruser.email_disabled %] + Bugmail has been disabled. + [% ELSE %] + Bugmail has been enabled. + [% END %] [% END %] </li> [% END %] @@ -91,7 +106,7 @@ </ul> [% ELSE %] [% title = "User $otheruser.login not changed" %] - You didn't request any change on the user account + You didn't request any changes to the user's account [%+ otheruser.login FILTER html %]. [% END %] @@ -100,6 +115,28 @@ The user account [% otheruser.login FILTER html %] has been deleted successfully. + [% ELSIF message_tag == "attachment_creation_failed" %] + The [% terms.bug %] was created successfully, but attachment creation + failed. + Please add your attachment by clicking the "Create a New Attachment" link + below. + + [% ELSIF message_tag == "bug_confirmed_by_votes" %] + *** This [% terms.bug %] has been confirmed by popular vote. *** + + [% ELSIF message_tag == "bug_duplicate_of" %] + *** This [% terms.bug %] has been marked as a duplicate of [% terms.bug %] [%+ dupe_of FILTER html %] *** + + [% ELSIF message_tag == "bug_has_duplicate" %] + *** [% terms.Bug %] [%+ dupe FILTER html %] has been marked as a duplicate of this [% terms.bug %]. *** + + [% ELSIF message_tag == "bug_moved_to" %] + <p>[% terms.Bug %] moved to [% Param("move-to-url") FILTER html %].</p> + <p>If the move succeeded, [% login FILTER html %] will receive a mail + containing the number of the new [% terms.bug %] in the other database. + If all went well, please mark this [% terms.bug %] verified, and paste + in a link to the new [% terms.bug %]. Otherwise, reopen this [% terms.bug %]. + [% ELSIF message_tag == "buglist_adding_field" %] [% title = "Adding field to search page..." %] [% link = "Click here if the page does not redisplay automatically." %] @@ -139,24 +176,39 @@ Click <a href="[% redirect_url FILTER html %]">here</a> if the page does not automatically refresh. + [% ELSIF message_tag == "custom_field_created" %] + [% title = "Custom Field Created" %] + The new custom field '[% field.name FILTER html %]' has been + successfully created. + + [% ELSIF message_tag == "custom_field_updated" %] + [% title = "Custom Field Updated" %] + Properties of the '[% field.name FILTER html %]' field have been + successfully updated. + [% ELSIF message_tag == "emailold_change_cancelled" %] [% title = "Cancel Request to Change Email Address" %] The request to change the email address for your account to - [%+ new_email FILTER html %] has been cancelled. + [%+ new_email FILTER html %] has been canceled. [% ELSIF message_tag == "email_change_cancelled" %] [% title = "Cancel Request to Change Email Address" %] The request to change the email address for the account [%+ old_email FILTER html %] to - [%+ new_email FILTER html %] has been cancelled. + [%+ new_email FILTER html %] has been canceled. [% ELSIF message_tag == "email_change_cancelled_reinstated" %] [% title = "Cancel Request to Change Email Address" %] The request to change the email address for the account [%+ old_email FILTER html %] to - [%+ new_email FILTER html %] has been cancelled. + [%+ new_email FILTER html %] has been canceled. Your old account settings have been reinstated. + [% ELSIF message_tag == "flag_creation_failed" %] + [% title = "Flag Creation Failure" %] + An error occured while validating flags: + [%+ flag_creation_error FILTER none %] + [% ELSIF message_tag == "logged_out" %] [% title = "Logged Out" %] [% url = "index.cgi?GoAheadAndLogIn=1" %] @@ -174,6 +226,9 @@ [% IF param_changed.size > 0 %] [% FOREACH param = param_changed %] Changed <em>[% param FILTER html %]</em><br> + [% IF param == 'utf8' && Param('utf8') %] + <strong>You must now re-run checksetup.pl.</strong><br> + [% END %] [% END %] [% ELSE %] No changes made. @@ -187,7 +242,7 @@ [% ELSIF message_tag == "password_change_cancelled" %] [% title = "Cancel Request to Change Password" %] - Your request has been cancelled. + Your request has been canceled. [% ELSIF message_tag == "password_change_request" %] [% title = "Request to Change Password" %] @@ -226,6 +281,91 @@ <a href="editflagtypes.cgi">Back to flag types.</a> </p> + [% ELSIF message_tag == "install_admin_get_email" %] + Enter the e-mail address of the administrator: + + [% ELSIF message_tag == "install_admin_get_name" %] + Enter the real name of the administrator: + + [% ELSIF message_tag == "install_admin_get_password" %] + Enter a password for the administrator account: + + [% ELSIF message_tag == "install_admin_get_password2" %] + Please retype the password to verify: + + [% ELSIF message_tag == "install_admin_created" %] + [% user.login FILTER html %] is now set up as an administrator. + + [% ELSIF message_tag == "install_admin_setup" %] + Looks like we don't have an administrator set up yet. + Either this is your first time using [% terms.Bugzilla %], or your + administrator's privileges might have accidentally been deleted. + + [% ELSIF message_tag == "install_column_add" %] + Adding new column '[% column FILTER html %]' to the '[% table FILTER html %]' table... + + [% ELSIF message_tag == "install_column_drop" %] + Deleting the '[% column FILTER html %]' column from the '[% table FILTER html %]' table... + + [% ELSIF message_tag == "install_column_rename" %] + Renaming column '[% old FILTER html %]' to '[% new FILTER html %]'... + + [% ELSIF message_tag == "install_default_classification" %] + Creating default classification '[% name FILTER html %]'... + + [% ELSIF message_tag == "install_default_product" %] + Creating initial dummy product '[% name FILTER html %]'... + + [% ELSIF message_tag == "install_file_perms_fix" %] + Fixing file permissions... + + [% ELSIF message_tag == "install_group_create" %] + Creating group [% name FILTER html %]... + + [% ELSIF message_tag == "install_setting_new" %] + Adding a new user setting called '[% name FILTER html %]' + + [% ELSIF message_tag == "install_table_drop" %] + Dropping the '[% name FILTER html %]' table... + + [% ELSIF message_tag == "install_table_rename" %] + Renaming the '[% old FILTER html %]' table to '[% new FILTER html %]'... + + [% ELSIF message_tag == "install_urlbase_default" %] + Now that you have installed [% terms.Bugzilla %], you should visit the + 'Parameters' page (linked in the footer of the Administrator + account) to ensure it is set up as you wish - this includes + setting the 'urlbase' option to the correct url. + + [% ELSIF message_tag == "install_webservergroup_empty" %] + **************************************************************************** + WARNING! You have not entered a value for the "webservergroup" parameter + in localconfig. This means that certain files and directories which need + to be editable by both you and the webserver must be world writable, and + other files (including the localconfig file which stores your database + password) must be world readable. This means that _anyone_ who can obtain + local access to this machine can do whatever they want to your + [%+ terms.Bugzilla %] installation, and is probably also able to run + arbitrary Perl code as the user that the webserver runs as. + + You really, really, really need to change this setting. + **************************************************************************** + + [% ELSIF message_tag == "install_webservergroup_not_in" %] + Warning: you have entered a value for the "webservergroup" parameter in + localconfig, but you are not either a) running this script as [% constants.ROOT_USER FILTER html %]; + or b) a member of this group. This can cause permissions problems and + decreased security. If you experience problems running [% terms.Bugzilla %] + scripts, log in as [% constants.ROOT_USER FILTER html %] and re-run this script, become a + member of the group, or remove the value of the "webservergroup" parameter. + + [% ELSIF message_tag == "install_webservergroup_windows" %] + Warning: You have set webservergroup in [% constants.bz_locations.localconfig FILTER html %] + Please understand that this does not bring you any security when + running under Windows. + Verify that the file permissions in your [% terms.Bugzilla %] directory are + suitable for your system. Avoid unnecessary write access. + [% ELSIF message_tag == "product_invalid" %] [% title = "$terms.Bugzilla Component Descriptions" %] The product <em>[% product FILTER html %]</em> does not exist @@ -268,6 +408,9 @@ The cookie that was remembering your login is now gone. [% END %] + [% ELSIF message_tag == "term" %] + [% terms.$term FILTER html %] + [% ELSIF message_tag == "user_match_failed" %] You entered a username that did not match any known [% terms.Bugzilla %] users, so we have instead left diff --git a/template/en/default/global/per-bug-queries.html.tmpl b/template/en/default/global/per-bug-queries.html.tmpl index a7a678532..1b9b21b92 100644 --- a/template/en/default/global/per-bug-queries.html.tmpl +++ b/template/en/default/global/per-bug-queries.html.tmpl @@ -15,29 +15,87 @@ #%] [% IF user.id && user.settings.per_bug_queries.value == "on" %] - <div id="links-special"> - <div class="label"> </div> - <div class="links"> - <form action="buglist.cgi" method="get"> + <li id="links-special"> + <script type="text/javascript"> + <!-- + function update_text() { + // 'lob' means list_of_bugs. + var lob_action = document.getElementById('lob_action'); + var action = lob_action.options[lob_action.selectedIndex].value; + var text = document.getElementById('lob_direction'); + var new_query_text = document.getElementById('lob_new_query_text'); + + if (action == "add") { + text.innerHTML = "to"; + new_query_text.style.display = 'inline'; + } + else { + text.innerHTML = "from"; + new_query_text.style.display = 'none'; + } + } + + function manage_old_lists() { + var old_lists = document.getElementById('lob_oldqueryname'); + // If there is no saved searches available, returns. + if (!old_lists) return; + + var new_query = document.getElementById('lob_newqueryname').value; + + if (new_query != "") { + old_lists.disabled = true; + } + else { + old_lists.disabled = false; + } + } + //--> + </script> + + [%# Get existing lists of bugs for this user %] + [% lists_of_bugs = [] %] + [% FOREACH q = user.queries %] + [% NEXT UNLESS q.bug_ids_only %] + [% lists_of_bugs.push(q.name) %] + [% END %] + <div class="label"></div> + <ul class="links"><li class="form"> + <form id="list_of_bugs" action="buglist.cgi" method="get"> <input type="hidden" name="cmdtype" value="doit"> <input type="hidden" name="remtype" value="asnamed"> - <input type="hidden" name="add_bugids" value="1"> - <input type="submit" value="Add"> [% terms.bugs %] - <input type="text" name="bug_ids" size="8" maxlength="80"> to - [% foundq = 0 %] - [% FOREACH q = user.queries %] - [% NEXT UNLESS q.query_type == constants.LIST_OF_BUGS %] - [% IF !foundq %] - [% foundq = 1 %] - <select name="oldqueryname"> + <input type="hidden" name="list_of_bugs" value="1"> + <select id="lob_action" name="action" onchange="update_text();"> + <option value="add">Add</option> + [% IF lists_of_bugs.size %] + <option value="remove">Remove</option> [% END %] - <option value="[% q.name FILTER html %]"> - [% q.name FILTER html %]</option> + </select> + + [% IF Param('docs_urlbase') %] + <a href="[% Param('docs_urlbase') %]query.html#individual-buglists">the named tag</a> + [% ELSE %] + the named tag + [% END %] + + [% IF lists_of_bugs.size %] + <select id="lob_oldqueryname" name="oldqueryname"> + [% FOREACH query = lists_of_bugs %] + <option value="[% query FILTER html %]">[% query FILTER html %]</option> + [% END %] + </select> [% END %] - [% "</select> or to " IF foundq %] - the new saved search: - <input type="text" name="newqueryname" size="20" maxlength="64"> + <span id="lob_new_query_text"> + [% " or create and add the tag" IF lists_of_bugs.size %] + <input class="txt" type="text" id="lob_newqueryname" + size="20" maxlength="64" name="newqueryname" + onkeyup="manage_old_lists();"> + </span> + <span id="lob_direction">to</span> + [%+ terms.bugs %] + <input type="text" name="bug_ids" size="12" maxlength="80" + [%- " value=\"$bugids\"" IF bugids %]> + <input type="submit" value="Commit" id="commit_list_of_bugs"> </form> - </div> - </div> + </li></ul> + </li> [% END %] diff --git a/template/en/default/global/select-menu.html.tmpl b/template/en/default/global/select-menu.html.tmpl index 725ec88dd..3233ad776 100644 --- a/template/en/default/global/select-menu.html.tmpl +++ b/template/en/default/global/select-menu.html.tmpl @@ -24,7 +24,7 @@ # # multiple: boolean; whether or not the menu is multi-select # - # size: integer; if multi-select, the number of items to display at once + # size: integer; the number of items to display at once # # options: array or hash; the items with which to populate the array. # If a hash is passed, the hash keys become the names displayed @@ -45,7 +45,8 @@ <select name="[% name FILTER html %]" [% IF onchange %]onchange="[% onchange FILTER html %]"[% END %] - [% IF multiple %] multiple [% IF size %] size="[% size %]" [% END %] [% END %]> + [% IF multiple %] multiple [% END %] + [% IF size %] size="[% size %]" [% END %]> [% IF options_type.search("ARRAY") %] [% FOREACH value = options %] <option value="[% value FILTER html %]" diff --git a/template/en/default/global/setting-descs.none.tmpl b/template/en/default/global/setting-descs.none.tmpl index 3ca7fe3f3..3992e1208 100644 --- a/template/en/default/global/setting-descs.none.tmpl +++ b/template/en/default/global/setting-descs.none.tmpl @@ -23,15 +23,23 @@ "comment_sort_order" => "When viewing $terms.abug, show comments in this order", "csv_colsepchar" => "Field separator character for CSV files", "display_quips" => "Show a quip at the top of each bug list", + "zoom_textareas" => "Zoom textareas large when in use (requires JavaScript)", "newest_to_oldest" => "Newest to Oldest", "newest_to_oldest_desc_first" => "Newest to Oldest, but keep Description at the top", "off" => "Off", "oldest_to_newest" => "Oldest to Newest", "on" => "On", - "per_bug_queries" => "Add individual $terms.bugs to saved searches", + "per_bug_queries" => "Enable tags for $terms.bugs", "post_bug_submit_action" => "After changing $terms.abug", "next_bug" => "Show next $terms.bug in my list", "same_bug" => "Show the updated $terms.bug", + "standard" => "Classic", + "skin" => "$terms.Bugzilla's general appearance (skin)", "nothing" => "Do Nothing", + "state_addselfcc" => "Automatically add me to the CC list of bugs I change", + "always" => "Always", + "never" => "Never", + "cc_unless_role" => "Only if I have no role on them", + "lang" => "Language used in email", } %] diff --git a/template/en/default/global/site-navigation.html.tmpl b/template/en/default/global/site-navigation.html.tmpl index 6056d3037..507b779c8 100644 --- a/template/en/default/global/site-navigation.html.tmpl +++ b/template/en/default/global/site-navigation.html.tmpl @@ -57,11 +57,16 @@ [% END %] [% END %] + [%# *** Attachment *** %] + [% IF attachment && attachment.bug_id %] + <link rel="Up" href="show_bug.cgi?id=[% attachment.bug_id FILTER none %]"> + [% END %] + [%# *** Dependencies, Votes, Activity, Print-version *** %] [% IF bug %] <link rel="Show" title="Dependency Tree" - href="showdependencytree.cgi?id=[% bug.bug_id %]"> + href="showdependencytree.cgi?id=[% bug.bug_id %]&hide_resolved=1"> [% IF Param('webdotbase') %] <link rel="Show" title="Dependency Graph" href="showdependencygraph.cgi?id=[% bug.bug_id %]"> @@ -92,14 +97,22 @@ href="buglist.cgi?cmdtype=runnamed&namedcmd=[% q.name FILTER url_quote %]"> [% END %] + [% FOREACH q = user.queries_subscribed %] + <link rel="Saved Search" + title="[% q.name FILTER html %] ([% q.user.login FILTER html %])" + href="buglist.cgi?cmdtype=dorem&remaction=run&namedcmd= + [% q.name FILTER url_quote %]&sharer_id= + [% q.user.id FILTER url_quote %]"> + [% END %] + [%# *** Bugzilla Administration Tools *** %] [% IF user.login %] [% '<link rel="Administration" title="Parameters" href="editparams.cgi">' IF user.groups.tweakparams %] [% '<link rel="Administration" title="Users" href="editusers.cgi">' IF user.groups.editusers %] - [% '<link rel="Administration" title="Products" - href="editproducts.cgi">' IF user.groups.editcomponents %] + [% '<link rel="Administration" title="Products" href="editproducts.cgi">' + IF user.groups.editcomponents || user.get_products_by_permission("editcomponents").size %] [% '<link rel="Administration" title="Flag Types" href="editflagtypes.cgi">' IF user.groups.editcomponents %] [% '<link rel="Administration" title="Groups" diff --git a/template/en/default/global/tabs.html.tmpl b/template/en/default/global/tabs.html.tmpl index 6f8601b86..25b931de3 100644 --- a/template/en/default/global/tabs.html.tmpl +++ b/template/en/default/global/tabs.html.tmpl @@ -18,6 +18,7 @@ # # Contributor(s): Gervase Markham <gerv@gerv.net> # Myk Melez <myk@mozilla.org> + # Marc Schumann <wurblzap@gmail.com> #%] [%# INTERFACE: @@ -28,20 +29,25 @@ # current_tab_name: string. name of the currently selected tab #%] -<center> - <table cellspacing="0" cellpadding="10" border="0" width="100%"> +<div class="tabbed"> + <table class="tabs" cellspacing="0" cellpadding="10" border="0" width="100%"> <tr> - <td class="tab spacer"> </td> + <td class="spacer"> </td> [% FOREACH tab = tabs %] [% IF tab.name == current_tab_name %] - <td class="tab selected">[% tab.label FILTER html %]</td> + <td class="selected">[% tab.label FILTER html %]</td> [% ELSE %] - <td class="tab"><a href="[% tab.link FILTER html %]">[% tab.label FILTER html %]</a></td> + <td class="clickable_area" onClick="document.location='[% tab.link FILTER html %]'"><a href="[% tab.link FILTER html %]">[% tab.label FILTER html %]</a></td> [% END %] [% END %] - <td class="tab spacer"> </td> - </tr> - </table> -</center> + <td class="spacer"> </td> + </tr> + </table> + + <div class="tabbody"> + [% content %] + </div> + +</div> diff --git a/template/en/default/global/textarea.html.tmpl b/template/en/default/global/textarea.html.tmpl new file mode 100644 index 000000000..8dd0cae47 --- /dev/null +++ b/template/en/default/global/textarea.html.tmpl @@ -0,0 +1,49 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # Contributor(s): Marc Schumann <wurblzap@gmail.com> + #%] + +[%# INTERFACE: + # + # id: (optional) The "id"-attribute of the textarea. + # name: (optional) The "name"-attribute of the textarea. + # accesskey: (optional) The "accesskey"-attribute of the textarea. + # style: (optional) The "style"-attribute of the textarea. + # wrap: (deprecated; optional) The "wrap"-attribute of the textarea. + # minrows: (required) Number of rows the textarea shall have initially + # and when not having focus. + # maxrows: (optional) Number of rows the textarea shall have if + # maximized (which happens on getting focus). If not given, + # the textarea doesn't maximize when getting focus. + # defaultrows: (optional) Number of rows the textarea shall have if + # the zoom_textareas user preference if off. If not given, + # minrows will be used. + # cols: (required) Number of columns the textarea shall have. + # defaultcontent: (optional) Default content for the textarea. + #%] + +<textarea [% IF name %]name="[% name FILTER html %]"[% END %] + [% IF id %] id="[% id FILTER html %]"[% END %] + [% IF accesskey %] accesskey="[% accesskey FILTER html %]"[% END %] + [% IF style %] style="[% style FILTER html %]"[% END %] + [% IF wrap %] wrap="[% wrap FILTER html %]"[% END %] + [% IF defaultrows && user.settings.zoom_textareas.value == 'off' %] + rows="[% defaultrows FILTER html %]" + [% ELSE %] + rows="[% minrows FILTER html %]" + [% END %] + cols="[% cols FILTER html %]" + [% IF maxrows && user.settings.zoom_textareas.value == 'on' %] + onFocus="this.rows=[% maxrows FILTER html %]" + [% END %]>[% defaultcontent FILTER html %]</textarea> diff --git a/template/en/default/global/useful-links.html.tmpl b/template/en/default/global/useful-links.html.tmpl index 71ad9009f..299cc7bbf 100644 --- a/template/en/default/global/useful-links.html.tmpl +++ b/template/en/default/global/useful-links.html.tmpl @@ -18,6 +18,7 @@ # # Contributor(s): Gervase Markham <gerv@gerv.net> # Svetlana Harisova <light@rathedg.com> + # Marc Schumann <wurblzap@gmail.com> #%] [%# Migration note: this whole file corresponds to the old %commandmenu% @@ -25,114 +26,115 @@ [% PROCESS global/variables.none.tmpl %] -<div id="useful-links"> - <div id="links-actions"> - <div class="label">Actions:</div> - <div class="links"> - <a href="./">Home</a> | - <a href="enter_bug.cgi">New</a> | - <a href="query.cgi">Search</a> | - - <form action="buglist.cgi" method="get" - onsubmit="if (this.quicksearch.value == '') - { alert('Please enter one or more search terms first.'); - return false; } return true;"> - <input class="txt" type="text" name="quicksearch"> - <input class="btn" type="submit" value="Find"> - </form> | - - <a href="report.cgi">Reports</a> - - [% IF user.id %] - [% email = user.login FILTER url_quote %] - | <a href="request.cgi?requester=[% email %]&requestee=[% email %]&do_union=1&group=type">My Requests</a> - [% ELSE %] - | <a href="request.cgi">Requests</a> +<ul id="useful-links"> + <li id="links-actions"> + <div class="label">Actions: </div> + [% PROCESS "global/common-links.html.tmpl" btn_id = "find_bottom" %] + </li> + + [%# We have no other choices than enumerating all required privileges to have + # at least one link in this section. %] + [% IF user.login + && (user.groups.tweakparams || user.groups.editusers || user.can_bless + || (Param('useclassification') && user.groups.editclassifications) + || user.groups.editcomponents || user.groups.admin || user.groups.creategroups + || user.get_products_by_permission("editcomponents").size + || user.groups.editkeywords || user.groups.bz_canusewhines) %] + + [% print_pipe = 0 %] + <li id="links-edit"> + <div class="label">Edit: </div> + <ul class="links"> + [% IF user.groups.tweakparams %] + <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="editparams.cgi">Parameters</a></li> + [% print_pipe = 1 %] + <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="editsettings.cgi">User Preferences</a></li> [% END %] - - [% IF user.id && Param('usevotes') %] - | <a href="votes.cgi?action=show_user">My Votes</a> - [% END %] - - [% IF user.login %] - [% ' | <a href="sanitycheck.cgi">Sanity check</a>' - IF user.groups.editcomponents %] - [% IF user.get_flag('can_logout') %] - | <a href="relogin.cgi">Log out</a> - [% ELSE %] - | Logged in as - [% END %] - [% IF sudoer %] - [% sudoer.login FILTER html %] (<b>impersonating - [% user.login FILTER html %]</b> - <a href="relogin.cgi?action=end-sudo">end session</a>) - [% ELSE %] - [% user.login FILTER html %] - [% END %] - [% ELSE %] - [% IF Param('createemailregexp') %] - | <a href="createaccount.cgi">New Account</a> - [% END %] - | <a href="index.cgi?GoAheadAndLogIn=1">Log In</a> + [% IF user.groups.editcomponents %] + <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="sanitycheck.cgi">Sanity Check</a></li> + [% print_pipe = 1 %] + [% END %] + [% IF user.groups.editusers || user.can_bless %] + <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="editusers.cgi">Users</a></li> + [% print_pipe = 1 %] [% END %] - </div> - </div> - - [% IF user.login %] - <div id="links-edit"> - <div class="label">Edit:</div> - <div class="links"> - - <a href="userprefs.cgi">Prefs</a> - [% ' | <a href="editparams.cgi">Parameters</a> ' _ - ' | <a href="editsettings.cgi">User Preferences</a>' - IF user.groups.tweakparams %] - [% ' | <a href="editusers.cgi">Users</a>' IF user.groups.editusers - || user.can_bless %] [% IF Param('useclassification') && user.groups.editclassifications %] - [% ' | <a href="editclassifications.cgi">Classifications</a>' %] - [% END %] - [% ' | <a href="editproducts.cgi">Products</a>' - IF user.groups.editcomponents %] - [% ' | <a href="editflagtypes.cgi">Flags</a>' - IF user.groups.editcomponents %] - [% ' | <a href="editvalues.cgi">Field Values</a>' - IF user.groups.editcomponents %] - [% ' | <a href="editgroups.cgi">Groups</a>' - IF user.groups.creategroups %] - [% ' | <a href="editkeywords.cgi">Keywords</a>' - IF user.groups.editkeywords %] - [% ' | <a href="editwhines.cgi">Whining</a>' - IF user.groups.bz_canusewhines %] - </div> - </div> - [% END %] + <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="editclassifications.cgi">Classifications</a></li> + [% print_pipe = 1 %] + [% END %] + [% IF user.groups.editcomponents || user.get_products_by_permission("editcomponents").size %] + <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="editproducts.cgi">Products</a></li> + [% print_pipe = 1 %] + [% END %] + [% IF user.groups.editcomponents %] + <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="editflagtypes.cgi">Flags</a></li> + [% print_pipe = 1 %] + [% END %] + [% IF user.groups.admin %] + <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="editfields.cgi">Custom Fields</a></li> + [% print_pipe = 1 %] + <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="editvalues.cgi">Field Values</a></li> + [% END %] + [% IF user.groups.creategroups %] + <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="editgroups.cgi">Groups</a></li> + [% print_pipe = 1 %] + [% END %] + [% IF user.groups.editkeywords %] + <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="editkeywords.cgi">Keywords</a></li> + [% print_pipe = 1 %] + [% END %] + [% IF user.groups.bz_canusewhines %] + <li>[% '<span class="separator">| </span>' IF print_pipe %]<a href="editwhines.cgi">Whining</a></li> + [% print_pipe = 1 %] + [% END %] + </ul> + </li> + [% END %] - [%# Saved searches %] - <div id="links-saved"> - <div class="label"> - [% IF user.showmybugslink OR user.queries.size %] - Saved Searches: - [% END %] - </div> - <div class="links"> + [% IF user.showmybugslink OR user.queries.size + OR user.queries_subscribed.size + %] + [% print_pipe = 0 %] + <li id="links-saved"> + <div class="label"> + Saved Searches: + </div> + <ul class="links"> [% IF user.showmybugslink %] [% filtered_username = user.login FILTER url_quote %] - <a href="[% Param('mybugstemplate').replace('%userid%', filtered_username) %]">My [% terms.Bugs %]</a> + <li><a href="[% Param('mybugstemplate').replace('%userid%', filtered_username) %]">My [% terms.Bugs %]</a></li> [% print_pipe = 1 %] [% END %] [% FOREACH q = user.queries %] - [% IF q.linkinfooter %] - [% " | " IF print_pipe %] - <a href="buglist.cgi?cmdtype=runnamed&namedcmd=[% q.name FILTER url_quote %]">[% q.name FILTER html FILTER no_break %]</a> + [% IF q.link_in_footer %] + <li>[% '<span class="separator">| </span>' IF print_pipe %] + <a href="buglist.cgi?cmdtype=runnamed&namedcmd=[% q.name FILTER url_quote %]">[% q.name FILTER html %]</a></li> [% print_pipe = 1 %] [% END %] [% END %] - </div> - </div> + [% new_line = print_pipe %] + [% print_pipe = 0 %] + [% FOREACH q = user.queries_subscribed %] + [% IF new_line %] + <br> + [% new_line = 0 %] + [% END %] + <li> + [% '<span class="separator">| </span>' IF print_pipe %] + <a href="buglist.cgi?cmdtype=dorem&remaction=run&namedcmd= + [% q.name FILTER url_quote %]&sharer_id= + [% q.user.id FILTER url_quote %]" + class="shared" + title="Shared by [% q.user.identity FILTER html %]" + >[% q.name FILTER html FILTER no_break %]</a></li> + [% print_pipe = 1 %] + [% END %] + </ul> + </li> + [% END %] [%# Individual bugs addition %] @@ -140,4 +142,4 @@ [%# Sections of links to more things users can do on this installation. %] [% Hook.process("end") %] -</div> +</ul> diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl index 7323c6a4b..7452ab8d1 100644 --- a/template/en/default/global/user-error.html.tmpl +++ b/template/en/default/global/user-error.html.tmpl @@ -31,7 +31,7 @@ # # Note that you must explicitly filter every single template variable # in this file; if you do not wish to change it, use the "none" filter. - # + # # Extension- or custom-specific error handling can be easily added # via hooks: just place your <extension>-errors.html.tmpl into # template/en/extension/hook/global/user-error.html.tmpl/errors/ @@ -82,8 +82,9 @@ [% ELSIF error == "alias_in_use" %] [% title = "Alias In Use" %] - [% terms.Bug %] [%+ bug_link FILTER none %] has already taken the alias - <em>[% alias FILTER html %]</em>. Please choose another one. + [% terms.Bug %] [%+ bug_id FILTER bug_link(bug_id) FILTER none %] + has already taken the alias <em>[% alias FILTER html %]</em>. + Please choose another one. [% ELSIF error == "alias_not_defined" %] [% title = "Alias Is Not Defined" %] @@ -109,6 +110,7 @@ [% ELSIF error == "auth_failure" %] [% title = "Authorization Required" %] + [% admindocslinks = {'groups.html' => 'Group Security'} %] Sorry, [% IF group %] you aren't a member of the '[% group FILTER html %]' group, @@ -156,6 +158,8 @@ classifications [% ELSIF object == "components" %] components + [% ELSIF object == "custom_fields" %] + custom fields [% ELSIF object == "field_values" %] field values [% ELSIF object == "flagtypes" %] @@ -194,16 +198,24 @@ versions [% END %]. + [% Hook.process("auth_failure") %] + + [% ELSIF error == "attachment_deletion_disabled" %] + [% title = "Attachment Deletion Disabled" %] + Attachment deletion is disabled on this installation. + [% ELSIF error == "attachment_removed" %] [% title = "Attachment Removed" %] The attachment you are attempting to access has been removed. [% ELSIF error == "bug_access_denied" %] [% title = "Access Denied" %] + [% admindocslinks = {'groups.html' => 'Group Security'} %] You are not authorized to access [% terms.bug %] #[% bug_id FILTER html %]. [% ELSIF error == "bug_access_query" %] [% title = "Access Denied" %] + [% docslinks = {'myaccount.html' => 'Creating an account'} %] You are not authorized to access [% terms.bug %] #[% bug_id FILTER html %]. To see this [% terms.bug %], you must first <a href="show_bug.cgi?id= @@ -212,6 +224,8 @@ [% ELSIF error == "buglist_parameters_required" %] [% title = "Parameters Required" %] + [% docslinks = {'query.html' => "Searching for $terms.bugs", + 'list.html' => "$terms.Bug lists"} %] You may not search, or create saved searches, without any search terms. [% ELSIF error == "bugs_not_changed" %] @@ -253,6 +267,11 @@ The classification '[% classification FILTER html %]' does not exist for product '[% product FILTER html %]'. + [% ELSIF error == "classification_invalid_sortkey" %] + [% title = "Invalid Sortkey for Classification" %] + The sortkey <em>[% sortkey FILTER html %]</em> for the '[% name FILTER html %]' + classification is invalid. It must be a positive integer. + [% ELSIF error == "classification_not_deletable" %] [% title = "Default Classification Can Not Be Deleted" %] You can not delete the default classification @@ -294,16 +313,19 @@ Product [% product FILTER html %] does not have a component named [% name FILTER html %]. - [% ELSIF error == "product_doesnt_exist" %] - [% title = "Specified Product Does Not Exist" %] - The product '[% product FILTER html %]' does not exist. + [% ELSIF error == "customfield_nonexistent" %] + [% title = "Unknown Custom Field" %] + There is no custom field with the name '[% name FILTER html %]'. [% ELSIF error == "dependency_loop_multi" %] [% title = "Dependency Loop Detected" %] The following [% terms.bug %](s) would appear on both the "depends on" and "blocks" parts of the dependency tree if these changes - are committed: [% both FILTER none %]. This would create a circular - dependency, which is not allowed. + are committed: + [% FOREACH dep = deps %] + [%+ dep FILTER bug_link(dep) FILTER none %] + [% END %]. + This would create a circular dependency, which is not allowed. [% ELSIF error == "dependency_loop_single" %] [% title = "Dependency Loop Detected" %] @@ -313,11 +335,6 @@ [% title = "Description Required" %] You must provide a description of the [% terms.bug %]. - [% ELSIF error == "dupe_entry_found" %] - [% title = "Already marked as duplicate" %] - This [% terms.bug %] has already been marked as a duplicate - of [% terms.bug %] [%+ dupe_of FILTER html %]. - [% ELSIF error == "dupe_not_allowed" %] [% title = "Cannot mark $terms.bugs as duplicates" %] You cannot mark [% terms.bugs %] as duplicates when @@ -342,6 +359,10 @@ [% title = "Email Address Confirmation Failed" %] Email address confirmation failed. + [% ELSIF error == "email_no_text_plain" %] + Your message did not contain any text.[% terms.Bugzilla %] does not + accept HTML-only email, or HTML email with attachments. + [% ELSIF error == "empty_group_description" %] [% title = "The group description can not be empty" %] You must enter a description for the group. @@ -352,10 +373,35 @@ [% ELSIF error == "entry_access_denied" %] [% title = "Permission Denied" %] + [% admindocslinks = {'groups.html' => 'Group Security'} %] Sorry, either the product <em>[% product FILTER html %]</em> does not exist or you aren't authorized to enter [% terms.abug %] into it. + [% ELSIF error == "field_already_exists" %] + [% title = "Field Already Exists" %] + The field '[% field.name FILTER html %]' + ([% field.description FILTER html %]) already exists. Please + choose another name. + + [% ELSIF error == "field_invalid_name" %] + [% title = "Invalid Field Name" %] + '[% name FILTER html %]' is not a valid name for a field. + A name may contain only letters, numbers, and the underscore character. + + [% ELSIF error == "field_invalid_sortkey" %] + [% title = "Invalid Sortkey for Field" %] + The sortkey [% sortkey FILTER html %] that you have provided for + this field is not a valid positive integer. + + [% ELSIF error == "field_missing_description" %] + [% title = "Missing Description for Field" %] + You must enter a description for this field. + + [% ELSIF error == "field_missing_name" %] + [% title = "Missing Name for Field" %] + You must enter a name for this field. + [% ELSIF error == "fieldname_invalid" %] [% title = "Specified Field Does Not Exist" %] The field '[% field FILTER html %]' does not exist or @@ -389,6 +435,16 @@ The value of a field is limited to 60 characters. '[% value FILTER html %]' is too long ([% value.length %] characters). + [% ELSIF error == "fieldvalue_not_editable" %] + [% title = "Field Value Not Editable" %] + The value '[% old_value FILTER html %]' cannot be renamed because + it plays some special role for the '[% field FILTER html %]' field. + + [% ELSIF error == "fieldvalue_not_deletable" %] + [% title = "Field Value Not Deletable" %] + The value '[% value FILTER html %]' cannot be removed because + it plays some special role for the '[% field FILTER html %]' field. + [% ELSIF error == "fieldvalue_not_specified" %] [% title = "Field Value Not Specified" %] No field value specified when trying to edit a field value. @@ -418,22 +474,39 @@ kilobytes (KB) in size. Non-patch attachments cannot be more than [%+ Param('maxattachmentsize') %] KB. <br> We recommend that you store your attachment elsewhere on the web, - and then insert a link to it in a comment, or in the URL field - for this [% terms.bug %]. Alternately, if your attachment is an image, - you could convert it to a compressible format like JPG or PNG and try - again. + [% IF Param("allow_attach_url") %] + and then specify the URL to this file on the attachment + creation page in the <b>AttachURL</b> field. + [% ELSE %] + and then insert the URL to it in a comment, or in the URL field + for this [% terms.bug %]. + [% END %] + <br>Alternately, if your attachment is an image, you could convert + it to a compressible format like JPG or PNG and try again. [% ELSIF error == "flag_not_multiplicable" %] + [% docslinks = {'flags-overview.html' => 'An overview on Flags', + 'flags.html' => 'Using Flags'} %] You can't ask more than one person at a time for <em>[% type.name FILTER html %]</em>. - + + [% ELSIF error == "flag_requestee_needs_privs" %] + [% title = "Flag Requestee Needs Privileges" %] + [% requestee.identity FILTER html %] does not have permission to set the + <em>[% flagtype.name FILTER html %]</em> flag. Please select a user who is + a member of the <em>[% flagtype.grant_group.name FILTER html %]</em> group. + [% ELSIF error == "flag_requestee_unauthorized" %] [% title = "Flag Requestee Not Authorized" %] + [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags', + 'groups.html' => 'Group Security'} %] + [% docslinks = {'flags-overview.html' => 'An overview on Flags', + 'flags.html' => 'Using Flags'} %] You asked [% requestee.identity FILTER html %] for <code>[% flag_type.name FILTER html %]</code> on [% terms.bug %] [%+ bug_id FILTER html -%] - [% IF attachment %], attachment [% attachment.id FILTER html %][% END %], + [% IF attach_id && attach_id > 0 %], attachment [% attach_id FILTER html %][% END %], but that [% terms.bug %] has been restricted to users in certain groups, and the user you asked isn't in all the groups to which the [% terms.bug %] has been restricted. @@ -442,30 +515,45 @@ [% ELSIF error == "flag_requestee_unauthorized_attachment" %] [% title = "Flag Requestee Not Authorized" %] + [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags', + 'groups.html' => 'Group Security'} %] + [% docslinks = {'flags-overview.html' => 'An overview on Flags', + 'flags.html' => 'Using Flags'} %] You asked [% requestee.identity FILTER html %] for <code>[% flag_type.name FILTER html %]</code> on [%+ terms.bug %] [%+ bug_id FILTER html %], - attachment [% attachment.id FILTER html %], but that attachment + attachment [% attach_id FILTER html %], but that attachment is restricted to users in the [% Param("insidergroup") FILTER html %] group, and the user you asked isn't in that group. Please choose someone else to ask, or ask an administrator to add the user to the group. [% ELSIF error == "flag_type_cc_list_invalid" %] [% title = "Flag Type CC List Invalid" %] + [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags'} %] The CC list [% cc_list FILTER html %] must be less than 200 characters long. + [% ELSIF error == "flag_type_component_without_product" %] + [% title = "Product Missing" %] + A component was selected without a product being selected. + [% ELSIF error == "flag_type_description_invalid" %] [% title = "Flag Type Description Invalid" %] + [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags'} %] The description must be less than 32K. [% ELSIF error == "flag_type_name_invalid" %] [% title = "Flag Type Name Invalid" %] + [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags'} %] The name <em>[% name FILTER html %]</em> must be 1-50 characters long and must not contain any spaces or commas. [% ELSIF error == "flag_update_denied" %] [% title = "Flag Modification Denied" %] + [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags', + 'groups.html' => 'Group Security'} %] + [% docslinks = {'flags-overview.html' => 'An overview on Flags', + 'flags.html' => 'Using Flags'} %] You tried to [% IF status == "+" %] grant [% ELSIF status == "-" %] deny [% ELSIF status == "X" %] clear [% ELSE %] request [% END %] <code>[% name FILTER html %] @@ -529,12 +617,12 @@ You entered <tt>[% value FILTER html %]</tt>, which isn't. [% ELSIF error == "illegal_attachment_edit" %] - [% title = "Unauthorized Action" %] - You are not authorized to edit attachment [% attach_id FILTER html %]. + [% title = "Unauthorised Action" %] + You are not authorised to edit attachment [% attach_id FILTER html %]. [% ELSIF error == "illegal_attachment_edit_bug" %] - [% title = "Unauthorized Action" %] - You are not authorized to edit attachments on [% terms.bug %] + [% title = "Unauthorised Action" %] + You are not authorised to edit attachments on [% terms.bug %] [%+ bug_id FILTER html %]. [% ELSIF error == "illegal_attachment_is_patch" %] @@ -599,6 +687,7 @@ [% ELSIF error == "illegal_group_control_combination" %] [% title = "Your Group Control Combination Is Illegal" %] + [% admindocslinks = {'groups.html' => 'Assigning Group Controls to Products'} %] Your group control combination for group " [% groupname FILTER html %]" is illegal. @@ -613,13 +702,18 @@ <, >, &. [% ELSIF error == "illegal_series_creation" %] - You are not authorized to create series. + [% admindocslinks = {'groups.html' => 'Group security'} %] + [% docslinks = {'reporting.html' => 'Reporting'} %] + You are not authorised to create series. [% ELSIF error == "illegal_series_edit" %] - You are not authorized to edit this series. To do this, you must either + [% admindocslinks = {'groups.html' => 'Group security'} %] + [% docslinks = {'reporting.html' => 'Reporting'} %] + You are not authorised to edit this series. To do this, you must either be its creator, or an administrator. [% ELSIF error == "insufficient_data_points" %] + [% docslinks = {'reporting.html' => 'Reporting'} %] We don't have enough data points to make a graph (yet). [% ELSIF error == "invalid_attach_id" %] @@ -760,6 +854,8 @@ [% ELSIF error == "milestone_already_exists" %] [% title = "Milestone Already Exists" %] + [% admindocslinks = {'products.html' => 'Administering products', + 'milestones.html' => 'About Milestones'} %] The milestone '[% name FILTER html %]' already exists for product ' [%- product FILTER html %]'. @@ -769,8 +865,11 @@ [% ELSIF error == "milestone_is_default" %] [% title = "Default milestone not deletable" %] - Sorry, but [% name FILTER html %] is the default milestone for - product '[% product FILTER html %]', and so it can not be deleted. + [% admindocslinks = {'products.html' => 'Administering products', + 'milestones.html' => 'About Milestones'} %] + Sorry, but [% milestone.name FILTER html %] is the default milestone + for product '[% product.name FILTER html %]', and so it can not be + deleted. [% ELSIF error == "milestone_name_too_long" %] [% title = "Milestone Name Is Too Long" %] @@ -814,11 +913,13 @@ [% ELSIF error == "missing_component" %] [% title = "Missing Component" %] - Sorry, the product <em>[% product FILTER html %]</em> + [% admindocslinks = {'products.html' => 'Administering products', + 'components.html' => 'Creating a component'} %] + Sorry, the product <em>[% product.name FILTER html %]</em> has to have at least one component in order for you to - enter [% terms.abug %] into it.<p> - [% IF UserInGroup("editcomponents") %] - <a href="editcomponents.cgi?action=add&product=[% product FILTER url_quote %]">Create + enter [% terms.abug %] into it.<br> + [% IF user.in_group("editcomponents", product.id) %] + <a href="editcomponents.cgi?action=add&product=[% product.name FILTER url_quote %]">Create a new component</a>. [% ELSE %] Please contact [% Param("maintainer") %] and ask them @@ -845,6 +946,7 @@ [% ELSIF error == "missing_datasets" %] [% title = "No Datasets Selected" %] + [% docslinks = {'reporting.html' => 'Reporting'} %] You must specify one or more datasets to plot. [% ELSIF error == "missing_email_type" %] @@ -854,16 +956,24 @@ [% ELSIF error == "missing_frequency" %] [% title = "Missing Frequency" %] + [% docslinks = {'reporting.html' => 'Reporting'} %] You did not specify a valid frequency for this series. [% ELSIF error == "missing_name" %] [% title = "Missing Name" %] + [% docslinks = {'reporting.html' => 'Reporting'} %] You did not specify a name for this series. [% ELSIF error == "missing_query" %] [% title = "Missing Search" %] - The search named <em>[% queryname FILTER html %]</em> does not - exist. + [% docslinks = {'query.html' => "Searching for $terms.bugs", + 'list.html' => "$terms.Bug lists"} %] + The search named <em>[% queryname FILTER html %]</em> + [% IF sharer_id && sharer_id != user.id %] + has not been made visible to you. + [% ELSE %] + does not exist. + [% END %] [% ELSIF error == "move_bugs_disabled" %] [% title = BLOCK %][% terms.Bug %] Moving Disabled[% END %] @@ -876,11 +986,12 @@ [% ELSIF error == "missing_version" %] [% title = "Missing Version" %] - Sorry, the product <em>[% product FILTER html %]</em> + [% admindocslinks = {'versions.html' => 'Defining versions'} %] + Sorry, the product <em>[% product.name FILTER html %]</em> has to have at least one version in order for you to - enter [% terms.abug %] into it.<p> - [% IF UserInGroup("editcomponents") %] - <a href="editversions.cgi?action=add&product=[% product FILTER url_quote %]">Create + enter [% terms.abug %] into it.<br> + [% IF user.in_group("editcomponents", product.id) %] + <a href="editversions.cgi?action=add&product=[% product.name FILTER url_quote %]">Create a new version</a>. [% ELSE %] Please contact [% Param("maintainer") %] and ask them @@ -889,6 +1000,7 @@ [% ELSIF error == "need_quip" %] [% title = "Quip Required" %] + [% docslinks = {'quips.html' => 'About quips'} %] Please enter a quip in the text field. [% ELSIF error == "new_password_missing" %] @@ -897,6 +1009,7 @@ [% ELSIF error == "no_axes_defined" %] [% title = "No Axes Defined" %] + [% docslinks = {'reporting.html' => 'Reporting'} %] You didn't define any axes to plot. [% ELSIF error == "no_bugs_chosen" %] @@ -905,7 +1018,21 @@ [% ELSIF error == "no_bug_ids" %] [% title = BLOCK %]No [% terms.Bugs %] Chosen[% END %] - You didn't choose any [% terms.bugs %] to add to the saved search. + You didn't choose any [% terms.bugs %] to + [% IF action == "add" %] add to [% ELSE %] remove from [% END %] + the saved search. + + [% ELSIF error == "no_bugs_in_list" %] + [% title = "Delete Saved Search?" %] + You are going to remove all [% terms.bugs %] from the '[% saved_search FILTER html %]' + saved search. This will delete this saved search completely. Click + <a href="buglist.cgi?cmdtype=dorem&remaction=forget&namedcmd= + [%- saved_search FILTER url_quote %]">here</a> if you really want to + remove it. + + [% ELSIF error == "no_bugs_to_remove" %] + [% title = "No Saved Search Selected" %] + You didn't select any saved search to remove [% terms.bugs %] from. [% ELSIF error == "no_component_change_for_multiple_products" %] [% title = "Action Not Permitted" %] @@ -914,27 +1041,32 @@ [% ELSIF error == "no_dupe_stats" %] [% title = "Cannot Find Duplicate Statistics" %] + [% admindocslinks = {'extraconfig.html' => 'Setting up the collecstats.pl job'} %] There are no duplicate statistics for today ([% today FILTER html %]) or yesterday. [% ELSIF error == "no_dupe_stats_error_today" %] [% title = "Error Reading Today's Dupes File" %] + [% admindocslinks = {'extraconfig.html' => 'Setting up the collecstats.pl job'} %] An error occurred opening today's dupes file: [% error_msg FILTER html %]. [% ELSIF error == "no_dupe_stats_error_whenever" %] [% title = "Error Reading Previous Dupes File" %] + [% admindocslinks = {'extraconfig.html' => 'Setting up the collecstats.pl job'} %] An error occurred opening [% changedsince FILTER html %] days ago ([% whenever FILTER html %])'s dupes file: [% error_msg FILTER html %]. [% ELSIF error == "no_dupe_stats_error_yesterday" %] [% title = "Error Reading Yesterday's Dupes File" %] + [% admindocslinks = {'extraconfig.html' => 'Setting up the collecstats.pl job'} %] There are no duplicate statistics for today ([% today FILTER html %]), and an error occurred opening yesterday's dupes file: [% error_msg FILTER html %]. [% ELSIF error == "no_new_quips" %] [% title = "No New Quips" %] + [% admindocslinks = {'quips.html' => 'Controlling quip usage'} %] This site does not permit the addition of new quips. [% ELSIF error == "no_page_specified" %] @@ -943,6 +1075,9 @@ [% ELSIF error == "no_products" %] [% title = "No Products" %] + [% admindocslinks = {'products.html' => 'Setting up a product', + 'components.html' => 'Adding components to products', + 'groups.html' => 'Groups security'} %] Either no products have been defined to enter [% terms.bugs %] against or you have not been given access to any. @@ -986,13 +1121,13 @@ [% ELSIF error == "password_too_long" %] [% title = "Password Too Long" %] - The password is more than 16 characters long. It must be no more than - 16 characters. + The password must be no more than + [%+ constants.USER_PASSWORD_MAX_LENGTH FILTER html %] characters long. [% ELSIF error == "password_too_short" %] [% title = "Password Too Short" %] - The password is less than three characters long. It must be at least - three characters. + The password must be at least + [%+ constants.USER_PASSWORD_MIN_LENGTH FILTER html %] characters long. [% ELSIF error == "patch_too_large" %] [% title = "File Too Large" %] @@ -1001,44 +1136,61 @@ Patches cannot be more than [% Param('maxpatchsize') %] KB in size. Try breaking your patch into several pieces. - [% ELSIF error == "prod_votes_per_bug_must_be_nonnegative" %] + [% ELSIF error == "product_access_denied" %] + Either the product '[% product FILTER html %]' does not exist or + you don't have access to it. + + [% ELSIF error == "product_doesnt_exist" %] + [% title = "Specified Product Does Not Exist" %] + The product '[% product FILTER html %]' does not exist. + + [% ELSIF error == "product_votes_per_bug_must_be_nonnegative" %] [% title = "Maximum Votes Must Be Non-negative" %] + [% admindocslinks = {'voting.html' => 'Setting up the voting feature'} %] '[% maxvotesperbug FILTER html %]' is an invalid value for the <em>'Maximum Votes Per [% terms.Bug %]'</em> field, which should contain a non-negative number. - [% ELSIF error == "prod_votes_per_user_must_be_nonnegative" %] + [% ELSIF error == "product_votes_per_user_must_be_nonnegative" %] [% title = "Votes Per User Must Be Non-negative" %] + [% admindocslinks = {'voting.html' => 'Setting up the voting feature'} %] '[% votesperuser FILTER html %]' is an invalid value for the <em>'Votes Per User'</em> field, which should contain a non-negative number. - [% ELSIF error == "prod_votes_to_confirm_must_be_nonnegative" %] + [% ELSIF error == "product_votes_to_confirm_must_be_nonnegative" %] [% title = "Votes To Confirm Must Be Non-negative" %] + [% admindocslinks = {'voting.html' => 'Setting up the voting feature'} %] '[% votestoconfirm FILTER html %]' is an invalid value for the <em>'Votes To Confirm'</em> field, which should contain a non-negative number. - [% ELSIF error == "prod_cant_delete_description" %] + [% ELSIF error == "product_cant_delete_description" %] [% title = "Cannot delete product description" %] + [% admindocslinks = {'products.html' => 'Administering products'} %] Cannot delete the description for product '[% product FILTER html %]'. - [% ELSIF error == "prod_cant_delete_name" %] + [% ELSIF error == "product_cant_delete_name" %] [% title = "Cannot delete product name" %] + [% admindocslinks = {'products.html' => 'Administering products'} %] Cannot delete the product name for product '[% product FILTER html %]'. - [% ELSIF error == "prod_name_already_in_use" %] + [% ELSIF error == "product_name_already_in_use" %] [% title = "Product name already in use" %] + [% admindocslinks = {'products.html' => 'Administering products'} %] The product name '[% product FILTER html %]' is already in use. - [% ELSIF error == "prod_name_diff_in_case" %] + [% ELSIF error == "product_name_diff_in_case" %] [% title = "Product name differs only in case" %] + [% admindocslinks = {'products.html' => 'Administering products'} %] The product name '[% product FILTER html %]' differs from existing product '[% existing_product FILTER html %]' only in case. - [% ELSIF error == "prod_must_define_defaultmilestone" %] + [% ELSIF error == "product_must_define_defaultmilestone" %] [% title = "Must define new default milestone" %] + [% admindocslinks = {'products.html' => 'Administering products', + 'milestones.html' => 'About Milestones'} %] [% IF classification %] [% classification_url_part = BLOCK %]&classification= [%- classification FILTER url_quote %] @@ -1056,39 +1208,60 @@ [% ELSIF error == "product_blank_name" %] [% title = "Blank Product Name Not Allowed" %] + [% admindocslinks = {'products.html' => 'Administering products'} %] You must enter a name for the new product. [% ELSIF error == "product_disabled" %] [% title = BLOCK %]Product closed for [% terms.Bugs %] Entry[% END %] + [% admindocslinks = {'products.html' => 'Administering products'} %] Sorry, entering [% terms.bugs %] into the - product <em>[% product FILTER html %]</em> has been disabled. + product <em>[% product.name FILTER html %]</em> has been disabled. [% ELSIF error == "product_edit_denied" %] [% title = "Product Edit Access Denied" %] + [% admindocslinks = {'products.html' => 'Administering products', + 'groups.html' => 'Group security'} %] You are not permitted to edit [% terms.bugs %] in product [%+ product FILTER html %]. [% ELSIF error == "product_has_bugs" %] [% title = BLOCK %]Product has [% terms.Bugs %][% END %] + [% admindocslinks = {'products.html' => 'Administering products'} %] There are [% nb FILTER html %] [%+ terms.bugs %] entered for this product! You must reassign those [% terms.bugs %] to another product before you can delete this one. [% ELSIF error == "product_must_have_description" %] [% title = "Product needs Description" %] + [% admindocslinks = {'products.html' => 'Administering products'} %] You must enter a description for product '[% product FILTER html %]'. [% ELSIF error == "product_must_have_version" %] [% title = "Product needs Version" %] + [% admindocslinks = {'products.html' => 'Administering products', + 'versions.html' => 'Administering versions'} %] You must enter a version for product '[% product FILTER html %]'. [% ELSIF error == "product_not_specified" %] [% title = "No Product Specified" %] + [% admindocslinks = {'products.html' => 'Administering products', + 'components.html' => 'Administering components', + 'milestones.html' => 'Administering milestones', + 'versions.html' => 'Administering versions'} %] No product specified when trying to edit components, milestones, versions or product. + [% ELSIF error == "query_name_exists" %] + [% title = "Search Name Already In Use" %] + The name <em>[% name FILTER html %]</em> is already used by another + saved search. You first have to + <a href="buglist.cgi?cmdtype=dorem&remaction=forget&namedcmd= + [%- name FILTER url_quote %]">delete</a> it if you really want to use + this name. + [% ELSIF error == "query_name_missing" %] [% title = "No Search Name Specified" %] + [% docslinks = {'list.html' => "About $terms.bug lists"} %] You must enter a name for your search. [% ELSIF error == "query_name_too_long" %] @@ -1113,8 +1286,13 @@ [% title = "Summary Needed" %] You must enter a summary for this [% terms.bug %]. + [% ELSIF error == "resolution_not_allowed" %] + [% title = "Resolution Not Allowed" %] + You cannot set a resolution for open [% terms.bugs %]. + [% ELSIF error == "saved_search_used_by_whines" %] [% title = "Saved Search In Use" %] + [% docslinks = {'whining.html' => 'About Whining'} %] The saved search <em>[% search_name FILTER html %]</em> is being used by <a href="editwhines.cgi">Whining events</a> with the following subjects: [%+ subjects FILTER html %] @@ -1127,6 +1305,7 @@ [% ELSIF error == "series_already_exists" %] [% title = "Series Already Exists" %] + [% docslinks = {'reporting.html' => 'Reporting'} %] A series named <em>[% series.category FILTER html %] / [%+ series.subcategory FILTER html %] / [%+ series.name FILTER html %]</em> @@ -1145,7 +1324,8 @@ [% ELSE %] dependencies [% END %]. Show - <a href="showdependencytree.cgi?id=[% dependencies.0.bug_id FILTER none %]">Dependency Tree</a>. + <a href="showdependencytree.cgi?id=[% dependencies.0.bug_id FILTER none %]&hide_resolved=1">Dependency + Tree</a>. [% ELSE %] There are [% dependency_count FILTER none %] open [% terms.bugs %] which have unresolved dependencies. @@ -1158,7 +1338,8 @@ [% ELSE %] dependencies. [% END %] - (<a href="showdependencytree.cgi?id=[% bug.bug_id FILTER none %]">Dependency Tree</a>)<br> + (<a href="showdependencytree.cgi?id=[% bug.bug_id FILTER none %]&hide_resolved=1">Dependency + Tree</a>)<br> [% END %] [% END %] @@ -1187,6 +1368,7 @@ [% ELSIF error == "too_many_votes_for_bug" %] [% title = "Illegal Vote" %] + [% admindocslinks = {'voting.html' => 'Setting up the voting feature'} %] You may only use at most [% max FILTER html %] votes for a single [%+ terms.bug %] in the <tt>[% product FILTER html %]</tt> product, but you are trying to @@ -1194,19 +1376,25 @@ [% ELSIF error == "too_many_votes_for_product" %] [% title = "Illegal Vote" %] + [% admindocslinks = {'voting.html' => 'Setting up the voting feature'} %] You tried to use [% votes FILTER html %] votes in the - <tt>[% product FILTER html %]</tt> product, which exceeds the maximum - of [% max FILTER html %] votes for this product. + <tt>[% product FILTER html %]</tt> product, which exceeds the maximum of + [%+ max FILTER html %] votes for this product. [% ELSIF error == "token_inexistent" %] [% title = "Token Does Not Exist" %] The token you submitted does not exist, has expired, or has - been cancelled. + been canceled. [% ELSIF error == "too_soon_for_new_token" %] [% title = "Too Soon For New Token" %] - You have requested a password token too recently to request - another. Please wait a while and try again. + You have requested + [% IF type == "password" %] + a password + [% ELSIF type == "account" %] + an account + [% END %] + token too recently to request another. Please wait a while and try again. [% ELSIF error == "unknown_keyword" %] [% title = "Unknown Keyword" %] @@ -1219,6 +1407,7 @@ [% ELSIF error == "version_already_exists" %] [% title = "Version Already Exists" %] + [% admindocslinks = {'versions.html' => 'Administering versions'} %] The version '[% name FILTER html %]' already exists for product ' [%- product FILTER html %]'. @@ -1243,10 +1432,12 @@ [% ELSIF error == "users_deletion_disabled" %] [% title = "Deletion not activated" %] + [% admindocslinks = {'useradmin.html' => 'User administration'} %] Sorry, the deletion of user accounts is not allowed. [% ELSIF error == "user_has_responsibility" %] [% title = "Can't Delete User Account" %] + [% admindocslinks = {'useradmin.html' => 'User administration'} %] The user you want to delete is set up as the default [% terms.bug %] assignee [% IF Param('useqacontact') %] @@ -1257,6 +1448,7 @@ [% ELSIF error == "user_login_required" %] [% title = "Login Name Required" %] + [% admindocslinks = {'useradmin.html' => 'User administration'} %] You must enter a login name for the new user. [% ELSIF error == "user_match_failed" %] @@ -1266,6 +1458,7 @@ [% ELSIF error == "votes_must_be_nonnegative" %] [% title = "Votes Must Be Non-negative" %] + [% admindocslinks = {'voting.html' => 'Setting up the voting feature'} %] Only use non-negative numbers for your [% terms.bug %] votes. [% ELSIF error == "wrong_token_for_cancelling_email_change" %] @@ -1276,18 +1469,22 @@ [% title = "Wrong Token" %] That token cannot be used to change your password. - [% ELSIF error == "extern_id_conflict" %] - [% title = "Extern ID Conflict" %] - Someone with a different external ID has that address. - [% ELSIF error == "wrong_token_for_confirming_email_change" %] [% title = "Wrong Token" %] That token cannot be used to change your email address. + [% ELSIF error == "wrong_token_for_creating_account" %] + [% title = "Wrong Token" %] + That token cannot be used to create a user account. + [% ELSIF error == "zero_length_file" %] [% title = "File Is Empty" %] The file you are trying to attach is empty! + [% ELSIF error == "illegal_user_id" %] + [% title = "Illegal User ID" %] + User ID '[% userid FILTER html %]' is not valid integer. + [% ELSE %] [%# Try to find hooked error messages %] @@ -1304,10 +1501,26 @@ [% END %] [% END %] +[%# We only want HTML error messages for ERROR_MODE_WEBPAGE %] +[% USE Bugzilla %] +[% IF Bugzilla.error_mode != constants.ERROR_MODE_WEBPAGE %] + [% IF Bugzilla.usage_mode == constants.USAGE_MODE_BROWSER %] + [% error_message FILTER none %] + [% ELSE %] + [% error_message FILTER txt %] + [% END %] + [% RETURN %] +[% END %] + [% UNLESS header_done %] [% PROCESS global/header.html.tmpl %] [% END %] +[% PROCESS global/docslinks.html.tmpl + docslinks = docslinks + admindocslinks = admindocslinks +%] + <table cellpadding="20"> <tr> <td bgcolor="#ff0000"> @@ -1325,11 +1538,12 @@ [%# If a saved search fails, people want the ability to edit or delete it. # This is the best way of getting information about that possible saved # search from any error call location. %] - -[% USE Bugzilla %] + [% namedcmd = Bugzilla.cgi.param("namedcmd") %] +[% sharer_id = Bugzilla.cgi.param("sharer_id") %] [% IF namedcmd AND error != "missing_query" - AND error != "saved_search_used_by_whines" %] + AND error != "saved_search_used_by_whines" + AND !sharer_id %] <p> Alternatively, you can <a href="buglist.cgi?cmdtype=dorem&remaction=forget&namedcmd= @@ -1337,7 +1551,7 @@ [% FOREACH q = Bugzilla.user.queries %] [% IF q.name == namedcmd %] - or <a href="query.cgi?[% q.query FILTER html %]">edit</a> + or <a href="query.cgi?[% q.url FILTER html %]">edit</a> [% END %] [% END %] diff --git a/template/en/default/global/variables.none.tmpl b/template/en/default/global/variables.none.tmpl index 76ec1bec6..d19d6407f 100644 --- a/template/en/default/global/variables.none.tmpl +++ b/template/en/default/global/variables.none.tmpl @@ -33,7 +33,7 @@ # This means if you change "bug" to "problem", then if you have # "problem 3" in a comment, it won't become a clickable URL. # To have that feature, you must edit the quoteUrls function in - # globals.pl (in the base Bugzilla directory). + # Bugzilla/Template.pm. # Change the line: # my $bug_re = qr/bug\s*\#?\s*(\d+)/i; # to something like: diff --git a/template/en/default/index.html.tmpl b/template/en/default/index.html.tmpl index a19334c30..d7c74e188 100644 --- a/template/en/default/index.html.tmpl +++ b/template/en/default/index.html.tmpl @@ -23,7 +23,7 @@ #%] [%# INTERFACE: - # This template has no interface. + # release: a hash containing data about new releases, if any. #%] [% PROCESS global/variables.none.tmpl %] @@ -31,6 +31,8 @@ [% PROCESS global/header.html.tmpl title = "$terms.Bugzilla Main Page" + header = "Main Page" + header_addl_info = "version $constants.BUGZILLA_VERSION" style_urls = [ 'skins/standard/index.css' ] onload = 'document.forms[\'f\'].quicksearch.focus();' %] @@ -56,36 +58,88 @@ function addSidebar() { //--> </script> +[% IF release %] + <div id="new_release"> + [% IF release.data %] + [% IF release.deprecated %] + <p>[% terms.Bugzilla %] [%+ release.deprecated FILTER html %] is no longer + supported. You are highly encouraged to upgrade in order to keep your + system secure.</p> + [% END %] + + <p>A new [% terms.Bugzilla %] version ([% release.data.latest_ver FILTER html %]) + is available at + <a href="[% release.data.url FILTER html %]">[% release.data.url FILTER html %]</a>.<br> + Release date: [% release.data.date FILTER html %]</p> + + <p class="notice">This message is only shown to logged in users with admin privs. + You can configure this notification from the + <a href="editparams.cgi?section=core#upgrade_notification">Parameters</a> page.</p> + [% ELSIF release.error == "missing_package" %] + <p>Missing package '[% release.package FILTER html %]'. This package is required to + <a href="editparams.cgi?section=core#upgrade_notification">notify you about new releases</a>.</p> + [% ELSIF release.error == "cannot_download" %] + <p>The local XML file '[% release.xml_file FILTER html %]' cannot be created. + Please make sure the web server can write in this directory.</p> + [% ELSIF release.error == "no_update" %] + <p>The local XML file '[% release.xml_file FILTER html %]' cannot be updated. + Please make sure the web server can edit this file.</p> + [% ELSIF release.error == "no_access" %] + <p>The local XML file '[% release.xml_file FILTER html %]' cannot be read. + Please make sure this file has the correct rights set on it.</p> + [% ELSIF release.error == "corrupted" %] + <p>The local XML file '[% release.xml_file FILTER html %]' has an invalid XML format. + Please delete it and try accessing this page again.</p> + [% ELSIF release.error == "unknown_parameter" %] + <p>'[% Param("upgrade_notification") FILTER html %]' is not a valid notification + parameter. Please check this parameter in the + <a href="editparams.cgi?section=core#upgrade_notification">Parameters</a> page.</p> + [% END %] + </div> +[% END %] <div id="page-index"> <div class="intro"></div> - <p>This is where we put in lots of nifty words explaining all about [% terms.Bugzilla %].</p> + <p>Welcome to [% terms.Bugzilla %]. To see what's new in this version + of [% terms.Bugzilla %], see the + <a href="page.cgi?id=release-notes.html">release notes</a>! + You may also want to read the + <a href="[% Param('docs_urlbase') FILTER html %]using.html"> + [%- terms.Bugzilla %] User's Guide</a> to find out more about + [%+ terms.Bugzilla %] and how to use it.</p> - <p>But it all boils down to a choice of:</p> + <p>Most common actions:</p> <ul> <li id="query"><a href="query.cgi">Search existing [% terms.bug %] reports</a></li> <li id="enter-bug"><a href="enter_bug.cgi">Enter a new [% terms.bug %] report</a></li> <li id="report"><a href="report.cgi">Summary reports and charts</a></li> [% IF user.id %] <li id="userprefs"><a href="userprefs.cgi">Change password or user preferences</a></li> - [% IF user.get_flag('can_logout') %] + [% IF user.authorizer.can_logout %] <li id="logout"><a href="relogin.cgi">Log out [% user.login FILTER html %]</a></li> [% END %] -[% ELSE %] +[% ELSIF user.authorizer.can_login %] + </ul> [% PROCESS "account/auth/login-small.html.tmpl" %] - [% IF Param('createemailregexp') %] + <ul> + [% IF Param('createemailregexp') && user.authorizer.user_can_create_account %] <li id="account"><a href="createaccount.cgi">Open a new [% terms.Bugzilla %] account</a></li> [% END %] [% END %] <li id="sidebar"><a href="javascript:addSidebar()">Add to Sidebar</a> (requires a Mozilla browser like Mozilla Firefox)</li> + <li id="quick_search_plugin"> + <a href="javascript:window.external.AddSearchProvider('[% Param('urlbase') %]search_plugin.cgi')">Install + the Quick Search plugin</a> (requires Firefox 2 or Internet Explorer 7) + </li> + [%# List items of links to more things users can do on this installation. %] [% Hook.process("links") %] </ul> - <form id="show-bug" name="f" action="buglist.cgi" method="get" + <form id="f" name="f" action="buglist.cgi" method="get" onsubmit="if (this.quicksearch.value == '') { alert('Please enter one or more search terms first.'); return false; } return true;"> diff --git a/template/en/default/list/CVS/Entries b/template/en/default/list/CVS/Entries index 493edf19b..4c14199ef 100644 --- a/template/en/default/list/CVS/Entries +++ b/template/en/default/list/CVS/Entries @@ -1,13 +1,13 @@ -/change-columns.html.tmpl/1.12/Sun Jan 18 18:39:28 2004//TBUGZILLA-2_22_3 -/edit-multiple.html.tmpl/1.31.2.3/Sat Oct 14 20:30:58 2006//TBUGZILLA-2_22_3 -/list-simple.html.tmpl/1.9.8.1/Sat Oct 14 20:30:58 2006//TBUGZILLA-2_22_3 -/list.atom.tmpl/1.1.4.1/Fri Feb 2 21:41:03 2007//TBUGZILLA-2_22_3 -/list.csv.tmpl/1.5/Wed Jul 20 02:14:26 2005//TBUGZILLA-2_22_3 -/list.html.tmpl/1.46/Tue Feb 21 00:06:05 2006//TBUGZILLA-2_22_3 -/list.ics.tmpl/1.4/Tue Mar 15 17:16:25 2005//TBUGZILLA-2_22_3 -/list.js.tmpl/1.2/Sat Nov 8 18:04:36 2003//TBUGZILLA-2_22_3 -/list.rdf.tmpl/1.5/Thu Aug 4 11:51:24 2005//TBUGZILLA-2_22_3 -/quips.html.tmpl/1.16/Mon Jun 20 19:42:11 2005//TBUGZILLA-2_22_3 -/server-push.html.tmpl/1.6/Wed Oct 26 16:52:28 2005//TBUGZILLA-2_22_3 -/table.html.tmpl/1.28.2.1/Mon Oct 2 23:23:50 2006//TBUGZILLA-2_22_3 +/change-columns.html.tmpl/1.13/Wed Jul 12 12:21:42 2006//TBUGZILLA-3_0 +/edit-multiple.html.tmpl/1.39/Sat Oct 14 20:26:54 2006//TBUGZILLA-3_0 +/list-simple.html.tmpl/1.10/Sat Oct 14 20:26:54 2006//TBUGZILLA-3_0 +/list.atom.tmpl/1.2/Fri Feb 2 21:40:06 2007//TBUGZILLA-3_0 +/list.csv.tmpl/1.5/Wed Jul 20 02:14:26 2005//TBUGZILLA-3_0 +/list.html.tmpl/1.52/Wed Dec 27 20:19:50 2006//TBUGZILLA-3_0 +/list.ics.tmpl/1.6/Fri Feb 9 23:06:22 2007//TBUGZILLA-3_0 +/list.js.tmpl/1.2/Sat Nov 8 18:04:36 2003//TBUGZILLA-3_0 +/list.rdf.tmpl/1.5/Thu Aug 4 11:51:24 2005//TBUGZILLA-3_0 +/quips.html.tmpl/1.19/Tue Oct 17 19:58:38 2006//TBUGZILLA-3_0 +/server-push.html.tmpl/1.6/Wed Oct 26 16:52:28 2005//TBUGZILLA-3_0 +/table.html.tmpl/1.32/Fri Oct 20 15:50:58 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/list/CVS/Tag b/template/en/default/list/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/list/CVS/Tag +++ b/template/en/default/list/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/list/change-columns.html.tmpl b/template/en/default/list/change-columns.html.tmpl index 715846001..9b610fe0c 100644 --- a/template/en/default/list/change-columns.html.tmpl +++ b/template/en/default/list/change-columns.html.tmpl @@ -64,14 +64,15 @@ </p> <p> - <input type="submit" value="Change Columns"> + <input type="submit" id="change" value="Change Columns"> </p> </form> <form action="colchange.cgi"> <input type="hidden" name="rememberedquery" value="[% buffer FILTER html %]"> <input type="hidden" name="resetit" value="1"> - <input type="submit" value="Reset to [% terms.Bugzilla %] default"> + <input type="submit" id="reset" + value="Reset to [% terms.Bugzilla %] default"> </form> [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/list/edit-multiple.html.tmpl b/template/en/default/list/edit-multiple.html.tmpl index 62399f83d..38e4e930f 100644 --- a/template/en/default/list/edit-multiple.html.tmpl +++ b/template/en/default/list/edit-multiple.html.tmpl @@ -17,6 +17,7 @@ # Rights Reserved. # # Contributor(s): Myk Melez <myk@mozilla.org> + # Max Kanat-Alexander <mkanat@bugzilla.org> #%] [% PROCESS global/variables.none.tmpl %] @@ -130,7 +131,7 @@ [% END %] </tr> - [% IF UserInGroup(Param("timetrackinggroup")) %] + [% IF user.in_group(Param("timetrackinggroup")) %] <tr> <th><label for="estimated_time">Estimated Hours:</label></th> <td> @@ -206,10 +207,25 @@ </tr> [% END %] + [% USE Bugzilla %] + [% FOREACH field = Bugzilla.get_fields({ obsolete => 0, custom => 1 }) %] + <tr> + [% PROCESS bug/field.html.tmpl value = dontchange + editable = 1 + allow_dont_change = 1 %] + </tr> + [% END %] + </table> <b><label for="comment">Additional Comments:</label></b><br> -<textarea id="comment" name="comment" rows="5" cols="[% constants.COMMENT_COLS FILTER none %]"></textarea><br> +[% INCLUDE global/textarea.html.tmpl + name = 'comment' + id = 'comment' + minrows = 5 + maxrows = 25 + cols = constants.COMMENT_COLS +%]<br> [% IF groups.size > 0 %] @@ -291,8 +307,8 @@ <select name="resolution" onchange="document.forms.changeform.knob[[% knum %]].checked=true"> [% FOREACH resolution = resolutions %] [% NEXT IF !resolution %] - <option value="[% resolution FILTER html %]" [% 'selected="selected"' IF resolution == "FIXED" %]> - [% resolution_descs.$resolution FILTER html %] + <option value="[% resolution FILTER html %]"> + [% get_resolution(resolution) FILTER html %] </option> [% END %] </select><br> @@ -341,10 +357,10 @@ Reassign [% terms.bugs %] to default assignee of selected component </label><br> -<input type="submit" value="Commit"> +<input type="submit" id="commit" value="Commit"> [% IF Param('move-enabled') && user.is_mover %] - <input type="submit" name="action" value="[% Param('move-button-text') %]"> + <input type="submit" name="action" id="action" value="[% Param('move-button-text') %]"> [% END %] [%############################################################################%] diff --git a/template/en/default/list/list.html.tmpl b/template/en/default/list/list.html.tmpl index 5ac715a0c..a12c39a9e 100644 --- a/template/en/default/list/list.html.tmpl +++ b/template/en/default/list/list.html.tmpl @@ -143,7 +143,7 @@ <input type="hidden" name="id" value="[% id FILTER html %]"> [% END %] <input type="hidden" name="format" value="multiple"> - <input type="submit" value="Long Format"> + <input type="submit" id="long_format" value="Long Format"> </form> <form method="post" action="show_bug.cgi"> <input type="hidden" name="ctype" value="xml"> @@ -151,13 +151,13 @@ <input type="hidden" name="id" value="[% id FILTER html %]"> [% END %] <input type="hidden" name="excludefield" value="attachmentdata"> - <input type="submit" value="XML"> + <input type="submit" value="XML" id="xml"> </form> - [% IF UserInGroup(Param('timetrackinggroup')) %] + [% IF user.in_group(Param('timetrackinggroup')) %] <form method="post" action="summarize_time.cgi"> <input type="hidden" name="id" value="[% buglist_joined FILTER html %]"> - <input type="submit" value="Time Summary"> + <input type="submit" id="timesummary" value="Time Summary"> </form> [% END %] </td> @@ -213,12 +213,12 @@ <td valign="middle"> <form method="get" action="buglist.cgi"> - <input type="submit" value="Remember search"> as + <input type="submit" id="remember" value="Remember search"> as <input type="hidden" name="newquery" value="[% urlquerypart FILTER html %][% "&order=$qorder" FILTER html IF order %]"> <input type="hidden" name="cmdtype" value="doit"> <input type="hidden" name="remtype" value="asnamed"> - <input type="text" name="newqueryname" size="20" + <input type="text" id="save_newqueryname" name="newqueryname" size="20" value="[% defaultsavename FILTER html %]"> </form> </td> @@ -226,6 +226,12 @@ </tr> </table> +[% IF cgi.param('product').size == 1 && cgi.param('product') != "" %] + <p> + <a href="enter_bug.cgi?product=[% cgi.param('product') FILTER url_quote %]">File + a new [% terms.bug %] in the "[% cgi.param('product') FILTER html %]" product</a> + </p> +[% END %] [%############################################################################%] [%# Page Footer #%] diff --git a/template/en/default/list/list.ics.tmpl b/template/en/default/list/list.ics.tmpl index 6246cf755..814a397aa 100644 --- a/template/en/default/list/list.ics.tmpl +++ b/template/en/default/list/list.ics.tmpl @@ -18,7 +18,7 @@ # # Contributor(s): William Jon McCann <mccann@jhu.edu> #%] -[% PROCESS global/variables.none.tmpl %][% USE date %] +[% PROCESS global/variables.none.tmpl %] BEGIN:VCALENDAR CALSCALE:GREGORIAN [%+ PROCESS ics_prodid +%] @@ -32,7 +32,7 @@ BEGIN:VTODO [%+ PROCESS ics_status bug_status = bug.bug_status +%] [%+ PROCESS ics_dtstamp +%] [% IF bug.changeddate %] -[%+ date.format(bug.changedtime,"%Y%m%dT%H%M%SZ") FILTER ics('LAST-MODIFIED') +%] +[%+ time2str("%Y%m%dT%H%M%SZ", bug.changedtime, "UTC") FILTER ics('LAST-MODIFIED') +%] [% END %] [% IF bug.percentage_complete %] [%+ bug.percentage_complete FILTER format('%d') FILTER ics('PERCENT-COMPLETE') +%] @@ -54,7 +54,7 @@ END:VTODO END:VCALENDAR [% BLOCK ics_prodid %] - [% "-//Mozilla/Bugzilla $VERSION//EN" FILTER ics('PRODID') %] + [% "-//Mozilla/Bugzilla $constants.BUGZILLA_VERSION//EN" FILTER ics('PRODID') %] [% END %] [% BLOCK ics_uid %] @@ -66,11 +66,11 @@ END:VCALENDAR [% END %] [% BLOCK ics_dtstart %] - [% date.format(bug.opentime,"%Y%m%dT%H%M%SZ") FILTER ics('DTSTART') %] + [% time2str("%Y%m%dT%H%M%SZ", bug.opentime, "UTC") FILTER ics('DTSTART') %] [% END %] [% BLOCK ics_dtstamp %] - [% date.format(date.now,"%Y%m%dT%H%M%SZ") FILTER ics('DTSTAMP') %] + [% time2str("%Y%m%dT%H%M%SZ", currenttime, "UTC") FILTER ics('DTSTAMP') %] [% END %] [% BLOCK ics_status %] diff --git a/template/en/default/list/quips.html.tmpl b/template/en/default/list/quips.html.tmpl index 92570777e..32529f4cc 100644 --- a/template/en/default/list/quips.html.tmpl +++ b/template/en/default/list/quips.html.tmpl @@ -31,7 +31,7 @@ [% PROCESS global/header.html.tmpl title = "$terms.Bugzilla Quip System" - h1 = "Add your own clever headline" + header = "Add your own clever headline" %] [% IF added_quip %] @@ -76,7 +76,7 @@ <input type="hidden" name="action" value="add"> <input size="80" name="quip"> <p> - <input type="submit" value="Add This Quip"> + <input type="submit" id="add" value="Add This Quip"> </p> </form> [% ELSE %] @@ -85,7 +85,7 @@ [% END %] [% IF show_quips %] - [% IF !UserInGroup('admin') %] + [% IF !user.in_group('admin') %] <h2> Existing quips: </h2> @@ -148,7 +148,7 @@ +'value="Check All" onclick="SetCheckboxes(true);">'); //--></script> - <input type="submit" value="Update"> + <input type="submit" id="update" value="Update"> </form> <br> [% END %] @@ -156,7 +156,7 @@ <p> Those who like their wisdom in large doses can <a href="quips.cgi?action=show">view - [% IF UserInGroup('admin') %] + [% IF user.in_group('admin') %] and edit [% END %] the whole quip list</a>. diff --git a/template/en/default/list/table.html.tmpl b/template/en/default/list/table.html.tmpl index 8d983dcce..2918007c1 100644 --- a/template/en/default/list/table.html.tmpl +++ b/template/en/default/list/table.html.tmpl @@ -160,7 +160,8 @@ [% tableheader %] [% END %] - <tr class="bz_[% bug.bug_severity FILTER css_class_quote -%] + <tr class="bz_bugitem + bz_[% bug.bug_severity FILTER css_class_quote -%] bz_[% bug.priority FILTER css_class_quote -%] bz_[% bug.bug_status FILTER css_class_quote -%] [%+ "bz_$bug.resolution" FILTER css_class_quote IF bug.resolution -%] @@ -168,7 +169,6 @@ [%+ "bz_secure_mode_$bug.secure_mode" FILTER css_class_quote IF bug.secure_mode -%] [%+ count % 2 == 1 ? "bz_row_odd" : "bz_row_even" -%] "> - [% IF dotweak %] <td> @@ -176,7 +176,8 @@ </td> [% END %] <td class="first-child"> - <a href="show_bug.cgi?id=[% bug.bug_id %]">[% bug.bug_id %]</a> + <a name="b[% bug.bug_id %]" + href="show_bug.cgi?id=[% bug.bug_id %]">[% bug.bug_id %]</a> <span style="display: none">[%+ '[SEC]' IF bug.secure_mode %]</span> </td> @@ -191,7 +192,7 @@ [% ELSIF column == 'bug_status' %] [%- status_descs.${bug.$column}.truncate(abbrev.$column.maxlength, abbrev.$column.ellipsis) FILTER html %] [% ELSIF column == 'resolution' %] - [%- resolution_descs.${bug.$column}.truncate(abbrev.$column.maxlength, abbrev.$column.ellipsis) FILTER html %] + [%- get_resolution(bug.$column).truncate(abbrev.$column.maxlength, abbrev.$column.ellipsis) FILTER html %] [% ELSE %] [%- bug.$column.truncate(abbrev.$column.maxlength, abbrev.$column.ellipsis) FILTER html -%] [% END %] diff --git a/template/en/default/pages/CVS/Entries b/template/en/default/pages/CVS/Entries index 91f9a3310..695c85f71 100644 --- a/template/en/default/pages/CVS/Entries +++ b/template/en/default/pages/CVS/Entries @@ -1,9 +1,10 @@ -/bug-writing.html.tmpl/1.4/Thu Sep 15 10:15:22 2005//TBUGZILLA-2_22_3 -/fields.html.tmpl/1.6.2.1/Mon Jun 12 17:41:40 2006//TBUGZILLA-2_22_3 -/linked.html.tmpl/1.8/Wed Feb 9 17:30:20 2005//TBUGZILLA-2_22_3 -/linkify.html.tmpl/1.5.6.2/Fri Mar 3 00:07:58 2006//TBUGZILLA-2_22_3 -/quicksearch.html.tmpl/1.1/Sun Aug 21 18:16:43 2005//TBUGZILLA-2_22_3 -/quicksearchhack.html.tmpl/1.2/Fri Aug 26 23:11:33 2005//TBUGZILLA-2_22_3 -/sudo.html.tmpl/1.1/Fri Nov 4 16:11:46 2005//TBUGZILLA-2_22_3 -/voting.html.tmpl/1.2/Thu Mar 18 16:21:57 2004//TBUGZILLA-2_22_3 +/bug-writing.html.tmpl/1.6.2.1/Tue Apr 10 19:02:34 2007//TBUGZILLA-3_0 +/fields.html.tmpl/1.9/Sun Jan 7 23:56:10 2007//TBUGZILLA-3_0 +/linked.html.tmpl/1.8/Wed Feb 9 17:30:20 2005//TBUGZILLA-3_0 +/linkify.html.tmpl/1.8/Wed Jul 12 12:21:42 2006//TBUGZILLA-3_0 +/quicksearch.html.tmpl/1.2/Wed Jul 12 12:21:42 2006//TBUGZILLA-3_0 +/quicksearchhack.html.tmpl/1.3/Wed Jul 12 12:21:42 2006//TBUGZILLA-3_0 +/release-notes.html.tmpl/1.1.2.3/Tue May 8 21:46:47 2007//TBUGZILLA-3_0 +/sudo.html.tmpl/1.1/Fri Nov 4 16:11:46 2005//TBUGZILLA-3_0 +/voting.html.tmpl/1.3/Thu Dec 28 17:56:00 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/pages/CVS/Tag b/template/en/default/pages/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/pages/CVS/Tag +++ b/template/en/default/pages/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/pages/bug-writing.html.tmpl b/template/en/default/pages/bug-writing.html.tmpl index 0317ae6a1..6df5d5fef 100644 --- a/template/en/default/pages/bug-writing.html.tmpl +++ b/template/en/default/pages/bug-writing.html.tmpl @@ -18,188 +18,164 @@ # # Contributor(s): Eli Goldberg <eli@prometheus-music.com> # Gervase Markham <gerv@gerv.net> + # Vera Horiuchi # Claudius Gayle # Peter Mock # Chris Pratt # Tom Schutter # Chris Yeh #%] - -[% PROCESS global/variables.none.tmpl %] -[% INCLUDE global/header.html.tmpl title = "$terms.Bug Writing Guidelines" %] -<h3>Why You Should Read This</h3> +[% PROCESS "global/field-descs.none.tmpl" %] + +[% INCLUDE global/header.html.tmpl title = "$terms.Bug Writing Guidelines" %] + +<h3>Contents</h3> +<ul> +<li><a href="#why">Why You Should Read This</a></li> +<li><a href="#useful">What Makes [% terms.aBug %] Report Useful?</a></li> +<li><a href="#before">Before You Start...</a></li> +<li><a href="#reporting">Reporting a New [% terms.Bug %]</a></li> +<li><a href="#more">More Information on Writing Good [% terms.Bugs %]</a></li> +</ul> + +<h3><a name="why">Why You Should Read This</a></h3> <blockquote> <p>Simply put, the more effectively you report [% terms.abug %], the more - likely an - engineer will actually fix it.</p> - - <p>These guidelines are a general tutorial to teach novice and - intermediate [% terms.bug %] reporters how to compose effective - [% terms.bug %] reports. Not - every sentence may precisely apply to your software project.</p> + likely an engineer will actually fix it. This tutorial teaches novice and + intermediate [% terms.bug %] reporters how to write effective + [% terms.bug %] reports.</p> </blockquote> -<h3>How to Write a Useful [% terms.Bug %] Report</h3> +<h3><a name="useful">What Makes [% terms.aBug %] Report Useful?</a></h3> <blockquote> - <p>Useful [% terms.bug %] reports are ones that get [% terms.bugs %] fixed. - A useful [% terms.bug %] report normally has two qualities:</p> - - <ol> - <li><b>Reproducible.</b> If an engineer can't see the [% terms.bug %] - herself to prove that it exists, she'll probably stamp your [% terms.bug %] - report "WORKSFORME" or "INVALID" and move on to the next [% terms.bug %]. - Every detail you can provide helps.<br> + <p>Useful [% terms.bug %] reports get [% terms.bugs %] fixed. + A useful [% terms.bug %] report has two qualities:</p> + + <ul> + <li><b>It's Reproducible.</b> Engineers usually prefer to fix [% terms.bugs %] + they can actually see. If an engineer can't reproduce the [% terms.bug %], + it'll probably be stamped "[% get_resolution("WORKSFORME") FILTER html %]" or + "[% get_resolution("INVALID") FILTER html %]".<br> <br> </li> - <li><b>Specific.</b> The quicker the engineer can isolate the - [% terms.bug %] to a specific area, the more likely she'll expediently - fix it. (If a programmer or tester has to decipher [% terms.abug %], - they may spend more time cursing the submitter than solving the - problem.)<br> - <br> - [ <a href="#tips" name="Anchor">Tell Me More</a> ]</li> - </ol> - - <p>Let's say the application you're testing is a web browser. You crash - at foo.com, and want to write up a [% terms.bug %] report:</p> + <li><b>It's Specific.</b> The quicker an engineer isolates the + [% terms.bug %] to a specific area, the more likely it'll be fixed. (If the + engineer must decipher your [% terms.bug %], + he or she will waste time cursing you instead.)<br> + </li> + </ul> - <blockquote> - <p><b>BAD:</b> "My browser crashed. I think I was on www.foo.com. I - play golf with Bill Gates, so you better fix this problem, or I'll - report you to him. By the way, your Back icon looks like a squashed - rodent. UGGGLY. And my grandmother's home page is all messed up in your - browser. Thx 4 UR help."</p> - - <p><b>GOOD:</b> "I crashed each time I went to www.foo.com, using the - 2002-02-25 build on a Windows 2000 system. I also rebooted into Linux, - and reproduced this problem using the 2002-02-24 Linux build.</p> - - <p>It again crashed each time upon drawing the Foo banner at the top of - the page. I broke apart the page, and discovered that the following - image link will crash the application reproducibly, unless you remove - the "border=0" attribute:</p> - - <p><tt><IMG SRC="http://www.foo.com/images/topics/topicfoos.gif" - width="34" height="44" border="0" alt="News"></tt></p> - </blockquote> </blockquote> -<h3>How to Enter your Useful [% terms.Bug %] Report - into [% terms.Bugzilla %]:</h3> +<h3><a name="before">Before You Start...</a></h3> -<blockquote> - <p>Before you enter your [% terms.bug %], use [% terms.Bugzilla %]'s - <a href="query.cgi">search page</a> to determine whether the defect - you've discovered is a known, already-reported [% terms.bug %]. If - your [% terms.bug %] is the 37th duplicate of a known issue, - you're more likely to annoy the engineer. (Annoyed engineers fix fewer - [% terms.bugs %].)</p> - - <p>Next, be sure to reproduce your [% terms.bug %] using a recent build. +<ol> + <li>Before you enter your [% terms.bug %], use [% terms.Bugzilla %]'s + <a href="query.cgi?format=specific">search page</a> to determine whether + your [% terms.bug %] is known.</li> + + <li>Reproduce your [% terms.bug %] using a recent build. Engineers tend to be most interested in problems affecting the code base - that they're actively working on. After all, the [% terms.bug %] you're - reporting may already be fixed.</p> + on which they're actively working. The [% terms.bug %] you're + reporting may already be fixed.</li> +</ol> - <p>If you've discovered a new [% terms.bug %] using a current build, report - it in [% terms.Bugzilla %]:</p> +<blockquote> +Can't find your [% terms.bug %] in [% terms.Bugzilla %]? And you can reproduce +it in a recent build? Let's report it. +</blockquote> - <ol> - <li>From your [% terms.Bugzilla %] main page, choose - "<a href="enter_bug.cgi">Enter a new [% terms.bug %]</a>".</li> +<h3><a name="reporting">Reporting a New [% terms.Bug %]</a></h3> - <li>Select the product that you've found a [% terms.bug %] in.</li> +<ol> + <li>From [% terms.Bugzilla %]'s main page, choose + "<a href="enter_bug.cgi">Enter a new [% terms.bug %]</a>".</li> - <li>Enter your e-mail address, password, and press the "Log in" button. - (If you don't yet have a password, enter your email address below and - press the "Submit Request" button instead. You'll quickly receive - an e-mail message with your password.)</li> - </ol> + <li>Select the product in which you've found [% terms.abug %].</li> + + <li>Log into [% terms.Bugzilla %].</li> + + <li>Fill out the form. Here's what it all means:</li> + +</ol> - <p>Now, fill out the form. Here's what it all means:</p> <p><b>Where did you find the [% terms.bug %]?</b></p> <blockquote> - <p><b>Product: In which product did you find the [% terms.bug %]?</b><br> + <p><b>Product:</b> In which product did you find it?<br> You just specified this on the last page, so you can't edit it here.</p> - <p><b>Version: In which product version did you find - the [% terms.bug %]?</b><br> + <p><b>Version:</b> In which product version did you find + it?<br> (If applicable)</p> - <p><b>Component: In which component does the [% terms.bug %] - exist?</b><br> + <p><b>Component:</b> In which component does it + exist?<br> [% terms.Bugzilla %] requires that you select a component to enter - a [% terms.bug %]. (Not sure which to choose? Click on the Component link. - You'll see a description of each component, to help you make the best - choice.)</p> - - <p><b>OS: On which Operating System (OS) did you find - this [% terms.bug %]?</b> - (e.g. Linux, Windows 2000, Mac OS 9.)<br> - If you know the [% terms.bug %] happens on all OSs, choose 'All'. - Otherwise, select the OS that you found the [% terms.bug %] on, or - "Other" if your OS isn't listed.</p> + [% terms.abug %]. (Click the Component link to see a description of each + component.)</p> + + <p><b>OS:</b> On which operating system (OS) did you find + it? + (e.g. Linux, Windows XP, Mac OS X.)<br> + If the [% terms.bug %] happens on all operating systems, choose "All". + Otherwise, select the OS, or "Other" if your OS isn't listed.</p> </blockquote> <p><b>How important is the [% terms.bug %]?</b></p> <blockquote> - <p><b>Severity: How damaging is the [% terms.bug %]?</b><br> - This item defaults to 'normal'. If you're not sure what severity your - [% terms.bug %] deserves, click on the Severity link. You'll see a - description of each severity rating.<br> + <p><b>Severity:</b> How damaging is it?<br> + The default is 'normal' severity. (Click on the Severity link to see + a description of each severity rating.<br> </p> </blockquote> <p><b>Who will be following up on the [% terms.bug %]?</b></p> <blockquote> - <p><b>Assigned To: Which engineer should be responsible for fixing - this [% terms.bug %]?</b><br> - [% terms.Bugzilla %] will automatically assign the [% terms.bug %] to a + <p><b>Assigned To:</b> Which engineer should be responsible for fixing + it?<br> + [% terms.Bugzilla %] automatically assigns the [% terms.bug %] to a default engineer upon submitting [% terms.abug %] report. If you'd prefer - to directly assign the [% terms.bug %] to someone else, enter their e-mail - address into this field. (To see the list of default engineers for each - component, click on the Component link.)</p> - - <p><b>Cc: Who else should receive e-mail updates on changes to this - [% terms.bug %]?</b><br> - List the full e-mail addresses of other individuals who should receive - an e-mail update upon every change to the [% terms.bug %] report. You can - enter as many e-mail addresses as you'd like, separated by spaces or - commas, as long as those people have [% terms.Bugzilla %] accounts.</p> + to directly assign the [% terms.bug %] to someone else, enter the person's + e-mail address. (To see the list of default engineers for each + component, click the Component link.)</p> + + <p><b>Cc:</b> Who else should receive e-mail updates on changes to this + [% terms.bug %]?<br> + List the e-mail addresses of other people who should receive + an update whenever the [% terms.bug %] report changes. Enter as many e-mail + addresses as you'd like, separating them by spaces or + commas. Important: You can only enter people who have + [% terms.Bugzilla %] accounts.</p> </blockquote> <p><b>What else can you tell the engineer about the [% terms.bug %]?</b></p> <blockquote> - <p><b>Summary:</b> <b>How would you describe the [% terms.bug %], in - approximately 60 or fewer characters?</b><br> + <p><b>Summary:</b> How would you describe the [% terms.bug %], in + approximately 60 or fewer characters?<br> A good summary should <b>quickly and uniquely identify [% terms.abug %] - report</b>. Otherwise, an engineer cannot meaningfully identify your - [% terms.bug %] by its summary, and will often fail to pay attention to - your [% terms.bug %] report when skimming through a 10 - page [% terms.bug %] list.<br> + report</b>. If an engineer can't identify your + [% terms.bug %] by its summary, it may be ignored when skimming through a + 10-page list.<br> <br> - A useful summary might be "<tt>PCMCIA install fails on Tosh Tecra - 780DVD w/ 3c589C</tt>". "<tt>Software fails</tt>" or "<tt>install - problem</tt>" would be examples of a bad summary.<br> - <br> - [ <a href="#summary">Tell Me More</a> ]<br> + A useful summary is "<tt>Cancelling a File Copy dialog crashes Nautilus</tt>". + Examples of bad summaries would be "<tt>Software crashes</tt>" or "<tt>copy problem</tt>".<br> <br> <b>Description:</b><br> - Please provide a detailed problem report in this field. Your - [% terms.bug %]'s recipients will most likely expect the following - information:</p> + Provide a detailed problem report. [% terms.aBug %]'s recipients usually + expect the following information:</p> <blockquote> - <p><b>Overview Description:</b> More detailed expansion of + <p><b>Overview Description:</b> More detailed restatement of summary.</p> <blockquote> @@ -213,13 +189,12 @@ Drag-selecting any page crashes Mac builds in NSGetFactory <blockquote> <pre> -1) View any web page. (I used the default sample page, -resource:/res/samples/test0.html) +1) View any web page. (I used the default sample page, resource:/res/samples/test0.html) 2) Drag-select the page. (Specifically, while holding down the mouse button, drag the mouse pointer downwards from any point in the browser's content region to the bottom of the -browser's content region.) +browser's content region.) </pre> </blockquote> @@ -228,7 +203,7 @@ browser's content region.) <blockquote> <pre> -The application crashed. Stack crawl appended below from MacsBug. +The application crashed. </pre> </blockquote> @@ -243,11 +218,11 @@ The window should scroll downwards. Scrolled content should be selected. </blockquote> <p><b>Build Date & Platform:</b> Date and platform of the build - that you first encountered the [% terms.bug %] in.</p> + in which you first encountered the [% terms.bug %].</p> <blockquote> <pre> -Build 2002-03-15 on Mac OS 9.0 +Build 2006-08-10 on Mac OS 10.4.3 </pre> </blockquote> @@ -257,13 +232,7 @@ Build 2002-03-15 on Mac OS 9.0 <blockquote> <pre> -- Also Occurs On -Mozilla (2002-03-15 build on Windows NT 4.0) - -- Doesn't Occur On -Mozilla (2002-03-15 build on Red Hat Linux; feature not supported) -Internet Explorer 5.0 (shipping build on Windows NT 4.0) -Netscape Communicator 4.5 (shipping build on Mac OS 9.0) +- Doesn't Occur On Build 2006-08-10 on Windows XP Home (Service Pack 2) </pre> </blockquote> @@ -271,38 +240,27 @@ Netscape Communicator 4.5 (shipping build on Mac OS 9.0) For crashing [% terms.bugs %]:</p> <ul> - <li><b>Win32:</b> if you receive a Dr. Watson error, please note - the type of the crash, and the module that the application crashed - in. (e.g. access violation in apprunner.exe)</li> + <li><b>Windows:</b> Note the type of the crash, and the module that the + application crashed in (e.g. access violation in apprunner.exe).</li> + + <li><b>Mac OS X:</b> Attach the "Crash Reporter" log that appears upon crash. + Only include the section directly below the crashing thread, usually titled + "Thread 0 Crashed". Please do not paste the entire log!</li> - <li><b>Mac OS:</b> if you're running MacsBug, please provide the - results of a <b>how</b> and an <b>sc</b>:</li> </ul> - <blockquote> -<pre> -*** MACSBUG STACK CRAWL OF CRASH (Mac OS) -Calling chain using A6/R1 links -Back chain ISA Caller -00000000 PPC 0BA85E74 -03AEFD80 PPC 0B742248 -03AEFD30 PPC 0B50FDDC NSGetFactory+027FC -PowerPC unmapped memory exception at 0B512BD0 NSGetFactory+055F0 -</pre> - </blockquote> </blockquote> - </blockquote> <p>You're done!<br> <br> After double-checking your entries for any possible errors, press the - "Commit" button, and your [% terms.bug %] report will now be in + "Commit" button. Your [% terms.bug %] report will now be in the [% terms.Bugzilla %] database.<br> </p> </blockquote> <hr> -<h3>More Information on Writing Good [% terms.Bugs %]</h3> +<h3><a name="more">More Information on Writing Good [% terms.Bugs %]</a></h3> <blockquote> <p><b><a name="tips"></a> 1. General Tips for a Useful [% terms.Bug %] @@ -311,8 +269,8 @@ PowerPC unmapped memory exception at 0B512BD0 NSGetFactory+055F0 <blockquote> <p><b>Use an explicit structure, so your [% terms.bug %] reports are easy to skim.</b> [% terms.Bug %] report users often need immediate access to - specific sections of your [% terms.bug %]. If your [% terms.Bugzilla %] - installation supports the [% terms.Bugzilla %] Helper, use it.</p> + specific sections of your [% terms.bug %]. Follow the structure + recommended above.</p> <p><b>Avoid cuteness if it costs clarity.</b> Nobody will be laughing at your funny [% terms.bug %] title at 3:00 AM when they can't remember how @@ -321,7 +279,7 @@ PowerPC unmapped memory exception at 0B512BD0 NSGetFactory+055F0 <p><b>One [% terms.bug %] per report.</b> Completely different people typically fix, verify, and prioritize different [% terms.bugs %]. If you mix a handful of [% terms.bugs %] into a single report, the right people - probably won't discover your [% terms.bugs %] in a timely fashion, or at + probably won't discover your [% terms.bugs %] in a timely fashion, if at all. Certain [% terms.bugs %] are also more important than others. It's impossible to prioritize [% terms.abug %] report when it contains four different issues, all of differing importance.</p> @@ -350,18 +308,17 @@ PowerPC unmapped memory exception at 0B512BD0 NSGetFactory+055F0 time opening up your [% terms.bug %] to determine whether it matters.</p> <p><b>Your [% terms.bug %] will often be searched by its summary.</b> Just - as you'd find web pages with Google by searching by keywords through - intuition, so will other people locate your [% terms.bugs %]. - Descriptive [% terms.bug %] summaries are - naturally keyword-rich, and easier to find.</p> + as you'd find web pages with Google by searching with keywords, so will other + people locate your [% terms.bugs %]. Descriptive [% terms.bug %] summaries are + naturally keyword-rich and easier to find.</p> - <p>For example, you'll find a [% terms.bug %] titled "<tt>Dragging icons + <p>For example, you'll find [% terms.abug %] titled "<tt>Dragging icons from List View to gnome-terminal doesn't paste path</tt>" if you search on "List", "terminal", or "path". Those search keywords wouldn't have - found a [% terms.bug %] titled "<tt>Dragging icons doesn't paste</tt>".</p> + found [% terms.abug %] titled "<tt>Dragging icons doesn't paste</tt>".</p> <p>Ask yourself, "Would someone understand my [% terms.bug %] from just - this summary?" If so, you've written a fine summary.</p> + this summary?" If so, you've succeeded.</p> <p><b>Don't write titles like these:</b></p> @@ -378,11 +335,11 @@ PowerPC unmapped memory exception at 0B512BD0 NSGetFactory+055F0 <p><b>Good [% terms.bug %] titles:</b></p> <ol> - <li>"1.0 upgrade installation fails if Mozilla M18 package present" - - Explains problem and the context.</li> + <li>"Save button disabled after failed post attempt" - + Explains the problem and context.</li> - <li>"RPM 4 installer crashes if launched on Red Hat 6.2 (RPM 3) - system" - Explains what happens, and the context.</li> + <li>"Enter & Escape have no effect in 'Upload Photos' dialog" - + Also explains the problem and context.</li> </ol> </blockquote> </blockquote> diff --git a/template/en/default/pages/fields.html.tmpl b/template/en/default/pages/fields.html.tmpl index a45fa0b87..6b77f8b2e 100644 --- a/template/en/default/pages/fields.html.tmpl +++ b/template/en/default/pages/fields.html.tmpl @@ -148,7 +148,7 @@ cycle of [% terms.abug %]. <td> <dl> <dt> - <b>[% resolution_descs.FIXED FILTER html %]</b> + <b>[% get_resolution("FIXED") FILTER html %]</b> </dt> <dd> A fix for this [% terms.bug %] is checked into the tree and @@ -156,14 +156,14 @@ cycle of [% terms.abug %]. </dd> <dt> - <b>[% resolution_descs.INVALID FILTER html %]</b> + <b>[% get_resolution("INVALID") FILTER html %]</b> </dt> <dd> The problem described is not [% terms.abug %]. </dd> <dt> - <b>[% resolution_descs.WONTFIX FILTER html %]</b> + <b>[% get_resolution("WONTFIX") FILTER html %]</b> </dt> <dd> The problem described is [% terms.abug %] which will never be @@ -171,7 +171,7 @@ cycle of [% terms.abug %]. </dd> <dt> - <b>[% resolution_descs.DUPLICATE FILTER html %]</b> + <b>[% get_resolution("DUPLICATE") FILTER html %]</b> </dt> <dd> The problem is a duplicate of an existing [% terms.bug %]. @@ -181,7 +181,7 @@ cycle of [% terms.abug %]. </dd> <dt> - <b>[% resolution_descs.WORKSFORME FILTER html %]</b> + <b>[% get_resolution("WORKSFORME") FILTER html %]</b> </dt> <dd> All attempts at reproducing this [% terms.bug %] were futile, @@ -191,7 +191,7 @@ cycle of [% terms.abug %]. </dd> <dt> - <b>[% resolution_descs.MOVED FILTER html %]</b> + <b>[% get_resolution("MOVED") FILTER html %]</b> </dt> <dd> The problem was specific to a related product @@ -251,7 +251,7 @@ This field describes the importance and order in which [% terms.abug %] should be fixed. This field is utilized by the programmers/engineers to prioritize their work to be done. The available priorities range from <b>P1</b> (most important) to -<b>P5</b> (least important.) +<b>P5</b> (least important). <h2><a name="rep_platform">Platform</a></h2> diff --git a/template/en/default/pages/linkify.html.tmpl b/template/en/default/pages/linkify.html.tmpl index 94f9ffb2d..af0a86ba8 100644 --- a/template/en/default/pages/linkify.html.tmpl +++ b/template/en/default/pages/linkify.html.tmpl @@ -30,10 +30,14 @@ </p> <form action="page.cgi" method="post"> - <textarea cols="[% constants.COMMENT_COLS FILTER none %]" rows="20" name="text"></textarea> + [% INCLUDE global/textarea.html.tmpl + name = 'text' + minrows = 20 + cols = constants.COMMENT_COLS + %] <br> <input type="hidden" name="id" value="linked.html"> - <input value="Linkify" type="submit"> + <input type="submit" id="linkify" value="Linkify"> </form> [% INCLUDE global/footer.html.tmpl %] diff --git a/template/en/default/pages/quicksearch.html.tmpl b/template/en/default/pages/quicksearch.html.tmpl index 73a0172ee..b8d412d5e 100644 --- a/template/en/default/pages/quicksearch.html.tmpl +++ b/template/en/default/pages/quicksearch.html.tmpl @@ -40,7 +40,7 @@ { alert('Please enter one or more search terms first.'); return false; } return true;"> <input type="text" size="40" name="quicksearch"> - <input type="submit" value="Find"> + <input type="submit" value="Find" id="find"> </form> <h2>Getting Started</h2> diff --git a/template/en/default/pages/quicksearchhack.html.tmpl b/template/en/default/pages/quicksearchhack.html.tmpl index 22913ec42..47a0eacd3 100644 --- a/template/en/default/pages/quicksearchhack.html.tmpl +++ b/template/en/default/pages/quicksearchhack.html.tmpl @@ -32,8 +32,8 @@ { alert('Please enter one or more search terms first.'); return false; } return true;"> <input type="text" size="40" name="quicksearch"> - <input type="submit" value="Find"> - <input type="submit" name="load" value="Load Search Form"> + <input type="submit" value="Find" id="find"> + <input type="submit" name="load" value="Load Search Form" id="load"> </form> <p> diff --git a/template/en/default/pages/release-notes.html.tmpl b/template/en/default/pages/release-notes.html.tmpl new file mode 100644 index 000000000..51d8e232d --- /dev/null +++ b/template/en/default/pages/release-notes.html.tmpl @@ -0,0 +1,763 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # The Initial Developer of the Original Code is Everything Solved. + # Portions created by Everything Solved are Copyright (C) 2006 + # Everything Solved. All Rights Reserved. + # + # Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org> + #%] + +[% PROCESS global/variables.none.tmpl %] +[% INCLUDE global/header.html.tmpl + title = "$terms.Bugzilla 3.0 Release Notes" + style_urls = ['skins/standard/release-notes.css'] +%] + +<h2>Table of Contents</h2> + +<ul class="bz_toc"> + <li><a href="#v30_introduction">Introduction</a></li> + <li><a href="#v30_req">Minimum Requirements</a></li> + <li><a href="#v30_feat">New Features and Improvements</a></li> + <li><a href="#v30_issues">Outstanding Issues</a></li> + <li><a href="#v30_upgrading">How to Upgrade From An Older Version</a></li> + <li><a href="#v30_code_changes">Code Changes Which May Affect + Customizations</a></li> + <li><a href="#v30_previous">Release Notes for Previous Versions</a></li> +</ul> + +<h2><a name="v30_introduction"></a>Introduction</h2> + +<p>Welcome to [% terms.Bugzilla %] 3.0! It's been over eight years since + we released [% terms.Bugzilla %] 2.0, and everything has changed since + then. Even just since our previous release, [% terms.Bugzilla %] 2.22, + we've added a <em>lot</em> of new features. So enjoy the release, we're + happy to bring it to you.</p> + +<p>If you're upgrading, make sure to read <a href="#v30_upgrading">How to + Upgrade From An Older Version</a>. If you are upgrading from a release + before 2.22, make sure to read the release notes for all the + <a href="#v30_previous">previous versions</a> in between your version + and [% terms.Bugzilla %] 3.0.</p> + +<h2><a name="v30_req"></a>Minimum Requirements</h2> + +<p>Any requirements that are new since 2.22 will look like + <span class="req_new">this</span>.</p> + +<ul> + <li><a href="#v30_req_perl">Perl</a></li> + <li><a href="#v30_req_mysql">For MySQL Users</a></li> + <li><a href="#v30_req_pg">For PostgreSQL Users</a></li> + <li><a href="#v30_req_modules">Required Perl Modules</a></li> + <li><a href="#v30_req_optional_mod">Optional Perl + Modules</a></li> +</ul> + + +<h3><a name="v30_req_perl"></a>Perl</h3> + +<ul> + <li>Perl <span class="req_new">v<strong>5.8.0</strong></span> (non-Windows + platforms)</li> + <li>Perl v<strong>5.8.1</strong> (Windows platforms)</li> +</ul> + +[% PROCESS db_req db='mysql' %] + +[% PROCESS db_req db='pg' %] + +<h3><a name="v30_req_modules"></a>Required Perl Modules</h3> + +[% INCLUDE req_table reqs = REQUIRED_MODULES + new = ['Email-MIME-Modifier', 'Email-Send'] + updated = ['DBI'] %] + +<h3><a name="v30_req_optional_mod"></a>Optional Perl Modules</h3> + +<p>The following perl modules, if installed, enable various + features of [% terms.Bugzilla %]:</p> + +[% INCLUDE req_table reqs = OPTIONAL_MODULES + new = ['libwww-perl', 'SOAP-Lite', 'mod_perl', + 'Apache-DBI', 'Email-MIME-Attachment-Stripper', + 'Email-Reply'] + updated = ['CGI'] + include_feature = 1 %] + +<h2><a name="v30_feat"></a>New Features and Improvements</h2> + +<ul> + <li><a href="#v30_feat_cf">Custom Fields</a></li> + <li><a href="#v30_feat_mp">mod_perl Support</a></li> + <li><a href="#v30_feat_sq">Shared Saved Searches</a></li> + <li> + <a href="#v30_feat_afn">Attachments and Flags on New [% terms.Bugs %]</a> + </li> + <li><a href="#v30_feat_cr">Custom Resolutions</a></li> + <li><a href="#v30_feat_ppp">Per-Product Permissions</a></li> + <li><a href="#v30_feat_ui">User Interface Improvements</a></li> + <li><a href="#v30_feat_xml">XML-RPC Interface</a></li> + <li><a href="#v30_feat_skin">Skins</a></li> + <li><a href="#v30_feat_sbu">Unchangeable Fields Appear + Unchangeable</a></li> + <li><a href="#v30_feat_et">All Emails in Templates</a></li> + <li><a href="#v30_feat_df">No More Double-Filed [% terms.Bugs %]</a></li> + <li><a href="#v30_feat_cc">Default CC List for Components</a></li> + <li><a href="#v30_feat_emi">File/Modify [% terms.Bugs %] By Email</a></li> + <li><a href="#v30_feat_gw">Users Who Get All [% terms.Bug %] + Notifications</a></li> + <li><a href="#v30_feat_utf8">Improved UTF-8 Support</a></li> + <li><a href="#v30_feat_upda">Automatic Update Notification</a></li> + <li><a href="#v30_feat_welc">Welcome Page for New Installs</a></li> + <li><a href="#v30_feat_other">Other Enhancements and Changes</a></li> +</ul> + +<h3><a name="v30_feat_cf"></a>Custom Fields</h3> + +<p>[% terms.Bugzilla %] now includes very basic support for custom fields.</p> + +<p>Users in the <kbd>admin</kbd> group can add plain-text or drop-down + custom fields. You can edit the values available for drop-down fields + using the "Field Values" control panel.</p> + +<p>Don't add too many custom fields! It can make [% terms.Bugzilla %] + very difficult to use. Try your best to get along with the default + fields, and then if you find that you can't live without custom fields + after a few weeks of using [% terms.Bugzilla %], only then should you + start your custom fields.</p> + +<h3><a name="v30_feat_mp"></a>mod_perl Support</h3> + +<p>[% terms.Bugzilla %] 3.0 supports mod_perl, which allows for extremely + enhanced page-load performance. mod_perl trades memory usage for performance, + allowing near-instantaneous page loads, but using much more memory.</p> + +<p>If you want to enable mod_perl for your [% terms.Bugzilla %], we recommend + a minimum of 1.5GB of RAM, and for a site with heavy traffic, 4GB to 8GB.</p> + +<p>If performance isn't that critical on your installation, you don't + have the memory, or you are running some other web server than + Apache, [% terms.Bugzilla %] still runs perfectly as a normal CGI + application, as well.</p> + +<h3><a name="v30_feat_sq"></a>Shared Saved Searches</h3> + +<p>Users can now choose to "share" their saved searches + with a certain group. That group will then be able to + "subscribe" to those searches, and have them appear + in their footer.</p> + +<p>If the sharer can "bless" the group he's sharing to, + (that is, if he can add users to that group), it's considered + that he's a manager of that group, and his queries show up + automatically in that group's footer (although they can + unsubscribe from any particular search, if they want.)</p> + +<p>In order to allow a user to share their queries, they also + have to be a member of the group specified in the + <code>querysharegroup</code> parameter.</p> + +<p>Users can control their shared and subscribed queries from + the "Preferences" screen.</p> + +<h3><a name="v30_feat_afn"></a>Attachments and Flags on New + [% terms.Bugs %]</h3> + +<p>You can now add an attachment while you are filing a new + [% terms.bug %].</p> + +<p>You can also set flags on the [% terms.bug %] and on attachments, while + filing a new [% terms.bug %].</p> + +<h3><a name="v30_feat_cr"></a>Custom Resolutions</h3> + +<p>You can now customize the list of resolutions available + in [% terms.Bugzilla %], including renaming the default resolutions.</p> + +<p>The resolutions <code>FIXED</code>, <code>DUPLICATE</code> + and <code>MOVED</code> have a special meaning to [% terms.Bugzilla %], + though, and cannot be renamed or deleted.</p> + +<h3><a name="v30_feat_ppp"></a>Per-Product Permissions</h3> + +<p>You can now grant users <kbd>editbugs</kbd> and <kbd>canconfirm</kbd> + for only certain products. You can also grant users <kbd>editcomponents</kbd> + on a product, which means they will be able to edit that product + including adding/removing components and other product-specific + controls.</p> + +<h3><a name="v30_feat_ui"></a>User Interface Improvements</h3> + +<p>There has been some work on the user interface for [% terms.Bugzilla %] 3.0, + including:</p> + +<ul> + <li>There is now navigation and a search box a the <em>top</em> of + each page, in addition to the bar at the bottom of the page.</li> + <li>A re-designed "Format for Printing" page for + [% terms.bugs %].</li> + <li>The layout of <kbd>show_bug.cgi</kbd> (the [% terms.bug %] editing + page) has been changed, and the attachment table has been redesigned.</li> +</ul> + +<h3><a name="v30_feat_xml"></a>XML-RPC Interface</h3> + +<p>[% terms.Bugzilla %] now has a Web Services interface using the XML-RPC + protocol. It can be accessed by external applications by going + to the <kbd>xmlrpc.cgi</kbd> on your installation.</p> + +<p>Documentation can be found in the + <a href="[% Param('docs_urlbase') FILTER html %]api/">[% terms.Bugzilla %] + API Docs</a>, in the various <kbd>Bugzilla::WebService</kbd> modules.</p> + +<h3><a name="v30_feat_skin"></a>Skins</h3> + +<p>[% terms.Bugzilla %] can have multiple "skins" installed, + and users can pick between them. To write a skin, you just have to + write several CSS files. See the <a href="[% Param('docs_urlbase') FILTER html %]cust-skins.html">Custom + Skins Documentation</a> for more details.</p> + +<p>We currently don't have any alternate skins shipping with + [% terms.Bugzilla %]. If you write an alternate skin, please + let us know!</p> + +<h3><a name="v30_feat_sbu"></a>Unchangeable Fields Appear + Unchangeable</h3> + +<p>As long as you are logged in, when viewing [% terms.abug %], if you + cannot change a field, it will not look like you can change it. That + is, the value will just appear as plain text.</p> + +<h3><a name="v30_feat_et"></a>All Emails in Templates</h3> + +<p>All outbound emails are now controlled by the templating system. + What used to be the <code>passwordmail</code>, <code>whinemail</code>, + <code>newchangedmail</code> and <code>voteremovedmail</code> + parameters are now all templates in the <kbd>template/</kbd> directory.</p> + +<p>This means that it's now much easier to customize your outbound + emails, and it's also possible for localizers to have more + localized emails as part of their language packs, if they want.</p> + +<p>We also added a <code>mailfrom</code> parameter to let you set + who shows up in the <code>From</code> field on all emails that + [%+ terms.Bugzilla %] sends.</p> + +<h3><a name="v30_feat_df"></a>No More Double-Filed [% terms.Bugs %]</h3> + +<p>Users of [% terms.Bugzilla %] will sometimes accidentally submit + [% terms.abug %] twice, either by going back in their web browser, + or just by refreshing a page. In the past, this could file the same + [% terms.bug %] twice (or even three times) in a row, irritating + developers and confusing users.</p> + +<p>Now, if you try to submit [% terms.abug %] twice from the same screen + (by going back or by refreshing the page), [% terms.Bugzilla %] will warn + you about what you're doing, before it actually submits the duplicate + [%+ terms.bug %].</p> + +<h3><a name="v30_feat_cc"></a>Default CC List for Components</h3> + +<p>You can specify a list of users who will <em>always</em> be added to + the CC list of new [% terms.bugs %] in a component.</p> + +<h3><a name="v30_feat_emi"></a>File/Modify [% terms.Bugs %] By Email</h3> + +<p>You can now file or modify [% terms.bugs %] via email. Previous versions + of [% terms.Bugzilla %] included this feature only as an + unsupported add-on, but it is now an official interface to + [%+ terms.Bugzilla %].</p> + +<p>For more details see the <a href="[% Param('docs_urlbase') FILTER html %]api/email_in.html">documentation + for email_in.pl</a>.</p> + +<h3><a name="v30_feat_gw"></a>Users Who Get All [% terms.Bug %] + Notifications</h3> + +<p>There is now a parameter called <kbd>globalwatchers</kbd>. This + is a comma-separated list of [% terms.Bugzilla %] users who will + get all [% terms.bug %] notifications generated by [% terms.Bugzilla %].</p> + +<p>Group controls still apply, though, so users who can't see a [% terms.bug %] + still won't get notifications about that [% terms.bug %].</p> + +<h3><a name="v30_feat_utf8"></a>Improved UTF-8 Support</h3> + +<p>[% terms.Bugzilla %] users running MySQL should now have excellent + UTF-8 support if they turn on the <kbd>utf8</kbd> parameter. (New + installs have this parameter on by default.) [% terms.Bugzilla %] + now correctly supports searching and sorting in non-English languages, + including multi-bytes languages such as Chinese.</p> + +<h3><a name="v30_feat_upda"></a>Automatic Update Notification</h3> + +<p>If you belong to the <kbd>admin</kbd> group, you will be notified + when you log in if there is a new release of [% terms.Bugzilla %] + available to download.</p> + +<p>You can control these notifications by changing the + <kbd>upgrade_notification</kbd> parameter.</p> + +<p>If your [% terms.Bugzilla %] installation is on a machine that needs to go + through a proxy to access the web, you may also have to set the + <kbd>proxy_url</kbd> parameter.</p> + +<h3><a name="v30_feat_welc"></a>Welcome Page for New Installs</h3> + +<p>When you log in for the first time on a brand-new [% terms.Bugzilla %] + installation, you will be presented with a page that describes + where you should go from here, and what parameters you should set.</p> + +<h3><a name="v30_feat_qs"></a>QuickSearch Plugin for IE7 and Firefox 2</h3> + +<p>Firefox 2 users and Internet Explorer 7 users will be presented + with the option to add [% terms.Bugzilla %] to their search bar. + This uses the + <a href="page.cgi?id=quicksearch.html">QuickSearch syntax</a>.</p> + +<h3><a name="v30_feat_other"></a>Other Enhancements and Changes</h3> + +<p>These are either minor enhancements, or enhancements that have + very short descriptions. Some of these are very useful, though!</p> + +<h4>Enhancements That Affect [% terms.Bugzilla %] Users</h4> + +<ul> + <li>In comments, quoted text (lines that start with <kbd>></kbd>) + will be a different color from normal text.</li> + <li>There is now a user preference that will add you to the CC list + of any [% terms.bug %] you modify. Note that it's <strong>on</strong> + by default.</li> + <li>[% terms.Bugs %] can now be filed with an initial state of + <kbd>ASSIGNED</kbd>, if you are in the <kbd>editbugs</kbd> group.</li> + <li>By default, comment fields will zoom large when you are typing in them, + and become small when you move out of them. You can disable this + in your user preferences.</li> + <li>You can hide obsolete attachments on [% terms.abug %] by clicking + "Hide Obsolete" at the bottom of the attachment table.</li> + <li>If a [% terms.bug %] has flags set, and you move it to a different + product that has flags with the same name, the flags will be + preserved.</li> + <li>You now can't request a flag to be set by somebody who can't set it + ([% terms.Bugzilla %] will throw an error if you try).</li> + <li>Many new headers have been added to outbound [% terms.Bugzilla %] + [%+ terms.bug %] emails: <code>X-Bugzilla-Status</code>, + <code>X-Bugzilla-Priority</code>, <code>X-Bugzilla-Assigned-To</code>, + <code>X-Bugzilla-Target-Milestone</code>, and + <code>X-Bugzilla-Changed-Fields</code>, <code>X-Bugzilla-Who</code>. + You can look at an email to get an idea of what they contain.</li> + <li>In addition to the old <code>X-Bugzilla-Reason</code> email header + which tells you why you got an email, if you got an email because + you were watching somebody, there is now an + <code>X-Bugzilla-Watch-Reason</code> header that tells you who you + were watching and what role they had.</li> + <li>If you hover your mouse over a full URL (like + <code>http://bugs.mycompany.com/show_bug.cgi?id=1212</code>) that + links to [% terms.abug %], you will see the title of the + [%+ terms.bug %]. Of course, this only works for [% terms.bugs %] in your + [%+ terms.Bugzilla %] installation.</li> + <li>If your installation has user watching enabled, you will now see + the users that you can remove from your watch-list as a multi-select + box, much like the current CC list. (Previously it was just a text + box.)</li> + <li>When a user creates their own account in [% terms.Bugzilla %], the + account is now not actually created until they verify their email + address by clicking on a link that is emailed to them.</li> + <li>You can change [% terms.abug %]'s resolution without reopening it.</li> + <li>When you view the dependency tree on [% terms.abug %], resolved + [%+ terms.bugs %] will be hidden by default. (In previous versions, + resolved [% terms.bugs %] were shown by default.)</li> + <li>When viewing [% terms.bug %] activity, fields that hold [% terms.bug %] + numbers (such as "Blocks") will have the [% terms.bug %] numbers + displayed as links to those [% terms.bugs %].</li> + <li>When viewing the "Keywords" field in a [% terms.bug %] list, + it will be sorted alphabetically, so you can sanely sort a list on + that field.</li> + <li>In most places, the Version field is now sorted using a version-sort + (so 1.10 is greater than 1.2) instead of an alphabetical sort.</li> + <li>Options for flags will only appear if you can set them. So, for + example, if you can't grant <kbd>+</kbd> on a flag, that option + won't appear for you.</li> + <li>You can limit the product-related output of <kbd>config.cgi</kbd> + by specifying a <kbd>product=</kbd> URL argument, containing the name + of a product. You can specify the argument more than once for multiple + products.</li> + <li>You can now search the boolean charts on whether or not a comment + is private.</li> +</ul> + +<h4>Enhancements For Administrators</h4> + +<ul> + <li>Administrators can now delete attachments, making them disappear + entirely from [% terms.Bugzilla %].</li> + <li><kbd>sanitycheck.cgi</kbd> can now only be accessed by users + in the <kbd>editcomponents</kbd> group.</li> + <li>The "Field Values" control panel can now only be accessed + by users in the <kbd>admin</kbd> group. (Previously it was accessible + to anybody in the <kbd>editcomponents</kbd> group.)</li> + <li>There is a new parameter <kbd>announcehtml</kbd>, that will allow + you to enter some HTML that will be displayed at the top of every + page, as an announcement.</li> + <li>The <kbd>loginnetmask</kbd> parameter now defaults to 0 for new + installations, meaning that as long as somebody has the right + login cookie, they can log in from any IP address. This makes + life a lot easier for dial-up users or other users whose IP + changes a lot. This could be done because the login cookie is now + very random, and thus secure.</li> + <li>Classifications now have sortkeys, so they can be sorted in an + order that isn't alphabetical.</li> + <li>Authentication now supports LDAP over SSL (LDAPS) or TLS (using + the STARTLS command) in addition to plain LDAP.</li> + <li>LDAP users can have their LDAP username be their email address, + instead of having the LDAP <kbd>mail</kbd> attribute be their + email address. You may wish to set the <kbd>emailsuffix</kbd> + parameter if you do this.</li> + <li>Administrators can now see what has changed in a user account, + when using the "Users" control panel.</li> + <li><code>REMIND</code> and <code>LATER</code> are no longer part + of the default list of resolutions. Upgrading installations will + not be affected--they will still have these resolutions.</li> + <li><kbd>editbugs</kbd> is now the default for the <kbd>timetrackinggroup</kbd> + parameter, meaning that time-tracking will be on by default in a new + installation.</li> +</ul> + +<h2><a name="v30_issues"></a>Outstanding Issues</h2> + +<ul> + <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=370739"> + [%- terms.Bug %] 370739</a>: There is a problem in Firefox 2.0 that + sometimes causes the [% terms.bug %] editing page to render incorrectly + after editing a [% terms.bug %].</li> + <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=69621"> + [%- terms.Bug %] 69621</a>: If you rename or remove a keyword that is + in use on [% terms.bugs %], you will need to rebuild the "keyword cache" + by running <a href="sanitycheck.cgi">sanitycheck.cgi</a> and choosing + the option to rebuild the cache when it asks. Otherwise keywords may + not show up properly in search results.</li> + <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=99215"> + [%- terms.Bug %] 99215</a>: Flags are not protected by "mid-air + collision" detection. Nor are any attachment changes.</li> + <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=89822"> + [%- terms.Bug %] 89822</a>: When changing multiple [% terms.bugs %] at + the same time, there is no "mid-air collision" protection.</li> + <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=276230"> + [%- terms.Bug %] 276230</a>: The support for restricting access to + particular Categories of New Charts is not complete. You should treat + the 'chartgroup' Param as the only access mechanism available.<br> + However, charts migrated from Old Charts will be restricted to + the groups that are marked MANDATORY for the corresponding Product. + There is currently no way to change this restriction, and the + groupings will not be updated if the group configuration + for the Product changes.</li> + <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=370370"> + [%- terms.Bug %] 370370</a>: mod_perl support may currently not + be working on Windows machines. Also, even when it does work, + editparams.cgi seems to crash on certain versions of mod_perl.</li> + <li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=361149"> + [%- terms.Bug %] 361149</a>: If you are using Perl 5.8.0, you may + get a lot of warnings in your Apache error_log about "deprecated + pseudo-hashes." These are harmless--they are a b[%# fool test %]ug in + Perl 5.8.0. Perl 5.8.1 and later do not have this problem.</li> + <li>[% terms.Bugzilla %] 3.0rc1 allowed custom field column names in + the database to be mixed-case. [% terms.Bugzilla %] 3.0 only allows + lowercase column names. It will fix any column names that you have + made mixed-case, but if you have custom fields that previously were + mixed-case in any Saved Search, you will have to re-create that Saved + Search yourself.</li> +</ul> + +<h2><a name="v30_upgrading"></a>How to Upgrade From An Older Version</h2> + +<h3>Notes For Upgraders</h3> + +<ul> + <li>If you upgrade by CVS, there are several .cvsignore files + that are now in CVS instead of being locally created by + <kbd>checksetup.pl</kbd>. This means that you will have to + delete those files when CVS tells you there's a conflict, and + then run <kbd>cvs update</kbd> again.</li> + <li>In this version of [% terms.Bugzilla %], the Summary field + is now limited to 255 characters. When you upgrade, any Summary + longer than that will be truncated, and the old summary will be + preserved in a comment.</li> + <li>If you have the <kbd>utf8</kbd> parameter turned on, at some + point you will have to convert your database. <kbd>checksetup.pl</kbd> + will tell you when this is, and it will give you certain instructions + at that time, that you have to follow before you can complete + the upgrade. Don't do the conversion yourself manually--follow + the instructions of checksetup.pl.</li> + <li>If you ever ran 2.23.3, 2.23.4, or 3.0rc1, you will have to run + <kbd>./collectstats.pl --regenerate</kbd> at the command line, because + the data for your Old Charts is corrupted. This can take several days, + so you may only want to run it if you use Old Charts.</li> + <li>You should also read the Outstanding Issues sections of + <a href="#v30_previous">older release notes</a> if you are upgrading + from a version lower than 2.22.</li> +</ul> + +<h3>Steps For Upgrading</h3> + +<ol> + <li>Read these entire Release Notes, particularly the "Notes for + Upgraders" section above.</li> + + <li>View the <a href="sanitycheck.cgi">Sanity Check</a> page on your + installation before upgrading. Attempt to fix all warnings that + the page produces before you go any further, or you may experience + problems during your upgrade.</li> + + <li>Make a backup of the [% terms.Bugzilla %] database before you upgrade, + perhaps by using <kbd>mysqldump</kbd>. <strong>THIS IS VERY + IMPORTANT</strong>. If anything goes wrong during the upgrade, your + installation can be corrupted beyond recovery. Having a backup keeps you + safe. + + <p>Example: <kbd>mysqldump -u root -p bu[%# trick filter %]gs > + bu[%# trick filter %]gs-db.sql</kbd></p></li> + + <li>Replace the files in your installation with the new version of + [% terms.Bugzilla %], or you can try to use CVS to upgrade. + + <p>You can also use a brand-new [% terms.Bugzilla %] directory, as long + as you copy over the old <kbd>data/</kbd> directory and the + <kbd>localconfig</kbd> file to the new installation.</p></li> + + <li>Now follow the standard + <a href="[% Param('docs_urlbase') FILTER html %]installing-bugzilla.html"> + [%- terms.Bugzilla %] installation process</a>.</li> + + <li>Run <kbd>checksetup.pl</kbd> after you install the new version.</li> + + <li>View the <a href="sanitycheck.cgi">Sanity Check</a> page again after + you run <kbd>checksetup.pl</kbd>.</li> + + <li>It is recommended that, if possible, you fix any problems you find + immediately. Failure to do this may mean that [% terms.Bugzilla %] will + not work correctly. Be aware that if the sanity check page contains more + errors after an upgrade, it doesn't necessarily mean there are more + errors in your database than there were before, as additional tests + are added to the sanity check over time, and it is possible that those + errors weren't being checked for in the old version.</li> +</ol> + +<h2><a name="v30_code_changes"></a>Code Changes Which May Affect + Customizations</h2> + +<ul> + <li><a href="#v30_code_loc"><strong>Packagers:</strong> Location + Variables Have Moved</a></li> + <li><a href="#v30_code_hooks">Hooks!</a></li> + <li><a href="#v30_code_api">API Documentation</a></li> + <li><a href="#v30_code_globals">Elimination of globals.pl</a></li> + <li><a href="#v30_code_scope">Cleaned Up Variable Scoping Issues</a></li> + <li><a href="#v30_code_sql">No More SendSQL</a></li> + <li><a href="#v30_code_auth">Auth Re-write</a></li> + <li><a href="#v30_code_obj">Bugzilla::Object</a></li> + <li><a href="#v30_code_req">Bugzilla->request_cache</a></li> + <li><a href="#v30_code_other">Other Changes</a></li> +</ul> + +<h3><a name="v30_code_loc"></a><strong>Packagers:</strong> Location + Variables Have Moved</h3> + +<p>In previous versions of [% terms.Bugzilla %], <kbd>Bugzilla::Config</kbd> + held all the paths for different things, such as the path to localconfig + and the path to the <kbd>data/</kbd> directory.</p> + +<p>Now, all of this data is stored in a subroutine, + <kbd>Bugzilla::Constants::bz_locations</kbd>.</p> + +<p>Also, note that for mod_perl, <kbd>bz_locations</kbd> must return + <em>absolute</em> (not relative) paths. There is already code in that + subroutine to help you with this.</p> + +<h3><a name="v30_code_hooks"></a>Hooks!</h3> + +<p>[% terms.Bugzilla %] now supports a code hook mechanism. See the + documentation for + <a href="[% Param('docs_urlbase') FILTER html %]api/Bugzilla/Hook.html">Bugzilla::Hook</a> + for more details.</p> + +<p>This gives [% terms.Bugzilla %] very advanced plugin support. You can + hook templates, hook code, add new parameters, and use the XML-RPC + interface. So we'd like to see some [% terms.Bugzilla %] plugins + written! Let us know on the <a href="http://bugzilla.org/cgi-bin/mj_wwwusr?func=lists-long-full&extra=developers">developers@bugzilla.org</a> + mailing list if you write a plugin.</p> + +<p>If you need more hooks, please + <a href="http://www.bugzilla.org/developers/reporting_bugs.html">File a + bug</a>!</p> + +<h3><a name="v30_code_api"></a>API Documentation</h3> + +<p>[% terms.Bugzilla %] now ships with all of its perldoc built + as HTML. Go ahead and read the + <a href="[% Param('docs_urlbase') FILTER html %]api/">API Documentation</a> + for all of the [% terms.Bugzilla %] modules now! Even scripts like + <kbd>checksetup.pl</kbd> have HTML documentation.</p> + +<h3><a name="v30_code_globals"></a>Elimination of globals.pl</h3> + +<p>The old file <kbd>globals.pl</kbd> has been eliminated. + Its code is now in various modules. Each function went to the module + that was appropriate for it.</p> + +<p>Usually we filed [% terms.abug %] in + <a href="https://bugzilla.mozilla.org">bugzilla.mozilla.org</a> for + each function we moved. You can search there for the old name of + the function, and that should get you the information about what + it's called now and where it lives.</p> + +<h3><a name="v30_code_scope"></a>Cleaned Up Variable Scoping Issues</h3> + +<p>In normal perl, you can have code like this:</p> +<pre>my $var = 0; +sub y { $var++ }</pre> + +<p>However, under mod_perl that doesn't work. So variables are no + longer "shared" with subroutines--instead all variables + that a subroutine needs must be declared inside the subroutine itself.</p> + +<h3><a name="v30_code_sql"></a>No More SendSQL</h3> + +<p>The old <kbd>SendSQL</kbd> function and all of its companions are + <strong>gone</strong>. Instead, we now use DBI for all database + interaction.</p> + +<p>For more information about how to use + <a href="http://search.cpan.org/perldoc?DBI">DBI</a> with + [% terms.Bugzilla %], see the + <a href="http://www.bugzilla.org/docs/developer.html#sql-sendreceive">Developer's + Guide Section About DBI</a></p> + +<h3><a name="v30_code_auth"></a>Auth Re-write</h3> + +<p>The <kbd>Bugzilla::Auth</kbd> family of modules have been completely + re-written. For details on how the new structure of authentication, + read the + <a href="[% Param('docs_urlbase') FILTER html %]api/Bugzilla/Auth.html">Bugzilla::Auth + API docs</a>.</p> + +<p>It should be very easy to write new authentication plugins, now.</p> + +<h3><a name="v30_code_obj"></a>Bugzilla::Object</h3> + +<p>There is a new base class for most of our objects, + <a href="[% Param('docs_urlbase') FILTER html %]api/Bugzilla/Object.html">Bugzilla::Object</a>. + It makes it really easy to create new objects based on things that are + in the database.</p> + +<h3><a name="v30_code_req"></a>Bugzilla->request-cache</h3> + +<p><kbd>Bugzilla.pm</kbd> used to cache things like the database + connection in package-global variables (like <kbd>$_dbh</kbd>). + That doesn't work in mod_perl, so instead now there's a hash + that can be accessed through <code>Bugzilla->request_cache</code> + to store things for the rest of the current page request.</p> + +<p>You shouldn't access <code>Bugzilla->request_cache</code> directly, + but you should use it inside of <kbd>Bugzilla.pm</kbd> if you modify + that. The only time you should be accessing it directly is if you need + to reset one of the caches. Hash keys are always named after the function + that they cache, so to reset the template object, you'd do: + <code>delete Bugzilla->request_cache->{template};</code>.</p> + +<h3><a name="v30_code_other"></a>Other Changes</h3> + +<ul> + <li><code>checksetup.pl</code> has been completely re-written, and most + of its code moved into modules in the <kbd>Bugzilla::Install</kbd> + namespace. See the + <a href="[% Param('docs_urlbase') FILTER html %]api/checksetup.html">checksetup + documentation</a> and <a href="https://bugzilla.mozilla.org/showdependencytree.cgi?id=277502&hide_resolved=0">[% terms.Bugzilla %] + [%+ terms.bug %] 277502</a> for details.</li> + <li>Instead of <kbd>UserInGroup()</kbd>, all of [% terms.Bugzilla %] now + uses <kbd>Bugzilla->user->in_group</kbd></li> + <li>mod_perl doesn't like dependency loops in modules, so we now have + a test for that detects dependency loops in modules when you run + <kbd>runtests.pl</kbd>.</li> + <li><kbd>globals.pl</kbd> used to modify the environment variables, + like <kbd>PATH</kbd>. That now happens in <kbd>Bugzilla.pm</kbd>.</li> + <li>Templates can now link to the documentation more easily. + See the <kbd>global/code-error.html.tmpl</kbd> and + <kbd>global/user-error.html.tmpl</kbd> templates for examples. + (Search for "docslinks.")</li> + <li>Parameters are accessed through <kbd>Bugzilla->params</kbd> + instead of using the <kbd>Param()</kbd> function, now.</li> + <li>The variables from the <kbd>localconfig</kbd> file are accessed + through the <code>Bugzilla->localconfig</code> hash instead of through + <kbd>Bugzilla::Config</kbd>.</li> + <li><kbd>Bugzilla::BugMail::MessageToMTA()</kbd> has moved into its + own module, along with other mail-handling code, called + <kbd>Bugzilla::Mailer</kbd></li> + <li>The <kbd>CheckCanChangeField()</kbd> subroutine in + <kbd>process_bug.cgi</kbd> has been moved to <kbd>Bugzilla::Bug</kbd>, + and is now a method of a [% terms.bug %] object.</li> + <li>The code that used to be in the <kbd>global/banner.html.tmpl</kbd> + template is now in <kbd>global/header.html.tmpl</kbd>. The banner + still exists, but the file is empty.</li> +</ul> + +<h2><a name="v30_previous"></a>Release Notes For Previous Versions</h2> + +<p>Release notes for versions of [% terms.Bugzilla %] for versions + prior to 3.0 are only available in text format: + <a href="docs/rel_notes.txt">Release Notes for [% terms.Bugzilla %] 2.22 + and Earlier</a>.</p> + +[% INCLUDE global/footer.html.tmpl %] + +[% BLOCK db_req %] + [% SET m = DB_MODULE.$db %] + <h3><a name="v30_req_[% db FILTER html %]"></a>For [% m.name FILTER html %] + Users</h3> + + <ul> + <li>[% m.name FILTER html %] v[% m.db_version FILTER html %]</li> + <li><strong>perl module:</strong> + [%+ m.dbd.module FILTER html %] v[% m.dbd.version FILTER html %]</li> + </ul> +[% END %] + + +[% BLOCK req_table %] + <table class="req_table" border="0" cellspacing="0" cellpadding="0"> + <tr> + <th>Module</th> <th>Version</th> + [% IF include_feature %] + <th>Enables Feature</th> + [% END %] + </tr> + [% FOREACH req = reqs %] + <tr> + <td [% 'class="req_new"' IF new.contains(req.package) %]> + [%- req.module FILTER html %]</td> + <td [% 'class="req_new"' IF updated.contains(req.package) + OR new.contains(req.package) %]> + [%- IF req.version == 0 %] + (Any) + [% ELSE %] + [%- req.version FILTER html %] + [% END %] + </td> + [% IF include_feature %] + <td>[% req.feature FILTER html %]</td> + [% END %] + </tr> + [% END %] +</table> +[% END %] diff --git a/template/en/default/pages/voting.html.tmpl b/template/en/default/pages/voting.html.tmpl index f1d768307..bec38b4ae 100644 --- a/template/en/default/pages/voting.html.tmpl +++ b/template/en/default/pages/voting.html.tmpl @@ -25,13 +25,18 @@ <p>[% terms.Bugzilla %] has a "voting" feature. Each product allows users to have a certain number of votes. (Some products may not allow any, which means -you can't vote on things in that product at all.) With your vote, you indicate -which [% terms.bugs %] you think are the most important to be fixed.</p> +you can't vote on things in those products at all.) With your vote, you +indicate which [% terms.bugs %] you think are the most important and +would like to see fixed. Note that voting is nowhere near as effective +as providing a fix yourself.</p> <p>Depending on how the administrator has configured the relevant product, -you may be able to vote for the same [% terms.bug %] more than one time. But -remember, you only have so many votes to use in total! So, you can either vote -a little for many [% terms.bugs %], or vote a lot for a few [% terms.bugs %]. +you may be able to vote for the same [% terms.bug %] more than once. +Remember that you have a limited number of votes. When weighted voting +is allowed and a limited number of votes are available to you, you will +have to decide whether you want to distribute your votes among a large +number of [% terms.bugs %] indicating your minimal interest or focus on +a few [% terms.bugs %] indicating your strong support for them. </p> <p>To look at votes:</p> diff --git a/template/en/default/reports/CVS/Entries b/template/en/default/reports/CVS/Entries index 5b3eb5c78..6f2ee38e5 100644 --- a/template/en/default/reports/CVS/Entries +++ b/template/en/default/reports/CVS/Entries @@ -1,23 +1,24 @@ -/chart.csv.tmpl/1.2/Wed Jul 20 02:14:34 2005//TBUGZILLA-2_22_3 -/chart.html.tmpl/1.2/Sun Jan 18 18:39:30 2004//TBUGZILLA-2_22_3 -/chart.png.tmpl/1.4.2.1/Thu May 10 11:15:30 2007//TBUGZILLA-2_22_3 -/components.html.tmpl/1.9.4.2/Sat Oct 14 20:50:44 2006//TBUGZILLA-2_22_3 -/create-chart.html.tmpl/1.11/Fri Feb 25 15:27:26 2005//TBUGZILLA-2_22_3 -/duplicates-simple.html.tmpl/1.4/Sun Jan 18 18:39:30 2004//TBUGZILLA-2_22_3 -/duplicates-table.html.tmpl/1.12/Mon Jan 9 21:54:17 2006//TBUGZILLA-2_22_3 -/duplicates.html.tmpl/1.15.2.1/Sat Oct 14 20:50:44 2006//TBUGZILLA-2_22_3 -/duplicates.rdf.tmpl/1.2/Thu Aug 4 11:51:25 2005//TBUGZILLA-2_22_3 -/edit-series.html.tmpl/1.5/Thu Feb 12 22:32:57 2004//TBUGZILLA-2_22_3 -/keywords.html.tmpl/1.6.12.1/Sat Oct 14 20:30:58 2006//TBUGZILLA-2_22_3 -/menu.html.tmpl/1.6/Tue Jul 6 01:12:29 2004//TBUGZILLA-2_22_3 -/report-bar.png.tmpl/1.5/Wed Jul 20 12:39:48 2005//TBUGZILLA-2_22_3 -/report-line.png.tmpl/1.6/Wed Jul 20 12:39:48 2005//TBUGZILLA-2_22_3 -/report-pie.png.tmpl/1.4/Wed Jul 20 12:39:48 2005//TBUGZILLA-2_22_3 -/report-simple.html.tmpl/1.1.6.1/Thu May 10 11:15:30 2007//TBUGZILLA-2_22_3 -/report-table.csv.tmpl/1.8/Thu Nov 17 09:16:02 2005//TBUGZILLA-2_22_3 -/report-table.html.tmpl/1.11/Tue Jun 14 22:43:12 2005//TBUGZILLA-2_22_3 -/report.csv.tmpl/1.2/Mon Jan 6 07:54:22 2003//TBUGZILLA-2_22_3 -/report.html.tmpl/1.10/Sun Jan 18 18:39:30 2004//TBUGZILLA-2_22_3 -/series-common.html.tmpl/1.3/Tue Sep 14 23:30:20 2004//TBUGZILLA-2_22_3 -/series.html.tmpl/1.6/Tue Sep 14 23:30:20 2004//TBUGZILLA-2_22_3 +/chart.csv.tmpl/1.2/Wed Jul 20 02:14:34 2005//TBUGZILLA-3_0 +/chart.html.tmpl/1.3/Tue Oct 17 19:58:38 2006//TBUGZILLA-3_0 +/chart.png.tmpl/1.4/Thu Dec 29 23:56:32 2005//TBUGZILLA-3_0 +/components.html.tmpl/1.12/Sat Oct 14 20:26:54 2006//TBUGZILLA-3_0 +/create-chart.html.tmpl/1.15/Mon Jan 8 00:56:45 2007//TBUGZILLA-3_0 +/duplicates-simple.html.tmpl/1.4/Sun Jan 18 18:39:30 2004//TBUGZILLA-3_0 +/duplicates-table.html.tmpl/1.13/Sun Sep 10 13:33:02 2006//TBUGZILLA-3_0 +/duplicates.html.tmpl/1.17/Sat Oct 14 20:48:48 2006//TBUGZILLA-3_0 +/duplicates.rdf.tmpl/1.2/Thu Aug 4 11:51:25 2005//TBUGZILLA-3_0 +/edit-series.html.tmpl/1.6/Tue Oct 17 19:58:38 2006//TBUGZILLA-3_0 +/keywords.html.tmpl/1.9/Sat Oct 14 20:26:54 2006//TBUGZILLA-3_0 +/menu.html.tmpl/1.7/Mon Sep 4 16:21:49 2006//TBUGZILLA-3_0 +/old-charts.html.tmpl/1.1/Thu Aug 3 17:54:04 2006//TBUGZILLA-3_0 +/report-bar.png.tmpl/1.6/Thu Jul 13 18:00:42 2006//TBUGZILLA-3_0 +/report-line.png.tmpl/1.7/Thu Jul 13 18:00:42 2006//TBUGZILLA-3_0 +/report-pie.png.tmpl/1.5/Thu Jul 13 18:00:43 2006//TBUGZILLA-3_0 +/report-simple.html.tmpl/1.1/Mon Mar 14 16:24:03 2005//TBUGZILLA-3_0 +/report-table.csv.tmpl/1.9/Thu Jul 13 18:00:43 2006//TBUGZILLA-3_0 +/report-table.html.tmpl/1.13/Fri Aug 18 17:43:41 2006//TBUGZILLA-3_0 +/report.csv.tmpl/1.2/Mon Jan 6 07:54:22 2003//TBUGZILLA-3_0 +/report.html.tmpl/1.13/Sun Oct 22 22:32:01 2006//TBUGZILLA-3_0 +/series-common.html.tmpl/1.4/Tue Apr 18 07:58:51 2006//TBUGZILLA-3_0 +/series.html.tmpl/1.8/Mon Sep 4 16:21:49 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/reports/CVS/Tag b/template/en/default/reports/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/reports/CVS/Tag +++ b/template/en/default/reports/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/reports/chart.html.tmpl b/template/en/default/reports/chart.html.tmpl index 8547c3592..821b6b0b6 100644 --- a/template/en/default/reports/chart.html.tmpl +++ b/template/en/default/reports/chart.html.tmpl @@ -28,7 +28,7 @@ [% PROCESS global/header.html.tmpl title = "Chart" - h3 = time2str("%Y-%m-%d %H:%M:%S", time) + header_addl_info = time2str("%Y-%m-%d %H:%M:%S", time) %] <div align="center"> diff --git a/template/en/default/reports/chart.png.tmpl b/template/en/default/reports/chart.png.tmpl index a3933e4b7..119ff344f 100644 --- a/template/en/default/reports/chart.png.tmpl +++ b/template/en/default/reports/chart.png.tmpl @@ -19,7 +19,7 @@ # Contributor(s): Gervase Markham <gerv@gerv.net> #%] -[% y_label = "$terms.Bugs" %] +[% y_label = "Bugs" %] [% x_label = "Time" %] [% IF chart.cumulate %] diff --git a/template/en/default/reports/components.html.tmpl b/template/en/default/reports/components.html.tmpl index 0a315498d..d135a7ef8 100644 --- a/template/en/default/reports/components.html.tmpl +++ b/template/en/default/reports/components.html.tmpl @@ -20,18 +20,14 @@ #%] [%# INTERFACE: - # product: string. The product this is the components list for. - # components: List of hashes. May be empty. Each hash has four members: - # name: string. Name of the component. - # description: string. Description of the component. May contain HTML. - # initialowner: string. Component's default assignee. - # initialqacontact: string. Component's default QA contact. + # product: object. The product for which we want to display component descriptions. #%] - -[% filtered_product = product FILTER html %] -[% PROCESS global/header.html.tmpl - title = "Components for $filtered_product" - h2 = filtered_product %] + +[% title = BLOCK %] + Components for [% product.name FILTER html %] +[% END %] + +[% PROCESS global/header.html.tmpl title = title %] [% IF Param("useqacontact") %] [% numcols = 3 %] @@ -39,28 +35,28 @@ [% numcols = 2 %] [% END %] -[% IF components.size == 0 %] - This product has no components. -[% ELSE %] - <table> - <tr> - <th align="left">Component</th> - <th align="left">Default Assignee</th> - [% IF Param("useqacontact") %] - <th align="left">Default QA Contact</th> - [% END %] - </tr> +<p> + [% product.description FILTER html_light %] +</p> - [% FOREACH comp = components %] - [% INCLUDE describe_comp %] +<table> + <tr> + <th align="left">Component</th> + <th align="left">Default Assignee</th> + [% IF Param("useqacontact") %] + <th align="left">Default QA Contact</th> [% END %] - <tr> - <td colspan="[% numcols %]"> - <hr> - </td> - </tr> - </table> -[% END %] + </tr> + + [% FOREACH comp = product.components %] + [% INCLUDE describe_comp %] + [% END %] + <tr> + <td colspan="[% numcols %]"> + <hr> + </td> + </tr> +</table> [% PROCESS global/footer.html.tmpl %] @@ -79,15 +75,13 @@ <a name="[% comp.name FILTER html %]">[% comp.name FILTER html %]</a> </td> <td> - <a href="mailto:[% comp.initialowner FILTER html %] - [% Param('emailsuffix') %]"> - [% comp.initialowner FILTER html %]</a> + <a href="mailto:[% comp.default_assignee.email FILTER html %]"> + [% comp.default_assignee.login FILTER html %]</a> </td> [% IF Param("useqacontact") %] <td> - <a href="mailto:[% comp.initialqacontact FILTER html %] - [% Param('emailsuffix') %]"> - [% comp.initialqacontact FILTER html %]</a> + <a href="mailto:[% comp.default_qa_contact.email FILTER html %]"> + [% comp.default_qa_contact.login FILTER html %]</a> </td> [% END %] </tr> diff --git a/template/en/default/reports/create-chart.html.tmpl b/template/en/default/reports/create-chart.html.tmpl index 005d14752..7001d2c9a 100644 --- a/template/en/default/reports/create-chart.html.tmpl +++ b/template/en/default/reports/create-chart.html.tmpl @@ -70,11 +70,11 @@ function subcatSelected() { </tr> [% ELSE %] <tr> - <th>Category:</th> + <th><label for="category">Category</label>:</th> <th></th> - <th>Sub-category:</th> + <th><label for="subcategory">Sub-category</label>:</th> <th></th> - <th>Name:</th> + <th><label for="name" accesskey="N">Name</label>:</th> <th><br> </th> </tr> @@ -87,7 +87,8 @@ function subcatSelected() { <td> <noscript> - <input type="submit" name="action-assemble" value="Update -->"> + <input type="submit" name="action-assemble" value="Update -->" + id="action-assemble"> </noscript> </td> @@ -97,28 +98,28 @@ function subcatSelected() { <td> <noscript> - <input type="submit" name="action-assemble" value="Update -->"> + <input type="submit" name="action-assemble" value="Update -->" + id="action-assemble"> </noscript> </td> <td align="left"> - <label for="name" accesskey="N"> - <select name="name" id="name" style="width: 15em" - size="5" multiple="multiple" - [%+ "disabled=\"disabled\"" UNLESS name.keys.size %]> - [% FOREACH x = name.keys.sort %] - <option value="[% name.$x FILTER html %]"> - [% x FILTER html %]</option> - [% END %] - [% UNLESS name.keys.size %] - <option value="" disabled="disabled"></option> - [% END %] - </select> - </label> + <select name="name" id="name" style="width: 15em" + size="5" multiple="multiple" + [%+ "disabled=\"disabled\"" UNLESS name.keys.size %]> + [% FOREACH x = name.keys.sort %] + <option value="[% name.$x FILTER html %]"> + [% x FILTER html %]</option> + [% END %] + [% UNLESS name.keys.size %] + <option value="" disabled="disabled"></option> + [% END %] + </select> </td> <td align="center" valign="middle"> - <input type="submit" name="action-add" value="Add To List"><br> + <input type="submit" name="action-add" value="Add To List" + id="action-add"><br> </td> </tr> [% END %] @@ -187,8 +188,8 @@ function subcatSelected() { </td> <td align="center"> - [% IF user.id == series.creator OR UserInGroup("admin") %] - <a href="chart.cgi?action=edit&series_id= + [% IF user.id == series.creator OR user.in_group("admin") %] + <a href="chart.cgi?action=edit&series_id= [% series.series_id %]">Edit</a> | [% END %] <a href="buglist.cgi?cmdtype=dorem&namedcmd= @@ -227,29 +228,30 @@ function subcatSelected() { <tr> <td valign="bottom" style="text-align: center;"> <input type="submit" name="action-sum" value="Sum" - style="width: 5em;"><br> + style="width: 5em;" id="action-sum"><br> <input type="submit" name="action-remove" value="Remove" - style="width: 5em;"> + style="width: 5em;" id="action-remove"> </td> <td style="text-align: right; vertical-align: bottom;"> - <b>Cumulate:</b> - <input type="checkbox" name="cumulate" value="1" + <label for="cumulate"><b>Cumulate</b></label>: + <input type="checkbox" name="cumulate" id="cumulate" value="1" [% " checked" IF chart.cumulate %]> </td> <td></td> - <td valign="bottom"> - <b>Date Range:</b> - <input type="text" size="12" name="datefrom" + <td valign="bottom"> + <label for="datefrom"><b>Date Range</b></label>: + <input type="text" size="12" name="datefrom" id="datefrom" value="[% time2str("%Y-%m-%d", chart.datefrom) IF chart.datefrom%]"> - <b>to</b> - <input type="text" size="12" name="dateto" + <label for="dateto"><b>to</b></label> + <input type="text" size="12" name="dateto" id="dateto" value="[% time2str("%Y-%m-%d", chart.dateto) IF chart.dateto %]"> </td> <td style="text-align: right" valign="bottom"> - <input type="submit" name="action-wrap" value="Chart This List"> + <input type="submit" name="action-wrap" value="Chart This List" + id="action-wrap"> </td> </tr> </table> @@ -258,7 +260,7 @@ function subcatSelected() { [% END %] </form> -[% IF UserInGroup('editbugs') %] +[% IF user.in_group('editbugs') %] <h3><a href="query.cgi?format=create-series">Create New Data Set</a></h3> [% END %] diff --git a/template/en/default/reports/duplicates-table.html.tmpl b/template/en/default/reports/duplicates-table.html.tmpl index 80a85ff3c..eb7eec1cf 100644 --- a/template/en/default/reports/duplicates-table.html.tmpl +++ b/template/en/default/reports/duplicates-table.html.tmpl @@ -118,8 +118,7 @@ <tr [% "class='resolved'" IF bug.resolution != "" %]> <td> <center> - [% isclosed = bug.resolution != "" %] - <a href="show_bug.cgi?id=[% bug.id %]">[% bug.id FILTER closed(isclosed) %]</a> + [% bug.id FILTER bug_link(bug.id) FILTER none %] </center> </td> diff --git a/template/en/default/reports/duplicates.html.tmpl b/template/en/default/reports/duplicates.html.tmpl index 8be0c5517..f60f28558 100644 --- a/template/en/default/reports/duplicates.html.tmpl +++ b/template/en/default/reports/duplicates.html.tmpl @@ -123,13 +123,14 @@ </table> - <input type="submit" value="Change"> + <input type="submit" id="change" value="Change"> </form> <form method="post" action="buglist.cgi"> <input type="hidden" name="bug_id" value="[% bug_ids_string %]"> <input type="hidden" name="order" value="Reuse same sort as last time"> - Or just give this to me as a <input type="submit" value="[% terms.bug %] list">. + Or just give this to me as a <input type="submit" id="list" + value="[% terms.bug %] list">. (Note: the order may not be the same.) </form> diff --git a/template/en/default/reports/edit-series.html.tmpl b/template/en/default/reports/edit-series.html.tmpl index 4d3526e3c..690e24305 100644 --- a/template/en/default/reports/edit-series.html.tmpl +++ b/template/en/default/reports/edit-series.html.tmpl @@ -20,7 +20,7 @@ #%] [% title = "Edit Series" %] -[% h2 = BLOCK %] +[% subheader = BLOCK %] [% default.category FILTER html %] / [%+ default.subcategory FILTER html %] / [%+ default.name FILTER html %] diff --git a/template/en/default/reports/keywords.html.tmpl b/template/en/default/reports/keywords.html.tmpl index 10bfe1e87..1a0ae0bf5 100644 --- a/template/en/default/reports/keywords.html.tmpl +++ b/template/en/default/reports/keywords.html.tmpl @@ -17,13 +17,15 @@ # Rights Reserved. # # Contributor(s): Gervase Markham <gerv@gerv.net> + # Contributor(s): David D. Kilzer <ddkilzer@kilzer.net> #%] [%# INTERFACE: - # keywords: array of hashes. May be empty. Each has has three members: + # keywords: array keyword objects. May be empty. Each has has four members: + # id: id of the keyword # name: the name of the keyword # description: keyword description. Can contain some limited HTML code. - # bugcount: number of bugs with that keyword + # bug_count: number of bugs with that keyword # caneditkeywords: boolean. True if this user can edit keywords %] @@ -43,7 +45,8 @@ <tr bgcolor="#6666FF"> <th align="left">Name</th> <th align="left">Description</th> - <th align="left">[% terms.Bugs %]</th> + <th align="left">Open [% terms.Bugs %]</th> + <th align="left">Total [% terms.Bugs %]</th> </tr> [% END %] @@ -53,10 +56,18 @@ [% keyword.name FILTER html %]</a> </th> <td>[% keyword.description FILTER html_light %]</td> + <td align="center"> + [% IF keyword.bug_count > 0 %] + <a href="buglist.cgi?keywords=[% keyword.name FILTER url_quote %]&resolution=---"> + Search</a> + [% ELSE %] + none + [% END %] + </td> <td align="right"> - [% IF keyword.bugcount > 0 %] + [% IF keyword.bug_count > 0 %] <a href="buglist.cgi?keywords=[% keyword.name FILTER url_quote %]"> - [% keyword.bugcount %]</a> + [% keyword.bug_count %]</a> [% ELSE %] none [% END %] diff --git a/template/en/default/reports/menu.html.tmpl b/template/en/default/reports/menu.html.tmpl index 5ac1516d5..f5c18bee2 100644 --- a/template/en/default/reports/menu.html.tmpl +++ b/template/en/default/reports/menu.html.tmpl @@ -64,7 +64,7 @@ plot the status and/or resolution of [% terms.bugs %] against time, for each product in your database. </li> - [% IF UserInGroup(Param("chartgroup")) %] + [% IF user.in_group(Param("chartgroup")) %] <li> <strong><a href="chart.cgi">New Charts</a></strong> - plot any arbitrary search against time. Far more powerful. diff --git a/template/en/default/reports/old-charts.html.tmpl b/template/en/default/reports/old-charts.html.tmpl new file mode 100644 index 000000000..724dba6c3 --- /dev/null +++ b/template/en/default/reports/old-charts.html.tmpl @@ -0,0 +1,69 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + #%] + +[%# INTERFACE: + # products: an array of product names the user is allowed to view. + # datasets: an array of hashes with available statuses and resolutions. + # url_image: URL of the generated graph. + #%] + +[% PROCESS "global/field-descs.none.tmpl" %] + +[% PROCESS global/header.html.tmpl title = "$terms.Bug Charts" + h1 = "Welcome to the $terms.Bugzilla Charting Kitchen" %] + +<div align="center"> + [% IF url_image %] + <img src="[% url_image FILTER html %]"> + <br clear="both"> + [% ELSE %] + <form id="choose_product" method="get" action="reports.cgi"> + <table border="1" cellpadding="5" cellspacing="2"> + <tr> + <th>Product:</th> + <td align="center"> + <select id="product" name="product"> + [% FOREACH product = products %] + <option value="[% product FILTER html %]">[% product FILTER html %]</option> + [% END %] + </select> + </td> + </tr> + <tr> + <th>Chart datasets:</th> + <td align="center"> + <select id="datasets" name="datasets" multiple="multiple" size="5"> + [%# We cannot use translated statuses and resolutions from field-descs.none.html + # because old charts do not distinguish statuses from resolutions. %] + [% FOREACH dataset = datasets %] + <option value="[% dataset.value FILTER html %]:" + [% " selected=\"selected\"" IF dataset.selected %]> + [% dataset.value FILTER html %]</option> + [% END %] + </select> + </td> + </tr> + <tr> + <th colspan="2"> + <input type="submit" id="submit" value="Continue"> + </th> + </tr> + </table> + </form> + [% END %] +</div> + +[% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/reports/report-bar.png.tmpl b/template/en/default/reports/report-bar.png.tmpl index bb5dab7cd..2c29a3558 100644 --- a/template/en/default/reports/report-bar.png.tmpl +++ b/template/en/default/reports/report-bar.png.tmpl @@ -35,7 +35,7 @@ [% IF col_field == 'resolution' %] [% FOR i IN [ 0 .. data.0.0.max ] %] - [% data.0.0.$i = resolution_descs.${data.0.0.$i} %] + [% data.0.0.$i = get_resolution(data.0.0.$i) %] [% END %] [% END %] @@ -47,7 +47,7 @@ [% IF row_field == 'resolution' %] [% FOR i IN [ 0 .. row_names.max ] %] - [% row_names.$i = resolution_descs.${row_names.$i} %] + [% row_names.$i = get_resolution(row_names.$i) %] [% END %] [% END %] diff --git a/template/en/default/reports/report-line.png.tmpl b/template/en/default/reports/report-line.png.tmpl index 60e9f261a..24215af98 100644 --- a/template/en/default/reports/report-line.png.tmpl +++ b/template/en/default/reports/report-line.png.tmpl @@ -35,7 +35,7 @@ [% IF col_field == 'resolution' %] [% FOR i IN [ 0 .. data.0.0.max ] %] - [% data.0.0.$i = resolution_descs.${data.0.0.$i} %] + [% data.0.0.$i = get_resolution(data.0.0.$i) %] [% END %] [% END %] @@ -47,7 +47,7 @@ [% IF row_field == 'resolution' %] [% FOR i IN [ 0 .. row_names.max ] %] - [% row_names.$i = resolution_descs.${row_names.$i} %] + [% row_names.$i = get_resolution(row_names.$i) %] [% END %] [% END %] diff --git a/template/en/default/reports/report-pie.png.tmpl b/template/en/default/reports/report-pie.png.tmpl index c70b06bcf..3eb73b1b0 100644 --- a/template/en/default/reports/report-pie.png.tmpl +++ b/template/en/default/reports/report-pie.png.tmpl @@ -31,7 +31,7 @@ [% IF col_field == 'resolution' %] [% FOR i IN [ 0 .. data.0.0.max ] %] - [% data.0.0.$i = resolution_descs.${data.0.0.$i} %] + [% data.0.0.$i = get_resolution(data.0.0.$i) %] [% END %] [% END %] diff --git a/template/en/default/reports/report-simple.html.tmpl b/template/en/default/reports/report-simple.html.tmpl index 9ef863835..04db73b76 100644 --- a/template/en/default/reports/report-simple.html.tmpl +++ b/template/en/default/reports/report-simple.html.tmpl @@ -22,7 +22,7 @@ <html> - [% title = "$terms.Bug List" %] + [% title = "Bug List" %] <head> <title>[% title FILTER html %]</title> diff --git a/template/en/default/reports/report-table.csv.tmpl b/template/en/default/reports/report-table.csv.tmpl index 0abb68ece..2f7f867af 100644 --- a/template/en/default/reports/report-table.csv.tmpl +++ b/template/en/default/reports/report-table.csv.tmpl @@ -44,7 +44,7 @@ [% IF col_field == 'bug_status' %] [% status_descs.$col FILTER csv -%] [% ELSIF col_field == 'resolution' %] - [% resolution_descs.$col FILTER csv -%] + [% get_resolution(col) FILTER csv -%] [% ELSE %] [% col FILTER csv -%] [% END %] @@ -57,7 +57,7 @@ [% IF row_field == 'bug_status' %] [% status_descs.$row FILTER csv -%] [% ELSIF row_field == 'resolution' %] - [% resolution_descs.$row FILTER csv -%] + [% get_resolution(row) FILTER csv -%] [% ELSE %] [% row FILTER csv -%] [% END %] diff --git a/template/en/default/reports/report-table.html.tmpl b/template/en/default/reports/report-table.html.tmpl index 0e2ae62c8..60965d502 100644 --- a/template/en/default/reports/report-table.html.tmpl +++ b/template/en/default/reports/report-table.html.tmpl @@ -37,10 +37,10 @@ [% row_field_disp = field_descs.$row_field || row_field %] [% IF tbl == "-total-" %] - [% urlbase = BLOCK %]buglist.cgi?[% buglistbase %] + [% urlbase = BLOCK %]buglist.cgi?[% buglistbase FILTER html %] [% "&$tbl_vals" IF tbl_vals %][% END %] [% ELSE %] - [% urlbase = BLOCK %]buglist.cgi?[% buglistbase %]& + [% urlbase = BLOCK %]buglist.cgi?[% buglistbase FILTER html %]& [% tbl_field FILTER url_quote %]=[% tbl FILTER url_quote %][% END %] [% END %] @@ -88,7 +88,7 @@ [% IF col_field == 'bug_status' %] [% status_descs.$col FILTER html FILTER replace('^ $',' ') %] [% ELSIF col_field == 'resolution' %] - [% resolution_descs.$col FILTER html FILTER replace('^ $',' ') %] + [% get_resolution(col) FILTER html FILTER replace('^ $',' ') %] [% ELSE %] [% col FILTER html FILTER replace('^ $',' ') %] [% END %] @@ -109,7 +109,7 @@ [% IF row_field == 'bug_status' %] [% status_descs.$row FILTER html FILTER replace('^ $',' ') %] [% ELSIF row_field == 'resolution' %] - [% resolution_descs.$row FILTER html FILTER replace('^ $',' ') %] + [% get_resolution(row) FILTER html FILTER replace('^ $',' ') %] [% ELSE %] [% row FILTER html FILTER replace('^ $',' ') %] [% END %] @@ -154,7 +154,6 @@ [% col_field FILTER url_quote %]=[% col FILTER url_quote %] [% "&$row_vals" IF row_vals %]"> [% col_totals.$col %]</a> - <strong> </td> [% END %] <td class="ttotal" align="right"> diff --git a/template/en/default/reports/report.html.tmpl b/template/en/default/reports/report.html.tmpl index 29157842f..06acaf422 100644 --- a/template/en/default/reports/report.html.tmpl +++ b/template/en/default/reports/report.html.tmpl @@ -29,6 +29,7 @@ # format: string. Format of the individual reports. # width: integer. For image charts, height of the image. # height: integer. For image charts, width of the image. + # imagebase: string. Base URL for chart image. # switchbase: string. Base URL for format switching. # cumulate: boolean. For bar/line charts, whether to cumulate data sets. #%] @@ -51,6 +52,7 @@ [% tbl_field_disp = field_descs.$tbl_field || tbl_field %] [% col_field_disp = field_descs.$col_field || col_field %] [% row_field_disp = field_descs.$row_field || row_field %] +[% switchbase = switchbase FILTER html %] [% title = BLOCK %] Report: @@ -73,7 +75,7 @@ .t4 { background-color: #c3d3ed } /* darker blue */ .ttotal { background-color: #cfffdf } /* light green */ " - h3 = time2str("%Y-%m-%d %H:%M:%S", time) + header_addl_info = time2str("%Y-%m-%d %H:%M:%S", time) %] [% IF debug %] @@ -96,7 +98,7 @@ <h2>[% tbl_disp FILTER html %]</h2> [% END %] - [% imageurl = BLOCK %]report.cgi?[% imagebase %]&format= + [% imageurl = BLOCK %]report.cgi?[% imagebase FILTER html %]&format= [% format FILTER url_quote %]&ctype=png&action=plot& [% IF tbl_field %] [% IF tbl != "-total-" %] @@ -125,8 +127,8 @@ { name => "line", description => "Line" }, { name => "table", description => "Table" } ] %] - [% formaturl = "report.cgi?$switchbase&width=$width&height=$height" _ - "&action=wrap" %] + [% formaturl = "report.cgi?$switchbase&width=$width" _ + "&height=$height&action=wrap" %] [% FOREACH other_format = formats %] [% NEXT IF other_format.name == "pie" AND row_field AND col_field %] [% UNLESS other_format.name == format %] @@ -157,7 +159,7 @@ [% height - 100 %]">Shorter</a><br> </td> [% END %] - <tr> + </tr> </table> <p> diff --git a/template/en/default/reports/series-common.html.tmpl b/template/en/default/reports/series-common.html.tmpl index 06b6af870..42bf0b7ba 100644 --- a/template/en/default/reports/series-common.html.tmpl +++ b/template/en/default/reports/series-common.html.tmpl @@ -99,22 +99,20 @@ function checkNewState() { [% BLOCK series_select %] <td align="left"> - <label for="[% sel.name %]" accesskey="[% sel.accesskey %]"> - <select name="[% sel.name %]" id="[% sel.name %]" - size="[% sel.size %]" style="width: 15em" - [%+ "disabled=\"disabled\"" UNLESS ${sel.name}.keys.size || newtext %] - [%+ "onchange=\"$sel.onchange\"" IF sel.onchange %]> - [% FOREACH x = ${sel.name}.keys.sort %] - <option value="[% x FILTER html %]" - [% " selected" IF default.${sel.name} == x %]> - [% x FILTER html %]</option> - [% END %] - [% IF newtext %] - <option value="">[% newtext FILTER html %]</option> - [% ELSIF NOT ${sel.name}.keys.size %] - <option value="" disabled="disabled"></option> - [% END %] - </select> - </label> + <select name="[% sel.name %]" id="[% sel.name %]" + size="[% sel.size %]" style="width: 15em" + [%+ "disabled=\"disabled\"" UNLESS ${sel.name}.keys.size || newtext %] + [%+ "onchange=\"$sel.onchange\"" IF sel.onchange %]> + [% FOREACH x = ${sel.name}.keys.sort %] + <option value="[% x FILTER html %]" + [% " selected" IF default.${sel.name} == x %]> + [% x FILTER html %]</option> + [% END %] + [% IF newtext %] + <option value="">[% newtext FILTER html %]</option> + [% ELSIF NOT ${sel.name}.keys.size %] + <option value="" disabled="disabled"></option> + [% END %] + </select> </td> [% END %] diff --git a/template/en/default/reports/series.html.tmpl b/template/en/default/reports/series.html.tmpl index d75808070..966c499ff 100644 --- a/template/en/default/reports/series.html.tmpl +++ b/template/en/default/reports/series.html.tmpl @@ -47,7 +47,8 @@ onchange => "catSelected()" } %] <td> <noscript> - <input type="submit" name="action-edit" value="Update -->"> + <input type="submit" name="action-edit" value="Update -->" + id="action-edit"> </noscript> </td> @@ -67,7 +68,7 @@ <span style="font-weight: bold;"> day(s)</span><br> [%# Change 'admin' here and in Series.pm, or remove the check completely, if you want to change who can make series public. %] - [% IF UserInGroup('admin') %] + [% IF user.in_group('admin') %] <input type="checkbox" name="public" [% "checked='checked'" IF default.public.0 %]> <span style="font-weight: bold;">Visible to all<br> @@ -89,7 +90,7 @@ </td> <td></td> <td> - <input type="submit" name="submit-button" + <input type="submit" name="submit-button" id="submit-button" value="[% button_name FILTER html %]"> </td> </tr> diff --git a/template/en/default/request/CVS/Entries b/template/en/default/request/CVS/Entries index 1413d38b3..0c9cec711 100644 --- a/template/en/default/request/CVS/Entries +++ b/template/en/default/request/CVS/Entries @@ -1,3 +1,3 @@ -/email.txt.tmpl/1.11.2.1/Thu Jul 6 02:20:08 2006//TBUGZILLA-2_22_3 -/queue.html.tmpl/1.14/Fri Sep 2 21:12:10 2005//TBUGZILLA-2_22_3 +/email.txt.tmpl/1.14.2.1/Mon Mar 26 08:00:22 2007//TBUGZILLA-3_0 +/queue.html.tmpl/1.17/Wed Aug 16 20:56:44 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/request/CVS/Tag b/template/en/default/request/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/request/CVS/Tag +++ b/template/en/default/request/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/request/email.txt.tmpl b/template/en/default/request/email.txt.tmpl index ece958348..a5fd17b88 100644 --- a/template/en/default/request/email.txt.tmpl +++ b/template/en/default/request/email.txt.tmpl @@ -23,10 +23,9 @@ [% PROCESS global/variables.none.tmpl %] -[% bugidsummary = flag.target.bug.id _ ': ' _ flag.target.bug.summary %] -[% attidsummary = flag.target.attachment.id _ ': ' _ - flag.target.attachment.summary %] -[% statuses = { '+' => "granted" , '-' => 'denied' , 'X' => "cancelled" , +[% bugidsummary = bug.bug_id _ ': ' _ bug.short_desc %] +[% attidsummary = attachment.id _ ': ' _ attachment.description %] +[% statuses = { '+' => "granted" , '-' => 'denied' , 'X' => "canceled" , '?' => "asked" } %] [% IF flag.status == '?' %] [% to_identity = flag.addressee.identity _ " for" %] @@ -37,11 +36,12 @@ [% END %] [% subject_status = statuses.${flag.status} %] [% END %] -From: bugzilla-request-daemon +From: [% Param('mailfrom') %] To: [% to %] -Subject: [% flag.type.name %] [%+ subject_status %]: [[% terms.Bug %] [%+ flag.target.bug.id %]] [% flag.target.bug.summary %] -[%- IF flag.target.attachment.exists %] : - [Attachment [% flag.target.attachment.id %]] [% flag.target.attachment.summary %][% END %] +Subject: [% flag.type.name %] [%+ subject_status %]: [[% terms.Bug %] [%+ bug.bug_id %]] [% bug.short_desc %] +X-Bugzilla-Type: request +[%- IF attachment %] : + [Attachment [% attachment.id %]] [% attachment.description %][% END %] [%+ USE wrap -%] [%- FILTER bullet = wrap(80) -%] @@ -50,13 +50,13 @@ Subject: [% flag.type.name %] [%+ subject_status %]: [[% terms.Bug %] [%+ flag.t [% terms.Bug %] [%+ bugidsummary %] [% END %] -[%+ Param('urlbase') %]show_bug.cgi?id=[% flag.target.bug.id %] -[% IF flag.target.attachment.exists %] +[%+ Param('urlbase') %]show_bug.cgi?id=[% bug.bug_id %] +[% IF attachment %] [% FILTER bullet = wrap(80) %] Attachment [% attidsummary %] [%- END %] -[%+ Param('urlbase') %]attachment.cgi?id=[% flag.target.attachment.id %]&action=edit +[%+ Param('urlbase') %]attachment.cgi?id=[% attachment.id %]&action=edit [%- END %] [%- FILTER bullet = wrap(80) %] diff --git a/template/en/default/request/queue.html.tmpl b/template/en/default/request/queue.html.tmpl index 73bbd8195..c80ecae87 100644 --- a/template/en/default/request/queue.html.tmpl +++ b/template/en/default/request/queue.html.tmpl @@ -24,32 +24,29 @@ [% USE Bugzilla %] [% cgi = Bugzilla.cgi %] -[%# The javascript block gets used in header.html.tmpl. %] -[% javascript = BLOCK %] - var usetms = 0; // do we have target milestone? - var first_load = 1; // is this the first time we load the page? - var last_sel = []; // caches last selection - var cpts = new Array(); - [% FOREACH prod = products %] - cpts['[% prod.name FILTER js %]'] = [ - [%- FOREACH comp = prod.components %]'[% comp.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; - [% END %] -[% END %] +[% PROCESS "global/js-products.html.tmpl" %] [% PROCESS global/header.html.tmpl title="Request Queue" style = " table.requests th { text-align: left; } - table#filter th { text-align: right; } + table#filtering th { text-align: right; } " onload="selectProduct(document.forms[0], 'product', 'component', 'Any');" javascript_urls=["productmenu.js"] %] +<p> +When you are logged in, only requests made by you or addressed to you +are shown by default. You can change the criteria using the form below. +When you are logged out, all pending requests that are not restricted +to some group are shown by default. +</p> + <form action="request.cgi" method="get"> <input type="hidden" name="action" value="queue"> - <table id="filter"> + <table id="filtering"> <tr> <th>Requester:</th> <td><input type="text" name="requester" value="[% cgi.param('requester') FILTER html %]" size="20" @@ -111,7 +108,7 @@ } %] [% PROCESS "global/select-menu.html.tmpl" name="group" options=groups default=cgi.param('group') %] </td> - <td><input type="submit" value="Filter"></td> + <td><input type="submit" id="filter" value="Filter"></td> </tr> </table> diff --git a/template/en/default/search/CVS/Entries b/template/en/default/search/CVS/Entries index bd4534410..0152315a5 100644 --- a/template/en/default/search/CVS/Entries +++ b/template/en/default/search/CVS/Entries @@ -1,12 +1,13 @@ -/boolean-charts.html.tmpl/1.12.8.1/Wed Jun 7 21:34:35 2006//TBUGZILLA-2_22_3 -/form.html.tmpl/1.35/Thu Dec 29 22:47:51 2005//TBUGZILLA-2_22_3 -/knob.html.tmpl/1.16.10.1/Sun Jul 22 22:25:17 2007//TBUGZILLA-2_22_3 -/search-advanced.html.tmpl/1.25/Wed Aug 10 01:30:41 2005//TBUGZILLA-2_22_3 -/search-create-series.html.tmpl/1.11.6.1/Tue May 23 00:22:29 2006//TBUGZILLA-2_22_3 -/search-help.html.tmpl/1.6.2.3/Sun Jul 22 22:25:17 2007//TBUGZILLA-2_22_3 -/search-report-graph.html.tmpl/1.8/Fri Aug 20 21:49:20 2004//TBUGZILLA-2_22_3 -/search-report-select.html.tmpl/1.6/Wed Mar 9 17:17:53 2005//TBUGZILLA-2_22_3 -/search-report-table.html.tmpl/1.9/Fri Aug 20 21:49:20 2004//TBUGZILLA-2_22_3 -/search-specific.html.tmpl/1.15/Mon Oct 31 18:48:59 2005//TBUGZILLA-2_22_3 -/tabs.html.tmpl/1.5/Sat Jul 30 00:41:10 2005//TBUGZILLA-2_22_3 +/boolean-charts.html.tmpl/1.15/Sat Dec 30 00:45:07 2006//TBUGZILLA-3_0 +/form.html.tmpl/1.47/Tue Feb 20 16:56:25 2007//TBUGZILLA-3_0 +/knob.html.tmpl/1.19/Fri Dec 29 20:55:08 2006//TBUGZILLA-3_0 +/search-advanced.html.tmpl/1.29/Thu Feb 8 20:11:02 2007//TBUGZILLA-3_0 +/search-create-series.html.tmpl/1.12/Tue May 23 00:20:17 2006//TBUGZILLA-3_0 +/search-help.html.tmpl/1.8/Thu Oct 19 19:32:23 2006//TBUGZILLA-3_0 +/search-plugin.xml.tmpl/1.1.2.1/Thu Apr 26 21:15:44 2007//TBUGZILLA-3_0 +/search-report-graph.html.tmpl/1.9/Wed Jul 12 12:21:43 2006//TBUGZILLA-3_0 +/search-report-select.html.tmpl/1.6/Wed Mar 9 17:17:53 2005//TBUGZILLA-3_0 +/search-report-table.html.tmpl/1.11/Sun Sep 3 20:41:20 2006//TBUGZILLA-3_0 +/search-specific.html.tmpl/1.20.2.1/Wed Feb 28 14:00:52 2007//TBUGZILLA-3_0 +/tabs.html.tmpl/1.6/Tue Oct 17 19:58:39 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/search/CVS/Tag b/template/en/default/search/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/search/CVS/Tag +++ b/template/en/default/search/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/search/boolean-charts.html.tmpl b/template/en/default/search/boolean-charts.html.tmpl index c1557b6cb..90234d2b4 100644 --- a/template/en/default/search/boolean-charts.html.tmpl +++ b/template/en/default/search/boolean-charts.html.tmpl @@ -52,7 +52,7 @@ [%# Whoever wrote the original version of boolean charts had a seriously twisted mind %] -[% jsmagic = "onclick=\"document.forms[0].action='query.cgi#chart'; document.forms[0].method='POST'; return 1;\"" %] +[% jsmagic = "onclick=\"this.form.action='query.cgi#chart'; this.form.method='POST'; return 1;\"" %] [% FOREACH chart = default.charts %] [% chartnum = loop.count - 1 %] @@ -100,8 +100,9 @@ [% ELSE %] <td> [% newor = colnum + 1 %] - <input type="submit" value="Or" - name="cmd-add[% "${chartnum}-${rownum}-${newor}" %]" [% jsmagic %]> + <input type="submit" value="Or" [% jsmagic %] + name="cmd-add[% "${chartnum}-${rownum}-${newor}" %]" + id="cmd-add[% "${chartnum}-${rownum}-${newor}" %]"> </td> [% END %] @@ -116,11 +117,13 @@ <tr> <td> [% newand = rownum + 1; newchart = chartnum + 1 %] - <input type="submit" value="And" - name="cmd-add[% "${chartnum}-${newand}-0" %]" [% jsmagic %]> + <input type="submit" value="And" [% jsmagic %] + name="cmd-add[% "${chartnum}-${newand}-0" %]" + id="cmd-add[% "${chartnum}-${newand}-0" %]"> - <input type="submit" value="Add another boolean chart" - name="cmd-add[% newchart %]-0-0" [% jsmagic %]> + <input type="submit" value="Add another boolean chart" [% jsmagic %] + name="cmd-add[% newchart %]-0-0" + id="cmd-add[% newchart %]-0-0"> </td> </tr> diff --git a/template/en/default/search/form.html.tmpl b/template/en/default/search/form.html.tmpl index daef7e58d..30e2f2650 100644 --- a/template/en/default/search/form.html.tmpl +++ b/template/en/default/search/form.html.tmpl @@ -44,8 +44,8 @@ var tms = new Array(); [% FOREACH c = classification %] prods[[% nclass FILTER js %]] = [ [% sep = '' %] - [%- FOREACH item = c.products -%] - [%- IF user.can_see_product(item.name) -%] + [%- FOREACH item = user.get_selectable_products(c.id) -%] + [%- IF item.components.size -%] [%- sep FILTER js %]'[% item.name FILTER js %]' [%- sep = ',' -%] [%- END -%] @@ -58,16 +58,17 @@ var tms = new Array(); [% n = 0 %] [% FOREACH p = product %] + [% NEXT IF NOT p.components.size %] [% IF Param('useclassification') %] prods['[% p.name FILTER js %]'] = [% n %] [% END %] cpts[[% n %]] = [ - [%- FOREACH item = p.components %]'[% item FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; + [%- FOREACH item = p.components %]'[% item.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; vers[[% n %]] = [ - [%- FOREACH item = p.versions -%]'[% item FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; + [%- FOREACH item = p.versions -%]'[% item.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; [% IF Param('usetargetmilestone') %] tms[[% n %]] = [ - [%- FOREACH item = p.milestones %]'[% item FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; + [%- FOREACH item = p.milestones %]'[% item.name FILTER js %]'[% ", " UNLESS loop.last %] [%- END -%] ]; [% END %] [% n = n+1 %] [% END %] @@ -87,7 +88,9 @@ function doOnSelectProduct(selectmode) { var milestone = (typeof(f.target_milestone) == "undefined" ? null : f.target_milestone); if (selectmode == 0) { - if (useclassification) { + // If there is no classification selected, give us a chance to fill + // the select fields with values from the possibly selected product. + if (useclassification && f.classification.selectedIndex > -1) { selectClassification(f.classification, f.product, f.component, f.version, milestone); } else { selectProduct(f.product, f.component, f.version, milestone); @@ -124,7 +127,9 @@ function doOnSelectProduct(selectmode) { <table> <tr> - <th align="right"><u>S</u>ummary:</th> + <th align="right"> + <label for="short_desc" accesskey="s"><u>S</u>ummary</label>: + </th> <td> <select name="short_desc_type"> [% FOREACH qv = query_variants %] @@ -134,7 +139,7 @@ function doOnSelectProduct(selectmode) { </select> </td> <td> - <input name="short_desc" size="40" accesskey="s" + <input name="short_desc" id="short_desc" size="40" value="[% default.short_desc.0 FILTER html %]"> <script type="text/javascript"> <!-- document.forms[queryform].short_desc.focus(); @@ -143,7 +148,8 @@ function doOnSelectProduct(selectmode) { </td> <td> [% IF button_name %] - <input type="submit" value="[% button_name FILTER html %]"> + <input type="submit" id="[% button_name.replace (' ' , '_') FILTER html %]" + value="[% button_name FILTER html %]"> [% END %] </td> </tr> @@ -157,21 +163,21 @@ function doOnSelectProduct(selectmode) { <td valign="top"> <table> <tr valign="bottom"> - <th align="left"><u>C</u>lassification:</th> + <th align="left"> + <label for="classification">Classification</label>: + </th> </tr> <tr valign="top"> <td align="left"> - <label for="classification"> - <select name="classification" multiple="multiple" size="5" id="classification" - onchange="doOnSelectProduct(1);"> + <select name="classification" multiple="multiple" size="5" id="classification" + onchange="doOnSelectProduct(1);"> [% FOREACH cat = classification %] <option value="[% cat.name FILTER html %]" [% " selected" IF lsearch(default.classification, cat.name) != -1 %]> [% cat.name FILTER html %] </option> [% END %] - </select> - </label> + </select> </td> </tr> </table> @@ -180,21 +186,23 @@ function doOnSelectProduct(selectmode) { <td valign="top"> <table> <tr valign="bottom"> - <th align="left"><u>P</u>roduct:</th> + <th align="left"> + <label for="product" accesskey="p"><u>P</u>roduct</label>: + </th> </tr> <tr valign="top"> [%# Can't use the select block here because of the onChange %] <td align="left"> - <label for="product" accesskey="p"> - <select name="product" multiple="multiple" size="5" id="product" - onchange="doOnSelectProduct(2);"> + <select name="product" multiple="multiple" size="5" id="product" + onchange="doOnSelectProduct(2);"> [% FOREACH p = product %] + [% IF p.components.size %] <option value="[% p.name FILTER html %]" [% " selected" IF lsearch(default.product, p.name) != -1 %]> [% p.name FILTER html %]</option> + [% END %] [% END %] - </select> - </label> + </select> </td> </tr> </table> @@ -203,23 +211,21 @@ function doOnSelectProduct(selectmode) { <table> <tr valign="bottom"> <th align="left"> - <a href="describecomponents.cgi">Co<u>m</u>ponent</a>: + <label for="component" accesskey="m"><a href="describecomponents.cgi">Co<u>m</u>ponent</a></label>: </th> </tr> <tr valign="top"> [%# Can't use the select block here because 'component' is a toolkit reserved word - we use 'component_' instead. %] <td align="left"> - <label for="component" accesskey="m"> - <select name="component" id="component" - multiple="multiple" size="5"> + <select name="component" id="component" + multiple="multiple" size="5"> [% FOREACH c = component_ %] <option value="[% c FILTER html %]" [% " selected" IF lsearch(default.component, c) != -1 %]> [% c FILTER html %]</option> [% END %] - </select> - </label> + </select> </td> </tr> </table> @@ -227,12 +233,13 @@ function doOnSelectProduct(selectmode) { <td valign="top"> <table> <tr valign="bottom"> - <th align="left"><u>V</u>ersion:</th> + <th align="left"> + <label for="version">Version</label>: + </th> </tr> <tr valign="top"> [% PROCESS select sel = { name => 'version', - size => 5, - accesskey => 'v' } %] + size => 5 } %] </tr> </table> </td> @@ -240,12 +247,13 @@ function doOnSelectProduct(selectmode) { <td valign="top"> <table> <tr valign="bottom"> - <th align="left"><u>T</u>arget:</th> + <th align="left"> + <label for="target_milestone">Target</label>: + </th> </tr> <tr valign="top"> [% PROCESS select sel = { name => 'target_milestone', - size => 5, - accesskey => 't' } %] + size => 5 } %] </tr> </table> </td> @@ -267,7 +275,9 @@ function doOnSelectProduct(selectmode) { [% UNLESS field.name == 'status_whiteboard' AND NOT Param('usestatuswhiteboard') %] <tr> - <th align="right">[% field.description %]:</th> + <th align="right"> + <label for="[% field.name %]" accesskey="[% field.accesskey %]">[% field.description %]</label>: + </th> <td> <select name="[% field.name %]_type"> [% FOREACH qv = query_variants %] @@ -277,8 +287,7 @@ function doOnSelectProduct(selectmode) { [% END %] </select> </td> - <td><input name="[% field.name %]" size="40" - accesskey="[% field.accesskey %]" + <td><input name="[% field.name %]" id="[% field.name %]" size="40" value="[% default.${field.name}.0 FILTER html %]"> </td> <td></td> @@ -289,7 +298,7 @@ function doOnSelectProduct(selectmode) { [% IF have_keywords %] <tr> <th align="right"> - <a href="describekeywords.cgi"><u>K</u>eywords</a>: + <label for="keywords" accesskey="k"><a href="describekeywords.cgi"><u>K</u>eywords</a></label>: </th> <td> <select name="keywords_type"> @@ -305,21 +314,21 @@ function doOnSelectProduct(selectmode) { </select> </td> <td> - <input name="keywords" size="40" accesskey="k" + <input name="keywords" id="keywords" size="40" value="[% default.keywords.0 FILTER html %]"> </td> </tr> [% END %] [%# Deadline %] - [% IF UserInGroup(Param("timetrackinggroup")) %] + [% IF user.in_group(Param("timetrackinggroup")) %] <tr> <th align="right"> - Dead<u>l</u>ine: + <label for="deadlinefrom" accesskey="l">Dead<u>l</u>ine</label>: </th> <td> from - <input name="deadlinefrom" size="10" maxlength="10" accesskey="l"> + <input name="deadlinefrom" id="deadlinefrom" size="10" maxlength="10"> to <input name="deadlineto" size="10" maxlength="10"> </td> @@ -340,12 +349,13 @@ function doOnSelectProduct(selectmode) { <td> <table> <tr> - <th align="left">St<u>a</u>tus:</th> + <th align="left"> + <label for="bug_status" accesskey="a">St<u>a</u>tus</label>: + </th> </tr> <tr valign="top"> [% PROCESS select sel = { name => 'bug_status', - size => 7, - accesskey => 'a' } %] + size => 7 } %] </tr> </table> </td> @@ -353,69 +363,70 @@ function doOnSelectProduct(selectmode) { <table> <tr> <th align="left"> - <u>R</u>esolution: + <label for="resolution" accesskey="r"><u>R</u>esolution</label>: </th> </tr> <tr valign="top"> [% PROCESS select sel = { name => 'resolution', - size => 7, - accesskey => 'r' } %] + size => 7 } %] </tr> </table> </td> <td> <table> <tr> - <th align="left">S<u>e</u>verity:</th> + <th align="left"> + <label for="bug_severity">Severity</label>: + </th> </tr> <tr valign="top"> [% PROCESS select sel = { name => 'bug_severity', - size => 7, - accesskey => 'e' } %] + size => 7 }%] </tr> </table> </td> <td> <table> <tr> - <th align="left">Pr<u>i</u>ority:</th> + <th align="left"> + <label for="priority" accesskey="i">Pr<u>i</u>ority</label>: + </th> </tr> <tr valign="top"> [% PROCESS select sel = { name => 'priority', - size => 7, - accesskey => 'i' } %] + size => 7 } %] </tr> </table> </td> <td> <table> <tr> - <th align="left"><u>H</u>ardware:</th> + <th align="left"> + <label for="rep_platform" accesskey="h"><u>H</u>ardware</label>: + </th> </tr> <tr valign="top"> [% PROCESS select sel = { name => 'rep_platform', - size => 7, - accesskey => 'h' } %] + size => 7 } %] </tr> </table> </td> <td> <table> <tr> - <th align="left"><u>O</u>S:</th> + <th align="left"> + <label for="op_sys" accesskey="o"><u>O</u>S</label>: + </th> </tr> <tr valign="top"> [% PROCESS select sel = { name => 'op_sys', - size => 7, - accesskey => 'o' } %] + size => 7 } %] </tr> </table> </td> </tr> </table> -<p> - [%# *** Email Numbering Votes *** %] <table> @@ -424,7 +435,11 @@ function doOnSelectProduct(selectmode) { <fieldset> <legend> <strong> - Email and Numbering + [% IF Param('usevotes') %] + Email Addresses, [% terms.Bug %] Numbers, and Votes + [% ELSE %] + Email Addresses and [% terms.Bug %] Numbers + [% END %] </strong> </legend> @@ -528,10 +543,11 @@ function doOnSelectProduct(selectmode) { <option value="include"[% " selected" IF default.bugidtype.0 == "include" %]>Only include</option> <option value="exclude"[% " selected" IF default.bugidtype.0 == "exclude" %]>Exclude</option> </select> - [% terms.bugs %] numbered: + <label for="bug_id">[% terms.bugs %] numbered</label>: </td> <td> - <input type="text" name="bug_id" value="[% default.bug_id.0 FILTER html %]" size="20"> + <input type="text" name="bug_id" id="bug_id" + value="[% default.bug_id.0 FILTER html %]" size="20"> </td> </tr> <tr> @@ -541,10 +557,12 @@ function doOnSelectProduct(selectmode) { [% IF Param('usevotes') %] <tr> <td align="right"> - Only [% terms.bugs %] with at least: + <label for="votes">Only [% terms.bugs %] with at least</label>: </td> <td> - <input name="votes" size="3" value="[% default.votes.0 FILTER html %]"> votes + <input name="votes" id="votes" size="3" + value="[% default.votes.0 FILTER html %]"> + votes </td> </tr> [% END %] @@ -562,25 +580,37 @@ function doOnSelectProduct(selectmode) { <dl class="bug_changes"> - <dt>Only [% terms.bugs %] changed between:</dt> + <dt> + <label for="chfieldfrom">Only [% terms.bugs %] changed between</label>: + </dt> <dd> - <input name="chfieldfrom" size="10" value="[% default.chfieldfrom.0 FILTER html %]"> + <input name="chfieldfrom" id="chfieldfrom" + size="10" value="[% default.chfieldfrom.0 FILTER html %]"> and <input name="chfieldto" size="10" value="[% default.chfieldto.0 FILTER html %]"> <br>(YYYY-MM-DD or relative dates) </dd> - <dt>where one or more of the following changed:</dt> + <dt> + <label for="chfield">where one or more of the following changed</label>: + </dt> <dd> - <select name="chfield" multiple="multiple" size="4"> + [%# Create array, so we can sort it by description #%] + [% chfields = [] %] [% FOREACH field = chfield %] - <option value="[% field FILTER html %]" - [% " selected" IF lsearch(default.chfield, field) != -1 %]> - [% (field_descs.$field || field) FILTER html %]</option> + [% chfields.push({value => field, desc => (field_descs.$field || field) }) %] + [% END %] + + <select name="chfield" id="chfield" multiple="multiple" size="4"> + [% FOREACH field = chfields.sort('desc') %] + <option value="[% field.value FILTER html %]" + [% " selected" IF lsearch(default.chfield, field.value) != -1 %]> + [% field.desc FILTER html %]</option> [% END %] </select> </dd> - <dt>and the new value was:</dt> + <dt>and <label for="chfieldvalue">the new value was</label>:</dt> <dd> - <input name="chfieldvalue" size="20" value="[% default.chfieldvalue.0 FILTER html %]"> + <input name="chfieldvalue" id="chfieldvalue" + size="20" value="[% default.chfieldvalue.0 FILTER html %]"> </dd> </dl> @@ -595,21 +625,20 @@ function doOnSelectProduct(selectmode) { [% BLOCK select %] <td align="left"> - <label for="[% sel.name %]" accesskey="[% sel.accesskey %]"> - <select name="[% sel.name %]" id="[% sel.name %]" - multiple="multiple" size="[% sel.size %]"> + <select name="[% sel.name %]" id="[% sel.name %]" + multiple="multiple" size="[% sel.size %]"> [% FOREACH name = ${sel.name} %] <option value="[% name FILTER html %]" [% " selected" IF lsearch(default.${sel.name}, name) != -1 %]> [% IF sel.name == "bug_status" %] - [% status_descs.${name} FILTER html %]</option> + [% status_descs.${name} FILTER html %] [% ELSIF sel.name == "resolution" %] - [% resolution_descs.${name} FILTER html %]</option> + [% get_resolution(name) FILTER html %] [% ELSE %] - [% name FILTER html %]</option> + [% name FILTER html %] [% END %] + </option> [% END %] - </select> - </label> + </select> </td> [% END %] diff --git a/template/en/default/search/knob.html.tmpl b/template/en/default/search/knob.html.tmpl index 00535bf26..58c83fdef 100644 --- a/template/en/default/search/knob.html.tmpl +++ b/template/en/default/search/knob.html.tmpl @@ -32,7 +32,7 @@ [% PROCESS global/variables.none.tmpl %] -[%# This is not necessary for English templates, but useful for localizers. %] +[%# This is not necessary for English templates, but useful for localisers. %] [% ordersdesc = { "Reuse same sort as last time" => "Reuse same sort as last time", "Bug Number" => "$terms.Bug Number", @@ -43,8 +43,8 @@ <input type="hidden" name="cmdtype" value="doit"> <p> - Sort results by: - <select name="order"> + <label for="order">Sort results by</label>: + <select name="order" id="order"> [% FOREACH order = orders %] <option value="[% order FILTER html %]" [% " selected" IF default.order.0 == order %]> @@ -54,10 +54,14 @@ </p> <p> - <input type="submit" value="[% button_name FILTER html %]"> + <input type="submit" id="[% button_name FILTER html %]" + value="[% button_name FILTER html %]"> [% IF known_name %] - <input type="hidden" name="query_based_on" - value="[% known_name FILTER html %]"> + [%# We store known_name in case the user add a boolean chart. %] + <input type="hidden" name="known_name" value="[% known_name FILTER html %]"> + + [%# The name of the existing query will be passed to buglist.cgi. %] + <input type="hidden" name="query_based_on" value="[% known_name FILTER html %]"> [% END %] </p> diff --git a/template/en/default/search/search-advanced.html.tmpl b/template/en/default/search/search-advanced.html.tmpl index e55c71ba1..5d9849caf 100644 --- a/template/en/default/search/search-advanced.html.tmpl +++ b/template/en/default/search/search-advanced.html.tmpl @@ -37,7 +37,6 @@ var queryform = "queryform" [% PROCESS global/header.html.tmpl title = "Search for $terms.bugs" - h1 = "" onload = "doOnSelectProduct(0); initHelp();" javascript = js_data javascript_urls = [ "js/productform.js" ] @@ -46,7 +45,7 @@ var queryform = "queryform" }" %] -[% PROCESS search/tabs.html.tmpl %] +[% WRAPPER search/tabs.html.tmpl %] [% button_name = "Search" %] @@ -54,7 +53,7 @@ var queryform = "queryform" [% IF NOT cgi.param("help") %] [% IF cgi.user_agent("Mozilla/5") %] <script type="text/javascript"> <!-- - document.write("<p><a href='query.cgi?help=1&format=advanced'>Give me some help</a> (reloads page.)</p>"); + document.write("<p><a href='query.cgi?help=1&format=advanced'>Give me some help<\/a> (reloads page).<\/p>"); // --> </script> [% END %] @@ -84,4 +83,6 @@ var queryform = "queryform" [% PROCESS "search/search-help.html.tmpl" IF cgi.param("help") %] +[% END %] + [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/search/search-help.html.tmpl b/template/en/default/search/search-help.html.tmpl index 3f39b97b2..ef80fd39a 100644 --- a/template/en/default/search/search-help.html.tmpl +++ b/template/en/default/search/search-help.html.tmpl @@ -70,7 +70,7 @@ { id => "bug_severity", html => "How severe the $terms.bug is, or whether it's an enhancement." }, { id => "priority", - html => "Engineers prioritize their $terms.bugs using this field." }, + html => "Engineers prioritise their $terms.bugs using this field." }, { id => "rep_platform", html => "The hardware platform the $terms.bug was observed on." }, { id => "op_sys", diff --git a/template/en/default/search/search-plugin.xml.tmpl b/template/en/default/search/search-plugin.xml.tmpl new file mode 100644 index 000000000..36a71f2c5 --- /dev/null +++ b/template/en/default/search/search-plugin.xml.tmpl @@ -0,0 +1,25 @@ +[%# 1.0@bugzilla.org #%] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + # + #%] +[% PROCESS global/variables.none.tmpl %] +<?xml version="1.0" encoding="UTF-8"?> +<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"> +<ShortName>[% terms.Bugzilla %]</ShortName> +<Description>[% terms.Bugzilla %] Quick Search</Description> +<InputEncoding>UTF-8</InputEncoding> +<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABGdBTUEAAK%2FINwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAALBSURBVHjaYnxckcEAA3%2F%2B%2FT%2F17LUcH%2Fevf%2F8U%2BHmYGBkZMABAALEgc%2B68%2F3T227cf2tJKKhJLt59n%2FfmbnYnZV1KEhYkJrgYggBghNrz78fPIi3d8uvKBIdb%2FOaWPnzitLc97%2Bc5rFXnhnVO3%2BslLwjUABBDIhnsfPl%2Fj53VO91FX4Gfgkjxw%2Fd%2F6Q49%2FWStqyAj%2B%2B88gZqn%2B9u5rYU52iAaAAGL69%2F%2F%2F2d9%2FYiMclGT4fv76%2BZ9DbO%2FeA39%2BfJHVcvj5l%2Bnh03e%2FWThOvnwLtwEgAAAxAM7%2FBPj8%2FRYkHQYHAf3%2F%2Fv%2F%2B%2Fv8BAVNTUPX18yorLNHE2S8mB%2FT2%2Bq7a4dvu8iUSDgAAAAKICRgUv3%2F8ZGKGeIvpz6eXBvq61lZWLMwMv%2F5zMP7%2FqSAjVFyZ%2FNvZftuT10DnAAQAMQDO%2FwQIBAPz5Or6%2Ff0CBQEAAgT99ubq38z2%2BwT18%2FAM%2F%2BkNDAv6%2FQMCAA1GVVrhMze5h4kCCORpkd9%2F3n74KiHO%2B%2BffX8b%2Ff7m%2BXWP985%2Bf5R%2BPLNdfoK%2F%2F%2Ffv39%2BePj2%2FkZYR0fe0BAgikQZGX%2B9b9FzLS%2FH%2F%2B%2FGVgYGRlZWNlA7nv7z9QuDP8%2B8nw%2FRXjn68Mv4Gu%2FAwQQCCni3FxPLn7nIGZGegfNhYmNjYWZnBMASOakZER6Eumf9%2FYGT4y%2FHx%2F%2BfBFgAAC2cDGzPT99WeGvwzvv%2Fx89vrr%2F39%2FJER4pcT5Gf4z%2FP37D2jtj9%2B%2FL918fmzrKSsWNoAAgiaN%2Fz9%2Fff%2F6S4CP8%2BWbz9vWHfv54aukpAAz0Og%2Ff%2F7%2F%2Bs36668cO3ugED9QJUAAQTUArf7%2F8x87D9vRjcejhPiZhAUYcACAAGI5%2FOHH9ddvXzAxmjz%2B8P8lw4fXn5l4eRlwA4AAYmaTkBFg%2FKvJwfbkwZuXN57y%2Fv%2F34stXGR4uRmxpGwgAAgwA4%2FkfrfCWvLQAAAAASUVORK5CYII%3D</Image> +<Url type="text/html" method="GET" template="[% Param('urlbase') %]buglist.cgi?quicksearch={searchTerms}"/> +</OpenSearchDescription> diff --git a/template/en/default/search/search-report-graph.html.tmpl b/template/en/default/search/search-report-graph.html.tmpl index 276fe7560..cfc585d8f 100644 --- a/template/en/default/search/search-report-graph.html.tmpl +++ b/template/en/default/search/search-report-graph.html.tmpl @@ -129,7 +129,8 @@ var queryform = "reportform" [% PROCESS search/form.html.tmpl %] <br> -<input type="submit" value="[% button_name FILTER html %]"> +<input type="submit" id="[% button_name FILTER html %]" + value="[% button_name FILTER html %]"> <input type="hidden" name="action" value="wrap"> <hr> diff --git a/template/en/default/search/search-report-table.html.tmpl b/template/en/default/search/search-report-table.html.tmpl index 1894fa795..9f7f2dd0f 100644 --- a/template/en/default/search/search-report-table.html.tmpl +++ b/template/en/default/search/search-report-table.html.tmpl @@ -64,9 +64,9 @@ var queryform = "reportform" [% PROCESS select name = 'y_axis_field' %] </td> <td width="150" height="150"> - <table border="1" width="100%" height="100%"> + <table border="1" width="100%"> <tr> - <td align="center" valign="middle"> + <td align="center" valign="middle" height="150"> <b>Multiple Tables:</b><br> [% PROCESS select name = 'z_axis_field' %] </td> @@ -81,7 +81,8 @@ var queryform = "reportform" [% PROCESS search/form.html.tmpl %] <br> -<input type="submit" value="[% button_name FILTER html %]"> +<input type="submit" id="[% button_name.replace (' ' , '_') FILTER html %]" + value="[% button_name FILTER html %]"> <input type="hidden" name="format" value="table"> <input type="hidden" name="action" value="wrap"> <hr> diff --git a/template/en/default/search/search-specific.html.tmpl b/template/en/default/search/search-specific.html.tmpl index dcc87130e..d93abd883 100644 --- a/template/en/default/search/search-specific.html.tmpl +++ b/template/en/default/search/search-specific.html.tmpl @@ -23,10 +23,9 @@ [% PROCESS global/header.html.tmpl title = "Find a Specific " _ terms.Bug - h1 = "" %] -[% PROCESS search/tabs.html.tmpl %] +[% WRAPPER search/tabs.html.tmpl %] <p> Find a specific [% terms.bug %] by entering words that describe it. @@ -73,8 +72,8 @@ for "crash secure SSL flash". [% IF Param('useclassification') %] [% FOREACH c = classification %] <optgroup label="[% c.name FILTER html %]"> - [% FOREACH p = c.products %] - [% IF user.can_see_product(p.name) %] + [% FOREACH p = user.get_selectable_products(c.id) %] + [% IF p.components.size %] <option value="[% p.name FILTER html %]" [% " selected" IF lsearch(default.product, p.name) != -1 %]> [% p.name FILTER html %] @@ -110,11 +109,17 @@ for "crash secure SSL flash". <tr> <td></td> <td> - <input type="submit" value="Search"> - </td> + <input type="submit" id="search" value="Search" + onclick="if (this.form.content.value == '') + {alert('The Words field cannot be empty. You have to ' + + 'enter at least one word in your search criteria.'); + return false;} return true;"> + </td> </tr> </table> </form> +[% END %] + [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/search/tabs.html.tmpl b/template/en/default/search/tabs.html.tmpl index 00358cb59..2fe05fa84 100644 --- a/template/en/default/search/tabs.html.tmpl +++ b/template/en/default/search/tabs.html.tmpl @@ -24,10 +24,14 @@ # This template has no interface. #%] -[% PROCESS global/tabs.html.tmpl +[% WRAPPER global/tabs.html.tmpl tabs = [ { name => 'specific', label => "Find a Specific $terms.Bug", link => "query.cgi?format=specific" }, { name => 'advanced', label => "Advanced Search", link => "query.cgi?format=advanced" } ] current_tab_name = query_format || format || "advanced" %] + +[% content %] + +[% END %] diff --git a/template/en/default/sidebar.xul.tmpl b/template/en/default/sidebar.xul.tmpl index 3b3172c85..6742889da 100644 --- a/template/en/default/sidebar.xul.tmpl +++ b/template/en/default/sidebar.xul.tmpl @@ -1,4 +1,4 @@ -[% template_version = "1.0@bugzilla.org" %] +[%# 1.0@bugzilla.org %] [%# -*- mode: sgml -*- %] [%# The contents of this file are subject to the Mozilla Public # License Version 1.1 (the "License"); you may not use this file @@ -25,7 +25,6 @@ [% PROCESS global/variables.none.tmpl %] <?xml version="1.0"?> -<!-- [% template_version %] --> <?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?> <?xml-stylesheet href="[% Param('urlbase') %]skins/standard/panel.css" type="text/css"?> <window @@ -98,7 +97,7 @@ function normal_keypress_handler( aEvent ) { [%- IF user.groups.editcomponents %] <text class="text-link" onclick="load_relative_url('sanitycheck.cgi')" value="sanity check"/> [%- END %] - [%- IF user.get_flag('can_logout') %] + [%- IF user.authorizer.can_logout %] <text class="text-link" onclick="load_relative_url('relogin.cgi')" value="log out [% user.login FILTER html %]"/> [%- END %] <separator class="thin"/> diff --git a/template/en/default/welcome-admin.html.tmpl b/template/en/default/welcome-admin.html.tmpl new file mode 100644 index 000000000..66ab72dfa --- /dev/null +++ b/template/en/default/welcome-admin.html.tmpl @@ -0,0 +1,90 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + #%] + +[%# INTERFACE: + # none + #%] + +[% PROCESS global/variables.none.tmpl %] + +[% title = BLOCK %]Welcome to [% terms.Bugzilla %][% END %] + +[% PROCESS global/header.html.tmpl + title = title + h3 = "version $constants.BUGZILLA_VERSION" + style_urls = [ 'skins/standard/index.css' ] +%] + +<div id="welcome-admin"> + <p>Welcome, [% user.identity FILTER html %].</p> + + <p>You are seeing this page because some of the core parameters have not been set up yet. + The goal of this page is to inform you about the last steps required to set up + your installation correctly.</p> + + <p>As an administrator, several administrative links are available at the bottom of + this page. These links will always be visible, on all pages. Among these links, + you must visit at least the <a href="editparams.cgi">Parameters</a> one, + which is the page from where you can set all important parameters for this installation. + By clicking this link, you will be able to set among others:</p> + + <ul> + <li><a href="editparams.cgi?section=core#maintainer">maintainer</a>, the person + responsible for this installation if something is running wrong.</li> + + <li><a href="editparams.cgi?section=core#urlbase">urlbase</a>, which is the URL + pointing to this installation and which will be used in emails (which is also the + reason you see this page: as long as this parameter is not set, you will see this + page again and again).</li> + + <li><a href="editparams.cgi?section=core#cookiepath">cookiepath</a> is important + for your browser to manage your cookies correctly.</li> + + <li><a href="editparams.cgi?section=core#utf8">utf8</a> will let you encode all + texts into UTF-8, if desired (it is strongly recommended to keep this parameter + turned on).</li> + </ul> + + <p>Also important are the following parameters:</p> + + <ul> + <li><a href="editparams.cgi?section=auth#requirelogin">requirelogin</a>, if turned + on, will protect your installation from users having no account on this installation. + In other words, users who are not explicitly authenticated with a valid account + cannot see any data. This is what you want if you want to keep your data private.</li> + + <li><a href="editparams.cgi?section=auth#createemailregexp">createemailregexp</a> + defines which users are allowed to create an account on this installation. If set + to ".*" (the default), everybody is free to create his own account. If set to + "@mycompany.com$", only users having an account @mycompany.com will be allowed to + create an account. If left blank, users will not be able to create accounts themselves; + only an administrator will be able to create one for them. If you want a private + installation, you must absolutely set this parameter to something different from + the default.</li> + + <li><a href="editparams.cgi?section=mta#mail_delivery_method">mail_delivery_method</a> + defines the method used to send emails, such as sendmail or SMTP. You have to set + it correctly to send emails.</li> + </ul> + + <p> + After having set up all this, we recommend looking at [% terms.Bugzilla %]'s other + parameters as well at some time so that you understand what they do and whether you + want to modify their settings for your installation. + </p> +</div> + +[% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/whine/CVS/Entries b/template/en/default/whine/CVS/Entries index 2304047c7..dd9194db5 100644 --- a/template/en/default/whine/CVS/Entries +++ b/template/en/default/whine/CVS/Entries @@ -1,5 +1,5 @@ -/mail.html.tmpl/1.3/Sun Aug 21 19:55:42 2005//TBUGZILLA-2_22_3 -/mail.txt.tmpl/1.3/Sun Aug 21 19:55:42 2005//TBUGZILLA-2_22_3 -/multipart-mime.txt.tmpl/1.4.6.1/Tue Mar 14 23:03:11 2006//TBUGZILLA-2_22_3 -/schedule.html.tmpl/1.3.2.1/Sat Oct 14 22:05:59 2006//TBUGZILLA-2_22_3 +/mail.html.tmpl/1.4/Thu Jul 13 18:00:43 2006//TBUGZILLA-3_0 +/mail.txt.tmpl/1.4/Thu Jul 13 18:00:43 2006//TBUGZILLA-3_0 +/multipart-mime.txt.tmpl/1.5/Tue Mar 14 23:01:23 2006//TBUGZILLA-3_0 +/schedule.html.tmpl/1.8/Thu Dec 28 17:57:50 2006//TBUGZILLA-3_0 D diff --git a/template/en/default/whine/CVS/Tag b/template/en/default/whine/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/default/whine/CVS/Tag +++ b/template/en/default/whine/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/default/whine/mail.html.tmpl b/template/en/default/whine/mail.html.tmpl index d81043a36..8fe11d657 100644 --- a/template/en/default/whine/mail.html.tmpl +++ b/template/en/default/whine/mail.html.tmpl @@ -84,7 +84,7 @@ <td align="left">[% bug.rep_platform FILTER html %]</td> <td align="left">[% bug.$assignee_login_string FILTER html %]</td> <td align="left">[% status_descs.${bug.bug_status} FILTER html %]</td> - <td align="left">[% resolution_descs.${bug.resolution} FILTER html %]</td> + <td align="left">[% get_resolution(bug.resolution) FILTER html %]</td> <td align="left">[% bug.short_desc FILTER html %]</td> </tr> [% END %] diff --git a/template/en/default/whine/mail.txt.tmpl b/template/en/default/whine/mail.txt.tmpl index 962972197..c7dcef3dc 100644 --- a/template/en/default/whine/mail.txt.tmpl +++ b/template/en/default/whine/mail.txt.tmpl @@ -59,7 +59,7 @@ Platform: [%+ bug.rep_platform %] Assignee: [%+ bug.$assignee_login_string %] Status: [%+ status_descs.${bug.bug_status} %] - [%- IF bug.resolution -%] Resolution: [% resolution_descs.${bug.resolution} -%] + [%- IF bug.resolution -%] Resolution: [% get_resolution(bug.resolution) -%] [%- END %] Summary: [% bug.short_desc %] diff --git a/template/en/default/whine/schedule.html.tmpl b/template/en/default/whine/schedule.html.tmpl index b158f5c0f..599498898 100644 --- a/template/en/default/whine/schedule.html.tmpl +++ b/template/en/default/whine/schedule.html.tmpl @@ -58,7 +58,7 @@ </p> <p> - Queries come from saved searches, which are created by executing a <a + Searches come from saved searches, which are created by executing a <a href="query.cgi">search</a>, then telling [% terms.Bugzilla %] to remember the search under a particular name. Add a query by clicking "Add a new query", and select the desired saved search name under "Search" and add a @@ -80,7 +80,7 @@ [%# This hidden submit button must be here to set default behavior when the user presses return on a form input field #%] <input type="submit" value="Update / Commit" name="commit" - style="visibility: hidden"> + style="display: none;" id="commit"> <input type="hidden" name="update" value="1"> <input type="hidden" name="token" value="[% token FILTER html %]"> @@ -94,7 +94,8 @@ </th> <td align="right"> <input type="submit" value="Remove Event" - name="remove_event_[% event.key %]"> + name="remove_event_[% event.key %]" + id="remove_event_[% event.key %]"> </td> </tr> @@ -114,9 +115,14 @@ Descriptive text sent within whine message: </td> <td> - <textarea name="event_[% event.key %]_body" - rows="5" cols="80"> - [% event.value.body FILTER html %]</textarea> + [% INCLUDE global/textarea.html.tmpl + name = "event_${event.key}_body" + minrows = 3 + maxrows = 10 + defaultrows = 5 + cols = 80 + defaultcontent = event.value.body + %] </td> </tr> @@ -129,7 +135,8 @@ <td align="left" bgcolor="#FFEEEE"> Not scheduled to run<br> <input type="submit" value="Add a new schedule" - name="add_schedule_[% event.key %]"> + name="add_schedule_[% event.key %]" + id="add_schedule_[% event.key %]"> </td> </tr> @@ -186,7 +193,8 @@ </td> <td align="left"> <input type="submit" value="Remove" - name="remove_schedule_[% schedule.id %]"> + name="remove_schedule_[% schedule.id %]" + id="remove_schedule_[% schedule.id %]"> </td> </tr> [% END %] @@ -194,7 +202,8 @@ <tr> <td> <input type="submit" value="Add a new schedule" - name="add_schedule_[% event.key %]"> + name="add_schedule_[% event.key %]" + id="add_schedule_[% event.key %]"> </td> </tr> @@ -210,14 +219,16 @@ <tr> <td valign="top" align="right"> - Queries: + Searches: </td> <td align="left" colspan="1"> - No queries <br> - <input type="submit" value="Add a new query" name="add_query_[% event.key %]"> + No searches <br> + <input type="submit" value="Add a new query" + name="add_query_[% event.key %]" + id="add_query_[% event.key %]"> </td> <td align="right" valign="bottom"> - <input type="submit" value="Update / Commit" name="commit"> + <input type="submit" value="Update / Commit" name="commit" id="update"> </td> </tr> @@ -225,7 +236,7 @@ <tr> <td valign="top" align="right"> - Queries: + Searches: </td> <td align="left"> @@ -267,7 +278,8 @@ </td> <td align="right"> <input type="submit" value="Remove" - name="remove_query_[% query.id %]"> + name="remove_query_[% query.id %]" + id="remove_query_[% query.id %]"> </td> </tr> @@ -276,7 +288,8 @@ <tr> <td colspan="3"> <input type="submit" value="Add a new query" - name="add_query_[% event.key %]"> + name="add_query_[% event.key %]" + id="add_query_[% event.key %]"> </td> </tr> @@ -284,7 +297,7 @@ </td> <td align="right" valign="bottom"> - <input type="submit" value="Update / Commit" name="commit"> + <input type="submit" value="Update / Commit" name="commit" id="update"> </td> </tr> @@ -295,7 +308,7 @@ [% END %] <p align="left"> - <input type="submit" value="Add a new event" name="add_event"> + <input type="submit" value="Add a new event" name="add_event" id="add_event"> </p> </form> diff --git a/template/en/extension/CVS/Entries b/template/en/extension/CVS/Entries index a483a4d25..fb1bcdb83 100644 --- a/template/en/extension/CVS/Entries +++ b/template/en/extension/CVS/Entries @@ -1,2 +1,2 @@ -/filterexceptions.pl/1.1/Tue Sep 27 16:54:58 2005//TBUGZILLA-2_22_3 +/filterexceptions.pl/1.2/Sat Feb 25 23:10:53 2006//TBUGZILLA-3_0 D diff --git a/template/en/extension/CVS/Tag b/template/en/extension/CVS/Tag index cb27bf8df..efdc1ff3e 100644 --- a/template/en/extension/CVS/Tag +++ b/template/en/extension/CVS/Tag @@ -1 +1 @@ -NBUGZILLA-2_22_3 +NBUGZILLA-3_0 diff --git a/template/en/extension/filterexceptions.pl b/template/en/extension/filterexceptions.pl index b8da2930f..29e2a1e94 100644 --- a/template/en/extension/filterexceptions.pl +++ b/template/en/extension/filterexceptions.pl @@ -30,7 +30,7 @@ # Simple literals - [% " selected" ... # Values always used for numbers - [% (i|j|k|n|count) %] # Params - [% Param(... -# Safe functions - [% (time2str|GetBugLink)... +# Safe functions - [% (time2str)... # Safe vmethods - [% foo.size %] [% foo.length %] # [% foo.push() %] # TT loop variables - [% loop.count %] diff --git a/testagent.cgi b/testagent.cgi index 2d558d2b9..4ecaa15fd 100755 --- a/testagent.cgi +++ b/testagent.cgi @@ -19,6 +19,6 @@ use strict; print "content-type:text/plain\n\n"; -print "OK\n"; +print "OK " . ($::ENV{MOD_PERL} || "mod_cgi") . "\n"; exit; diff --git a/testserver.pl b/testserver.pl index 87c6c0802..108a19ac2 100755 --- a/testserver.pl +++ b/testserver.pl @@ -18,17 +18,25 @@ # as its only argument. It attempts to troubleshoot as many installation # issues as possible. -use Socket; -use Bugzilla::Config qw($datadir); -my $envpath = $ENV{'PATH'}; -use lib "."; use strict; -require "globals.pl"; +use lib "."; + +BEGIN { + my $envpath = $ENV{'PATH'}; + require Bugzilla; + # $ENV{'PATH'} is required by the 'ps' command to run correctly. + $ENV{'PATH'} = $envpath; +} + +use Bugzilla::Constants; + +use Socket; + +my $datadir = bz_locations()->{'datadir'}; + eval "require LWP; require LWP::UserAgent;"; my $lwp = $@ ? 0 : 1; -$ENV{'PATH'}= $envpath; - if ((@ARGV != 1) || ($ARGV[0] !~ /^https?:/)) { print "Usage: $0 <URL to this Bugzilla installation>\n"; @@ -54,15 +62,16 @@ if ($^O !~ /MSWin32/i) { # Determine the numeric GID of $webservergroup my $webgroupnum = 0; -if ($::webservergroup =~ /^(\d+)$/) { +my $webservergroup = Bugzilla->localconfig->{webservergroup}; +if ($webservergroup =~ /^(\d+)$/) { $webgroupnum = $1; } else { - eval { $webgroupnum = (getgrnam $::webservergroup) || 0; }; + eval { $webgroupnum = (getgrnam $webservergroup) || 0; }; } # Check $webservergroup against the server's GID if ($sgid > 0) { - if ($::webservergroup eq "") { + if ($webservergroup eq "") { print "WARNING \$webservergroup is set to an empty string. That is a very insecure practice. Please refer to the @@ -98,8 +107,8 @@ Check your webserver configuration and try again.\n"; # Try to execute a cgi script my $response = fetch($ARGV[0] . "/testagent.cgi"); -if ($response =~ /^OK/) { - print "TEST-OK Webserver is executing CGIs.\n"; +if ($response =~ /^OK (.*)$/) { + print "TEST-OK Webserver is executing CGIs via $1.\n"; } elsif ($response =~ /^#!/) { print "TEST-FAILED Webserver is fetching rather than executing CGI files. @@ -110,8 +119,9 @@ Check the AddHandler statement in your httpd.conf file.\n"; } # Make sure that webserver is honoring .htaccess files -$::localconfig =~ s~^\./~~; -$url = $ARGV[0] . "/$::localconfig"; +my $localconfig = bz_locations()->{'localconfig'}; +$localconfig =~ s~^\./~~; +$url = $ARGV[0] . "/$localconfig"; $response = fetch($url); if ($response) { print diff --git a/token.cgi b/token.cgi index c25ee7e9c..e45f49fba 100755 --- a/token.cgi +++ b/token.cgi @@ -19,6 +19,7 @@ # Rights Reserved. # # Contributor(s): Myk Melez <myk@mozilla.org> +# Frédéric Buclin <LpSolit@gmail.com> ############################################################################ # Script Initialization @@ -32,23 +33,19 @@ use lib qw(.); use Bugzilla; use Bugzilla::Constants; use Bugzilla::Util; +use Bugzilla::Error; +use Bugzilla::Token; +use Bugzilla::User; -my $cgi = Bugzilla->cgi; -my $dbh = Bugzilla->dbh; -my $template = Bugzilla->template; -my $vars = {}; +use Date::Parse; -# Include the Bugzilla CGI and general utility library. -require "globals.pl"; +my $dbh = Bugzilla->dbh; +local our $cgi = Bugzilla->cgi; +local our $template = Bugzilla->template; +local our $vars = {}; Bugzilla->login(LOGIN_OPTIONAL); -# Use the "Bugzilla::Token" module that contains functions for doing various -# token-related tasks. -use Bugzilla::Token; - -use Bugzilla::User; - ################################################################################ # Data Validation / Security Authorization ################################################################################ @@ -67,8 +64,8 @@ if ($cgi->param('t')) { $::token = $cgi->param('t'); # Make sure the token contains only valid characters in the right amount. - # ValidatePassword will throw an error if token is invalid - ValidatePassword($::token); + # validate_password will throw an error if token is invalid + validate_password($::token); Bugzilla::Token::CleanTokenTable(); @@ -92,6 +89,12 @@ if ($cgi->param('t')) { Bugzilla::Token::Cancel($::token, "wrong_token_for_confirming_email_change"); ThrowUserError("wrong_token_for_confirming_email_change"); } + if (($::action =~ /^(request|confirm|cancel)_new_account$/) + && ($tokentype ne 'account')) + { + Bugzilla::Token::Cancel($::token, 'wrong_token_for_creating_account'); + ThrowUserError('wrong_token_for_creating_account'); + } } @@ -105,12 +108,12 @@ if ( $::action eq 'reqpw' ) { || ThrowUserError("login_needed_for_password_change"); # check verification methods - unless (Bugzilla::Auth->has_db) { + unless (Bugzilla->user->authorizer->can_change_password) { ThrowUserError("password_change_requests_not_allowed"); } validate_email_syntax($login_name) - || ThrowUserError('illegal_email_address', {addr => $login_name}); + || ThrowUserError('illegal_email_address', {addr => $login_name}); my ($user_id) = $dbh->selectrow_array('SELECT userid FROM profiles WHERE ' . $dbh->sql_istrcmp('login_name', '?'), @@ -127,7 +130,7 @@ if ( $::action eq 'chgpw' ) { && defined $cgi->param('matchpassword') || ThrowUserError("require_new_password"); - ValidatePassword($password, $cgi->param('matchpassword')); + validate_password($password, $cgi->param('matchpassword')); } ################################################################################ @@ -152,6 +155,12 @@ if ($::action eq 'reqpw') { cancelChangeEmail(); } elsif ($::action eq 'chgem') { changeEmail(); +} elsif ($::action eq 'request_new_account') { + request_create_account(); +} elsif ($::action eq 'confirm_new_account') { + confirm_create_account(); +} elsif ($::action eq 'cancel_new_account') { + cancel_create_account(); } else { # If the action that the user wants to take (specified in the "a" form field) # is none of the above listed actions, display an error telling the user @@ -339,3 +348,57 @@ sub cancelChangeEmail { || ThrowTemplateError($template->error()); } +sub request_create_account { + my (undef, $date, $login_name) = Bugzilla::Token::GetTokenData($::token); + $vars->{'token'} = $::token; + $vars->{'email'} = $login_name . Bugzilla->params->{'emailsuffix'}; + $vars->{'date'} = str2time($date); + + # We require a HTTPS connection if possible. + if (Bugzilla->params->{'sslbase'} ne '' + && Bugzilla->params->{'ssl'} ne 'never') + { + $cgi->require_https(Bugzilla->params->{'sslbase'}); + } + print $cgi->header(); + + $template->process('account/email/confirm-new.html.tmpl', $vars) + || ThrowTemplateError($template->error()); +} + +sub confirm_create_account { + my (undef, undef, $login_name) = Bugzilla::Token::GetTokenData($::token); + + my $password = $cgi->param('passwd1') || ''; + validate_password($password, $cgi->param('passwd2') || ''); + + my $otheruser = Bugzilla::User->create({ + login_name => $login_name, + realname => $cgi->param('realname'), + cryptpassword => $password}); + + # Now delete this token. + delete_token($::token); + + # Let the user know that his user account has been successfully created. + $vars->{'message'} = 'account_created'; + $vars->{'otheruser'} = $otheruser; + $vars->{'login_info'} = 1; + + print $cgi->header(); + + $template->process('global/message.html.tmpl', $vars) + || ThrowTemplateError($template->error()); +} + +sub cancel_create_account { + my (undef, undef, $login_name) = Bugzilla::Token::GetTokenData($::token); + + $vars->{'message'} = 'account_creation_cancelled'; + $vars->{'account'} = $login_name; + Bugzilla::Token::Cancel($::token, $vars->{'message'}); + + print $cgi->header(); + $template->process('global/message.html.tmpl', $vars) + || ThrowTemplateError($template->error()); +} diff --git a/userprefs.cgi b/userprefs.cgi index 3dc68121e..564057ee8 100755 --- a/userprefs.cgi +++ b/userprefs.cgi @@ -30,17 +30,16 @@ use Bugzilla; use Bugzilla::Constants; use Bugzilla::Search; use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::User; -require "globals.pl"; - my $template = Bugzilla->template; -my $vars = {}; +local our $vars = {}; ############################################################################### # Each panel has two functions - panel Foo has a DoFoo, to get the data # necessary for displaying the panel, and a SaveFoo, to save the panel's -# contents from the form data (if appropriate.) +# contents from the form data (if appropriate). # SaveFoo may be called before DoFoo. ############################################################################### sub DoAccount { @@ -50,10 +49,11 @@ sub DoAccount { ($vars->{'realname'}) = $dbh->selectrow_array( "SELECT realname FROM profiles WHERE userid = ?", undef, $user->id); - if(Param('allowemailchange')) { + if(Bugzilla->params->{'allowemailchange'} + && Bugzilla->user->authorizer->can_change_email) { my @token = $dbh->selectrow_array( "SELECT tokentype, issuedate + " . - $dbh->sql_interval(3, 'DAY') . ", eventdata + $dbh->sql_interval(MAX_TOKEN_AGE, 'DAY') . ", eventdata FROM tokens WHERE userid = ? AND tokentype LIKE 'email%' @@ -96,11 +96,10 @@ sub SaveAccount { { $cgi->param('new_password1') || ThrowUserError("new_password_missing"); - ValidatePassword($pwd1, $pwd2); + validate_password($pwd1, $pwd2); if ($cgi->param('Bugzilla_password') ne $pwd1) { my $cryptedpassword = bz_crypt($pwd1); - trick_taint($cryptedpassword); # Only used in a placeholder $dbh->do(q{UPDATE profiles SET cryptpassword = ? WHERE userid = ?}, @@ -112,7 +111,7 @@ sub SaveAccount { } } - if(Param("allowemailchange") && $cgi->param('new_login_name')) { + if(Bugzilla->params->{"allowemailchange"} && $cgi->param('new_login_name')) { my $old_login_name = $cgi->param('Bugzilla_login'); my $new_login_name = trim($cgi->param('new_login_name')); @@ -129,7 +128,6 @@ sub SaveAccount { # Before changing an email address, confirm one does not exist. validate_email_syntax($new_login_name) || ThrowUserError('illegal_email_address', {addr => $new_login_name}); - trick_taint($new_login_name); is_available_username($new_login_name) || ThrowUserError("account_exists", {email => $new_login_name}); @@ -199,13 +197,14 @@ sub DoEmail { ########################################################################### # User watching ########################################################################### - if (Param("supportwatchers")) { + if (Bugzilla->params->{"supportwatchers"}) { my $watched_ref = $dbh->selectcol_arrayref( "SELECT profiles.login_name FROM watch INNER JOIN profiles" . " ON watch.watched = profiles.userid" . - " WHERE watcher = ?", + " WHERE watcher = ?" . + " ORDER BY profiles.login_name", undef, $user->id); - $vars->{'watchedusers'} = join(',', @$watched_ref); + $vars->{'watchedusers'} = $watched_ref; my $watcher_ids = $dbh->selectcol_arrayref( "SELECT watcher FROM watch WHERE watched = ?", @@ -297,41 +296,54 @@ sub SaveEmail { ########################################################################### # User watching ########################################################################### - if (Param("supportwatchers") && defined $cgi->param('watchedusers')) { + if (Bugzilla->params->{"supportwatchers"} + && (defined $cgi->param('new_watchedusers') + || defined $cgi->param('remove_watched_users'))) + { # Just in case. Note that this much locking is actually overkill: # we don't really care if anyone reads the watch table. So # some small amount of contention could be gotten rid of by # using user-defined locks rather than table locking. $dbh->bz_lock_tables('watch WRITE', 'profiles READ'); - # what the db looks like now + # Use this to protect error messages on duplicate submissions my $old_watch_ids = $dbh->selectcol_arrayref("SELECT watched FROM watch" . " WHERE watcher = ?", undef, $user->id); - - # The new information given to us by the user. - my @new_watch_names = split(/[,\s]+/, $cgi->param('watchedusers')); + + # The new information given to us by the user. + my @new_watch_names = split(/[,\s]+/, $cgi->param('new_watchedusers')); my %new_watch_ids; + foreach my $username (@new_watch_names) { - my $watched_userid = DBNameToIdAndCheck(trim($username)); + my $watched_userid = login_to_id(trim($username), THROW_ERROR); $new_watch_ids{$watched_userid} = 1; } - my ($removed, $added) = diff_arrays($old_watch_ids, [keys %new_watch_ids]); - - # Remove people who were removed. - my $delete_sth = $dbh->prepare('DELETE FROM watch WHERE watched = ?' - . ' AND watcher = ?'); - foreach my $remove_me (@$removed) { - $delete_sth->execute($remove_me, $user->id); - } # Add people who were added. my $insert_sth = $dbh->prepare('INSERT INTO watch (watched, watcher)' . ' VALUES (?, ?)'); - foreach my $add_me (@$added) { + foreach my $add_me (keys(%new_watch_ids)) { + next if grep($_ == $add_me, @$old_watch_ids); $insert_sth->execute($add_me, $user->id); } + if (defined $cgi->param('remove_watched_users')) { + my @removed = $cgi->param('watched_by_you'); + # Remove people who were removed. + my $delete_sth = $dbh->prepare('DELETE FROM watch WHERE watched = ?' + . ' AND watcher = ?'); + + my %remove_watch_ids; + foreach my $username (@removed) { + my $watched_userid = login_to_id(trim($username), THROW_ERROR); + $remove_watch_ids{$watched_userid} = 1; + } + foreach my $remove_me (keys(%remove_watch_ids)) { + $delete_sth->execute($remove_me, $user->id); + } + } + $dbh->bz_unlock_tables(); } } @@ -349,15 +361,22 @@ sub DoPermissions { my ($nam, $desc) = @$group; push(@has_bits, {"desc" => $desc, "name" => $nam}); } - $groups = $dbh->selectall_arrayref( - "SELECT DISTINCT name, description FROM groups ORDER BY name"); + $groups = $dbh->selectall_arrayref('SELECT DISTINCT id, name, description + FROM groups + ORDER BY name'); foreach my $group (@$groups) { - my ($nam, $desc) = @$group; - if ($user->can_bless($nam)) { + my ($group_id, $nam, $desc) = @$group; + if ($user->can_bless($group_id)) { push(@set_bits, {"desc" => $desc, "name" => $nam}); } } - + + # If the user has product specific privileges, inform him about that. + foreach my $privs (PER_PRODUCT_PRIVILEGES) { + next if $user->in_group($privs); + $vars->{"local_$privs"} = $user->get_products_by_permission($privs); + } + $vars->{'has_bits'} = \@has_bits; $vars->{'set_bits'} = \@set_bits; } @@ -366,29 +385,13 @@ sub DoPermissions { sub DoSavedSearches { - # 2004-12-13 - colin.ogilvie@gmail.com, bug 274397 - # Need to work around the possibly missing query_format=advanced + my $dbh = Bugzilla->dbh; my $user = Bugzilla->user; - my @queries = @{$user->queries}; - my @newqueries; - foreach my $q (@queries) { - if ($q->{'query'} =~ /query_format=([^&]*)/) { - my $format = $1; - if (!IsValidQueryType($format)) { - if ($format eq "") { - $q->{'query'} =~ s/query_format=/query_format=advanced/; - } - else { - $q->{'query'} .= '&query_format=advanced'; - } - } - } else { - $q->{'query'} .= '&query_format=advanced'; - } - push @newqueries, $q; + if ($user->queryshare_groups_as_string) { + $vars->{'queryshare_groups'} = + Bugzilla::Group->new_from_list($user->queryshare_groups); } - $vars->{'queries'} = \@newqueries; } sub SaveSavedSearches { @@ -396,18 +399,87 @@ sub SaveSavedSearches { my $dbh = Bugzilla->dbh; my $user = Bugzilla->user; - my @queries = @{$user->queries}; - my $sth = $dbh->prepare("UPDATE namedqueries SET linkinfooter = ? - WHERE userid = ? - AND name = ?"); - foreach my $q (@queries) { - my $linkinfooter = - defined($cgi->param("linkinfooter_$q->{'name'}")) ? 1 : 0; - $sth->execute($linkinfooter, $user->id, $q->{'name'}); + # We'll need this in a loop, so do the call once. + my $user_id = $user->id; + + my $sth_insert_nl = $dbh->prepare('INSERT INTO namedqueries_link_in_footer + (namedquery_id, user_id) + VALUES (?, ?)'); + my $sth_delete_nl = $dbh->prepare('DELETE FROM namedqueries_link_in_footer + WHERE namedquery_id = ? + AND user_id = ?'); + my $sth_insert_ngm = $dbh->prepare('INSERT INTO namedquery_group_map + (namedquery_id, group_id) + VALUES (?, ?)'); + my $sth_update_ngm = $dbh->prepare('UPDATE namedquery_group_map + SET group_id = ? + WHERE namedquery_id = ?'); + my $sth_delete_ngm = $dbh->prepare('DELETE FROM namedquery_group_map + WHERE namedquery_id = ?'); + + # Update namedqueries_link_in_footer for this user. + foreach my $q (@{$user->queries}, @{$user->queries_available}) { + if (defined $cgi->param("link_in_footer_" . $q->id)) { + $sth_insert_nl->execute($q->id, $user_id) if !$q->link_in_footer; + } + else { + $sth_delete_nl->execute($q->id, $user_id) if $q->link_in_footer; + } + } + + # For user's own queries, update namedquery_group_map. + foreach my $q (@{$user->queries}) { + my $group_id; + + if ($user->in_group(Bugzilla->params->{'querysharegroup'})) { + $group_id = $cgi->param("share_" . $q->id) || ''; + } + + if ($group_id) { + # Don't allow the user to share queries with groups he's not + # allowed to. + next unless grep($_ eq $group_id, @{$user->queryshare_groups}); + + # $group_id is now definitely a valid ID of a group the + # user can share queries with, so we can trick_taint. + detaint_natural($group_id); + if ($q->shared_with_group) { + $sth_update_ngm->execute($group_id, $q->id); + } + else { + $sth_insert_ngm->execute($q->id, $group_id); + } + + # If we're sharing our query with a group we can bless, we + # subscribe direct group members to our search automatically. + # Otherwise, the group members need to opt in. This behaviour + # is deemed most likely to fit users' needs. + if ($user->can_bless($group_id)) { + my $group = new Bugzilla::Group($group_id); + my $members = $group->members_non_inherited; + foreach my $member (@$members) { + next if $member->id == $user->id; + $sth_insert_nl->execute($q->id, $member->id) + if !$q->link_in_footer($member); + } + } + } + else { + # They have unshared that query. + if ($q->shared_with_group) { + $sth_delete_ngm->execute($q->id); + } + + # Don't remove namedqueries_link_in_footer entries for users + # subscribing to the shared query. The idea is that they will + # probably want to be subscribers again should the sharing + # user choose to share the query again. + } } $user->flush_queries_cache; + # Update profiles.mybugslink. my $showmybugslink = defined($cgi->param("showmybugslink")) ? 1 : 0; $dbh->do("UPDATE profiles SET mybugslink = ? WHERE userid = ?", undef, ($showmybugslink, $user->id)); @@ -432,11 +504,9 @@ Bugzilla->login(LOGIN_REQUIRED); $cgi->param('Bugzilla_login', $bugzilla_login); $cgi->param('Bugzilla_password', $bugzilla_password); -GetVersionTable(); - $vars->{'changes_saved'} = $cgi->param('dosave'); -my $current_tab_name = $cgi->param('tab') || "account"; +my $current_tab_name = $cgi->param('tab') || "settings"; # The SWITCH below makes sure that this is valid trick_taint($current_tab_name); diff --git a/votes.cgi b/votes.cgi index 7616e5e16..43a693b52 100755 --- a/votes.cgi +++ b/votes.cgi @@ -22,19 +22,23 @@ # Stephan Niemz <st.n@gmx.net> # Christopher Aillon <christopher@aillon.com> # Gervase Markham <gerv@gerv.net> +# Frédéric Buclin <LpSolit@gmail.com> use strict; use lib "."; use Bugzilla; use Bugzilla::Constants; +use Bugzilla::Util; +use Bugzilla::Error; use Bugzilla::Bug; +use Bugzilla::User; +use Bugzilla::Product; -require "globals.pl"; +use List::Util qw(min); my $cgi = Bugzilla->cgi; -my $template = Bugzilla->template; -my $vars = {}; +local our $vars = {}; # If the action is show_bug, you need a bug_id. # If the action is show_user, you can supply a userid to show the votes for @@ -70,14 +74,14 @@ ValidateBugID($bug_id) if defined $bug_id; ################################################################################ if ($action eq "show_bug") { - show_bug(); + show_bug($bug_id); } elsif ($action eq "show_user") { - show_user(); + show_user($bug_id); } elsif ($action eq "vote") { - record_votes() if Param('usevotes'); - show_user(); + record_votes() if Bugzilla->params->{'usevotes'}; + show_user($bug_id); } else { ThrowCodeError("unknown_action", {action => $action}); @@ -87,8 +91,10 @@ exit; # Display the names of all the people voting for this one bug. sub show_bug { + my ($bug_id) = @_; my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; + my $template = Bugzilla->template; ThrowCodeError("missing_bug_id") unless defined $bug_id; @@ -109,25 +115,24 @@ sub show_bug { # Display all the votes for a particular user. If it's the user # doing the viewing, give them the option to edit them too. sub show_user { - GetVersionTable(); - + my ($bug_id) = @_; my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; my $user = Bugzilla->user; + my $template = Bugzilla->template; # If a bug_id is given, and we're editing, we'll add it to the votes list. $bug_id ||= ""; - + my $name = $cgi->param('user') || $user->login; - my $who = DBNameToIdAndCheck($name); + my $who = login_to_id($name, THROW_ERROR); my $userid = $user->id; - - my $canedit = (Param('usevotes') && $userid == $who) ? 1 : 0; + + my $canedit = (Bugzilla->params->{'usevotes'} && $userid == $who) ? 1 : 0; $dbh->bz_lock_tables('bugs READ', 'products READ', 'votes WRITE', 'cc READ', 'bug_group_map READ', 'user_group_map READ', - 'group_group_map READ', - 'cc AS selectVisible_cc READ', 'groups READ'); + 'group_group_map READ', 'groups READ', 'group_control_map READ'); if ($canedit && $bug_id) { # Make sure there is an entry for this bug @@ -140,38 +145,27 @@ sub show_user { VALUES (?, ?, 0)', undef, ($who, $bug_id)); } } - - # Calculate the max votes per bug for each product; doing it here means - # we can do it all in one query. - my %maxvotesperbug; - if($canedit) { - my $products = $dbh->selectall_arrayref('SELECT name, maxvotesperbug - FROM products'); - foreach (@$products) { - my ($prod, $max) = @$_; - $maxvotesperbug{$prod} = $max; - } - } - + my @products; - - # Read the votes data for this user for each product - foreach my $product (sort(keys(%::prodmaxvotes))) { - next if $::prodmaxvotes{$product} <= 0; - + my $products = $user->get_selectable_products; + # Read the votes data for this user for each product. + foreach my $product (@$products) { + next unless ($product->votes_per_user > 0); + my @bugs; my $total = 0; my $onevoteonly = 0; my $vote_list = $dbh->selectall_arrayref('SELECT votes.bug_id, votes.vote_count, - bugs.short_desc, bugs.bug_status - FROM votes - INNER JOIN bugs ON votes.bug_id = bugs.bug_id - INNER JOIN products ON bugs.product_id = products.id - WHERE votes.who = ? AND products.name = ? + bugs.short_desc, bugs.bug_status + FROM votes + INNER JOIN bugs + ON votes.bug_id = bugs.bug_id + WHERE votes.who = ? + AND bugs.product_id = ? ORDER BY votes.bug_id', - undef, ($who, $product)); + undef, ($who, $product->id)); foreach (@$vote_list) { my ($id, $count, $summary, $status) = @$_; @@ -181,29 +175,25 @@ sub show_user { # and they can see there are votes 'missing', but not on what bug # they are. This seems a reasonable compromise; the alternative is # to lie in the totals. - next if !$user->can_see_bug($id); + next if !$user->can_see_bug($id); push (@bugs, { id => $id, summary => $summary, count => $count, - opened => IsOpenedState($status) }); + opened => is_open_state($status) }); } - - # In case we didn't populate this earlier (i.e. an error, or - # a not logged in user viewing a users votes) - $maxvotesperbug{$product} ||= 0; - - $onevoteonly = 1 if (min($::prodmaxvotes{$product}, - $maxvotesperbug{$product}) == 1); - + + $onevoteonly = 1 if (min($product->votes_per_user, + $product->max_votes_per_bug) == 1); + # Only add the product for display if there are any bugs in it. - if ($#bugs > -1) { - push (@products, { name => $product, + if ($#bugs > -1) { + push (@products, { name => $product->name, bugs => \@bugs, onevoteonly => $onevoteonly, total => $total, - maxvotes => $::prodmaxvotes{$product}, - maxperbug => $maxvotesperbug{$product} }); + maxvotes => $product->votes_per_user, + maxperbug => $product->max_votes_per_bug }); } } @@ -228,6 +218,7 @@ sub record_votes { my $cgi = Bugzilla->cgi; my $dbh = Bugzilla->dbh; + my $template = Bugzilla->template; # Build a list of bug IDs for which votes have been submitted. Votes # are submitted in form fields in which the field names are the bug @@ -266,43 +257,35 @@ sub record_votes { ############################################################################ # End Data/Security Validation ############################################################################ - - GetVersionTable(); - my $who = Bugzilla->user->id; # If the user is voting for bugs, make sure they aren't overstuffing # the ballot box. if (scalar(@buglist)) { - my $product_vote_settings = - $dbh->selectall_arrayref('SELECT bugs.bug_id, products.name, - products.maxvotesperbug - FROM bugs - INNER JOIN products - ON products.id = bugs.product_id - WHERE bugs.bug_id IN - (' . join(', ', @buglist) . ')'); - my %prodcount; - foreach (@$product_vote_settings) { - my ($id, $prod, $max) = @$_; + my %products; + # XXX - We really need a $bug->product() method. + foreach my $bug_id (@buglist) { + my $bug = new Bugzilla::Bug($bug_id); + my $prod = $bug->product; + $products{$prod} ||= new Bugzilla::Product({name => $prod}); $prodcount{$prod} ||= 0; - $prodcount{$prod} += $votes{$id}; - + $prodcount{$prod} += $votes{$bug_id}; + # Make sure we haven't broken the votes-per-bug limit - ($votes{$id} <= $max) + ($votes{$bug_id} <= $products{$prod}->max_votes_per_bug) || ThrowUserError("too_many_votes_for_bug", - {max => $max, - product => $prod, - votes => $votes{$id}}); + {max => $products{$prod}->max_votes_per_bug, + product => $prod, + votes => $votes{$bug_id}}); } # Make sure we haven't broken the votes-per-product limit foreach my $prod (keys(%prodcount)) { - ($prodcount{$prod} <= $::prodmaxvotes{$prod}) + ($prodcount{$prod} <= $products{$prod}->votes_per_user) || ThrowUserError("too_many_votes_for_product", - {max => $::prodmaxvotes{$prod}, - product => $prod, + {max => $products{$prod}->votes_per_user, + product => $prod, votes => $prodcount{$prod}}); } } diff --git a/whine.pl b/whine.pl index 2fd80a3e3..bfe6abcc1 100755 --- a/whine.pl +++ b/whine.pl @@ -27,13 +27,12 @@ use strict; use lib "."; -require "globals.pl"; -use Bugzilla::Config qw(:DEFAULT $datadir); +use Bugzilla; use Bugzilla::Constants; use Bugzilla::Search; use Bugzilla::User; -use Bugzilla::BugMail; +use Bugzilla::Mailer; use Bugzilla::Util; # create some handles that we'll need @@ -94,33 +93,17 @@ my $sth_schedules_by_event = $dbh->prepare( # After that, it looks over each user to see if they have schedules that need # running, then runs those and generates the email messages. -# Send whines from the address in the 'maintainer' Parameter so that all +# Send whines from the address in the 'mailfrom' Parameter so that all # Bugzilla-originated mail appears to come from a single address. -my $fromaddress = Param('maintainer'); +my $fromaddress = Bugzilla->params->{'mailfrom'}; -if ($fromaddress !~ Param('emailregexp')) { - die "Cannot run. " . - "The maintainer email address has not been properly set!\n"; -} - -# Check the nomail file for users who should not receive mail -my %nomail; -if (open(NOMAIL, '<', "$datadir/nomail")) { - while (<NOMAIL>) { - $nomail{trim($_)} = 1; - } -} - -# get the current date and time from the database -$sth = $dbh->prepare('SELECT ' . $dbh->sql_date_format('NOW()', '%y,%m,%d,%a,%H,%i')); -$sth->execute; -my ($now_year, $now_month, $now_day, $now_weekdayname, $now_hour, $now_minute) = - split(',', $sth->fetchrow_array); -$sth->finish; - -# As DBs have different days numbering, use day name and convert it -# to the range 0-6 -my $now_weekday = index("SunMonTueWedThuFriSat", $now_weekdayname) / 3; +# get the current date and time +my ($now_sec, $now_minute, $now_hour, $now_day, $now_month, $now_year, + $now_weekday) = localtime; +# Convert year to two digits +$now_year = sprintf("%02d", $now_year % 100); +# Convert the month to January being "1" instead of January being "0". +$now_month++; my @daysinmonth = qw(0 31 28 31 30 31 30 31 31 30 31 30 31); # Alter February in case of a leap year. This simple way to do it only @@ -377,7 +360,7 @@ sub mail { my $args = shift; # Don't send mail to someone on the nomail list. - return if $nomail{$args->{'recipient'}->{'login'}}; + return if $args->{recipient}->email_disabled; my $msg = ''; # it's a temporary variable to hold the template output $args->{'alternatives'} ||= []; @@ -409,7 +392,7 @@ sub mail { $template->process("whine/multipart-mime.txt.tmpl", $args, \$msg) or die($template->error()); - Bugzilla::BugMail::MessageToMTA($msg); + MessageToMTA($msg); delete $args->{'boundary'}; delete $args->{'alternatives'}; diff --git a/whineatnews.pl b/whineatnews.pl index 50e06383e..42df7be55 100755 --- a/whineatnews.pl +++ b/whineatnews.pl @@ -30,29 +30,32 @@ use strict; use lib '.'; -require "globals.pl"; - -use Bugzilla::BugMail; +use Bugzilla; +use Bugzilla::Mailer; use Bugzilla::Util; # Whining is disabled if whinedays is zero -exit unless Param('whinedays') >= 1; +exit unless Bugzilla->params->{'whinedays'} >= 1; my $dbh = Bugzilla->dbh; -SendSQL("SELECT bug_id, short_desc, login_name " . - "FROM bugs INNER JOIN profiles ON userid = assigned_to " . - "WHERE (bug_status = 'NEW' OR bug_status = 'REOPENED') " . - "AND " . $dbh->sql_to_days('NOW()') . " - " . - $dbh->sql_to_days('delta_ts') . " > " . - Param('whinedays') . " " . - "ORDER BY bug_id"); +my $query = q{SELECT bug_id, short_desc, login_name + FROM bugs + INNER JOIN profiles + ON userid = assigned_to + WHERE (bug_status = ? OR bug_status = ?) + AND disable_mail = 0 + AND } . $dbh->sql_to_days('NOW()') . " - " . + $dbh->sql_to_days('delta_ts') . " > " . + Bugzilla->params->{'whinedays'} . + " ORDER BY bug_id"; my %bugs; my %desc; -my @row; -while (@row = FetchSQLData()) { - my ($id, $desc, $email) = (@row); +my $slt_bugs = $dbh->selectall_arrayref($query, undef, 'NEW', 'REOPENED'); + +foreach my $bug (@$slt_bugs) { + my ($id, $desc, $email) = @$bug; if (!defined $bugs{$email}) { $bugs{$email} = []; } @@ -64,22 +67,25 @@ while (@row = FetchSQLData()) { } -my $template = Param('whinemail'); -my $urlbase = Param('urlbase'); -my $emailsuffix = Param('emailsuffix'); - foreach my $email (sort (keys %bugs)) { - my %substs; - $substs{'email'} = $email . $emailsuffix; - $substs{'userid'} = $email; - my $msg = perform_substs($template, \%substs); + my $vars = { + 'email' => $email + }; + my @bugs = (); foreach my $i (@{$bugs{$email}}) { - $msg .= " " . shift(@{$desc{$email}}) . "\n"; - $msg .= " -> ${urlbase}show_bug.cgi?id=$i\n"; + my $bug = {}; + $bug->{'summary'} = shift(@{$desc{$email}}); + $bug->{'id'} = $i; + push @bugs, $bug; } + $vars->{'bugs'} = \@bugs; + + my $msg; + my $template = Bugzilla->template; + $template->process("email/whine.txt.tmpl", $vars, \$msg); - Bugzilla::BugMail::MessageToMTA($msg); + MessageToMTA($msg); print "$email " . join(" ", @{$bugs{$email}}) . "\n"; } diff --git a/xmlrpc.cgi b/xmlrpc.cgi new file mode 100755 index 000000000..c17cab86c --- /dev/null +++ b/xmlrpc.cgi @@ -0,0 +1,39 @@ +#!/usr/bin/perl -wT +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Marc Schumann <wurblzap@gmail.com> + +use strict; +use lib qw(.); + +use Bugzilla; +use Bugzilla::Constants; + +# Use an eval here so that runtests.pl accepts this script even if SOAP-Lite +# is not installed. +eval 'use XMLRPC::Transport::HTTP; + use Bugzilla::WebService;'; +$@ && ThrowCodeError('soap_not_installed'); + +Bugzilla->usage_mode(Bugzilla::Constants::USAGE_MODE_WEBSERVICE); + +my $response = Bugzilla::WebService::XMLRPC::Transport::HTTP::CGI + ->dispatch_with({'Bugzilla' => 'Bugzilla::WebService::Bugzilla', + 'Bug' => 'Bugzilla::WebService::Bug', + 'User' => 'Bugzilla::WebService::User', + 'Product' => 'Bugzilla::WebService::Product', + }) + ->on_action(\&Bugzilla::WebService::handle_login) + ->handle; -- GitLab