liquid_feedback_frontend

changeset 1045:701a5cf6b067

Imported LiquidFeedback Frontend 3.0 branch
author bsw
date Thu Jul 10 01:19:48 2014 +0200 (2014-07-10)
parents a6c7bf07badb
children b9300c2e75da
files INSTALL.html INSTALL.mkd LICENSE app/main/_filter/21_auth.lua app/main/_filter_view/30_navigation.lua app/main/_layout/default.html app/main/_layout/system_error.html app/main/admin/_action/area_update.lua app/main/admin/area_show.lua app/main/admin/cancel_issue.lua app/main/admin/index.lua app/main/admin/member_edit.lua app/main/admin/member_list.lua app/main/admin/policy_list.lua app/main/admin/policy_show.lua app/main/admin/unit_edit.lua app/main/area/_head.lua app/main/area/_issue_list.lua app/main/area/_sidebar_members.lua app/main/area/_sidebar_whatcanido.lua app/main/area/show.lua app/main/contact/list.lua app/main/delegation/_info.lua app/main/delegation/_list.lua app/main/delegation/show.lua app/main/delegation/show_incoming.lua app/main/draft/_action/add.lua app/main/draft/diff.lua app/main/draft/list.lua app/main/draft/new.lua app/main/draft/show.lua app/main/event/_list.lua app/main/help/introduction.lua app/main/index/404.lua app/main/index/_action/login.lua app/main/index/_login.lua app/main/index/_motd.lua app/main/index/_sidebar_members.lua app/main/index/_sidebar_motd_intern.lua app/main/index/_sidebar_motd_public.lua app/main/index/_sidebar_notifications.lua app/main/index/_sidebar_units.lua app/main/index/_sidebar_whatcanido.lua app/main/index/about.lua app/main/index/check_delegations.lua app/main/index/document.lua app/main/index/download.lua app/main/index/email_unconfirmed.lua app/main/index/index.lua app/main/index/login.lua app/main/index/notifications.lua app/main/index/register.lua app/main/index/reset_password.lua app/main/index/search.lua app/main/index/send_login.lua app/main/index/usage_terms.lua app/main/initiative/_action/add_support.lua app/main/initiative/_action/create.lua app/main/initiative/_action/remove_support.lua app/main/initiative/_bargraph.lua app/main/initiative/_battles.lua app/main/initiative/_head.lua app/main/initiative/_initiators.lua app/main/initiative/_list.lua app/main/initiative/_list_element.lua app/main/initiative/_show.lua app/main/initiative/_sidebar_history.lua app/main/initiative/_sidebar_policies.lua app/main/initiative/_sidebar_state.lua app/main/initiative/_sidebar_support.lua app/main/initiative/_sidebar_wikisyntax.lua app/main/initiative/add_initiator.lua app/main/initiative/history.lua app/main/initiative/new.lua app/main/initiative/remove_initiator.lua app/main/initiative/revoke.lua app/main/initiative/show.lua app/main/interest/_action/update.lua app/main/interest/show_incoming.lua app/main/issue/_details.lua app/main/issue/_filters.lua app/main/issue/_head.lua app/main/issue/_head2.lua app/main/issue/_list.lua app/main/issue/_list2.lua app/main/issue/_show.lua app/main/issue/_sidebar_issue.lua app/main/issue/_sidebar_members.lua app/main/issue/_sidebar_state.lua app/main/issue/_sidebar_whatcanido.lua app/main/issue/history.lua app/main/issue/list.lua app/main/issue/show.lua app/main/member/_action/update.lua app/main/member/_event_list.lua app/main/member/_list.lua app/main/member/_profile.lua app/main/member/_show.lua app/main/member/_show_thumb.lua app/main/member/_sidebar_contacts.lua app/main/member/_sidebar_whatcanido.lua app/main/member/developer_settings.lua app/main/member/edit.lua app/main/member/edit_images.lua app/main/member/history.lua app/main/member/list.lua app/main/member/settings.lua app/main/member/settings_email.lua app/main/member/settings_login.lua app/main/member/settings_name.lua app/main/member/settings_notification.lua app/main/member/settings_password.lua app/main/member/show.lua app/main/membership/_action/update.lua app/main/opinion/_action/update.lua app/main/policy/_list.lua app/main/policy/list.lua app/main/slideshow/_index.lua app/main/slideshow/_slideshow.lua app/main/slideshow/index.lua app/main/suggestion/_action/add.lua app/main/suggestion/new.lua app/main/supporter/show_incoming.lua app/main/timeline/_action/delete_filter.lua app/main/timeline/_action/save.lua app/main/timeline/_action/update.lua app/main/timeline/_constants.lua app/main/timeline/_filter/29_filter.lua app/main/timeline/_list.lua app/main/timeline/index.lua app/main/timeline/list_filter.lua app/main/timeline/save_filter.lua app/main/unit/_head.lua app/main/unit/_list.lua app/main/unit/_sidebar.lua app/main/unit/_sidebar_members.lua app/main/unit/_sidebar_whatcanido.lua app/main/unit/list.lua app/main/unit/show.lua app/main/vote/_action/update.lua app/main/vote/list.lua app/main/vote/show_incoming.lua config/devel.lua config/example.lua config/init.lua config/lf3.lua env/format/interval_text.lua env/format/wiki_text.lua env/model/has_rendered_content.lua env/ui/actions.lua env/ui/bargraph.lua env/ui/contextbar.lua env/ui/delegation.lua env/ui/filters.lua env/ui/raw_title.lua env/ui/section.lua env/ui/sectionHead.lua env/ui/sectionRow.lua env/ui/sidebar.lua env/ui/sidebarHead.lua env/ui/sidebarHeadWhatCanIDo.lua env/ui/sidebarSection.lua env/ui/title.lua env/ui/titleAdmin.lua env/ui/titleMember.lua env/util/help.lua env/util/initiative_pie.lua env/util/micro_avatar.lua locale/Makefile locale/help/area.show.de.txt locale/help/area.show.el.txt locale/help/area.show.en.txt locale/help/area.show.zh-Hans.txt locale/help/area.show.zh-TW.txt locale/help/contact.list.de.txt locale/help/contact.list.el.txt locale/help/contact.list.en.txt locale/help/contact.list.eo.txt locale/help/contact.list.zh-Hans.txt locale/help/contact.list.zh-TW.txt locale/help/delegation.new.area.de.txt locale/help/delegation.new.area.el.txt locale/help/delegation.new.area.en.txt locale/help/delegation.new.area.eo.txt locale/help/delegation.new.area.zh-Hans.txt locale/help/delegation.new.area.zh-TW.txt locale/help/delegation.new.issue.de.txt locale/help/delegation.new.issue.el.txt locale/help/delegation.new.issue.en.txt locale/help/delegation.new.issue.eo.txt locale/help/delegation.new.issue.zh-Hans.txt locale/help/delegation.new.issue.zh-TW.txt locale/help/delegation.new.unit.de.txt locale/help/delegation.new.unit.el.txt locale/help/delegation.new.unit.en.txt locale/help/delegation.new.unit.zh-Hans.txt locale/help/delegation.new.unit.zh-TW.txt locale/help/index.check_delegations.de.txt locale/help/index.check_delegations.en.txt locale/help/index.check_delegations_hard.de.txt locale/help/index.check_delegations_hard.en.txt locale/help/index.download.de.txt locale/help/index.download.el.txt locale/help/index.download.en.txt locale/help/index.download.eo.txt locale/help/index.download.zh-Hans.txt locale/help/index.download.zh-TW.txt locale/help/index.index.de.txt locale/help/index.index.el.txt locale/help/index.index.en.txt locale/help/index.index.zh-Hans.txt locale/help/index.index.zh-TW.txt locale/help/initiative.add_initiator.de.txt locale/help/initiative.add_initiator.el.txt locale/help/initiative.add_initiator.en.txt locale/help/initiative.add_initiator.eo.txt locale/help/initiative.add_initiator.zh-Hans.txt locale/help/initiative.add_initiator.zh-TW.txt locale/help/initiative.remove_initiator.de.txt locale/help/initiative.remove_initiator.el.txt locale/help/initiative.remove_initiator.en.txt locale/help/initiative.remove_initiator.eo.txt locale/help/initiative.remove_initiator.zh-Hans.txt locale/help/initiative.remove_initiator.zh-TW.txt locale/help/initiative.revoke.de.txt locale/help/initiative.revoke.el.txt locale/help/initiative.revoke.en.txt locale/help/initiative.revoke.eo.txt locale/help/initiative.revoke.zh-Hans.txt locale/help/initiative.revoke.zh-TW.txt locale/help/initiative.show.de.txt locale/help/initiative.show.el.txt locale/help/initiative.show.en.txt locale/help/initiative.show.eo.txt locale/help/initiative.show.zh-Hans.txt locale/help/initiative.show.zh-TW.txt locale/help/issue.show.de.txt locale/help/issue.show.el.txt locale/help/issue.show.en.txt locale/help/issue.show.zh-Hans.txt locale/help/issue.show.zh-TW.txt locale/help/member.edit.de.txt locale/help/member.edit.el.txt locale/help/member.edit.en.txt locale/help/member.edit.eo.txt locale/help/member.edit.zh-Hans.txt locale/help/member.edit.zh-TW.txt locale/help/member.edit_images.de.txt locale/help/member.edit_images.el.txt locale/help/member.edit_images.en.txt locale/help/member.edit_images.eo.txt locale/help/member.edit_images.zh-Hans.txt locale/help/member.edit_images.zh-TW.txt locale/help/member.settings.email_address.de.txt locale/help/member.settings.email_address.el.txt locale/help/member.settings.email_address.en.txt locale/help/member.settings.email_address.zh-Hans.txt locale/help/member.settings.email_address.zh-TW.txt locale/help/member.settings.login.de.txt locale/help/member.settings.login.el.txt locale/help/member.settings.login.en.txt locale/help/member.settings.login.eo.txt locale/help/member.settings.login.zh-Hans.txt locale/help/member.settings.login.zh-TW.txt locale/help/member.settings.name.de.txt locale/help/member.settings.name.el.txt locale/help/member.settings.name.en.txt locale/help/member.settings.name.eo.txt locale/help/member.settings.name.zh-Hans.txt locale/help/member.settings.name.zh-TW.txt locale/help/member.settings.notification.de.txt locale/help/member.settings.notification.el.txt locale/help/member.settings.notification.en.txt locale/help/member.settings.notification.zh-Hans.txt locale/help/member.settings.notification.zh-TW.txt locale/help/member.settings.password.de.txt locale/help/member.settings.password.el.txt locale/help/member.settings.password.en.txt locale/help/member.settings.password.eo.txt locale/help/member.settings.password.zh-Hans.txt locale/help/member.settings.password.zh-TW.txt locale/help/member.show.de.txt locale/help/member.show.el.txt locale/help/member.show.en.txt locale/help/member.show.eo.txt locale/help/member.show.zh-Hans.txt locale/help/member.show.zh-TW.txt locale/help/policy.list.de.txt locale/help/policy.list.el.txt locale/help/policy.list.en.txt locale/help/policy.list.eo.txt locale/help/policy.list.zh-Hans.txt locale/help/policy.list.zh-TW.txt locale/help/vote.list.de.txt locale/help/vote.list.el.txt locale/help/vote.list.en.txt locale/help/vote.list.eo.txt locale/help/vote.list.zh-Hans.txt locale/help/vote.list.zh-TW.txt locale/help/wikisyntax.en.txt locale/help/wikisyntax_compat.en.txt locale/help/wikisyntax_rocketwiki.en.txt locale/translations.de.lua model/battle.lua model/contact.lua model/initiative.lua model/issue.lua model/member.lua static/back.png static/back50.png static/icons/16/chart_organisation.png static/icons/32/empty.png static/icons/32/phase_current.png static/icons/32/phase_failed.png static/icons/32/phase_finished.png static/icons/32/support_none.png static/icons/32/support_satisfied.png static/icons/32/support_satisfied_via_delegation.png static/icons/32/support_unsatisfied.png static/icons/32/support_unsatisfied_via_delegation.png static/icons/32/voted_no.png static/icons/48/bell.png static/icons/48/eye.png static/icons/48/home.png static/icons/48/info.png static/icons/48/lf_plus.png static/icons/48/star.png static/icons/48/star_empty.png static/icons/48/voted_ok.png static/js/less-1.4.1.min.js static/lf3.css static/lf3.less static/star.png static/style.css utils/optparse.lua
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/INSTALL.html	Thu Jul 10 01:19:48 2014 +0200
     1.3 @@ -0,0 +1,191 @@
     1.4 +<html>
     1.5 +<head>
     1.6 +  <title>LiquidFeedback Installation Instructions</title>
     1.7 +  <style type="text/css">code{white-space: pre;}</style>
     1.8 +</head>
     1.9 +<body>
    1.10 +<h1 id="liquidfeedback-installation-instructions">LiquidFeedback Installation Instructions</h1>
    1.11 +<p>This document gives a short outline about the necessary steps to setup a LiquidFeedback system.</p>
    1.12 +<h2 id="install-necessary-dependencies">1. Install necessary dependencies</h2>
    1.13 +<p>If you're using a Debian system, make sure that the following packages are installed:</p>
    1.14 +<ul>
    1.15 +<li>lua5.1</li>
    1.16 +<li>postgresql</li>
    1.17 +<li>build-essential</li>
    1.18 +<li>libpq-dev</li>
    1.19 +<li>liblua5.1-0-dev</li>
    1.20 +<li>lighttpd</li>
    1.21 +<li>ghc</li>
    1.22 +<li>libghc6-parsec3-dev</li>
    1.23 +<li>imagemagick</li>
    1.24 +<li>exim4</li>
    1.25 +</ul>
    1.26 +<p>If you're using any other Linux distribution or BSD system, install the necessary software components accordingly.</p>
    1.27 +<h2 id="ensure-that-the-user-account-of-your-webserver-has-access-to-the-database">2. Ensure that the user account of your webserver has access to the database</h2>
    1.28 +<p>Whichever useraccount is used by the webserver (usually <code>www-data</code>) needs to have access to your PostgreSQL installation. This is done by executing PostgreSQL's shell command <code>createuser</code> as database superuser (usually <code>pgsql</code>, or <code>postgres</code> for Debian installations):</p>
    1.29 +<pre><code>su - postgres
    1.30 +createuser
    1.31 +
    1.32 +Enter name of role to add: www-data
    1.33 +Shall the new role be a superuser? (y/n) n
    1.34 +Shall the new role be allowed to create databases? (y/n) y
    1.35 +Shall the new role be allowed to create more new roles? (y/n) n
    1.36 +
    1.37 +exit</code></pre>
    1.38 +<h2 id="install-and-configure-liquidfeedback-core">3. Install and configure LiquidFeedback-Core</h2>
    1.39 +<p>We recommend to create the database with the same user as your webserver (usually <code>www-data</code>) to avoid having to setup database privileges.</p>
    1.40 +<p>The example below installs the database as <code>www-data</code> and stores the two executables <code>lf_update</code> and <code>lf_update_issue_order</code> in the directory <code>/opt/liquid_feedback_core/</code>:</p>
    1.41 +<pre><code># Download and unpack LiquidFeedback-Core
    1.42 +# from http://www.public-software-group.org/pub/projects/liquid_feedback/backend/
    1.43 +make
    1.44 +mkdir /opt/liquid_feedback_core
    1.45 +cp core.sql lf_update lf_update_issue_order /opt/liquid_feedback_core
    1.46 +su - www-data
    1.47 +cd /opt/liquid_feedback_core
    1.48 +createdb liquid_feedback
    1.49 +createlang plpgsql liquid_feedback  # command may be omitted, depending on PostgreSQL version
    1.50 +psql -v ON_ERROR_STOP=1 -f core.sql liquid_feedback</code></pre>
    1.51 +<p>A simple configuration may look as follows:</p>
    1.52 +<pre><code>psql liquid_feedback
    1.53 +
    1.54 +INSERT INTO system_setting (member_ttl) VALUES (&#39;1 year&#39;);
    1.55 +INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (false, &#39;1 hour&#39;, 20, 6);
    1.56 +INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (false, &#39;1 day&#39;, 80, 12);
    1.57 +INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (true, &#39;1 hour&#39;, 200, 60);
    1.58 +INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (true, &#39;1 day&#39;, 800, 120);
    1.59 +INSERT INTO policy (index, name, admission_time, discussion_time, verification_time, voting_time, issue_quorum_num, issue_quorum_den, initiative_quorum_num, initiative_quorum_den) VALUES (1, &#39;Default policy&#39;, &#39;8 days&#39;, &#39;15 days&#39;, &#39;8 days&#39;, &#39;15 days&#39;, 10, 100, 10, 100);
    1.60 +INSERT INTO unit (name) VALUES (&#39;Our organization&#39;);
    1.61 +INSERT INTO area (unit_id, name) VALUES (1, &#39;Default area&#39;);
    1.62 +INSERT INTO allowed_policy (area_id, policy_id, default_policy) VALUES (1, 1, TRUE);</code></pre>
    1.63 +<p>If you want to create an admin user with an empty password (CAUTION!), then execute the following SQL statement:</p>
    1.64 +<pre><code>INSERT INTO member (login, name, admin, password) VALUES (&#39;admin&#39;, &#39;Administrator&#39;, TRUE, &#39;$1$/EMPTY/$NEWt7XJg2efKwPm4vectc1&#39;);</code></pre>
    1.65 +<p>Exit the <code>psql</code> interface by typing:</p>
    1.66 +<pre><code>\q</code></pre>
    1.67 +<p>And don't forget to quit the <code>www-data</code> shell:</p>
    1.68 +<pre><code>exit</code></pre>
    1.69 +<h2 id="install-webmcp">4. Install WebMCP</h2>
    1.70 +<p>Note: Using Debian, it may be necessary to append <code>-I /usr/include/lua5.1</code> at the end of the CFLAGS line in <code>Makefile.options</code> of the WebMCP source distibution:</p>
    1.71 +<pre><code># Download and unpack WebMCP
    1.72 +# from http://www.public-software-group.org/pub/projects/webmcp/
    1.73 +vi Makefile.options  # Debian requires  -I /usr/include/lua5.1  at end of CFLAGS line
    1.74 +make
    1.75 +mkdir /opt/webmcp
    1.76 +cp -RL framework/* /opt/webmcp/</code></pre>
    1.77 +<h2 id="install-rocketwiki-lqfb-edition">5. Install RocketWiki LqFb-Edition</h2>
    1.78 +<pre><code># Download and unpack &quot;RocketWiki LqFb-Edition&quot;
    1.79 +# from http://www.public-software-group.org/pub/projects/rocketwiki/liquid_feedback_edition/
    1.80 +make
    1.81 +mkdir /opt/rocketwiki-lqfb
    1.82 +cp rocketwiki-lqfb rocketwiki-lqfb-compat /opt/rocketwiki-lqfb/</code></pre>
    1.83 +<p>If you experience problems with multi-byte encoding (UTF-8) later, then apply the following patch to both <code>rocketwiki-lqfb.hs</code> and <code>rocketwiki-lqfb-compat.hs</code> prior compilation:</p>
    1.84 +<pre><code>--- rocketwiki-lqfb.hs
    1.85 ++++ rocketwiki-lqfb.hs
    1.86 +@@ -1,4 +1,6 @@
    1.87 +
    1.88 ++import System.IO (hSetEncoding, stdin, stdout, utf8)
    1.89 ++
    1.90 + import Text.ParserCombinators.Parsec
    1.91 + import Control.Applicative ((&lt;$&gt;), (&lt;*&gt;))
    1.92 + import Data.List (intercalate)
    1.93 +@@ -405,7 +407,10 @@
    1.94 +       return htmlEntity
    1.95 + 
    1.96 + 
    1.97 +-main = interact wikiParse
    1.98 ++main = do
    1.99 ++  hSetEncoding stdin utf8
   1.100 ++  hSetEncoding stdout utf8
   1.101 ++  interact wikiParse
   1.102 +
   1.103 + wikiParse str
   1.104 +   | success parseResult = html</code></pre>
   1.105 +<h2 id="install-the-liquidfeedback-frontend">6. Install the LiquidFeedback-Frontend</h2>
   1.106 +<p>Unpack source tree into appropriate directory, e.g. <code>/opt/liquid_feedback_frontend</code>:</p>
   1.107 +<pre><code># Download LiquidFeedback-Frontend
   1.108 +# from http://www.public-software-group.org/pub/projects/liquid_feedback/frontend/
   1.109 +mv liquid_feedback_frontend-vX.X.X /opt/liquid_feedback_frontend</code></pre>
   1.110 +<p>Create HTML code for help texts:</p>
   1.111 +<pre><code>cd /opt/liquid_feedback_frontend/locale
   1.112 +PATH=/opt/rocketwiki-lqfb:$PATH make</code></pre>
   1.113 +<p>Make <code>tmp/</code> directory of LiquidFeedback-Frontend writable for webserver:</p>
   1.114 +<pre><code>chown www-data /opt/liquid_feedback_frontend/tmp</code></pre>
   1.115 +<p>Compile binary for fast delivery of member images:</p>
   1.116 +<pre><code>cd /opt/liquid_feedback_frontend/fastpath
   1.117 +vi getpic.c  # check and modify #define commands as necessary
   1.118 +make</code></pre>
   1.119 +<h2 id="configure-mail-system">7. Configure mail system</h2>
   1.120 +<p>It may be necessary to configure your server's mail system, e.g. running <code>dpkg-reconfigure exim4-config</code> on a Debian system.</p>
   1.121 +<h2 id="configure-the-webserver-for-liquidfeedback">8. Configure the Webserver for LiquidFeedback:</h2>
   1.122 +<p>A sample configuration for <code>lighttpd</code> is given below (assuming <code>mod_alias</code> has been included elsewhere):</p>
   1.123 +<pre><code>server.modules += (&quot;mod_cgi&quot;, &quot;mod_rewrite&quot;, &quot;mod_redirect&quot;, &quot;mod_setenv&quot;)
   1.124 +
   1.125 +# Enable CGI-Execution of *.lua files through lua binary
   1.126 +cgi.assign += ( &quot;.lua&quot; =&gt; &quot;/usr/bin/lua5.1&quot; )
   1.127 +
   1.128 +alias.url += ( &quot;/lf/fastpath/&quot; =&gt; &quot;/opt/liquid_feedback_frontend/fastpath/&quot;,
   1.129 +               &quot;/lf/static&quot;    =&gt; &quot;/opt/liquid_feedback_frontend/static&quot;,
   1.130 +               &quot;/lf&quot;           =&gt; &quot;/opt/webmcp/cgi-bin&quot; )
   1.131 +
   1.132 +# Configure environment for demo application
   1.133 +$HTTP[&quot;url&quot;] =~ &quot;^/lf&quot; {
   1.134 +  setenv.add-environment += (
   1.135 +    &quot;LANG&quot; =&gt; &quot;en_US.UTF-8&quot;,
   1.136 +    &quot;WEBMCP_APP_BASEPATH&quot; =&gt; &quot;/opt/liquid_feedback_frontend/&quot;,
   1.137 +    &quot;WEBMCP_CONFIG_NAME&quot;  =&gt; &quot;myconfig&quot;)
   1.138 +}
   1.139 +
   1.140 +# URL beautification
   1.141 +url.rewrite-once += (
   1.142 +  # do not rewrite static URLs
   1.143 +      &quot;^/lf/fastpath/(.*)$&quot; =&gt; &quot;/lf/fastpath/$1&quot;,
   1.144 +      &quot;^/lf/static/(.*)$&quot;   =&gt; &quot;/lf/static/$1&quot;,
   1.145 +
   1.146 +  # dynamic URLs
   1.147 +      &quot;^/lf/([^\?]*)(\?(.*))?$&quot; =&gt; &quot;/lf/webmcp-wrapper.lua?_webmcp_path=$1&amp;$3&quot;,
   1.148 +
   1.149 +)
   1.150 +
   1.151 +$HTTP[&quot;url&quot;] =~ &quot;^/lf/fastpath/&quot; {
   1.152 +  cgi.assign = ( &quot;&quot; =&gt; &quot;&quot; )
   1.153 +  setenv.add-response-header = ( &quot;Cache-Control&quot; =&gt; &quot;private; max-age=86400&quot; )
   1.154 +}</code></pre>
   1.155 +<p>If you're using Debian, you may want to create a file with the name <code>/etc/lighttpd/conf-available/60-liquidfeedback.conf</code> and create a softlink in <code>/etc/lighttpd/conf-enabled/</code>.</p>
   1.156 +<h2 id="configure-the-liquidfeedback-frontend">9. Configure the LiquidFeedback-Frontend:</h2>
   1.157 +<pre><code>cd /opt/liquid_feedback_frontend/config
   1.158 +cp example.lua myconfig.lua
   1.159 +# edit myconfig.lua according to your needs</code></pre>
   1.160 +<p>Use the following option in your configuration file to enable fast image loading:</p>
   1.161 +<pre><code>config.fastpath_url_func = function(member_id, image_type)
   1.162 +  return request.get_absolute_baseurl() .. &quot;fastpath/getpic?&quot; .. tostring(member_id) .. &quot;+&quot; .. tostring(image_type)
   1.163 +end</code></pre>
   1.164 +<h2 id="setup-regular-execution-of-lf_update-and-lf_update_suggestion_order">10. Setup regular execution of <code>lf_update</code> and <code>lf_update_suggestion_order</code></h2>
   1.165 +<p>The executables <code>lf_update</code> and <code>lf_update_suggestion_order</code> must be executed regularly. This may be achieved by creating a file named <code>/opt/liquid_feedback_core/lf_updated</code> with the following contents:</p>
   1.166 +<pre><code>#!/bin/sh
   1.167 +
   1.168 +PIDFILE=&quot;/var/run/lf_updated.pid&quot;
   1.169 +PID=$$
   1.170 +
   1.171 +if [ -f &quot;${PIDFILE}&quot; ] &amp;&amp; kill -CONT $( cat &quot;${PIDFILE}&quot; ); then
   1.172 +  echo &quot;lf_updated is already running.&quot;
   1.173 +  exit 1
   1.174 +fi
   1.175 +
   1.176 +echo &quot;${PID}&quot; &gt; &quot;${PIDFILE}&quot;
   1.177 +
   1.178 +while true; do
   1.179 +  su - www-data -c &#39;nice /opt/liquid_feedback_core/lf_update dbname=liquid_feedback 2&gt;&amp;1 | logger -t &quot;lf_updated&quot;&#39;
   1.180 +  su - www-data -c &#39;nice /opt/liquid_feedback_core/lf_update_suggestion_order dbname=liquid_feedback 2&gt;&amp;1 | logger -t &quot;lf_updated&quot;&#39;
   1.181 +  sleep 5
   1.182 +done</code></pre>
   1.183 +<p>This file must be marked as executable:</p>
   1.184 +<pre><code>chmod +x /opt/liquid_feedback_core/lf_updated</code></pre>
   1.185 +<p>And this file should be started automatically at system boot.</p>
   1.186 +<h2 id="setup-notification-loop-in-background">11. Setup notification loop in background</h2>
   1.187 +<p>In addition to regular execution of <code>lf_update</code> and <code>lf_update_suggestion_order</code>, the following commands should be executed in background:</p>
   1.188 +<pre><code>su - www-data
   1.189 +cd /opt/liquid_feedback_frontend/
   1.190 +echo &quot;Event:send_notifications_loop()&quot; | ../webmcp/bin/webmcp_shell myconfig</code></pre>
   1.191 +<h2 id="start-the-sytem">12. Start the sytem</h2>
   1.192 +<p>After <code>lf_update</code> has been executed at least once, and the webserver has been restarted (using the configuration above), you should be able to access your LiquidFeedback system.</p>
   1.193 +</body>
   1.194 +</html>
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/INSTALL.mkd	Thu Jul 10 01:19:48 2014 +0200
     2.3 @@ -0,0 +1,289 @@
     2.4 +LiquidFeedback Installation Instructions
     2.5 +========================================
     2.6 +
     2.7 +This document gives a short outline about the necessary steps to setup a
     2.8 +LiquidFeedback system.
     2.9 +
    2.10 +
    2.11 +1. Install necessary dependencies
    2.12 +---------------------------------
    2.13 +
    2.14 +If you're using a Debian system, make sure that the following packages are
    2.15 +installed:
    2.16 +
    2.17 +  * lua5.1
    2.18 +  * postgresql
    2.19 +  * build-essential
    2.20 +  * libpq-dev
    2.21 +  * liblua5.1-0-dev
    2.22 +  * lighttpd
    2.23 +  * ghc
    2.24 +  * libghc6-parsec3-dev
    2.25 +  * imagemagick
    2.26 +  * exim4
    2.27 +
    2.28 +If you're using any other Linux distribution or BSD system, install the
    2.29 +necessary software components accordingly.
    2.30 +
    2.31 +
    2.32 +2. Ensure that the user account of your webserver has access to the database
    2.33 +----------------------------------------------------------------------------
    2.34 +
    2.35 +Whichever useraccount is used by the webserver (usually `www-data`) needs to
    2.36 +have access to your PostgreSQL installation. This is done by executing
    2.37 +PostgreSQL's shell command `createuser` as database superuser (usually `pgsql`,
    2.38 +or `postgres` for Debian installations):
    2.39 +
    2.40 +    su - postgres
    2.41 +    createuser
    2.42 +
    2.43 +    Enter name of role to add: www-data
    2.44 +    Shall the new role be a superuser? (y/n) n
    2.45 +    Shall the new role be allowed to create databases? (y/n) y
    2.46 +    Shall the new role be allowed to create more new roles? (y/n) n
    2.47 +
    2.48 +    exit
    2.49 +
    2.50 +
    2.51 +3. Install and configure LiquidFeedback-Core
    2.52 +--------------------------------------------
    2.53 +
    2.54 +We recommend to create the database with the same user as your webserver
    2.55 +(usually `www-data`) to avoid having to setup database privileges.
    2.56 +
    2.57 +The example below installs the database as `www-data` and stores the two
    2.58 +executables `lf_update` and `lf_update_issue_order` in the directory
    2.59 +`/opt/liquid_feedback_core/`:
    2.60 +
    2.61 +    # Download and unpack LiquidFeedback-Core
    2.62 +    # from http://www.public-software-group.org/pub/projects/liquid_feedback/backend/
    2.63 +    make
    2.64 +    mkdir /opt/liquid_feedback_core
    2.65 +    cp core.sql lf_update lf_update_issue_order /opt/liquid_feedback_core
    2.66 +    su - www-data
    2.67 +    cd /opt/liquid_feedback_core
    2.68 +    createdb liquid_feedback
    2.69 +    createlang plpgsql liquid_feedback  # command may be omitted, depending on PostgreSQL version
    2.70 +    psql -v ON_ERROR_STOP=1 -f core.sql liquid_feedback
    2.71 +
    2.72 +A simple configuration may look as follows:
    2.73 +
    2.74 +    psql liquid_feedback
    2.75 +
    2.76 +    INSERT INTO system_setting (member_ttl) VALUES ('1 year');
    2.77 +    INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (false, '1 hour', 20, 6);
    2.78 +    INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (false, '1 day', 80, 12);
    2.79 +    INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (true, '1 hour', 200, 60);
    2.80 +    INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (true, '1 day', 800, 120);
    2.81 +    INSERT INTO policy (index, name, admission_time, discussion_time, verification_time, voting_time, issue_quorum_num, issue_quorum_den, initiative_quorum_num, initiative_quorum_den) VALUES (1, 'Default policy', '8 days', '15 days', '8 days', '15 days', 10, 100, 10, 100);
    2.82 +    INSERT INTO unit (name) VALUES ('Our organization');
    2.83 +    INSERT INTO area (unit_id, name) VALUES (1, 'Default area');
    2.84 +    INSERT INTO allowed_policy (area_id, policy_id, default_policy) VALUES (1, 1, TRUE);
    2.85 +
    2.86 +If you want to create an admin user with an empty password (CAUTION!), then execute the following SQL statement:
    2.87 +
    2.88 +    INSERT INTO member (login, name, admin, password) VALUES ('admin', 'Administrator', TRUE, '$1$/EMPTY/$NEWt7XJg2efKwPm4vectc1');
    2.89 +
    2.90 +Exit the `psql` interface by typing:
    2.91 +
    2.92 +    \q
    2.93 +
    2.94 +And don't forget to quit the `www-data` shell:
    2.95 +
    2.96 +    exit
    2.97 +
    2.98 +
    2.99 +4. Install WebMCP
   2.100 +-----------------
   2.101 +
   2.102 +Note: Using Debian, it may be necessary to append `-I /usr/include/lua5.1` at
   2.103 +the end of the CFLAGS line in `Makefile.options` of the WebMCP source
   2.104 +distibution:
   2.105 +
   2.106 +    # Download and unpack WebMCP
   2.107 +    # from http://www.public-software-group.org/pub/projects/webmcp/
   2.108 +    vi Makefile.options  # Debian requires  -I /usr/include/lua5.1  at end of CFLAGS line
   2.109 +    make
   2.110 +    mkdir /opt/webmcp
   2.111 +    cp -RL framework/* /opt/webmcp/
   2.112 +
   2.113 +
   2.114 +5. Install RocketWiki LqFb-Edition
   2.115 +----------------------------------
   2.116 +
   2.117 +    # Download and unpack "RocketWiki LqFb-Edition"
   2.118 +    # from http://www.public-software-group.org/pub/projects/rocketwiki/liquid_feedback_edition/
   2.119 +    make
   2.120 +    mkdir /opt/rocketwiki-lqfb
   2.121 +    cp rocketwiki-lqfb rocketwiki-lqfb-compat /opt/rocketwiki-lqfb/
   2.122 +
   2.123 +If you experience problems with multi-byte encoding (UTF-8) later, then apply
   2.124 +the following patch to both `rocketwiki-lqfb.hs` and
   2.125 +`rocketwiki-lqfb-compat.hs` prior compilation:
   2.126 +
   2.127 +    --- rocketwiki-lqfb.hs
   2.128 +    +++ rocketwiki-lqfb.hs
   2.129 +    @@ -1,4 +1,6 @@
   2.130 + 
   2.131 +    +import System.IO (hSetEncoding, stdin, stdout, utf8)
   2.132 +    +
   2.133 +     import Text.ParserCombinators.Parsec
   2.134 +     import Control.Applicative ((<$>), (<*>))
   2.135 +     import Data.List (intercalate)
   2.136 +    @@ -405,7 +407,10 @@
   2.137 +           return htmlEntity
   2.138 +     
   2.139 +     
   2.140 +    -main = interact wikiParse
   2.141 +    +main = do
   2.142 +    +  hSetEncoding stdin utf8
   2.143 +    +  hSetEncoding stdout utf8
   2.144 +    +  interact wikiParse
   2.145 + 
   2.146 +     wikiParse str
   2.147 +       | success parseResult = html
   2.148 +
   2.149 +
   2.150 +6. Install the LiquidFeedback-Frontend
   2.151 +--------------------------------------
   2.152 +
   2.153 +Unpack source tree into appropriate directory, e.g. `/opt/liquid_feedback_frontend`:
   2.154 +
   2.155 +    # Download LiquidFeedback-Frontend
   2.156 +    # from http://www.public-software-group.org/pub/projects/liquid_feedback/frontend/
   2.157 +    mv liquid_feedback_frontend-vX.X.X /opt/liquid_feedback_frontend
   2.158 +
   2.159 +Create HTML code for help texts:
   2.160 +
   2.161 +    cd /opt/liquid_feedback_frontend/locale
   2.162 +    PATH=/opt/rocketwiki-lqfb:$PATH make
   2.163 +
   2.164 +Make `tmp/` directory of LiquidFeedback-Frontend writable for webserver:
   2.165 +
   2.166 +    chown www-data /opt/liquid_feedback_frontend/tmp
   2.167 +
   2.168 +Compile binary for fast delivery of member images:
   2.169 +
   2.170 +    cd /opt/liquid_feedback_frontend/fastpath
   2.171 +    vi getpic.c  # check and modify #define commands as necessary
   2.172 +    make
   2.173 +
   2.174 +
   2.175 +7. Configure mail system
   2.176 +------------------------
   2.177 +
   2.178 +It may be necessary to configure your server's mail system, e.g. running
   2.179 +`dpkg-reconfigure exim4-config` on a Debian system.
   2.180 +
   2.181 +
   2.182 +8. Configure the Webserver for LiquidFeedback:
   2.183 +----------------------------------------------
   2.184 +
   2.185 +A sample configuration for `lighttpd` is given below (assuming `mod_alias` has
   2.186 +been included elsewhere):
   2.187 +
   2.188 +    server.modules += ("mod_cgi", "mod_rewrite", "mod_redirect", "mod_setenv")
   2.189 +
   2.190 +    # Enable CGI-Execution of *.lua files through lua binary
   2.191 +    cgi.assign += ( ".lua" => "/usr/bin/lua5.1" )
   2.192 +
   2.193 +    alias.url += ( "/lf/fastpath/" => "/opt/liquid_feedback_frontend/fastpath/",
   2.194 +                   "/lf/static"    => "/opt/liquid_feedback_frontend/static",
   2.195 +                   "/lf"           => "/opt/webmcp/cgi-bin" )
   2.196 +
   2.197 +    # Configure environment for demo application
   2.198 +    $HTTP["url"] =~ "^/lf" {
   2.199 +      setenv.add-environment += (
   2.200 +        "LANG" => "en_US.UTF-8",
   2.201 +        "WEBMCP_APP_BASEPATH" => "/opt/liquid_feedback_frontend/",
   2.202 +        "WEBMCP_CONFIG_NAME"  => "myconfig")
   2.203 +    }
   2.204 +
   2.205 +    # URL beautification
   2.206 +    url.rewrite-once += (
   2.207 +      # do not rewrite static URLs
   2.208 +          "^/lf/fastpath/(.*)$" => "/lf/fastpath/$1",
   2.209 +          "^/lf/static/(.*)$"   => "/lf/static/$1",
   2.210 +
   2.211 +      # dynamic URLs
   2.212 +          "^/lf/([^\?]*)(\?(.*))?$" => "/lf/webmcp-wrapper.lua?_webmcp_path=$1&$3",
   2.213 +
   2.214 +    )
   2.215 +
   2.216 +    $HTTP["url"] =~ "^/lf/fastpath/" {
   2.217 +      cgi.assign = ( "" => "" )
   2.218 +      setenv.add-response-header = ( "Cache-Control" => "private; max-age=86400" )
   2.219 +    }
   2.220 +
   2.221 +If you're using Debian, you may want to create a file with the name
   2.222 +`/etc/lighttpd/conf-available/60-liquidfeedback.conf` and create a softlink in
   2.223 +`/etc/lighttpd/conf-enabled/`.
   2.224 +
   2.225 +
   2.226 +9. Configure the LiquidFeedback-Frontend:
   2.227 +-----------------------------------------
   2.228 +
   2.229 +    cd /opt/liquid_feedback_frontend/config
   2.230 +    cp example.lua myconfig.lua
   2.231 +    # edit myconfig.lua according to your needs
   2.232 +
   2.233 +Use the following option in your configuration file to enable fast image
   2.234 +loading:
   2.235 +
   2.236 +    config.fastpath_url_func = function(member_id, image_type)
   2.237 +      return request.get_absolute_baseurl() .. "fastpath/getpic?" .. tostring(member_id) .. "+" .. tostring(image_type)
   2.238 +    end
   2.239 +
   2.240 +
   2.241 +10. Setup regular execution of `lf_update` and `lf_update_suggestion_order`
   2.242 +---------------------------------------------------------------------------
   2.243 +
   2.244 +The executables `lf_update` and `lf_update_suggestion_order` must be executed
   2.245 +regularly. This may be achieved by creating a file named
   2.246 +`/opt/liquid_feedback_core/lf_updated` with the following contents:
   2.247 +
   2.248 +    #!/bin/sh
   2.249 +
   2.250 +    PIDFILE="/var/run/lf_updated.pid"
   2.251 +    PID=$$
   2.252 +
   2.253 +    if [ -f "${PIDFILE}" ] && kill -CONT $( cat "${PIDFILE}" ); then
   2.254 +      echo "lf_updated is already running."
   2.255 +      exit 1
   2.256 +    fi
   2.257 +
   2.258 +    echo "${PID}" > "${PIDFILE}"
   2.259 +
   2.260 +    while true; do
   2.261 +      su - www-data -c 'nice /opt/liquid_feedback_core/lf_update dbname=liquid_feedback 2>&1 | logger -t "lf_updated"'
   2.262 +      su - www-data -c 'nice /opt/liquid_feedback_core/lf_update_suggestion_order dbname=liquid_feedback 2>&1 | logger -t "lf_updated"'
   2.263 +      sleep 5
   2.264 +    done
   2.265 +
   2.266 +This file must be marked as executable:
   2.267 +
   2.268 +    chmod +x /opt/liquid_feedback_core/lf_updated
   2.269 +
   2.270 +And this file should be started automatically at system boot.
   2.271 +
   2.272 +
   2.273 +11. Setup notification loop in background
   2.274 +-----------------------------------------
   2.275 +
   2.276 +In addition to regular execution of `lf_update` and
   2.277 +`lf_update_suggestion_order`, the following commands should be executed in
   2.278 +background:
   2.279 +
   2.280 +    su - www-data
   2.281 +    cd /opt/liquid_feedback_frontend/
   2.282 +    echo "Event:send_notifications_loop()" | ../webmcp/bin/webmcp_shell myconfig
   2.283 +
   2.284 +
   2.285 +12. Start the sytem
   2.286 +-------------------
   2.287 +
   2.288 +After `lf_update` has been executed at least once, and the webserver has been
   2.289 +restarted (using the configuration above), you should be able to access your
   2.290 +LiquidFeedback system.
   2.291 +
   2.292 +
     3.1 --- a/LICENSE	Thu Jul 10 01:02:43 2014 +0200
     3.2 +++ b/LICENSE	Thu Jul 10 01:19:48 2014 +0200
     3.3 @@ -1,4 +1,4 @@
     3.4 -Copyright (c) 2009-2013 Public Software Group e. V., Berlin, Germany
     3.5 +Copyright (c) 2009-2014 Public Software Group e. V., Berlin, Germany
     3.6  
     3.7  Permission is hereby granted, free of charge, to any person obtaining a
     3.8  copy of this software and associated documentation files (the "Software"),
     4.1 --- a/app/main/_filter/21_auth.lua	Thu Jul 10 01:02:43 2014 +0200
     4.2 +++ b/app/main/_filter/21_auth.lua	Thu Jul 10 01:19:48 2014 +0200
     4.3 @@ -5,8 +5,7 @@
     4.4  local auth_needed = not (
     4.5    module == 'index'
     4.6    and (
     4.7 -       view   == "index"
     4.8 -    or view   == "login"
     4.9 +view   == "login"
    4.10      or action == "login"
    4.11      or view   == "register"
    4.12      or action == "register"
    4.13 @@ -26,16 +25,17 @@
    4.14  if app.session:has_access("anonymous") then
    4.15  
    4.16    if
    4.17 -    module == "area" and view == "show"
    4.18 +    module == "index" and view == "index"
    4.19 +    or module == "area" and view == "show"
    4.20      or module == "unit" and view == "show"
    4.21      or module == "policy" and view == "show"
    4.22      or module == "policy" and view == "list"
    4.23      or module == "issue" and view == "show"
    4.24      or module == "initiative" and view == "show"
    4.25 +    or module == "initiative" and view == "history"
    4.26      or module == "suggestion" and view == "show"
    4.27      or module == "draft" and view == "diff"
    4.28      or module == "draft" and view == "show"
    4.29 -    or module == "draft" and view == "list"
    4.30      or module == "index" and view == "search"
    4.31      or module == "index" and view == "usage_terms"
    4.32    then
    4.33 @@ -44,11 +44,16 @@
    4.34  
    4.35  end
    4.36  
    4.37 +if app.session:has_access("authors_pseudonymous") then
    4.38 +  if module == "member_image" and view == "show" then
    4.39 +    auth_needed = false
    4.40 +  end
    4.41 +end
    4.42 +
    4.43  if app.session:has_access("all_pseudonymous") then
    4.44 -  if module == "member_image" and view == "show"
    4.45 -   or module == "vote" and view == "show_incoming"
    4.46 +  if module == "vote" and view == "show_incoming"
    4.47 +   or module == "member" and view == "list"
    4.48     or module == "interest" and view == "show_incoming"
    4.49 -   or module == "supporter" and view == "show_incoming" 
    4.50     or module == "vote" and view == "list" then
    4.51      auth_needed = false
    4.52    end
     5.1 --- a/app/main/_filter_view/30_navigation.lua	Thu Jul 10 01:02:43 2014 +0200
     5.2 +++ b/app/main/_filter_view/30_navigation.lua	Thu Jul 10 01:19:48 2014 +0200
     5.3 @@ -1,88 +1,86 @@
     5.4 -slot.select('navigation', function()
     5.5 +slot.select ( 'instance_name', function ()
     5.6 +  slot.put ( encode.html ( config.instance_name ) )
     5.7 +end)
     5.8  
     5.9 -  ui.link{
    5.10 -    content = function()
    5.11 -      ui.tag{ attr = { class = "logo_liquidfeedback" }, content = _"LiquidFeedback" }
    5.12 -      slot.put(" &middot; ")
    5.13 -      ui.tag{ content = config.instance_name }
    5.14 -    end,
    5.15 -    module = 'index',
    5.16 -    view   = 'index'
    5.17 -  }
    5.18    
    5.19 -  if app.session:has_access("anonymous") and not (app.session.needs_delegation_check) then
    5.20 +slot.select ( 'navigation_right', function ()
    5.21  
    5.22 -    ui.link{
    5.23 -      content = _"Search",
    5.24 -      module = 'index',
    5.25 -      view   = 'search'
    5.26 -    }
    5.27 +  if app.session:has_access ("anonymous") and not (app.session.needs_delegation_check) then
    5.28    
    5.29 -    if app.session.member == nil then
    5.30 -      ui.link{
    5.31 -        text   = _"Login",
    5.32 -        module = 'index',
    5.33 -        view   = 'login',
    5.34 -        params = {
    5.35 -          redirect_module = request.get_module(),
    5.36 -          redirect_view = request.get_view(),
    5.37 -          redirect_id = param.get_id()
    5.38 +    ui.form {
    5.39 +      attr = { class = "inline search" },
    5.40 +      method = "get",
    5.41 +      module = "index", view   = "search",
    5.42 +      content = function ()
    5.43 +        
    5.44 +        ui.field.text {
    5.45 +          attr = { placeholder = "search" },
    5.46 +          name = "q"
    5.47          }
    5.48 -      }
    5.49 -    end
    5.50 +        
    5.51 +      end 
    5.52 +    }
    5.53 +
    5.54 +    ui.link {
    5.55 +      attr = { class = "searchLink" },
    5.56 +      module = "index", view = "search", content = function ()
    5.57 +        ui.image { static = "icons/16/magnifier.png" }
    5.58 +      end
    5.59 +    }
    5.60      
    5.61    end
    5.62 -
    5.63 +  
    5.64    if app.session.member == nil then
    5.65 -    ui.link{
    5.66 +    
    5.67 +    slot.put ( " " )
    5.68 +    
    5.69 +    ui.link {
    5.70 +      text   = _"Login",
    5.71 +      module = 'index',
    5.72 +      view   = 'login',
    5.73 +      params = {
    5.74 +        redirect_module = request.get_module(),
    5.75 +        redirect_view = request.get_view(),
    5.76 +        redirect_id = param.get_id()
    5.77 +      }
    5.78 +    }
    5.79 +    
    5.80 +    slot.put ( " " )
    5.81 +    
    5.82 +    ui.link {
    5.83        text   = _"Registration",
    5.84        module = 'index',
    5.85        view   = 'register'
    5.86      }
    5.87 +
    5.88    end
    5.89 +  
    5.90 +  
    5.91 +  if app.session.member then
    5.92 +  
    5.93 +    slot.put ( " " )
    5.94 +    
    5.95 +    ui.tag { attr = { id = "member_menu" }, content = function()
    5.96 +      util.micro_avatar(app.session.member)
    5.97 +    end }
    5.98 +    
    5.99 +  end -- if app.session.member
   5.100 +    
   5.101  end)
   5.102  
   5.103 +-- show notifications about things the user should take care of
   5.104 +if app.session.member then
   5.105 +  execute.view{
   5.106 +    module = "index", view = "_sidebar_notifications", params = {
   5.107 +      mode = "link"
   5.108 +    }
   5.109 +  }
   5.110 +end
   5.111  
   5.112 -slot.select('navigation_right', function()
   5.113 -  ui.tag{ 
   5.114 -    tag = "ul",
   5.115 -    attr = { id = "member_menu" },
   5.116 -    content = function()
   5.117 -      ui.tag{ 
   5.118 -        tag = "li",
   5.119 -        content = function()
   5.120 -          ui.link{
   5.121 -            module = "index",
   5.122 -            view = "menu",
   5.123 -            content = function()
   5.124 -              if app.session.member_id then
   5.125 -                execute.view{
   5.126 -                  module = "member_image",
   5.127 -                  view = "_show",
   5.128 -                  params = {
   5.129 -                    member = app.session.member,
   5.130 -                    image_type = "avatar",
   5.131 -                    show_dummy = true,
   5.132 -                    class = "micro_avatar",
   5.133 -                  }
   5.134 -                }
   5.135 -                ui.tag{ content = app.session.member.name }
   5.136 -              else
   5.137 -                ui.tag{ content = _"Select language" }
   5.138 -              end
   5.139 -            end
   5.140 -          }
   5.141 -          execute.view{ module = "index", view = "_menu" }
   5.142 -        end
   5.143 -      }
   5.144 -    end
   5.145 -  }
   5.146 -end)
   5.147 -
   5.148 -slot.select("footer", function()
   5.149 +slot.select ("footer", function ()
   5.150    if app.session.member_id and app.session.member.admin then
   5.151 -    ui.link{
   5.152 -      text   = _"Admin",
   5.153 +    ui.link {
   5.154 +      text   = _"System settings",
   5.155        module = 'admin',
   5.156        view   = 'index'
   5.157      }
   5.158 @@ -102,8 +100,6 @@
   5.159      }
   5.160    end
   5.161    slot.put(" &middot; ")
   5.162 -  ui.tag{ content = _"This site is using" }
   5.163 -  slot.put(" ")
   5.164    ui.link{
   5.165      text   = _"LiquidFeedback",
   5.166      external = "http://www.public-software-group.org/liquid_feedback"
     6.1 --- a/app/main/_layout/default.html	Thu Jul 10 01:02:43 2014 +0200
     6.2 +++ b/app/main/_layout/default.html	Thu Jul 10 01:19:48 2014 +0200
     6.3 @@ -1,67 +1,277 @@
     6.4  <html>
     6.5 -  <head>
     6.6 -    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
     6.7 -    <meta name="viewport" content="width=device-width" />
     6.8 -    <title> <!-- WEBMCP SLOTNODIV html_title --></title>
     6.9 -    <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/trace.css" />
    6.10 -    <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/gregor.js/gregor.css" />
    6.11 -    <link rel="stylesheet" type="text/css" media="screen" href="<!-- WEBMCP SLOTNODIV stylesheet_url -->" />
    6.12 -    <!-- WEBMCP SLOTNODIV html_head -->
    6.13 -    <script type="text/javascript">jsFail = true;</script>
    6.14 -    <![if !IE]>
    6.15 -      <script type="text/javascript">jsFail = false;</script>
    6.16 -    <![endif]>
    6.17 -    <script type="text/javascript" src="__BASEURL__/static/js/jsprotect.js"></script>
    6.18 -    <script type="text/javascript" src="__BASEURL__/static/js/partialload.js"></script>
    6.19 -    <script type="text/javascript">var ui_tabs_active = {};</script>
    6.20 -  </head>
    6.21 -  <body>
    6.22 -    <div class="topbar">
    6.23 -      <div class="topbar_content">
    6.24 -        <div class="navigation" id="navigation">
    6.25 -          <!-- WEBMCP SLOT navigation -->
    6.26 -        </div>
    6.27 -        <div class="navigation_right" id="navigation_right">
    6.28 -          <!-- WEBMCP SLOT navigation_right -->
    6.29 -        </div>
    6.30 -        <div class="help_hidden" id="help_hidden">
    6.31 -          <!-- WEBMCP SLOT help_hidden -->
    6.32 -        </div>
    6.33 -        <br style="clear: both;" />
    6.34 +<head>
    6.35 +  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    6.36 +  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
    6.37 +  <title><!-- WEBMCP SLOTNODIV html_title --></title>
    6.38 +  <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/gregor.js/gregor.css" />
    6.39 +  <link rel="stylesheet" type="text/less" href="__BASEURL__/static/lf3.less" />
    6.40 +  <!-- WEBMCP SLOTNODIV html_head -->
    6.41 +  <script type="text/javascript" src="__BASEURL__/static/js/less-1.4.1.min.js"></script>
    6.42 +  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    6.43 +  <script type="text/javascript">jsFail = true;</script>
    6.44 +  <![if !IE]>
    6.45 +    <script type="text/javascript">jsFail = false;</script>
    6.46 +  <![endif]>
    6.47 +  <script type="text/javascript" src="__BASEURL__/static/js/jsprotect.js"></script>
    6.48 +  <script type="text/javascript" src="__BASEURL__/static/js/partialload.js"></script>
    6.49 +  <script type="text/javascript">var ui_tabs_active = {};</script>
    6.50 +</head>
    6.51 +<body style="">
    6.52 +<div class="head_outer">
    6.53 +  <div class="head">
    6.54 +    <div class="nav">
    6.55 +      <!--WEBMCP SLOTNODIV navigation -->
    6.56 +      <!--WEBMCP SLOTNODIV navigation_right -->
    6.57 +      <!--WEBMCP SLOTNODIV notification -->
    6.58 +    </div>
    6.59 +
    6.60 +    <a class="logo" href="__BASEURL__/">
    6.61 +      <span class="liquid">Liquid</span><span class="feedback">Feedback</span>
    6.62 +      <span class="instanceName"><!-- WEBMCP SLOTNODIV instance_name --></span>
    6.63 +    </a>
    6.64 +
    6.65 +    
    6.66 +  </div>
    6.67 +</div>
    6.68 +
    6.69 +<div class="page">
    6.70 +  <div class="layout_notice" id="layout_notice" onclick="document.getElementById('layout_notice').style.display='none';">
    6.71 +    <!-- WEBMCP SLOT notice -->
    6.72 +  </div>
    6.73 +  
    6.74 +  <div class="layout_warning" id="layout_warning" onclick="document.getElementById('layout_warning').style.display='none';">
    6.75 +    <!-- WEBMCP SLOT warning -->
    6.76 +  </div>
    6.77 +  
    6.78 +  <div class="layout_error" id="layout_error" onclick="document.getElementById('layout_error').style.display='none';">
    6.79 +    <!-- WEBMCP SLOT error -->
    6.80 +  </div>
    6.81 +
    6.82 +  <div class="layout_motd" id="layout_motd" onclick="document.getElementById('layout_motd').style.display='none';">
    6.83 +    <!-- WEBMCP SLOT motd -->
    6.84 +  </div>
    6.85 +
    6.86 +  <div class="title_outer">
    6.87 +    <!-- WEBMCP SLOT title -->
    6.88 +  </div>
    6.89 +  
    6.90 +  <!-- WEBMCP SLOT tabs -->
    6.91 +
    6.92 +  <!-- WEBMCP SLOTNODIV actions -->
    6.93 +  
    6.94 +  <div id="swiper_tabs" class="swiper_tabs" style="display: none;">
    6.95 +<!--    <div><a id="tab-0" href="#" onclick="slider.to(0); return false;"><img src="__BASEURL__/static/icons/16/chart_organisation.png" /></a></div>-->
    6.96 +    <div><a id="tab-0" href="#" onclick="slider.to(0); return false;"><img src="__BASEURL__/static/icons/16/text_list_bullets.png" width="32" height="32" /></a></div>
    6.97 +    <div><a id="tab-1" href="#" onclick="slider.to(1); return false;"><img src="__BASEURL__/static/icons/48/info.png" width="32" height="32" /></a></div>
    6.98 +    <div><a id="tab-2" href="#" onclick="slider.to(2); return false;"><img src="__BASEURL__/static/icons/16/group.png" width="32" height="32" /></a></div>
    6.99 +  </div>
   6.100 +  
   6.101 +  <div id="swiper_info"><!-- WEBMCP SLOTNODIV swiper_info --></div>
   6.102 +  <div id="swiper" class="swiper" style="position: absolute; width: 100%;">
   6.103 +    <div id="swiper_wrap" class="swiper_wrap">
   6.104 +    </div>
   6.105 +  </div>
   6.106 +  
   6.107 +  <div class="content">
   6.108 +    <div class="sidebar">
   6.109 +      <!-- WEBMCP SLOTNODIV sidebar -->
   6.110 +    </div>
   6.111 +
   6.112 +    <div class="main_outer">
   6.113 +      <!-- WEBMCP SLOTNODIV slideshow -->
   6.114 +      <div class="main">
   6.115 +        <!-- WEBMCP SLOTNODIV default -->
   6.116 +        <!-- WEBMCP SLOTNODIV extra -->
   6.117        </div>
   6.118      </div>
   6.119 -    <div class="page">
   6.120 -      <div class="page_head" id="head">
   6.121 -        <!-- WEBMCP SLOT head -->
   6.122 -      </div>
   6.123 -      <div class="layout_notice" id="layout_notice" onclick="document.getElementById('layout_notice').style.display='none';">
   6.124 -        <!-- WEBMCP SLOT notice -->
   6.125 -      </div>
   6.126 -      <div class="layout_warning" id="layout_warning" onclick="document.getElementById('layout_warning').style.display='none';">
   6.127 -        <!-- WEBMCP SLOT warning -->
   6.128 -      </div>
   6.129 -      <div class="layout_error" id="layout_error" onclick="document.getElementById('layout_error').style.display='none';">
   6.130 -        <!-- WEBMCP SLOT error -->
   6.131 -      </div>
   6.132 -      <div class="main" id="default">
   6.133 -        <!-- WEBMCP SLOT default -->
   6.134 -      </div>
   6.135 -      <br style="clear: both;" />
   6.136 -    </div>
   6.137 -    <div class="footer" id="footer">
   6.138 -      <!-- WEBMCP SLOT footer -->
   6.139 -    </div>
   6.140 -    <!-- WEBMCP SLOT trace_button -->
   6.141 +  </div>
   6.142 +  <br style="clear: both;" />
   6.143 +  <div class="footer">
   6.144 +    <!-- WEBMCP SLOTNODIV footer -->
   6.145 +  </div>
   6.146 +</div>
   6.147 +
   6.148 +  <div id="trace">
   6.149 +    <!-- WEBMCP SLOTNODIV trace_button -->
   6.150      <div id="trace_content" style="display: none;">
   6.151        <tt id="system_error"><!-- WEBMCP SLOT system_error --></tt>
   6.152 -      <div id="trace">&nbsp;</div><hr />
   6.153 +      <h1>System trace (for computer programmers purposes)</h1>
   6.154 +      <br />
   6.155        <!-- WEBMCP SLOT trace -->
   6.156        <div class="trace_close" onclick="document.getElementById('trace_show').style.display='block';document.getElementById('trace_content').style.display='none';">
   6.157          close
   6.158        </div>
   6.159      </div>
   6.160 -    <script type="text/javascript">
   6.161 -    <!-- WEBMCP SLOTNODIV custom_script -->
   6.162 -    </script>
   6.163 -  </body>
   6.164 +  </div>
   6.165 +  <script>
   6.166 +    $(".trace_view > .trace_list").hide();
   6.167 +    $(".trace_head").click(function() {
   6.168 +      var el = this.nextSibling
   6.169 +      if (el) $(el).toggle();
   6.170 +    });
   6.171 +  </script>
   6.172 +  
   6.173 +  <!-- WEBMCP SLOTNODIV script -->
   6.174 +  
   6.175 +  <script>
   6.176 +  
   6.177 +    var slider;
   6.178 +  
   6.179 +    function initSlider () {
   6.180 +    
   6.181 +      var els = [
   6.182 +        $( '.main, .extra' ),
   6.183 +        $( '.tab-notification, .tab-whatcanido' ),
   6.184 +        $( '.tab-members' )
   6.185 +      ];
   6.186 +      
   6.187 +      var sidebarFound = false;
   6.188 +      for ( i = 1; i < els.length; i++) {
   6.189 +        if (els[i].length > 0) sidebarFound = true;
   6.190 +      }
   6.191 +      
   6.192 +      if (sidebarFound) $("#swiper_tabs").show();
   6.193 +
   6.194 +      var elsCount = 3;
   6.195 +      
   6.196 +      var slidePos;
   6.197 +
   6.198 +      function slideTo ( pos ) {
   6.199 +        if ( typeof ( slidePos ) != "undefined" ) {
   6.200 +          els[ slidePos ].hide();
   6.201 +          $ ( "#tab-" + slidePos ).removeClass ( "active" );
   6.202 +        }
   6.203 +        slidePos = pos;
   6.204 +        els[ slidePos ].show();
   6.205 +        $ ( "#tab-" + slidePos ).addClass ( "active" );
   6.206 +        if (pos == 1) {
   6.207 +          $("#swiper_info").hide();
   6.208 +        }
   6.209 +      }
   6.210 +      
   6.211 +      function slideNext () {
   6.212 +        var pos = slidePos + 1;
   6.213 +        if ( pos > elsCount - 1 ) {
   6.214 +          pos = elsCount - 1;
   6.215 +        } else {
   6.216 +          $( "#swiper").css("left", "400px");
   6.217 +          $( "#swiper").animate({ "left": "0px" }, 200);
   6.218 +        }
   6.219 +        slideTo ( pos );
   6.220 +      }
   6.221 +      
   6.222 +      function slidePrev () {
   6.223 +        var pos = slidePos - 1;
   6.224 +        if ( pos < 0 ) {
   6.225 +          pos = 0;
   6.226 +        } else {
   6.227 +          $( "#swiper").css("left", "-400px");
   6.228 +          $( "#swiper").animate({ "left": "0px" }, 200);
   6.229 +        }
   6.230 +        slideTo ( pos );
   6.231 +      }
   6.232 +      
   6.233 +      function exit() {
   6.234 +        for ( i = 0; i < els.length; i++) {
   6.235 +          els[i].show();
   6.236 +        }
   6.237 +        $( ".main_outer" ).append ( $( ".main" ).detach() );
   6.238 +        $( ".extra_outer" ).append ( $( ".extra" ).detach() );
   6.239 +        $( ".sidebar" ).append ( $(els[1]).detach() );
   6.240 +        $( ".sidebar" ).append ( $(els[2]).detach() );
   6.241 +        $( ".page" ).append ( $('.footer') );
   6.242 +        $( "body" ).append ( $('#trace') );
   6.243 +
   6.244 +      }
   6.245 +      
   6.246 +      var touchStartX;
   6.247 +      var touchStartY;
   6.248 +      var isScrolling;
   6.249 +      
   6.250 +      function touchDown ( e ) {
   6.251 +        touchStartX = e.originalEvent.touches[0].pageX;
   6.252 +        touchStartY = e.originalEvent.touches[0].pageY;
   6.253 +        isScrolling = undefined;
   6.254 +      }
   6.255 +      
   6.256 +      function touchMove ( e ) {
   6.257 +        var diffX = touchStartX - e.originalEvent.changedTouches[0].pageX;
   6.258 +        var diffY = touchStartY - e.originalEvent.changedTouches[0].pageY;
   6.259 +        if ( typeof( isScrolling ) == 'undefined' ) {
   6.260 +          isScrolling = Math.abs ( diffY ) > Math.abs ( diffX );
   6.261 +        }
   6.262 +        if ( ! isScrolling ) {
   6.263 +          $( "#swiper").css("left", -diffX + "px");
   6.264 +          e.preventDefault();
   6.265 +        }
   6.266 +      }
   6.267 +      
   6.268 +      function touchUp ( e ) {
   6.269 +        var diffX = touchStartX - e.originalEvent.changedTouches[0].pageX;
   6.270 +        var diffY = touchStartY - e.originalEvent.changedTouches[0].pageY;
   6.271 +        
   6.272 +        if ( isScrolling ) {
   6.273 +          // vertical scrolling
   6.274 +          return;
   6.275 +        }
   6.276 +        
   6.277 +        if ( Math.abs ( diffX ) < 100 ) {
   6.278 +          // go back not enough
   6.279 +          $( "#swiper").animate({
   6.280 +            "left": "0px",
   6.281 +          }, 200);
   6.282 +          return;
   6.283 +        }
   6.284 +        var direction = diffX < 0 ? "right" : "left";
   6.285 +
   6.286 +        if ( direction == "left" ) {
   6.287 +          slideNext();
   6.288 +        } else {
   6.289 +          slidePrev();
   6.290 +        }
   6.291 +      }
   6.292 +
   6.293 +      for ( i = 0; i < els.length; i++) {
   6.294 +        var el = els[i].detach();
   6.295 +        el.hide();
   6.296 +        $('#swiper_wrap').append ( el ) ;
   6.297 +      }
   6.298 +      
   6.299 +      $('#swiper_wrap').append ( $('.footer') );
   6.300 +      $('#swiper_wrap').append ( $('#trace') );
   6.301 +      slideTo ( 0 );
   6.302 +      
   6.303 +      if ( 'ontouchstart' in document.documentElement ) {
   6.304 +        $( "body" ).on( "touchstart", touchDown );
   6.305 +        $( "body" ).on( "touchmove", touchMove );
   6.306 +        $( "body" ).on( "touchend",   touchUp );
   6.307 +      }
   6.308 +      
   6.309 +      return {
   6.310 +        to: slideTo,
   6.311 +        exit: exit
   6.312 +      }
   6.313 +      
   6.314 +    }
   6.315 +    
   6.316 +    function resizeHandler() {
   6.317 +      if ( $(window).width() < 768 ) {
   6.318 +        if ( typeof ( slider ) == "undefined" ) {
   6.319 +          slider = initSlider();
   6.320 +        }
   6.321 +      } else {
   6.322 +        if ( typeof ( slider ) != "undefined" ) {
   6.323 +          slider.exit();
   6.324 +          slider = undefined;
   6.325 +        }
   6.326 +      }
   6.327 +      
   6.328 +    }
   6.329 +    
   6.330 +    $( window ).resize( resizeHandler );
   6.331 +    resizeHandler();
   6.332 +    
   6.333 +  </script>
   6.334 +
   6.335 +</body>
   6.336  </html>
     7.1 --- a/app/main/_layout/system_error.html	Thu Jul 10 01:02:43 2014 +0200
     7.2 +++ b/app/main/_layout/system_error.html	Thu Jul 10 01:19:48 2014 +0200
     7.3 @@ -1,75 +1,86 @@
     7.4  <html>
     7.5 -  <head>
     7.6 -    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
     7.7 -    <title>LiquidFeedback Error</title>
     7.8 -    <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/trace.css" />
     7.9 -    <style>
    7.10 -      body {
    7.11 -        font-family: sans-serif;
    7.12 -      }
    7.13 -      .title {
    7.14 -        font-size: 150%;
    7.15 -        font-weight: bold;
    7.16 -      }
    7.17 -      .layout_trace {
    7.18 -        left: 0;
    7.19 -      }
    7.20 -      a {
    7.21 -        background-color: #ddd;
    7.22 -        color: #000;
    7.23 -        padding: 1ex;
    7.24 -        margin: 1ex;
    7.25 -        line-height: 300%;
    7.26 -        border: 1px solid #777;
    7.27 -      }
    7.28 -      hr {
    7.29 -        margin-top: 2ex;
    7.30 -        margin-bottom: 2ex;
    7.31 -      }
    7.32 -    </style>
    7.33 -  </head>
    7.34 -  <body class="system_error">
    7.35 -
    7.36 -    <div class="title">
    7.37 -      <img src="__BASEURL__/static/lang/en.png" />
    7.38 -      Ooops, a system error occured
    7.39 -    </div>
    7.40 -    <p>
    7.41 -      Most probably you found a software bug. Don't panic, you can now choose one of the following options:
    7.42 -    </p>
    7.43 -
    7.44 -    <nobr><a href="__BASEURL__">Go to start page</a></nobr>
    7.45 -    <nobr><a href="#" onclick="window.location.reload()">Retry request</a></nobr>
    7.46 -    <nobr><a href="http://trac.public-software-group.org/projects/lf" target="_blank">Create bug report</a></nobr>
    7.47 -
    7.48 -    <hr />
    7.49 -
    7.50 -    <div class="title">
    7.51 -      <img src="__BASEURL__/static/lang/de.png" />
    7.52 -      Leider ist ein Systemfehler aufgetreten
    7.53 -    </div>
    7.54 -    <p>
    7.55 -      Du hast vermutlich gerade einen Fehler in der Software entdeckt. Das ist kein Grund zur Panik, dir bleiben die folgenden Optionen:
    7.56 -    </p>
    7.57 -
    7.58 -    <nobr><a href="__BASEURL__">Weiter zur Startseite</a></nobr>
    7.59 -    <nobr><a href="#" onclick="window.location.reload()">Anfrage wiederholen</a></nobr>
    7.60 -    <nobr><a href="http://trac.public-software-group.org/projects/lf" target="_blank">Fehlerbericht erstellen</a></nobr>
    7.61 -
    7.62 -    <hr />
    7.63 -    <p>
    7.64 -      If you write a bug report, please include the following output in your bug report.<br />
    7.65 -      Falls Du einen Fehlerbericht erstellst, füge bitte die folgenden Ausgaben mit ein.
    7.66 -    </p>
    7.67 -    <tt style="font-size: 75%;"><!-- WEBMCP SLOT system_error --></tt>
    7.68 -
    7.69 -
    7.70 -    <div class="layout_trace" id="layout_trace" style="xdisplay: none">
    7.71 -      <div id="trace_show" onclick="document.getElementById('trace_content').style.display='block';this.style.display='none';" style="display: none;">TRACE</div>
    7.72 -      <div id="trace_content">
    7.73 -        <!-- WEBMCP SLOT trace -->
    7.74 -      <div class="trace_close" onclick="document.getElementById('trace_show').style.display='block';document.getElementById('trace_content').style.display='none';">close</div>
    7.75 +<head>
    7.76 +  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    7.77 +  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
    7.78 +  <title><!-- WEBMCP SLOTNODIV html_title --></title>
    7.79 +  <link href='http://fonts.googleapis.com/css?family=Signika:300,400,600' rel='stylesheet' type='text/css'>
    7.80 +  <link href='http://fonts.googleapis.com/css?family=Kreon:300,400,700' rel='stylesheet' type='text/css'>
    7.81 +  <link href='http://fonts.googleapis.com/css?family=Crimson+Text:600italic' rel='stylesheet' type='text/css'>
    7.82 +  <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/gregor.js/gregor.css" />
    7.83 +  <link rel="stylesheet" type="text/less" href="__BASEURL__/static/lf3.less" />
    7.84 +  <!-- WEBMCP SLOTNODIV html_head -->
    7.85 +  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    7.86 +  <script type="text/javascript" src="__BASEURL__/static/js/less-1.4.1.min.js"></script>
    7.87 +  <script type="text/javascript">jsFail = true;</script>
    7.88 +  <![if !IE]>
    7.89 +    <script type="text/javascript">jsFail = false;</script>
    7.90 +  <![endif]>
    7.91 +  <script type="text/javascript" src="__BASEURL__/static/js/jsprotect.js"></script>
    7.92 +  <script type="text/javascript" src="__BASEURL__/static/js/partialload.js"></script>
    7.93 +  <script type="text/javascript">var ui_tabs_active = {};</script>
    7.94 +  <style>
    7.95 +  body {
    7.96 +    background-image: url('__BASEURL__/static/back/berlin2.png');
    7.97 +    background-repeat: no-repeat;
    7.98 +    background-position: left bottom;
    7.99 +    background-size: 100%; 
   7.100 +    background: #397ab6;
   7.101 +  }
   7.102 +  </style>
   7.103 +</head>
   7.104 +<body style="">
   7.105 +<div class="head_outer">
   7.106 +  <div class="head">
   7.107 +    <div class="nav">
   7.108 +      <!--WEBMCP SLOTNODIV navigation -->
   7.109      </div>
   7.110  
   7.111 -  </body>
   7.112 +    <a class="logo" href="__BASEURL__/">
   7.113 +      <span class="liquid">Liquid</span><span class="feedback">Feedback</span>
   7.114 +      <span class="instanceName"><!-- WEBMCP SLOTNODIV instance_name --></span>
   7.115 +    </a>
   7.116 +
   7.117 +    
   7.118 +  </div>
   7.119 +</div>
   7.120 +
   7.121 +<div class="page">
   7.122 +  <div class="title_outer">
   7.123 +    <div class="slot_title">System error</div>
   7.124 +  </div>
   7.125 +  
   7.126 +  <div class="content">
   7.127 +    <div class="sidebar">
   7.128 +    </div>
   7.129 +
   7.130 +    <div class="main_outer">
   7.131 +      <div class="main">
   7.132 +        <div class="section">
   7.133 +          <div class="sectionHead">
   7.134 +            <h1>A system error occured</h1>
   7.135 +          </div>
   7.136 +          <div class="sectionRow">
   7.137 +            Sorry, a system error occured.
   7.138 +            <br />
   7.139 +            <br />
   7.140 +            <br />
   7.141 +            <a href="__BASEURL__">Go back to home page</a>
   7.142 +          </div>
   7.143 +        </div>
   7.144 +      </div>
   7.145 +    </div>
   7.146 +  </div>
   7.147 +  <br style="clear: both;" />
   7.148 +  <div class="footer">
   7.149 +    <!-- WEBMCP SLOTNODIV footer -->
   7.150 +  </div>
   7.151 +</div>
   7.152 +
   7.153 +<div id="trace_content">
   7.154 +  <tt id="system_error"><!-- WEBMCP SLOT system_error --></tt>
   7.155 +  <hr />
   7.156 +  <!-- WEBMCP SLOT trace -->
   7.157 +</div>
   7.158 +
   7.159 +</body>
   7.160  </html>
   7.161 \ No newline at end of file
     8.1 --- a/app/main/admin/_action/area_update.lua	Thu Jul 10 01:02:43 2014 +0200
     8.2 +++ b/app/main/admin/_action/area_update.lua	Thu Jul 10 01:19:48 2014 +0200
     8.3 @@ -2,6 +2,13 @@
     8.4  
     8.5  param.update(area, "unit_id", "name", "description", "active")
     8.6  
     8.7 +if #area.name < 1 then
     8.8 +  slot.select("error", function()
     8.9 +    ui.tag{ content = _"Please choose an area name" }
    8.10 +  end)
    8.11 +  return false
    8.12 +end
    8.13 +
    8.14  area:save()
    8.15  
    8.16  param.update_relationship{
     9.1 --- a/app/main/admin/area_show.lua	Thu Jul 10 01:02:43 2014 +0200
     9.2 +++ b/app/main/admin/area_show.lua	Thu Jul 10 01:19:48 2014 +0200
     9.3 @@ -1,25 +1,27 @@
     9.4  local id = param.get_id()
     9.5  
     9.6 +local hint = not id
     9.7 +
     9.8  local area = Area:by_id(id) or Area:new()
     9.9  
    9.10  if not area.unit_id then
    9.11    area.unit_id = param.get("unit_id", atom.integer)
    9.12  end
    9.13  
    9.14 -ui.title(_"Create / edit area")
    9.15 +ui.titleAdmin(_"area")
    9.16  
    9.17  ui.form{
    9.18 -  attr = { class = "vertical" },
    9.19 +  attr = { class = "vertical section" },
    9.20    record = area,
    9.21    module = "admin",
    9.22    action = "area_update",
    9.23    routing = {
    9.24 -    default = {
    9.25 +    ok = {
    9.26        mode = "redirect",
    9.27        module = "admin",
    9.28 -      view = "area_list",
    9.29 +      view = "index",
    9.30        params = { unit_id = area.unit_id }
    9.31 -    }
    9.32 +    },
    9.33    },
    9.34    id = id,
    9.35    content = function()
    9.36 @@ -34,25 +36,38 @@
    9.37        def_policy[#def_policy+1] = record
    9.38      end
    9.39  
    9.40 -    ui.field.hidden{ name = "unit_id", value = area.unit_id }
    9.41 -    ui.field.text{    label = _"Unit", value = area.unit.name, readonly = true }
    9.42 -    ui.field.text{    label = _"Name",        name = "name" }
    9.43 -    ui.field.text{    label = _"Description", name = "description", multiline = true }
    9.44 -    ui.field.select{  label = _"Default Policy",   name = "default_policy",
    9.45 -                 value=area.default_policy and area.default_policy.id or "-1",
    9.46 -                 foreign_records = def_policy,
    9.47 -                 foreign_id      = "id",
    9.48 -                 foreign_name    = "name"
    9.49 -    }
    9.50 -    ui.multiselect{   label = _"Policies",    name = "allowed_policies[]",
    9.51 -                      foreign_records = policies,
    9.52 -                      foreign_id      = "id",
    9.53 -                      foreign_name    = "name",
    9.54 -                      connecting_records = area.allowed_policies or {},
    9.55 -                      foreign_reference  = "id",
    9.56 -    }
    9.57 -    slot.put("<br /><br />")
    9.58 -    ui.field.boolean{ label = _"Active?",     name = "active" }
    9.59 -    ui.submit{ text = _"Save" }
    9.60 +    
    9.61 +    ui.section( function()
    9.62 +      ui.sectionHead( function()
    9.63 +        ui.heading { level = 1, content = area.name or _"New area" }
    9.64 +      end )
    9.65 +    
    9.66 +      ui.sectionRow( function()
    9.67 +        
    9.68 +        ui.field.hidden{ name = "unit_id", value = area.unit_id }
    9.69 +        ui.field.text{    label = _"Unit", value = area.unit.name, readonly = true }
    9.70 +        ui.field.text{    label = _"Name",        name = "name" }
    9.71 +        ui.field.text{    label = _"Description", name = "description", multiline = true }
    9.72 +        ui.field.select{  label = _"Default Policy",   name = "default_policy",
    9.73 +                    value=area.default_policy and area.default_policy.id or "-1",
    9.74 +                    foreign_records = def_policy,
    9.75 +                    foreign_id      = "id",
    9.76 +                    foreign_name    = "name"
    9.77 +        }
    9.78 +        ui.heading { level = 3, content = _"Allowed policies" }
    9.79 +        ui.multiselect{   name = "allowed_policies[]",
    9.80 +                          foreign_records = policies,
    9.81 +                          foreign_id      = "id",
    9.82 +                          foreign_name    = "name",
    9.83 +                          connecting_records = area.allowed_policies or {},
    9.84 +                          foreign_reference  = "id",
    9.85 +        }
    9.86 +        slot.put("<br /><br />")
    9.87 +        ui.field.boolean{ label = _"Active?",     name = "active", value = hint and true or nil }
    9.88 +        ui.submit{ text = _"update area" }
    9.89 +        slot.put(" ")
    9.90 +        ui.link{ module = "admin", view = "index", content = _"cancel" }
    9.91 +      end )
    9.92 +    end )
    9.93    end
    9.94  }
    10.1 --- a/app/main/admin/cancel_issue.lua	Thu Jul 10 01:02:43 2014 +0200
    10.2 +++ b/app/main/admin/cancel_issue.lua	Thu Jul 10 01:19:48 2014 +0200
    10.3 @@ -1,38 +1,39 @@
    10.4 -
    10.5  local id = param.get("id")
    10.6  
    10.7  if not id then
    10.8 -  ui.title("Cancel issue")
    10.9 -  ui.actions()
   10.10 -  ui.form{
   10.11 -    module = "admin",
   10.12 -    view = "cancel_issue",
   10.13 -    content = function()
   10.14 -      ui.field.text{ label = _"Issue ID", name = "id" }
   10.15 -      ui.submit{ text = _"Cancel issue" }
   10.16 -    end
   10.17 -  }
   10.18 -else
   10.19 - 
   10.20 -  local issue = Issue:by_id(id)
   10.21 - 
   10.22 -  ui.title(_("Cancel issue #{id}", { id = issue.id }))
   10.23 -  ui.actions()
   10.24 +  return
   10.25 +end
   10.26 +
   10.27 +local issue = Issue:by_id(id)
   10.28 +issue:load_everything_for_member_id ( app.session.member_id )
   10.29 +issue.initiatives:load_everything_for_member_id ( app.session.member_id )
   10.30 +
   10.31 +ui.titleAdmin(_"Cancel issue")
   10.32  
   10.33 +ui.form{
   10.34 +  module = "admin",
   10.35 +  action = "cancel_issue",
   10.36 +  id = id,
   10.37 +  attr = { class = "vertical section" },
   10.38 +  content = function()
   10.39      
   10.40 -  execute.view{ module = "initiative", view = "_list", params = {
   10.41 -    initiatives_selector = issue:get_reference_selector("initiatives")
   10.42 -  } }
   10.43 +    ui.sectionHead( function()
   10.44 +      ui.heading { level = 1, content = _("Cancel issue ##{id}", { id = issue.id }) }
   10.45 +    end )
   10.46  
   10.47 -  ui.form{
   10.48 -    module = "admin",
   10.49 -    action = "cancel_issue",
   10.50 -    id = id,
   10.51 -    attr = { class = "vertical" },
   10.52 -    content = function()
   10.53 -      ui.field.text{ label = _"Public administrative notice:", name = "admin_notice", multiline = true }
   10.54 -      ui.submit{ text = _"Cancel issue now" }
   10.55 -    end
   10.56 -  }
   10.57 +    ui.sectionRow( function()
   10.58 +      execute.view{ module = "initiative", view = "_list", params = {
   10.59 +        issue = issue,
   10.60 +        initiatives = issue.initiatives
   10.61 +      } }
   10.62 +    end )
   10.63 +    
   10.64 +    ui.sectionRow( function()
   10.65 +      ui.field.text{ label = _"public administrative notice:", name = "admin_notice", multiline = true }
   10.66 +      ui.submit{ text = _"cancel issue now" }
   10.67 +      slot.put(" ")
   10.68 +      ui.link { module = "admin", view = "index", content = "go back to safety" }
   10.69 +    end )
   10.70 +  end
   10.71 +}
   10.72  
   10.73 -end
    11.1 --- a/app/main/admin/index.lua	Thu Jul 10 01:02:43 2014 +0200
    11.2 +++ b/app/main/admin/index.lua	Thu Jul 10 01:19:48 2014 +0200
    11.3 @@ -1,34 +1,126 @@
    11.4 -slot.put_into("title", _"Admin menu")
    11.5 +local units = Unit:get_flattened_tree{ active = true }
    11.6 +local policies = Policy:build_selector{}:add_order_by("index"):exec()
    11.7 +
    11.8 +slot.put_into("title", _"Manage system settings")
    11.9  
   11.10 +ui.sidebar( "tab-members", function()
   11.11 +  ui.sidebarHead( function()
   11.12 +    ui.heading { level = 2, content = _"Members" }
   11.13 +  end )
   11.14 +  
   11.15 +  ui.sidebarSection( function()
   11.16 +    ui.tag { tag = "ul", attr = { class = "ul" }, content = function()
   11.17 +      ui.tag { tag = "li", content = function()
   11.18 +        ui.form{
   11.19 +          module = "admin", view = "member_list",
   11.20 +          content = function()
   11.21 +          
   11.22 +            ui.field.text{ label = _"search", name = "search" }
   11.23 +            
   11.24 +            ui.submit{ value = _"search" }
   11.25 +          
   11.26 +          end
   11.27 +        }
   11.28 +      end }
   11.29 +    end }
   11.30 +  end )
   11.31 +  ui.sidebarSection( "moreLink", function()
   11.32 +    ui.link{
   11.33 +      text = _"Register new member",
   11.34 +      module = "admin",
   11.35 +      view = "member_edit"
   11.36 +    }
   11.37 +  end )
   11.38 +end )
   11.39  
   11.40 -ui.tag{ tag = "ul", content = function()
   11.41 -  ui.tag{ tag= "li", content = function()
   11.42 +ui.sidebar( "tab-whatcanido", function()
   11.43 +  ui.sidebarHead( function()
   11.44 +    ui.heading { level = 2, content = _"Cancel issue" }
   11.45 +  end )
   11.46 +  
   11.47 +  ui.sidebarSection( function()
   11.48 +    ui.form{
   11.49 +      module = "admin",
   11.50 +      view = "cancel_issue",
   11.51 +      content = function()
   11.52 +        ui.tag { tag = "ul", attr = { class = "ul" }, content = function()
   11.53 +          ui.tag { tag = "li", content = function()
   11.54 +            ui.field.text{ label = _"Issue #", name = "id" }
   11.55 +            ui.submit{ text = _"cancel issue" }
   11.56 +          end }
   11.57 +        end }
   11.58 +      end
   11.59 +    }
   11.60 +  end )
   11.61 +end )
   11.62 +
   11.63 +ui.sidebar("tab-whatcanido", function()
   11.64 +  ui.sidebarHead( function()
   11.65 +    ui.heading { level = 2, content = _"Policies" }
   11.66 +  end )
   11.67 +  
   11.68 +  ui.sidebarSection( function()
   11.69 +    ui.tag { tag = "ul", attr = { class = "ul" }, content = function()
   11.70 +      for i, policy in ipairs(policies) do
   11.71 +        ui.tag { tag = "li", content = function()
   11.72 +          ui.link{
   11.73 +            content = policy.name,
   11.74 +            module = "admin",
   11.75 +            view = "policy_show",
   11.76 +            id = policy.id
   11.77 +          }
   11.78 +        end }
   11.79 +      end
   11.80 +    end }
   11.81 +  end )
   11.82 +  ui.sidebarSection( "moreLink", function()
   11.83      ui.link{
   11.84 -      text = _"Policies",
   11.85 +      text = _"Create new policy",
   11.86 +      module = "admin",
   11.87 +      view = "policy_show"
   11.88 +    }
   11.89 +  end )
   11.90 +  ui.sidebarSection( "moreLink", function()
   11.91 +    ui.link{
   11.92 +      text = _"Show policies not in use",
   11.93        module = "admin",
   11.94        view = "policy_list",
   11.95 -    }
   11.96 -  end }
   11.97 -  ui.tag{ tag= "li", content = function()
   11.98 -    ui.link{
   11.99 -      text = _"Units",
  11.100 -      module = "admin",
  11.101 -      view = "unit_list",
  11.102 +      params = { show_not_in_use = true }
  11.103      }
  11.104 -  end }
  11.105 -  ui.tag{ tag= "li", content = function()
  11.106 -    ui.link{
  11.107 -      text = _"Members",
  11.108 -      module = "admin",
  11.109 -      view = "member_list",
  11.110 -    }
  11.111 -  end }
  11.112 -  ui.tag{ tag= "li", content = function()
  11.113 -    ui.link{
  11.114 -      text = _"Cancel issue",
  11.115 -      module = "admin",
  11.116 -      view = "cancel_issue",
  11.117 -    }
  11.118 -  end }
  11.119 -end }
  11.120 +  end )
  11.121 +end )
  11.122 +
  11.123 +
  11.124 +ui.section( function()
  11.125 +  ui.sectionHead( function()
  11.126 +    ui.heading { level = 1, content = _"Organizational units and subject areas" }
  11.127 +  end )
  11.128 +  ui.sectionRow( function()
  11.129  
  11.130 +    for i_unit, unit in ipairs(units) do
  11.131 +      ui.container { 
  11.132 +        attr = { style = "margin-left: " .. ((unit.depth - 1)* 2) .. "em;" },
  11.133 +        content = function ()
  11.134 +          ui.heading { level = 1, content = function ()
  11.135 +            ui.link{ text = unit.name, module = "admin", view = "unit_edit", id = unit.id }
  11.136 +          end }
  11.137 +          ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  11.138 +            for i, area in ipairs(unit:get_reference_selector("areas"):add_order_by("name"):exec()) do
  11.139 +              ui.tag { tag = "li", content = function ()
  11.140 +                ui.link{ text = area.name, module = "admin", view = "area_show", id = area.id }
  11.141 +              end }
  11.142 +            end
  11.143 +            ui.tag { tag = "li", content = function ()
  11.144 +              ui.link { module = "admin", view = "area_show", params = { unit_id = unit.id }, content = _"+ add new subject area" }
  11.145 +            end }
  11.146 +            slot.put("<br />")
  11.147 +          end }
  11.148 +        end
  11.149 +      }
  11.150 +    end
  11.151 +    
  11.152 +    slot.put("<br />")
  11.153 +    ui.link { module = "admin", view = "unit_edit", content = _"+ add new organizational unit" }
  11.154 +      
  11.155 +  end)
  11.156 +end)
    12.1 --- a/app/main/admin/member_edit.lua	Thu Jul 10 01:02:43 2014 +0200
    12.2 +++ b/app/main/admin/member_edit.lua	Thu Jul 10 01:19:48 2014 +0200
    12.3 @@ -2,11 +2,7 @@
    12.4  
    12.5  local member = Member:by_id(id)
    12.6  
    12.7 -if member then
    12.8 -  ui.title(_("Member: '#{identification}' (#{name})", { identification = member.identification, name = member.name }))
    12.9 -else
   12.10 -  ui.title(_"Register new member")
   12.11 -end
   12.12 +ui.title(_"member")
   12.13  
   12.14  local units_selector = Unit:new_selector()
   12.15    
   12.16 @@ -19,7 +15,7 @@
   12.17  local units = units_selector:exec()
   12.18    
   12.19  ui.form{
   12.20 -  attr = { class = "vertical" },
   12.21 +  attr = { class = "vertical section" },
   12.22    module = "admin",
   12.23    action = "member_update",
   12.24    id = member and member.id,
   12.25 @@ -29,43 +25,54 @@
   12.26      default = {
   12.27        mode = "redirect",
   12.28        modules = "admin",
   12.29 -      view = "member_list"
   12.30 +      view = "index"
   12.31      }
   12.32    },
   12.33    content = function()
   12.34 -    ui.field.text{     label = _"Identification", name = "identification" }
   12.35 -    ui.field.text{     label = _"Notification email", name = "notify_email" }
   12.36 -    if member and member.activated then
   12.37 -      ui.field.text{     label = _"Screen name",        name = "name" }
   12.38 -      ui.field.text{     label = _"Login name",        name = "login" }
   12.39 -    end
   12.40 -    ui.field.boolean{  label = _"Admin?",       name = "admin" }
   12.41  
   12.42 -    slot.put("<br />")
   12.43 -    
   12.44 -    for i, unit in ipairs(units) do
   12.45 -      ui.field.boolean{
   12.46 -        name = "unit_" .. unit.id,
   12.47 -        label = unit.name,
   12.48 -        value = unit.voting_right
   12.49 +    ui.sectionHead( function()
   12.50 +      ui.heading { level = 1, content = member and member.name or _"New member" }
   12.51 +      if member and member.identification then
   12.52 +        ui.heading { level = 3, content = member.identification }
   12.53 +      end
   12.54 +    end )
   12.55 +  
   12.56 +    ui.sectionRow( function()
   12.57 +      ui.field.text{     label = _"Identification", name = "identification" }
   12.58 +      ui.field.text{     label = _"Notification email", name = "notify_email" }
   12.59 +      if member and member.activated then
   12.60 +        ui.field.text{     label = _"Screen name",        name = "name" }
   12.61 +        ui.field.text{     label = _"Login name",        name = "login" }
   12.62 +      end
   12.63 +      
   12.64 +      for i, unit in ipairs(units) do
   12.65 +        ui.field.boolean{
   12.66 +          name = "unit_" .. unit.id,
   12.67 +          label = unit.name,
   12.68 +          value = unit.voting_right
   12.69 +        }
   12.70 +      end
   12.71 +      slot.put("<br /><br />")
   12.72 +
   12.73 +      if not member or not member.activated then
   12.74 +        ui.field.boolean{  label = _"Send invite?",       name = "invite_member" }
   12.75 +      end
   12.76 +      
   12.77 +      if member and member.activated then
   12.78 +        ui.field.boolean{  label = _"Lock member?",       name = "locked" }
   12.79 +      end
   12.80 +      
   12.81 +      ui.field.boolean{ 
   12.82 +        label = _"Member inactive?", name = "deactivate",
   12.83 +        readonly = member and member.active, value = member and member.active == false
   12.84        }
   12.85 -    end
   12.86 -    slot.put("<br /><br />")
   12.87 -
   12.88 -    if not member or not member.activated then
   12.89 -      ui.field.boolean{  label = _"Send invite?",       name = "invite_member" }
   12.90 -    end
   12.91 -    
   12.92 -    if member and member.activated then
   12.93 -      ui.field.boolean{  label = _"Lock member?",       name = "locked" }
   12.94 -    end
   12.95 -    
   12.96 -    ui.field.boolean{ 
   12.97 -      label = _"Member inactive?", name = "deactivate",
   12.98 -      readonly = member and member.active, value = member and member.active == false
   12.99 -    }
  12.100 -    
  12.101 -    slot.put("<br />")
  12.102 -    ui.submit{         text  = _"Save" }
  12.103 +      
  12.104 +      slot.put("<br />")
  12.105 +      ui.field.boolean{  label = _"Admin?",       name = "admin" }
  12.106 +      slot.put("<br />")
  12.107 +      ui.submit{         text  = _"update member" }
  12.108 +      slot.put(" ")
  12.109 +      ui.link { module = "admin", view = "index", content = _"cancel" }
  12.110 +    end )
  12.111    end
  12.112  }
    13.1 --- a/app/main/admin/member_list.lua	Thu Jul 10 01:02:43 2014 +0200
    13.2 +++ b/app/main/admin/member_list.lua	Thu Jul 10 01:19:48 2014 +0200
    13.3 @@ -1,96 +1,100 @@
    13.4  local search = param.get("search")
    13.5  
    13.6 -ui.title(_"Member list")
    13.7 +ui.titleAdmin(_"Member list")
    13.8 +
    13.9 +ui.section( function()
   13.10 +
   13.11 +  ui.sectionHead( function()
   13.12 +    ui.heading { level = 1, content = _"Member list" }
   13.13 +  end )
   13.14  
   13.15 -ui.actions(function()
   13.16 -  ui.link{
   13.17 -    attr = { class = { "admin_only" } },
   13.18 -    text = _"Register new member",
   13.19 -    module = "admin",
   13.20 -    view = "member_edit"
   13.21 -  }
   13.22 -end)
   13.23 -
   13.24 -
   13.25 -ui.form{
   13.26 -  module = "admin", view = "member_list",
   13.27 -  content = function()
   13.28 +  ui.sectionRow( function ()
   13.29 +    ui.form{
   13.30 +      module = "admin", view = "member_list",
   13.31 +      content = function()
   13.32 +      
   13.33 +        ui.field.text{ label = _"search", name = "search", value = search }
   13.34 +        
   13.35 +        ui.submit{ value = _"search" }
   13.36 +      
   13.37 +      end
   13.38 +    }
   13.39 +  end )
   13.40    
   13.41 -    ui.field.text{ label = _"Search for members", name = "search" }
   13.42 -    
   13.43 -    ui.submit{ value = _"Start search" }
   13.44 -  
   13.45 -  end
   13.46 -}
   13.47  
   13.48 -if not search then
   13.49 -  return
   13.50 -end
   13.51 -
   13.52 -local members_selector = Member:build_selector{
   13.53 -  admin_search = search,
   13.54 -  order = "identification"
   13.55 -}
   13.56 +  ui.sectionRow( function ()
   13.57 +    local members_selector = Member:build_selector{
   13.58 +      admin_search = search,
   13.59 +      order = "identification"
   13.60 +    }
   13.61  
   13.62  
   13.63 -ui.paginate{
   13.64 -  selector = members_selector,
   13.65 -  per_page = 30,
   13.66 -  content = function() 
   13.67 -    ui.list{
   13.68 -      records = members_selector:exec(),
   13.69 -      columns = {
   13.70 -        {
   13.71 -          field_attr = { style = "text-align: right;" },
   13.72 -          label = _"Id",
   13.73 -          name = "id"
   13.74 -        },
   13.75 -        {
   13.76 -          label = _"Identification",
   13.77 -          name = "identification"
   13.78 -        },
   13.79 -        {
   13.80 -          label = _"Screen name",
   13.81 -          name = "name"
   13.82 -        },
   13.83 -        {
   13.84 -          label = _"Admin?",
   13.85 -          content = function(record)
   13.86 -            if record.admin then
   13.87 -              ui.field.text{ value = "admin" }
   13.88 -            end
   13.89 -          end
   13.90 -        },
   13.91 -        {
   13.92 -          content = function(record)
   13.93 -            if not record.activated then
   13.94 -              ui.field.text{ value = "not activated" }
   13.95 -            elseif not record.active then
   13.96 -              ui.field.text{ value = "inactive" }
   13.97 -            else
   13.98 -              ui.field.text{ value = "active" }
   13.99 -            end
  13.100 -          end
  13.101 -        },
  13.102 -        {
  13.103 -          content = function(record)
  13.104 -            if record.locked then
  13.105 -              ui.field.text{ value = "locked" }
  13.106 -            end
  13.107 -          end
  13.108 -        },
  13.109 -        {
  13.110 -          content = function(record)
  13.111 -            ui.link{
  13.112 -              attr = { class = "action admin_only" },
  13.113 -              text = _"Edit",
  13.114 -              module = "admin",
  13.115 -              view = "member_edit",
  13.116 -              id = record.id
  13.117 -            }
  13.118 -          end
  13.119 +    ui.paginate{
  13.120 +      selector = members_selector,
  13.121 +      per_page = 30,
  13.122 +      content = function() 
  13.123 +        ui.list{
  13.124 +          records = members_selector:exec(),
  13.125 +          columns = {
  13.126 +            {
  13.127 +              label = _"Id",
  13.128 +              content = function(record)
  13.129 +                ui.link{
  13.130 +                  text = record.id,
  13.131 +                  module = "admin",
  13.132 +                  view = "member_edit",
  13.133 +                  id = record.id
  13.134 +                }
  13.135 +              end
  13.136 +            },
  13.137 +            {
  13.138 +              label = _"Identification",
  13.139 +              content = function(record)
  13.140 +                ui.link{
  13.141 +                  text = record.identification or "",
  13.142 +                  module = "admin",
  13.143 +                  view = "member_edit",
  13.144 +                  id = record.id
  13.145 +                }
  13.146 +              end
  13.147 +            },
  13.148 +            {
  13.149 +              label = _"Screen name",
  13.150 +              content = function(record)
  13.151 +                ui.link{
  13.152 +                  text = record.name or "",
  13.153 +                  module = "admin",
  13.154 +                  view = "member_edit",
  13.155 +                  id = record.id
  13.156 +                }
  13.157 +              end
  13.158 +            },
  13.159 +            {
  13.160 +              content = function(record)
  13.161 +                if record.admin then
  13.162 +                  ui.field.text{ value = "admin" }
  13.163 +                end
  13.164 +              end
  13.165 +            },
  13.166 +            {
  13.167 +              content = function(record)
  13.168 +                if not record.activated then
  13.169 +                  ui.field.text{ value = "not activated" }
  13.170 +                elseif not record.active then
  13.171 +                  ui.field.text{ value = "inactive" }
  13.172 +                end
  13.173 +              end
  13.174 +            },
  13.175 +            {
  13.176 +              content = function(record)
  13.177 +                if record.locked then
  13.178 +                  ui.field.text{ value = "locked" }
  13.179 +                end
  13.180 +              end
  13.181 +            },
  13.182 +          }
  13.183          }
  13.184 -      }
  13.185 +      end
  13.186      }
  13.187 -  end
  13.188 -}
  13.189 \ No newline at end of file
  13.190 +  end )
  13.191 +end )
  13.192 \ No newline at end of file
    14.1 --- a/app/main/admin/policy_list.lua	Thu Jul 10 01:02:43 2014 +0200
    14.2 +++ b/app/main/admin/policy_list.lua	Thu Jul 10 01:19:48 2014 +0200
    14.3 @@ -3,52 +3,58 @@
    14.4  local policies = Policy:build_selector{ active = not show_not_in_use }:exec()
    14.5  
    14.6  
    14.7 -ui.title(_"Policy list")
    14.8 +ui.titleAdmin(_"Policy list")
    14.9  
   14.10 +ui.section( function()
   14.11 +  ui.sectionHead( function()
   14.12 +    ui.heading { level = 1, content = _"Policy list" }
   14.13 +  end )
   14.14 +  
   14.15 +  ui.sectionRow( function()
   14.16  
   14.17 -ui.actions(function()
   14.18 +    if show_not_in_use then
   14.19 +      ui.link{
   14.20 +        text = _"Show policies in use",
   14.21 +        module = "admin",
   14.22 +        view = "policy_list"
   14.23 +      }
   14.24  
   14.25 -  if show_not_in_use then
   14.26 -    ui.link{
   14.27 -      text = _"Show policies in use",
   14.28 -      module = "admin",
   14.29 -      view = "policy_list"
   14.30 +    else
   14.31 +      ui.link{
   14.32 +        text = _"Create new policy",
   14.33 +        module = "admin",
   14.34 +        view = "policy_show"
   14.35 +      }
   14.36 +      slot.put(" &middot; ")
   14.37 +      ui.link{
   14.38 +        text = _"Show policies not in use",
   14.39 +        module = "admin",
   14.40 +        view = "policy_list",
   14.41 +        params = { show_not_in_use = true }
   14.42 +      }
   14.43 +
   14.44 +    end
   14.45 +
   14.46 +  end )
   14.47 +  
   14.48 +  ui.sectionRow( function()
   14.49 +
   14.50 +    ui.list{
   14.51 +      records = policies,
   14.52 +      columns = {
   14.53 +
   14.54 +        { content = function(record)
   14.55 +            ui.link{
   14.56 +              text = record.name,
   14.57 +              module = "admin",
   14.58 +              view = "policy_show",
   14.59 +              id = record.id
   14.60 +            }
   14.61 +          end
   14.62 +        }
   14.63 +
   14.64 +      }
   14.65      }
   14.66  
   14.67 -  else
   14.68 -    ui.link{
   14.69 -      text = _"Create new policy",
   14.70 -      module = "admin",
   14.71 -      view = "policy_show"
   14.72 -    }
   14.73 -    slot.put(" &middot; ")
   14.74 -    ui.link{
   14.75 -      text = _"Show policies not in use",
   14.76 -      module = "admin",
   14.77 -      view = "policy_list",
   14.78 -      params = { show_not_in_use = true }
   14.79 -    }
   14.80 -
   14.81 -  end
   14.82 -
   14.83 -end)
   14.84 -
   14.85 -
   14.86 -ui.list{
   14.87 -  records = policies,
   14.88 -  columns = {
   14.89 -
   14.90 -    { label = _"Policy", name = "name" },
   14.91 -
   14.92 -    { content = function(record)
   14.93 -        ui.link{
   14.94 -          text = _"Edit",
   14.95 -          module = "admin",
   14.96 -          view = "policy_show",
   14.97 -          id = record.id
   14.98 -        }
   14.99 -      end
  14.100 -    }
  14.101 -
  14.102 -  }
  14.103 -}
  14.104 \ No newline at end of file
  14.105 +  end )
  14.106 +end )
  14.107 \ No newline at end of file
    15.1 --- a/app/main/admin/policy_show.lua	Thu Jul 10 01:02:43 2014 +0200
    15.2 +++ b/app/main/admin/policy_show.lua	Thu Jul 10 01:19:48 2014 +0200
    15.3 @@ -1,59 +1,71 @@
    15.4  local policy = Policy:by_id(param.get_id()) or Policy:new()
    15.5  
    15.6 -ui.title(_"Create / edit policy")
    15.7 +local hint = not policy.id
    15.8 +
    15.9 +ui.titleAdmin(policy.name or _"New policy")
   15.10 +
   15.11 +ui.section( function()
   15.12  
   15.13 -ui.form{
   15.14 -  attr = { class = "vertical" },
   15.15 -  record = policy,
   15.16 -  module = "admin",
   15.17 -  action = "policy_update",
   15.18 -  routing = {
   15.19 -    default = {
   15.20 -      mode = "redirect",
   15.21 +  ui.sectionHead( function()
   15.22 +    ui.heading { level = 1, content = _"Policy" }
   15.23 +  end )
   15.24 +  ui.sectionRow( function()
   15.25 +    ui.form{
   15.26 +      attr = { class = "vertical" },
   15.27 +      record = policy,
   15.28        module = "admin",
   15.29 -      view = "policy_list"
   15.30 -    }
   15.31 -  },
   15.32 -  id = policy.id,
   15.33 -  content = function()
   15.34 +      action = "policy_update",
   15.35 +      routing = {
   15.36 +        default = {
   15.37 +          mode = "redirect",
   15.38 +          module = "admin",
   15.39 +          view = "index"
   15.40 +        }
   15.41 +      },
   15.42 +      id = policy.id,
   15.43 +      content = function()
   15.44  
   15.45 -    ui.field.text{ label = _"Index",        name = "index" }
   15.46 -
   15.47 -    ui.field.text{ label = _"Name",        name = "name" }
   15.48 -    ui.field.text{ label = _"Description", name = "description", multiline = true }
   15.49 -    ui.field.text{ label = _"Hint",        readonly = true, 
   15.50 -                    value = _"Interval format:" .. " 3 mons 2 weeks 1 day 10:30:15" }
   15.51 +        ui.field.text{ label = _"Index",        name = "index", value = hint and "1" or nil }
   15.52  
   15.53 -    ui.field.text{ label = _"Admission time",     name = "admission_time" }
   15.54 -    ui.field.text{ label = _"Discussion time",    name = "discussion_time" }
   15.55 -    ui.field.text{ label = _"Verification time",  name = "verification_time" }
   15.56 -    ui.field.text{ label = _"Voting time",        name = "voting_time" }
   15.57 +        ui.field.text{ label = _"Name",        name = "name" }
   15.58 +        ui.field.text{ label = _"Description", name = "description", multiline = true }
   15.59 +        ui.field.text{ label = _"Hint",        readonly = true, 
   15.60 +                        value = _"Interval format:" .. " 3 mons 2 weeks 1 day 10:30:15" }
   15.61  
   15.62 -    ui.field.text{ label = _"Issue quorum numerator",   name = "issue_quorum_num" }
   15.63 -    ui.field.text{ label = _"Issue quorum denumerator", name = "issue_quorum_den" }
   15.64 +        ui.field.text{ label = _"Admission time",     name = "admission_time", value = hint and "30 days" or nil }
   15.65 +        ui.field.text{ label = _"Discussion time",    name = "discussion_time", value = hint and "30 days" or nil }
   15.66 +        ui.field.text{ label = _"Verification time",  name = "verification_time", value = hint and "15 days" or nil }
   15.67 +        ui.field.text{ label = _"Voting time",        name = "voting_time", value = hint and "15 days" or nil }
   15.68  
   15.69 -    ui.field.text{ label = _"Initiative quorum numerator",   name = "initiative_quorum_num" }
   15.70 -    ui.field.text{ label = _"Initiative quorum denumerator", name = "initiative_quorum_den" }
   15.71 +        ui.field.text{ label = _"Issue quorum numerator",   name = "issue_quorum_num", value = hint and "10" or nil }
   15.72 +        ui.field.text{ label = _"Issue quorum denominator", name = "issue_quorum_den", value = hint and "100" or nil }
   15.73 +
   15.74 +        ui.field.text{ label = _"Initiative quorum numerator",   name = "initiative_quorum_num", value = hint and "10" or nil }
   15.75 +        ui.field.text{ label = _"Initiative quorum denominator", name = "initiative_quorum_den", value = hint and "100" or nil }
   15.76  
   15.77 -    ui.field.text{ label = _"Direct majority numerator",   name = "direct_majority_num" }
   15.78 -    ui.field.text{ label = _"Direct majority denumerator", name = "direct_majority_den" }
   15.79 -    ui.field.boolean{ label = _"Strict direct majority", name = "direct_majority_strict" }
   15.80 -    ui.field.text{ label = _"Direct majority positive",   name = "direct_majority_positive" }
   15.81 -    ui.field.text{ label = _"Direct majority non negative", name = "direct_majority_non_negative" }
   15.82 +        ui.field.text{ label = _"Direct majority numerator",   name = "direct_majority_num", value = hint and "50" or nil }
   15.83 +        ui.field.text{ label = _"Direct majority denominator", name = "direct_majority_den", value = hint and "100" or nil }
   15.84 +        ui.field.boolean{ label = _"Strict direct majority", name = "direct_majority_strict", value = hint and true or nil }
   15.85 +        ui.field.text{ label = _"Direct majority positive",   name = "direct_majority_positive", value = hint and "0" or nil }
   15.86 +        ui.field.text{ label = _"Direct majority non negative", name = "direct_majority_non_negative", value = hint and "0" or nil }
   15.87  
   15.88 -    ui.field.text{ label = _"Indirect majority numerator",   name = "indirect_majority_num" }
   15.89 -    ui.field.text{ label = _"Indirect majority denumerator", name = "indirect_majority_den" }
   15.90 -    ui.field.boolean{ label = _"Strict indirect majority", name = "indirect_majority_strict" }
   15.91 -    ui.field.text{ label = _"Indirect majority positive",   name = "indirect_majority_positive" }
   15.92 -    ui.field.text{ label = _"Indirect majority non negative", name = "indirect_majority_non_negative" }
   15.93 +        ui.field.text{ label = _"Indirect majority numerator",   name = "indirect_majority_num", value = hint and "50" or nil }
   15.94 +        ui.field.text{ label = _"Indirect majority denominator", name = "indirect_majority_den", value = hint and "100" or nil }
   15.95 +        ui.field.boolean{ label = _"Strict indirect majority", name = "indirect_majority_strict", value = hint and true or nil }
   15.96 +        ui.field.text{ label = _"Indirect majority positive",   name = "indirect_majority_positive", value = hint and "0" or nil }
   15.97 +        ui.field.text{ label = _"Indirect majority non negative", name = "indirect_majority_non_negative", value = hint and "0" or nil }
   15.98  
   15.99 -    ui.field.boolean{ label = _"No reverse beat path", name = "no_reverse_beat_path" }
  15.100 -    ui.field.boolean{ label = _"No multistage majority", name = "no_multistage_majority" }
  15.101 -    ui.field.boolean{ label = _"Polling mode", name = "polling" }
  15.102 +        ui.field.boolean{ label = _"No reverse beat path", name = "no_reverse_beat_path", value = hint and false or nil }
  15.103 +        ui.field.boolean{ label = _"No multistage majority", name = "no_multistage_majority", value = hint and false or nil }
  15.104 +        ui.field.boolean{ label = _"Polling mode", name = "polling", value = hint and false or nil }
  15.105  
  15.106  
  15.107 -    ui.field.boolean{ label = _"Active?", name = "active" }
  15.108 +        ui.field.boolean{ label = _"Active?", name = "active", value = hint and true or nil }
  15.109  
  15.110 -    ui.submit{ text = _"Save" }
  15.111 -  end
  15.112 -}
  15.113 +        ui.submit{ text = _"update policy" }
  15.114 +        slot.put(" ")
  15.115 +        ui.link { module = "admin", view = "index", content = _"cancel" }
  15.116 +      end
  15.117 +    }
  15.118 +  end )
  15.119 +end )
  15.120 \ No newline at end of file
    16.1 --- a/app/main/admin/unit_edit.lua	Thu Jul 10 01:02:43 2014 +0200
    16.2 +++ b/app/main/admin/unit_edit.lua	Thu Jul 10 01:19:48 2014 +0200
    16.3 @@ -3,9 +3,7 @@
    16.4  local unit = Unit:by_id(id)
    16.5  
    16.6  if unit then
    16.7 -  ui.title(_("Unit: '#{name}'", { name = unit.name }))
    16.8 -else
    16.9 -  ui.title(_"Add new unit")
   16.10 +  ui.titleAdmin(_"Organizational unit")
   16.11  end
   16.12  
   16.13  local units = {
   16.14 @@ -17,7 +15,7 @@
   16.15  end
   16.16  
   16.17  ui.form{
   16.18 -  attr = { class = "vertical" },
   16.19 +  attr = { class = "vertical section" },
   16.20    module = "admin",
   16.21    action = "unit_update",
   16.22    id = unit and unit.id,
   16.23 @@ -26,22 +24,29 @@
   16.24      default = {
   16.25        mode = "redirect",
   16.26        modules = "admin",
   16.27 -      view = "unit_list"
   16.28 +      view = "index"
   16.29      }
   16.30    },
   16.31    content = function()
   16.32 -    ui.field.select{
   16.33 -      label = _"Parent unit",
   16.34 -      name = "parent_id",
   16.35 -      foreign_records = units,
   16.36 -      foreign_id      = "id",
   16.37 -      foreign_name    = "name"
   16.38 -    }
   16.39 -    ui.field.text{     label = _"Name",         name = "name" }
   16.40 -    ui.field.text{     label = _"Description",  name = "description", multiline = true }
   16.41 -    ui.field.boolean{  label = _"Active?",      name = "active" }
   16.42 +    ui.sectionHead( function()
   16.43 +      ui.heading { level = 1, content = unit and unit.name or _"New organizational unit" }
   16.44 +    end )
   16.45 +    ui.sectionRow( function()
   16.46 +      ui.field.select{
   16.47 +        label = _"Parent unit",
   16.48 +        name = "parent_id",
   16.49 +        foreign_records = units,
   16.50 +        foreign_id      = "id",
   16.51 +        foreign_name    = "name"
   16.52 +      }
   16.53 +      ui.field.text{     label = _"Name",         name = "name" }
   16.54 +      ui.field.text{     label = _"Description",  name = "description", multiline = true }
   16.55 +      ui.field.boolean{  label = _"Active?",      name = "active" }
   16.56  
   16.57 -    slot.put("<br />")
   16.58 -    ui.submit{         text  = _"Save" }
   16.59 +      slot.put("<br />")
   16.60 +      ui.submit{         text  = _"update unit" }
   16.61 +      slot.put(" ")
   16.62 +      ui.link{ module = "admin", view = "index", content = _"cancel" }
   16.63 +    end )
   16.64    end
   16.65  }
    17.1 --- a/app/main/area/_head.lua	Thu Jul 10 01:02:43 2014 +0200
    17.2 +++ b/app/main/area/_head.lua	Thu Jul 10 01:19:48 2014 +0200
    17.3 @@ -1,110 +1,39 @@
    17.4  local area = param.get("area", "table")
    17.5  local member = param.get("member", "table")
    17.6  
    17.7 -local show_content = param.get("show_content", atom.boolean)
    17.8 +ui.title ( function ()
    17.9  
   17.10 -if app.session.member_id then
   17.11 -  area:load_delegation_info_once_for_member_id(app.session.member_id)
   17.12 -end
   17.13 +  -- unit link
   17.14 +  ui.link {
   17.15 +    attr = { class = "unit" },
   17.16 +    content = function()
   17.17 +      ui.tag{ attr = { class = "name" }, content = area.unit.name }
   17.18 +    end,
   17.19 +    module = "unit", view = "show",
   17.20 +    id = area.unit.id
   17.21 +  }
   17.22  
   17.23 -if not param.get("hide_unit", atom.boolean) then
   17.24 -  execute.view{ module = "unit", view = "_head", params = { unit = area.unit, member = member } }
   17.25 -end
   17.26 +  ui.tag { attr = { class = "spacer" }, content = function()
   17.27 +    slot.put ( " » " )
   17.28 +  end }
   17.29  
   17.30 -ui.container{ attr = { class = "area_head" }, content = function()
   17.31 -
   17.32 -  execute.view{ module = "delegation", view = "_info", params = { area = area, member = member } }
   17.33 +  ui.tag { attr = { class = "area" }, content = function()
   17.34 +    -- area link
   17.35 +    ui.link {
   17.36 +      content = function()
   17.37 +        ui.tag{ attr = { class = "name" }, content = area.name }
   17.38 +      end,
   17.39 +      module = "area", view = "show",
   17.40 +      id = area.id
   17.41 +    }
   17.42 +    
   17.43 +    slot.put ( " " )
   17.44  
   17.45 -  ui.container{ attr = { class = "title" }, content = function()
   17.46 -    -- area name
   17.47 -    ui.link{
   17.48 -      module = "area", view = "show", id = area.id,
   17.49 -      attr = { class = "area_name" }, content = area.name 
   17.50 +    execute.view {
   17.51 +      module = "delegation", view = "_info", params = { 
   17.52 +        area = area, member = member, for_title = true
   17.53 +      }
   17.54      }
   17.55    end }
   17.56    
   17.57 -  if show_content then
   17.58 -    
   17.59 -    ui.container{ attr = { class = "content" }, content = function()
   17.60 -
   17.61 -      -- actions (members with appropriate voting right only)
   17.62 -      if member then
   17.63 -
   17.64 -        -- membership
   17.65 -        local membership = Membership:by_pk(area.id, member.id)
   17.66 -
   17.67 -        if membership then
   17.68 -          
   17.69 -          if app.session.member_id == member.id then
   17.70 -            ui.tag{ content = _"You are participating in this area" }
   17.71 -            slot.put(" ")
   17.72 -            ui.tag{ content = function()
   17.73 -              slot.put("(")
   17.74 -              ui.link{
   17.75 -                text    = _"Withdraw",
   17.76 -                module  = "membership",
   17.77 -                action  = "update",
   17.78 -                params  = { area_id = area.id, delete = true },
   17.79 -                routing = {
   17.80 -                  default = {
   17.81 -                    mode = "redirect",
   17.82 -                    module = request.get_module(),
   17.83 -                    view = request.get_view(),
   17.84 -                    id = param.get_id_cgi(),
   17.85 -                    params = param.get_all_cgi()
   17.86 -                  }
   17.87 -                }
   17.88 -              }
   17.89 -              slot.put(")")
   17.90 -            end }
   17.91 -          else
   17.92 -            ui.tag{ content = _"Member is participating in this area" }
   17.93 -          end
   17.94 -
   17.95 -        elseif app.session.member_id == member.id and member:has_voting_right_for_unit_id(area.unit_id) then
   17.96 -          ui.link{
   17.97 -            text   = _"Participate in this area",
   17.98 -            module = "membership",
   17.99 -            action = "update",
  17.100 -            params = { area_id = area.id },
  17.101 -            routing = {
  17.102 -              default = {
  17.103 -                mode = "redirect",
  17.104 -                module = request.get_module(),
  17.105 -                view = request.get_view(),
  17.106 -                id = param.get_id_cgi(),
  17.107 -                params = param.get_all_cgi()
  17.108 -              }
  17.109 -            }
  17.110 -          }
  17.111 -        end
  17.112 -        
  17.113 -        if app.session.member_id == member.id and app.session.member:has_voting_right_for_unit_id(area.unit_id) then
  17.114 -
  17.115 -          slot.put(" &middot; ")
  17.116 -          if area.delegation_info.own_delegation_scope ~= "area" then
  17.117 -            ui.link{ text = _"Delegate area", module = "delegation", view = "show", params = { area_id = area.id } }
  17.118 -          else
  17.119 -            ui.link{ text = _"Change area delegation", module = "delegation", view = "show", params = { area_id = area.id } }
  17.120 -          end
  17.121 -          slot.put(" &middot; ")
  17.122 -
  17.123 -          ui.link{
  17.124 -            content = function()
  17.125 -              slot.put(_"Create new issue")
  17.126 -            end,
  17.127 -            module = "initiative",
  17.128 -            view = "new",
  17.129 -            params = { area_id = area.id }
  17.130 -          }
  17.131 -        end
  17.132 -
  17.133 -      end
  17.134 -
  17.135 -    end }
  17.136 -
  17.137 -  else
  17.138 -    slot.put("<br />")
  17.139 -  end
  17.140 -
  17.141 -end }
  17.142 \ No newline at end of file
  17.143 +end )
  17.144 \ No newline at end of file
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/app/main/area/_issue_list.lua	Thu Jul 10 01:19:48 2014 +0200
    18.3 @@ -0,0 +1,43 @@
    18.4 +local issues_selector = param.get("issues_selector", "table")
    18.5 +local phase = param.get("phase")
    18.6 +
    18.7 +if phase == "admission" then
    18.8 +  headline = _"Issues in admission phase"
    18.9 +elseif phase == "discussion" then
   18.10 +  headline = _"Issues in discussion phase"
   18.11 +elseif phase == "verification" then
   18.12 +  headline = _"Issues in verification phase"
   18.13 +elseif phase == "voting" then
   18.14 +  headline = _"Issues in voting phase"
   18.15 +elseif phase == "closed" then
   18.16 +  headline = _"Closed issues"
   18.17 +end
   18.18 +  
   18.19 +ui.heading { level = "1", content = headline }
   18.20 +
   18.21 +local issues = issues_selector:exec()
   18.22 +
   18.23 +ui.tag {
   18.24 +  tag = "ul",
   18.25 +  attr = { class = { "issues" } },
   18.26 +  content = function ()
   18.27 +
   18.28 +    for i, issue in ipairs(issues) do
   18.29 +      
   18.30 +      ui.tag { tag = "li", content = function ()
   18.31 +        ui.heading { level = 2, content = issue.name }
   18.32 +        
   18.33 +        execute.view { 
   18.34 +          module = "initiative", view = "_list", params = {
   18.35 +            initiatives = issue.initiatives,
   18.36 +            state = phase
   18.37 +          }
   18.38 +        }
   18.39 +        
   18.40 +        slot.put ( '<hr class="nice" />' )
   18.41 +        
   18.42 +      end }
   18.43 +      
   18.44 +    end
   18.45 +  end
   18.46 +}
   18.47 \ No newline at end of file
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/app/main/area/_sidebar_members.lua	Thu Jul 10 01:19:48 2014 +0200
    19.3 @@ -0,0 +1,33 @@
    19.4 +if not app.session:has_access("all_pseudonymous") then
    19.5 +  return
    19.6 +end
    19.7 +
    19.8 +local area = param.get("area", "table")
    19.9 +local members_selector = Member:new_selector()
   19.10 +  :join("membership", nil, { "membership.member_id = member.id AND membership.area_id = ?", area.id })
   19.11 +  :add_where("member.active")
   19.12 +  :limit(50)
   19.13 +  
   19.14 +ui.sidebar ( "tab-members", function ()
   19.15 +  ui.sidebarHead( function ()
   19.16 +    ui.heading {
   19.17 +      level = 2,
   19.18 +      content = _("Subscribed members (#{count})", {
   19.19 +        count = area.direct_member_count
   19.20 +      })
   19.21 +    }
   19.22 +  end )
   19.23 +  execute.view {
   19.24 +    module = 'member', view   = '_list', params = {
   19.25 +      members_selector = members_selector,
   19.26 +      no_filter = true, no_paginate = true,
   19.27 +      member_class = "sidebarRow sidebarRowNarrow"
   19.28 +   }
   19.29 +  }
   19.30 +  if area.direct_member_count > members_selector:count() then
   19.31 +    ui.link {
   19.32 +      text = _"Show all members",
   19.33 +      module = "member", view = "list"
   19.34 +    }
   19.35 +  end
   19.36 +end )
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/app/main/area/_sidebar_whatcanido.lua	Thu Jul 10 01:19:48 2014 +0200
    20.3 @@ -0,0 +1,168 @@
    20.4 +local member = param.get ( "member", "table" ) or app.session.member
    20.5 +
    20.6 +local area = param.get ( "area", "table" )
    20.7 +
    20.8 +local participating_trustee_id
    20.9 +local participating_trustee_name
   20.10 +if member then
   20.11 +  if area.delegation_info.first_trustee_participation then
   20.12 +    participating_trustee_id = area.delegation_info.first_trustee_id
   20.13 +    participating_trustee_name = area.delegation_info.first_trustee_name
   20.14 +  elseif area.delegation_info.other_trustee_participation then
   20.15 +    participating_trustee_id = area.delegation_info.other_trustee_id
   20.16 +    participating_trustee_name = area.delegation_info.other_trustee_name
   20.17 +  end
   20.18 +end
   20.19 +
   20.20 +ui.sidebar ( "tab-whatcanido", function ()
   20.21 +
   20.22 +  ui.sidebarHeadWhatCanIDo()
   20.23 +  
   20.24 +  if member and not app.session.member:has_voting_right_for_unit_id(area.unit_id) then
   20.25 +    ui.sidebarSection( _"You are not entitled to vote in this unit" )
   20.26 +  end
   20.27 +  
   20.28 +  if member and app.session.member:has_voting_right_for_unit_id(area.unit_id) then
   20.29 +    if not area.delegation_info.own_participation then
   20.30 +      ui.sidebarSection ( function ()
   20.31 +      
   20.32 +        ui.heading {
   20.33 +          level = 3, 
   20.34 +          content = _"I want to participate in this subject area"
   20.35 +        }
   20.36 +        ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
   20.37 +          ui.tag { tag = "li", content = function ()
   20.38 +            ui.tag { content = function ()
   20.39 +              ui.link {
   20.40 +                module = "membership", action = "update",
   20.41 +                routing = { default = {
   20.42 +                  mode = "redirect", module = "area", view = "show", id = area.id
   20.43 +                } },
   20.44 +                params = { area_id = area.id },
   20.45 +                text = _"subscribe"
   20.46 +              }
   20.47 +            end }
   20.48 +          end }
   20.49 +        end }
   20.50 +      end )
   20.51 +    end
   20.52 +      
   20.53 +    if area.delegation_info.own_participation then
   20.54 +      ui.sidebarSection ( function ()
   20.55 +        ui.image{ attr = { class = "right" }, static = "icons/48/star.png" }
   20.56 +        ui.heading {
   20.57 +          level = 3, 
   20.58 +          content = _"You are subscribed for this subject area" 
   20.59 +        }
   20.60 +        ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
   20.61 +          ui.tag { tag = "li", content = function ()
   20.62 +            ui.tag { content = function ()
   20.63 +              ui.link {
   20.64 +                module = "membership", action = "update",
   20.65 +                routing = { default = {
   20.66 +                  mode = "redirect", module = "area", view = "show", id = area.id
   20.67 +                } },
   20.68 +                params = { area_id = area.id, delete = true },
   20.69 +                text = _"unsubscribe"
   20.70 +              }
   20.71 +            end }
   20.72 +          end }
   20.73 +        end }
   20.74 +      end )
   20.75 +    end
   20.76 +    
   20.77 +    
   20.78 +    ui.sidebarSection ( function ()
   20.79 +    
   20.80 +
   20.81 +      if not area.delegation_info.first_trustee_id then
   20.82 +        ui.heading{ level = 3, content = _"I want to delegate this subject area" }
   20.83 +      else
   20.84 +        ui.container { attr = { class = "right" }, content = function()
   20.85 +          local member = Member:by_id(area.delegation_info.first_trustee_id)
   20.86 +          execute.view{
   20.87 +            module = "member_image",
   20.88 +            view = "_show",
   20.89 +            params = {
   20.90 +              member = member,
   20.91 +              image_type = "avatar",
   20.92 +              show_dummy = true
   20.93 +            }
   20.94 +          }
   20.95 +        end }
   20.96 +        ui.heading{ level = 3, content = _"You delegated this subject area" }
   20.97 +      end
   20.98 +
   20.99 +      ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  20.100 +        if area.delegation_info.own_delegation_scope == "unit" then
  20.101 +          ui.tag { tag = "li", content = function ()
  20.102 +            ui.link {
  20.103 +              module = "delegation", view = "show", params = {
  20.104 +                unit_id = area.unit_id,
  20.105 +              },
  20.106 +              content = _("change/revoke delegation of organizational unit")
  20.107 +            }
  20.108 +          end }
  20.109 +        end
  20.110 +        
  20.111 +        if area.delegation_info.own_delegation_scope == nil then
  20.112 +          ui.tag { tag = "li", content = function ()
  20.113 +            ui.link {
  20.114 +              module = "delegation", view = "show", params = {
  20.115 +                area_id = area.id
  20.116 +              },
  20.117 +              content = _"choose subject area delegatee" 
  20.118 +            }
  20.119 +          end }
  20.120 +        elseif area.delegation_info.own_delegation_scope == "area" then
  20.121 +          ui.tag { tag = "li", content = function ()
  20.122 +            ui.link {
  20.123 +              module = "delegation", view = "show", params = {
  20.124 +                area_id = area.id
  20.125 +              },
  20.126 +              content = _"change/revoke area delegation" 
  20.127 +            }
  20.128 +          end }
  20.129 +        else
  20.130 +          ui.tag { tag = "li", content = function ()
  20.131 +            ui.link {
  20.132 +              module = "delegation", view = "show", params = {
  20.133 +                area_id = area.id
  20.134 +              },
  20.135 +              content = _"change/revoke delegation only for this subject area" 
  20.136 +            }
  20.137 +          end }
  20.138 +        end
  20.139 +      end }
  20.140 +    end )
  20.141 +
  20.142 +
  20.143 +      
  20.144 +      
  20.145 +    if app.session.member:has_voting_right_for_unit_id ( area.unit_id ) then
  20.146 +      ui.sidebarSection ( function ()
  20.147 +        ui.heading {
  20.148 +          level = 3, 
  20.149 +          content = _("I want to start a new initiative", {
  20.150 +            area_name = area.name
  20.151 +          } ) 
  20.152 +        }
  20.153 +        ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  20.154 +          ui.tag { tag = "li", content = _"Take a look through the existing issues. Maybe someone else started a debate on your topic (and you can join it) or the topic has been decided already in the past." }
  20.155 +          ui.tag { tag = "li", content = function ()
  20.156 +            ui.tag { content = function ()
  20.157 +              ui.tag { content = _"If you cannot find any appropriate existing issue, " }
  20.158 +              ui.link {
  20.159 +                module = "initiative", view = "new",
  20.160 +                params = { area_id = area.id },
  20.161 +                text = _"start an initiative in a new issue"
  20.162 +              }
  20.163 +            end }
  20.164 +          end }
  20.165 +        end }
  20.166 +      end )
  20.167 +    end
  20.168 +  else
  20.169 +  end
  20.170 +  
  20.171 +end )
  20.172 \ No newline at end of file
    21.1 --- a/app/main/area/show.lua	Thu Jul 10 01:02:43 2014 +0200
    21.2 +++ b/app/main/area/show.lua	Thu Jul 10 01:19:48 2014 +0200
    21.3 @@ -1,27 +1,53 @@
    21.4  local area = Area:by_id(param.get_id())
    21.5  
    21.6 +if not area then
    21.7 +  execute.view { module = "index", view = "404" }
    21.8 +  request.set_status("404 Not Found")
    21.9 +  return
   21.10 +end
   21.11 +
   21.12 +area:load_delegation_info_once_for_member_id(app.session.member_id)
   21.13  
   21.14  app.html_title.title = area.name
   21.15  app.html_title.subtitle = _("Area")
   21.16  
   21.17 -util.help("area.show")
   21.18 -
   21.19 -slot.select("head", function()
   21.20 -  execute.view{ module = "area", view = "_head", params = { area = area, show_content = true, member = app.session.member } }
   21.21 -end)
   21.22 +execute.view {
   21.23 +  module = "area", view = "_head", params = {
   21.24 +    area = area, member = app.session.member
   21.25 +  }
   21.26 +}
   21.27  
   21.28 -ui.container{
   21.29 -  attr = { class = "vertical"},
   21.30 -  content = function()
   21.31 -    ui.field.text{ value = area.description }
   21.32 -  end
   21.33 +execute.view {
   21.34 +  module = "area", view = "_sidebar_whatcanido", params = {
   21.35 +    area = area
   21.36 +  }
   21.37 +}
   21.38 +
   21.39 +execute.view {
   21.40 +  module = "area", view = "_sidebar_members", params = {
   21.41 +    area = area
   21.42 +  }
   21.43  }
   21.44  
   21.45 -local open_issues_selector = area:get_reference_selector("issues")
   21.46 -  :add_where("issue.closed ISNULL")
   21.47 -  :add_order_by("coalesce(issue.fully_frozen + issue.voting_time, issue.half_frozen + issue.verification_time, issue.accepted + issue.discussion_time, issue.created + issue.admission_time) - now()")
   21.48 +function getOpenIssuesSelector()
   21.49 +  return area:get_reference_selector("issues")
   21.50 +    :add_order_by("coalesce(issue.fully_frozen + issue.voting_time, issue.half_frozen + issue.verification_time, issue.accepted + issue.discussion_time, issue.created + issue.admission_time) - now()")
   21.51 +end
   21.52 +
   21.53 +local admission_selector = getOpenIssuesSelector()
   21.54 +  :add_where("issue.state = 'admission'");
   21.55  
   21.56 -local closed_issues_selector = area:get_reference_selector("issues")
   21.57 +local discussion_selector = getOpenIssuesSelector()
   21.58 +  :add_where("issue.state = 'discussion'");
   21.59 +
   21.60 +local verification_selector = getOpenIssuesSelector()
   21.61 +  :add_where("issue.state = 'verification'");
   21.62 +
   21.63 +local voting_selector = getOpenIssuesSelector()
   21.64 +  :add_where("issue.state = 'voting'");
   21.65 +
   21.66 +
   21.67 +local closed_selector = area:get_reference_selector("issues")
   21.68    :add_where("issue.closed NOTNULL")
   21.69    :add_order_by("issue.closed DESC")
   21.70  
   21.71 @@ -30,61 +56,9 @@
   21.72    :join("member", "truster", "truster.id = delegation.truster_id AND truster.active")
   21.73    :join("member", "trustee", "trustee.id = delegation.trustee_id AND trustee.active")
   21.74  
   21.75 -local tabs = {
   21.76 -  module = "area",
   21.77 -  view = "show_tab",
   21.78 -  static_params = { area_id = area.id },
   21.79 -}
   21.80  
   21.81 -tabs[#tabs+1] = {
   21.82 -  name = "timeline",
   21.83 -  label = _"Latest events",
   21.84 -  module = "event",
   21.85 -  view = "_list",
   21.86 +execute.view {
   21.87 +  module = "issue",
   21.88 +  view = "_list2",
   21.89    params = { for_area = area }
   21.90  }
   21.91 -
   21.92 -tabs[#tabs+1] = {
   21.93 -  name = "open",
   21.94 -  label = _"Open issues",
   21.95 -  module = "issue",
   21.96 -  view = "_list",
   21.97 -  params = {
   21.98 -    for_state = "open",
   21.99 -    issues_selector = open_issues_selector, for_area = true
  21.100 -  }
  21.101 -}
  21.102 -tabs[#tabs+1] = {
  21.103 -  name = "closed",
  21.104 -  label = _"Closed issues",
  21.105 -  module = "issue",
  21.106 -  view = "_list",
  21.107 -  params = {
  21.108 -    for_state = "closed",
  21.109 -    issues_selector = closed_issues_selector, for_area = true
  21.110 -  }
  21.111 -}
  21.112 -
  21.113 -if app.session:has_access("all_pseudonymous") then
  21.114 -  tabs[#tabs+1] =
  21.115 -    {
  21.116 -      name = "members",
  21.117 -      label = _"Participants" .. " (" .. tostring(members_selector:count()) .. ")",
  21.118 -      icon = { static = "icons/16/group.png" },
  21.119 -      module = "member",
  21.120 -      view = "_list",
  21.121 -      params = { members_selector = members_selector }
  21.122 -    }
  21.123 -
  21.124 -  tabs[#tabs+1] =
  21.125 -    {
  21.126 -      name = "delegations",
  21.127 -      label = _"Delegations" .. " (" .. tostring(delegations_selector:count()) .. ")",
  21.128 -      icon = { static = "icons/16/table_go.png" },
  21.129 -      module = "delegation",
  21.130 -      view = "_list",
  21.131 -      params = { delegations_selector = delegations_selector }
  21.132 -    }
  21.133 -end
  21.134 -
  21.135 -ui.tabs(tabs)
    22.1 --- a/app/main/contact/list.lua	Thu Jul 10 01:02:43 2014 +0200
    22.2 +++ b/app/main/contact/list.lua	Thu Jul 10 01:19:48 2014 +0200
    22.3 @@ -6,9 +6,6 @@
    22.4  ui.title(_"Contacts")
    22.5  
    22.6  
    22.7 -util.help("contact.list")
    22.8 -
    22.9 -
   22.10  ui.paginate{
   22.11    selector = contacts_selector,
   22.12    content = function()
    23.1 --- a/app/main/delegation/_info.lua	Thu Jul 10 01:02:43 2014 +0200
    23.2 +++ b/app/main/delegation/_info.lua	Thu Jul 10 01:19:48 2014 +0200
    23.3 @@ -8,6 +8,8 @@
    23.4  local area  = param.get("area", "table")
    23.5  local issue = param.get("issue", "table")
    23.6  
    23.7 +local for_title = param.get("for_title", "boolean")
    23.8 +
    23.9  local unit_id  = unit  and unit.id  or nil
   23.10  local area_id  = area  and area.id  or nil
   23.11  local issue_id = issue and issue.id or nil
   23.12 @@ -21,7 +23,6 @@
   23.13  end
   23.14  
   23.15  if area then
   23.16 -  area:load_delegation_info_once_for_member_id(member.id)
   23.17    info = area.delegation_info
   23.18    delegation_text = _"Delegate area"
   23.19  end
   23.20 @@ -31,24 +32,13 @@
   23.21    delegation_text = _"Delegate issue"
   23.22  end
   23.23  
   23.24 +if not info then
   23.25 +  --return
   23.26 +end
   23.27 +
   23.28  local function print_delegation_info()
   23.29 -  local participant_occured = false
   23.30 +  local participant_occured = info.own_participation
   23.31    
   23.32 -  if info.own_participation or info.first_trustee_id then
   23.33 -    
   23.34 -    local class = "micro_avatar"
   23.35 -    if info.own_participation then
   23.36 -      participant_occured = true
   23.37 -      class = class .. " highlighted"
   23.38 -    end
   23.39 -    
   23.40 -    execute.view{ module = "member_image", view = "_show", params = {
   23.41 -      member = member, class = class, popup_text = member.name,
   23.42 -      image_type = "avatar", show_dummy = true,
   23.43 -    } }
   23.44 -
   23.45 -  end
   23.46 -
   23.47    if not (issue and issue.state == "voting" and info.own_participation) then
   23.48      
   23.49      if info.first_trustee_id then
   23.50 @@ -154,10 +144,15 @@
   23.51            static = "delegation_arrow_24_horizontal.png"
   23.52          }
   23.53  
   23.54 -        execute.view{ module = "member_image", view = "_show", params = {
   23.55 -          member_id = info.first_trustee_id, class = "micro_avatar", popup_text = info.first_trustee_name,
   23.56 -          image_type = "avatar", show_dummy = true,
   23.57 -        } }
   23.58 +        execute.view{
   23.59 +          module = "member_image", view = "_show", params = {
   23.60 +            member_id = info.first_trustee_id, 
   23.61 +            class = "micro_avatar", 
   23.62 +            popup_text = info.first_trustee_name,
   23.63 +            image_type = "avatar",
   23.64 +            show_dummy = true,
   23.65 +          }
   23.66 +        }
   23.67        end
   23.68      
   23.69          
   23.70 @@ -174,24 +169,94 @@
   23.71    end
   23.72  end
   23.73  
   23.74 +if not param.get("no_star", "boolean") then
   23.75 +  
   23.76 +  if info.own_participation then
   23.77 +    if issue and issue.fully_frozen then
   23.78 +      ui.link{
   23.79 +        attr = { class = "right" },
   23.80 +        module = "vote", view = "list", params = {
   23.81 +          issue_id = issue.id
   23.82 +        },
   23.83 +        content = function ()
   23.84 +          ui.tag { content = _"you voted" }
   23.85 +        end
   23.86 +      }
   23.87 +    else
   23.88 +      if issue then
   23.89 +        local text = _"you are interested"
   23.90 +        ui.image { attr = { class = "star", title = text, alt = text }, static = "icons/48/eye.png" }
   23.91 +        if not issue.closed and info.own_participation and info.weight and info.weight > 1 then
   23.92 +          ui.link { 
   23.93 +            attr = { class = "right" }, content = "+" .. (info.weight - 1),
   23.94 +            module = "delegation", view = "show_incoming", params = { 
   23.95 +              issue_id = issue.id, member_id = member.id
   23.96 +            }
   23.97 +          }
   23.98 +        end
   23.99 +      else
  23.100 +        local text = _"you are subscribed"
  23.101 +        ui.image { attr = { class = "icon24 star", title = text, alt = text }, static = "icons/48/star.png" }
  23.102 +      end
  23.103 +      if not for_title then
  23.104 +        slot.put("<br />")
  23.105 +      else
  23.106 +        slot.put(" ")
  23.107 +      end
  23.108 +    end
  23.109 +  end
  23.110 +end
  23.111 +
  23.112  
  23.113  if info.own_participation or info.first_trustee_id then
  23.114 +  local class = "delegation_info"
  23.115 +  if info.own_participation then
  23.116 +    class = class .. " suspended"
  23.117 +  end
  23.118 +
  23.119 +  local voting_member_id
  23.120 +  local voting_member_name
  23.121 +  if issue and issue.fully_frozen and issue.closed then
  23.122 +    if issue.member_info.first_trustee_participation then
  23.123 +      voting_member_id = issue.member_info.first_trustee_id
  23.124 +      voting_member_name = issue.member_info.first_trustee_name
  23.125 +    elseif issue.member_info.other_trustee_participation then
  23.126 +      voting_member_id = issue.member_info.other_trustee_id
  23.127 +      voting_member_name = issue.member_info.other_trustee_name
  23.128 +    end
  23.129 +  end
  23.130 +  
  23.131    if app.session.member_id == member.id then
  23.132 -    ui.link{
  23.133 -      module = "delegation", view = "show", params = {
  23.134 -        unit_id = unit_id,
  23.135 -        area_id = area_id,
  23.136 -        issue_id = issue_id
  23.137 -      },
  23.138 -      attr = { class = "delegation_info" }, content = function()
  23.139 -        print_delegation_info()
  23.140 -      end
  23.141 -    }
  23.142 +
  23.143 +    if voting_member_id  then
  23.144 +      ui.link{
  23.145 +        module = "vote", view = "list", params = {
  23.146 +          issue_id = issue.id,
  23.147 +          member_id = voting_member_id
  23.148 +        },
  23.149 +        attr = { class = class }, content = function()
  23.150 +          print_delegation_info()
  23.151 +        end
  23.152 +      }
  23.153 +    
  23.154 +    else
  23.155 +      ui.link{
  23.156 +        module = "delegation", view = "show", params = {
  23.157 +          unit_id = unit_id,
  23.158 +          area_id = area_id,
  23.159 +          issue_id = issue_id
  23.160 +        },
  23.161 +        attr = { class = class }, content = function()
  23.162 +          print_delegation_info()
  23.163 +        end
  23.164 +      }
  23.165 +    end
  23.166    else
  23.167      ui.container{
  23.168 -      attr = { class = "delegation_info" }, content = function()
  23.169 +      attr = { class = class }, content = function()
  23.170          print_delegation_info()
  23.171        end
  23.172      }
  23.173    end
  23.174  end
  23.175 +
    24.1 --- a/app/main/delegation/_list.lua	Thu Jul 10 01:02:43 2014 +0200
    24.2 +++ b/app/main/delegation/_list.lua	Thu Jul 10 01:19:48 2014 +0200
    24.3 @@ -3,83 +3,84 @@
    24.4  local incoming = param.get("incoming", atom.boolean)
    24.5  
    24.6  local function delegation_scope(delegation)
    24.7 -  ui.container{
    24.8 +  ui.tag{
    24.9      attr = { class = "delegation_scope" },
   24.10      content = function()
   24.11        local area
   24.12        local unit
   24.13        if delegation.issue then
   24.14          area = delegation.issue.area
   24.15 +        unit = area.unit
   24.16        elseif delegation.area then
   24.17          area = delegation.area
   24.18 +        unit = area.unit
   24.19        else
   24.20          unit = delegation.unit
   24.21        end
   24.22 -      if unit then
   24.23 +      slot.put("<br style='clear: left;' />")
   24.24 +      ui.heading { attr = { style = "float: left;" }, level = 3, content = function()
   24.25          ui.link{
   24.26 -          content = _"Unit '#{name}'":gsub("#{name}", unit.name),
   24.27 +          content = unit.name,
   24.28            module = "unit",
   24.29            view = "show",
   24.30            id = unit.id
   24.31          }
   24.32 -      end
   24.33 -      if area then
   24.34 -        ui.link{
   24.35 -          content = _"Area '#{name}'":gsub("#{name}", area.name),
   24.36 -          module = "area",
   24.37 -          view = "show",
   24.38 -          id = area.id
   24.39 -        }
   24.40 -      end
   24.41 -      if delegation.issue then
   24.42 -        ui.link{
   24.43 -          content = _"Issue ##{id}":gsub("#{id}", delegation.issue.id),
   24.44 -          module = "issue",
   24.45 -          view = "show",
   24.46 -          id = delegation.issue.id
   24.47 -        }
   24.48 -      end
   24.49 +        if area then
   24.50 +          slot.put(" &middot; ")
   24.51 +          ui.link{
   24.52 +            content = area.name,
   24.53 +            module = "area",
   24.54 +            view = "show",
   24.55 +            id = area.id
   24.56 +          }
   24.57 +        end
   24.58 +        if delegation.issue then
   24.59 +          slot.put(" &middot; ")
   24.60 +          ui.link{
   24.61 +            content = delegation.issue.name,
   24.62 +            module = "issue",
   24.63 +            view = "show",
   24.64 +            id = delegation.issue.id
   24.65 +          }
   24.66 +        end
   24.67 +      end }
   24.68      end
   24.69    }
   24.70  end
   24.71  
   24.72  
   24.73 -ui.paginate{
   24.74 -  selector = delegations_selector,
   24.75 -  content = function()
   24.76 +--ui.paginate{
   24.77 +--  selector = delegations_selector,
   24.78 +--  name = incoming and "delegation_incoming" or "delegation_outgoing",
   24.79 +--  content = function()
   24.80 +    local last_scope = {}
   24.81      for i, delegation in ipairs(delegations_selector:exec()) do
   24.82 -      ui.container{
   24.83 -        attr = { class = "delegation_list_entry" },
   24.84 -        content = function()
   24.85 -          if outgoing then
   24.86 -            delegation_scope(delegation)
   24.87 -          else
   24.88 -            execute.view{
   24.89 -              module = "member",
   24.90 -              view = "_show_thumb",
   24.91 -              params = { member = delegation.truster }
   24.92 -            }
   24.93 -          end
   24.94 -          ui.image{
   24.95 -            attr = { class = "delegation_arrow" },
   24.96 -            static = "delegation_arrow.jpg"
   24.97 -          }
   24.98 -          if incoming then
   24.99 -            delegation_scope(delegation)
  24.100 -          else
  24.101 -            if delegation.trustee then
  24.102 -              execute.view{
  24.103 -                module = "member",
  24.104 -                view = "_show_thumb",
  24.105 -                params = { member = delegation.trustee }
  24.106 -              }
  24.107 -            else
  24.108 -              ui.tag{ content = _"Delegation abandoned" }
  24.109 -            end
  24.110 -          end
  24.111 -        end
  24.112 -      }
  24.113 +      if last_scope.unit_id ~= delegation.unit_id
  24.114 +        or last_scope.area_id ~= delegation.area_id
  24.115 +        or last_scope.issue_id ~= delegation.issue_id
  24.116 +      then
  24.117 +        last_scope.unit_id = delegation.unit_id
  24.118 +        last_scope.area_id = delegation.area_id
  24.119 +        last_scope.issue_id = delegation.issue_id
  24.120 +        delegation_scope(delegation)
  24.121 +      end
  24.122 +      if incoming then
  24.123 +        execute.view{ module = "member_image", view = "_show", params = {
  24.124 +          member_id = delegation.truster_id, class = "micro_avatar", popup_text = delegation.truster.name,
  24.125 +          image_type = "avatar", show_dummy = true,
  24.126 +        } }
  24.127 +      elseif delegation.trustee then
  24.128 +        ui.image{
  24.129 +          attr = { class = "delegation_arrow" },
  24.130 +          static = "delegation_arrow_24_horizontal.png"
  24.131 +        }
  24.132 +        execute.view{ module = "member_image", view = "_show", params = {
  24.133 +          member_id = delegation.trustee_id, class = "micro_avatar", popup_text = delegation.trustee.name,
  24.134 +          image_type = "avatar", show_dummy = true,
  24.135 +        } }
  24.136 +      else
  24.137 +        ui.tag{ content = _"Delegation abandoned" }
  24.138 +      end
  24.139      end
  24.140 -    slot.put("<br style='clear: left;' />")
  24.141 -  end
  24.142 -}
  24.143 +--  end
  24.144 +--}
    25.1 --- a/app/main/delegation/show.lua	Thu Jul 10 01:02:43 2014 +0200
    25.2 +++ b/app/main/delegation/show.lua	Thu Jul 10 01:19:48 2014 +0200
    25.3 @@ -2,7 +2,17 @@
    25.4  local current_trustee_id
    25.5  local current_trustee_name
    25.6  
    25.7 +local head_text
    25.8 +
    25.9  local unit = Unit:by_id(param.get("unit_id", atom.integer))
   25.10 +local area = Area:by_id(param.get("area_id", atom.integer))
   25.11 +local issue = Issue:by_id(param.get("issue_id", atom.integer))
   25.12 +local initiative = Initiative:by_id(param.get("initiative_id", atom.integer))
   25.13 +
   25.14 +if initiative then
   25.15 +  issue = initiative.issue
   25.16 +end
   25.17 +
   25.18  if unit then
   25.19    unit:load_delegation_info_once_for_member_id(app.session.member_id)
   25.20    voting_right_unit_id = unit.id
   25.21 @@ -10,11 +20,10 @@
   25.22      current_trustee_id = unit.delegation_info.first_trustee_id
   25.23      current_trustee_name = unit.delegation_info.first_trustee_name
   25.24    end
   25.25 -  ui.title(config.single_unit_id and _"Set global delegation" or _"Set unit delegation")
   25.26 -  util.help("delegation.new.unit")
   25.27 +  execute.view { module = "unit", view = "_head", params = { unit = unit } }
   25.28 +  head_text = _"Set unit delegation"
   25.29  end
   25.30  
   25.31 -local area = Area:by_id(param.get("area_id", atom.integer))
   25.32  if area then
   25.33    area:load_delegation_info_once_for_member_id(app.session.member_id)
   25.34    voting_right_unit_id = area.unit_id
   25.35 @@ -22,11 +31,10 @@
   25.36      current_trustee_id = area.delegation_info.first_trustee_id
   25.37      current_trustee_name = area.delegation_info.first_trustee_name
   25.38    end
   25.39 -  ui.title(_"Set delegation for Area '#{name}'":gsub("#{name}", area.name))
   25.40 -  util.help("delegation.new.area")
   25.41 +  execute.view { module = "area", view = "_head", params = { area = area } }
   25.42 +  head_text = _"Set area delegation"
   25.43  end
   25.44  
   25.45 -local issue = Issue:by_id(param.get("issue_id", atom.integer))
   25.46  if issue then
   25.47    issue:load("member_info", { member_id = app.session.member_id })
   25.48    voting_right_unit_id = issue.area.unit_id
   25.49 @@ -34,8 +42,13 @@
   25.50      current_trustee_id = issue.member_info.first_trustee_id
   25.51      current_trustee_name = issue.member_info.first_trustee_name
   25.52    end
   25.53 -  ui.title(_"Set delegation for Issue ##{number} in Area '#{area_name}'":gsub("#{number}", issue.id):gsub("#{area_name}", issue.area.name))
   25.54 -  util.help("delegation.new.issue")
   25.55 +  execute.view { module = "issue", view = "_head", params = { issue = issue } }
   25.56 +  head_text = _"Set issue delegation"
   25.57 +end
   25.58 +
   25.59 +if param.get("initiative_id", atom.integer) then
   25.60 +  issue_id = initiative.issue_id
   25.61 +  scope = "issue"
   25.62  end
   25.63  
   25.64  
   25.65 @@ -44,17 +57,16 @@
   25.66  local area_id
   25.67  local issue_id
   25.68  local initiative_id
   25.69 -local initiative
   25.70  
   25.71  local scope = "unit"
   25.72  
   25.73 +local inline = param.get("inline", atom.boolean)
   25.74 +
   25.75 +
   25.76  unit_id = param.get("unit_id", atom.integer)
   25.77  
   25.78 -local inline = param.get("inline", atom.boolean)
   25.79 -
   25.80  if param.get("initiative_id", atom.integer) then
   25.81 -  initiative_id = param.get("initiative_id", atom.integer)
   25.82 -  initiative = Initiative:by_id(initiative_id)
   25.83 +  initiative_id = initiative.id
   25.84    issue_id = initiative.issue_id
   25.85    scope = "issue"
   25.86  end
   25.87 @@ -106,177 +118,204 @@
   25.88  
   25.89  ui.script{ static = "js/update_delegation_info.js" }
   25.90  
   25.91 -ui.actions(function()
   25.92 -  if issue then
   25.93 -    ui.link{
   25.94 -      module = "issue",
   25.95 -      view = "show",
   25.96 -      id = issue.id,
   25.97 -      content = function()
   25.98 -          ui.image{ static = "icons/16/cancel.png" }
   25.99 -          slot.put(_"Cancel")
  25.100 -      end,
  25.101 -    }
  25.102 -  elseif area then
  25.103 -    ui.link{
  25.104 -      module = "area",
  25.105 -      view = "show",
  25.106 -      id = area.id,
  25.107 -      content = function()
  25.108 -          ui.image{ static = "icons/16/cancel.png" }
  25.109 -          slot.put(_"Cancel")
  25.110 -      end,
  25.111 -    }
  25.112 -  else
  25.113 -    ui.link{
  25.114 -      module = "index",
  25.115 -      view = "index",
  25.116 -      content = function()
  25.117 -          ui.image{ static = "icons/16/cancel.png" }
  25.118 -          slot.put(_"Cancel")
  25.119 -      end,
  25.120 -    }
  25.121 -  end
  25.122 -end)
  25.123 +
  25.124 +ui.section( function () 
  25.125 +  
  25.126 +  ui.sectionHead( function ()
  25.127 +    ui.heading{ level = 1, content = head_text }
  25.128 +  end )
  25.129 +  
  25.130 +  ui.sectionRow( function ()
  25.131  
  25.132 -
  25.133 -ui.form{
  25.134 -  attr = { class = "vertical", id = "delegationForm" },
  25.135 -  module = "delegation",
  25.136 -  action = "update",
  25.137 -  params = {
  25.138 -    unit_id = unit and unit.id or nil,
  25.139 -    area_id = area and area.id or nil,
  25.140 -    issue_id = issue and issue.id or nil,
  25.141 -    initiative_id = initiative_id
  25.142 -  },
  25.143 -  routing = {
  25.144 -    default = {
  25.145 -      mode = "redirect",
  25.146 -      module = area and "area" or initiative and "initiative" or issue and "issue" or "unit",
  25.147 -      view = "show",
  25.148 -      id = area and area.id or initiative and initiative.id or issue and issue.id or unit.id,
  25.149 -    }
  25.150 -  },
  25.151 -  content = function()
  25.152 -    local records
  25.153 -
  25.154 -    if issue then
  25.155 -      local delegate_name = ""
  25.156 -      local scope = "no delegation set"
  25.157 -      local area_delegation = Delegation:by_pk(app.session.member_id, nil, issue.area_id)
  25.158 -      if area_delegation then
  25.159 -        delegate_name = area_delegation.trustee and area_delegation.trustee.name or _"abandoned"
  25.160 -        scope = _"area"
  25.161 -      else
  25.162 -        local unit_delegation = Delegation:by_pk(app.session.member_id, issue.area.unit_id)
  25.163 +  ui.form{
  25.164 +    attr = { class = "wide section", id = "delegationForm" },
  25.165 +    module = "delegation",
  25.166 +    action = "update",
  25.167 +    params = {
  25.168 +      unit_id = unit and unit.id or nil,
  25.169 +      area_id = area and area.id or nil,
  25.170 +      issue_id = issue and issue.id or nil,
  25.171 +      initiative_id = initiative_id
  25.172 +    },
  25.173 +    routing = {
  25.174 +      default = {
  25.175 +        mode = "redirect",
  25.176 +        module = area and "area" or initiative and "initiative" or issue and "issue" or "unit",
  25.177 +        view = "show",
  25.178 +        id = area and area.id or initiative and initiative.id or issue and issue.id or unit.id,
  25.179 +      }
  25.180 +    },
  25.181 +    content = function()
  25.182 +      local record
  25.183 +      if issue then
  25.184 +        local delegate_name = ""
  25.185 +        local scope = "no delegation set"
  25.186 +        local area_delegation = Delegation:by_pk(app.session.member_id, nil, issue.area_id)
  25.187 +        if area_delegation then
  25.188 +          delegate_name = area_delegation.trustee and area_delegation.trustee.name or _"abandoned"
  25.189 +          scope = _"area"
  25.190 +        else
  25.191 +          local unit_delegation = Delegation:by_pk(app.session.member_id, issue.area.unit_id)
  25.192 +          if unit_delegation then
  25.193 +            delegate_name = unit_delegation.trustee.name
  25.194 +            scope = config.single_unit_id and _"global" or _"unit"
  25.195 +          end
  25.196 +        end
  25.197 +        local text_apply
  25.198 +        local text_abandon
  25.199 +        if config.single_unit_id then
  25.200 +          text_apply = _("Apply global or area delegation for this issue (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope })
  25.201 +          text_abandon = _"Abandon unit and area delegations for this issue"
  25.202 +        else
  25.203 +          text_apply = _("Apply unit or area delegation for this issue (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope })
  25.204 +          text_abandon = _"Abandon unit and area delegations for this issue"
  25.205 +        end
  25.206 +        
  25.207 +        records = {
  25.208 +          { id = -1, name = text_apply },
  25.209 +          { id = 0,  name = text_abandon }
  25.210 +        }
  25.211 +      elseif area then
  25.212 +        local delegate_name = ""
  25.213 +        local scope = "no delegation set"
  25.214 +        local unit_delegation = Delegation:by_pk(app.session.member_id, area.unit_id)
  25.215          if unit_delegation then
  25.216            delegate_name = unit_delegation.trustee.name
  25.217            scope = config.single_unit_id and _"global" or _"unit"
  25.218          end
  25.219 -      end
  25.220 -      local text_apply
  25.221 -      local text_abandon
  25.222 -      if config.single_unit_id then
  25.223 -        text_apply = _("Apply global or area delegation for this issue (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope })
  25.224 -        text_abandon = _"Abandon unit and area delegations for this issue"
  25.225 +        local text_apply
  25.226 +        local text_abandon
  25.227 +        if config.single_unit_id then
  25.228 +          text_apply = _("Apply global delegation for this area (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope })
  25.229 +          text_abandon = _"Abandon global delegation for this area"
  25.230 +        else
  25.231 +          text_apply = _("Apply unit delegation for this area (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope })
  25.232 +          text_abandon = _"Abandon unit delegation for this area"
  25.233 +        end
  25.234 +        records = {
  25.235 +          {
  25.236 +            id = -1,
  25.237 +            name = text_apply
  25.238 +          },
  25.239 +          {
  25.240 +            id = 0,
  25.241 +            name = text_abandon
  25.242 +          }
  25.243 +        }
  25.244 +
  25.245        else
  25.246 -        text_apply = _("Apply unit or area delegation for this issue (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope })
  25.247 -        text_abandon = _"Abandon unit and area delegations for this issue"
  25.248 +        records = {
  25.249 +          {
  25.250 +            id = -1,
  25.251 +            name = _"No delegation"
  25.252 +          }
  25.253 +        }
  25.254 +
  25.255        end
  25.256 -      records = {
  25.257 -        { id = -1, name = text_apply },
  25.258 -        { id = 0,  name = text_abandon }
  25.259 -      }
  25.260 -    elseif area then
  25.261 -      local delegate_name = ""
  25.262 -      local scope = "no delegation set"
  25.263 -      local unit_delegation = Delegation:by_pk(app.session.member_id, area.unit_id)
  25.264 -      if unit_delegation then
  25.265 -        delegate_name = unit_delegation.trustee.name
  25.266 -        scope = config.single_unit_id and _"global" or _"unit"
  25.267 +      -- add current trustee
  25.268 +      if current_trustee_id then
  25.269 +        records[#records+1] = {id="_", name= "--- " .. _"Current delegatee" .. " ---"}
  25.270 +        records[#records+1] = { id = current_trustee_id, name = current_trustee_name }
  25.271 +      end
  25.272 +      -- add initiative authors
  25.273 +      if initiative then
  25.274 +        records[#records+1] = {id="_", name= "--- " .. _"Initiators" .. " ---"}
  25.275 +        for i,record in ipairs(initiative.initiators) do
  25.276 +          records[#records+1] = record.member
  25.277 +        end
  25.278 +      end
  25.279 +      -- add saved members
  25.280 +      if #contact_members > 0 then
  25.281 +        records[#records+1] = {id="_", name= "--- " .. _"Saved contacts" .. " ---"}
  25.282 +        for i, record in ipairs(contact_members) do
  25.283 +          records[#records+1] = record
  25.284 +        end
  25.285 +      end
  25.286 +
  25.287 +      disabled_records = {}
  25.288 +      disabled_records["_"] = true
  25.289 +      disabled_records[app.session.member_id] = true
  25.290 +
  25.291 +      local value = current_trustee_id
  25.292 +      if preview_trustee_id then
  25.293 +        value = preview_trustee_id
  25.294 +      end
  25.295 +      if preview_trustee_id == nil and delegation and not delegation.trustee_id then
  25.296 +        value = 0
  25.297        end
  25.298 -      local text_apply
  25.299 -      local text_abandon
  25.300 -      if config.single_unit_id then
  25.301 -        text_apply = _("Apply global delegation for this area (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope })
  25.302 -        text_abandon = _"Abandon global delegation for this area"
  25.303 +
  25.304 +      ui.heading{ level = 2, content = _"Choose your delegatee" }
  25.305 +      
  25.306 +      ui.field.select{
  25.307 +        attr = { onchange = "updateDelegationInfo();" },
  25.308 +        name = "trustee_id",
  25.309 +        foreign_records = records,
  25.310 +        foreign_id = "id",
  25.311 +        foreign_name = "name",
  25.312 +        disabled_records = disabled_records,
  25.313 +        value = value
  25.314 +      }
  25.315 +      
  25.316 +      ui.container{ content = _"You can choose only members which you have been saved as contact before." }
  25.317 +
  25.318 +      ui.field.hidden{ name = "preview" }
  25.319 +      
  25.320 +      slot.put("<br />")
  25.321 +      ui.tag { tag = "input", content = "", attr = { 
  25.322 +        type = "submit",
  25.323 +        value = _"Save",
  25.324 +        class = "btn btn-default",
  25.325 +      } }
  25.326 +        
  25.327 +      slot.put("<br /><br /><br />")
  25.328 +      if initiative then
  25.329 +        ui.link{
  25.330 +          module = "initiative",
  25.331 +          view = "show",
  25.332 +          id = initiative.id,
  25.333 +          content = function()
  25.334 +              slot.put(_"Cancel")
  25.335 +          end,
  25.336 +        }
  25.337 +      elseif issue then
  25.338 +        ui.link{
  25.339 +          module = "issue",
  25.340 +          view = "show",
  25.341 +          id = issue.id,
  25.342 +          content = function()
  25.343 +              slot.put(_"Cancel")
  25.344 +          end,
  25.345 +        }
  25.346 +      elseif area then
  25.347 +        ui.link{
  25.348 +          module = "area",
  25.349 +          view = "show",
  25.350 +          id = area.id,
  25.351 +          content = function()
  25.352 +              slot.put(_"Cancel")
  25.353 +          end,
  25.354 +        }
  25.355        else
  25.356 -        text_apply = _("Apply unit delegation for this area (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope })
  25.357 -        text_abandon = _"Abandon unit delegation for this area"
  25.358 +        ui.link{
  25.359 +          module = "index",
  25.360 +          view = "index",
  25.361 +          content = function()
  25.362 +              slot.put(_"Cancel")
  25.363 +          end,
  25.364 +        }
  25.365        end
  25.366 -      records = {
  25.367 -        {
  25.368 -          id = -1,
  25.369 -          name = text_apply
  25.370 -        },
  25.371 -        {
  25.372 -          id = 0,
  25.373 -          name = text_abandon
  25.374 -        }
  25.375 -      }
  25.376 -
  25.377 -    else
  25.378 -      records = {
  25.379 -        {
  25.380 -          id = -1,
  25.381 -          name = _"No delegation"
  25.382 -        }
  25.383 -      }
  25.384  
  25.385      end
  25.386 -    -- add current trustee
  25.387 -    if current_trustee_id then
  25.388 -      records[#records+1] = {id="_", name= "--- " .. _"Current trustee" .. " ---"}
  25.389 -      records[#records+1] = { id = current_trustee_id, name = current_trustee_name }
  25.390 -    end
  25.391 -    -- add initiative authors
  25.392 -    if initiative then
  25.393 -      records[#records+1] = {id="_", name= "--- " .. _"Initiators" .. " ---"}
  25.394 -      for i,record in ipairs(initiative.initiators) do
  25.395 -        records[#records+1] = record.member
  25.396 -      end
  25.397 -    end
  25.398 -    -- add saved members
  25.399 -    if #contact_members > 0 then
  25.400 -      records[#records+1] = {id="_", name= "--- " .. _"Saved contacts" .. " ---"}
  25.401 -      for i, record in ipairs(contact_members) do
  25.402 -        records[#records+1] = record
  25.403 -      end
  25.404 -    end
  25.405 +  }
  25.406  
  25.407 -    disabled_records = {}
  25.408 -    disabled_records["_"] = true
  25.409 -    disabled_records[app.session.member_id] = true
  25.410 +end ) end )
  25.411 +-- ------------------------
  25.412  
  25.413 -    local value = current_trustee_id
  25.414 -    if preview_trustee_id then
  25.415 -      value = preview_trustee_id
  25.416 -    end
  25.417 -    if preview_trustee_id == nil and delegation and not delegation.trustee_id then
  25.418 -      value = 0
  25.419 -    end
  25.420 -    
  25.421 -    ui.field.select{
  25.422 -      attr = { onchange = "updateDelegationInfo();" },
  25.423 -      label = _"Trustee",
  25.424 -      name = "trustee_id",
  25.425 -      foreign_records = records,
  25.426 -      foreign_id = "id",
  25.427 -      foreign_name = "name",
  25.428 -      disabled_records = disabled_records,
  25.429 -      value = value
  25.430 -    }
  25.431 +ui.sidebar( "tab-members", function () 
  25.432  
  25.433 -    ui.field.hidden{ name = "preview" }
  25.434 -    
  25.435 -    ui.submit{ text = _"Save" }
  25.436 -    
  25.437 -  end
  25.438 -}
  25.439 -
  25.440 -
  25.441 --- ------------------------
  25.442 +ui.sidebarHead( function ()
  25.443 +  ui.heading { level = 1, content = _"Preview of delegation" }
  25.444 +end )
  25.445  
  25.446  local preview_inherit = false
  25.447  local tmp_preview_trustee_id = preview_trustee_id
  25.448 @@ -293,50 +332,58 @@
  25.449  for i, record in ipairs(delegation_chain) do
  25.450    local style
  25.451    local overridden = (not issue or issue.state ~= 'voting') and record.overridden
  25.452 -  if record.scope_in then
  25.453 -    if not overridden then
  25.454 -      ui.image{
  25.455 -        attr = { class = "delegation_arrow" },
  25.456 -        static = "delegation_arrow_24_vertical.png"
  25.457 -      }
  25.458 -    else
  25.459 -      ui.image{
  25.460 -        attr = { class = "delegation_arrow delegation_arrow_overridden" },
  25.461 -        static = "delegation_arrow_24_vertical.png"
  25.462 +  ui.sidebarSection( function ()
  25.463 +    if record.scope_in then
  25.464 +      if not overridden then
  25.465 +        local text = _"delegated to"
  25.466 +        ui.image{
  25.467 +          attr = { class = "delegation_arrow", alt = text, title = text },
  25.468 +          static = "delegation_arrow_24_vertical.png"
  25.469 +        }
  25.470 +      else
  25.471 +        local text = _"delegated to"
  25.472 +        ui.image{
  25.473 +          attr = { class = "delegation_arrow delegation_arrow_overridden", alt = text, title = text  },
  25.474 +          static = "delegation_arrow_24_vertical.png"
  25.475 +        }
  25.476 +      end
  25.477 +      ui.tag{
  25.478 +        attr = { class = "delegation_scope" .. (overridden and " delegation_scope_overridden" or "") },
  25.479 +        content = function()
  25.480 +          if record.scope_in == "unit" then
  25.481 +            slot.put(config.single_object_mode and _"Global delegation" or _"Unit delegation")
  25.482 +          elseif record.scope_in == "area" then
  25.483 +            slot.put(_"Area delegation")
  25.484 +          elseif record.scope_in == "issue" then
  25.485 +            slot.put(_"Issue delegation")
  25.486 +          end
  25.487 +        end
  25.488        }
  25.489      end
  25.490 -    ui.tag{
  25.491 -      attr = { class = "delegation_scope" .. (overridden and " delegation_scope_overridden" or "") },
  25.492 +    ui.container{
  25.493 +      attr = { class = overridden and "delegation_overridden" or "" },
  25.494        content = function()
  25.495 -        if record.scope_in == "unit" then
  25.496 -          slot.put(config.single_object_mode and _"Global delegation" or _"Unit delegation")
  25.497 -        elseif record.scope_in == "area" then
  25.498 -          slot.put(_"Area delegation")
  25.499 -        elseif record.scope_in == "issue" then
  25.500 -          slot.put(_"Issue delegation")
  25.501 -        end
  25.502 +        execute.view{
  25.503 +          module = "member",
  25.504 +          view = "_show_thumb",
  25.505 +          params = { member = record }
  25.506 +        }
  25.507        end
  25.508      }
  25.509 -  end
  25.510 -  ui.container{
  25.511 -    attr = { class = overridden and "delegation_overridden" or "" },
  25.512 -    content = function()
  25.513 -      execute.view{
  25.514 -        module = "member",
  25.515 -        view = "_show_thumb",
  25.516 -        params = { member = record }
  25.517 +    if issue and issue.state ~= 'voting' and record.participation and not record.overridden then
  25.518 +      ui.container{
  25.519 +        attr = { class = "delegation_participation" },
  25.520 +        content = function()
  25.521 +          if i == #delegation_chain then
  25.522 +          ui.tag{ content = _"This member is currently participating in this issue." }
  25.523 +          else
  25.524 +          ui.tag{ content = _"This member is participating, the remaining delegation chain is suspended during discussing." }
  25.525 +          end
  25.526 +        end
  25.527        }
  25.528      end
  25.529 -  }
  25.530 -  if (not issue or issue.state ~= 'voting') and record.participation and not record.overridden then
  25.531 -    ui.container{
  25.532 -      attr = { class = "delegation_participation" },
  25.533 -      content = function()
  25.534 -        slot.put(_"This member is participating, the rest of delegation chain is suspended while discussing")
  25.535 -      end
  25.536 -    }
  25.537 -  end
  25.538 -  slot.put("<br style='clear: left'/>")
  25.539 +    slot.put("<br style='clear: left'/>")
  25.540 +  end )
  25.541  end
  25.542  
  25.543  if preview_trustee_id == 0 or not preview_trustee_id == null and delegation and not delegation.trustee_id then
  25.544 @@ -350,3 +397,5 @@
  25.545    end
  25.546  end
  25.547  
  25.548 +
  25.549 +end )
  25.550 \ No newline at end of file
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/app/main/delegation/show_incoming.lua	Thu Jul 10 01:19:48 2014 +0200
    26.3 @@ -0,0 +1,35 @@
    26.4 +local issue = Issue:by_id(param.get("issue_id", atom.integer))
    26.5 +
    26.6 +local member = Member:by_id(param.get("member_id", atom.integer))
    26.7 +
    26.8 +local members_selector = Member:new_selector()
    26.9 +  :join("delegating_interest_snapshot", nil, "delegating_interest_snapshot.member_id = member.id")
   26.10 +  :join("issue", nil, "issue.id = delegating_interest_snapshot.issue_id")
   26.11 +  :add_where{ "delegating_interest_snapshot.issue_id = ?", issue.id }
   26.12 +  :add_where{ "delegating_interest_snapshot.event = ?", issue.latest_snapshot_event }
   26.13 +  :add_where{ "delegating_interest_snapshot.delegate_member_ids[1] = ?", member.id }
   26.14 +  :add_field{ "delegating_interest_snapshot.weight" }
   26.15 +
   26.16 +  
   26.17 +execute.view {
   26.18 +  module = "issue", view = "_head", params = {
   26.19 +    issue = issue
   26.20 +  }
   26.21 +}
   26.22 +
   26.23 +ui.section( function()
   26.24 +
   26.25 +  ui.sectionHead( function()
   26.26 +    ui.heading{ level = 1, content = _("Incoming delegations for '#{member_name}'", { member_name = member.name } ) }
   26.27 +  end)
   26.28 +
   26.29 +  execute.view{
   26.30 +    module = "member",
   26.31 +    view = "_list",
   26.32 +    params = { 
   26.33 +      members_selector = members_selector,
   26.34 +      issue = issue,
   26.35 +      trustee = member
   26.36 +    }
   26.37 +  }
   26.38 +end )
   26.39 \ No newline at end of file
    27.1 --- a/app/main/draft/_action/add.lua	Thu Jul 10 01:02:43 2014 +0200
    27.2 +++ b/app/main/draft/_action/add.lua	Thu Jul 10 01:19:48 2014 +0200
    27.3 @@ -25,19 +25,24 @@
    27.4    return false
    27.5  end
    27.6  
    27.7 -local formatting_engine = param.get("formatting_engine")
    27.8 +local formatting_engine
    27.9 +if config.enforce_formatting_engine then
   27.10 +  formatting_engine = config.enforce_formatting_engine 
   27.11 +else
   27.12 +  formatting_engine = param.get("formatting_engine")
   27.13  
   27.14 -local formatting_engine_valid = false
   27.15 -for fe, dummy in pairs(config.formatting_engine_executeables) do
   27.16 -  if formatting_engine == fe then
   27.17 -    formatting_engine_valid = true
   27.18 +  local formatting_engine_valid = false
   27.19 +  for i, fe in pairs(config.formatting_engines) do
   27.20 +    if formatting_engine == fe.id then
   27.21 +      formatting_engine_valid = true
   27.22 +    end
   27.23 +  end
   27.24 +  if not formatting_engine_valid then
   27.25 +    error("invalid formatting engine!")
   27.26    end
   27.27  end
   27.28 -if not formatting_engine_valid then
   27.29 -  error("invalid formatting engine!")
   27.30 -end
   27.31  
   27.32 -if param.get("preview") then
   27.33 +if param.get("preview") or param.get("edit") then
   27.34    return false
   27.35  end
   27.36  
   27.37 @@ -57,5 +62,5 @@
   27.38  
   27.39  draft:render_content()
   27.40  
   27.41 -slot.put_into("notice", _"New draft has been added to initiative")
   27.42 +slot.put_into("notice", _"The initiative text has been updated")
   27.43  
    28.1 --- a/app/main/draft/diff.lua	Thu Jul 10 01:02:43 2014 +0200
    28.2 +++ b/app/main/draft/diff.lua	Thu Jul 10 01:19:48 2014 +0200
    28.3 @@ -1,13 +1,20 @@
    28.4  local old_draft_id = param.get("old_draft_id", atom.integer)
    28.5  local new_draft_id = param.get("new_draft_id", atom.integer)
    28.6 +local initiative_id = param.get("initiative_id", atom.number)
    28.7  
    28.8 -if not old_draft_id or not new_draft_id then
    28.9 -  slot.put( _"Please choose two versions of the draft to compare")
   28.10 -  return
   28.11 -end
   28.12 -
   28.13 -if old_draft_id == new_draft_id then
   28.14 -  slot.put( _"Please choose two different versions of the draft to compare")
   28.15 +if not old_draft_id 
   28.16 +  or not new_draft_id 
   28.17 +  or old_draft_id == new_draft_id
   28.18 +then
   28.19 +  slot.reset_all()
   28.20 +  slot.select("error", function()
   28.21 +    ui.tag{ content = _"Please choose two different versions of the draft to compare" }
   28.22 +  end )
   28.23 +  request.redirect{
   28.24 +    module = "draft", view = "list", params = {
   28.25 +      initiative_id = initiative_id
   28.26 +    }
   28.27 +  }
   28.28    return
   28.29  end
   28.30  
   28.31 @@ -20,40 +27,46 @@
   28.32  local old_draft = Draft:by_id(old_draft_id)
   28.33  local new_draft = Draft:by_id(new_draft_id)
   28.34  
   28.35 -execute.view{
   28.36 -  module = "draft",
   28.37 -  view = "_head",
   28.38 -  params = { draft = new_draft}
   28.39 +local initiative = new_draft.initiative
   28.40 +
   28.41 +if app.session.member then
   28.42 +  initiative:load_everything_for_member_id(app.session.member_id)
   28.43 +  initiative.issue:load_everything_for_member_id(app.session.member_id)
   28.44 +end
   28.45 +
   28.46 +
   28.47 +execute.view{ module = "issue", view = "_sidebar_state", params = {
   28.48 +  initiative = initiative
   28.49 +} }
   28.50 +
   28.51 +execute.view { 
   28.52 +  module = "issue", view = "_sidebar_issue", 
   28.53 +  params = {
   28.54 +    issue = initiative.issue,
   28.55 +    highlight_initiative_id = initiative.id
   28.56 +  }
   28.57  }
   28.58  
   28.59 -ui.title(_"Diff")
   28.60 +execute.view {
   28.61 +  module = "issue", view = "_sidebar_whatcanido",
   28.62 +  params = { initiative = initiative }
   28.63 +}
   28.64  
   28.65 -if app.session.member_id and not new_draft.initiative.revoked then
   28.66 -  local supporter = Supporter:new_selector():add_where{"member_id = ?", app.session.member_id}:count()
   28.67 -  if supporter then
   28.68 -    ui.container{
   28.69 -      attr = { class = "draft_updated_info" },
   28.70 -      content = function()
   28.71 -        slot.put(_"The draft of this initiative has been updated!")
   28.72 -        slot.put(" ")
   28.73 -        ui.link{
   28.74 -          text   = _"Refresh support to current draft",
   28.75 -          module = "initiative",
   28.76 -          action = "add_support",
   28.77 -          id     = new_draft.initiative.id,
   28.78 -          routing = {
   28.79 -            default = {
   28.80 -              mode = "redirect",
   28.81 -              module = "initiative",
   28.82 -              view = "show",
   28.83 -              id = new_draft.initiative.id
   28.84 -            }
   28.85 -          }
   28.86 -        }
   28.87 -      end
   28.88 -    }
   28.89 -  end
   28.90 -end
   28.91 +execute.view { 
   28.92 +  module = "issue", view = "_sidebar_members", params = {
   28.93 +    issue = initiative.issue, initiative = initiative
   28.94 +  }
   28.95 +}
   28.96 +
   28.97 +
   28.98 +
   28.99 +execute.view {
  28.100 +  module = "issue", view = "_head", params = {
  28.101 +    issue = initiative.issue
  28.102 +  }
  28.103 +}
  28.104 +
  28.105 +
  28.106  
  28.107  local old_draft_content = string.gsub(string.gsub(old_draft.content, "\n", " ###ENTER###\n"), " ", "\n")
  28.108  local new_draft_content = string.gsub(string.gsub(new_draft.content, "\n", " ###ENTER###\n"), " ", "\n")
  28.109 @@ -111,17 +124,87 @@
  28.110    end
  28.111  end
  28.112  
  28.113 -if not status then
  28.114 -  ui.field.text{ value = _"The drafts do not differ" }
  28.115 -else
  28.116 -  ui.container{
  28.117 -    tag = "div",
  28.118 -    attr = { class = "diff" },
  28.119 -    content = function()
  28.120 -      output = output:gsub("[^\n\r]+", function(line)
  28.121 -        process_line(line)
  28.122 -      end)
  28.123 +ui.section( function()
  28.124 +  ui.sectionHead( function()
  28.125 +    ui.link{
  28.126 +      module = "initiative", view = "show", id = initiative.id,
  28.127 +      content = function ()
  28.128 +        ui.heading { 
  28.129 +          level = 1,
  28.130 +          content = initiative.display_name
  28.131 +        }
  28.132 +      end
  28.133 +    }
  28.134 +    ui.heading{ level = 2, content = _("Comparision of revisions #{id1} and #{id2}", {
  28.135 +      id1 = old_draft.id,
  28.136 +      id2 = new_draft.id 
  28.137 +    } ) }
  28.138 +  end )
  28.139 +
  28.140 +  if app.session.member_id and not new_draft.initiative.revoked then
  28.141 +    local supporter = app.session.member:get_reference_selector("supporters")
  28.142 +      :add_where{ "initiative_id = ?", new_draft.initiative_id }
  28.143 +      :optional_object_mode()
  28.144 +      :exec()
  28.145 +    if supporter and supporter.draft_id ~= new_draft.id then
  28.146 +      ui.sectionRow("draft_updated_info", function()
  28.147 +        ui.container{ 
  28.148 +          attr = { class = "info" },
  28.149 +          content = _"The draft of this initiative has been updated!"
  28.150 +        }
  28.151 +        slot.put(" ")
  28.152 +        ui.link{
  28.153 +          text   = _"refresh my support",
  28.154 +          module = "initiative",
  28.155 +          action = "add_support",
  28.156 +          id     = new_draft.initiative.id,
  28.157 +          params = { draft_id = new_draft.id },
  28.158 +          routing = {
  28.159 +            default = {
  28.160 +              mode = "redirect",
  28.161 +              module = "initiative",
  28.162 +              view = "show",
  28.163 +              id = new_draft.initiative.id
  28.164 +            }
  28.165 +          }
  28.166 +        }
  28.167 +
  28.168 +        slot.put(" &middot; ")
  28.169 +         
  28.170 +        ui.link{
  28.171 +          text   = _"remove my support",
  28.172 +          module = "initiative",
  28.173 +          action = "remove_support",
  28.174 +          id     = new_draft.initiative.id,
  28.175 +          routing = {
  28.176 +            default = {
  28.177 +              mode = "redirect",
  28.178 +              module = "initiative",
  28.179 +              view = "show",
  28.180 +              id = new_draft.initiative.id
  28.181 +            }
  28.182 +          }
  28.183 +        }        
  28.184 +        
  28.185 +      end )
  28.186      end
  28.187 -  }
  28.188 -end 
  28.189 +  end
  28.190 +
  28.191 +  ui.sectionRow( function()
  28.192  
  28.193 +    if not status then
  28.194 +      ui.field.text{ value = _"The drafts do not differ" }
  28.195 +    else
  28.196 +      ui.container{
  28.197 +        tag = "div",
  28.198 +        attr = { class = "diff" },
  28.199 +        content = function()
  28.200 +          output = output:gsub("[^\n\r]+", function(line)
  28.201 +            process_line(line)
  28.202 +          end)
  28.203 +        end
  28.204 +      }
  28.205 +    end 
  28.206 +
  28.207 +  end )
  28.208 +end )
  28.209 \ No newline at end of file
    29.1 --- a/app/main/draft/list.lua	Thu Jul 10 01:02:43 2014 +0200
    29.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.3 @@ -1,61 +0,0 @@
    29.4 -local initiative = Initiative:by_id(param.get("initiative_id", atom.number))
    29.5 -
    29.6 -execute.view{
    29.7 -  module = "initiative", view = "_show", params = {
    29.8 -    initiative = initiative, show_as_head = true
    29.9 -  }
   29.10 -}
   29.11 -
   29.12 -ui.link{
   29.13 -  text = _"Back to initiative",
   29.14 -  module = "initiative", view = "show", id = initiative.id
   29.15 -}
   29.16 -
   29.17 -slot.put("<br />")
   29.18 -slot.put("<br />")
   29.19 -
   29.20 -ui.form{
   29.21 -  method = "get",
   29.22 -  module = "draft",
   29.23 -  view = "diff",
   29.24 -  content = function()
   29.25 -    ui.list{
   29.26 -      records = initiative.drafts,
   29.27 -      columns = {
   29.28 -        {
   29.29 -          label = _"Created at",
   29.30 -          content = function(record)
   29.31 -            ui.field.text{ readonly = true, value = format.timestamp(record.created) }
   29.32 -          end
   29.33 -        },
   29.34 -        {
   29.35 -          label = _"Author",
   29.36 -          content = function(record)
   29.37 -            if record.author then
   29.38 -              return record.author:ui_field_text()
   29.39 -            end
   29.40 -          end
   29.41 -        },
   29.42 -        {
   29.43 -          content = function(record)
   29.44 -            ui.link{
   29.45 -              attr = { class = "action" },
   29.46 -              text = _"Show",
   29.47 -              module = "draft",
   29.48 -              view = "show",
   29.49 -              id = record.id
   29.50 -            }
   29.51 -          end
   29.52 -        },
   29.53 -        {
   29.54 -          label = _"Compare",
   29.55 -          content = function(record)
   29.56 -            slot.put('<input type="radio" name="old_draft_id" value="' .. tostring(record.id) .. '">')
   29.57 -            slot.put('<input type="radio" name="new_draft_id" value="' .. tostring(record.id) .. '">')
   29.58 -          end
   29.59 -        }
   29.60 -      }
   29.61 -    }
   29.62 -    ui.submit{ text = _"Compare" }
   29.63 -  end
   29.64 -}
    30.1 --- a/app/main/draft/new.lua	Thu Jul 10 01:02:43 2014 +0200
    30.2 +++ b/app/main/draft/new.lua	Thu Jul 10 01:19:48 2014 +0200
    30.3 @@ -1,24 +1,27 @@
    30.4 -slot.put_into("title", _"Edit draft")
    30.5 +local initiative = Initiative:by_id(param.get("initiative_id"))
    30.6 +initiative:load_everything_for_member_id(app.session.member_id)
    30.7 +initiative.issue:load_everything_for_member_id(app.session.member_id)
    30.8  
    30.9 -local initiative = Initiative:by_id(param.get("initiative_id"))
   30.10  
   30.11 -ui.actions(function()
   30.12 -  ui.link{
   30.13 -    content = function()
   30.14 -        ui.image{ static = "icons/16/cancel.png" }
   30.15 -        slot.put(_"Cancel")
   30.16 -    end,
   30.17 -    module = "initiative",
   30.18 -    view = "show",
   30.19 -    id = initiative.id
   30.20 +execute.view{
   30.21 +  module = "issue", view = "_head", params = {
   30.22 +    issue = initiative.issue,
   30.23 +    initiative = initiative
   30.24    }
   30.25 -end)
   30.26 +}
   30.27 +
   30.28 +execute.view { 
   30.29 +  module = "issue", view = "_sidebar_issue", 
   30.30 +  params = {
   30.31 +    issue = initiative.issue,
   30.32 +  }
   30.33 +}
   30.34  
   30.35  
   30.36  
   30.37  ui.form{
   30.38    record = initiative.current_draft,
   30.39 -  attr = { class = "vertical" },
   30.40 +  attr = { class = "vertical section" },
   30.41    module = "draft",
   30.42    action = "add",
   30.43    params = { initiative_id = initiative.id },
   30.44 @@ -31,78 +34,103 @@
   30.45      }
   30.46    },
   30.47    content = function()
   30.48 -
   30.49 -    ui.field.text{ label = _"Unit", value = initiative.issue.area.unit.name, readonly = true }
   30.50 -    ui.field.text{ label = _"Area", value = initiative.issue.area.name, readonly = true }
   30.51 -    ui.field.text{ label = _"Policy", value = initiative.issue.policy.name, readonly = true }
   30.52 -    ui.field.text{ label = _"Issue", value = _("Issue ##{id}", { id = initiative.issue.id } ), readonly = true }
   30.53 -    slot.put("<br />")
   30.54 -    ui.field.text{ label = _"Initiative", value = initiative.name, readonly = true }
   30.55 -
   30.56 +  
   30.57 +    ui.sectionHead( function()
   30.58 +      ui.heading { level = 1, content = initiative.display_name }
   30.59 +    end)
   30.60 +    
   30.61      if param.get("preview") then
   30.62 -      ui.container{
   30.63 -        attr = { class = "draft_content wiki" },
   30.64 -        content = function()
   30.65 -          slot.put(format.wiki_text(param.get("content"), param.get("formatting_engine")))
   30.66 +      ui.sectionRow( function()
   30.67 +        ui.field.hidden{ name = "formatting_engine", value = param.get("formatting_engine") }
   30.68 +        ui.field.hidden{ name = "content", value = param.get("content") }
   30.69 +        if config.enforce_formatting_engine then
   30.70 +          formatting_engine = config.enforce_formatting_engine
   30.71 +        else
   30.72 +          formatting_engine = param.get("formatting_engine")
   30.73          end
   30.74 -      }
   30.75 -      slot.put("<br />")
   30.76 -      ui.submit{ text = _"Save" }
   30.77 -      slot.put("<br />")
   30.78 -      slot.put("<br />")
   30.79 -    end
   30.80 -    slot.put("<br />")
   30.81 +        ui.container{
   30.82 +          attr = { class = "draft" },
   30.83 +          content = function()
   30.84 +            slot.put(format.wiki_text(param.get("content"), formatting_engine))
   30.85 +          end
   30.86 +        }
   30.87  
   30.88 +        slot.put("<br />")
   30.89 +        ui.tag{
   30.90 +          tag = "input",
   30.91 +          attr = {
   30.92 +            type = "submit",
   30.93 +            class = "btn btn-default",
   30.94 +            value = _'Publish now'
   30.95 +          },
   30.96 +          content = ""
   30.97 +        }
   30.98 +        slot.put("<br />")
   30.99 +        slot.put("<br />")
  30.100  
  30.101 -    ui.field.select{
  30.102 -      label = _"Wiki engine",
  30.103 -      name = "formatting_engine",
  30.104 -      foreign_records = {
  30.105 -        { id = "rocketwiki", name = "RocketWiki" },
  30.106 -        { id = "compat", name = _"Traditional wiki syntax" }
  30.107 -      },
  30.108 -      attr = {id = "formatting_engine"},
  30.109 -      foreign_id = "id",
  30.110 -      foreign_name = "name"
  30.111 -    }
  30.112 -    ui.tag{
  30.113 -      tag = "div",
  30.114 -      content = function()
  30.115          ui.tag{
  30.116 -          tag = "label",
  30.117 -          attr = { class = "ui_field_label" },
  30.118 -          content = function() slot.put("&nbsp;") end,
  30.119 +          tag = "input",
  30.120 +          attr = {
  30.121 +            type = "submit",
  30.122 +            name = "edit",
  30.123 +            class = "btn-link",
  30.124 +            value = _'Edit again'
  30.125 +          },
  30.126 +          content = ""
  30.127 +        }
  30.128 +        slot.put(" | ")
  30.129 +        ui.link{
  30.130 +          content = _"Cancel",
  30.131 +          module = "initiative",
  30.132 +          view = "show",
  30.133 +          id = initiative.id
  30.134 +        }
  30.135 +      end )
  30.136 +
  30.137 +    else
  30.138 +      ui.sectionRow( function()
  30.139 +        execute.view{ module = "initiative", view = "_sidebar_wikisyntax" }
  30.140 +      
  30.141 +        if not config.enforce_formatting_engine then
  30.142 +          ui.field.select{
  30.143 +            label = _"Wiki engine",
  30.144 +            name = "formatting_engine",
  30.145 +            foreign_records = config.formatting_engines,
  30.146 +            attr = {id = "formatting_engine"},
  30.147 +            foreign_id = "id",
  30.148 +            foreign_name = "name"
  30.149 +          }
  30.150 +        end
  30.151 +
  30.152 +        ui.heading{ level = 2, content = _"Enter your proposal and/or reasons" }
  30.153 +
  30.154 +        ui.field.text{
  30.155 +          name = "content",
  30.156 +          multiline = true,
  30.157 +          attr = { style = "height: 50ex; width: 100%;" },
  30.158 +          value = param.get("content")
  30.159          }
  30.160          ui.tag{
  30.161 -          content = function()
  30.162 -            ui.link{
  30.163 -              text = _"Syntax help",
  30.164 -              module = "help",
  30.165 -              view = "show",
  30.166 -              id = "wikisyntax",
  30.167 -              attr = {onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"}
  30.168 -            }
  30.169 -            slot.put(" ")
  30.170 -            ui.link{
  30.171 -              text = _"(new window)",
  30.172 -              module = "help",
  30.173 -              view = "show",
  30.174 -              id = "wikisyntax",
  30.175 -              attr = {target = "_blank", onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"}
  30.176 -            }
  30.177 -          end
  30.178 +          tag = "input",
  30.179 +          attr = {
  30.180 +            type = "submit",
  30.181 +            name = "preview",
  30.182 +            class = "btn btn-default",
  30.183 +            value = _'Preview'
  30.184 +          },
  30.185 +          content = ""
  30.186          }
  30.187 -      end
  30.188 -    }
  30.189 -    ui.field.text{
  30.190 -      label = _"Content",
  30.191 -      name = "content",
  30.192 -      multiline = true,
  30.193 -      attr = { style = "height: 50ex;" },
  30.194 -      value = param.get("content")
  30.195 -   }
  30.196 -
  30.197 -    ui.submit{ name = "preview", text = _"Preview" }
  30.198 -    ui.submit{ text = _"Save" }
  30.199 +        slot.put("<br />")
  30.200 +        slot.put("<br />")
  30.201 +        
  30.202 +        ui.link{
  30.203 +          content = _"Cancel",
  30.204 +          module = "initiative",
  30.205 +          view = "show",
  30.206 +          id = initiative.id
  30.207 +        }
  30.208 +        
  30.209 +      end )
  30.210 +    end
  30.211    end
  30.212  }
    31.1 --- a/app/main/draft/show.lua	Thu Jul 10 01:02:43 2014 +0200
    31.2 +++ b/app/main/draft/show.lua	Thu Jul 10 01:19:48 2014 +0200
    31.3 @@ -2,39 +2,51 @@
    31.4  local source = param.get("source", atom.boolean)
    31.5  
    31.6  execute.view{
    31.7 -  module = "draft",
    31.8 +  module = "issue",
    31.9    view = "_head",
   31.10 -  params = { draft = draft}
   31.11 +  params = { issue = draft.initiative.issue }
   31.12  }
   31.13  
   31.14 -slot.put_into("title", " &middot; " .. _"History")
   31.15 -
   31.16 -if source then
   31.17 -  ui.actions(function()
   31.18 -    ui.link{
   31.19 -      content = _"Rendered",
   31.20 -      module = "draft",
   31.21 -      view = "show",
   31.22 -      id = param.get_id(),
   31.23 -      params = { source = false }
   31.24 -    }
   31.25 -    end
   31.26 -  )
   31.27 -else
   31.28 -  ui.actions(function()
   31.29 +ui.section( function()
   31.30 +  
   31.31 +  ui.sectionHead( function()
   31.32      ui.link{
   31.33 -      content = _"Source",
   31.34 -      module = "draft",
   31.35 -      view = "show",
   31.36 -      id = param.get_id(),
   31.37 -      params = { source = true }
   31.38 +      module = "initiative", view = "show", id = draft.initiative.id,
   31.39 +      content = function ()
   31.40 +        ui.heading { 
   31.41 +          level = 1,
   31.42 +          content = draft.initiative.display_name
   31.43 +        }
   31.44 +      end
   31.45      }
   31.46 -    end
   31.47 -  )
   31.48 -end
   31.49 -
   31.50 -execute.view{
   31.51 -  module = "draft",
   31.52 -  view = "_show",
   31.53 -  params = { draft = draft, source = source }
   31.54 -}
   31.55 +    ui.container { attr = { class = "right" }, content = function()
   31.56 +      if source then
   31.57 +        ui.link{
   31.58 +          content = _"Rendered",
   31.59 +          module = "draft",
   31.60 +          view = "show",
   31.61 +          id = param.get_id(),
   31.62 +          params = { source = false }
   31.63 +        }
   31.64 +      else
   31.65 +        ui.link{
   31.66 +          content = _"Source",
   31.67 +          module = "draft",
   31.68 +          view = "show",
   31.69 +          id = param.get_id(),
   31.70 +          params = { source = true }
   31.71 +        }
   31.72 +      end
   31.73 +    end }
   31.74 +    ui.heading { level = 2, content = _("Draft revision #{id}", { id = draft.id } ) }
   31.75 +  end)
   31.76 +  
   31.77 +  ui.sectionRow( function()
   31.78 +  
   31.79 +    execute.view{
   31.80 +      module = "draft",
   31.81 +      view = "_show",
   31.82 +      params = { draft = draft, source = source }
   31.83 +    }
   31.84 +  end)
   31.85 +end)
    32.1 --- a/app/main/event/_list.lua	Thu Jul 10 01:02:43 2014 +0200
    32.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.3 @@ -1,227 +0,0 @@
    32.4 ---local global = param.get("global", atom.boolean)
    32.5 -local for_member = param.get("for_member", "table")
    32.6 -local for_unit = param.get("for_unit", "table")
    32.7 -local for_area = param.get("for_area", "table")
    32.8 -local event_max_id = param.get_all_cgi()["event_max_id"]
    32.9 -local event_selector = Event:new_selector()
   32.10 -  :add_order_by("event.id DESC")
   32.11 -  :limit(25)
   32.12 -  :join("issue", nil, "issue.id = event.issue_id")
   32.13 -  :add_field("now()::date - event.occurrence::date", "time_ago")
   32.14 -  
   32.15 -if event_max_id then
   32.16 -  event_selector:add_where{ "event.id < ?", event_max_id }
   32.17 -end
   32.18 -  
   32.19 -if for_member then
   32.20 -  event_selector:add_where{ "event.member_id = ?", for_member.id }
   32.21 -elseif for_unit then
   32.22 -  event_selector:join("area", nil, "area.id = issue.area_id")
   32.23 -  event_selector:add_where{ "area.unit_id = ?", for_unit.id }
   32.24 -elseif for_area then
   32.25 -  event_selector:add_where{ "issue.area_id = ?", for_area.id }
   32.26 ---elseif not global then
   32.27 ---  event_selector:join("event_seen_by_member", nil, { "event_seen_by_member.id = event.id AND event_seen_by_member.seen_by_member_id = ?", app.session.member_id })
   32.28 -end
   32.29 -  
   32.30 -if app.session.member_id then
   32.31 -  event_selector
   32.32 -    :left_join("interest", "_interest", { "_interest.issue_id = issue.id AND _interest.member_id = ?", app.session.member.id } )
   32.33 -    :add_field("(_interest.member_id NOTNULL)", "is_interested")
   32.34 -    :left_join("delegating_interest_snapshot", "_delegating_interest", { "_delegating_interest.issue_id = issue.id AND _delegating_interest.member_id = ? AND _delegating_interest.event = issue.latest_snapshot_event", app.session.member.id } )
   32.35 -    :add_field("_delegating_interest.delegate_member_ids[1]", "is_interested_by_delegation_to_member_id")
   32.36 -    :add_field("_delegating_interest.delegate_member_ids[array_upper(_delegating_interest.delegate_member_ids, 1)]", "is_interested_via_member_id")
   32.37 -    :add_field("array_length(_delegating_interest.delegate_member_ids, 1)", "delegation_chain_length")
   32.38 -end
   32.39 -
   32.40 -local filters = execute.load_chunk{module="issue", chunk="_filters.lua", params = {
   32.41 -  for_events = true,
   32.42 -  member = app.session.member, for_member = for_member, state = for_state, for_unit = for_unit and true or false, for_area = for_area and true or false
   32.43 -}}
   32.44 -
   32.45 -filters.opened = true
   32.46 -filters.selector = event_selector
   32.47 -
   32.48 -filters.content = function()
   32.49 -
   32.50 -
   32.51 -  local last_event_id
   32.52 -
   32.53 -  local events = event_selector:exec()
   32.54 -
   32.55 -  local issues = events:load("issue")
   32.56 -  issues:load_everything_for_member_id(app.session.member_id)
   32.57 -
   32.58 -  events:load("initiative")
   32.59 -  events:load("suggestion")
   32.60 -  events:load("member")
   32.61 -
   32.62 -
   32.63 -  ui.container{ attr = { class = "issues events" }, content = function()
   32.64 -
   32.65 -    local last_event_date
   32.66 -    for i, event in ipairs(events) do
   32.67 -      last_event_id = event.id
   32.68 -
   32.69 -      ui.container{ attr = { class = "event_info" }, content = function()
   32.70 -        local event_name = event.event_name
   32.71 -        local event_image
   32.72 -        if event.event == "issue_state_changed" then
   32.73 -          if event.state == "discussion" then
   32.74 -            event_name = _"Discussion started"
   32.75 -            event_image = "comments.png"
   32.76 -          elseif event.state == "verification" then
   32.77 -            event_name = _"Verification started"
   32.78 -            event_image = "lock.png"
   32.79 -          elseif event.state == "voting" then
   32.80 -            event_name = _"Voting started"
   32.81 -            event_image = "email_open.png"
   32.82 -          elseif event.state == "finished_with_winner" then
   32.83 -            event_name = event.state_name
   32.84 -            event_image = "award_star_gold_2.png"
   32.85 -          elseif event.state == "finished_without_winner" then
   32.86 -            event_name = event.state_name
   32.87 -            event_image = "cross.png"
   32.88 -          else
   32.89 -            event_name = event.state_name
   32.90 -          end
   32.91 -          if event_image then
   32.92 -            ui.image{ static = "icons/16/" .. event_image }
   32.93 -            slot.put(" ")
   32.94 -          end
   32.95 -        end
   32.96 -        local days_ago_text
   32.97 -        if event.time_ago == 0 then
   32.98 -          days_ago_text = _("Today at #{time}", { time = format.time(event.occurrence) })
   32.99 -        elseif event.time_ago == 1 then
  32.100 -          days_ago_text = _("Yesterday at #{time}", { time = format.time(event.occurrence) })
  32.101 -        else
  32.102 -          days_ago_text = _("#{date} at #{time}", { date = format.date(event.occurrence.date), time = format.time(event.occurrence, { hide_seconds = true }) })
  32.103 -        end
  32.104 -        ui.tag{ attr = { class = "event_name" }, content = event_name }
  32.105 -        slot.put("<br />") 
  32.106 -        ui.tag{ content = days_ago_text }
  32.107 -  --[[      if event.time_ago > 1 then
  32.108 -          slot.put("<br />(")
  32.109 -          ui.tag{ content = _("#{count} days ago", { count = event.time_ago }) }
  32.110 -          slot.put(")")
  32.111 -        end
  32.112 -        --]]
  32.113 -        if app.session:has_access("authors_pseudonymous") and event.member_id then
  32.114 -          slot.put("<br />") 
  32.115 -          slot.put("<br />") 
  32.116 -          if app.session.member_id then
  32.117 -            ui.link{
  32.118 -              content = function()
  32.119 -                execute.view{
  32.120 -                  module = "member_image",
  32.121 -                  view = "_show",
  32.122 -                  params = {
  32.123 -                    member = event.member,
  32.124 -                    image_type = "avatar",
  32.125 -                    show_dummy = true,
  32.126 -                    class = "micro_avatar",
  32.127 -                    popup_text = text
  32.128 -                  }
  32.129 -                }
  32.130 -              end,
  32.131 -              module = "member", view = "show", id = event.member_id
  32.132 -            }
  32.133 -            slot.put(" ")
  32.134 -          end
  32.135 -          ui.link{
  32.136 -            text = event.member.name,
  32.137 -            module = "member", view = "show", id = event.member_id
  32.138 -          }
  32.139 -        end
  32.140 -      end }
  32.141 -
  32.142 -      ui.container{ attr = { class = "issue" }, content = function()
  32.143 -
  32.144 -        execute.view{ module = "delegation", view = "_info", params = { issue = event.issue, member = for_member } }
  32.145 -
  32.146 -        ui.container{ attr = { class = "content" }, content = function()
  32.147 -          ui.link{
  32.148 -            module = "unit", view = "show", id = event.issue.area.unit_id,
  32.149 -            attr = { class = "unit_link" }, text = event.issue.area.unit.name
  32.150 -          }
  32.151 -          slot.put(" ")
  32.152 -          ui.link{
  32.153 -            module = "area", view = "show", id = event.issue.area_id,
  32.154 -            attr = { class = "area_link" }, text = event.issue.area.name
  32.155 -          }
  32.156 -        end }
  32.157 -        
  32.158 -        ui.container{ attr = { class = "title" }, content = function()
  32.159 -          ui.link{
  32.160 -            attr = { class = "issue_id" },
  32.161 -            text = _("#{policy} ##{id}", { policy = event.issue.policy.name, id = event.issue_id }),
  32.162 -            module = "issue",
  32.163 -            view = "show",
  32.164 -            id = event.issue_id
  32.165 -          }
  32.166 -        end }
  32.167 -
  32.168 -        ui.container{ attr = { class = "initiative_list" }, content = function()
  32.169 -          if not event.initiative_id then
  32.170 -            local initiatives_selector = Initiative:new_selector()
  32.171 -              :add_where{ "initiative.issue_id = ?", event.issue_id }
  32.172 -              :add_order_by("initiative.admitted DESC NULLS LAST, initiative.rank NULLS LAST, initiative.harmonic_weight DESC NULLS LAST, id")
  32.173 -            execute.view{ module = "initiative", view = "_list", params = { 
  32.174 -              issue = event.issue,
  32.175 -              initiatives_selector = initiatives_selector,
  32.176 -              no_sort = true,
  32.177 -              limit = 5,
  32.178 -              for_member = for_member
  32.179 -            } }
  32.180 -          else
  32.181 -            local initiatives_selector = Initiative:new_selector()
  32.182 -              :add_where{ "initiative.id = ?", event.initiative_id }
  32.183 -            execute.view{ module = "initiative", view = "_list", params = { 
  32.184 -              initiatives_selector = initiatives_selector,
  32.185 -              no_sort = true,
  32.186 -              hide_more_initiatives = true,
  32.187 -              for_member = for_member
  32.188 -            } }
  32.189 -          end
  32.190 -        end }
  32.191 -
  32.192 -        ui.container{ attr = { class = "content suggestion" }, content = function()
  32.193 -          if event.suggestion_id then
  32.194 -            ui.link{
  32.195 -              text = event.suggestion.name,
  32.196 -              module = "suggestion", view = "show", id = event.suggestion_id
  32.197 -            }
  32.198 -          end
  32.199 -        end }
  32.200 -      end }
  32.201 -    end
  32.202 -
  32.203 -  end }
  32.204 -
  32.205 -  slot.put("<br />")
  32.206 -
  32.207 -  if #events > 0 then
  32.208 -    ui.link{
  32.209 -      attr = { class = "more_events_links" },
  32.210 -      text = _"Show older events",
  32.211 -      module = request.get_module(),
  32.212 -      view = request.get_view(),
  32.213 -      id = for_unit and for_unit.id or for_area and for_area.id,
  32.214 -      params = {
  32.215 -        tab = param.get_all_cgi()["tab"],
  32.216 -        events = param.get_all_cgi()["events"],
  32.217 -        event_max_id = last_event_id
  32.218 -      }
  32.219 -    }
  32.220 -  else
  32.221 -    ui.tag{ content = _"No more events available" }
  32.222 -  end
  32.223 -
  32.224 -  slot.put("<br />")
  32.225 -  slot.put("<br />")
  32.226 -
  32.227 -end
  32.228 -
  32.229 -
  32.230 -ui.filters(filters)
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/app/main/help/introduction.lua	Thu Jul 10 01:19:48 2014 +0200
    33.3 @@ -0,0 +1,132 @@
    33.4 +ui.title(_"Introduction")
    33.5 +
    33.6 +local lang = locale.get("lang")
    33.7 +
    33.8 +ui.section(function()
    33.9 +  ui.sectionHead(function()
   33.10 +    ui.heading{ level = 1, content = _"Structured discussion" }
   33.11 +  end)
   33.12 +  ui.sectionRow(function()
   33.13 +    ui.heading{ level = 2, content = _"Initiatives and issues" }
   33.14 +    if lang == "de" then
   33.15 +      ui.tag{ tag = "p", content = [[
   33.16 +        LiquidFeedback ist kein Umfragesystem, es werden keine bereits vorher feststehenden Fragen gestellt. Statt dessen kann jeder Teilnehmer neue Initiativen starten, die Vorschläge und/oder Argumente umfassen. Sobald eine Initiative eingestellt wurde, können alle Teilnehmer alternative Initiativen mit Gegenvorschlägen starten. Alle zueinander in Konkrurrenz stehenden Initiativen bilden zusammen ein Thema. Sowohl Themen als auch Initiativen werden nummeriert. Themen erhalten hierbei vor der Nummer ein #-Zeichen (z. B. #123), während Initiativen durch ein führendes i gekennzeichnet sind (z. B. i456). Ein Thema kann mehrere Initiativen enthalten. Nur eine Initiative kann gewinnen.
   33.17 +      ]] }
   33.18 +    else
   33.19 +      ui.tag{ tag = "p", content = [[
   33.20 +        LiquidFeedback is no survey, it doesn't ask you predefined questions. Instead every participant is allowed to post new initiatives containing a proposal and/or reasoning. As soon as the initiative is posted, all other participants can create alternative initiatives with counter proposals and/or reasoning. A group of concurring initiatives forms an issue. Issues in LiquidFeedback are numbered with a hash sign (e.g. #123) while initiatives are numbered with a leading "i" character (i456). In short: One issue may contain multiple initiatives. Only one initiative can win.
   33.21 +      ]] }
   33.22 +    end
   33.23 +      
   33.24 +    ui.heading{ level = 2, content = _"Subject areas" }
   33.25 +    if lang == "de" then
   33.26 +      ui.tag{ tag = "p", content = [[
   33.27 +        Themen werden immer einem Themenbereich zugeordnet. Dies dient der Strukturierung der Diskussion und des Entscheidungsprozesses.
   33.28 +      ]] }
   33.29 +    else
   33.30 +      ui.tag{ tag = "p", content = [[
   33.31 +        Issues are always assigned to a subject area in order to structure the discussion and decision process.
   33.32 +      ]] }
   33.33 +    end
   33.34 +    ui.heading{ level = 2, content = _"Organizational units" }
   33.35 +    if lang == "de" then
   33.36 +      ui.tag{ tag = "p", content = [[
   33.37 +        Gliederungen ermöglichen Diskussionen und Entscheidungen auch für Teilmengen der Benutzer (z. B. Gliederungen einer Organisation). In jeder Gliederung können eigene Themenbereiche zur Verfügung stehen.
   33.38 +      ]] }
   33.39 +    else
   33.40 +      ui.tag{ tag = "p", content = [[
   33.41 +        To allow discussions and decisions by sub groups of participants (e.g. by the members of a subdivision of an organization), participants can be assigned to different units. Every organizational unit can have its own subject areas.
   33.42 +      ]] }
   33.43 +    end
   33.44 +    ui.heading{ level = 2, content = _"Rules of procedure" }
   33.45 +    if lang == "de" then
   33.46 +      ui.tag{ tag = "p", content = [[
   33.47 +        Ein Regelwerk definiert Fristen, Quoren und erforderliche Mehrheiten. Initiatoren wählen bei Erstellung eines Themas ein geeignetes Verfahren, das dem verfolgten Zweck entspricht.
   33.48 +      ]] }
   33.49 +    else
   33.50 +      ui.tag{ tag = "p", content = [[
   33.51 +        A policy defines the timing, quorums and required majorities for an issue in LiquidFeedback. Initiators choose the fitting policy for their purpose when creating a new issue.
   33.52 +      ]] }
   33.53 +    end
   33.54 +  end )
   33.55 +end )
   33.56 +ui.section(function()
   33.57 +  ui.sectionHead(function()
   33.58 +    ui.heading{ level = 1, content = _"4 phases of a decision" }
   33.59 +  end)
   33.60 +  ui.sectionRow(function()
   33.61 +    ui.heading{ level = 2, content = _"(1) Admission phase" }
   33.62 +    if lang == "de" then
   33.63 +      ui.tag{ tag = "p", content = [[
   33.64 +        Nicht jedes neue Thema wird auf ein Mindestinteresse der Teilnehmer stoßen. Daher muss ein neues Thema von einer vorab festzulegenden Mindestanzahl Teilnehmer als diskussionswürdig betrachtet  werden, um für die Diskussionsphase zugelassen zu werden. Andernfalls wird das Thema am Ende der Zulassungsphase abgebrochen und nicht weiter behandelt.
   33.65 +      ]] }
   33.66 +    else
   33.67 +      ui.tag{ tag = "p", content = [[
   33.68 +        As every participant can open a new issue in LiquidFeedback, not all of them will be intersting for at least a minimum of the participants. Therefore new issues need to gain a given quorum of supporters to become accepted for further discussion. Issues which do not reach the necessary quorum will be closed at the end of the admission phase.
   33.69 +      ]] }
   33.70 +    end
   33.71 +    ui.heading{ level = 2, content = _"(2) Discussion phase" }
   33.72 +    if lang == "de" then
   33.73 +      ui.tag{ tag = "p", content = [[
   33.74 +        Während der Diskussionsphase arbeiten Initiativen auf die Verbesserung des Vorschlags und die Vervollkommnung der Argumentation hin, um die erforderliche Mehrheit zu erreichen und sich gegen eventuell vorhandene alternative Initiativen durchzusetzen.
   33.75 +      ]] }
   33.76 +    else
   33.77 +      ui.tag{ tag = "p", content = [[
   33.78 +        During the discussion phase all initiatives try to improve their proposals and reasoning to gain more supporters. The aim is to eventually reach the necessary majority and to beat alternative initiatives.
   33.79 +      ]] }
   33.80 +    end
   33.81 +    ui.heading{ level = 2, content = _"(3) Verification phase" }
   33.82 +    if lang == "de" then
   33.83 +      ui.tag{ tag = "p", content = [[
   33.84 +        Alle in dieser Phase angezeigten Initiativtexte können nicht mehr verändert werden. Neue Initiativen können gestartet aber ebenfalls nicht mehr geändert werden. Dieses Vorgehen schützt die Teilnehmer vor überraschenden Änderungen in letzter Minute.
   33.85 +      ]] }
   33.86 +    else
   33.87 +      ui.tag{ tag = "p", content = [[
   33.88 +        During the verification phase, initiative drafts with the proposal and reasoning become final and cannot be changed any more. So everyone can double check everything. In case of some last minute situation, it is still possible to add competing initiatives. But they cannot be edited again and need to gain supporters from scratch.
   33.89 +      ]] }
   33.90 +    end
   33.91 +    ui.heading{ level = 2, content = _"(4) Voting phase" }
   33.92 +    if lang == "de" then
   33.93 +      ui.tag{ tag = "p", content = [[
   33.94 +        Jede Initiative, die eine Mindestanzahl an Unterstützern erreicht, wird zur Abstimmung zugelassen und erscheint auf dem Stimmzettel. Während der Abstimmung können die Teilnehmer mittels Präferenzwahl abstimmen, die es neben Zustimmung, Enthaltung und Ablehnung zusätzlich erlaubt Präferenzen zwischen den Initiativen anzugeben.
   33.95 +      ]] }
   33.96 +    else
   33.97 +      ui.tag{ tag = "p", content = [[
   33.98 +        Every initiative reaching a required quorum of supporters at the end of the verification phase is admitted for voting and appears on the voting ballot. During the voting phase every eligible participant may give a vote using a preferential voting system allowing to express individual preferences between the initiatives in addition to a yes/neutral/no vote.
   33.99 +      ]] }
  33.100 +    end
  33.101 +    
  33.102 +  end)
  33.103 +end)
  33.104 +ui.section(function()
  33.105 +  ui.sectionHead(function()
  33.106 +    ui.heading{ level = 1, content = _"Vote delegation" }
  33.107 +  end)
  33.108 +  ui.sectionRow(function()
  33.109 +    if lang == "de" then
  33.110 +      ui.tag{ tag = "p", content = [[
  33.111 +        Delegationen ermöglichen eine dynamische Arbeitsteilung. Sie entsprechen einer Stimmrechtsvollmacht, können jederzeit geändert werden, sind weisungsfrei und übertragbar. Delegationen können für eine Gliederung, für einen Themenbereich der Gliederung oder für ein konkretes Thema erteilt werden. Konkretere Delegationen gehen allgemeineren Delegationen vor. Delegationen werden sowohl für den Diskurs (Phasen 1 bis 3) als auch für die Abstimmphase genutzt. Bei Aktivität eines Benutzers werden eventuell vorhandene Delegationen für die jeweilige Aktivität ausgesetzt.
  33.112 +      ]] }
  33.113 +    else
  33.114 +      ui.tag{ tag = "p", content = [[
  33.115 +        Delegations allow for a dynamic division of labor. A delegation is a proxy statement (voting power under a power of attorney), can be altered at any time, is not bound to directives and can be delegated onward. Delegations can be used for a whole organizational unit, for a subject area within an organizational unit, or for a specific issue. More specific delegations overrule more general delegations. Delegations are used in both the discourse (phase 1 to 3) and the voting phase. Any activity suspends existing delegations for the given activity.
  33.116 +      ]] }
  33.117 +    end
  33.118 +  end)
  33.119 +end)
  33.120 +ui.section(function()
  33.121 +  ui.sectionHead(function()
  33.122 +    ui.heading{ level = 1, content = _"Preference voting" }
  33.123 +  end)
  33.124 +  ui.sectionRow(function()
  33.125 +    if lang == "de" then
  33.126 +      ui.tag{ tag = "p", content = [[
  33.127 +        Im Falle mehrerer ähnlicher Vorschläge auf dem Stimmzettel gibt es keine Notwendigkeit einen dieser Vorschläge auszuwählen. Stattdessen kann für (bzw. gegen) beliebig viele konkurrierende Initiativen gestimmt werden und gleichzeitig eine Präferenzreihenfolge dieser Initiativen angegeben werden. Die Präferenzen bestimmen den Gewinner, falls am Ende mehr als eine Initiative die notwendige Mehrheit an Ja-Stimmen erreicht. Auf diese Weise wird niemand ermutigt für eine Initiative zu stimmen, nur um eine andere Initiative zu verhindern, und es wird niemand ermutigt gegen eine Initiative zu stimmen, nur um einer anderen Initiative eine Chance zu geben.
  33.128 +      ]] }
  33.129 +    else
  33.130 +      ui.tag{ tag = "p", content = [[
  33.131 +        If there are similar competing proposals on the ballot, there is no necessity to choose one of them. Instead, it is possible to vote for (and against) as many initiatives as one wants to while being able to express the individual preferences amongst those initiatives during voting phase. Those preferences will determine the winner if more than one initiative has reached the necessary majority of approvals at end of voting phase. That way, nobody is encouraged to vote in favor of one initiative just to outrank another one, and nobody is encouraged to vote against an initiative just to increase the chances for another initiative to win.
  33.132 +      ]] }
  33.133 +    end
  33.134 +  end)
  33.135 +end)
    34.1 --- a/app/main/index/404.lua	Thu Jul 10 01:02:43 2014 +0200
    34.2 +++ b/app/main/index/404.lua	Thu Jul 10 01:19:48 2014 +0200
    34.3 @@ -1,3 +1,13 @@
    34.4  ui.title("404 Not found")
    34.5  
    34.6 -ui.container{ content = "Page not found" }
    34.7 +ui.section(function()
    34.8 +  ui.sectionHead(function()
    34.9 +    ui.heading{ level = 1, content = _"Page not found" }
   34.10 +  end)
   34.11 +  ui.sectionRow(function()
   34.12 +    ui.link{
   34.13 +      content = _"Go back to home page",
   34.14 +      module = "index", view = "index"
   34.15 +    }
   34.16 +  end)
   34.17 +end)
   34.18 \ No newline at end of file
    35.1 --- a/app/main/index/_action/login.lua	Thu Jul 10 01:02:43 2014 +0200
    35.2 +++ b/app/main/index/_action/login.lua	Thu Jul 10 01:19:48 2014 +0200
    35.3 @@ -90,6 +90,18 @@
    35.4    if config.etherpad then
    35.5      do_etherpad_auth(member)
    35.6    end
    35.7 +  slot.select("script", function()
    35.8 +    ui.script{ script = [[
    35.9 +      $('#swiper_info').addClass('active');
   35.10 +    ]] }
   35.11 +  end)
   35.12 +  slot.select("swiper_info", function()
   35.13 +    ui.tag { content = _"select tabs" }
   35.14 +    slot.put(" &uparrow; ")
   35.15 +    ui.tag { content = _"or swipe" }
   35.16 +    slot.put(" &leftarrow;<br />")
   35.17 +    ui.tag { content = _"to show more info and learn what you can do" }
   35.18 +  end )
   35.19  else
   35.20    slot.select("error", function()
   35.21      ui.tag{ content = _'Invalid login name or password!' }
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/app/main/index/_login.lua	Thu Jul 10 01:19:48 2014 +0200
    36.3 @@ -0,0 +1,37 @@
    36.4 +ui.form{
    36.5 +  attr = { class = "login" },
    36.6 +  module = 'index',
    36.7 +  action = 'login',
    36.8 +  routing = {
    36.9 +    ok = {
   36.10 +      mode   = 'redirect',
   36.11 +      module = param.get("redirect_module") or "index",
   36.12 +      view = param.get("redirect_view") or "index",
   36.13 +      id = param.get("redirect_id"),
   36.14 +    },
   36.15 +    error = {
   36.16 +      mode   = 'forward',
   36.17 +      module = 'index',
   36.18 +      view   = 'login',
   36.19 +    }
   36.20 +  },
   36.21 +  content = function()
   36.22 +    ui.field.text{
   36.23 +      attr = { id = "username_field" },
   36.24 +      label     = _'login name',
   36.25 +      html_name = 'login',
   36.26 +      value     = ''
   36.27 +    }
   36.28 +    ui.script{ script = 'document.getElementById("username_field").focus();' }
   36.29 +    ui.field.password{
   36.30 +      label     = _'Password',
   36.31 +      html_name = 'password',
   36.32 +      value     = ''
   36.33 +    }
   36.34 +    ui.submit{
   36.35 +      text = _'Login'
   36.36 +    }
   36.37 +    slot.put("&nbsp;&nbsp;")
   36.38 +    ui.link{ module = "index", view = "reset_password", text = _"Forgot password?" }
   36.39 +  end
   36.40 +}
   36.41 \ No newline at end of file
    37.1 --- a/app/main/index/_motd.lua	Thu Jul 10 01:02:43 2014 +0200
    37.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.3 @@ -1,9 +0,0 @@
    37.4 -if config.motd_intern then
    37.5 -  local help_text = config.motd_intern
    37.6 -  ui.container{
    37.7 -    attr = { class = "wiki" },
    37.8 -    content = function()
    37.9 -      slot.put(format.wiki_text(help_text))
   37.10 -    end
   37.11 -  }
   37.12 -end
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/app/main/index/_sidebar_members.lua	Thu Jul 10 01:19:48 2014 +0200
    38.3 @@ -0,0 +1,33 @@
    38.4 +if not app.session:has_access("all_pseudonymous") then
    38.5 +  return
    38.6 +end
    38.7 +
    38.8 +ui.sidebar ( "tab-members", function ()
    38.9 +  local member_count = MemberCount:get()
   38.10 +  ui.sidebarHead( function()
   38.11 +    ui.heading {
   38.12 +      level = 2,
   38.13 +      content = _("Registered members (#{count})", { count = member_count })
   38.14 +    }
   38.15 +  end )
   38.16 +
   38.17 +  local selector = Member:new_selector()
   38.18 +    :add_where("active")
   38.19 +    :add_order_by("last_login DESC NULLS LAST, id DESC")
   38.20 +    :limit(50)
   38.21 +  
   38.22 +  execute.view {
   38.23 +    module = 'member', view   = '_list', params = {
   38.24 +      members_selector = selector,
   38.25 +      no_filter = true, no_paginate = true,
   38.26 +      member_class = "sidebarRow sidebarRowNarrow"
   38.27 +    }
   38.28 +  }
   38.29 +  
   38.30 +  ui.link {
   38.31 +    attr = { class = "sidebarRow moreLink" },
   38.32 +    text = _"Show full member list",
   38.33 +    module = "member", view = "list"
   38.34 +  }
   38.35 +  
   38.36 +end )
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/app/main/index/_sidebar_motd_intern.lua	Thu Jul 10 01:19:48 2014 +0200
    39.3 @@ -0,0 +1,10 @@
    39.4 +if config.motd_intern then
    39.5 +  slot.select("motd", function()
    39.6 +    ui.container{
    39.7 +      attr = { class = "wiki motd" },
    39.8 +      content = function()
    39.9 +        slot.put(config.motd_intern)
   39.10 +      end
   39.11 +    }
   39.12 +  end )
   39.13 +end
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/app/main/index/_sidebar_motd_public.lua	Thu Jul 10 01:19:48 2014 +0200
    40.3 @@ -0,0 +1,10 @@
    40.4 +if config.motd_public then
    40.5 +  slot.select("motd", function()
    40.6 +    ui.container{
    40.7 +      attr = { class = "wiki motd" },
    40.8 +      content = function()
    40.9 +        slot.put(config.motd_public)
   40.10 +      end
   40.11 +    }
   40.12 +  end )
   40.13 +end
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/app/main/index/_sidebar_notifications.lua	Thu Jul 10 01:19:48 2014 +0200
    41.3 @@ -0,0 +1,132 @@
    41.4 +local notification_links = {}
    41.5 +
    41.6 +if app.session.member.notify_email_unconfirmed then
    41.7 +  notification_links[#notification_links+1] = {
    41.8 +    module = "index", view = "email_unconfirmed",
    41.9 +    text = _"Confirm your email address"
   41.10 +  }
   41.11 +end
   41.12 +
   41.13 +if app.session.member.notify_level == nil then
   41.14 +  notification_links[#notification_links+1] = {
   41.15 +    module = "member", view = "settings_notification",
   41.16 +    text = _"Select a notification level"
   41.17 +  }
   41.18 +end
   41.19 +
   41.20 +if config.check_delegations_interval_soft then
   41.21 +  local member = Member:new_selector()
   41.22 +    :add_where({ "id = ?", app.session.member_id })
   41.23 +    :add_field({ "now() > COALESCE(last_delegation_check, activated) + ?::interval", config.check_delegations_interval_soft }, "needs_delegation_check_soft")
   41.24 +    :single_object_mode()
   41.25 +    :exec()
   41.26 +    
   41.27 +
   41.28 +  if member.needs_delegation_check_soft then
   41.29 +
   41.30 +    local delegations = Delegation:delegations_to_check_for_member_id(member.id)
   41.31 +    
   41.32 +    if #delegations > 0 then
   41.33 +      notification_links[#notification_links+1] = {
   41.34 +        module = "index", view = "check_delegations", 
   41.35 +        text = _"Check your outgoing delegations"
   41.36 +      }
   41.37 +    end
   41.38 +    
   41.39 +  end
   41.40 +end
   41.41 +
   41.42 +local broken_delegations = Delegation:selector_for_broken(app.session.member_id):exec()
   41.43 +
   41.44 +for i, delegation in ipairs(broken_delegations) do
   41.45 +  local scope
   41.46 +  local context
   41.47 +  if delegation.scope == "unit" then
   41.48 +    scope = _"unit"
   41.49 +    id = delegation.unit_id
   41.50 +    context = delegation.unit.name
   41.51 +  elseif delegation.scope == "area" then
   41.52 +    scope = _"area"
   41.53 +    id = delegation.area_id
   41.54 +    context = delegation.area.name
   41.55 +  elseif delegation.scope == "issue" then
   41.56 +    scope = _"issue"
   41.57 +    id = delegation.issue_id
   41.58 +    context = delegation.issue.name
   41.59 +  end
   41.60 +   
   41.61 +  notification_links[#notification_links+1] = {
   41.62 +    module = delegation.scope, view = "show", id = id,
   41.63 +    text = _("Check your #{scope} delegation to '#{trustee_name}' for '#{context}'", {
   41.64 +      trustee_name = delegation.trustee.name,
   41.65 +      scope = scope,
   41.66 +      context = context
   41.67 +    })
   41.68 +  }
   41.69 +end
   41.70 +
   41.71 +local selector = Issue:new_selector()
   41.72 +  :join("area", nil, "area.id = issue.area_id")
   41.73 +  :join("privilege", nil, { "privilege.unit_id = area.unit_id AND privilege.member_id = ? AND privilege.voting_right", app.session.member_id })
   41.74 +  :left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id })
   41.75 +  :left_join("non_voter", nil, { "non_voter.issue_id = issue.id AND non_voter.member_id = ?", app.session.member.id })
   41.76 +  :left_join("interest", nil, { "interest.issue_id = issue.id AND interest.member_id = ?", app.session.member.id })
   41.77 +  :add_where{ "direct_voter.member_id ISNULL" }
   41.78 +  :add_where{ "non_voter.member_id ISNULL" }
   41.79 +  :add_where{ "interest.member_id NOTNULL" }
   41.80 +  :add_where{ "issue.fully_frozen NOTNULL" }
   41.81 +  :add_where{ "issue.closed ISNULL" }
   41.82 +  :add_order_by{ "issue.fully_frozen + issue.voting_time ASC" }
   41.83 +  
   41.84 +local issues_to_vote = selector:exec()
   41.85 +
   41.86 +for i, issue in ipairs(issues_to_vote) do
   41.87 +  notification_links[#notification_links+1] = {
   41.88 +    module = "issue", view = "show", id = issue.id,
   41.89 +    text = _("#{issue} is in voting", { issue = issue.name })
   41.90 +  }
   41.91 +end
   41.92 +
   41.93 +local initiator_invites = Initiator:selector_for_invites(app.session.member_id):exec()
   41.94 +  
   41.95 +for i, initiative in ipairs(initiator_invites) do
   41.96 +  notification_links[#notification_links+1] = {
   41.97 +    module = "initiative", view = "show", id = initiative.id,
   41.98 +    text = _("You are invited to become initiator of '#{initiative_name}'", { initiative_name = initiative.display_name })
   41.99 +  }
  41.100 +end
  41.101 +
  41.102 +updated_drafts = Initiative:selector_for_updated_drafts(app.session.member_id):exec()
  41.103 +
  41.104 +for i, initiative in ipairs(updated_drafts) do
  41.105 +  notification_links[#notification_links+1] = {
  41.106 +    module = "initiative", view = "show", id = initiative.id,
  41.107 +    text = _("New draft for initiative '#{initiative_name}'", { initiative_name = initiative.display_name })
  41.108 +  }
  41.109 +end
  41.110 +
  41.111 +local mode = param.get("mode") or "view"
  41.112 +
  41.113 +if #notification_links > 0 then
  41.114 +  if mode == "link" then
  41.115 +    slot.select("notification", function ()
  41.116 +      local text = _"notifications"
  41.117 +      ui.link {
  41.118 +        attr = { class = "notifications", title = text },
  41.119 +        module = "index", view = "notifications",
  41.120 +        content = function ()
  41.121 +          ui.image { attr = { class = "icon", alt = text }, static = "icons/48/bell.png" }
  41.122 +          ui.tag { attr = { class = "count" }, content = #notification_links }
  41.123 +        end
  41.124 +      }
  41.125 +    end )
  41.126 +  elseif mode == "view" then
  41.127 +    ui.tag{ tag = "ul", attr = { class = "ul" }, content = function()
  41.128 +      for i, notification_link in ipairs(notification_links) do
  41.129 +        ui.tag{ tag = "li", content = function()
  41.130 +          ui.link(notification_link)
  41.131 +        end }
  41.132 +      end
  41.133 +    end }
  41.134 +  end
  41.135 +end
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/app/main/index/_sidebar_units.lua	Thu Jul 10 01:19:48 2014 +0200
    42.3 @@ -0,0 +1,154 @@
    42.4 +local member = param.get ( "member", "table" )
    42.5 +local units
    42.6 +if member then
    42.7 +  units = member.units
    42.8 +  units:load_delegation_info_once_for_member_id(member.id)
    42.9 +else
   42.10 +  units = Unit:new_selector():add_where("active"):add_order_by("name"):exec()
   42.11 +  ui.sidebar( "tab-whatcanido", function()
   42.12 +    ui.sidebarHead( function()
   42.13 +      ui.heading { level = 2, content = _"Organizational units" }
   42.14 +    end )
   42.15 +    ui.sidebarSection( function()
   42.16 +      execute.view { module = "unit", view = "_list" }
   42.17 +    end )
   42.18 +  end )
   42.19 +  return
   42.20 +end
   42.21 +
   42.22 +
   42.23 +for i, unit in ipairs(units) do
   42.24 +  
   42.25 +  ui.sidebar ( "tab-whatcanido units", function ()
   42.26 +
   42.27 +    local areas_selector = Area:new_selector()
   42.28 +      :reset_fields()
   42.29 +      :add_field("area.id", nil, { "grouped" })
   42.30 +      :add_field("area.unit_id", nil, { "grouped" })
   42.31 +      :add_field("area.name", nil, { "grouped" })
   42.32 +      :add_where{ "area.unit_id = ?", unit.id }
   42.33 +      :add_where{ "area.active" }
   42.34 +      :add_order_by("area.name")
   42.35 +
   42.36 +    if member then
   42.37 +      areas_selector:left_join ( 
   42.38 +        "membership", nil, 
   42.39 +        { "membership.area_id = area.id AND membership.member_id = ?", member.id } 
   42.40 +      )
   42.41 +      areas_selector:add_field("membership.member_id NOTNULL", "subscribed", { "grouped" })
   42.42 +    end
   42.43 +
   42.44 +    local areas = areas_selector:exec()
   42.45 +    if member then
   42.46 +      areas:load_delegation_info_once_for_member_id(member.id)
   42.47 +    end
   42.48 +    
   42.49 +    if #areas > 0 then
   42.50 +
   42.51 +      ui.container {
   42.52 +        attr = { class = "sidebarHead" },
   42.53 +        content = function ()
   42.54 +          ui.heading { level = 2, content = function ()
   42.55 +            ui.link {
   42.56 +              attr = { class = "unit" },
   42.57 +              module = "unit", view = "show", id = unit.id,
   42.58 +              content = unit.name
   42.59 +            }
   42.60 +          
   42.61 +            if member then
   42.62 +              local delegation = Delegation:by_pk(member.id, unit.id, nil, nil)
   42.63 +              
   42.64 +              if delegation then
   42.65 +                ui.link { 
   42.66 +                  module = "delegation", view = "show", params = {
   42.67 +                    unit_id = unit.id
   42.68 +                  },
   42.69 +                  attr = { class = "delegation_info" }, 
   42.70 +                  content = function ()
   42.71 +                    ui.delegation(delegation.trustee_id, delegation.trustee.name)
   42.72 +                  end
   42.73 +                }
   42.74 +              end
   42.75 +            end
   42.76 +          end }
   42.77 +          
   42.78 +        end
   42.79 +      }
   42.80 +      
   42.81 +      
   42.82 +      ui.tag { tag = "div", attr = { class = "areas areas-" .. unit.id }, content = function ()
   42.83 +      
   42.84 +        local any_subscribed = false
   42.85 +        local subscribed_count = 0
   42.86 +        for i, area in ipairs(areas) do
   42.87 +
   42.88 +          local class = "sidebarRow"
   42.89 +          class = class .. (not area.subscribed and " disabled" or "")
   42.90 +          
   42.91 +          ui.tag { tag = "div", attr = { class = class }, content = function ()
   42.92 +            
   42.93 +            if area.subscribed then
   42.94 +              local text = _"subscribed"
   42.95 +              ui.image { attr = { class = "icon24 star", alt = text, title = text }, static = "icons/48/star.png" }
   42.96 +              any_subscribed = true
   42.97 +              subscribed_count = subscribed_count +1
   42.98 +            end
   42.99 +            
  42.100 +            if member then
  42.101 +              local delegation = Delegation:by_pk(member.id, nil, area.id, nil)
  42.102 +        
  42.103 +              if delegation then
  42.104 +                ui.link { 
  42.105 +                  module = "delegation", view = "show", params = {
  42.106 +                    area_id = area.id
  42.107 +                  },
  42.108 +                  attr = { class = "delegation_info" }, 
  42.109 +                  content = function ()
  42.110 +                    ui.delegation(delegation.trustee_id, delegation.trustee_id and delegation.trustee.name)
  42.111 +                  end
  42.112 +                }
  42.113 +              end
  42.114 +            end
  42.115 +      
  42.116 +            slot.put ( " " )
  42.117 +            
  42.118 +            ui.link {
  42.119 +              attr = { class = "area" },
  42.120 +              module = "area", view = "show", id = area.id,
  42.121 +              content = area.name
  42.122 +            }
  42.123 +            
  42.124 +            
  42.125 +          end }
  42.126 +        end
  42.127 +        if subscribed_count < #areas then
  42.128 +          local text 
  42.129 +          if any_subscribed then
  42.130 +            text = _"show other subject areas"
  42.131 +          else
  42.132 +            text = _"show subject areas"
  42.133 +          end
  42.134 +          ui.script{ script = "$('.areas-" .. unit.id .. "').addClass('folded');" }
  42.135 +          ui.tag { tag = "div", attr = { class = "sidebarRow moreLink whenfolded" }, content = function ()
  42.136 +            ui.link {
  42.137 +              attr = { 
  42.138 +                onclick = "$('.areas-" .. unit.id .. "').removeClass('folded'); return false;"
  42.139 +              },
  42.140 +              text = text
  42.141 +            }
  42.142 +          end }
  42.143 +          ui.tag { tag = "div", attr = { class = "sidebarRow moreLink whenunfolded" }, content = function ()
  42.144 +            ui.link {
  42.145 +              attr = { 
  42.146 +                onclick = "$('.areas-" .. unit.id .. "').addClass('folded'); return false;"
  42.147 +              },
  42.148 +              text = _"collapse subject areas"
  42.149 +            }
  42.150 +          end }
  42.151 +        end
  42.152 +      end }
  42.153 +    end 
  42.154 +  end )
  42.155 +end
  42.156 +
  42.157 +
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/app/main/index/_sidebar_whatcanido.lua	Thu Jul 10 01:19:48 2014 +0200
    43.3 @@ -0,0 +1,71 @@
    43.4 +ui.sidebar ( "tab-whatcanido", function ()
    43.5 +
    43.6 +  ui.sidebarHeadWhatCanIDo()
    43.7 +
    43.8 +  if app.session.member then
    43.9 +    ui.sidebarSection( function()
   43.10 +      ui.heading { level = 3, content = _"I want to know whats going on" }
   43.11 +      ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
   43.12 +        ui.tag { tag = "li", content = _"take a look on the issues (see left)" }
   43.13 +        ui.tag { tag = "li", content = _"by default only those issues are shown, for which your are eligible to participate (change filters on top of the list)" }
   43.14 +      end } 
   43.15 +    end )
   43.16 +    ui.sidebarSection( function()
   43.17 +      ui.heading { level = 3, content = _"I want to stay informed" }
   43.18 +      ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
   43.19 +        ui.tag { tag = "li", content = function ()
   43.20 +          ui.tag{ content = _"check your " }
   43.21 +          ui.link{
   43.22 +            module = "member", view = "settings_notification",
   43.23 +            params = { return_to = "home" },
   43.24 +            text = _"notifications settings"
   43.25 +          }
   43.26 +        end }
   43.27 +        ui.tag { tag = "li", content = function ()
   43.28 +          ui.tag{ content = _"subscribe subject areas or add your interested to issues and you will be notified about changes (follow the instruction on the area or issue page)" }
   43.29 +        end }
   43.30 +      end } 
   43.31 +    end )
   43.32 +    ui.sidebarSection( function()
   43.33 +      ui.heading { level = 3, content = _"I want to start a new initiative" }
   43.34 +      ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
   43.35 +        ui.tag { tag = "li", content = _"open the appropriate subject area for your issue and follow the instruction on that page." }
   43.36 +      end } 
   43.37 +    end )
   43.38 +    ui.sidebarSection( function()
   43.39 +      ui.heading { level = 3, content = _"I want to delegate my vote" }
   43.40 +      ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
   43.41 +        ui.tag { tag = "li", content = _"open the organizational unit, subject area or issue you like to delegate and follow the instruction on that page." }
   43.42 +      end } 
   43.43 +    end )
   43.44 +    ui.sidebarSection( function()
   43.45 +      ui.heading { level = 3, content = _"I want to take a look at other organizational units" }
   43.46 +      ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
   43.47 +        ui.tag { tag = "li", content = function ()
   43.48 +          ui.link{
   43.49 +            module = "unit", view = "list",
   43.50 +            text = _"show all units"
   43.51 +          }
   43.52 +        end }
   43.53 +      end } 
   43.54 +    end )
   43.55 +    ui.sidebarSection( function()
   43.56 +      ui.heading { level = 3, content = _"I want to learn more about LiquidFeedback" }
   43.57 +      ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
   43.58 +        ui.tag { tag = "li", content = function()
   43.59 +          ui.link { module = "help", view = "introduction", content = _"structured discussion" }
   43.60 +        end }
   43.61 +        ui.tag { tag = "li", content = function()
   43.62 +          ui.link { module = "help", view = "introduction", content = _"4 phases of a decision" }
   43.63 +        end }
   43.64 +        ui.tag { tag = "li", content = function()
   43.65 +          ui.link { module = "help", view = "introduction", content = _"vote delegation" }
   43.66 +        end }
   43.67 +        ui.tag { tag = "li", content = function()
   43.68 +          ui.link { module = "help", view = "introduction", content = _"preference voting" }
   43.69 +        end }
   43.70 +      end } 
   43.71 +    end )
   43.72 +  end 
   43.73 +
   43.74 +end )
    44.1 --- a/app/main/index/about.lua	Thu Jul 10 01:02:43 2014 +0200
    44.2 +++ b/app/main/index/about.lua	Thu Jul 10 01:19:48 2014 +0200
    44.3 @@ -1,102 +1,91 @@
    44.4  ui.title(_"About site")
    44.5  
    44.6 -if app.session.member_id and config.use_terms then
    44.7 -  ui.actions(function()
    44.8 -    ui.link{
    44.9 -      module = "index",
   44.10 -      view = "usage_terms",
   44.11 -      text = _"Terms of use"
   44.12 -    }
   44.13 -  end)
   44.14 -end
   44.15 +ui.section( function()
   44.16  
   44.17 +  ui.sectionHead( function()
   44.18 +    ui.heading{ level = 1, content = _"About site" }
   44.19 +  end )
   44.20 +
   44.21 +  ui.sectionRow( function()
   44.22  
   44.23 -slot.put("<br />")
   44.24 -ui.field.text{ attr = { style = "font-weight: bold;" }, value = _"This service is provided by:" }
   44.25 -slot.put("<br />")
   44.26 -
   44.27 -slot.put(config.app_service_provider)
   44.28 +    ui.heading{ level = 3, content = _"This service is provided by:" }
   44.29 +    slot.put(config.app_service_provider)
   44.30  
   44.31 -slot.put("<br />")
   44.32 -slot.put("<br />")
   44.33 -slot.put("<br />")
   44.34 +  end )
   44.35  
   44.36 +  ui.sectionRow( function()
   44.37  
   44.38 -ui.field.text{ attr = { style = "font-weight: bold;" }, value = _"This service is provided using the following software components:" }
   44.39 -slot.put("<br />")
   44.40 +    ui.heading{ level = 3, content = _"This service is provided using the following software components:" }
   44.41  
   44.42 -local tmp = {
   44.43 -  {
   44.44 -    name = "LiquidFeedback Frontend",
   44.45 -    url = "http://www.public-software-group.org/liquid_feedback",
   44.46 -    version = config.app_version,
   44.47 -    license = "MIT/X11",
   44.48 -    license_url = "http://www.public-software-group.org/licenses"
   44.49 -  },
   44.50 -  {
   44.51 -    name = "LiquidFeedback Core",
   44.52 -    url = "http://www.public-software-group.org/liquid_feedback",
   44.53 -    version = db:query("SELECT * from liquid_feedback_version;")[1].string,
   44.54 -    license = "MIT/X11",
   44.55 -    license_url = "http://www.public-software-group.org/licenses"
   44.56 -  },
   44.57 -  {
   44.58 -    name = "WebMCP",
   44.59 -    url = "http://www.public-software-group.org/webmcp",
   44.60 -    version = _WEBMCP_VERSION,
   44.61 -    license = "MIT/X11",
   44.62 -    license_url = "http://www.public-software-group.org/licenses"
   44.63 -  },
   44.64 -  {
   44.65 -    name = "Lua",
   44.66 -    url = "http://www.lua.org",
   44.67 -    version = _VERSION:gsub("Lua ", ""),
   44.68 -    license = "MIT/X11",
   44.69 -    license_url = "http://www.lua.org/license.html"
   44.70 -  },
   44.71 -  {
   44.72 -    name = "PostgreSQL",
   44.73 -    url = "http://www.postgresql.org/",
   44.74 -    version = db:query("SELECT version();")[1].version:gsub("PostgreSQL ", ""):gsub("on.*", ""),
   44.75 -    license = "BSD",
   44.76 -    license_url = "http://www.postgresql.org/about/licence"
   44.77 -  },
   44.78 -}
   44.79 +    local tmp = {
   44.80 +      {
   44.81 +        name = "LiquidFeedback Frontend",
   44.82 +        url = "http://www.public-software-group.org/liquid_feedback",
   44.83 +        version = config.app_version,
   44.84 +        license = "MIT/X11",
   44.85 +        license_url = "http://www.public-software-group.org/licenses"
   44.86 +      },
   44.87 +      {
   44.88 +        name = "LiquidFeedback Core",
   44.89 +        url = "http://www.public-software-group.org/liquid_feedback",
   44.90 +        version = db:query("SELECT * from liquid_feedback_version;")[1].string,
   44.91 +        license = "MIT/X11",
   44.92 +        license_url = "http://www.public-software-group.org/licenses"
   44.93 +      },
   44.94 +      {
   44.95 +        name = "WebMCP",
   44.96 +        url = "http://www.public-software-group.org/webmcp",
   44.97 +        version = _WEBMCP_VERSION,
   44.98 +        license = "MIT/X11",
   44.99 +        license_url = "http://www.public-software-group.org/licenses"
  44.100 +      },
  44.101 +      {
  44.102 +        name = "Lua",
  44.103 +        url = "http://www.lua.org",
  44.104 +        version = _VERSION:gsub("Lua ", ""),
  44.105 +        license = "MIT/X11",
  44.106 +        license_url = "http://www.lua.org/license.html"
  44.107 +      },
  44.108 +      {
  44.109 +        name = "PostgreSQL",
  44.110 +        url = "http://www.postgresql.org/",
  44.111 +        version = db:query("SELECT version();")[1].version:gsub("PostgreSQL ", ""):gsub("on.*", ""),
  44.112 +        license = "BSD",
  44.113 +        license_url = "http://www.postgresql.org/about/licence"
  44.114 +      },
  44.115 +    }
  44.116  
  44.117 -ui.list{
  44.118 -  records = tmp,
  44.119 -  columns = {
  44.120 -    {
  44.121 -      label = _"Software",
  44.122 -      content = function(record) 
  44.123 -        ui.link{
  44.124 -          content = record.name,
  44.125 -          external = record.url
  44.126 +    ui.list{
  44.127 +      records = tmp,
  44.128 +      columns = {
  44.129 +        {
  44.130 +          content = function(record) 
  44.131 +            ui.link{
  44.132 +              content = record.name,
  44.133 +              external = record.url
  44.134 +            }
  44.135 +          end
  44.136 +        },
  44.137 +        {
  44.138 +          content = function(record) ui.field.text{ value = record.version } end
  44.139 +        },
  44.140 +        {
  44.141 +          content = function(record) 
  44.142 +            ui.link{
  44.143 +              content = record.license,
  44.144 +              external = record.license_url
  44.145 +            }
  44.146 +          end
  44.147 +
  44.148          }
  44.149 -      end
  44.150 -    },
  44.151 -    {
  44.152 -      label = _"Version",
  44.153 -      content = function(record) ui.field.text{ value = record.version } end
  44.154 -    },
  44.155 -    {
  44.156 -      label = _"License",
  44.157 -      content = function(record) 
  44.158 -        ui.link{
  44.159 -          content = record.license,
  44.160 -          external = record.license_url
  44.161 -        }
  44.162 -      end
  44.163 +      }
  44.164 +    }
  44.165 +
  44.166 +  end )
  44.167  
  44.168 -    }
  44.169 -  }
  44.170 -}
  44.171 +  ui.sectionRow( function()
  44.172 +    ui.heading{ level = 3, content = "3rd party license information:" }
  44.173 +    slot.put('Some of the icons used in Liquid Feedback are from <a href="http://www.famfamfam.com/lab/icons/silk/">Silk icon set 1.3</a> by Mark James. His work is licensed under a <a href="http://creativecommons.org/licenses/by/2.5/">Creative Commons Attribution 2.5 License.</a>')
  44.174  
  44.175 -slot.put("<br />")
  44.176 -slot.put("<br />")
  44.177 -slot.put("<br />")
  44.178 -
  44.179 -ui.field.text{ attr = { style = "font-weight: bold;" }, value = "3rd party license information:" }
  44.180 -slot.put("<br />")
  44.181 -slot.put('The icons used in Liquid Feedback (except national flags) are from <a href="http://www.famfamfam.com/lab/icons/silk/">Silk icon set 1.3</a> by Mark James. His work is licensed under a <a href="http://creativecommons.org/licenses/by/2.5/">Creative Commons Attribution 2.5 License.</a>')
  44.182 -
  44.183 +  end )
  44.184 +end )
    45.1 --- a/app/main/index/check_delegations.lua	Thu Jul 10 01:02:43 2014 +0200
    45.2 +++ b/app/main/index/check_delegations.lua	Thu Jul 10 01:19:48 2014 +0200
    45.3 @@ -8,12 +8,6 @@
    45.4    end
    45.5  end)
    45.6  
    45.7 -if app.session.needs_delegation_check then
    45.8 -  util.help("index.check_delegations_hard", _"Check delegations")
    45.9 -else
   45.10 -  util.help("index.check_delegations", _"Check delegations")
   45.11 -end
   45.12 -
   45.13  ui.form{
   45.14    module = "index", action = "check_delegations",
   45.15    routing = {
    46.1 --- a/app/main/index/document.lua	Thu Jul 10 01:02:43 2014 +0200
    46.2 +++ b/app/main/index/document.lua	Thu Jul 10 01:19:48 2014 +0200
    46.3 @@ -15,8 +15,6 @@
    46.4    }
    46.5  end)
    46.6  
    46.7 -util.help("index.document", _"Download documents")
    46.8 -
    46.9  local file_list = extos.listdir(config.document_dir)
   46.10  
   46.11  local tmp = {}
    47.1 --- a/app/main/index/download.lua	Thu Jul 10 01:02:43 2014 +0200
    47.2 +++ b/app/main/index/download.lua	Thu Jul 10 01:19:48 2014 +0200
    47.3 @@ -15,12 +15,10 @@
    47.4    }
    47.5  end)
    47.6  
    47.7 -util.help("index.download", _"Download")
    47.8 -
    47.9  ui.container{
   47.10    attr = { class = "wiki use_terms" },
   47.11    content = function()
   47.12 -    slot.put(format.wiki_text(config.download_use_terms))
   47.13 +    slot.put(config.download_use_terms)
   47.14    end
   47.15  }
   47.16  
    48.1 --- a/app/main/index/email_unconfirmed.lua	Thu Jul 10 01:02:43 2014 +0200
    48.2 +++ b/app/main/index/email_unconfirmed.lua	Thu Jul 10 01:19:48 2014 +0200
    48.3 @@ -7,48 +7,50 @@
    48.4      :optional_object_mode()
    48.5      :exec()
    48.6  
    48.7 -  slot.select("head", function()
    48.8 -    ui.container{
    48.9 -      attr = { class = "title" },
   48.10 -      content = _"Notification address unconfirmed"
   48.11 -    }
   48.12 -  end )
   48.13 +  ui.title(_"Confirm notification address")
   48.14  
   48.15 -  if current then
   48.16 -    ui.tag{
   48.17 -      tag = "div",
   48.18 -      content = _("You didn't confirm your email address '#{email}'. You have received an email with an activation link.", { email = app.session.member.notify_email_unconfirmed })
   48.19 -    }
   48.20 -  else
   48.21 -    ui.tag{
   48.22 -      tag = "div",
   48.23 -      content = _("You didn't confirm your email address '#{email}' within 7 days.", { email = app.session.member.notify_email_unconfirmed })
   48.24 -    }
   48.25 -  end
   48.26 -  slot.put("<br />")
   48.27 +  ui.section( function()
   48.28 +    ui.sectionHead( function()
   48.29 +      ui.heading{ level = 1, content = _"Notification address unconfirmed" }
   48.30 +    end )
   48.31 +    
   48.32 +    ui.sectionRow( function()
   48.33 +      if current then
   48.34 +        ui.tag{
   48.35 +          tag = "div",
   48.36 +          content = _("You didn't confirm your email address '#{email}'. You have received an email with an activation link.", { email = app.session.member.notify_email_unconfirmed })
   48.37 +        }
   48.38 +      else
   48.39 +        ui.tag{
   48.40 +          tag = "div",
   48.41 +          content = _("You didn't confirm your email address '#{email}' within 7 days.", { email = app.session.member.notify_email_unconfirmed })
   48.42 +        }
   48.43 +      end
   48.44 +      slot.put("<br />")
   48.45  
   48.46 -  ui.link{
   48.47 -    text = _"Change email address",
   48.48 -    module = "member",
   48.49 -    view = "settings_email",
   48.50 -  }
   48.51 -  slot.put("<br />")
   48.52 -  slot.put("<br />")
   48.53 +      ui.link{
   48.54 +        text = _"Change email address",
   48.55 +        module = "member",
   48.56 +        view = "settings_email",
   48.57 +      }
   48.58 +      slot.put("<br />")
   48.59 +      slot.put("<br />")
   48.60  
   48.61 -  ui.link{
   48.62 -    text = _("Resend activation email to '#{email}'", { email = app.session.member.notify_email_unconfirmed }),
   48.63 -    module = "member",
   48.64 -    action = "update_email",
   48.65 -    params = {
   48.66 -      resend = true
   48.67 -    },
   48.68 -    routing = {
   48.69 -      default = {
   48.70 -        mode = "redirect",
   48.71 -        module = "index",
   48.72 -        view = "index"
   48.73 +      ui.link{
   48.74 +        text = _("Resend activation email to '#{email}'", { email = app.session.member.notify_email_unconfirmed }),
   48.75 +        module = "member",
   48.76 +        action = "update_email",
   48.77 +        params = {
   48.78 +          resend = true
   48.79 +        },
   48.80 +        routing = {
   48.81 +          default = {
   48.82 +            mode = "redirect",
   48.83 +            module = "index",
   48.84 +            view = "index"
   48.85 +          }
   48.86 +        }
   48.87        }
   48.88 -    }
   48.89 -  }
   48.90 -
   48.91 +    end )
   48.92 +  end )
   48.93  end
    49.1 --- a/app/main/index/index.lua	Thu Jul 10 01:02:43 2014 +0200
    49.2 +++ b/app/main/index/index.lua	Thu Jul 10 01:19:48 2014 +0200
    49.3 @@ -1,132 +1,114 @@
    49.4 -if app.session.member_id then
    49.5 -  util.help("index.index", _"Home")
    49.6 +function getIssuesSelector()
    49.7 +  return Issue:new_selector()
    49.8 +    :add_order_by([[
    49.9 +      coalesce(
   49.10 +        issue.fully_frozen + issue.voting_time, 
   49.11 +        issue.half_frozen + issue.verification_time, 
   49.12 +        issue.accepted + issue.discussion_time, 
   49.13 +        issue.created + issue.admission_time
   49.14 +      ) - now()
   49.15 +    ]])
   49.16 +end
   49.17  
   49.18 -  execute.view{
   49.19 -    module = "index", view = "_index_member"
   49.20 -  }
   49.21 +--[[
   49.22 +ui.title( function ()
   49.23 +  ui.link { attr = { class = "home" }, module = "index", view = "index", text = _"Home" }
   49.24 +end)
   49.25 +--]]
   49.26 +
   49.27 +ui.title()
   49.28  
   49.29 -elseif app.session:has_access("anonymous") then
   49.30 -  if config.motd_public then
   49.31 -    local help_text = config.motd_public
   49.32 -    ui.container{
   49.33 -      attr = { class = "wiki motd" },
   49.34 -      content = function()
   49.35 -        slot.put(format.wiki_text(help_text))
   49.36 -      end
   49.37 -    }
   49.38 -  end
   49.39 +if false then
   49.40 +slot.select ( "tabs", function ()
   49.41    
   49.42 -  local open_issues_selector = Issue:new_selector()
   49.43 -    :add_where("issue.closed ISNULL")
   49.44 -    :add_order_by("coalesce(issue.fully_frozen + issue.voting_time, issue.half_frozen + issue.verification_time, issue.accepted + issue.discussion_time, issue.created + issue.admission_time) - now()")
   49.45 -
   49.46 -  local closed_issues_selector = Issue:new_selector()
   49.47 -    :add_where("issue.closed NOTNULL")
   49.48 -    :add_order_by("issue.closed DESC")
   49.49 -
   49.50 +  ui.tag {
   49.51 +    attr = { onclick = "showTab(0);" },
   49.52 +    content = "units",
   49.53 +  }
   49.54 +  slot.put ( " " )
   49.55 +  ui.tag {
   49.56 +    attr = { onclick = "showTab(1);" },
   49.57 +    content = "timeline"
   49.58 +  }
   49.59 +  slot.put ( " " )
   49.60 +  ui.tag {
   49.61 +    attr = { onclick = "showTab(2);" },
   49.62 +    content = "what"
   49.63 +  }
   49.64 +  slot.put ( " " )
   49.65 +  ui.tag {
   49.66 +    attr = { onclick = "showTab(3);" },
   49.67 +    content = "members"
   49.68 +  }
   49.69    
   49.70 -  local tabs = {
   49.71 -    module = "index",
   49.72 -    view = "index"
   49.73 -  }
   49.74 -
   49.75 -  tabs[#tabs+1] = {
   49.76 -    name = "units",
   49.77 -    label = _"Units",
   49.78 -    module = "unit",
   49.79 -    view = "_list"
   49.80 -  }
   49.81 +end )
   49.82  
   49.83 -  tabs[#tabs+1] = {
   49.84 -    name = "timeline",
   49.85 -    label = _"Latest events",
   49.86 -    module = "event",
   49.87 -    view = "_list",
   49.88 -    params = { global = true }
   49.89 -  }
   49.90 +ui.script { script = [[
   49.91 +  
   49.92 +  var tabs = ["tab1", "main", "tab2", "tab3"]
   49.93 +  var currentId;
   49.94 +  
   49.95 +  function showTab(id) {
   49.96 +    var tabId = tabs[id];
   49.97 +    $('.tab').hide();
   49.98 +    $('.main').hide();
   49.99 +    $('.' + tabId).show();
  49.100 +    currentId = id;
  49.101 +  };
  49.102 +  
  49.103 +  showTab(0);
  49.104 +  
  49.105 +  $(function(){
  49.106 +    // Bind the swipeHandler callback function to the swipe event on div.box
  49.107 +    $( "body" ).on( "swiperight", function swipeHandler( event ) {
  49.108 +      newId = currentId - 1;
  49.109 +      if (newId < 0) return;
  49.110 +      showTab(newId);
  49.111 +    } )
  49.112 +    $( "body" ).on( "swipeleft", function swipeHandler( event ) {
  49.113 +      newId = currentId + 1;
  49.114 +      if (newId > tabs.length - 1) return;
  49.115 +      showTab(newId);
  49.116 +    } )
  49.117 +  });
  49.118 +  
  49.119 +]]}
  49.120 +end
  49.121  
  49.122 -  tabs[#tabs+1] = {
  49.123 -    name = "open",
  49.124 -    label = _"Open issues",
  49.125 -    module = "issue",
  49.126 -    view = "_list",
  49.127 -    params = {
  49.128 -      for_state = "open",
  49.129 -      issues_selector = open_issues_selector
  49.130 +
  49.131 +if app.session.member then
  49.132 +  execute.view{ module = "index", view = "_sidebar_motd_intern" }
  49.133 +else
  49.134 +  execute.view{ module = "index", view = "_sidebar_motd_public" }
  49.135 +end
  49.136 +
  49.137 +if app.session:has_access("anonymous") then
  49.138 +  -- show the units the member has voting privileges for
  49.139 +  execute.view {
  49.140 +    module = "index", view = "_sidebar_units", params = {
  49.141 +      member = app.session.member
  49.142      }
  49.143    }
  49.144 -  tabs[#tabs+1] = {
  49.145 -    name = "closed",
  49.146 -    label = _"Closed issues",
  49.147 -    module = "issue",
  49.148 -    view = "_list",
  49.149 -    params = {
  49.150 -      for_state = "closed",
  49.151 -      issues_selector = closed_issues_selector
  49.152 -    }
  49.153 -  }
  49.154 -
  49.155 -  if app.session:has_access('all_pseudonymous') then
  49.156 -    tabs[#tabs+1] = {
  49.157 -      name = "members",
  49.158 -      label = _"Members",
  49.159 -      module = 'member',
  49.160 -      view   = '_list',
  49.161 -      params = { members_selector = Member:new_selector():add_where("active") }
  49.162 -    }
  49.163 -  end
  49.164 -
  49.165 -  ui.tabs(tabs)
  49.166 -  
  49.167 -else
  49.168 -
  49.169 -  if config.motd_public then
  49.170 -    local help_text = config.motd_public
  49.171 -    ui.container{
  49.172 -      attr = { class = "wiki motd" },
  49.173 -      content = function()
  49.174 -        slot.put(format.wiki_text(help_text))
  49.175 -      end
  49.176 -    }
  49.177 -  end
  49.178 -
  49.179 -  ui.tag{ tag = "p", content = _"Closed user group, please login to participate." }
  49.180 +end
  49.181  
  49.182 -  ui.form{
  49.183 -  attr = { class = "login" },
  49.184 -  module = 'index',
  49.185 -  action = 'login',
  49.186 -  routing = {
  49.187 -    ok = {
  49.188 -      mode   = 'redirect',
  49.189 -      module = param.get("redirect_module") or "index",
  49.190 -      view = param.get("redirect_view") or "index",
  49.191 -      id = param.get("redirect_id"),
  49.192 -    },
  49.193 -    error = {
  49.194 -      mode   = 'forward',
  49.195 -      module = 'index',
  49.196 -      view   = 'login',
  49.197 -    }
  49.198 -  },
  49.199 -  content = function()
  49.200 -    ui.field.text{
  49.201 -      attr = { id = "username_field" },
  49.202 -      label     = _'login name',
  49.203 -      html_name = 'login',
  49.204 -      value     = ''
  49.205 -    }
  49.206 -    ui.script{ script = 'document.getElementById("username_field").focus();' }
  49.207 -    ui.field.password{
  49.208 -      label     = _'Password',
  49.209 -      html_name = 'password',
  49.210 -      value     = ''
  49.211 -    }
  49.212 -    ui.submit{
  49.213 -      text = _'Login'
  49.214 -    }
  49.215 -  end
  49.216 -}
  49.217 +-- show the user what can be done
  49.218 +execute.view { module = "index", view = "_sidebar_whatcanido" }
  49.219  
  49.220 +-- show active members
  49.221 +if app.session:has_access("all_pseudonymous") then
  49.222 +  execute.view{ module = "index", view = "_sidebar_members" }
  49.223  end
  49.224  
  49.225 +if app.session:has_access("anonymous") then
  49.226 +  
  49.227 +  if not app.session.member then
  49.228 +--    execute.view {
  49.229 +--      module = "slideshow", view = "_index"
  49.230 +--    }
  49.231 +  end
  49.232 +  
  49.233 +  execute.view {
  49.234 +    module = "issue", view = "_list2", params = { }
  49.235 +  }
  49.236 +  
  49.237 +end -- if app.session:has_access "anonymous"
  49.238 \ No newline at end of file
    50.1 --- a/app/main/index/login.lua	Thu Jul 10 01:02:43 2014 +0200
    50.2 +++ b/app/main/index/login.lua	Thu Jul 10 01:19:48 2014 +0200
    50.3 @@ -5,32 +5,47 @@
    50.4    end
    50.5  }
    50.6  
    50.7 -ui.actions()
    50.8 -
    50.9  ui.title(_"Login")
   50.10  app.html_title.title = _"Login"
   50.11  
   50.12 -if config.motd_public then
   50.13 -  local help_text = config.motd_public
   50.14 -  ui.container{
   50.15 -    attr = { class = "wiki motd" },
   50.16 -    content = function()
   50.17 -      slot.put(format.wiki_text(help_text))
   50.18 -    end
   50.19 -  }
   50.20 -end
   50.21 +execute.view{ module = "index", view = "_sidebar_motd_public" }
   50.22 +
   50.23 +ui.section(function() 
   50.24 +
   50.25 +ui.sectionHead(function()
   50.26 +  ui.heading{ level = 1, content = _"Login" }
   50.27 +  ui.container { attr = { class = "right" }, content = function()
   50.28 +    for i, lang in ipairs(config.enabled_languages) do
   50.29  
   50.30 -if app.session:has_access("anonymous") then
   50.31 -  ui.tag{
   50.32 -    tag = 'p',
   50.33 -    content = _'You need to be logged in, to use all features of this system.'
   50.34 -  }
   50.35 -else
   50.36 -  ui.tag{ tag = "p", content = _"Closed user group, please login to participate." }
   50.37 -end
   50.38 -
   50.39 +      locale.do_with({ lang = lang }, function()
   50.40 +        langcode = _("[Name of Language]")
   50.41 +      end)
   50.42 +      
   50.43 +      if i > 1 then
   50.44 +        slot.put(" | ")
   50.45 +      end
   50.46 +      
   50.47 +      ui.link{
   50.48 +        content = function()
   50.49 +          ui.tag{ content = langcode }
   50.50 +        end,
   50.51 +        module = "index",
   50.52 +        action = "set_lang",
   50.53 +        params = { lang = lang },
   50.54 +        routing = {
   50.55 +          default = {
   50.56 +            mode = "redirect",
   50.57 +            module = request.get_module(),
   50.58 +            view = request.get_view(),
   50.59 +            id = param.get_id_cgi(),
   50.60 +            params = param.get_all_cgi()
   50.61 +          }
   50.62 +        }
   50.63 +      }
   50.64 +    end
   50.65 +  end }
   50.66 +end)
   50.67  ui.form{
   50.68 -  attr = { class = "login" },
   50.69    module = 'index',
   50.70    action = 'login',
   50.71    routing = {
   50.72 @@ -47,22 +62,36 @@
   50.73      }
   50.74    },
   50.75    content = function()
   50.76 -    ui.field.text{
   50.77 -      attr = { id = "username_field" },
   50.78 -      label     = _'login name',
   50.79 -      html_name = 'login',
   50.80 -      value     = ''
   50.81 -    }
   50.82 -    ui.script{ script = 'document.getElementById("username_field").focus();' }
   50.83 -    ui.field.password{
   50.84 -      label     = _'Password',
   50.85 -      html_name = 'password',
   50.86 -      value     = ''
   50.87 -    }
   50.88 -    ui.submit{
   50.89 -      text = _'Login'
   50.90 -    }
   50.91 -    slot.put("&nbsp;&nbsp;")
   50.92 -    ui.link{ module = "index", view = "reset_password", text = _"Forgot password?" }
   50.93 +    ui.sectionRow(function()
   50.94 +      ui.field.text{
   50.95 +        attr = { id = "username_field" },
   50.96 +        label     = _'Login name',
   50.97 +        name = 'login',
   50.98 +        value     = ''
   50.99 +      }
  50.100 +      ui.script{ script = 'document.getElementById("username_field").focus();' }
  50.101 +      ui.field.password{
  50.102 +        label     = _'Password',
  50.103 +        name = 'password',
  50.104 +        value     = ''
  50.105 +      }
  50.106 +      ui.container { attr = { class = "actions" }, content = function()
  50.107 +        ui.tag{
  50.108 +          tag = "input",
  50.109 +          attr = {
  50.110 +            type = "submit",
  50.111 +            class = "btn btn-default",
  50.112 +            value = _'Login'
  50.113 +          },
  50.114 +          content = ""
  50.115 +        }
  50.116 +        slot.put("<br />")
  50.117 +        slot.put("<br />")
  50.118 +        ui.link{ module = "index", view = "reset_password", text = _"Forgot password?" }
  50.119 +        slot.put("&nbsp;&nbsp;")
  50.120 +        ui.link{ module = "index", view = "send_login", text = _"Forgot login name?" }
  50.121 +      end }
  50.122 +    end )
  50.123    end
  50.124  }
  50.125 +end )
  50.126 \ No newline at end of file
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/app/main/index/notifications.lua	Thu Jul 10 01:19:48 2014 +0200
    51.3 @@ -0,0 +1,14 @@
    51.4 +if app.session.member then
    51.5 +  ui.title(_"Notifications")
    51.6 +    
    51.7 +  ui.section( function() 
    51.8 +
    51.9 +    ui.sectionHead( function()
   51.10 +      ui.heading{ level = 1, content = _"Notifications" }
   51.11 +    end )
   51.12 +  
   51.13 +    ui.sectionRow( function()
   51.14 +      execute.view { module = "index", view = "_sidebar_notifications" }
   51.15 +    end ) 
   51.16 +  end )
   51.17 +end
    52.1 --- a/app/main/index/register.lua	Thu Jul 10 01:02:43 2014 +0200
    52.2 +++ b/app/main/index/register.lua	Thu Jul 10 01:19:48 2014 +0200
    52.3 @@ -7,7 +7,7 @@
    52.4  local login = param.get("login")
    52.5  
    52.6  ui.form{
    52.7 -  attr = { class = "vertical" },
    52.8 +  attr = { class = "section vertical" },
    52.9    module = 'index',
   52.10    action = 'register',
   52.11    params = {
   52.12 @@ -19,30 +19,27 @@
   52.13    content = function()
   52.14  
   52.15      if not code then
   52.16 +      ui.field.hidden{ name = "step", value = 1 }
   52.17        ui.title(_"Registration (step 1 of 3: Invite code)")
   52.18 -      ui.actions(function()
   52.19 +      ui.sectionHead( function()
   52.20 +        ui.heading { level = 1, content = _"Please enter the invite code you've received" }
   52.21 +      end )
   52.22 +      ui.sectionRow( function()
   52.23 +        ui.field.text{
   52.24 +          label = _'Invite code',
   52.25 +          name  = 'code',
   52.26 +          value = param.get("invite")
   52.27 +        }
   52.28 +        ui.submit{
   52.29 +          text = _'proceed with registration'
   52.30 +        }
   52.31 +        slot.put(" ")
   52.32          ui.link{
   52.33 -          content = function()
   52.34 -              slot.put(_"Cancel registration")
   52.35 -          end,
   52.36 +          content = _"cancel registration",
   52.37            module = "index",
   52.38            view = "index"
   52.39          }
   52.40 -      end)
   52.41 -      ui.field.hidden{ name = "step", value = 1 }
   52.42 -      ui.tag{
   52.43 -        tag = "p",
   52.44 -        content = _"Please enter the invite code you've received."
   52.45 -      }
   52.46 -      ui.field.text{
   52.47 -        label = _'Invite code',
   52.48 -        name  = 'code',
   52.49 -        value = param.get("invite")
   52.50 -      }
   52.51 -      ui.submit{
   52.52 -        text = _'Proceed with registration'
   52.53 -      }
   52.54 -
   52.55 +      end )
   52.56      else
   52.57        local member = Member:new_selector()
   52.58          :add_where{ "invite_code = ?", code }
   52.59 @@ -53,79 +50,145 @@
   52.60        if not member.notify_email and not notify_email or not member.name and not name or not member.login and not login or step == 1 then
   52.61          ui.title(_"Registration (step 2 of 3: Personal information)")
   52.62          ui.field.hidden{ name = "step", value = 2 }
   52.63 -        ui.actions(function()
   52.64 +
   52.65 +        ui.sectionHead( function()
   52.66 +          ui.heading { level = 1, content = _"Check and enter personal data" }
   52.67 +        end )
   52.68 +        ui.sectionRow( function()
   52.69 +          ui.tag{
   52.70 +            tag = "p",
   52.71 +            content = _"This invite key is connected with the following information:"
   52.72 +          }
   52.73 +          
   52.74 +          execute.view{ module = "member", view = "_profile", params = { member = member, for_registration = true } }
   52.75 +
   52.76 +          if not config.locked_profile_fields.notify_email then
   52.77 +            ui.tag{
   52.78 +              tag = "p",
   52.79 +              content = _"Please enter your email address. This address will be used for automatic notifications (if you request them) and in case you've lost your password. This address will not be published. After registration you will receive an email with a confirmation link."
   52.80 +            }
   52.81 +            ui.field.text{
   52.82 +              label     = _'Email address',
   52.83 +              name      = 'notify_email',
   52.84 +              value     = param.get("notify_email") or member.notify_email
   52.85 +            }
   52.86 +          end
   52.87 +          if not config.locked_profile_fields.name then
   52.88 +            ui.tag{
   52.89 +              tag = "p",
   52.90 +              content = _"Please choose a name, i.e. your real name or your nick name. This name will be shown to others to identify you."
   52.91 +            }
   52.92 +            ui.field.text{
   52.93 +              label     = _'Screen name',
   52.94 +              name      = 'name',
   52.95 +              value     = param.get("name") or member.name
   52.96 +            }
   52.97 +          end
   52.98 +          if not config.locked_profile_fields.login then
   52.99 +            ui.tag{
  52.100 +              tag = "p",
  52.101 +              content = _"Please choose a login name. This name will not be shown to others and is used only by you to login into the system. The login name is case sensitive."
  52.102 +            }
  52.103 +            ui.field.text{
  52.104 +              label     = _'Login name',
  52.105 +              name      = 'login',
  52.106 +              value     = param.get("login") or member.login
  52.107 +            }
  52.108 +          end
  52.109 +          ui.submit{
  52.110 +            text = _'proceed with registration'
  52.111 +          }
  52.112 +          slot.put(" ")
  52.113            ui.link{
  52.114 -            content = function()
  52.115 -                slot.put(_"One step back")
  52.116 -            end,
  52.117 +            content = _"one step back",
  52.118              module = "index",
  52.119              view = "register",
  52.120              params = {
  52.121                invite = code
  52.122              }
  52.123            }
  52.124 -          slot.put(" &middot; ")
  52.125 +          slot.put(" ")
  52.126            ui.link{
  52.127 -            content = function()
  52.128 -                slot.put(_"Cancel registration")
  52.129 -            end,
  52.130 +            content = _"cancel registration",
  52.131              module = "index",
  52.132              view = "index"
  52.133            }
  52.134 -        end)
  52.135 -
  52.136 -        ui.tag{
  52.137 -          tag = "p",
  52.138 -          content = _"This invite key is connected with the following information:"
  52.139 -        }
  52.140 -        
  52.141 -        execute.view{ module = "member", view = "_profile", params = { member = member, include_private_data = true } }
  52.142 -
  52.143 -        if not config.locked_profile_fields.notify_email then
  52.144 -          ui.tag{
  52.145 -            tag = "p",
  52.146 -            content = _"Please enter your email address. This address will be used for automatic notifications (if you request them) and in case you've lost your password. This address will not be published. After registration you will receive an email with a confirmation link."
  52.147 -          }
  52.148 -          ui.field.text{
  52.149 -            label     = _'Email address',
  52.150 -            name      = 'notify_email',
  52.151 -            value     = param.get("notify_email") or member.notify_email
  52.152 -          }
  52.153 -        end
  52.154 -        if not config.locked_profile_fields.name then
  52.155 -          ui.tag{
  52.156 -            tag = "p",
  52.157 -            content = _"Please choose a name, i.e. your real name or your nick name. This name will be shown to others to identify you."
  52.158 -          }
  52.159 -          ui.field.text{
  52.160 -            label     = _'Screen name',
  52.161 -            name      = 'name',
  52.162 -            value     = param.get("name") or member.name
  52.163 -          }
  52.164 -        end
  52.165 -        if not config.locked_profile_fields.login then
  52.166 -          ui.tag{
  52.167 -            tag = "p",
  52.168 -            content = _"Please choose a login name. This name will not be shown to others and is used only by you to login into the system. The login name is case sensitive."
  52.169 -          }
  52.170 -          ui.field.text{
  52.171 -            label     = _'Login name',
  52.172 -            name      = 'login',
  52.173 -            value     = param.get("login") or member.login
  52.174 -          }
  52.175 -        end
  52.176 -        ui.submit{
  52.177 -          text = _'Proceed with registration'
  52.178 -        }
  52.179 +        end )
  52.180        else
  52.181  
  52.182          ui.field.hidden{ name = "step", value = "3" }
  52.183          ui.title(_"Registration (step 3 of 3: Terms of use and password)")
  52.184 -        ui.actions(function()
  52.185 -          ui.link{
  52.186 +        ui.sectionHead( function()
  52.187 +          ui.heading { level = 1, content = _"Read and accept the terms and choose a password" }
  52.188 +        end )
  52.189 +        ui.sectionRow( function()
  52.190 +          ui.container{
  52.191 +            attr = { class = "wiki use_terms" },
  52.192              content = function()
  52.193 -                slot.put(_"One step back")
  52.194 -            end,
  52.195 +              slot.put(config.use_terms)
  52.196 +            end
  52.197 +          }
  52.198 +
  52.199 +          member.notify_email = notify_email or member.notify_email
  52.200 +          member.name = name or member.name
  52.201 +          member.login = login or member.login
  52.202 +          
  52.203 +          execute.view{ module = "member", view = "_profile", params = {
  52.204 +            member = member, include_private_data = true
  52.205 +          } }
  52.206 +          
  52.207 +          for i, checkbox in ipairs(config.use_terms_checkboxes) do
  52.208 +            slot.put("<br />")
  52.209 +            ui.tag{
  52.210 +              tag = "div",
  52.211 +              content = function()
  52.212 +                ui.tag{
  52.213 +                  tag = "input",
  52.214 +                  attr = {
  52.215 +                    type = "checkbox",
  52.216 +                    id = "use_terms_checkbox_" .. checkbox.name,
  52.217 +                    name = "use_terms_checkbox_" .. checkbox.name,
  52.218 +                    value = "1",
  52.219 +                    style = "float: left;",
  52.220 +                    checked = param.get("use_terms_checkbox_" .. checkbox.name, atom.boolean) and "checked" or nil
  52.221 +                  }
  52.222 +                }
  52.223 +                slot.put("&nbsp;")
  52.224 +                ui.tag{
  52.225 +                  tag = "label",
  52.226 +                  attr = { ['for'] = "use_terms_checkbox_" .. checkbox.name },
  52.227 +                  content = function() slot.put(checkbox.html) end
  52.228 +                }
  52.229 +              end
  52.230 +            }
  52.231 +          end
  52.232 +
  52.233 +          slot.put("<br />")
  52.234 +
  52.235 +          ui.tag{
  52.236 +            tag = "p",
  52.237 +            content = _"Please choose a password and enter it twice. The password is case sensitive."
  52.238 +          }
  52.239 +          ui.field.text{
  52.240 +            readonly  = true,
  52.241 +            label     = _'Login name',
  52.242 +            name      = 'login',
  52.243 +            value     = member.login
  52.244 +          }
  52.245 +          ui.field.password{
  52.246 +            label     = _'Password',
  52.247 +            name      = 'password1',
  52.248 +          }
  52.249 +          ui.field.password{
  52.250 +            label     = _'Password (repeat)',
  52.251 +            name      = 'password2',
  52.252 +          }
  52.253 +          ui.submit{
  52.254 +            text = _'activate account'
  52.255 +          }
  52.256 +          slot.put(" ")
  52.257 +          ui.link{
  52.258 +            content = _"one step back",
  52.259              module = "index",
  52.260              view = "register",
  52.261              params = {
  52.262 @@ -136,83 +199,13 @@
  52.263                step = 1
  52.264              }
  52.265            }
  52.266 -          slot.put(" &middot; ")
  52.267 +          slot.put(" ")
  52.268            ui.link{
  52.269 -            content = function()
  52.270 -                slot.put(_"Cancel registration")
  52.271 -            end,
  52.272 +            content = _"cancel registration",
  52.273              module = "index",
  52.274              view = "index"
  52.275            }
  52.276 -        end)
  52.277 -        ui.container{
  52.278 -          attr = { class = "wiki use_terms" },
  52.279 -          content = function()
  52.280 -            if config.use_terms_html then
  52.281 -              slot.put(config.use_terms_html)
  52.282 -            else
  52.283 -              slot.put(format.wiki_text(config.use_terms))
  52.284 -            end
  52.285 -          end
  52.286 -        }
  52.287 -
  52.288 -        member.notify_email = notify_email or member.notify_email
  52.289 -        member.name = name or member.name
  52.290 -        member.login = login or member.login
  52.291 -        
  52.292 -        execute.view{ module = "member", view = "_profile", params = {
  52.293 -          member = member, include_private_data = true
  52.294 -        } }
  52.295 -        
  52.296 -        for i, checkbox in ipairs(config.use_terms_checkboxes) do
  52.297 -          slot.put("<br />")
  52.298 -          ui.tag{
  52.299 -            tag = "div",
  52.300 -            content = function()
  52.301 -              ui.tag{
  52.302 -                tag = "input",
  52.303 -                attr = {
  52.304 -                  type = "checkbox",
  52.305 -                  id = "use_terms_checkbox_" .. checkbox.name,
  52.306 -                  name = "use_terms_checkbox_" .. checkbox.name,
  52.307 -                  value = "1",
  52.308 -                  style = "float: left;",
  52.309 -                  checked = param.get("use_terms_checkbox_" .. checkbox.name, atom.boolean) and "checked" or nil
  52.310 -                }
  52.311 -              }
  52.312 -              slot.put("&nbsp;")
  52.313 -              ui.tag{
  52.314 -                tag = "label",
  52.315 -                attr = { ['for'] = "use_terms_checkbox_" .. checkbox.name },
  52.316 -                content = function() slot.put(checkbox.html) end
  52.317 -              }
  52.318 -            end
  52.319 -          }
  52.320 -        end
  52.321 -
  52.322 -        slot.put("<br />")
  52.323 -
  52.324 -        ui.tag{
  52.325 -          tag = "p",
  52.326 -          content = _"Please choose a password and enter it twice. The password is case sensitive."
  52.327 -        }
  52.328 -        ui.field.text{
  52.329 -          readonly  = true,
  52.330 -          label     = _'Login name',
  52.331 -          name      = 'login',
  52.332 -          value     = member.login
  52.333 -        }
  52.334 -        ui.field.password{
  52.335 -          label     = _'Password',
  52.336 -          name      = 'password1',
  52.337 -        }
  52.338 -        ui.field.password{
  52.339 -          label     = _'Password (repeat)',
  52.340 -          name      = 'password2',
  52.341 -        }
  52.342 -        ui.submit{
  52.343 -          text = _'Activate account'
  52.344 -        }
  52.345 +        end )
  52.346        end
  52.347      end
  52.348    end
    53.1 --- a/app/main/index/reset_password.lua	Thu Jul 10 01:02:43 2014 +0200
    53.2 +++ b/app/main/index/reset_password.lua	Thu Jul 10 01:19:48 2014 +0200
    53.3 @@ -2,83 +2,123 @@
    53.4  
    53.5  ui.title(_"Reset password")
    53.6  
    53.7 -ui.actions(function()
    53.8 -  ui.link{
    53.9 -    content = function()
   53.10 -        slot.put(_"Cancel")
   53.11 -    end,
   53.12 -    module = "index",
   53.13 -    view = "login"
   53.14 -  }
   53.15 -end)
   53.16 +ui.section( function()
   53.17 +
   53.18 +  ui.sectionHead( function()
   53.19 +    ui.heading{ level = 1, content = _"Reset password" }
   53.20 +  end )
   53.21 +
   53.22 +  ui.sectionRow( function()
   53.23  
   53.24  
   53.25 -local secret = param.get("secret")
   53.26 +    local secret = param.get("secret")
   53.27  
   53.28 -if not secret then
   53.29 -  ui.tag{
   53.30 -    tag = 'p',
   53.31 -    content = _'Please enter your login name. You will receive an email with a link to reset your password.'
   53.32 -  }
   53.33 -  ui.form{
   53.34 -    attr = { class = "vertical" },
   53.35 -    module = "index",
   53.36 -    action = "reset_password",
   53.37 -    routing = {
   53.38 -      ok = {
   53.39 -        mode = "redirect",
   53.40 -        module = "index",
   53.41 -        view = "index"
   53.42 -      }
   53.43 -    },
   53.44 -    content = function()
   53.45 -      ui.field.text{ 
   53.46 -        label = _"login name",
   53.47 -        name = "login"
   53.48 -      }
   53.49 -      ui.submit{ text = _"Request password reset link" }
   53.50 -      slot.put("&nbsp;&nbsp;")
   53.51 -      ui.link{ module = "index", view = "send_login", text = _"Forgot login name?" }
   53.52 -    end
   53.53 -  }
   53.54 -
   53.55 -else
   53.56 -
   53.57 -  ui.form{
   53.58 -    attr = { class = "vertical" },
   53.59 -    module = "index",
   53.60 -    action = "reset_password",
   53.61 -    routing = {
   53.62 -      ok = {
   53.63 -        mode = "redirect",
   53.64 -        module = "index",
   53.65 -        view = "index"
   53.66 -      }
   53.67 -    },
   53.68 -    content = function()
   53.69 +    if not secret then
   53.70        ui.tag{
   53.71          tag = 'p',
   53.72 -        content = _'Please enter the email reset code you have received:'
   53.73 +        content = _'Please enter your login name. You will receive an email with a link to reset your password.'
   53.74        }
   53.75 -      ui.field.text{
   53.76 -        label = _"Reset code",
   53.77 -        name = "secret",
   53.78 -        value = secret
   53.79 -      }
   53.80 -      ui.tag{
   53.81 -        tag = 'p',
   53.82 -        content = _'Please enter your new password twice.'
   53.83 +      ui.form{
   53.84 +        attr = { class = "vertical" },
   53.85 +        module = "index",
   53.86 +        action = "reset_password",
   53.87 +        routing = {
   53.88 +          ok = {
   53.89 +            mode = "redirect",
   53.90 +            module = "index",
   53.91 +            view = "index"
   53.92 +          }
   53.93 +        },
   53.94 +        content = function()
   53.95 +          ui.field.text{ 
   53.96 +            label = _"login name",
   53.97 +            name = "login"
   53.98 +          }
   53.99 +
  53.100 +          ui.container { attr = { class = "actions" }, content = function()
  53.101 +            ui.tag{
  53.102 +              tag = "input",
  53.103 +              attr = {
  53.104 +                type = "submit",
  53.105 +                class = "btn btn-default",
  53.106 +                value = _"Request password reset link"
  53.107 +              },
  53.108 +              content = ""
  53.109 +            }
  53.110 +            slot.put("<br /><br />")
  53.111 +            ui.link{ module = "index", view = "send_login", text = _"Forgot login name?" }
  53.112 +            slot.put("&nbsp;&nbsp;")
  53.113 +            ui.link{
  53.114 +              content = function()
  53.115 +                  slot.put(_"Cancel")
  53.116 +              end,
  53.117 +              module = "index",
  53.118 +              view = "login"
  53.119 +            }
  53.120 +          end }
  53.121 +        end
  53.122        }
  53.123 -      ui.field.password{
  53.124 -        label = "New password",
  53.125 -        name = "password1"
  53.126 +
  53.127 +    else
  53.128 +
  53.129 +      ui.form{
  53.130 +        attr = { class = "vertical" },
  53.131 +        module = "index",
  53.132 +        action = "reset_password",
  53.133 +        routing = {
  53.134 +          ok = {
  53.135 +            mode = "redirect",
  53.136 +            module = "index",
  53.137 +            view = "index"
  53.138 +          }
  53.139 +        },
  53.140 +        content = function()
  53.141 +          ui.tag{
  53.142 +            tag = 'p',
  53.143 +            content = _'Please enter the email reset code you have received:'
  53.144 +          }
  53.145 +          ui.field.text{
  53.146 +            label = _"Reset code",
  53.147 +            name = "secret",
  53.148 +            value = secret
  53.149 +          }
  53.150 +          ui.tag{
  53.151 +            tag = 'p',
  53.152 +            content = _'Please enter your new password twice.'
  53.153 +          }
  53.154 +          ui.field.password{
  53.155 +            label = "New password",
  53.156 +            name = "password1"
  53.157 +          }
  53.158 +          ui.field.password{
  53.159 +            label = "New password (repeat)",
  53.160 +            name = "password2"
  53.161 +          }
  53.162 +          
  53.163 +          ui.container { attr = { class = "actions" }, content = function()
  53.164 +            ui.tag{
  53.165 +              tag = "input",
  53.166 +              attr = {
  53.167 +                type = "submit",
  53.168 +                class = "btn btn-default",
  53.169 +                value = _"Save new password"
  53.170 +              },
  53.171 +              content = ""
  53.172 +            }
  53.173 +            slot.put("<br />")
  53.174 +            slot.put("<br />")
  53.175 +
  53.176 +            ui.link{
  53.177 +              content = function()
  53.178 +                  slot.put(_"Cancel")
  53.179 +              end,
  53.180 +              module = "index",
  53.181 +              view = "login"
  53.182 +            }
  53.183 +          end }
  53.184 +        end
  53.185        }
  53.186 -      ui.field.password{
  53.187 -        label = "New password (repeat)",
  53.188 -        name = "password2"
  53.189 -      }
  53.190 -      ui.submit{ text = _"Set new password" }
  53.191 +
  53.192      end
  53.193 -  }
  53.194 -
  53.195 -end
  53.196 \ No newline at end of file
  53.197 +  end )
  53.198 +end )
  53.199 \ No newline at end of file
    54.1 --- a/app/main/index/search.lua	Thu Jul 10 01:02:43 2014 +0200
    54.2 +++ b/app/main/index/search.lua	Thu Jul 10 01:19:48 2014 +0200
    54.3 @@ -1,65 +1,104 @@
    54.4  local search_for = param.get("search_for", atom.string) or "global"
    54.5 -local search_string = param.get("search", atom.string)
    54.6 +local search_string = param.get("q", atom.string)
    54.7  
    54.8  if search_string then
    54.9 -  slot.put_into("title", encode.html(_("Search results for: '#{search}'", { search  = search_string })))
   54.10 +  ui.title ( _("Search results for: '#{search}'", { search  = search_string } ) )
   54.11  else
   54.12 -  slot.put_into("title", encode.html(_"Search"))
   54.13 +  ui.title ( _"Search" )
   54.14  end
   54.15  
   54.16  ui.form{
   54.17    method = "get", module = "index", view = "search",
   54.18    routing = { default = { mode = "redirect",
   54.19 -    module = "index", view = "search", search_for = search_for, search = search_string
   54.20 +    module = "index", view = "search", search_for = search_for, q = search_string
   54.21    } },
   54.22 -  attr = { class = "vertical" },
   54.23 +  attr = { class = "vertical section" },
   54.24    content = function()
   54.25 -    
   54.26 -    if app.session:has_access("everything") then
   54.27 -      ui.field.select{
   54.28 -        label = _"Search context",
   54.29 -        name = "search_for",
   54.30 -        value = search_for,
   54.31 -        foreign_records = {
   54.32 -          { id = "global", name = _"Global search" },
   54.33 -          { id = "member", name = _"Search for members" },
   54.34 -          { id = "issue", name = _"Search for issues" }
   54.35 -        },
   54.36 -        foreign_id = "id",
   54.37 -        foreign_name = "name",
   54.38 +  
   54.39 +    ui.sectionHead( function()
   54.40 +      ui.heading { level = 1, content = _"Search" }
   54.41 +    end)
   54.42 +  
   54.43 +    ui.sectionRow( function()
   54.44 +      ui.tag { content =  _"Search term (only complete words)" }
   54.45 +      ui.tag {
   54.46 +        tag = "input",
   54.47 +        attr = { 
   54.48 +          name = "q",
   54.49 +          value = search_string
   54.50 +        }
   54.51        }
   54.52 -    end
   54.53 -    ui.field.text{ label = _"Search term (only complete words)", name = "search", value = search_string }
   54.54 -    ui.submit{ value = _"Start search" }
   54.55 +      ui.tag{ 
   54.56 +        tag = "input",
   54.57 +        attr = { 
   54.58 +          class = "btn btn-search",
   54.59 +          type = "submit",
   54.60 +          value = _"search"
   54.61 +        }
   54.62 +      }
   54.63 +    end )
   54.64    end
   54.65  }
   54.66  
   54.67 -slot.put("<br />")
   54.68  
   54.69 -if search_string then
   54.70 +if not search_string then
   54.71 +  return
   54.72 +end
   54.73 +
   54.74  
   54.75 -  if app.session:has_access("everything") then
   54.76 -    if search_for == "global" or search_for == "member" then
   54.77 -      local members_selector = Member:get_search_selector(search_string)
   54.78 +local members_selector = Member:get_search_selector(search_string)
   54.79 +local count = members_selector:count()
   54.80 +local text
   54.81 +if count == 0 then
   54.82 +  text = _"No matching members found"
   54.83 +elseif count == 1 then
   54.84 +  text = _"1 matching member found"
   54.85 +else
   54.86 +  text = _"#{count} matching members found"
   54.87 +end
   54.88 +if app.session:has_access("everything") then
   54.89 +  ui.section( function()
   54.90 +    ui.sectionHead( function()
   54.91 +      ui.heading { level = 1, content = _(text, { count = count }) }
   54.92 +    end )
   54.93 +    if count > 0 then
   54.94        execute.view{
   54.95          module = "member",
   54.96          view = "_list",
   54.97 -        params = { members_selector = members_selector },
   54.98 +        params = {
   54.99 +          members_selector = members_selector,
  54.100 +          no_filter = true
  54.101 +        },
  54.102        }
  54.103      end
  54.104 -  end
  54.105 +  end )
  54.106 +end
  54.107 +
  54.108 +slot.put("<br />")
  54.109 +
  54.110 +local issues_selector = Issue:get_search_selector(search_string)
  54.111 +local count = issues_selector:count()
  54.112 +local text
  54.113 +if count == 0 then
  54.114 +  text = _"No matching issues found"
  54.115 +elseif count == 1 then
  54.116 +  text = _"1 matching issue found"
  54.117 +else
  54.118 +  text = _"#{count} matching issues found"
  54.119 +end
  54.120      
  54.121 -  if search_for == "global" or search_for == "issue" then
  54.122 -    local issues_selector = Issue:get_search_selector(search_string)
  54.123 +ui.section( function()
  54.124 +  ui.sectionHead( function()
  54.125 +    ui.heading { level = 1, content = _(text, { count = count }) }
  54.126 +  end )
  54.127 +  if count > 0 then
  54.128      execute.view{
  54.129        module = "issue",
  54.130 -      view = "_list",
  54.131 +      view = "_list2",
  54.132        params = {
  54.133 -        issues_selector = issues_selector,
  54.134 -        highlight_string = search_string,
  54.135 +        search = search_string,
  54.136          no_filter = true
  54.137        },
  54.138      }
  54.139    end
  54.140 -  
  54.141 -end
  54.142 +end)
    55.1 --- a/app/main/index/send_login.lua	Thu Jul 10 01:02:43 2014 +0200
    55.2 +++ b/app/main/index/send_login.lua	Thu Jul 10 01:19:48 2014 +0200
    55.3 @@ -1,35 +1,54 @@
    55.4 -ui.title(_"Request email with login name")
    55.5 +ui.title(_"Recover login name")
    55.6 +
    55.7 +ui.section( function()
    55.8  
    55.9 -ui.actions(function()
   55.10 -  ui.link{
   55.11 -    content = function()
   55.12 -        slot.put(_"Cancel")
   55.13 -    end,
   55.14 -    module = "index",
   55.15 -    view = "login"
   55.16 -  }
   55.17 -end)
   55.18 +  ui.sectionHead( function()
   55.19 +    ui.heading{ level = 1, content = _"Request email with login name" }
   55.20 +  end )
   55.21 +
   55.22 +  ui.sectionRow( function()
   55.23  
   55.24 -ui.tag{
   55.25 -  tag = 'p',
   55.26 -  content = _'Please enter your email address. You will receive an email with your login name.'
   55.27 -}
   55.28 -ui.form{
   55.29 -  attr = { class = "vertical" },
   55.30 -  module = "index",
   55.31 -  action = "send_login",
   55.32 -  routing = {
   55.33 -    ok = {
   55.34 -      mode = "redirect",
   55.35 +    ui.tag{
   55.36 +      tag = 'p',
   55.37 +      content = _'Please enter your email address. You will receive an email with your login name.'
   55.38 +    }
   55.39 +    ui.form{
   55.40 +      attr = { class = "vertical" },
   55.41        module = "index",
   55.42 -      view = "index"
   55.43 +      action = "send_login",
   55.44 +      routing = {
   55.45 +        ok = {
   55.46 +          mode = "redirect",
   55.47 +          module = "index",
   55.48 +          view = "index"
   55.49 +        }
   55.50 +      },
   55.51 +      content = function()
   55.52 +        ui.field.text{ 
   55.53 +          label = _"Email address",
   55.54 +          name = "email"
   55.55 +        }
   55.56 +
   55.57 +        ui.container { attr = { class = "actions" }, content = function()
   55.58 +          ui.tag{
   55.59 +            tag = "input",
   55.60 +            attr = {
   55.61 +              type = "submit",
   55.62 +              class = "btn btn-default",
   55.63 +              value = _"Request email with login name"
   55.64 +            },
   55.65 +            content = ""
   55.66 +          }
   55.67 +          slot.put("<br /><br />")
   55.68 +          ui.link{
   55.69 +            content = function()
   55.70 +                slot.put(_"Cancel")
   55.71 +            end,
   55.72 +            module = "index",
   55.73 +            view = "login"
   55.74 +          }
   55.75 +        end }
   55.76 +      end
   55.77      }
   55.78 -  },
   55.79 -  content = function()
   55.80 -    ui.field.text{ 
   55.81 -      label = _"Email address",
   55.82 -      name = "email"
   55.83 -    }
   55.84 -    ui.submit{ text = _"Request email with login name" }
   55.85 -  end
   55.86 -}
   55.87 +  end )
   55.88 +end )
   55.89 \ No newline at end of file
    56.1 --- a/app/main/index/usage_terms.lua	Thu Jul 10 01:02:43 2014 +0200
    56.2 +++ b/app/main/index/usage_terms.lua	Thu Jul 10 01:19:48 2014 +0200
    56.3 @@ -1,8 +1,19 @@
    56.4 -slot.put("<br />")
    56.5 +ui.title(_"Terms of use")
    56.6 +
    56.7 +ui.section( function()
    56.8 +
    56.9 +  ui.sectionHead( function()
   56.10 +    ui.heading { level = 1, content = _"Terms of use" }
   56.11 +  end )
   56.12 +
   56.13 +  ui.sectionRow( function()
   56.14  
   56.15 -ui.container{
   56.16 -  attr = { class = "wiki use_terms" },
   56.17 -  content = function()
   56.18 -    slot.put(format.wiki_text(config.use_terms))
   56.19 -  end
   56.20 -}
   56.21 +    ui.container{
   56.22 +      attr = { class = "wiki use_terms" },
   56.23 +      content = function()
   56.24 +        slot.put(config.use_terms)
   56.25 +      end
   56.26 +    }
   56.27 +
   56.28 +  end )
   56.29 +end )
   56.30 \ No newline at end of file
    57.1 --- a/app/main/initiative/_action/add_support.lua	Thu Jul 10 01:02:43 2014 +0200
    57.2 +++ b/app/main/initiative/_action/add_support.lua	Thu Jul 10 01:19:48 2014 +0200
    57.3 @@ -1,6 +1,8 @@
    57.4  local initiative = Initiative:new_selector():add_where{ "id = ?", param.get_id()}:single_object_mode():exec()
    57.5  local auto_support = param.get("auto_support", atom.boolean)
    57.6  
    57.7 +local draft_id = param.get("draft_id", atom.integer)
    57.8 +
    57.9  -- TODO important m1 selectors returning result _SET_!
   57.10  local issue = initiative:get_reference_selector("issue"):for_share():single_object_mode():exec()
   57.11  
   57.12 @@ -37,6 +39,13 @@
   57.13    :limit(1)
   57.14    :single_object_mode()
   57.15    :exec()
   57.16 +  
   57.17 +if draft_id and draft_id ~= last_draft.id then
   57.18 +  slot.select("error", function()
   57.19 +    ui.tag{ content = _"The initiative draft has been updated again in the meanwhile, support not updated!" }
   57.20 +  end)
   57.21 +  return false
   57.22 +end
   57.23  
   57.24  if not supporter then
   57.25    supporter = Supporter:new()
   57.26 @@ -47,12 +56,11 @@
   57.27      supporter.auto_support = auto_support
   57.28    end
   57.29    supporter:save()
   57.30 ---  slot.put_into("notice", _"Your support has been added to this initiative")
   57.31  elseif supporter.draft_id ~= last_draft.id then
   57.32    supporter.draft_id = last_draft.id
   57.33    supporter:save()
   57.34 ---  slot.put_into("notice", _"Your support has been updated to the latest draft")
   57.35 +  slot.put_into("notice", _"Your support has been updated to the latest draft")
   57.36  else
   57.37 ---  slot.put_into("notice", _"You are already supporting the latest draft")
   57.38 +  slot.put_into("notice", _"You are already supporting the latest draft")
   57.39  end
   57.40  
    58.1 --- a/app/main/initiative/_action/create.lua	Thu Jul 10 01:02:43 2014 +0200
    58.2 +++ b/app/main/initiative/_action/create.lua	Thu Jul 10 01:19:48 2014 +0200
    58.3 @@ -73,23 +73,32 @@
    58.4  local name = util.trim(name)
    58.5  
    58.6  if #name < 3 then
    58.7 -  slot.put_into("error", _"This name is really too short!")
    58.8 +  slot.put_into("error", _"Please enter a meaningful title for your initiative!")
    58.9 +  return false
   58.10 +end
   58.11 +
   58.12 +if #name > 140 then
   58.13 +  slot.put_into("error", _"This title is too long!")
   58.14    return false
   58.15  end
   58.16  
   58.17 -local formatting_engine = param.get("formatting_engine")
   58.18 -
   58.19 -local formatting_engine_valid = false
   58.20 -for fe, dummy in pairs(config.formatting_engine_executeables) do
   58.21 -  if formatting_engine == fe then
   58.22 -    formatting_engine_valid = true
   58.23 +local formatting_engine
   58.24 +if config.enforce_formatting_engine then
   58.25 +  formatting_engine = config.enforce_formatting_engine
   58.26 +else
   58.27 +  formatting_engine = param.get("formatting_engine")
   58.28 +  local formatting_engine_valid = false
   58.29 +  for i, fe in ipairs(config.formatting_engines) do
   58.30 +    if formatting_engine == fe.id then
   58.31 +      formatting_engine_valid = true
   58.32 +    end
   58.33 +  end
   58.34 +  if not formatting_engine_valid then
   58.35 +    error("invalid formatting engine!")
   58.36    end
   58.37  end
   58.38 -if not formatting_engine_valid then
   58.39 -  error("invalid formatting engine!")
   58.40 -end
   58.41  
   58.42 -if param.get("preview") then
   58.43 +if param.get("preview") or param.get("edit") then
   58.44    return
   58.45  end
   58.46  
   58.47 @@ -155,7 +164,6 @@
   58.48  end
   58.49  initiative.issue_id = issue.id
   58.50  initiative.name = name
   58.51 -param.update(initiative, "discussion_url")
   58.52  initiative:save()
   58.53  
   58.54  local draft = Draft:new()
    59.1 --- a/app/main/initiative/_action/remove_support.lua	Thu Jul 10 01:02:43 2014 +0200
    59.2 +++ b/app/main/initiative/_action/remove_support.lua	Thu Jul 10 01:19:48 2014 +0200
    59.3 @@ -23,7 +23,5 @@
    59.4  
    59.5  if supporter then  
    59.6    supporter:destroy()
    59.7 ---  slot.put_into("notice", _"Your support has been removed from this initiative")
    59.8  else
    59.9 ---  slot.put_into("notice", _"You are already not supporting this initiative")
   59.10  end
   59.11 \ No newline at end of file
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/app/main/initiative/_bargraph.lua	Thu Jul 10 01:19:48 2014 +0200
    60.3 @@ -0,0 +1,61 @@
    60.4 +local initiative = param.get("initiative", "table")
    60.5 +local batteled_initiative = param.get("battled_initiative", "table")
    60.6 +
    60.7 +local grey = "#eee"
    60.8 +
    60.9 +if initiative.issue.fully_frozen and initiative.issue.closed
   60.10 +   and initiative.negative_votes and initiative.positive_votes and initiative.rank ~= 1 then
   60.11 +    if not batteled_initiative then
   60.12 +      return
   60.13 +    end
   60.14 +    local battle1 = Battle:getByInitiativeIds(batteled_initiative.id, initiative.id)
   60.15 +    local battle2 = Battle:getByInitiativeIds(initiative.id, batteled_initiative.id)
   60.16 +    
   60.17 +    if not battle1 or not battle2 then
   60.18 +      return
   60.19 +    end
   60.20 +    
   60.21 +    local positive_votes = battle2.count
   60.22 +    local negative_votes = battle1.count
   60.23 +    
   60.24 +    local max_value = initiative.issue.voter_count
   60.25 +    if max_value > 0 then
   60.26 +      ui.bargraph{
   60.27 +        max_value = max_value * 2,
   60.28 +        width = 100,
   60.29 +        bars = {
   60.30 +          { color = grey, value = max_value - negative_votes },
   60.31 +          { color = "#a00", value = negative_votes },
   60.32 +          { color = "#0a0", value = positive_votes },
   60.33 +          { color = grey, value = max_value - positive_votes },
   60.34 +        }
   60.35 +      }
   60.36 +    else
   60.37 +      ui.bargraph{
   60.38 +        max_value = 1,
   60.39 +        width = 100,
   60.40 +        bars = {
   60.41 +          { color = grey, value = 1 },
   60.42 +        }
   60.43 +      }
   60.44 +    end
   60.45 +else
   60.46 +  local max_value = initiative.issue.population or 0
   60.47 +  local quorum
   60.48 +  if initiative.issue.accepted then
   60.49 +    quorum = initiative.issue.policy.initiative_quorum_num / initiative.issue.policy.initiative_quorum_den
   60.50 +  else
   60.51 +    quorum = initiative.issue.policy.issue_quorum_num / initiative.issue.policy.issue_quorum_den
   60.52 +  end
   60.53 +  ui.bargraph{
   60.54 +    max_value = max_value,
   60.55 +    width = 100,
   60.56 +    quorum = max_value * quorum,
   60.57 +    quorum_color = "#00F",
   60.58 +    bars = {
   60.59 +      { color = "#5a5", value = (initiative.satisfied_supporter_count or 0) },
   60.60 +      { color = "#fa5", value = (initiative.supporter_count or 0) - (initiative.satisfied_supporter_count or 0) },
   60.61 +      { color = grey, value = max_value - (initiative.supporter_count or 0) },
   60.62 +    }
   60.63 +  }
   60.64 +end
    61.1 --- a/app/main/initiative/_battles.lua	Thu Jul 10 01:02:43 2014 +0200
    61.2 +++ b/app/main/initiative/_battles.lua	Thu Jul 10 01:19:48 2014 +0200
    61.3 @@ -19,6 +19,7 @@
    61.4    :count()
    61.5  
    61.6  if number_of_initiatives > 1 then
    61.7 +  ui.heading { level = 1, content = _"Preference comparison" }
    61.8    ui.list{
    61.9      records = battled_initiatives,
   61.10      columns = {
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/app/main/initiative/_head.lua	Thu Jul 10 01:19:48 2014 +0200
    62.3 @@ -0,0 +1,198 @@
    62.4 +local initiative = param.get("initiative", "table")
    62.5 +local member = param.get("member", "table") or app.session.member
    62.6 +
    62.7 +-- TODO performance
    62.8 +local initiator
    62.9 +if member then
   62.10 +  initiator = Initiator:by_pk(initiative.id, member.id)
   62.11 +end
   62.12 +
   62.13 +local initiators_members_selector = initiative:get_reference_selector("initiating_members")
   62.14 +  :add_field("initiator.accepted", "accepted")
   62.15 +  :add_order_by("member.name")
   62.16 +if initiator and initiator.accepted then
   62.17 +  initiators_members_selector:add_where("initiator.accepted ISNULL OR initiator.accepted")
   62.18 +else
   62.19 +  initiators_members_selector:add_where("initiator.accepted")
   62.20 +end
   62.21 +
   62.22 +local initiators = initiators_members_selector:exec()
   62.23 +
   62.24 +
   62.25 +ui.sectionHead( "initiativeInfo", function ()
   62.26 +
   62.27 +    ui.heading { 
   62.28 +      level = 1,
   62.29 +      content = initiative.display_name
   62.30 +    }
   62.31 +
   62.32 +    ui.container { attr = { class = "support" }, content = function ()
   62.33 +      if initiative.supporter_count == nil then
   62.34 +        ui.tag { 
   62.35 +          attr = { class = "supporterCount" },
   62.36 +          content = _"[calculating]"
   62.37 +        }
   62.38 +      elseif initiative.issue.closed == nil then
   62.39 +        ui.tag { 
   62.40 +          attr = { class = "satisfiedSupporterCount" },
   62.41 +          content = _("#{count} supporter", { count = initiative.satisfied_supporter_count })
   62.42 +        }
   62.43 +        if initiative.potential_supporter_count and
   62.44 +            initiative.potential_supporter_count > 0 
   62.45 +        then
   62.46 +          slot.put ( " " )
   62.47 +          ui.tag { 
   62.48 +            attr = { class = "potentialSupporterCount" },
   62.49 +            content = _("(+ #{count} potential)", { count = initiative.potential_supporter_count })
   62.50 +          }
   62.51 +        end
   62.52 +      
   62.53 +      end 
   62.54 +      
   62.55 +      slot.put ( "<br />" )
   62.56 +      
   62.57 +      execute.view {
   62.58 +        module = "initiative", view = "_bargraph", params = {
   62.59 +          initiative = initiative
   62.60 +        }
   62.61 +      }
   62.62 +    end }
   62.63 +    
   62.64 +    if member then
   62.65 +      ui.container { attr = { class = "mySupport right" }, content = function ()
   62.66 +        if initiative.issue.fully_frozen then
   62.67 +          if initiative.issue.member_info.direct_voted then
   62.68 +            --ui.image { attr = { class = "icon48 right" }, static = "icons/48/voted_ok.png" }
   62.69 +            ui.tag { content = _"You have voted" }
   62.70 +            slot.put("<br />")
   62.71 +            if not initiative.issue.closed then
   62.72 +              ui.link {
   62.73 +                module = "vote", view = "list", 
   62.74 +                params = { issue_id = initiative.issue.id },
   62.75 +                text = _"change vote"
   62.76 +              }
   62.77 +            else
   62.78 +              ui.link {
   62.79 +                module = "vote", view = "list", 
   62.80 +                params = { issue_id = initiative.issue.id },
   62.81 +                text = _"show vote"
   62.82 +              }
   62.83 +            end
   62.84 +            slot.put(" ")
   62.85 +          elseif active_trustee_id then
   62.86 +            ui.tag { content = _"You have voted via delegation" }
   62.87 +            ui.link {
   62.88 +              content = _"Show voting ballot",
   62.89 +              module = "vote", view = "list", params = {
   62.90 +                issue_id = initiative.issue.id, member_id = active_trustee_id
   62.91 +              }
   62.92 +            }
   62.93 +          elseif not initiative.issue.closed then
   62.94 +            ui.link {
   62.95 +              attr = { class = "btn btn-default" },
   62.96 +              module = "vote", view = "list", 
   62.97 +              params = { issue_id = initiative.issue.id },
   62.98 +              text = _"vote now"
   62.99 +            }
  62.100 +          end
  62.101 +        elseif initiative.member_info.supported then
  62.102 +          if initiative.member_info.satisfied then
  62.103 +            ui.image { attr = { class = "icon48 right" }, static = "icons/32/support_satisfied.png" }
  62.104 +          else
  62.105 +            ui.image { attr = { class = "icon48 right" }, static = "icons/32/support_unsatisfied.png" }
  62.106 +          end           
  62.107 +          ui.container { content = _"You are supporter" }
  62.108 +
  62.109 +          if initiative.issue.member_info.own_participation then
  62.110 +            ui.link {
  62.111 +              attr = { class = "btn-link" },
  62.112 +              module = "initiative", action = "remove_support", 
  62.113 +              routing = { default = {
  62.114 +                mode = "redirect", module = "initiative", view = "show", id = initiative.id
  62.115 +              } },
  62.116 +              id = initiative.id,
  62.117 +              text = "remove my support"
  62.118 +            }
  62.119 +            
  62.120 +          else
  62.121 +            
  62.122 +            ui.link {
  62.123 +              module = "delegation", view = "show", params = {
  62.124 +                issue_id = initiative.issue_id,
  62.125 +                initiative_id = initiative.id
  62.126 +              },
  62.127 +              content = _"via delegation" 
  62.128 +            }
  62.129 +            
  62.130 +          end
  62.131 +          
  62.132 +          slot.put(" ")
  62.133 +      
  62.134 +
  62.135 +        else
  62.136 +          ui.link {
  62.137 +            attr = { class = "btn btn-default" },
  62.138 +            module = "initiative", action = "add_support", 
  62.139 +            routing = { default = {
  62.140 +              mode = "redirect", module = "initiative", view = "show", id = initiative.id
  62.141 +            } },
  62.142 +            id = initiative.id,
  62.143 +            text = _"add my support"
  62.144 +          }
  62.145 +            
  62.146 +        end
  62.147 +      end }
  62.148 +      
  62.149 +    end
  62.150 +    
  62.151 +    slot.put("<br style='clear: both;'/>")
  62.152 +
  62.153 +    ui.container {
  62.154 +      attr = { class = "initiators" },
  62.155 +      content = function ()
  62.156 +      
  62.157 +        if app.session:has_access("authors_pseudonymous") then
  62.158 +          for i, member in ipairs(initiators) do
  62.159 +            if i > 1 then
  62.160 +              slot.put(" ")
  62.161 +            end
  62.162 +            util.micro_avatar(member)
  62.163 +            if member.accepted == nil then
  62.164 +              slot.put ( " " )
  62.165 +              ui.tag { content = _"(invited)" }
  62.166 +            end
  62.167 +          end -- for i, member
  62.168 +          
  62.169 +        end
  62.170 +          
  62.171 +      end
  62.172 +    } -- ui.container "initiators"
  62.173 +
  62.174 +    ui.container {
  62.175 +      attr = { class = "links" },
  62.176 +      content = function ()
  62.177 +        
  62.178 +        local drafts_count = initiative:get_reference_selector("drafts"):count()
  62.179 +        ui.link {
  62.180 +          content = _("suggestions (#{count}) ↓", {
  62.181 +            count = # ( initiative.suggestions )
  62.182 +          }),
  62.183 +          external = "#suggestions"
  62.184 +        }
  62.185 +
  62.186 +        slot.put ( " | " )
  62.187 +          
  62.188 +        ui.link{
  62.189 +          module = "initiative", view = "history", id = initiative.id,
  62.190 +          content = _("draft history (#{count})", { count = drafts_count })
  62.191 +        }
  62.192 +        
  62.193 +      end
  62.194 +    } -- ui.containers "links"
  62.195 +  end )
  62.196 + 
  62.197 +  execute.view {
  62.198 +    module = "initiative", view = "_sidebar_state",
  62.199 +    params = { initiative = initiative }
  62.200 +  }
  62.201 +
    63.1 --- a/app/main/initiative/_initiators.lua	Thu Jul 10 01:02:43 2014 +0200
    63.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.3 @@ -1,58 +0,0 @@
    63.4 -local initiative = param.get("initiative", "table")
    63.5 -local initiator = param.get("initiator", "table")
    63.6 -local initiators_members_selector = param.get("initiators_members_selector", "table")
    63.7 -
    63.8 -local initiator_count = initiators_members_selector:count()
    63.9 -
   63.10 -if initiator and initiator.accepted and not initiative.issue.fully_frozen and not initiative.issue.closed and not initiative.revoked then
   63.11 -  ui.link{
   63.12 -    attr = { class = "action" },
   63.13 -    content = function()
   63.14 -      ui.image{ static = "icons/16/user_add.png" }
   63.15 -      slot.put(_"Invite initiator")
   63.16 -    end,
   63.17 -    module = "initiative",
   63.18 -    view = "add_initiator",
   63.19 -    params = { initiative_id = initiative.id }
   63.20 -  }
   63.21 -  if initiator_count > 1 then
   63.22 -    ui.link{
   63.23 -      content = function()
   63.24 -        ui.image{ static = "icons/16/user_delete.png" }
   63.25 -        slot.put(_"Remove initiator")
   63.26 -      end,
   63.27 -      module = "initiative",
   63.28 -      view = "remove_initiator",
   63.29 -      params = { initiative_id = initiative.id }
   63.30 -    }
   63.31 -  end
   63.32 -end
   63.33 -if initiator and initiator.accepted == false then
   63.34 -    ui.link{
   63.35 -      image  = { static = "icons/16/user_delete.png" },
   63.36 -      text   = _"Cancel refuse of invitation",
   63.37 -      module = "initiative",
   63.38 -      action = "remove_initiator",
   63.39 -      params = {
   63.40 -        initiative_id = initiative.id,
   63.41 -        member_id = app.session.member.id
   63.42 -      },
   63.43 -      routing = {
   63.44 -        ok = {
   63.45 -          mode = "redirect",
   63.46 -          module = "initiative",
   63.47 -          view = "show",
   63.48 -          id = initiative.id
   63.49 -        }
   63.50 -      }
   63.51 -    }
   63.52 -end
   63.53 -
   63.54 -execute.view{
   63.55 -  module = "member",
   63.56 -  view = "_list",
   63.57 -  params = {
   63.58 -    members_selector = initiators_members_selector,
   63.59 -    initiator = initiator
   63.60 -  }
   63.61 -}
    64.1 --- a/app/main/initiative/_list.lua	Thu Jul 10 01:02:43 2014 +0200
    64.2 +++ b/app/main/initiative/_list.lua	Thu Jul 10 01:19:48 2014 +0200
    64.3 @@ -1,79 +1,79 @@
    64.4 -local issue = param.get("issue", "table")
    64.5 -local initiatives_selector = param.get("initiatives_selector", "table")
    64.6 +local member = param.get("member", "table") or app.session.member
    64.7  
    64.8 -local initiatives
    64.9 -if issue then
   64.10 -  initiatives = issue.initiatives
   64.11 -else
   64.12 -  initiatives = initiatives_selector:exec()
   64.13 -  initiatives:load_everything_for_member_id(app.session.member_id)
   64.14 -end
   64.15 -
   64.16 -local highlight_initiative = param.get("highlight_initiative", "table")
   64.17 -
   64.18 -local for_member = param.get("for_member", "table") or app.session.member
   64.19 +local initiatives = param.get("initiatives", "table")
   64.20 +local highlight_initiative_id = param.get ( "highlight_initiative_id", "number" )
   64.21  
   64.22 -local limit = param.get("limit", atom.number)
   64.23 -local hide_more_initiatives = param.get("hide_more_initiatives", atom.boolean)
   64.24 +local for_initiative = param.get("initiative", "table")
   64.25  
   64.26 -local more_initiatives_count
   64.27 -if limit then
   64.28 -  if #initiatives > limit then
   64.29 -    more_initiatives_count = #initiatives - limit
   64.30 -  end
   64.31 -  initiatives = {}
   64.32 -  for i, initiative in ipairs(issue.initiatives) do
   64.33 -    if i <= limit then
   64.34 -      initiatives[#initiatives+1] = initiative
   64.35 -    end
   64.36 -  end
   64.37 -end
   64.38 +local for_event = param.get("for_event", atom.boolean)
   64.39  
   64.40 -local name = "initiative_list"
   64.41 -if issue then
   64.42 -  name = "issue_" .. tostring(issue.id) ..  "_initiative_list"
   64.43 +if for_initiative then
   64.44 +  initiatives = { for_initiative }
   64.45  end
   64.46  
   64.47 -ui.add_partial_param_names{ name }
   64.48 +ui.tag { 
   64.49 +  tag = "ul",
   64.50 +  attr = { class = "initiatives" },
   64.51 +  content = function ()
   64.52 +    local last_group
   64.53 +    for i, initiative in ipairs(initiatives) do
   64.54 +      local group
   64.55 +      if initiative.issue.closed then
   64.56 +        if initiative.rank == 1 then
   64.57 +          group = "1st_rank"
   64.58 +        elseif initiative.admitted then
   64.59 +          group = "admitted"
   64.60 +        elseif initiative.revoked_by_member_id then
   64.61 +          group = "revoked"
   64.62 +        else
   64.63 +          group = "not_admitted"
   64.64 +        end
   64.65 +      end
   64.66 +      if not for_initiative and group ~= last_group and not for_event then
   64.67  
   64.68 -if highlight_initiative then
   64.69 -  local highlight_initiative_found
   64.70 -  for i, initiative in ipairs(initiatives) do
   64.71 -    if initiative.id == highlight_initiative.id then
   64.72 -      highhighlight_initiative_found = true
   64.73 -    end
   64.74 -  end
   64.75 -  if not highhighlight_initiative_found then
   64.76 -    initiatives[#initiatives+1] = highlight_initiative
   64.77 -    if more_initiatives_count then
   64.78 -      more_initiatives_count = more_initiatives_count - 1
   64.79 +        local text
   64.80 +        if group == "admitted" then
   64.81 +          if initiative.issue.state == "finished_with_winner" then
   64.82 +            text = _"Competing initiatives in pairwise comparison to winner:"
   64.83 +          else
   64.84 +            text = _"Competing initiatives in pairwise comparison to best initiative:"
   64.85 +          end
   64.86 +        end
   64.87 +        if group == "not_admitted" then
   64.88 +          text = _("Competing initiatives failed the 2nd quorum (#{num}/#{den}):", {
   64.89 +            num = initiative.issue.policy.initiative_quorum_num,
   64.90 +            den = initiative.issue.policy.initiative_quorum_den
   64.91 +          } )
   64.92 +        end
   64.93 +        if text then
   64.94 +          slot.put("<br />")
   64.95 +          ui.container { attr = { class = "result" }, content = text }
   64.96 +        end
   64.97 +        last_group = group
   64.98 +      end
   64.99 +
  64.100 +      local class = ""
  64.101 +      if highlight_initiative_id == initiative.id then
  64.102 +        class = "highlighted"
  64.103 +      end
  64.104 +      if app.session.member then
  64.105 +        if initiative.member_info.supported then
  64.106 +          class = class .. " supported"
  64.107 +        end
  64.108 +        if initiative.member_info.satisfied then
  64.109 +          class = class .. " satisfied"
  64.110 +        end
  64.111 +      end
  64.112 +      ui.tag {
  64.113 +        tag = "li", attr = { class = class },
  64.114 +        content = function ()
  64.115 +          execute.view {
  64.116 +            module = "initiative", view = "_list_element", params = {
  64.117 +              initiative = initiative, for_event = for_event
  64.118 +            }
  64.119 +          }
  64.120 +        end
  64.121 +      }
  64.122      end
  64.123 -  end
  64.124 -end
  64.125 -for i, initiative in ipairs(initiatives) do
  64.126 -  execute.view{
  64.127 -    module = "initiative",
  64.128 -    view = "_list_element",
  64.129 -    params = {
  64.130 -      initiative = initiative,
  64.131 -      selected = highlight_initiative and highlight_initiative.id == initiative.id or nil,
  64.132 -      for_member = for_member
  64.133 -    }
  64.134 -  }
  64.135 -end
  64.136 -
  64.137 -if not hide_more_initiatives and more_initiatives_count and more_initiatives_count > 0 then
  64.138 -  local text
  64.139 -  if more_initiatives_count == 1 then
  64.140 -    text = _("and one more initiative")
  64.141 -  else
  64.142 -    text = _("and #{count} more initiatives", { count = more_initiatives_count })
  64.143 -  end
  64.144 -  ui.link{
  64.145 -    attr = { class = "more_initiatives_link" },
  64.146 -    content = text,
  64.147 -    module = "issue",
  64.148 -    view = "show",
  64.149 -    id = issue.id,
  64.150 -  }
  64.151 -end
  64.152 +  end 
  64.153 +}
  64.154 \ No newline at end of file
    65.1 --- a/app/main/initiative/_list_element.lua	Thu Jul 10 01:02:43 2014 +0200
    65.2 +++ b/app/main/initiative/_list_element.lua	Thu Jul 10 01:19:48 2014 +0200
    65.3 @@ -1,152 +1,110 @@
    65.4  local initiative = param.get("initiative", "table")
    65.5 -local selected = param.get("selected", atom.boolean)
    65.6 -local for_member = param.get("for_member", "table") or app.session.member
    65.7 +local for_event = param.get("for_event", atom.boolean)
    65.8 +
    65.9 +local issue = initiative.issue
   65.10  
   65.11  local class = "initiative"
   65.12  
   65.13 -if selected then
   65.14 -  class = class .. " selected"
   65.15 +if initiative.rank == 1 then
   65.16 +  class = class .. " rank1"
   65.17  end
   65.18  
   65.19 -if initiative.polling then
   65.20 -  class = class .. " polling"
   65.21 +if initiative.revoked then
   65.22 +  class = class .. " revoked"
   65.23  end
   65.24  
   65.25 -ui.container{ attr = { class = class }, content = function()
   65.26 -
   65.27 -  ui.container{ attr = { class = "rank" }, content = function()
   65.28 -    if initiative.issue.fully_frozen and initiative.issue.closed
   65.29 -      or initiative.admitted == false
   65.30 -    then 
   65.31 -      ui.field.rank{ attr = { class = "rank" }, value = initiative.rank, eligible = initiative.eligible }
   65.32 -    elseif not initiative.issue.closed then
   65.33 -      ui.image{ static = "icons/16/script.png" }
   65.34 -    else
   65.35 -      ui.image{ static = "icons/16/cross.png" }
   65.36 -    end
   65.37 -  end }
   65.38 -
   65.39 -  ui.container{ attr = { class = "bar" }, content = function()
   65.40 -    if initiative.issue.fully_frozen and initiative.issue.closed then
   65.41 -      if initiative.negative_votes and initiative.positive_votes then
   65.42 -        local max_value = initiative.issue.voter_count
   65.43 -        ui.bargraph{
   65.44 -          max_value = max_value,
   65.45 -          width = 100,
   65.46 -          bars = {
   65.47 -            { color = "#0a5", value = initiative.positive_votes },
   65.48 -            { color = "#aaa", value = max_value - initiative.negative_votes - initiative.positive_votes },
   65.49 -            { color = "#a00", value = initiative.negative_votes },
   65.50 -          }
   65.51 -        }
   65.52 -      else
   65.53 -         slot.put("&nbsp;")
   65.54 -      end
   65.55 -    else
   65.56 -      local max_value = initiative.issue.population or 0
   65.57 -      local quorum
   65.58 -      if initiative.issue.accepted then
   65.59 -        quorum = initiative.issue.policy.initiative_quorum_num / initiative.issue.policy.initiative_quorum_den
   65.60 -      else
   65.61 -        quorum = initiative.issue.policy.issue_quorum_num / initiative.issue.policy.issue_quorum_den
   65.62 -      end
   65.63 -      ui.bargraph{
   65.64 -        max_value = max_value,
   65.65 -        width = 100,
   65.66 -        quorum = max_value * quorum,
   65.67 -        quorum_color = "#00F",
   65.68 -        bars = {
   65.69 -          { color = "#0a5", value = (initiative.satisfied_supporter_count or 0) },
   65.70 -          { color = "#aaa", value = (initiative.supporter_count or 0) - (initiative.satisfied_supporter_count or 0) },
   65.71 -          { color = "#fff", value = max_value - (initiative.supporter_count or 0) },
   65.72 +ui.container{
   65.73 +  attr = { class = class },
   65.74 +  content = function ()
   65.75 +    if initiative.rank ~= 1 and not for_event then
   65.76 +      execute.view {
   65.77 +        module = "initiative", view = "_bargraph", params = {
   65.78 +          initiative = initiative,
   65.79 +          battled_initiative = issue.initiatives[1]
   65.80          }
   65.81        }
   65.82 +      slot.put(" ")
   65.83      end
   65.84 -  end }
   65.85 -
   65.86 -  if app.session.member_id then
   65.87 -    ui.container{ attr = { class = "interest" }, content = function()
   65.88 -      if initiative.member_info.initiated then
   65.89 -        local label 
   65.90 -        if for_member and for_member.id ~= app.session.member_id then
   65.91 -          label = _"This member is initiator of this initiative"
   65.92 -        else
   65.93 -          label = _"You are initiator of this initiative"
   65.94 -        end
   65.95 -        ui.image{
   65.96 -          attr = { alt = label, title = label },
   65.97 -          static = "icons/16/user_edit.png"
   65.98 +    ui.tag {
   65.99 +      attr = { class = "initiative_name" },
  65.100 +      content = function()
  65.101 +        ui.link {
  65.102 +          text = initiative.display_name,
  65.103 +          module = "initiative", view = "show", id = initiative.id
  65.104          }
  65.105 -      elseif initiative.member_info.directly_supported then
  65.106 -        if initiative.member_info.satisfied then
  65.107 -          if for_member and for_member.id ~= app.session.member_id then
  65.108 -            label = _"This member is supporter of this initiative"
  65.109 -          else
  65.110 -            local label = _"You are supporter of this initiative"
  65.111 +        slot.put(" ")
  65.112 +        if initiative.vote_grade ~= nil then
  65.113 +          if initiative.vote_grade > 0 then
  65.114 +            local text = _"voted yes"
  65.115 +            ui.image { attr = { class = "icon16", title = text, alt = text }, static = "icons/32/support_satisfied.png" }
  65.116 +          elseif initiative.vote_grade == 0 then
  65.117 +          elseif initiative.vote_grade < 0 then
  65.118 +            local text = _"voted no"
  65.119 +            ui.image { attr = { class = "icon16", title = text, alt = text }, static = "icons/32/voted_no.png" }
  65.120            end
  65.121 -          ui.image{
  65.122 -            attr = { alt = label, title = label },
  65.123 -            static = "icons/16/thumb_up_green.png"
  65.124 -          }
  65.125 -        else
  65.126 -          if for_member and for_member.id ~= app.session.member_id then
  65.127 -            label = _"This member is potential supporter of this initiative"
  65.128 -          else
  65.129 -            local label = _"You are potential supporter of this initiative"
  65.130 +        elseif app.session.member then
  65.131 +          if initiative.member_info.supported then
  65.132 +            if initiative.member_info.satisfied then
  65.133 +              local text = _"supporter"
  65.134 +              ui.image { attr = { class = "icon16", title = text, alt = text }, static = "icons/32/support_satisfied.png" }
  65.135 +            else
  65.136 +              local text = _"supporter with restricting suggestions"
  65.137 +              ui.image { attr = { class = "icon16", title = text, alt = text }, static = "icons/32/support_unsatisfied.png" }
  65.138 +            end           
  65.139            end
  65.140 -          ui.image{
  65.141 -            attr = { alt = label, title = label },
  65.142 -            static = "icons/16/thumb_up.png"
  65.143 -          }
  65.144 -        end
  65.145 -      elseif initiative.member_info.supported then
  65.146 -        if initiative.member_info.satisfied then
  65.147 -          if for_member and for_member.id ~= app.session.member_id then
  65.148 -            label = _"This member is supporter of this initiative via delegation"
  65.149 -          else
  65.150 -            local label = _"You are supporter of this initiative via delegation"
  65.151 -          end
  65.152 -          ui.image{
  65.153 -            attr = { alt = label, title = label },
  65.154 -            static = "icons/16/thumb_up_green_arrow.png"
  65.155 -          }
  65.156 -        else
  65.157 -          if for_member and for_member.id ~= app.session.member_id then
  65.158 -            label = _"This member is potential supporter of this initiative via delegation"
  65.159 -          else
  65.160 -            local label = _"You are potential supporter of this initiative via delegation"
  65.161 -          end
  65.162 -          ui.image{
  65.163 -            attr = { alt = label, title = label },
  65.164 -            static = "icons/16/thumb_up_arrow.png"
  65.165 -          }
  65.166          end
  65.167        end
  65.168 -    end }
  65.169 +    }
  65.170 +
  65.171    end
  65.172 -    
  65.173 -  ui.container{ attr = { class = "name" }, content = function()
  65.174 -    local link_class = "initiative_link"
  65.175 -    if initiative.revoked then
  65.176 -      link_class = "revoked"
  65.177 +}
  65.178 +
  65.179 +if initiative.rank == 1 
  65.180 +  and issue.voter_count 
  65.181 +  and initiative.positive_votes ~= nil 
  65.182 +  and initiative.negative_votes ~= nil 
  65.183 +  and not for_event
  65.184 +then
  65.185 +  function percent(p, q)
  65.186 +    if q > 0 then
  65.187 +      return math.floor(p / q * 100) .. "%"
  65.188 +    else
  65.189 +      return "0%"
  65.190      end
  65.191 -    ui.link{
  65.192 -      attr = { class = link_class },
  65.193 -      content = function()
  65.194 -        local name
  65.195 -        if initiative.name_highlighted then
  65.196 -          name = encode.highlight(initiative.name_highlighted)
  65.197 -        else
  65.198 -          name = encode.html(initiative.shortened_name)
  65.199 -        end
  65.200 -        ui.tag{ content = "i" .. initiative.id .. ": " }
  65.201 -        slot.put(name)
  65.202 -      end,
  65.203 -      module  = "initiative",
  65.204 -      view    = "show",
  65.205 -      id      = initiative.id
  65.206 -    }
  65.207 -        
  65.208 -  end }
  65.209 +  end
  65.210 +  local result = ""
  65.211 +  if initiative.eligible then
  65.212 +    result = _("Reached #{sign}#{num}/#{den}", {
  65.213 +      sign = issue.policy.direct_majority_strict and ">" or "≥",
  65.214 +      num = issue.policy.direct_majority_num,
  65.215 +      den = issue.policy.direct_majority_den
  65.216 +    })
  65.217 +  else
  65.218 +    result = _("Failed  #{sign}#{num}/#{den}", {
  65.219 +      sign = issue.policy.direct_majority_strict and ">" or "≥",
  65.220 +      num = issue.policy.direct_majority_num,
  65.221 +      den = issue.policy.direct_majority_den
  65.222 +    })
  65.223 +  end
  65.224 +  local neutral_count = issue.voter_count - initiative.positive_votes - initiative.negative_votes
  65.225 +  
  65.226 +  local result_text 
  65.227 +  
  65.228 +  if issue.voter_count > 0 then
  65.229 +    result_text = _("#{result}: #{yes_count} Yes (#{yes_percent}), #{no_count} No (#{no_percent}), #{neutral_count} Abstention (#{neutral_percent})", {
  65.230 +      result = result,
  65.231 +      yes_count = initiative.positive_votes,
  65.232 +      yes_percent = percent(initiative.positive_votes, issue.voter_count),
  65.233 +      neutral_count = neutral_count,
  65.234 +      neutral_percent = percent(neutral_count, issue.voter_count),
  65.235 +      no_count = initiative.negative_votes,
  65.236 +      no_percent = percent(initiative.negative_votes, issue.voter_count)
  65.237 +    })
  65.238 +  else
  65.239 +    result_text = _("#{result}: No votes (0)", { result = result })
  65.240 +  end
  65.241 +  
  65.242 +  ui.container { attr = { class = "result" }, content = result_text }
  65.243  
  65.244 -end }
  65.245 +end
  65.246 +      
    66.1 --- a/app/main/initiative/_show.lua	Thu Jul 10 01:02:43 2014 +0200
    66.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.3 @@ -1,531 +0,0 @@
    66.4 -local initiative = param.get("initiative", "table")
    66.5 -
    66.6 -local show_as_head = param.get("show_as_head", atom.boolean)
    66.7 -
    66.8 -initiative:load_everything_for_member_id(app.session.member_id)
    66.9 -
   66.10 -local issue = initiative.issue
   66.11 -
   66.12 --- TODO performance
   66.13 -local initiator
   66.14 -if app.session.member_id then
   66.15 -  initiator = Initiator:by_pk(initiative.id, app.session.member.id)
   66.16 -end
   66.17 -
   66.18 -if app.session.member_id then
   66.19 -  issue:load_everything_for_member_id(app.session.member_id)
   66.20 -end
   66.21 -
   66.22 -app.html_title.title = initiative.name
   66.23 -app.html_title.subtitle = _("Initiative ##{id}", { id = initiative.id })
   66.24 -
   66.25 -slot.select("head", function()
   66.26 -  execute.view{
   66.27 -    module = "issue", view = "_head",
   66.28 -    params = { issue = issue, initiative = initiative }
   66.29 -  }
   66.30 -end)
   66.31 -  
   66.32 -local initiators_members_selector = initiative:get_reference_selector("initiating_members")
   66.33 -  :add_field("initiator.accepted", "accepted")
   66.34 -  :add_order_by("member.name")
   66.35 -if initiator and initiator.accepted then
   66.36 -  initiators_members_selector:add_where("initiator.accepted ISNULL OR initiator.accepted")
   66.37 -else
   66.38 -  initiators_members_selector:add_where("initiator.accepted")
   66.39 -end
   66.40 -
   66.41 -local initiators = initiators_members_selector:exec()
   66.42 -
   66.43 -
   66.44 -local initiatives_selector = initiative.issue:get_reference_selector("initiatives")
   66.45 -slot.select("head", function()
   66.46 -  execute.view{
   66.47 -    module = "issue",
   66.48 -    view = "_show",
   66.49 -    params = {
   66.50 -      issue = initiative.issue,
   66.51 -      initiative_limit = 3,
   66.52 -      for_initiative = initiative
   66.53 -    }
   66.54 -  }
   66.55 -end)
   66.56 -
   66.57 -util.help("initiative.show")
   66.58 -
   66.59 -local class = "initiative_head"
   66.60 -
   66.61 -if initiative.polling then
   66.62 -  class = class .. " polling"
   66.63 -end
   66.64 -
   66.65 -ui.container{ attr = { class = class }, content = function()
   66.66 -
   66.67 -  local text = _("Initiative i#{id}: #{name}", { id = initiative.id, name = initiative.name }) 
   66.68 -  if show_as_head then
   66.69 -    ui.link{
   66.70 -      attr = { class = "title" }, text = text,
   66.71 -      module = "initiative", view = "show", id = initiative.id
   66.72 -    }
   66.73 -  else
   66.74 -    ui.container{ attr = { class = "title" }, content = text }
   66.75 -  end
   66.76 -  if app.session:has_access("authors_pseudonymous") then
   66.77 -    ui.container{ attr = { class = "content" }, content = function()
   66.78 -      ui.tag{
   66.79 -        attr = { class = "initiator_names" },
   66.80 -        content = function()
   66.81 -          for i, initiator in ipairs(initiators) do
   66.82 -            slot.put(" ")
   66.83 -            if app.session:has_access("all_pseudonymous") then
   66.84 -              ui.link{
   66.85 -                content = function ()
   66.86 -                  execute.view{
   66.87 -                    module = "member_image",
   66.88 -                    view = "_show",
   66.89 -                    params = {
   66.90 -                      member = initiator,
   66.91 -                      image_type = "avatar",
   66.92 -                      show_dummy = true,
   66.93 -                      class = "micro_avatar",
   66.94 -                      popup_text = text
   66.95 -                    }
   66.96 -                  }
   66.97 -                end,
   66.98 -                module = "member", view = "show", id = initiator.id
   66.99 -              }
  66.100 -              slot.put(" ")
  66.101 -            end
  66.102 -            ui.link{
  66.103 -              text = initiator.name,
  66.104 -              module = "member", view = "show", id = initiator.id
  66.105 -            }
  66.106 -            if not initiator.accepted then
  66.107 -              ui.tag{ attr = { title = _"Not accepted yet" }, content = "?" }
  66.108 -            end
  66.109 -          end
  66.110 -          if initiator and initiator.accepted and not initiative.issue.fully_frozen and not initiative.issue.closed and not initiative.revoked then
  66.111 -            slot.put(" &middot; ")
  66.112 -            ui.link{
  66.113 -              attr = { class = "action" },
  66.114 -              content = function()
  66.115 -                slot.put(_"Invite initiator")
  66.116 -              end,
  66.117 -              module = "initiative",
  66.118 -              view = "add_initiator",
  66.119 -              params = { initiative_id = initiative.id }
  66.120 -            }
  66.121 -            if #initiators > 1 then
  66.122 -              slot.put(" &middot; ")
  66.123 -              ui.link{
  66.124 -                content = function()
  66.125 -                  slot.put(_"Remove initiator")
  66.126 -                end,
  66.127 -                module = "initiative",
  66.128 -                view = "remove_initiator",
  66.129 -                params = { initiative_id = initiative.id }
  66.130 -              }
  66.131 -            end
  66.132 -          end
  66.133 -          if initiator and initiator.accepted == false then
  66.134 -              slot.put(" &middot; ")
  66.135 -              ui.link{
  66.136 -                text   = _"Cancel refuse of invitation",
  66.137 -                module = "initiative",
  66.138 -                action = "remove_initiator",
  66.139 -                params = {
  66.140 -                  initiative_id = initiative.id,
  66.141 -                  member_id = app.session.member.id
  66.142 -                },
  66.143 -                routing = {
  66.144 -                  ok = {
  66.145 -                    mode = "redirect",
  66.146 -                    module = "initiative",
  66.147 -                    view = "show",
  66.148 -                    id = initiative.id
  66.149 -                  }
  66.150 -                }
  66.151 -              }
  66.152 -          end
  66.153 -          if (initiative.discussion_url and #initiative.discussion_url > 0) then
  66.154 -            slot.put(" &middot; ")
  66.155 -            if initiative.discussion_url:find("^https?://") then
  66.156 -              if initiative.discussion_url and #initiative.discussion_url > 0 then
  66.157 -                ui.link{
  66.158 -                  attr = {
  66.159 -                    target = "_blank",
  66.160 -                    title = _"Discussion with initiators"
  66.161 -                  },
  66.162 -                  text = _"Discuss with initiators",
  66.163 -                  external = initiative.discussion_url
  66.164 -                }
  66.165 -              end
  66.166 -            else
  66.167 -              slot.put(encode.html(initiative.discussion_url))
  66.168 -            end
  66.169 -          end
  66.170 -          if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then
  66.171 -            slot.put(" &middot; ")
  66.172 -            ui.link{
  66.173 -              text   = _"change discussion URL",
  66.174 -              module = "initiative",
  66.175 -              view   = "edit",
  66.176 -              id     = initiative.id
  66.177 -            }
  66.178 -            slot.put(" ")
  66.179 -          end
  66.180 -        end
  66.181 -      }
  66.182 -    end }
  66.183 -  end
  66.184 -
  66.185 -  if app.session.member_id then
  66.186 -    ui.container{ attr = { class = "content" }, content = function()
  66.187 -      execute.view{
  66.188 -        module = "supporter",
  66.189 -        view = "_show_box",
  66.190 -        params = {
  66.191 -          initiative = initiative
  66.192 -        }
  66.193 -      }
  66.194 -    end }
  66.195 -  end
  66.196 -
  66.197 -  
  66.198 -  -- voting results
  66.199 -  if initiative.issue.fully_frozen and initiative.issue.closed and initiative.admitted then
  66.200 -    local class = initiative.winner and "admitted_info" or "not_admitted_info"
  66.201 -    ui.container{
  66.202 -      attr = { class = class },
  66.203 -      content = function()
  66.204 -        local max_value = initiative.issue.voter_count
  66.205 -        slot.put("&nbsp;")
  66.206 -        local positive_votes = initiative.positive_votes
  66.207 -        local negative_votes = initiative.negative_votes
  66.208 -        local sum_votes = initiative.positive_votes + initiative.negative_votes
  66.209 -        local function perc(votes, sum)
  66.210 -          if sum > 0 and votes > 0 then return " (" .. string.format( "%.f", votes * 100 / sum ) .. "%)" end
  66.211 -          return ""
  66.212 -        end
  66.213 -        slot.put(_"Yes" .. ": <b>" .. tostring(positive_votes) .. perc(positive_votes, sum_votes) .. "</b>")
  66.214 -        slot.put(" &middot; ")
  66.215 -        slot.put(_"Abstention" .. ": <b>" .. tostring(max_value - initiative.negative_votes - initiative.positive_votes)  .. "</b>")
  66.216 -        slot.put(" &middot; ")
  66.217 -        slot.put(_"No" .. ": <b>" .. tostring(initiative.negative_votes) .. perc(negative_votes, sum_votes) .. "</b>")
  66.218 -        slot.put(" &middot; ")
  66.219 -        slot.put("<b>")
  66.220 -        if initiative.winner then
  66.221 -          slot.put(_"Approved")
  66.222 -        elseif initiative.rank then
  66.223 -          slot.put(_("Not approved (rank #{rank})", { rank = initiative.rank }))
  66.224 -        else
  66.225 -          slot.put(_"Not approved")
  66.226 -        end
  66.227 -        slot.put("</b>")
  66.228 -      end
  66.229 -    }
  66.230 -  end
  66.231 -
  66.232 -  ui.container{ attr = { class = "content" }, content = function()
  66.233 -    execute.view{
  66.234 -      module = "initiative",
  66.235 -      view = "_battles",
  66.236 -      params = { initiative = initiative }
  66.237 -    }
  66.238 -  end }
  66.239 -    
  66.240 -  -- initiative not admitted info
  66.241 -  if initiative.admitted == false then
  66.242 -    local policy = initiative.issue.policy
  66.243 -    ui.container{
  66.244 -      attr = { class = "not_admitted_info" },
  66.245 -      content = _("This initiative has not been admitted! It failed the quorum of #{quorum}.", { quorum = format.percentage(policy.initiative_quorum_num / policy.initiative_quorum_den) })
  66.246 -    }
  66.247 -  end
  66.248 -
  66.249 -  -- initiative revoked info
  66.250 -  if initiative.revoked then
  66.251 -    ui.container{
  66.252 -      attr = { class = "revoked_info" },
  66.253 -      content = function()
  66.254 -        slot.put(_("This initiative has been revoked at #{revoked}", { revoked = format.timestamp(initiative.revoked) }))
  66.255 -        local suggested_initiative = initiative.suggested_initiative
  66.256 -        if suggested_initiative then
  66.257 -          slot.put("<br /><br />")
  66.258 -          slot.put(_("The initiators suggest to support the following initiative:"))
  66.259 -          slot.put(" ")
  66.260 -          ui.link{
  66.261 -            content = _("Issue ##{id}", { id = suggested_initiative.issue.id } ) .. ": " .. encode.html(suggested_initiative.name),
  66.262 -            module = "initiative",
  66.263 -            view = "show",
  66.264 -            id = suggested_initiative.id
  66.265 -          }
  66.266 -        end
  66.267 -      end
  66.268 -    }
  66.269 -  end
  66.270 -
  66.271 -
  66.272 -  -- invited as initiator
  66.273 -  if initiator and initiator.accepted == nil and not initiative.issue.half_frozen and not initiative.issue.closed then
  66.274 -    ui.container{
  66.275 -      attr = { class = "initiator_invite_info" },
  66.276 -      content = function()
  66.277 -        slot.put(_"You are invited to become initiator of this initiative.")
  66.278 -        slot.put(" ")
  66.279 -        ui.link{
  66.280 -          image  = { static = "icons/16/tick.png" },
  66.281 -          text   = _"Accept invitation",
  66.282 -          module = "initiative",
  66.283 -          action = "accept_invitation",
  66.284 -          id     = initiative.id,
  66.285 -          routing = {
  66.286 -            default = {
  66.287 -              mode = "redirect",
  66.288 -              module = request.get_module(),
  66.289 -              view = request.get_view(),
  66.290 -              id = param.get_id_cgi(),
  66.291 -              params = param.get_all_cgi()
  66.292 -            }
  66.293 -          }
  66.294 -        }
  66.295 -        slot.put(" ")
  66.296 -        ui.link{
  66.297 -          image  = { static = "icons/16/cross.png" },
  66.298 -          text   = _"Refuse invitation",
  66.299 -          module = "initiative",
  66.300 -          action = "reject_initiator_invitation",
  66.301 -          params = {
  66.302 -            initiative_id = initiative.id,
  66.303 -            member_id = app.session.member.id
  66.304 -          },
  66.305 -          routing = {
  66.306 -            default = {
  66.307 -              mode = "redirect",
  66.308 -              module = request.get_module(),
  66.309 -              view = request.get_view(),
  66.310 -              id = param.get_id_cgi(),
  66.311 -              params = param.get_all_cgi()
  66.312 -            }
  66.313 -          }
  66.314 -        }
  66.315 -      end
  66.316 -    }
  66.317 -  end
  66.318 -
  66.319 -  -- draft updated
  66.320 -  local supporter
  66.321 -
  66.322 -  if app.session.member_id then
  66.323 -    supporter = app.session.member:get_reference_selector("supporters")
  66.324 -      :add_where{ "initiative_id = ?", initiative.id }
  66.325 -      :optional_object_mode()
  66.326 -      :exec()
  66.327 -  end
  66.328 -
  66.329 -  if supporter and not initiative.issue.closed then
  66.330 -    local old_draft_id = supporter.draft_id
  66.331 -    local new_draft_id = initiative.current_draft.id
  66.332 -    if old_draft_id ~= new_draft_id then
  66.333 -      ui.container{
  66.334 -        attr = { class = "draft_updated_info" },
  66.335 -        content = function()
  66.336 -          slot.put(_"The draft of this initiative has been updated!")
  66.337 -          slot.put(" ")
  66.338 -          ui.link{
  66.339 -            content = _"Show diff",
  66.340 -            module = "draft",
  66.341 -            view = "diff",
  66.342 -            params = {
  66.343 -              old_draft_id = old_draft_id,
  66.344 -              new_draft_id = new_draft_id
  66.345 -            }
  66.346 -          }
  66.347 -          if not initiative.revoked then
  66.348 -            slot.put(" ")
  66.349 -            ui.link{
  66.350 -              text   = _"Refresh support to current draft",
  66.351 -              module = "initiative",
  66.352 -              action = "add_support",
  66.353 -              id     = initiative.id,
  66.354 -              routing = {
  66.355 -                default = {
  66.356 -                  mode = "redirect",
  66.357 -                  module = "initiative",
  66.358 -                  view = "show",
  66.359 -                  id = initiative.id
  66.360 -                }
  66.361 -              }
  66.362 -            }
  66.363 -          end
  66.364 -        end
  66.365 -      }
  66.366 -    end
  66.367 -  end
  66.368 -
  66.369 -  if not show_as_head then
  66.370 -    local drafts_count = initiative:get_reference_selector("drafts"):count()
  66.371 -
  66.372 -    ui.container{ attr = { class = "content" }, content = function()
  66.373 -    
  66.374 -      if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then
  66.375 -        ui.link{
  66.376 -          content = function()
  66.377 -            slot.put(_"Edit draft")
  66.378 -          end,
  66.379 -          module = "draft",
  66.380 -          view = "new",
  66.381 -          params = { initiative_id = initiative.id }
  66.382 -        }
  66.383 -        slot.put(" &middot; ")
  66.384 -        ui.link{
  66.385 -          content = function()
  66.386 -            slot.put(_"Revoke initiative")
  66.387 -          end,
  66.388 -          module = "initiative",
  66.389 -          view = "revoke",
  66.390 -          id = initiative.id
  66.391 -        }
  66.392 -        slot.put(" &middot; ")
  66.393 -      end
  66.394 -
  66.395 -      ui.tag{
  66.396 -        attr = { class = "draft_version" },
  66.397 -        content = _("Latest draft created at #{date} #{time}", {
  66.398 -          date = format.date(initiative.current_draft.created),
  66.399 -          time = format.time(initiative.current_draft.created)
  66.400 -        })
  66.401 -      }
  66.402 -      if drafts_count > 1 then
  66.403 -        slot.put(" &middot; ")
  66.404 -        ui.link{
  66.405 -          module = "draft", view = "list", params = { initiative_id = initiative.id },
  66.406 -          text = _("List all revisions (#{count})", { count = drafts_count })
  66.407 -        }
  66.408 -      end
  66.409 -    end }
  66.410 -
  66.411 -    execute.view{
  66.412 -      module = "draft",
  66.413 -      view = "_show",
  66.414 -      params = {
  66.415 -        draft = initiative.current_draft
  66.416 -      }
  66.417 -    }
  66.418 -  end
  66.419 -end }
  66.420 -
  66.421 -if not show_as_head then
  66.422 -  execute.view{
  66.423 -    module = "suggestion",
  66.424 -    view = "_list",
  66.425 -    params = {
  66.426 -      initiative = initiative,
  66.427 -      suggestions_selector = initiative:get_reference_selector("suggestions"),
  66.428 -      tab_id = param.get("tab_id")
  66.429 -    }
  66.430 -  }
  66.431 -
  66.432 -
  66.433 -  if app.session:has_access("all_pseudonymous") then
  66.434 -    if initiative.issue.fully_frozen and initiative.issue.closed then
  66.435 -      local members_selector = initiative.issue:get_reference_selector("direct_voters")
  66.436 -            :left_join("vote", nil, { "vote.initiative_id = ? AND vote.member_id = member.id", initiative.id })
  66.437 -            :add_field("direct_voter.weight as voter_weight")
  66.438 -            :add_field("coalesce(vote.grade, 0) as grade")
  66.439 -            :add_field("direct_voter.comment as voter_comment")
  66.440 -            :left_join("initiative", nil, "initiative.id = vote.initiative_id")
  66.441 -            :left_join("issue", nil, "issue.id = initiative.issue_id")
  66.442 -      
  66.443 -      ui.anchor{ name = "voter", attr = { class = "heading" }, content = _"Voters" }
  66.444 -      
  66.445 -      execute.view{
  66.446 -        module = "member",
  66.447 -        view = "_list",
  66.448 -        params = {
  66.449 -          initiative = initiative,
  66.450 -          for_votes = true,
  66.451 -          members_selector = members_selector,
  66.452 -          paginator_name = "voter"
  66.453 -        }
  66.454 -      }
  66.455 -    end
  66.456 -    
  66.457 -    local members_selector = initiative:get_reference_selector("supporting_members_snapshot")
  66.458 -              :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id")
  66.459 -              :join("direct_interest_snapshot", nil, "direct_interest_snapshot.event = issue.latest_snapshot_event AND direct_interest_snapshot.issue_id = issue.id AND direct_interest_snapshot.member_id = member.id")
  66.460 -              :add_field("direct_interest_snapshot.weight")
  66.461 -              :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event")
  66.462 -              :add_where("direct_supporter_snapshot.satisfied")
  66.463 -              :add_field("direct_supporter_snapshot.informed", "is_informed")
  66.464 -
  66.465 -    if members_selector:count() > 0 then
  66.466 -      if issue.fully_frozen then
  66.467 -        ui.anchor{ name = "supporters", attr = { class = "heading" }, content = _"Supporters (before begin of voting)" }
  66.468 -      else
  66.469 -        ui.anchor{ name = "supporters", attr = { class = "heading" }, content = _"Supporters" }
  66.470 -      end      
  66.471 -      
  66.472 -      execute.view{
  66.473 -        module = "member",
  66.474 -        view = "_list",
  66.475 -        params = {
  66.476 -          initiative = initiative,
  66.477 -          members_selector = members_selector,
  66.478 -          paginator_name = "supporters"
  66.479 -        }
  66.480 -    }
  66.481 -    else
  66.482 -      if issue.fully_frozen then
  66.483 -        ui.anchor{ name = "supporters", attr = { class = "heading" }, content = _"No supporters (before begin of voting)" }
  66.484 -      else
  66.485 -        ui.anchor{ name = "supporters", attr = { class = "heading" }, content = _"No supporters" }
  66.486 -      end
  66.487 -      slot.put("<br />")
  66.488 -    end
  66.489 -
  66.490 -    local members_selector = initiative:get_reference_selector("supporting_members_snapshot")
  66.491 -              :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id")
  66.492 -              :join("direct_interest_snapshot", nil, "direct_interest_snapshot.event = issue.latest_snapshot_event AND direct_interest_snapshot.issue_id = issue.id AND direct_interest_snapshot.member_id = member.id")
  66.493 -              :add_field("direct_interest_snapshot.weight")
  66.494 -              :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event")
  66.495 -              :add_where("NOT direct_supporter_snapshot.satisfied")
  66.496 -              :add_field("direct_supporter_snapshot.informed", "is_informed")
  66.497 -
  66.498 -    if members_selector:count() > 0 then
  66.499 -      if issue.fully_frozen then
  66.500 -        ui.anchor{ name = "potential_supporters", attr = { class = "heading" }, content = _"Potential supporters (before begin of voting)" }
  66.501 -      else
  66.502 -        ui.anchor{ name = "potential_supporters", attr = { class = "heading" }, content = _"Potential supporters" }
  66.503 -      end
  66.504 -                
  66.505 -      execute.view{
  66.506 -        module = "member",
  66.507 -        view = "_list",
  66.508 -        params = {
  66.509 -          initiative = initiative,
  66.510 -          members_selector = members_selector,
  66.511 -          paginator_name = "potential_supporters"
  66.512 -        }
  66.513 -      }
  66.514 -    else
  66.515 -      if issue.fully_frozen then
  66.516 -        ui.anchor{ name = "potential_supporters", attr = { class = "heading" }, content = _"No potential supporters (before begin of voting)" }
  66.517 -      else
  66.518 -        ui.anchor{ name = "potential_supporters", attr = { class = "heading" }, content = _"No potential supporters" }
  66.519 -      end
  66.520 -      slot.put("<br />")
  66.521 -    end
  66.522 -    
  66.523 -    ui.container{ attr = { class = "heading" }, content = _"Details" }
  66.524 -    execute.view {
  66.525 -      module = "initiative",
  66.526 -      view = "_details",
  66.527 -      params = {
  66.528 -        initiative = initiative,
  66.529 -        members_selector = members_selector
  66.530 -      }
  66.531 -    }
  66.532 -
  66.533 -  end
  66.534 -end
  66.535 \ No newline at end of file
    67.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.2 +++ b/app/main/initiative/_sidebar_history.lua	Thu Jul 10 01:19:48 2014 +0200
    67.3 @@ -0,0 +1,14 @@
    67.4 +local initiative = param.get("initiative", "table")
    67.5 +
    67.6 +
    67.7 +ui.sidebar( function ()
    67.8 +  ui.sidebarHead( function ()
    67.9 +    ui.link { attr = { name = "history" }, text = "" }
   67.10 +    ui.heading { level = 1, content = _"History" }
   67.11 +  end )
   67.12 +  execute.view {
   67.13 +    module = "issue", view = "_list2", params = {
   67.14 +      for_initiative = initiative, for_sidebar = true
   67.15 +    }
   67.16 +  }
   67.17 +end )
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/app/main/initiative/_sidebar_policies.lua	Thu Jul 10 01:19:48 2014 +0200
    68.3 @@ -0,0 +1,10 @@
    68.4 +local area = param.get("area", "table")
    68.5 +
    68.6 +ui.sidebar ( "tab-whatcanido", function ()
    68.7 +  ui.sidebarHead( function()
    68.8 +    ui.heading { level = 2, content = _"Available policies" }
    68.9 +  end )
   68.10 +  execute.view { module = "policy", view = "_list", params = {
   68.11 +    for_area = area
   68.12 +  } }
   68.13 +end )
   68.14 \ No newline at end of file
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/app/main/initiative/_sidebar_state.lua	Thu Jul 10 01:19:48 2014 +0200
    69.3 @@ -0,0 +1,111 @@
    69.4 +local initiative = param.get("initiative", "table")
    69.5 +
    69.6 +
    69.7 +-- voting results
    69.8 +if initiative.issue.fully_frozen and initiative.issue.closed and initiative.admitted
    69.9 +  and initiative.issue.voter_count then
   69.10 +  local class = initiative.winner and "sectionRow admitted_info" or "sectionRow not_admitted_info"
   69.11 +  ui.container{
   69.12 +    attr = { class = class },
   69.13 +    content = function()
   69.14 +      local max_value = initiative.issue.voter_count
   69.15 +      local positive_votes = initiative.positive_votes
   69.16 +      local negative_votes = initiative.negative_votes
   69.17 +      local abstention_votes = max_value - 
   69.18 +              negative_votes - 
   69.19 +              positive_votes
   69.20 +      local function perc(votes, sum)
   69.21 +        if sum > 0 then return string.format( "%.f", votes * 100 / sum ) .. "%" end
   69.22 +        return ""
   69.23 +      end
   69.24 +      local head_text
   69.25 +      if initiative.winner then
   69.26 +        head_text = _"Approved"
   69.27 +      elseif initiative.rank then
   69.28 +        head_text = _("Rejected (rank #{rank})", { rank = initiative.rank })
   69.29 +      else
   69.30 +        head_text = _"Rejected"
   69.31 +      end
   69.32 +
   69.33 +      util.initiative_pie( initiative )
   69.34 +      
   69.35 +      ui.heading { level = 1, content = head_text }
   69.36 +      
   69.37 +      ui.tag { tag = "table", content = function ()
   69.38 +        ui.tag { tag = "tr", attr = { class = "yes" }, content = function ()
   69.39 +          ui.tag { tag = "td", content = 
   69.40 +            tostring(positive_votes) 
   69.41 +          }
   69.42 +          ui.tag { tag = "th", content = _"Yes" }
   69.43 +          ui.tag { tag = "td", content = 
   69.44 +            perc(positive_votes, max_value) 
   69.45 +          }
   69.46 +          ui.tag { tag = "th", content = _"Yes" }
   69.47 +        end }
   69.48 +        ui.tag { tag = "tr", attr = { class = "abstention" }, content = function ()
   69.49 +          ui.tag { tag = "td", content = 
   69.50 +            tostring(abstention_votes)
   69.51 +          }
   69.52 +          ui.tag { tag = "th", content = _"Abstention" }
   69.53 +          ui.tag { tag = "td", content =
   69.54 +            perc(abstention_votes, max_value) 
   69.55 +          }
   69.56 +          ui.tag { tag = "th", content = _"Abstention" }
   69.57 +        end }
   69.58 +        ui.tag { tag = "tr", attr = { class = "no" }, content = function ()
   69.59 +          ui.tag { tag = "td", content = 
   69.60 +            tostring(negative_votes)
   69.61 +          }
   69.62 +          ui.tag { tag = "th", content = _"No" }
   69.63 +          ui.tag { tag = "td", content =
   69.64 +            perc(negative_votes, max_value) 
   69.65 +          }
   69.66 +          ui.tag { tag = "th", content = _"No" }
   69.67 +        end }
   69.68 +      end }
   69.69 +    end
   69.70 +  }
   69.71 +end
   69.72 +  
   69.73 +-- initiative not admitted info
   69.74 +if initiative.admitted == false then
   69.75 +  local policy = initiative.issue.policy
   69.76 +  ui.container{
   69.77 +    attr = { class = "sectionRow not_admitted_info" },
   69.78 +    content = function ()
   69.79 +      ui.heading { level = 1, content = _"Initiative not admitted" }
   69.80 +      ui.container { content = _("This initiative has not been admitted! It failed the 2nd quorum of #{quorum}.", { quorum = format.percentage ( policy.initiative_quorum_num / policy.initiative_quorum_den ) } ) }
   69.81 +    end
   69.82 +  }
   69.83 +end
   69.84 +
   69.85 +-- initiative revoked info
   69.86 +if initiative.revoked then
   69.87 +  ui.container{
   69.88 +    attr = { class = "sectionRow revoked_info" },
   69.89 +    content = function()
   69.90 +      ui.heading { level = 1, content = _"Initiative revoked" }
   69.91 +      slot.put(_("This initiative has been revoked at #{revoked} by:", {
   69.92 +        revoked = format.timestamp(initiative.revoked)
   69.93 +      }))
   69.94 +      slot.put(" ")
   69.95 +      ui.link{
   69.96 +        module = "member", view = "show", id = initiative.revoked_by_member_id,
   69.97 +        content = initiative.revoked_by_member.name
   69.98 +      }
   69.99 +      local suggested_initiative = initiative.suggested_initiative
  69.100 +      if suggested_initiative then
  69.101 +        slot.put("<br /><br />")
  69.102 +        slot.put(_("The initiators suggest to support the following initiative:"))
  69.103 +        slot.put("<br />")
  69.104 +        ui.link{
  69.105 +          content = suggested_initiative.display_name,
  69.106 +          module = "initiative",
  69.107 +          view = "show",
  69.108 +          id = suggested_initiative.id
  69.109 +        }
  69.110 +      end
  69.111 +    end
  69.112 +  }
  69.113 +end
  69.114 + 
  69.115 \ No newline at end of file
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/app/main/initiative/_sidebar_support.lua	Thu Jul 10 01:19:48 2014 +0200
    70.3 @@ -0,0 +1,108 @@
    70.4 +if not app.session.member then
    70.5 +  return
    70.6 +end
    70.7 +
    70.8 +local initiative = param.get("initiative", "table")
    70.9 +
   70.10 +local initiative_info = initiative.member_info
   70.11 +local issue_info = initiative.issue.member_info
   70.12 +
   70.13 +local active_trustee_id
   70.14 +if not issue_info.own_participation then
   70.15 +  if issue_info.first_trustee_participation then
   70.16 +    active_trustee_id = issue_info.first_trustee_id
   70.17 +  elseif issue_info.other_trustee_participation then
   70.18 +    active_trustee_id = issue_info.other_trustee_id
   70.19 +  end
   70.20 +end
   70.21 +
   70.22 +
   70.23 +slot.select ( "sidebar", function ()
   70.24 +  
   70.25 +  if 
   70.26 +    not initiative.issue.fully_frozen
   70.27 +    and not initiative.issue.closed
   70.28 +    and (issue_info.own_participation or active_trustee_id)
   70.29 +  then
   70.30 +    ui.container {
   70.31 +      attr = { class = "tab-whatcanido sidebarSection" },
   70.32 +      content = function ()
   70.33 +
   70.34 +        
   70.35 +        if initiative_info.supported then
   70.36 +          ui.heading { level = 1, content = function ()
   70.37 +            ui.tag { content = _"I'm supporting this initiative" }
   70.38 +            if issue_info.weight then
   70.39 +              slot.put ( " " )
   70.40 +              ui.link {
   70.41 +                module = "delegation", view = "show_incoming", params = {
   70.42 +                  issue_id = initiative.issue_id,
   70.43 +                  member_id = app.session.member_id
   70.44 +                },
   70.45 +                content = "+" .. issue_info.weight
   70.46 +              }
   70.47 +            end
   70.48 +          end }
   70.49 +          
   70.50 +        else
   70.51 +          ui.heading { level = 1, content = function ()
   70.52 +            ui.tag { content = _"I'm interested in this issue" }
   70.53 +            if issue_info.weight then
   70.54 +              slot.put ( " " )
   70.55 +              ui.link {
   70.56 +                module = "delegation", view = "show_incoming", params = {
   70.57 +                  issue_id = initiative.issue_id,
   70.58 +                  member_id = app.session.member_id
   70.59 +                },
   70.60 +                content = "+" .. issue_info.weight
   70.61 +              }
   70.62 +            end
   70.63 +          end }
   70.64 +        end
   70.65 +
   70.66 +        if active_trustee_id then
   70.67 +          ui.tag { content = _"via delegation" }
   70.68 +        elseif issue_info.first_trustee_id then
   70.69 +          ui.tag { content = _"delegation suspended during discussion" }
   70.70 +        end
   70.71 +      end
   70.72 +    }
   70.73 +  end
   70.74 +      
   70.75 +  if 
   70.76 +    initiative.issue.fully_frozen and
   70.77 +    (issue_info.direct_voted or active_trustee_id)
   70.78 +  then
   70.79 +    ui.container {
   70.80 +      attr = { class = "tab-whatcanido sidebarSection" },
   70.81 +      content = function ()
   70.82 +      
   70.83 +        if issue_info.direct_voted then
   70.84 +          ui.heading { level = 1, content = _"You have been voted" }
   70.85 +          ui.link {
   70.86 +            content = _"Show my voting ballot",
   70.87 +            module = "vote", view = "list", params = {
   70.88 +              issue_id = initiative.issue.id
   70.89 +            }
   70.90 +          }
   70.91 +        else
   70.92 +          
   70.93 +          
   70.94 +          if active_trustee_id then
   70.95 +            ui.heading { level = 1, content = _"You have been voted" }
   70.96 +            ui.container { 
   70.97 +              content = _"via delegation"
   70.98 +            }
   70.99 +            ui.link {
  70.100 +              content = _"Show voting ballot",
  70.101 +              module = "vote", view = "list", params = {
  70.102 +                issue_id = initiative.issue.id, member_id = active_trustee_id
  70.103 +              }
  70.104 +            }
  70.105 +          end
  70.106 +        end
  70.107 +      end
  70.108 +    }
  70.109 +  end
  70.110 +end )
  70.111 +        
  70.112 \ No newline at end of file
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/app/main/initiative/_sidebar_wikisyntax.lua	Thu Jul 10 01:19:48 2014 +0200
    71.3 @@ -0,0 +1,61 @@
    71.4 +if config.enforce_formatting_engine ~= 'markdown2' then
    71.5 +  return
    71.6 +end
    71.7 +
    71.8 +ui.sidebar( "tab-whatcanido", function()
    71.9 +  ui.sidebarHead( function()
   71.10 +    ui.heading { level = 2, content = _"Formatting help" }
   71.11 +  end )
   71.12 +  ui.sidebarSection( function ()
   71.13 +    ui.heading { level = 3, content = _"Paragraphs" }
   71.14 +    ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
   71.15 +      ui.tag { tag = "li", content = function ()
   71.16 +        ui.tag { content = _"Separate each paragraph with at least one blank line" }
   71.17 +      end }
   71.18 +    end }
   71.19 +
   71.20 +    ui.heading { level = 3, content = _"Headlines" }
   71.21 +    ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
   71.22 +      ui.tag { tag = "li", content = function ()
   71.23 +        ui.tag { content = _"Underline main headlines with ===" }
   71.24 +      end }
   71.25 +      ui.tag { tag = "li", content = function ()
   71.26 +        ui.tag { content = _"Underline sub headlines with ---" }
   71.27 +      end }
   71.28 +    end }
   71.29 +
   71.30 +    ui.heading { level = 3, content = _"Emphasis" }
   71.31 +    ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
   71.32 +      ui.tag { tag = "li", content = function ()
   71.33 +        ui.tag { content = _"Put *asterisks* or around a phrase to make it italic" }
   71.34 +      end }
   71.35 +      ui.tag { tag = "li", content = function ()
   71.36 +        ui.tag { content = _"Put **double asterisks** around a phrase to make it bold" }
   71.37 +      end }
   71.38 +    end }
   71.39 +
   71.40 +    ui.heading { level = 3, content = _"Lists" }
   71.41 +    ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
   71.42 +      ui.tag { tag = "li", content = function ()
   71.43 +        ui.tag { content = _"Lists must be preceeded and followed by at least one blank line" }
   71.44 +      end }
   71.45 +      ui.tag { tag = "li", content = function ()
   71.46 +        ui.tag { content = _"Put a hypen (-) or asterisk (*) followed by a space in front of each item" }
   71.47 +      end }
   71.48 +      ui.tag { tag = "li", content = function ()
   71.49 +        ui.tag { content = _"For numbered items use a digit (e.g. 1) followed by a dot (.) and a space" }
   71.50 +      end }
   71.51 +      ui.tag { tag = "li", content = function ()
   71.52 +        ui.tag { content = _"Indent sub items with spaces" }
   71.53 +      end }
   71.54 +    end }
   71.55 +
   71.56 +    ui.heading { level = 3, content = _"Links" }
   71.57 +    ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
   71.58 +      ui.tag { tag = "li", content = function ()
   71.59 +        ui.tag { content = _"Use [Text](http://example.com/) for links" }
   71.60 +      end }
   71.61 +    end }
   71.62 +
   71.63 +  end )
   71.64 +end )
    72.1 --- a/app/main/initiative/add_initiator.lua	Thu Jul 10 01:02:43 2014 +0200
    72.2 +++ b/app/main/initiative/add_initiator.lua	Thu Jul 10 01:19:48 2014 +0200
    72.3 @@ -1,26 +1,55 @@
    72.4  local initiative = Initiative:by_id(param.get("initiative_id"))
    72.5  
    72.6 -slot.put_into("title", _"Invite an initiator to initiative")
    72.7 +local member = app.session.member
    72.8 +if member then
    72.9 +  initiative:load_everything_for_member_id(member.id)
   72.10 +  initiative.issue:load_everything_for_member_id(member.id)
   72.11 +end
   72.12 +
   72.13 +
   72.14 +local records = {
   72.15 +  {
   72.16 +    id = "-1",
   72.17 +    name = _"Choose member"
   72.18 +  }
   72.19 +}
   72.20 +local contact_members = app.session.member:get_reference_selector("saved_members"):add_order_by("name"):exec()
   72.21 +for i, record in ipairs(contact_members) do
   72.22 +  records[#records+1] = record
   72.23 +end
   72.24  
   72.25 -slot.select("actions", function()
   72.26 -  ui.link{
   72.27 -    content = function()
   72.28 -        ui.image{ static = "icons/16/cancel.png" }
   72.29 -        slot.put(_"Cancel")
   72.30 -    end,
   72.31 -    module = "initiative",
   72.32 -    view = "show",
   72.33 -    id = initiative.id,
   72.34 -    params = {
   72.35 -      tab = "initiators"
   72.36 -    }
   72.37 +execute.view {
   72.38 +  module = "issue", view = "_head", params = {
   72.39 +    issue = initiative.issue,
   72.40 +    member = app.session.member
   72.41    }
   72.42 -end)
   72.43 +}
   72.44 +
   72.45 +execute.view{ module = "issue", view = "_sidebar_state", params = {
   72.46 +  initiative = initiative
   72.47 +} }
   72.48  
   72.49 -util.help("initiative.add_initiator", _"Invite an initiator to initiative")
   72.50 +execute.view { 
   72.51 +  module = "issue", view = "_sidebar_issue", 
   72.52 +  params = {
   72.53 +    issue = initiative.issue,
   72.54 +    highlight_initiative_id = initiative.id
   72.55 +  }
   72.56 +}
   72.57 +
   72.58 +execute.view {
   72.59 +  module = "issue", view = "_sidebar_whatcanido",
   72.60 +  params = { initiative = initiative }
   72.61 +}
   72.62 +
   72.63 +execute.view { 
   72.64 +  module = "issue", view = "_sidebar_members", params = {
   72.65 +    issue = initiative.issue, initiative = initiative
   72.66 +  }
   72.67 +}
   72.68  
   72.69  ui.form{
   72.70 -  attr = { class = "vertical" },
   72.71 +  attr = { class = "wide section" },
   72.72    module = "initiative",
   72.73    action = "add_initiator",
   72.74    params = {
   72.75 @@ -38,23 +67,50 @@
   72.76      }
   72.77    },
   72.78    content = function()
   72.79 -    local records = {
   72.80 -      {
   72.81 -        id = "-1",
   72.82 -        name = _"Choose member"
   72.83 +
   72.84 +    ui.sectionHead( function()
   72.85 +      ui.link{
   72.86 +        module = "initiative", view = "show", id = initiative.id,
   72.87 +        content = function ()
   72.88 +          ui.heading { 
   72.89 +            level = 1,
   72.90 +            content = initiative.display_name
   72.91 +          }
   72.92 +        end
   72.93 +      }
   72.94 +      ui.heading { level = 2, content = _"Invite an initiator to initiative" }
   72.95 +    end )
   72.96 +
   72.97 +    ui.sectionRow( function()
   72.98 +      ui.heading { level = 2, content = _"Choose a member to invite" }
   72.99 +      ui.field.select{
  72.100 +        name = "member_id",
  72.101 +        foreign_records = records,
  72.102 +        foreign_id = "id",
  72.103 +        foreign_name = "name"
  72.104        }
  72.105 -    }
  72.106 -    local contact_members = app.session.member:get_reference_selector("saved_members"):add_order_by("name"):exec()
  72.107 -    for i, record in ipairs(contact_members) do
  72.108 -      records[#records+1] = record
  72.109 -    end
  72.110 -    ui.field.select{
  72.111 -      label = _"Member",
  72.112 -      name = "member_id",
  72.113 -      foreign_records = records,
  72.114 -      foreign_id = "id",
  72.115 -      foreign_name = "name"
  72.116 -    }
  72.117 -    ui.submit{ text = _"Save" }
  72.118 +      ui.container{ content = _"You can choose only members which you have been saved as contact before." }
  72.119 +      slot.put("<br />")
  72.120 +      ui.tag{
  72.121 +        tag = "input",
  72.122 +        attr = {
  72.123 +          type = "submit",
  72.124 +          class = "btn btn-default",
  72.125 +          value = _"Invite member"
  72.126 +        },
  72.127 +        content = ""
  72.128 +      }
  72.129 +      slot.put("<br />")
  72.130 +      slot.put("<br />")
  72.131 +      ui.link{
  72.132 +        content = _"Cancel",
  72.133 +        module = "initiative",
  72.134 +        view = "show",
  72.135 +        id = initiative.id,
  72.136 +        params = {
  72.137 +          tab = "initiators"
  72.138 +        }
  72.139 +      }
  72.140 +    end )
  72.141    end
  72.142  }
  72.143 \ No newline at end of file
    73.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.2 +++ b/app/main/initiative/history.lua	Thu Jul 10 01:19:48 2014 +0200
    73.3 @@ -0,0 +1,117 @@
    73.4 +local initiative = Initiative:by_id(param.get_id())
    73.5 +
    73.6 +initiative:load_everything_for_member_id(app.session.member_id)
    73.7 +initiative.issue:load_everything_for_member_id(app.session.member_id)
    73.8 +
    73.9 +
   73.10 +execute.view{ module = "issue", view = "_sidebar_state", params = {
   73.11 +  initiative = initiative
   73.12 +} }
   73.13 +
   73.14 +execute.view { 
   73.15 +  module = "issue", view = "_sidebar_issue", 
   73.16 +  params = {
   73.17 +    issue = initiative.issue,
   73.18 +    highlight_initiative_id = initiative.id
   73.19 +  }
   73.20 +}
   73.21 +
   73.22 +execute.view {
   73.23 +  module = "issue", view = "_sidebar_whatcanido",
   73.24 +  params = { initiative = initiative }
   73.25 +}
   73.26 +
   73.27 +execute.view { 
   73.28 +  module = "issue", view = "_sidebar_members", params = {
   73.29 +    issue = initiative.issue, initiative = initiative
   73.30 +  }
   73.31 +}
   73.32 +
   73.33 +
   73.34 +
   73.35 +execute.view {
   73.36 +  module = "issue", view = "_head", params = {
   73.37 +    issue = initiative.issue
   73.38 +  }
   73.39 +}
   73.40 +
   73.41 +ui.form{
   73.42 +  method = "get",
   73.43 +  module = "draft",
   73.44 +  view = "diff",
   73.45 +  attr = { class = "section" },
   73.46 +  content = function()
   73.47 +    ui.field.hidden{ name = "initiative_id", value = initiative.id }
   73.48 +  
   73.49 +    ui.sectionHead( function()
   73.50 +      ui.link{
   73.51 +        module = "initiative", view = "show", id = initiative.id,
   73.52 +        content = function ()
   73.53 +          ui.heading { 
   73.54 +            level = 1,
   73.55 +            content = initiative.display_name
   73.56 +          }
   73.57 +        end
   73.58 +      }
   73.59 +      ui.heading { level = 2, content = _"Draft history" }
   73.60 +    end)
   73.61 +    
   73.62 +    ui.sectionRow( function()
   73.63 +    
   73.64 +      local columns = {
   73.65 +        {
   73.66 +          label = _"draft ID",
   73.67 +          content = function(record)
   73.68 +            ui.tag { content = record.id }
   73.69 +          end
   73.70 +        },
   73.71 +        {
   73.72 +          label = _"published at",
   73.73 +          content = function(record)
   73.74 +            ui.link{
   73.75 +              attr = { class = "action" },
   73.76 +              module = "draft", view = "show", id = record.id,
   73.77 +              text = format.timestamp(record.created)
   73.78 +            }
   73.79 +          end
   73.80 +        },
   73.81 +        {
   73.82 +          label = _"compare",
   73.83 +          content = function(record)
   73.84 +            slot.put('<input type="radio" name="old_draft_id" value="' .. tostring(record.id) .. '">')
   73.85 +            slot.put('<input type="radio" name="new_draft_id" value="' .. tostring(record.id) .. '">')
   73.86 +          end
   73.87 +        }
   73.88 +      }
   73.89 +      
   73.90 +      if app.session:has_access("authors_pseudonymous") then
   73.91 +        columns[#columns+1] = {
   73.92 +          label = _"author",
   73.93 +          content = function(record)
   73.94 +            if record.author then
   73.95 +              return util.micro_avatar ( record.author )
   73.96 +            end
   73.97 +          end
   73.98 +        }
   73.99 +      end
  73.100 +      
  73.101 +      ui.list{
  73.102 +        records = initiative.drafts,
  73.103 +        columns = columns
  73.104 +      }
  73.105 +      
  73.106 +      slot.put("<br />")
  73.107 +      ui.container { attr = { class = "actions" }, content = function()
  73.108 +        ui.tag{
  73.109 +          tag = "input",
  73.110 +          attr = {
  73.111 +            type = "submit",
  73.112 +            class = "btn btn-default",
  73.113 +            value = _"compare revisions"
  73.114 +          },
  73.115 +          content = ""
  73.116 +        }
  73.117 +      end }
  73.118 +    end )
  73.119 +  end
  73.120 +}
    74.1 --- a/app/main/initiative/new.lua	Thu Jul 10 01:02:43 2014 +0200
    74.2 +++ b/app/main/initiative/new.lua	Thu Jul 10 01:19:48 2014 +0200
    74.3 @@ -4,11 +4,13 @@
    74.4  local issue_id = param.get("issue_id", atom.integer)
    74.5  if issue_id then
    74.6    issue = Issue:new_selector():add_where{"id=?",issue_id}:single_object_mode():exec()
    74.7 +  issue:load_everything_for_member_id(app.session.member_id)
    74.8    area = issue.area
    74.9  
   74.10  else
   74.11    local area_id = param.get("area_id", atom.integer)
   74.12    area = Area:new_selector():add_where{"id=?",area_id}:single_object_mode():exec()
   74.13 +  area:load_delegation_info_once_for_member_id(app.session.member_id)
   74.14  end
   74.15  
   74.16  local polling = param.get("polling", atom.boolean)
   74.17 @@ -16,17 +18,49 @@
   74.18  local policy_id = param.get("policy_id", atom.integer)
   74.19  local policy
   74.20  
   74.21 +local preview = param.get("preview")
   74.22 +
   74.23 +if #(slot.get_content("error")) > 0 then
   74.24 +  preview = false
   74.25 +end
   74.26 +
   74.27  if policy_id then
   74.28    policy = Policy:by_id(policy_id)
   74.29  end
   74.30  
   74.31  if issue_id then
   74.32 -  ui.title(_"Add alternative initiative to issue")
   74.33 +  execute.view {
   74.34 +    module = "issue", view = "_head", 
   74.35 +    params = { issue = issue, member = app.session.member }
   74.36 +  }
   74.37 +  execute.view { 
   74.38 +    module = "issue", view = "_sidebar_state", 
   74.39 +    params = {
   74.40 +      issue = issue
   74.41 +    }
   74.42 +  }
   74.43 +  execute.view { 
   74.44 +    module = "issue", view = "_sidebar_issue", 
   74.45 +    params = {
   74.46 +      issue = issue
   74.47 +    }
   74.48 +  }
   74.49  else
   74.50 -  ui.title(_"Create new issue")
   74.51 +  execute.view {
   74.52 +    module = "area", view = "_head", 
   74.53 +    params = { area = area, member = app.session.member }
   74.54 +  }
   74.55 +  execute.view { 
   74.56 +    module = "initiative", view = "_sidebar_policies", 
   74.57 +    params = {
   74.58 +      area = area,
   74.59 +    }
   74.60 +  }
   74.61  end
   74.62  
   74.63 -local preview = param.get("preview")
   74.64 +
   74.65 +
   74.66 +
   74.67  
   74.68  if not preview and not issue_id and app.session.member:has_polling_right_for_unit_id(area.unit_id) then
   74.69    ui.actions(function()
   74.70 @@ -59,181 +93,214 @@
   74.71    },
   74.72    attr = { class = "vertical" },
   74.73    content = function()
   74.74 -    ui.field.text{ label = _"Unit",  value = area.unit.name }
   74.75 -    ui.field.text{ label = _"Area",  value = area.name }
   74.76 -    slot.put("<br />")
   74.77 -    if issue_id then
   74.78 -      ui.field.text{ label = _"Issue",  value = issue_id }
   74.79 -    elseif policy then
   74.80 -      ui.field.hidden{ name = "policy_id", value = policy.id }
   74.81 -      ui.field.text{ label = _"Policy",  value = policy.name }
   74.82 -      if policy.free_timeable then
   74.83 -        local available_timings
   74.84 -        if config.free_timing and config.free_timing.available_func then
   74.85 -          available_timings = config.free_timing.available_func(policy)
   74.86 -          if available_timings == false then
   74.87 -            error("error in free timing config")
   74.88 +  
   74.89 +    if preview then
   74.90 +      ui.section( function()
   74.91 +        ui.sectionHead( function()
   74.92 +          ui.heading{ level = 1, content = encode.html(param.get("name")) }
   74.93 +          if not issue then
   74.94 +            ui.container { content = policy.name }
   74.95            end
   74.96 -        end
   74.97 -        if available_timings then
   74.98 -          ui.field.select{
   74.99 -            label = _"Free timing",
  74.100 -            name = "free_timing",
  74.101 -            foreign_records = available_timings,
  74.102 -            foreign_id = "id",
  74.103 -            foreign_name = "name",
  74.104 -            value = param.get("free_timing")
  74.105 -          }
  74.106 -        else
  74.107 -          ui.field.text{ label = _"Free timing", name = "free_timing", value = param.get("free_timing") }
  74.108 -        end
  74.109 -      end
  74.110 -    else
  74.111 -      tmp = { { id = -1, name = _"Please choose a policy" } }
  74.112 -      for i, allowed_policy in ipairs(area.allowed_policies) do
  74.113 -        if not allowed_policy.polling then
  74.114 -          tmp[#tmp+1] = allowed_policy
  74.115 -        end
  74.116 -      end
  74.117 -      ui.field.select{
  74.118 -        label = _"Policy",
  74.119 -        name = "policy_id",
  74.120 -        foreign_records = tmp,
  74.121 -        foreign_id = "id",
  74.122 -        foreign_name = "name",
  74.123 -        value = param.get("policy_id", atom.integer) or area.default_policy and area.default_policy.id
  74.124 -      }
  74.125 -      ui.tag{
  74.126 -        tag = "div",
  74.127 -        content = function()
  74.128 -          ui.tag{
  74.129 -            tag = "label",
  74.130 -            attr = { class = "ui_field_label" },
  74.131 -            content = function() slot.put("&nbsp;") end,
  74.132 -          }
  74.133 -          ui.tag{
  74.134 +          slot.put("<br />")
  74.135 +
  74.136 +          ui.field.hidden{ name = "formatting_engine", value = param.get("formatting_engine") }
  74.137 +          ui.field.hidden{ name = "policy_id", value = param.get("policy_id") }
  74.138 +          ui.field.hidden{ name = "name", value = param.get("name") }
  74.139 +          ui.field.hidden{ name = "draft", value = param.get("draft") }
  74.140 +          local formatting_engine
  74.141 +          if config.enforce_formatting_engine then
  74.142 +            formatting_engine = config.enforce_formatting_engine
  74.143 +          else
  74.144 +            formatting_engine = param.get("formatting_engine")
  74.145 +          end
  74.146 +          ui.container{
  74.147 +            attr = { class = "draft_content wiki" },
  74.148              content = function()
  74.149 -              ui.link{
  74.150 -                text = _"Information about the available policies",
  74.151 -                module = "policy",
  74.152 -                view = "list"
  74.153 -              }
  74.154 -              slot.put(" ")
  74.155 -              ui.link{
  74.156 -                attr = { target = "_blank" },
  74.157 -                text = _"(new window)",
  74.158 -                module = "policy",
  74.159 -                view = "list"
  74.160 -              }
  74.161 +              slot.put(format.wiki_text(param.get("draft"), formatting_engine))
  74.162              end
  74.163            }
  74.164 -        end
  74.165 -      }
  74.166 -    end
  74.167 -    
  74.168 -    if issue and issue.policy.polling and app.session.member:has_polling_right_for_unit_id(area.unit_id) then
  74.169 -      ui.field.boolean{ name = "polling", label = _"No admission needed", value = polling }
  74.170 -    end
  74.171 -    
  74.172 -    if preview then
  74.173 -      ui.heading{ level = 1, content = encode.html(param.get("name")) }
  74.174 -      local discussion_url = param.get("discussion_url")
  74.175 -      ui.container{
  74.176 -        attr = { class = "ui_field_label" },
  74.177 -        content = _"Discussion with initiators"
  74.178 -      }
  74.179 -      ui.tag{
  74.180 -        tag = "span",
  74.181 -        content = function()
  74.182 -          if discussion_url:find("^https?://") then
  74.183 -            if discussion_url and #discussion_url > 0 then
  74.184 -              ui.link{
  74.185 -                attr = {
  74.186 -                  class = "actions",
  74.187 -                  target = "_blank",
  74.188 -                  title = discussion_url
  74.189 -                },
  74.190 -                content = discussion_url,
  74.191 -                external = discussion_url
  74.192 -              }
  74.193 -            end
  74.194 +          slot.put("<br />")
  74.195 +
  74.196 +          ui.tag{
  74.197 +            tag = "input",
  74.198 +            attr = {
  74.199 +              type = "submit",
  74.200 +              class = "btn btn-default",
  74.201 +              value = _'Publish now'
  74.202 +            },
  74.203 +            content = ""
  74.204 +          }
  74.205 +          slot.put("<br />")
  74.206 +          slot.put("<br />")
  74.207 +          ui.tag{
  74.208 +            tag = "input",
  74.209 +            attr = {
  74.210 +              type = "submit",
  74.211 +              name = "edit",
  74.212 +              class = "btn-link",
  74.213 +              value = _'Edit again'
  74.214 +            },
  74.215 +            content = ""
  74.216 +          }
  74.217 +          slot.put(" | ")
  74.218 +          if issue then
  74.219 +            ui.link{ content = _"Cancel", module = "issue", view = "show", id = issue.id }
  74.220            else
  74.221 -            slot.put(encode.html(discussion_url))
  74.222 +            ui.link{ content = _"Cancel", module = "area", view = "show", id = area.id }
  74.223            end
  74.224 -        end
  74.225 -      }
  74.226 -      ui.container{
  74.227 -        attr = { class = "draft_content wiki" },
  74.228 -        content = function()
  74.229 -          slot.put(format.wiki_text(param.get("draft"), param.get("formatting_engine")))
  74.230 -        end
  74.231 -      }
  74.232 -      slot.put("<br />")
  74.233 -      ui.submit{ text = _"Save" }
  74.234 -      slot.put("<br />")
  74.235 -      slot.put("<br />")
  74.236 -    end
  74.237 -    slot.put("<br />")
  74.238 +        end )
  74.239 +      end )
  74.240 +    else
  74.241 +      
  74.242 +     
  74.243 +      execute.view{ module = "initiative", view = "_sidebar_wikisyntax" }
  74.244  
  74.245 -    ui.field.text{
  74.246 -      label = _"Title of initiative",
  74.247 -      name  = "name",
  74.248 -      value = param.get("name")
  74.249 -    }
  74.250 -    ui.field.text{
  74.251 -      label = _"Discussion URL",
  74.252 -      name = "discussion_url",
  74.253 -      value = param.get("discussion_url")
  74.254 -    }
  74.255 -    ui.field.select{
  74.256 -      label = _"Wiki engine",
  74.257 -      name = "formatting_engine",
  74.258 -      foreign_records = {
  74.259 -        { id = "rocketwiki", name = "RocketWiki" },
  74.260 -        { id = "compat", name = _"Traditional wiki syntax" }
  74.261 -      },
  74.262 -      attr = {id = "formatting_engine"},
  74.263 -      foreign_id = "id",
  74.264 -      foreign_name = "name",
  74.265 -      value = param.get("formatting_engine")
  74.266 -    }
  74.267 -    ui.tag{
  74.268 -        tag = "div",
  74.269 -        content = function()
  74.270 -          ui.tag{
  74.271 -            tag = "label",
  74.272 -            attr = { class = "ui_field_label" },
  74.273 -            content = function() slot.put("&nbsp;") end,
  74.274 +      ui.section( function()
  74.275 +        if preview then
  74.276 +          ui.sectionHead( function()
  74.277 +            ui.heading { level = 1, content = _"Edit again" }
  74.278 +          end )
  74.279 +        elseif issue_id then
  74.280 +          ui.sectionHead( function()
  74.281 +            ui.heading { level = 1, content = _"Add a new competing initiative to issue" }
  74.282 +          end )
  74.283 +        else
  74.284 +          ui.sectionHead( function()
  74.285 +            ui.heading { level = 1, content = _"Create a new issue" }
  74.286 +          end )
  74.287 +        end
  74.288 +      
  74.289 +        ui.sectionRow( function()
  74.290 +          if not preview and not issue_id then
  74.291 +            ui.container { attr = { class = "section" }, content = _"Before creating a new issue, please check any existant issues before, if the topic is already in discussion." }
  74.292 +            slot.put("<br />")
  74.293 +          end
  74.294 +          if not issue_id then
  74.295 +            tmp = { { id = -1, name = "" } }
  74.296 +            for i, allowed_policy in ipairs(area.allowed_policies) do
  74.297 +              if not allowed_policy.polling then
  74.298 +                tmp[#tmp+1] = allowed_policy
  74.299 +              end
  74.300 +            end
  74.301 +            ui.heading{ level = 2, content = _"Please choose a policy for the new issue:" }
  74.302 +            ui.field.select{
  74.303 +              name = "policy_id",
  74.304 +              foreign_records = tmp,
  74.305 +              foreign_id = "id",
  74.306 +              foreign_name = "name",
  74.307 +              value = param.get("policy_id", atom.integer) or area.default_policy and area.default_policy.id
  74.308 +            }
  74.309 +            if policy and policy.free_timeable then
  74.310 +              ui.sectionRow( function()
  74.311 +                local available_timings
  74.312 +                if config.free_timing and config.free_timing.available_func then
  74.313 +                  available_timings = config.free_timing.available_func(policy)
  74.314 +                  if available_timings == false then
  74.315 +                    error("error in free timing config")
  74.316 +                  end
  74.317 +                end
  74.318 +                ui.heading{ level = 4, content = _"Free timing:" }
  74.319 +                if available_timings then
  74.320 +                  ui.field.select{
  74.321 +                    name = "free_timing",
  74.322 +                    foreign_records = available_timings,
  74.323 +                    foreign_id = "id",
  74.324 +                    foreign_name = "name",
  74.325 +                    value = param.get("free_timing")
  74.326 +                  }
  74.327 +                else
  74.328 +                  ui.field.text{
  74.329 +                    name = "free_timing",
  74.330 +                    value = param.get("free_timing")
  74.331 +                  }
  74.332 +                end
  74.333 +              end )
  74.334 +            end
  74.335 +          end
  74.336 +
  74.337 +          if issue and issue.policy.polling and app.session.member:has_polling_right_for_unit_id(area.unit_id) then
  74.338 +            slot.put("<br />")
  74.339 +            ui.field.boolean{ name = "polling", label = _"No admission needed", value = polling }
  74.340 +          end
  74.341 +          
  74.342 +          slot.put("<br />")
  74.343 +          ui.heading { level = 2, content = _"Enter a title for your initiative (max. 140 chars):" }
  74.344 +          ui.field.text{
  74.345 +            attr = { style = "width: 100%;" },
  74.346 +            name  = "name",
  74.347 +            value = param.get("name")
  74.348            }
  74.349 +          ui.container { content = _"The title is the figurehead of your iniative. It should be short but meaningful! As others identifies your initiative by this title, you cannot change it later!" }
  74.350 +          
  74.351 +          if not config.enforce_formatting_engine then
  74.352 +            slot.put("<br />")
  74.353 +            ui.heading { level = 4, content = _"Choose a formatting engine:" }
  74.354 +            ui.field.select{
  74.355 +              name = "formatting_engine",
  74.356 +              foreign_records = config.formatting_engines,
  74.357 +              attr = {id = "formatting_engine"},
  74.358 +              foreign_id = "id",
  74.359 +              foreign_name = "name",
  74.360 +              value = param.get("formatting_engine")
  74.361 +            }
  74.362 +          end
  74.363 +          slot.put("<br />")
  74.364 +
  74.365 +          ui.heading { level = 2, content = _"Enter your proposal and/or reasons:" }
  74.366 +          ui.field.text{
  74.367 +            name = "draft",
  74.368 +            multiline = true, 
  74.369 +            attr = { style = "height: 50ex; width: 100%;" },
  74.370 +            value = param.get("draft") or
  74.371 +                [[
  74.372 +Proposal
  74.373 +======
  74.374 +
  74.375 +Replace me with your proposal.
  74.376 +
  74.377 +
  74.378 +Reasons
  74.379 +======
  74.380 +
  74.381 +Argument 1
  74.382 +------
  74.383 +
  74.384 +Replace me with your first argument
  74.385 +
  74.386 +
  74.387 +Argument 2
  74.388 +------
  74.389 +
  74.390 +Replace me with your second argument
  74.391 +
  74.392 +]]
  74.393 +          }
  74.394 +          if not issue or issue.state == "admission" or issue.state == "discussion" then
  74.395 +            ui.container { content = _"You can change your text again anytime during admission and discussion phase" }
  74.396 +          else
  74.397 +            ui.container { content = _"You cannot change your text again later, because this issue is already in verfication phase!" }
  74.398 +          end
  74.399 +          slot.put("<br />")
  74.400            ui.tag{
  74.401 -            content = function()
  74.402 -              ui.link{
  74.403 -                text = _"Syntax help",
  74.404 -                module = "help",
  74.405 -                view = "show",
  74.406 -                id = "wikisyntax",
  74.407 -                attr = {onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"}
  74.408 -              }
  74.409 -              slot.put(" ")
  74.410 -              ui.link{
  74.411 -                text = _"(new window)",
  74.412 -                module = "help",
  74.413 -                view = "show",
  74.414 -                id = "wikisyntax",
  74.415 -                attr = {target = "_blank", onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"}
  74.416 -              }
  74.417 -            end
  74.418 +            tag = "input",
  74.419 +            attr = {
  74.420 +              type = "submit",
  74.421 +              name = "preview",
  74.422 +              class = "btn btn-default",
  74.423 +              value = _'Preview'
  74.424 +            },
  74.425 +            content = ""
  74.426            }
  74.427 -        end
  74.428 -      }
  74.429 -    ui.field.text{
  74.430 -      label = _"Draft",
  74.431 -      name = "draft",
  74.432 -      multiline = true, 
  74.433 -      attr = { style = "height: 50ex;" },
  74.434 -      value = param.get("draft")
  74.435 -    }
  74.436 -    ui.submit{ name = "preview", text = _"Preview" }
  74.437 -    ui.submit{ text = _"Save" }
  74.438 +          slot.put("<br />")
  74.439 +          slot.put("<br />")
  74.440 +          
  74.441 +          if issue then
  74.442 +            ui.link{ content = _"Cancel", module = "issue", view = "show", id = issue.id }
  74.443 +          else
  74.444 +            ui.link{ content = _"Cancel", module = "area", view = "show", id = area.id }
  74.445 +          end
  74.446 +        end )
  74.447 +      end )
  74.448 +    end
  74.449    end
  74.450  }
    75.1 --- a/app/main/initiative/remove_initiator.lua	Thu Jul 10 01:02:43 2014 +0200
    75.2 +++ b/app/main/initiative/remove_initiator.lua	Thu Jul 10 01:19:48 2014 +0200
    75.3 @@ -1,31 +1,48 @@
    75.4  local initiative = Initiative:by_id(param.get("initiative_id"))
    75.5  
    75.6 +local member = app.session.member
    75.7 +if member then
    75.8 +  initiative:load_everything_for_member_id(member.id)
    75.9 +  initiative.issue:load_everything_for_member_id(member.id)
   75.10 +end
   75.11 +
   75.12  local initiator = Initiator:by_pk(initiative.id, app.session.member.id)
   75.13  if not initiator or initiator.accepted ~= true then
   75.14    error("access denied")
   75.15  end
   75.16  
   75.17 -slot.put_into("title", _"Remove initiator from initiative")
   75.18 +execute.view {
   75.19 +  module = "issue", view = "_head", params = {
   75.20 +    issue = initiative.issue,
   75.21 +    member = app.session.member
   75.22 +  }
   75.23 +}
   75.24 +
   75.25 +execute.view{ module = "issue", view = "_sidebar_state", params = {
   75.26 +  initiative = initiative
   75.27 +} }
   75.28  
   75.29 -slot.select("actions", function()
   75.30 -  ui.link{
   75.31 -    content = function()
   75.32 -        ui.image{ static = "icons/16/cancel.png" }
   75.33 -        slot.put(_"Cancel")
   75.34 -    end,
   75.35 -    module = "initiative",
   75.36 -    view = "show",
   75.37 -    id = initiative.id,
   75.38 -    params = {
   75.39 -      tab = "initiators"
   75.40 -    }
   75.41 +execute.view { 
   75.42 +  module = "issue", view = "_sidebar_issue", 
   75.43 +  params = {
   75.44 +    issue = initiative.issue,
   75.45 +    highlight_initiative_id = initiative.id
   75.46    }
   75.47 -end)
   75.48 +}
   75.49  
   75.50 -util.help("initiative.remove_initiator", _"Remove initiator from initiative")
   75.51 +execute.view {
   75.52 +  module = "issue", view = "_sidebar_whatcanido",
   75.53 +  params = { initiative = initiative }
   75.54 +}
   75.55 +
   75.56 +execute.view { 
   75.57 +  module = "issue", view = "_sidebar_members", params = {
   75.58 +    issue = initiative.issue, initiative = initiative
   75.59 +  }
   75.60 +}
   75.61  
   75.62  ui.form{
   75.63 -  attr = { class = "vertical" },
   75.64 +  attr = { class = "vertical section" },
   75.65    module = "initiative",
   75.66    action = "remove_initiator",
   75.67    params = {
   75.68 @@ -43,23 +60,50 @@
   75.69      }
   75.70    },
   75.71    content = function()
   75.72 -    local records = {
   75.73 -      {
   75.74 -        id = "-1",
   75.75 -        name = _"Choose initiator"
   75.76 +
   75.77 +    ui.sectionHead( function()
   75.78 +      ui.link{
   75.79 +        module = "initiative", view = "show", id = initiative.id,
   75.80 +        content = function ()
   75.81 +          ui.heading { 
   75.82 +            level = 1,
   75.83 +            content = initiative.display_name
   75.84 +          }
   75.85 +        end
   75.86 +      }
   75.87 +      ui.heading { level = 2, content = _"Remove an initiator from initiative" }
   75.88 +    end )
   75.89 +
   75.90 +    ui.sectionRow( function()
   75.91 +      local records = initiative:get_reference_selector("initiating_members"):add_where("accepted OR accepted ISNULL"):exec()
   75.92 +      ui.heading{ level = 2, content = _"Choose an initiator to remove" }
   75.93 +      ui.field.select{
   75.94 +        name = "member_id",
   75.95 +        foreign_records = records,
   75.96 +        foreign_id = "id",
   75.97 +        foreign_name = "name",
   75.98        }
   75.99 -    }
  75.100 -    local members = initiative:get_reference_selector("initiating_members"):add_where("accepted OR accepted ISNULL"):exec()
  75.101 -    for i, record in ipairs(members) do
  75.102 -      records[#records+1] = record
  75.103 -    end
  75.104 -    ui.field.select{
  75.105 -      label = _"Member",
  75.106 -      name = "member_id",
  75.107 -      foreign_records = records,
  75.108 -      foreign_id = "id",
  75.109 -      foreign_name = "name"
  75.110 -    }
  75.111 -    ui.submit{ text = _"Save" }
  75.112 +      slot.put("<br />")
  75.113 +      ui.tag{
  75.114 +        tag = "input",
  75.115 +        attr = {
  75.116 +          type = "submit",
  75.117 +          class = "btn btn-dangerous",
  75.118 +          value = _"Remove initiator"
  75.119 +        },
  75.120 +        content = ""
  75.121 +      }
  75.122 +      slot.put("<br />")
  75.123 +      slot.put("<br />")
  75.124 +      ui.link{
  75.125 +        content = _"Cancel",
  75.126 +        module = "initiative",
  75.127 +        view = "show",
  75.128 +        id = initiative.id,
  75.129 +        params = {
  75.130 +          tab = "initiators"
  75.131 +        }
  75.132 +      }
  75.133 +    end )
  75.134    end
  75.135  }
  75.136 \ No newline at end of file
    76.1 --- a/app/main/initiative/revoke.lua	Thu Jul 10 01:02:43 2014 +0200
    76.2 +++ b/app/main/initiative/revoke.lua	Thu Jul 10 01:19:48 2014 +0200
    76.3 @@ -1,26 +1,60 @@
    76.4  local initiative = Initiative:by_id(param.get_id())
    76.5 +local initiatives = app.session.member
    76.6 +  :get_reference_selector("supported_initiatives")
    76.7 +  :join("issue", nil, "issue.id = initiative.issue_id")
    76.8 +  :add_where("issue.closed ISNULL")
    76.9 +  :add_order_by("issue.id")
   76.10 +  :exec()
   76.11  
   76.12 -slot.put_into("title", _"Revoke initiative")
   76.13 +  
   76.14 +local member = app.session.member
   76.15 +if member then
   76.16 +  initiative:load_everything_for_member_id(member.id)
   76.17 +  initiative.issue:load_everything_for_member_id(member.id)
   76.18 +end
   76.19 +
   76.20 +
   76.21 +local tmp = { { id = -1, myname = _"Suggest no initiative" }}
   76.22 +for i, initiative in ipairs(initiatives) do
   76.23 +  initiative.myname = _("Issue ##{issue_id}: #{initiative_name}", {
   76.24 +    issue_id = initiative.issue.id,
   76.25 +    initiative_name = initiative.name
   76.26 +  })
   76.27 +  tmp[#tmp+1] = initiative
   76.28 +end
   76.29  
   76.30 -slot.select("actions", function()
   76.31 -  ui.link{
   76.32 -    content = function()
   76.33 -        ui.image{ static = "icons/16/cancel.png" }
   76.34 -        slot.put(_"Cancel")
   76.35 -    end,
   76.36 -    module = "initiative",
   76.37 -    view = "show",
   76.38 -    id = initiative.id,
   76.39 -    params = {
   76.40 -      tab = "initiators"
   76.41 -    }
   76.42 +execute.view {
   76.43 +  module = "issue", view = "_head", params = {
   76.44 +    issue = initiative.issue,
   76.45 +    member = member
   76.46    }
   76.47 -end)
   76.48 +}
   76.49 +execute.view{ module = "issue", view = "_sidebar_state", params = {
   76.50 +  initiative = initiative
   76.51 +} }
   76.52  
   76.53 -util.help("initiative.revoke")
   76.54 +execute.view { 
   76.55 +  module = "issue", view = "_sidebar_issue", 
   76.56 +  params = {
   76.57 +    issue = initiative.issue,
   76.58 +    highlight_initiative_id = initiative.id
   76.59 +  }
   76.60 +}
   76.61 +
   76.62 +execute.view {
   76.63 +  module = "issue", view = "_sidebar_whatcanido",
   76.64 +  params = { initiative = initiative }
   76.65 +}
   76.66 +
   76.67 +execute.view { 
   76.68 +  module = "issue", view = "_sidebar_members", params = {
   76.69 +    issue = initiative.issue, initiative = initiative
   76.70 +  }
   76.71 +}
   76.72 +
   76.73  
   76.74  ui.form{
   76.75 -  attr = { class = "vertical" },
   76.76 +  attr = { class = "wide section" },
   76.77    module = "initiative",
   76.78    action = "revoke",
   76.79    id = initiative.id,
   76.80 @@ -33,30 +67,67 @@
   76.81      }
   76.82    },
   76.83    content = function()
   76.84 -    local initiatives = app.session.member
   76.85 -      :get_reference_selector("supported_initiatives")
   76.86 -      :join("issue", nil, "issue.id = initiative.issue_id")
   76.87 -      :add_field("'Issue #' || issue.id || ': ' || initiative.name", "myname")
   76.88 -      :exec()
   76.89 +
   76.90 +    ui.sectionHead( function()
   76.91 +      ui.link{
   76.92 +        module = "initiative", view = "show", id = initiative.id,
   76.93 +        content = function ()
   76.94 +          ui.heading { 
   76.95 +            level = 1,
   76.96 +            content = initiative.display_name
   76.97 +          }
   76.98 +        end
   76.99 +      }
  76.100 +      ui.heading { level = 2, content = _"Revoke initiative" }
  76.101 +    end )
  76.102 +
  76.103 +    ui.sectionRow( function()
  76.104  
  76.105 -    local tmp = { { id = -1, myname = _"Suggest no initiative" }}
  76.106 -    for i, initiative in ipairs(initiatives) do
  76.107 -      tmp[#tmp+1] = initiative
  76.108 -    end
  76.109 -    ui.field.select{
  76.110 -      label = _"Suggested initiative",
  76.111 -      name = "suggested_initiative_id",
  76.112 -      foreign_records = tmp,
  76.113 -      foreign_id = "id",
  76.114 -      foreign_name = "myname",
  76.115 -      value = param.get("suggested_initiative_id", atom.integer)
  76.116 -    }
  76.117 -    slot.put("")
  76.118 -    ui.field.boolean{
  76.119 -      label = _"Are you sure?",
  76.120 -      name = "are_you_sure",
  76.121 -    }
  76.122 +      ui.heading{ level = 2, content = _"Do you want to suggest to support another initiative?" }
  76.123 +    
  76.124 +      ui.field.select{
  76.125 +        name = "suggested_initiative_id",
  76.126 +        foreign_records = tmp,
  76.127 +        foreign_id = "id",
  76.128 +        foreign_name = "myname",
  76.129 +        value = param.get("suggested_initiative_id", atom.integer)
  76.130 +      }
  76.131 +      ui.container{ content = _"You may choose one of the ongoing initiatives you are currently supporting" }
  76.132 +      slot.put("<br />")
  76.133 +      ui.heading { level = 2, content = _"Are you aware that revoking an initiative is irrevocable?" }
  76.134 +      ui.container{ content = function()
  76.135 +        ui.tag{ tag = "input", attr = {
  76.136 +          type = "checkbox",
  76.137 +          name = "are_you_sure",
  76.138 +          value = "1"
  76.139 +        } }
  76.140 +        ui.tag { content = _"I understand, that this is not revocable" }
  76.141 +      end }
  76.142 +      
  76.143 +      
  76.144 +      slot.put("<br />")
  76.145 +      ui.tag{
  76.146 +        tag = "input",
  76.147 +        attr = {
  76.148 +          type = "submit",
  76.149 +          class = "btn btn-dangerous",
  76.150 +          value = _"Revoke now"
  76.151 +        },
  76.152 +        content = ""
  76.153 +      }
  76.154 +      slot.put("<br />")
  76.155 +      slot.put("<br />")
  76.156  
  76.157 -    ui.submit{ text = _"Revoke initiative" }
  76.158 +      ui.link{
  76.159 +        content = _"Cancel",
  76.160 +        module = "initiative",
  76.161 +        view = "show",
  76.162 +        id = initiative.id,
  76.163 +        params = {
  76.164 +          tab = "initiators"
  76.165 +        }
  76.166 +      }
  76.167 +    end )
  76.168 +
  76.169    end
  76.170  }
  76.171 \ No newline at end of file
    77.1 --- a/app/main/initiative/show.lua	Thu Jul 10 01:02:43 2014 +0200
    77.2 +++ b/app/main/initiative/show.lua	Thu Jul 10 01:19:48 2014 +0200
    77.3 @@ -1,7 +1,541 @@
    77.4 -local initiative = Initiative:by_id(param.get_id())
    77.5 +local initiative = Initiative:by_id ( param.get_id() )
    77.6 +local member = app.session.member
    77.7 +
    77.8 +if not initiative then
    77.9 +  execute.view { module = "index", view = "404" }
   77.10 +  request.set_status("404 Not Found")
   77.11 +  return
   77.12 +end
   77.13 +
   77.14 +local issue_info
   77.15 +
   77.16 +if member then
   77.17 +  initiative:load_everything_for_member_id(member.id)
   77.18 +  initiative.issue:load_everything_for_member_id(member.id)
   77.19 +  issue_info = initiative.issue.member_info
   77.20 +end
   77.21 +
   77.22 +execute.view {
   77.23 +  module = "issue", view = "_head", 
   77.24 +  params = {
   77.25 +    issue = initiative.issue,
   77.26 +    initiative = initiative,
   77.27 +    member = app.session.member
   77.28 +  }
   77.29 +}
   77.30 +
   77.31 +if app.session.member_id then
   77.32 +  direct_supporter = initiative.issue.member_info.own_participation and initiative.member_info.supported
   77.33 +end
   77.34  
   77.35 -execute.view{
   77.36 -  module = "initiative", view = "_show", params = {
   77.37 -    initiative = initiative
   77.38 +ui.script { script = [[
   77.39 +  function showTab(tabId) {
   77.40 +    $('.tab').hide();
   77.41 +    $('.main').hide();
   77.42 +    $('.main, .slot_extra .section').hide();
   77.43 +    $('.' + tabId).show();
   77.44 +    if (tabId == "main") $('.slot_extra .section').show();
   77.45 +  };
   77.46 +  showTab('main');
   77.47 +]]}
   77.48 +
   77.49 +execute.view{ module = "issue", view = "_sidebar_state", params = {
   77.50 +  initiative = initiative
   77.51 +} }
   77.52 +
   77.53 +execute.view { 
   77.54 +  module = "issue", view = "_sidebar_issue", 
   77.55 +  params = {
   77.56 +    issue = initiative.issue,
   77.57 +    highlight_initiative_id = initiative.id
   77.58 +  }
   77.59 +}
   77.60 +
   77.61 +execute.view {
   77.62 +  module = "issue", view = "_sidebar_whatcanido",
   77.63 +  params = { initiative = initiative }
   77.64 +}
   77.65 +
   77.66 +execute.view { 
   77.67 +  module = "issue", view = "_sidebar_members", params = {
   77.68 +    issue = initiative.issue, initiative = initiative
   77.69    }
   77.70  }
   77.71 +
   77.72 +ui.section( function ()
   77.73 +  execute.view{
   77.74 +    module = "initiative", view = "_head", params = {
   77.75 +      initiative = initiative
   77.76 +    }
   77.77 +  }
   77.78 +
   77.79 +  if direct_supporter and not initiative.issue.closed then
   77.80 +    local supporter = app.session.member:get_reference_selector("supporters")
   77.81 +      :add_where{ "initiative_id = ?", initiative.id }
   77.82 +      :optional_object_mode()
   77.83 +      :exec()
   77.84 +      
   77.85 +    if supporter then
   77.86 +
   77.87 +      local old_draft_id = supporter.draft_id
   77.88 +      local new_draft_id = initiative.current_draft.id
   77.89 +      
   77.90 +      if old_draft_id ~= new_draft_id then
   77.91 +        ui.sectionRow( "draft_updated_info", function ()
   77.92 +          ui.container{ 
   77.93 +            attr = { class = "info" },
   77.94 +            content = _"The draft of this initiative has been updated!"
   77.95 +          }
   77.96 +          slot.put(" ")
   77.97 +          ui.link{
   77.98 +            content = _"show differences",
   77.99 +            module = "draft",
  77.100 +            view = "diff",
  77.101 +            params = {
  77.102 +              old_draft_id = old_draft_id,
  77.103 +              new_draft_id = new_draft_id
  77.104 +            }
  77.105 +          }
  77.106 +          if not initiative.revoked then
  77.107 +            slot.put(" | ")
  77.108 +            ui.link{
  77.109 +              text   = _"refresh my support",
  77.110 +              module = "initiative",
  77.111 +              action = "add_support",
  77.112 +              id     = initiative.id,
  77.113 +              params = { draft_id = initiative.current_draft.id },
  77.114 +              routing = {
  77.115 +                default = {
  77.116 +                  mode = "redirect",
  77.117 +                  module = "initiative",
  77.118 +                  view = "show",
  77.119 +                  id = initiative.id
  77.120 +                }
  77.121 +              }
  77.122 +            }
  77.123 +            slot.put(" | ")
  77.124 +          end
  77.125 +
  77.126 +          ui.link{
  77.127 +            text   = _"remove my support",
  77.128 +            module = "initiative",
  77.129 +            action = "remove_support",
  77.130 +            id     = initiative.id,
  77.131 +            routing = {
  77.132 +              default = {
  77.133 +                mode = "redirect",
  77.134 +                module = "initiative",
  77.135 +                view = "show",
  77.136 +                id = initiative.id
  77.137 +              }
  77.138 +            }
  77.139 +          }
  77.140 +
  77.141 +        end )
  77.142 +      end
  77.143 +    end
  77.144 +  end
  77.145 +  
  77.146 +
  77.147 +  ui.sectionRow( function ()
  77.148 +    ui.container {
  77.149 +      attr = { class = "draft" },
  77.150 +      content = function ()
  77.151 +        slot.put ( initiative.current_draft:get_content ( "html" ) )
  77.152 +      end
  77.153 +    }
  77.154 +  end )
  77.155 +
  77.156 +end)
  77.157 +
  77.158 +ui.link { attr = { name = "suggestions" }, text = "" }
  77.159 +
  77.160 +
  77.161 +ui.container {
  77.162 +  attr = { class = "section suggestions" },
  77.163 +  content = function ()
  77.164 +
  77.165 +    if # ( initiative.suggestions ) > 0 then
  77.166 +  
  77.167 +      ui.sectionHead( function ()
  77.168 +        ui.heading { 
  77.169 +          level = 1, 
  77.170 +          content = _("Suggestions for improvement (#{count})", { count = # ( initiative.suggestions ) } ) 
  77.171 +        }
  77.172 +        ui.container { content = _"written and rated by the supportes of this initiative to improve the proposal and its reasons" }
  77.173 +      end )
  77.174 +      
  77.175 +      for i, suggestion in ipairs(initiative.suggestions) do
  77.176 +        
  77.177 +        local opinion = Opinion:by_pk(app.session.member_id, suggestion.id)
  77.178 +
  77.179 +        local class = "sectionRow suggestion"
  77.180 +        if suggestion.id == param.get("suggestion_id", atom.number) then
  77.181 +          class = class .. " highlighted"
  77.182 +        end
  77.183 +        if member and not initiative.issue.fully_frozen and not initiative.issue.closed and initiative.member_info.supported then
  77.184 +          class = class .. " rateable"
  77.185 +        end
  77.186 +      
  77.187 +        
  77.188 +        ui.tag { tag = "div", attr = { class = class, id = "s" .. suggestion.id }, content = function ()
  77.189 +
  77.190 +          if opinion then
  77.191 +            
  77.192 +            ui.container { attr = { class = "opinion"}, content = function()
  77.193 +              local class = ""
  77.194 +              local text = ""
  77.195 +              
  77.196 +              if opinion.degree == 2 then
  77.197 +                class = "must"
  77.198 +                text = _"must"
  77.199 +              elseif opinion.degree == 1 then
  77.200 +                class = "should"
  77.201 +                text = _"should"
  77.202 +              elseif opinion.degree == 0 then
  77.203 +                class = "neutral"
  77.204 +                text = _"neutral"
  77.205 +              elseif opinion.degree == -1 then
  77.206 +                class = "shouldnot"
  77.207 +                text = _"should not"
  77.208 +              elseif opinion.degree == -2 then
  77.209 +                class = "mustnot"
  77.210 +                text = _"must not"
  77.211 +              end
  77.212 +              
  77.213 +              ui.tag { 
  77.214 +                attr = { class = class }, 
  77.215 +                content = text 
  77.216 +              }
  77.217 +              
  77.218 +              slot.put ( " " )
  77.219 +              
  77.220 +              if 
  77.221 +                (opinion.degree > 0 and not opinion.fulfilled)
  77.222 +                or (opinion.degree < 0 and opinion.fulfilled)
  77.223 +              then
  77.224 +                ui.tag{ content = _"but" }
  77.225 +              else
  77.226 +                ui.tag{ content = _"and" }
  77.227 +              end
  77.228 +                
  77.229 +              slot.put ( " " )
  77.230 +              
  77.231 +              local class = ""
  77.232 +              local text = ""
  77.233 +              
  77.234 +              if opinion.fulfilled then
  77.235 +                class = "implemented"
  77.236 +                text = _"is implemented"
  77.237 +              else
  77.238 +                class = "notimplemented"
  77.239 +                text = _"is not implemented"
  77.240 +              end
  77.241 +
  77.242 +              ui.tag { 
  77.243 +                attr = { class = class }, 
  77.244 +                content = text
  77.245 +              }
  77.246 +
  77.247 +              if 
  77.248 +                (opinion.degree > 0 and not opinion.fulfilled)
  77.249 +                or (opinion.degree < 0 and opinion.fulfilled)
  77.250 +              then
  77.251 +                if math.abs(opinion.degree) > 1 then
  77.252 +                  slot.put(" !!")
  77.253 +                else
  77.254 +                  slot.put(" !")
  77.255 +                end
  77.256 +              else
  77.257 +                slot.put(" ✓")
  77.258 +              end
  77.259 +
  77.260 +            end }
  77.261 +
  77.262 +          end
  77.263 +          
  77.264 +          
  77.265 +          ui.link { attr = { name = "s" .. suggestion.id }, text = "" }
  77.266 +          ui.heading { level = 2, 
  77.267 +            attr = { class = "suggestionHead" },
  77.268 +            content = format.string(suggestion.name, {
  77.269 +            truncate_at = 160, truncate_suffix = true
  77.270 +          }) }
  77.271 +  
  77.272 +
  77.273 +            local plus2  = (suggestion.plus2_unfulfilled_count or 0)
  77.274 +                            + (suggestion.plus2_fulfilled_count or 0)
  77.275 +            local plus1  = (suggestion.plus1_unfulfilled_count  or 0)
  77.276 +                            + (suggestion.plus1_fulfilled_count or 0)
  77.277 +            local minus1 = (suggestion.minus1_unfulfilled_count  or 0)
  77.278 +                            + (suggestion.minus1_fulfilled_count or 0)
  77.279 +            local minus2 = (suggestion.minus2_unfulfilled_count  or 0)
  77.280 +                            + (suggestion.minus2_fulfilled_count or 0)
  77.281 +            
  77.282 +            local with_opinion = plus2 + plus1 + minus1 + minus2
  77.283 +
  77.284 +            local neutral = (suggestion.initiative.supporter_count or 0)
  77.285 +                            - with_opinion
  77.286 +
  77.287 +            local neutral2 = with_opinion 
  77.288 +                              - (suggestion.plus2_fulfilled_count or 0)
  77.289 +                              - (suggestion.plus1_fulfilled_count or 0)
  77.290 +                              - (suggestion.minus1_fulfilled_count or 0)
  77.291 +                              - (suggestion.minus2_fulfilled_count or 0)
  77.292 +            
  77.293 +            ui.container { 
  77.294 +            attr = { class = "suggestionInfo" },
  77.295 +            content = function ()
  77.296 +              
  77.297 +              if with_opinion > 0 then
  77.298 +                ui.container { attr = { class = "suggestion-rating" }, content = function ()
  77.299 +                  ui.tag { content = _"collective rating:" }
  77.300 +                  slot.put("&nbsp;")
  77.301 +                  ui.bargraph{
  77.302 +                    max_value = suggestion.initiative.supporter_count,
  77.303 +                    width = 100,
  77.304 +                    bars = {
  77.305 +                      { color = "#0a0", value = plus2 },
  77.306 +                      { color = "#8a8", value = plus1 },
  77.307 +                      { color = "#eee", value = neutral },
  77.308 +                      { color = "#a88", value = minus1 },
  77.309 +                      { color = "#a00", value = minus2 },
  77.310 +                    }
  77.311 +                  }
  77.312 +                  slot.put(" | ")
  77.313 +                  ui.tag { content = _"implemented:" }
  77.314 +                  slot.put ( "&nbsp;" )
  77.315 +                  ui.bargraph{
  77.316 +                    max_value = with_opinion,
  77.317 +                    width = 100,
  77.318 +                    bars = {
  77.319 +                      { color = "#0a0", value = suggestion.plus2_fulfilled_count },
  77.320 +                      { color = "#8a8", value = suggestion.plus1_fulfilled_count },
  77.321 +                      { color = "#eee", value = neutral2 },
  77.322 +                      { color = "#a88", value = suggestion.minus1_fulfilled_count },
  77.323 +                      { color = "#a00", value = suggestion.minus2_fulfilled_count },
  77.324 +                    }
  77.325 +                  }
  77.326 +                end }
  77.327 +              end
  77.328 +
  77.329 +              if app.session:has_access("authors_pseudonymous") then
  77.330 +                util.micro_avatar ( suggestion.author )
  77.331 +              else
  77.332 +                slot.put("<br />")
  77.333 +              end
  77.334 +              
  77.335 +              ui.container {
  77.336 +                attr = { class = "suggestion-text" },
  77.337 +                content = function ()
  77.338 +                  slot.put ( suggestion:get_content( "html" ) )
  77.339 +
  77.340 +              if direct_supporter then
  77.341 +                
  77.342 +                ui.container {
  77.343 +                  attr = { class = "rating" },
  77.344 +                  content = function ()
  77.345 +
  77.346 +                    if not opinion then
  77.347 +                      opinion = {}
  77.348 +                    end
  77.349 +                    ui.form { 
  77.350 +                      module = "opinion", action = "update", params = {
  77.351 +                        suggestion_id = suggestion.id
  77.352 +                      },
  77.353 +                      routing = { default = {
  77.354 +                        mode = "redirect", 
  77.355 +                        module = "initiative", view = "show", id = suggestion.initiative_id,
  77.356 +                        params = { suggestion_id = suggestion.id },
  77.357 +                        anchor = "s" .. suggestion.id -- TODO webmcp
  77.358 +                      } },
  77.359 +                      content = function ()
  77.360 +                      
  77.361 +                        
  77.362 +                        ui.heading { level = 3, content = _"Should the initiator implement this suggestion?" }
  77.363 +                        ui.container { content = function ()
  77.364 +                        
  77.365 +                          local active = opinion.degree == 2
  77.366 +                          ui.tag { tag = "input", attr = {
  77.367 +                            type = "radio", name = "degree", value = 2, 
  77.368 +                            id = "s" .. suggestion.id .. "_degree2",
  77.369 +                            checked = active and "checked" or nil
  77.370 +                          } }
  77.371 +                          ui.tag { 
  77.372 +                            tag = "label", 
  77.373 +                            attr = {
  77.374 +                              ["for"] = "s" .. suggestion.id .. "_degree2",
  77.375 +                              class = active and "active-plus2" or nil,
  77.376 +                            },
  77.377 +                            content = _"must"
  77.378 +                          }
  77.379 +                          
  77.380 +                          local active = opinion.degree == 1
  77.381 +                          ui.tag { tag = "input", attr = {
  77.382 +                            type = "radio", name = "degree", value = 1,
  77.383 +                            id = "s" .. suggestion.id .. "_degree1",
  77.384 +                            checked = active and "checked" or nil
  77.385 +                          } }
  77.386 +                          ui.tag { 
  77.387 +                            tag = "label", 
  77.388 +                            attr = {
  77.389 +                              ["for"] = "s" .. suggestion.id .. "_degree1",
  77.390 +                              class = active and "active-plus1" or nil,
  77.391 +                            },
  77.392 +                            content = _"should"
  77.393 +                          }
  77.394 +
  77.395 +                          local active = not opinion.member_id
  77.396 +                          ui.tag { tag = "input", attr = {
  77.397 +                            type = "radio", name = "degree", value = 0,
  77.398 +                            id = "s" .. suggestion.id .. "_degree0",
  77.399 +                            checked = active and "checked" or nil
  77.400 +                          } }
  77.401 +                          ui.tag { 
  77.402 +                            tag = "label", 
  77.403 +                            attr = {
  77.404 +                              ["for"] = "s" .. suggestion.id .. "_degree0",
  77.405 +                              class = active and "active-neutral" or nil,
  77.406 +                            },
  77.407 +                            content = _"neutral"
  77.408 +                          }
  77.409 +
  77.410 +                          local active = opinion.degree == -1
  77.411 +                          ui.tag { tag = "input", attr = {
  77.412 +                            type = "radio", name = "degree", value = -1,
  77.413 +                            id = "s" .. suggestion.id .. "_degree-1",
  77.414 +                            checked = active and "checked" or nil
  77.415 +                          } }
  77.416 +                          ui.tag { 
  77.417 +                            tag = "label", 
  77.418 +                            attr = {
  77.419 +                              ["for"] = "s" .. suggestion.id .. "_degree-1",
  77.420 +                              class = active and "active-minus1" or nil,
  77.421 +                            },
  77.422 +                            content = _"should not"
  77.423 +                          }
  77.424 +
  77.425 +                          local active = opinion.degree == -2
  77.426 +                          ui.tag { tag = "input", attr = {
  77.427 +                            type = "radio", name = "degree", value = -2,
  77.428 +                            id = "s" .. suggestion.id .. "_degree-2",
  77.429 +                            checked = active and "checked" or nil
  77.430 +                          } }
  77.431 +                          ui.tag { 
  77.432 +                            tag = "label", 
  77.433 +                            attr = {
  77.434 +                              ["for"] = "s" .. suggestion.id .. "_degree-2",
  77.435 +                              class = active and "active-minus2" or nil,
  77.436 +                            },
  77.437 +                            content = _"must not"
  77.438 +                          }
  77.439 +                        end }
  77.440 +                        
  77.441 +                        slot.put("<br />")
  77.442 +
  77.443 +                        ui.heading { level = 3, content = _"Did the initiator implement this suggestion?" }
  77.444 +                        ui.container { content = function ()
  77.445 +                          local active = opinion.fulfilled == false
  77.446 +                          ui.tag { tag = "input", attr = {
  77.447 +                            type = "radio", name = "fulfilled", value = "false",
  77.448 +                            id = "s" .. suggestion.id .. "_notfulfilled",
  77.449 +                            checked = active and "checked" or nil
  77.450 +                          } }
  77.451 +                          ui.tag { 
  77.452 +                            tag = "label", 
  77.453 +                            attr = {
  77.454 +                              ["for"] = "s" .. suggestion.id .. "_notfulfilled",
  77.455 +                              class = active and "active-notfulfilled" or nil,
  77.456 +                            },
  77.457 +                            content = _"No (not yet)"
  77.458 +                          }
  77.459 +
  77.460 +                          local active = opinion.fulfilled
  77.461 +                          ui.tag { tag = "input", attr = {
  77.462 +                            type = "radio", name = "fulfilled", value = "true",
  77.463 +                            id = "s" .. suggestion.id .. "_fulfilled",
  77.464 +                            checked = active and "checked" or nil
  77.465 +                          } }
  77.466 +                          ui.tag { 
  77.467 +                            tag = "label", 
  77.468 +                            attr = {
  77.469 +                              ["for"] = "s" .. suggestion.id .. "_fulfilled",
  77.470 +                              class = active and "active-fulfilled" or nil,
  77.471 +                            },
  77.472 +                            content = _"Yes, it's implemented"
  77.473 +                          }
  77.474 +                        end }
  77.475 +                        slot.put("<br />")
  77.476 +                        
  77.477 +                        ui.tag{
  77.478 +                          tag = "input",
  77.479 +                          attr = {
  77.480 +                            type = "submit",
  77.481 +                            class = "btn btn-default",
  77.482 +                            value = _"publish my rating"
  77.483 +                          },
  77.484 +                          content = ""
  77.485 +                        }
  77.486 +                        
  77.487 +                      end 
  77.488 +                    }
  77.489 +
  77.490 +                  end -- if not issue,fully_frozen or closed
  77.491 +                }
  77.492 +              end 
  77.493 +                
  77.494 +                local text = _"Read more"
  77.495 +                
  77.496 +                if direct_supporter then
  77.497 +                  text = _"Show more and rate this"
  77.498 +                end
  77.499 +                  
  77.500 +                ui.link { 
  77.501 +                  attr = { 
  77.502 +                    class = "suggestion-more",
  77.503 +                    onclick = "$('#s" .. suggestion.id .. "').removeClass('folded').addClass('unfolded'); return false;"
  77.504 +                  },
  77.505 +                  text = text
  77.506 +                }
  77.507 +                
  77.508 +                ui.link { 
  77.509 +                  attr = { 
  77.510 +                    class = "suggestion-less",
  77.511 +                    onclick = "$('#s" .. suggestion.id .. "').addClass('folded').removeClass('unfolded'); return false;"
  77.512 +                  },
  77.513 +                  text = _"Show less"
  77.514 +                }
  77.515 +                end
  77.516 +              }
  77.517 +              
  77.518 +              ui.script{ script = [[
  77.519 +                var textEl = $('#s]] .. suggestion.id .. [[ .suggestion-text');
  77.520 +                var height = textEl.height();
  77.521 +                if (height > 150) $('#s]] .. suggestion.id .. [[').addClass('folded');
  77.522 +              ]] }
  77.523 +               
  77.524 +            end
  77.525 +          } -- ui.paragraph
  77.526 +          
  77.527 +              
  77.528 +
  77.529 +        end } -- ui.tag "li"
  77.530 +        
  77.531 +      end -- for i, suggestion
  77.532 +      
  77.533 +    else -- if #initiative.suggestions > 0
  77.534 +      
  77.535 +      local text
  77.536 +      if initiative.issue.closed then
  77.537 +        text = "No suggestions"
  77.538 +      else
  77.539 +        text = "No suggestions (yet)"
  77.540 +      end
  77.541 +      ui.sectionHead( function()
  77.542 +        ui.heading { level = 1, content = text }
  77.543 +      end)
  77.544 +      
  77.545 +    end -- if #initiative.suggestions > 0
  77.546 +    
  77.547 +  end
  77.548 +}
    78.1 --- a/app/main/interest/_action/update.lua	Thu Jul 10 01:02:43 2014 +0200
    78.2 +++ b/app/main/interest/_action/update.lua	Thu Jul 10 01:19:48 2014 +0200
    78.3 @@ -4,6 +4,10 @@
    78.4  
    78.5  local issue = Issue:new_selector():add_where{ "id = ?", issue_id }:for_share():single_object_mode():exec()
    78.6  
    78.7 +if not app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then
    78.8 +  error("access denied")
    78.9 +end
   78.10 +
   78.11  if issue.closed then
   78.12    slot.put_into("error", _"This issue is already closed.")
   78.13    return false
   78.14 @@ -21,23 +25,17 @@
   78.15  if param.get("delete", atom.boolean) then
   78.16    if interest then
   78.17      interest:destroy()
   78.18 -    --slot.put_into("notice", _"Interest removed")
   78.19 +    slot.put_into("notice", _"Interest removed")
   78.20    else
   78.21 -    --slot.put_into("notice", _"Interest not existent")
   78.22 +    slot.put_into("notice", _"Interest already removed")
   78.23    end
   78.24    return
   78.25  end
   78.26  
   78.27 -if not app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then
   78.28 -  error("access denied")
   78.29 -end
   78.30 -
   78.31  if not interest then
   78.32    interest = Interest:new()
   78.33    interest.issue_id   = issue_id
   78.34    interest.member_id  = app.session.member_id
   78.35 +  interest:save()
   78.36 +  slot.put_into("notice", _"Interest updated")
   78.37  end
   78.38 -
   78.39 -interest:save()
   78.40 -
   78.41 ---slot.put_into("notice", _"Interest updated")
    79.1 --- a/app/main/interest/show_incoming.lua	Thu Jul 10 01:02:43 2014 +0200
    79.2 +++ b/app/main/interest/show_incoming.lua	Thu Jul 10 01:19:48 2014 +0200
    79.3 @@ -10,11 +10,25 @@
    79.4    :add_field{ "delegating_interest_snapshot.weight" }
    79.5  
    79.6  execute.view{
    79.7 -  module = "member",
    79.8 -  view = "_list",
    79.9 -  params = { 
   79.10 -    members_selector = members_selector,
   79.11 -    issue = issue,
   79.12 -    trustee = member
   79.13 +  module = "issue", view = "_head", params = {
   79.14 +    issue = issue
   79.15    }
   79.16 -}
   79.17 \ No newline at end of file
   79.18 +}
   79.19 +  
   79.20 +ui.section( function()
   79.21 +    
   79.22 +  ui.sectionHead( function()
   79.23 +    ui.heading{ level = 1, content = _("Incoming delegations for '#{member}'", { member = member.name }) }
   79.24 +  end)
   79.25 +
   79.26 +  execute.view{
   79.27 +    module = "member",
   79.28 +    view = "_list",
   79.29 +    params = { 
   79.30 +      members_selector = members_selector,
   79.31 +      issue = issue,
   79.32 +      trustee = member
   79.33 +    }
   79.34 +  }
   79.35 +
   79.36 +end )
   79.37 \ No newline at end of file
    80.1 --- a/app/main/issue/_details.lua	Thu Jul 10 01:02:43 2014 +0200
    80.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.3 @@ -1,58 +0,0 @@
    80.4 -local issue = param.get("issue", "table")
    80.5 -
    80.6 -local policy = issue.policy
    80.7 -ui.form{
    80.8 -  record = issue,
    80.9 -  readonly = true,
   80.10 -  attr = { class = "vertical" },
   80.11 -  content = function()
   80.12 -    ui.field.text{       label = _"Population",            name = "population" }
   80.13 -    ui.field.timestamp{  label = _"Created at",            name = "created" }
   80.14 -    if policy.polling then
   80.15 -      ui.field.text{       label = _"Admission time",        value = _"Implicitly admitted" }
   80.16 -    else
   80.17 -      ui.field.text{       label = _"Admission time",        value = format.interval_text(issue.admission_time_text) }
   80.18 -      ui.field.text{
   80.19 -        label = _"Issue quorum",
   80.20 -        value = format.percentage(policy.issue_quorum_num / policy.issue_quorum_den)
   80.21 -      }
   80.22 -      if issue.population then
   80.23 -        ui.field.text{
   80.24 -          label = _"Currently required",
   80.25 -          value = math.ceil(issue.population * policy.issue_quorum_num / policy.issue_quorum_den)
   80.26 -        }
   80.27 -      end
   80.28 -    end
   80.29 -    if issue.accepted then
   80.30 -      ui.field.timestamp{  label = _"Accepted at",           name = "accepted" }
   80.31 -    end
   80.32 -    ui.field.text{       label = _"Discussion time",       value = format.interval_text(issue.discussion_time_text) }
   80.33 -    if issue.half_frozen then
   80.34 -      ui.field.timestamp{  label = _"Half frozen at",        name = "half_frozen" }
   80.35 -    end
   80.36 -    ui.field.text{       label = _"Verification time",     value = format.interval_text(issue.verification_time_text) }
   80.37 -    ui.field.text{
   80.38 -      label   = _"Initiative quorum",
   80.39 -      value = format.percentage(policy.initiative_quorum_num / policy.initiative_quorum_den)
   80.40 -    }
   80.41 -    if issue.population then
   80.42 -      ui.field.text{
   80.43 -        label   = _"Currently required",
   80.44 -        value = math.ceil(issue.population * (issue.policy.initiative_quorum_num / issue.policy.initiative_quorum_den)),
   80.45 -      }
   80.46 -    end
   80.47 -    if issue.fully_frozen then
   80.48 -      ui.field.timestamp{  label = _"Fully frozen at",       name = "fully_frozen" }
   80.49 -    end
   80.50 -    ui.field.text{       label = _"Voting time",           value = format.interval_text(issue.voting_time_text) }
   80.51 -    if issue.closed then
   80.52 -      ui.field.timestamp{  label = _"Closed",                name = "closed" }
   80.53 -    end
   80.54 -  end
   80.55 -}
   80.56 -ui.form{
   80.57 -  record = issue.policy,
   80.58 -  readonly = true,
   80.59 -  content = function()
   80.60 -  end
   80.61 -}
    81.1 --- a/app/main/issue/_filters.lua	Thu Jul 10 01:02:43 2014 +0200
    81.2 +++ b/app/main/issue/_filters.lua	Thu Jul 10 01:19:48 2014 +0200
    81.3 @@ -1,386 +1,326 @@
    81.4 -local member = param.get("member", "table")
    81.5 -local for_member = param.get("for_member", "table")
    81.6 -local state = param.get("state")
    81.7 +local params = param.get_all_cgi()
    81.8 +
    81.9  local for_unit = param.get("for_unit", atom.boolean)
   81.10  local for_area = param.get("for_area", atom.boolean)
   81.11 -
   81.12  local for_events = param.get("for_events", atom.boolean)
   81.13 +local for_member = param.get("for_member", "table")
   81.14 +local member = param.get("member", "table")
   81.15 +local phase = params["phase"]
   81.16  
   81.17  local filters = {}
   81.18  
   81.19 -local filter = { name = "filter" }
   81.20 -  
   81.21 -if state ~= "closed" then
   81.22 -  filter[#filter+1] = {
   81.23 -    name = "any",
   81.24 -    label = _"Any phase",
   81.25 -    selector_modifier = function(selector) end
   81.26 -  }
   81.27 +local admission_order_field = "filter_issue_order.order_in_unit"
   81.28 +if for_area then
   81.29 +  admission_order_field = "filter_issue_order.order_in_area"
   81.30  end
   81.31  
   81.32 -if not state then
   81.33 +if not for_issue and not for_member then
   81.34 +  
   81.35 +  -- mode
   81.36 +
   81.37 +  local filter = { class = "filter_mode", name = "mode" }
   81.38 +  
   81.39 +  filter[#filter+1] = {
   81.40 +    name = "issue",
   81.41 +    label = _"issue view",
   81.42 +    selector_modifier = function () end
   81.43 +  }
   81.44 +
   81.45    filter[#filter+1] = {
   81.46 -    name = "open",
   81.47 -    label = _"Open",
   81.48 -    selector_modifier = function(selector)
   81.49 -      if for_events then
   81.50 -        selector:add_where("event.state in ('admission', 'discussion', 'verification', 'voting')")
   81.51 -      else
   81.52 -        selector:add_where("issue.closed ISNULL")
   81.53 +    name = "timeline",
   81.54 +    label = _"timeline",
   81.55 +    selector_modifier = function ( selector ) 
   81.56 +      selector:add_order_by ( "event.occurrence DESC" )
   81.57 +      selector:add_order_by ( "id DESC" )
   81.58 +    end
   81.59 +  }
   81.60 +
   81.61 +  filters[#filters+1] = filter
   81.62 +
   81.63 +  -- context
   81.64 +
   81.65 +  local filter = { class = "filter_filter", name = "filter" }
   81.66 +  
   81.67 +  if member and not for_unit and not for_area then
   81.68 +    filter[#filter+1] = {
   81.69 +      name = "my_units",
   81.70 +      label = _"in my units",
   81.71 +      selector_modifier = function ( selector )
   81.72 +        selector:join ( "area", "filter_area", "filter_area.id = issue.area_id" )
   81.73 +        selector:join ( "privilege", "filter_privilege", { 
   81.74 +          "filter_privilege.unit_id = filter_area.unit_id AND filter_privilege.member_id = ?", member.id
   81.75 +        })
   81.76 +      end
   81.77 +    }
   81.78 +  end
   81.79 +  
   81.80 +  if member and not for_area then
   81.81 +    
   81.82 +    filter[#filter+1] = {
   81.83 +      name = "my_areas",
   81.84 +      label = _"in my areas",
   81.85 +      selector_modifier = function ( selector )
   81.86 +        selector:join ( "membership", "filter_membership", { 
   81.87 +          "filter_membership.area_id = issue.area_id AND filter_membership.member_id = ?", member.id
   81.88 +        })
   81.89 +      end
   81.90 +    }
   81.91 +  end
   81.92 +  
   81.93 +  if member then
   81.94 +    filter[#filter+1] = {
   81.95 +      name = "my_issues",
   81.96 +      label = _"my issues",
   81.97 +      selector_modifier = function ( selector )
   81.98 +        selector:left_join("interest", "filter_interest", { "filter_interest.issue_id = issue.id AND filter_interest.member_id = ? ", member.id })
   81.99 +        --selector:left_join("direct_interest_snapshot", "filter_interest_s", { "filter_interest_s.issue_id = issue.id AND filter_interest_s.member_id = ? AND filter_interest_s.event = issue.latest_snapshot_event", member.id })
  81.100 +        selector:left_join("delegating_interest_snapshot", "filter_d_interest_s", { "filter_d_interest_s.issue_id = issue.id AND filter_d_interest_s.member_id = ? AND filter_d_interest_s.event = issue.latest_snapshot_event", member.id })
  81.101 +      end
  81.102 +    }
  81.103 +  end
  81.104 +  
  81.105 +  filter[#filter+1] = {
  81.106 +    name = "all",
  81.107 +    label = _"all issues",
  81.108 +    selector_modifier = function()  end
  81.109 +  }
  81.110 +
  81.111 +  filters[#filters+1] = filter
  81.112 +
  81.113 +  -- phase
  81.114 +  
  81.115 +  local filter = { name = "phase" }
  81.116 +  
  81.117 +  filter[#filter+1] = {
  81.118 +    name = "all",
  81.119 +    label = _"in all phases",
  81.120 +    selector_modifier = function ( selector )
  81.121 +      if not for_events then
  81.122 +        selector:left_join ( "issue_order_in_admission_state", "filter_issue_order",    "filter_issue_order.id = issue.id" )
  81.123 +        selector:add_order_by ( "issue.closed DESC NULLS FIRST" )
  81.124 +        selector:add_order_by ( "issue.accepted ISNULL" )
  81.125 +        selector:add_order_by ( "CASE WHEN issue.accepted ISNULL THEN NULL ELSE justify_interval(coalesce(issue.fully_frozen + issue.voting_time, issue.half_frozen + issue.verification_time, issue.accepted + issue.discussion_time, issue.created + issue.admission_time) - now()) END" )
  81.126 +        selector:add_order_by ( "CASE WHEN issue.accepted ISNULL THEN " .. admission_order_field .. " ELSE NULL END" )
  81.127 +        selector:add_order_by ( "id" )
  81.128        end
  81.129      end
  81.130    }
  81.131 -end
  81.132  
  81.133 -if not state or state == "open" then
  81.134    filter[#filter+1] = {
  81.135 -    name = "new",
  81.136 -    label = _"New",
  81.137 -    selector_modifier = function(selector)
  81.138 -      if for_events then
  81.139 -        selector:add_where("event.state = 'admission'")
  81.140 -      else
  81.141 -        selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL")
  81.142 +    name = "admission",
  81.143 +    label = _"(1) Admission",
  81.144 +    selector_modifier = function ( selector )
  81.145 +      selector:add_where { "issue.state = ?", "admission" }
  81.146 +      if not for_events then
  81.147 +        selector:left_join ( "issue_order_in_admission_state", "filter_issue_order", "filter_issue_order.id = issue.id" )
  81.148 +        selector:add_order_by ( admission_order_field )
  81.149 +        selector:add_order_by ( "id" )
  81.150        end
  81.151      end
  81.152    }
  81.153 +
  81.154    filter[#filter+1] = {
  81.155 -    name = "accepted",
  81.156 -    label = _"Discussion",
  81.157 -    selector_modifier = function(selector)
  81.158 -      if for_events then
  81.159 -        selector:add_where("event.state = 'discussion'")
  81.160 -      else
  81.161 -        selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL")
  81.162 +    name = "discussion",
  81.163 +    label = _"(2) Discussion",
  81.164 +    selector_modifier = function ( selector )
  81.165 +      selector:add_where { "issue.state = ?", "discussion" }
  81.166 +      if not for_events then
  81.167 +        selector:add_order_by ( "issue.accepted + issue.discussion_time - now()" )
  81.168 +        selector:add_order_by ( "id" )
  81.169        end
  81.170      end
  81.171    }
  81.172 +
  81.173    filter[#filter+1] = {
  81.174 -    name = "half_frozen",
  81.175 -    label = _"Frozen",
  81.176 -    selector_modifier = function(selector)
  81.177 -      if for_events then
  81.178 -        selector:add_where("event.state = 'verification'")
  81.179 -      else
  81.180 -        selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL")
  81.181 +    name = "verification",
  81.182 +    label = _"(3) Verification",
  81.183 +    selector_modifier = function ( selector )
  81.184 +      selector:add_where { "issue.state = ?", "verification" }
  81.185 +      if not for_events then
  81.186 +        selector:add_order_by ( "issue.half_frozen + issue.verification_time - now()" )
  81.187 +        selector:add_order_by ( "id" )
  81.188 +      end
  81.189 +    end
  81.190 +  }
  81.191 +
  81.192 +  filter[#filter+1] = {
  81.193 +    name = "voting",
  81.194 +    label = _"(4) Voting",
  81.195 +    selector_modifier = function ( selector )
  81.196 +      selector:add_where { "issue.state = ?", "voting" }
  81.197 +      if not for_events then
  81.198 +        selector:add_order_by ( "issue.fully_frozen + issue.voting_time - now()" )
  81.199 +        selector:add_order_by ( "id" )
  81.200        end
  81.201      end
  81.202    }
  81.203 -  filter[#filter+1] = {
  81.204 -    name = "frozen",
  81.205 -    label = _"Voting",
  81.206 -    selector_modifier = function(selector)
  81.207 -      if for_events then
  81.208 -        selector:add_where("event.state = 'voting'")
  81.209 -      else
  81.210 -        selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL")
  81.211 -      end
  81.212 -      filter_voting = true
  81.213 -    end
  81.214 -  }
  81.215 -end
  81.216  
  81.217 -if not state then
  81.218    filter[#filter+1] = {
  81.219 -    name = "finished",
  81.220 -    label = _"Finished",
  81.221 -    selector_modifier = function(selector)
  81.222 -      if for_events then
  81.223 -        selector:add_where("event.state IN ('finished_with_winner', 'finished_without_winner')")
  81.224 -      else
  81.225 -        selector:add_where("issue.closed NOTNULL AND issue.fully_frozen NOTNULL")
  81.226 -      end
  81.227 -    end
  81.228 -  }
  81.229 -  filter[#filter+1] = {
  81.230 -    name = "canceled",
  81.231 -    label = _"Canceled",
  81.232 -    selector_modifier = function(selector)
  81.233 -        
  81.234 -      if for_events then
  81.235 -        selector:add_where("event.state IN ('canceled_revoked_before_accepted', 'canceled_issue_not_accepted', 'canceled_after_revocation_during_discussion', 'canceled_after_revocation_during_verification')")
  81.236 -      else
  81.237 -        selector:add_where("issue.closed NOTNULL AND issue.fully_frozen ISNULL")
  81.238 +    name = "closed",
  81.239 +    label = _"(5) Result",
  81.240 +    selector_modifier = function ( selector )
  81.241 +      if not for_events then
  81.242 +        selector:add_where ( "issue.closed NOTNULL" )
  81.243 +        selector:add_order_by ( "issue.closed DESC" )
  81.244 +        selector:add_order_by ( "id" )
  81.245        end
  81.246      end
  81.247    }
  81.248 -end
  81.249 +
  81.250 +  filters[#filters+1] = filter
  81.251 +  
  81.252 +  -- my issues
  81.253 +
  81.254 +  if params["filter"] == "my_issues" then
  81.255 +    
  81.256 +    local delegation = params["delegation"]
  81.257  
  81.258 -if state == "closed" then
  81.259 -  filter[#filter+1] = {
  81.260 -    name = "any",
  81.261 -    label = _"Any state",
  81.262 -    selector_modifier = function(selector) end
  81.263 -  }
  81.264 +    local filter = { class = "filter_interest subfilter", name = "interest" }
  81.265 +    
  81.266 +    filter[#filter+1] = {
  81.267 +      name = "all",
  81.268 +      label = _"interested directly or via delegation",
  81.269 +      selector_modifier = function ( selector ) 
  81.270 +        selector:add_where ( "filter_interest.issue_id NOTNULL OR filter_d_interest_s.issue_id NOTNULL" )
  81.271 +      end
  81.272 +    }
  81.273 +
  81.274 +    filter[#filter+1] = {
  81.275 +      name = "direct",
  81.276 +      label = _"direct interest",
  81.277 +      selector_modifier = function ( selector )  
  81.278 +        selector:add_where ( "filter_interest.issue_id NOTNULL" )
  81.279 +      end
  81.280 +    }
  81.281  
  81.282 -  filter[#filter+1] = {
  81.283 -    name = "finished",
  81.284 -    label = _"Finished",
  81.285 -    selector_modifier = function(selector)
  81.286 -      if for_events then
  81.287 -        selector:add_where("event.state IN ('finished_with_winner', 'finished_without_winner')")
  81.288 -      else
  81.289 -        selector:add_where("issue.state IN ('finished_with_winner', 'finished_without_winner')")
  81.290 +    filter[#filter+1] = {
  81.291 +      name = "via_delegation",
  81.292 +      label = _"interest via delegation",
  81.293 +      selector_modifier = function ( selector )  
  81.294 +        selector:add_where ( "filter_d_interest_s.issue_id NOTNULL" )
  81.295 +      end
  81.296 +    }
  81.297 +
  81.298 +    filter[#filter+1] = {
  81.299 +      name = "initiated",
  81.300 +      label = _"initiated by me",
  81.301 +      selector_modifier = function ( selector )  
  81.302 +        selector:add_where ( "filter_interest.issue_id NOTNULL" )
  81.303        end
  81.304 -    end
  81.305 -  }
  81.306 -  filter[#filter+1] = {
  81.307 -    name = "finished_with_winner",
  81.308 -    label = _"with winner",
  81.309 -    selector_modifier = function(selector)
  81.310 -      if for_events then
  81.311 -        selector:add_where("event.state = 'finished_with_winner'")
  81.312 -      else
  81.313 -        selector:add_where("issue.state = 'finished_with_winner'")
  81.314 +    }
  81.315 +    
  81.316 +    filters[#filters+1] = filter
  81.317 +
  81.318 +  end
  81.319 +  
  81.320 +  -- voting
  81.321 +
  81.322 +  if phase == "voting" and member then
  81.323 +  
  81.324 +    local filter = { class = "subfilter", name = "voted" }
  81.325 +    
  81.326 +    filter[#filter+1] = {
  81.327 +      name = "all",
  81.328 +      label = _"voted and not voted by me",
  81.329 +      selector_modifier = function(selector)  end
  81.330 +    }
  81.331 +
  81.332 +    filter[#filter+1] = {
  81.333 +      name = "voted",
  81.334 +      label = _"voted by me",
  81.335 +      selector_modifier = function(selector) 
  81.336 +        selector:join("direct_voter", "filter_direct_voter", { "filter_direct_voter.issue_id = issue.id AND filter_direct_voter.member_id = ?", member.id })
  81.337        end
  81.338 -    end
  81.339 -  }
  81.340 -  filter[#filter+1] = {
  81.341 -    name = "finished_without_winner",
  81.342 -    label = _"without winner",
  81.343 -    selector_modifier = function(selector)
  81.344 -      if for_events then
  81.345 -        selector:add_where("event.state = 'finished_without_winner'")
  81.346 -      else
  81.347 -        selector:add_where("issue.state = 'finished_without_winner'")
  81.348 +    }
  81.349 +
  81.350 +    filter[#filter+1] = {
  81.351 +      name = "not_voted",
  81.352 +      label = _"not voted by me",
  81.353 +      selector_modifier = function(selector)
  81.354 +        selector:left_join("direct_voter", "filter_direct_voter", { "filter_direct_voter.issue_id = issue.id AND filter_direct_voter.member_id = ?", member.id })
  81.355 +        selector:add_where("filter_direct_voter.issue_id ISNULL")
  81.356        end
  81.357 -    end
  81.358 -  }
  81.359 -  filter[#filter+1] = {
  81.360 -    name = "canceled",
  81.361 -    label = _"Canceled",
  81.362 -    selector_modifier = function(selector)
  81.363 -      if for_events then
  81.364 -        selector:add_where("event.state NOT IN ('finished_with_winner', 'finished_without_winner')")
  81.365 -      else
  81.366 -        selector:add_where("issue.state NOT IN ('finished_with_winner', 'finished_without_winner')")
  81.367 +    }
  81.368 +    filters[#filters+1] = filter
  81.369 +    
  81.370 +    
  81.371 +  end
  81.372 +  
  81.373 +  -- closed
  81.374 +
  81.375 +  if phase == "closed" then
  81.376 +  
  81.377 +    local filter = { class = "subfilter", name = "closed" }
  81.378 +    
  81.379 +    filter[#filter+1] = {
  81.380 +      name = "finished",
  81.381 +      label = _"finished",
  81.382 +      selector_modifier = function ( selector )
  81.383 +        selector:add_where ( "issue.state::text like 'finished_%'" )
  81.384 +      end
  81.385 +    }
  81.386 +
  81.387 +    filter[#filter+1] = {
  81.388 +      name = "canceled",
  81.389 +      label = _"canceled",
  81.390 +      selector_modifier = function ( selector )  
  81.391 +        selector:add_where ( "issue.closed NOTNULL AND NOT issue.state::text like 'finished_%' AND issue.accepted NOTNULL" )
  81.392        end
  81.393 -    end
  81.394 -  }
  81.395 -end
  81.396 +    }
  81.397 +
  81.398 +    filter[#filter+1] = {
  81.399 +      name = "not_accepted",
  81.400 +      label = _"not admitted",
  81.401 +      selector_modifier = function ( selector )  
  81.402 +        selector:add_where ( "issue.closed NOTNULL AND issue.accepted ISNULL" )
  81.403 +      end
  81.404 +    }
  81.405  
  81.406 -filters[#filters+1] = filter
  81.407 -
  81.408 +    if member then
  81.409 +      filter[#filter+1] = {
  81.410 +        name = "voted",
  81.411 +        label = _"voted by me",
  81.412 +        selector_modifier = function(selector)
  81.413 +          selector:left_join("direct_voter", "filter_direct_voter", { "filter_direct_voter.issue_id = issue.id AND filter_direct_voter.member_id = ?", member.id })
  81.414 +          selector:left_join("delegating_voter", "filter_delegating_voter", { "filter_delegating_voter.issue_id = issue.id AND filter_delegating_voter.member_id = ?", member.id })
  81.415 +          selector:add_where("filter_direct_voter.issue_id NOTNULL or filter_delegating_voter.issue_id NOTNULL")
  81.416 +        end
  81.417 +      }
  81.418  
  81.419 -if member then
  81.420 -  local filter = {
  81.421 -    name = "filter_interest",
  81.422 -  }
  81.423 -  if not for_member then
  81.424 -    if not for_unit and not for_area then
  81.425 +      filter[#filter+1] = {
  81.426 +        name = "voted_direct",
  81.427 +        label = _"voted directly by me",
  81.428 +        selector_modifier = function(selector)
  81.429 +          selector:join("direct_voter", "filter_direct_voter", { "filter_direct_voter.issue_id = issue.id AND filter_direct_voter.member_id = ?", member.id })
  81.430 +        end
  81.431 +      }
  81.432 +
  81.433        filter[#filter+1] = {
  81.434 -        name = "any",
  81.435 -        label = _"All units",
  81.436 -        selector_modifier = function()  end
  81.437 +        name = "voted_via_delegation",
  81.438 +        label = _"voted via delegation",
  81.439 +        selector_modifier = function(selector)
  81.440 +          selector:join("delegating_voter", "filter_delegating_voter", { "filter_delegating_voter.issue_id = issue.id AND filter_delegating_voter.member_id = ?", member.id })
  81.441 +        end
  81.442        }
  81.443 +
  81.444        filter[#filter+1] = {
  81.445 -        name = "unit",
  81.446 -        label = _"My units",
  81.447 +        name = "not_voted",
  81.448 +        label = _"not voted by me",
  81.449          selector_modifier = function(selector)
  81.450 -          selector:join("area", nil, "area.id = issue.area_id")
  81.451 -          selector:join("privilege", nil, { "privilege.unit_id = area.unit_id AND privilege.member_id = ? AND privilege.voting_right", member.id })
  81.452 +          selector:left_join("direct_voter", "filter_direct_voter", { "filter_direct_voter.issue_id = issue.id AND filter_direct_voter.member_id = ?", member.id })
  81.453 +          selector:left_join("delegating_voter", "filter_delegating_voter", { "filter_delegating_voter.issue_id = issue.id AND filter_delegating_voter.member_id = ?", member.id })
  81.454 +          selector:add_where("filter_direct_voter.issue_id ISNULL AND filter_delegating_voter.issue_id ISNULL")
  81.455          end
  81.456        }
  81.457      end
  81.458 -    if for_unit and not for_area then
  81.459 -    filter[#filter+1] = {
  81.460 -        name = "any",
  81.461 -        label = _"All areas",
  81.462 -        selector_modifier = function()  end
  81.463 -      }
  81.464 -    end
  81.465 -    if not for_area then
  81.466 -      filter[#filter+1] = {
  81.467 -        name = "area",
  81.468 -        label = _"My areas",
  81.469 -        selector_modifier = function(selector)
  81.470 -          selector:join("membership", nil, { "membership.area_id = issue.area_id AND membership.member_id = ?", member.id })
  81.471 -        end
  81.472 -      }
  81.473 -    end
  81.474 -    if for_area then
  81.475 -    filter[#filter+1] = {
  81.476 -        name = "any",
  81.477 -        label = _"All issues",
  81.478 -        selector_modifier = function()  end
  81.479 -      }
  81.480 -    end
  81.481 -  end
  81.482 -  filter[#filter+1] = {
  81.483 -    name = "issue",
  81.484 -    label = _"Interested",
  81.485 -    selector_modifier = function() end
  81.486 -  }
  81.487 -  filter[#filter+1] = {
  81.488 -    name = "initiated",
  81.489 -    label = _"Initiated",
  81.490 -    selector_modifier = function(selector)
  81.491 -      selector:add_where({ "EXISTS (SELECT 1 FROM initiative JOIN initiator ON initiator.initiative_id = initiative.id AND initiator.member_id = ? AND initiator.accepted WHERE initiative.issue_id = issue.id)", member.id })
  81.492 -    end
  81.493 -  }
  81.494 -  filter[#filter+1] = {
  81.495 -    name = "supported",
  81.496 -    label = _"Supported",
  81.497 -    selector_modifier = function() end
  81.498 -  }
  81.499 -  filter[#filter+1] = {
  81.500 -    name = "potentially_supported",
  81.501 -    label = _"Potentially supported",
  81.502 -    selector_modifier = function() end
  81.503 -  }
  81.504 -  if state == 'closed' or (for_events) then
  81.505 -    filter[#filter+1] = {
  81.506 -      name = "voted",
  81.507 -      label = _"Voted",
  81.508 -      selector_modifier = function() end
  81.509 -    }
  81.510 +    
  81.511 +    filters[#filters+1] = filter
  81.512 +    
  81.513 +    
  81.514    end
  81.515  
  81.516 -  filters[#filters+1] = filter
  81.517 +  
  81.518  end
  81.519  
  81.520  
  81.521 -
  81.522 -if app.session.member then
  81.523 -
  81.524 -  local filter_interest = param.get_all_cgi()["filter_interest"]
  81.525 -    
  81.526 -  if filter_interest ~= "any" and filter_interest ~= nil and (
  81.527 -    filter_interest == "issue" or filter_interest == "supported" or filter_interest == "potentially_supported" or 
  81.528 -    (filter_interest == 'voted' and state ~= 'open')
  81.529 -  ) then
  81.530 -    
  81.531 -    local function add_default_joins(selector)
  81.532 -      selector:left_join("interest", "filter_interest", { "filter_interest.issue_id = issue.id AND filter_interest.member_id = ? ", member.id })
  81.533 -      selector:left_join("direct_interest_snapshot", "filter_interest_s", { "filter_interest_s.issue_id = issue.id AND filter_interest_s.member_id = ? AND filter_interest_s.event = issue.latest_snapshot_event", member.id })
  81.534 -      selector:left_join("delegating_interest_snapshot", "filter_d_interest_s", { "filter_d_interest_s.issue_id = issue.id AND filter_d_interest_s.member_id = ? AND filter_d_interest_s.event = issue.latest_snapshot_event", member.id })        
  81.535 -    end
  81.536 -    
  81.537 -    filters[#filters+1] = {
  81.538 -      name = "filter_delegation",
  81.539 -      {
  81.540 -        name = "any",
  81.541 -        label = _"Direct and by delegation",
  81.542 -        selector_modifier = function(selector)
  81.543 -          add_default_joins(selector)
  81.544 -          selector:add_where("CASE WHEN issue.fully_frozen ISNULL AND issue.closed ISNULL THEN filter_interest.member_id NOTNULL ELSE filter_interest_s.member_id NOTNULL END OR filter_d_interest_s.member_id NOTNULL")
  81.545 -          if filter_interest == "supported" then
  81.546 -            selector:add_where({ 
  81.547 -              "CASE WHEN issue.fully_frozen ISNULL AND issue.closed ISNULL THEN " ..
  81.548 -                "EXISTS(SELECT 1 FROM initiative JOIN supporter ON supporter.initiative_id = initiative.id AND supporter.member_id = ? LEFT JOIN critical_opinion ON critical_opinion.initiative_id = initiative.id AND critical_opinion.member_id = supporter.member_id WHERE initiative.issue_id = issue.id AND critical_opinion.member_id ISNULL) " ..
  81.549 -              "ELSE " ..
  81.550 -                "EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = ? AND direct_supporter_snapshot.satisfied) " ..
  81.551 -              "END OR EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = filter_d_interest_s.delegate_member_ids[array_upper(filter_d_interest_s.delegate_member_ids,1)] AND direct_supporter_snapshot.satisfied)", member.id, member.id, member.id })
  81.552 -
  81.553 -          elseif filter_interest == "potentially_supported" then
  81.554 -            selector:add_where({
  81.555 -              "CASE WHEN issue.fully_frozen ISNULL AND issue.closed ISNULL THEN " ..
  81.556 -                "EXISTS(SELECT 1 FROM initiative JOIN supporter ON supporter.initiative_id = initiative.id AND supporter.member_id = ? LEFT JOIN critical_opinion ON critical_opinion.initiative_id = initiative.id AND critical_opinion.member_id = supporter.member_id WHERE initiative.issue_id = issue.id AND critical_opinion.member_id NOTNULL) " ..
  81.557 -              "ELSE " ..
  81.558 -                "EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = ? AND NOT direct_supporter_snapshot.satisfied) " ..
  81.559 -              "END OR EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = filter_d_interest_s.delegate_member_ids[array_upper(filter_d_interest_s.delegate_member_ids,1)] AND NOT direct_supporter_snapshot.satisfied)", member.id, member.id, member.id })
  81.560 -
  81.561 -          elseif filter_interest == "voted" then
  81.562 -            selector:add_where({ "EXISTS(SELECT 1 FROM direct_voter WHERE direct_voter.issue_id = issue.id AND direct_voter.member_id = ?) OR (issue.closed NOTNULL AND EXISTS(SELECT 1 FROM delegating_voter WHERE delegating_voter.issue_id = issue.id AND delegating_voter.member_id = ?)) ", member.id, member.id })
  81.563 -
  81.564 -          end
  81.565 -
  81.566 -        end
  81.567 -      },
  81.568 -      {
  81.569 -        name = "direct",
  81.570 -        label = _"Direct",
  81.571 -        selector_modifier = function(selector)
  81.572 -          add_default_joins(selector)
  81.573 -          selector:add_where("CASE WHEN issue.fully_frozen ISNULL AND issue.closed ISNULL THEN filter_interest.member_id NOTNULL ELSE filter_interest_s.member_id NOTNULL END")
  81.574 -
  81.575 -          if filter_interest == "supported" then
  81.576 -            selector:add_where({ 
  81.577 -              "CASE WHEN issue.fully_frozen ISNULL AND issue.closed ISNULL THEN " ..
  81.578 -                "EXISTS(SELECT 1 FROM initiative JOIN supporter ON supporter.initiative_id = initiative.id AND supporter.member_id = ? LEFT JOIN critical_opinion ON critical_opinion.initiative_id = initiative.id AND critical_opinion.member_id = supporter.member_id WHERE initiative.issue_id = issue.id AND critical_opinion.member_id ISNULL) " ..
  81.579 -              "ELSE " ..
  81.580 -                "EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = ? AND direct_supporter_snapshot.satisfied) " ..
  81.581 -              "END", member.id, member.id })
  81.582 -
  81.583 -          elseif filter_interest == "potentially_supported" then
  81.584 -            selector:add_where({
  81.585 -              "CASE WHEN issue.fully_frozen ISNULL AND issue.closed ISNULL THEN " ..
  81.586 -                "EXISTS(SELECT 1 FROM initiative JOIN supporter ON supporter.initiative_id = initiative.id AND supporter.member_id = ? LEFT JOIN critical_opinion ON critical_opinion.initiative_id = initiative.id AND critical_opinion.member_id = supporter.member_id WHERE initiative.issue_id = issue.id AND critical_opinion.member_id NOTNULL) " ..
  81.587 -              "ELSE " ..
  81.588 -                "EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = ? AND NOT direct_supporter_snapshot.satisfied) " ..
  81.589 -              "END", member.id, member.id })
  81.590 -          elseif filter_interest == "voted" then
  81.591 -            selector:add_where({ "EXISTS(SELECT 1 FROM direct_voter WHERE direct_voter.issue_id = issue.id AND direct_voter.member_id = ?) ", member.id })
  81.592 -
  81.593 -          end
  81.594 -        end
  81.595 -      },
  81.596 -      {
  81.597 -        name = "delegated",
  81.598 -        label = _"By delegation",
  81.599 -        selector_modifier = function(selector)
  81.600 -          add_default_joins(selector)
  81.601 -          selector:add_where("filter_d_interest_s.member_id NOTNULL AND filter_interest.member_id ISNULL")
  81.602 -
  81.603 -          if filter_interest == "supported" then
  81.604 -            selector:add_where({ 
  81.605 -              "EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = filter_d_interest_s.delegate_member_ids[array_upper(filter_d_interest_s.delegate_member_ids,1)] AND direct_supporter_snapshot.satisfied)", member.id })
  81.606 -
  81.607 -          elseif filter_interest == "potentially_supported" then
  81.608 -            selector:add_where({ 
  81.609 -              "EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = filter_d_interest_s.delegate_member_ids[array_upper(filter_d_interest_s.delegate_member_ids,1)] AND NOT direct_supporter_snapshot.satisfied)", member.id })
  81.610 -          elseif filter_interest == "voted" then
  81.611 -            selector:add_where({ "issue.closed NOTNULL AND EXISTS(SELECT 1 FROM delegating_voter WHERE delegating_voter.issue_id = issue.id AND delegating_voter.member_id = ?) ", member.id })
  81.612 -
  81.613 -          end
  81.614 -        end
  81.615 -      }
  81.616 -    }
  81.617 -  end
  81.618 -
  81.619 -end
  81.620 -
  81.621 -if state == 'open' and app.session.member and member.id == app.session.member_id and (param.get_all_cgi()["filter"] == "frozen") then
  81.622 -  filters[#filters+1] = {
  81.623 -    name = "filter_voting",
  81.624 -    {
  81.625 -      name = "any",
  81.626 -      label = _"Any",
  81.627 -      selector_modifier = function()  end
  81.628 -    },
  81.629 -    {
  81.630 -      name = "not_voted",
  81.631 -      label = _"Not voted",
  81.632 -      selector_modifier = function(selector)
  81.633 -        selector:left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", member.id })
  81.634 -        selector:add_where("direct_voter.member_id ISNULL")
  81.635 -        selector:left_join("non_voter", nil, { "non_voter.issue_id = issue.id AND non_voter.member_id = ?", member.id })
  81.636 -        selector:add_where("non_voter.member_id ISNULL")
  81.637 -      end
  81.638 -    },
  81.639 -    {
  81.640 -      name = "voted",
  81.641 -      label = _"Voted",
  81.642 -      selector_modifier = function(selector)
  81.643 -        selector:join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", member.id })
  81.644 -      end
  81.645 -    },
  81.646 -  }
  81.647 -end
  81.648 -
  81.649 -
  81.650 -
  81.651 -
  81.652 -function filters:get_filter(group, name)
  81.653 -  for i,grp in ipairs(self) do
  81.654 -    if grp.name == group then
  81.655 -      for i,entry in ipairs(grp) do
  81.656 -        if entry.name == name then
  81.657 -          return entry
  81.658 -        end
  81.659 -      end
  81.660 -    end
  81.661 -  end
  81.662 -end
  81.663 -
  81.664 -return filters
  81.665 \ No newline at end of file
  81.666 +return filters
    82.1 --- a/app/main/issue/_head.lua	Thu Jul 10 01:02:43 2014 +0200
    82.2 +++ b/app/main/issue/_head.lua	Thu Jul 10 01:19:48 2014 +0200
    82.3 @@ -1,3 +1,74 @@
    82.4  local issue = param.get("issue", "table")
    82.5 +local initiative = param.get("initiative", "table")
    82.6 +
    82.7 +local member = param.get ( "member", "table" )
    82.8 +
    82.9 +
   82.10 +ui.title ( function ()
   82.11 +
   82.12 +  ui.tag {
   82.13 +    attr = { class = "unit" },
   82.14 +    content = function()
   82.15 +      ui.link {
   82.16 +        content = function()
   82.17 +          ui.tag{ attr = { class = "name" }, content = issue.area.unit.name }
   82.18 +        end,
   82.19 +        module = "unit", view = "show",
   82.20 +        id = issue.area.unit.id
   82.21 +      }
   82.22 +    end
   82.23 +  }
   82.24 +  ui.tag { attr = { class = "spacer" }, content = function()
   82.25 +    slot.put ( " » " )
   82.26 +  end }
   82.27 +
   82.28 +  ui.tag {
   82.29 +    attr = { class = "area" },
   82.30 +    content = function()
   82.31 +      ui.link {
   82.32 +        content = function()
   82.33 +          ui.tag{ attr = { class = "name" }, content = issue.area.name }
   82.34 +        end,
   82.35 +        module = "area", view = "show",
   82.36 +        id = issue.area.id
   82.37 +      }
   82.38 +    end
   82.39 +  }
   82.40  
   82.41 -execute.view{ module = "area", view = "_head", params = { area = issue.area } }
   82.42 +  ui.tag { attr = { class = "spacer" }, content = function()
   82.43 +    slot.put ( " » " )
   82.44 +  end }
   82.45 +  
   82.46 +  ui.tag {
   82.47 +    attr = { class = "issue" },
   82.48 +    content = function()
   82.49 +      -- issue link
   82.50 +      ui.link {
   82.51 +        text = _("#{policy_name} ##{issue_id}", { 
   82.52 +          policy_name = issue.policy.name,
   82.53 +          issue_id = issue.id
   82.54 +        } ),
   82.55 +        module = "issue", view = "show",
   82.56 +        id = issue.id
   82.57 +      }
   82.58 +
   82.59 +      slot.put ( " " )
   82.60 +      
   82.61 +      if member then
   82.62 +        execute.view {
   82.63 +          module = "delegation", view = "_info", params = { 
   82.64 +            issue = issue, member = member, for_title = true
   82.65 +          }
   82.66 +        }
   82.67 +      end
   82.68 +    end
   82.69 +  }
   82.70 +  
   82.71 +  if initiative then
   82.72 +    ui.tag{
   82.73 +      attr = { class = "initiative" },
   82.74 +      content = initiative.display_name
   82.75 +    }
   82.76 +  end
   82.77 +  
   82.78 +end ) -- ui.title
    83.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.2 +++ b/app/main/issue/_head2.lua	Thu Jul 10 01:19:48 2014 +0200
    83.3 @@ -0,0 +1,96 @@
    83.4 +local issue = param.get("issue", "table")
    83.5 +local for_history = param.get("for_history", atom.boolean)
    83.6 +
    83.7 +ui.sectionHead( "issueInfo", function ()
    83.8 +  ui.container { attr = { class = "left" }, content = function()
    83.9 +    ui.heading { level = 1, content = issue.name }
   83.10 +  end }
   83.11 +  if app.session.member then
   83.12 +    ui.container { attr = { class = "right" }, content = function ()
   83.13 +      if issue.fully_frozen then
   83.14 +        if issue.member_info.direct_voted then
   83.15 +          ui.image { attr = { class = "icon48 right" }, static = "icons/48/voted_ok.png" }
   83.16 +          ui.tag { content = _"You have voted" }
   83.17 +          slot.put(" ")
   83.18 +          if not issue.closed then
   83.19 +            slot.put("<br />")
   83.20 +            ui.link {
   83.21 +              module = "vote", view = "list", 
   83.22 +              params = { issue_id = issue.id },
   83.23 +              text = _"change vote"
   83.24 +            }
   83.25 +          else
   83.26 +            ui.link {
   83.27 +              module = "vote", view = "list", 
   83.28 +              params = { issue_id = issue.id },
   83.29 +              text = _"show vote"
   83.30 +            }
   83.31 +          end
   83.32 +          slot.put(" ")
   83.33 +        elseif active_trustee_id then
   83.34 +          ui.tag { content = _"You have voted via delegation" }
   83.35 +          ui.link {
   83.36 +            content = _"Show voting ballot",
   83.37 +            module = "vote", view = "list", params = {
   83.38 +              issue_id = issue.id, member_id = active_trustee_id
   83.39 +            }
   83.40 +          }
   83.41 +        elseif not issue.closed then
   83.42 +          ui.link {
   83.43 +            attr = { class = "btn btn-default" },
   83.44 +            module = "vote", view = "list", 
   83.45 +            params = { issue_id = issue.id },
   83.46 +            text = _"vote now"
   83.47 +          }
   83.48 +        end
   83.49 +      elseif not issue.closed then
   83.50 +        if issue.member_info.own_participation then
   83.51 +          ui.image { attr = { class = "icon48 right" }, static = "icons/48/eye.png" }
   83.52 +          ui.tag{ content = _"You are interested in this issue" }
   83.53 +          slot.put("<br />")
   83.54 +          ui.link {
   83.55 +            module = "interest", action = "update", 
   83.56 +            params = { issue_id = issue.id, delete = true },
   83.57 +            routing = { default = {
   83.58 +              mode = "redirect", module = "issue", view = "show", id = issue.id
   83.59 +            } },
   83.60 +            text = _"remove my interest"
   83.61 +          }
   83.62 +        else
   83.63 +          ui.link {
   83.64 +            attr = { class = "btn btn-default" },
   83.65 +            module = "interest", action = "update", 
   83.66 +            params = { issue_id = issue.id },
   83.67 +            routing = { default = {
   83.68 +              mode = "redirect", module = "issue", view = "show", id = issue.id
   83.69 +            } },
   83.70 +            text = _"add my interest"
   83.71 +          }
   83.72 +        end
   83.73 +      end
   83.74 +    end }
   83.75 +  end
   83.76 +end)
   83.77 +  
   83.78 +ui.container {
   83.79 +  attr = { class = "ui_filter", style="clear: left; margin-top: 4px;" },
   83.80 +  content = function ()
   83.81 +    ui.container {
   83.82 +      attr = { class = "ui_filter_head" },
   83.83 +      content = function ()
   83.84 +        
   83.85 +        ui.link{
   83.86 +          attr = { class = not for_history and "active" or nil },
   83.87 +          text = _"Initiatives",
   83.88 +          module = "issue", view = "show", id = issue.id
   83.89 +        }
   83.90 +        slot.put(" ")
   83.91 +        ui.link{
   83.92 +          attr = { class = for_history and "active" or nil },
   83.93 +          text = _"History",
   83.94 +          module = "issue", view = "history", id = issue.id
   83.95 +        }
   83.96 +      end
   83.97 +    }
   83.98 +  end
   83.99 +}
    84.1 --- a/app/main/issue/_list.lua	Thu Jul 10 01:02:43 2014 +0200
    84.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.3 @@ -1,57 +0,0 @@
    84.4 -local issues_selector = param.get("issues_selector", "table")
    84.5 -local member = param.get("for_member", "table") or app.session.member
    84.6 -local for_member = param.get("for_member", "table")
    84.7 -local for_state = param.get("for_state")
    84.8 -local for_unit = param.get("for_unit", atom.boolean)
    84.9 -local for_area = param.get("for_area", atom.boolean)
   84.10 -
   84.11 -
   84.12 -if for_state == "open" then
   84.13 -  issues_selector:add_where("issue.closed ISNULL")
   84.14 -elseif for_state == "closed" then
   84.15 -  issues_selector:add_where("issue.closed NOTNULL")
   84.16 -end
   84.17 -
   84.18 -ui.add_partial_param_names{
   84.19 -  "filter",
   84.20 -  "filter_open",
   84.21 -  "filter_voting",
   84.22 -  "filter_interest",
   84.23 -  "issue_list" 
   84.24 -}
   84.25 -
   84.26 -local filters = execute.load_chunk{module="issue", chunk="_filters.lua", params = {
   84.27 -  member = member, for_member = for_member, state = for_state, for_unit = for_unit, for_area = for_area
   84.28 -}}
   84.29 -
   84.30 -filters.content = function()
   84.31 -  ui.paginate{
   84.32 -    per_page = tonumber(param.get("per_page") or 25),
   84.33 -    selector = issues_selector,
   84.34 -    content = function()
   84.35 -      local highlight_string = param.get("highlight_string", "string")
   84.36 -      local issues = issues_selector:exec()
   84.37 -      issues:load_everything_for_member_id(member and member.id or nil)
   84.38 -
   84.39 -      ui.container{ attr = { class = "issues" }, content = function()
   84.40 -
   84.41 -        for i, issue in ipairs(issues) do
   84.42 -
   84.43 -          execute.view{ module = "issue", view = "_show", params = {
   84.44 -            issue = issue, for_listing = true, for_member = for_member
   84.45 -          } }
   84.46 -          
   84.47 -        end
   84.48 -      end }
   84.49 -    end
   84.50 -  }
   84.51 -end
   84.52 -
   84.53 -filters.opened = true
   84.54 -filters.selector = issues_selector
   84.55 -
   84.56 -if param.get("no_filter", atom.boolean) then
   84.57 -  filters.content()
   84.58 -else
   84.59 -  ui.filters(filters)
   84.60 -end
    85.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.2 +++ b/app/main/issue/_list2.lua	Thu Jul 10 01:19:48 2014 +0200
    85.3 @@ -0,0 +1,373 @@
    85.4 +local for_member = param.get ( "for_member", "table" )
    85.5 +local for_unit =   param.get ( "for_unit",   "table" )
    85.6 +local for_area =   param.get ( "for_area",   "table" )
    85.7 +local for_issue =  param.get ( "for_issue",  "table" )
    85.8 +local for_initiative =  param.get ( "for_initiative",  "table" )
    85.9 +local for_sidebar = param.get("for_sidebar", atom.boolean)
   85.10 +local no_filter =  param.get ( "no_filter",  atom.boolean )
   85.11 +local search =     param.get ( "search" )
   85.12 +
   85.13 +local limit = 25
   85.14 +
   85.15 +local mode = param.get_all_cgi()["mode"] or "issue"
   85.16 +
   85.17 +if for_initiative or for_issue or for_member then
   85.18 +  mode = "timeline"
   85.19 +end
   85.20 +
   85.21 +local selector
   85.22 +
   85.23 +if search then
   85.24 +
   85.25 +  selector = Issue:get_search_selector(search)
   85.26 +
   85.27 +  
   85.28 +elseif mode == "timeline" then
   85.29 +
   85.30 +  local event_max_id = param.get_all_cgi()["event_max_id"]
   85.31 +
   85.32 +  selector = Event:new_selector()
   85.33 +    :add_order_by("event.id DESC")
   85.34 +    :join("issue", nil, "issue.id = event.issue_id")
   85.35 +    :add_field("now() - event.occurrence", "time_ago")
   85.36 +    :limit(limit + 1)
   85.37 +    
   85.38 +  if event_max_id then
   85.39 +    selector:add_where{ "event.id < ?", event_max_id }
   85.40 +  end
   85.41 +
   85.42 +  if for_member then
   85.43 +    selector:add_where{ "event.member_id = ?", for_member.id }
   85.44 +  end
   85.45 +
   85.46 +  if for_initiative then
   85.47 +    selector:add_where{ "event.initiative_id = ?", for_initiative.id }
   85.48 +  end
   85.49 +
   85.50 +  
   85.51 +elseif mode == "issue" then
   85.52 +  
   85.53 +  selector = Issue:new_selector()
   85.54 +
   85.55 +end
   85.56 +
   85.57 +if for_unit then
   85.58 +  selector:join("area", nil, "area.id = issue.area_id")
   85.59 +  selector:add_where{ "area.unit_id = ?", for_unit.id }
   85.60 +elseif for_area then
   85.61 +  selector:add_where{ "issue.area_id = ?", for_area.id }
   85.62 +elseif for_issue then
   85.63 +  selector:add_where{ "issue.id = ?", for_issue.id }
   85.64 +end
   85.65 +  
   85.66 +if not search and app.session.member_id then
   85.67 +  selector
   85.68 +    :left_join("interest", "_interest", { 
   85.69 +      "_interest.issue_id = issue.id AND _interest.member_id = ?", app.session.member.id 
   85.70 +    } )
   85.71 +    :add_field("(_interest.member_id NOTNULL)", "is_interested")
   85.72 +    :left_join("delegating_interest_snapshot", "_delegating_interest", { [[
   85.73 +      _delegating_interest.issue_id = issue.id AND 
   85.74 +      _delegating_interest.member_id = ? AND
   85.75 +      _delegating_interest.event = issue.latest_snapshot_event
   85.76 +    ]], app.session.member.id } )
   85.77 +    :add_field("_delegating_interest.delegate_member_ids[1]", "is_interested_by_delegation_to_member_id")
   85.78 +    :add_field("_delegating_interest.delegate_member_ids[array_upper(_delegating_interest.delegate_member_ids, 1)]", "is_interested_via_member_id")    
   85.79 +    :add_field("array_length(_delegating_interest.delegate_member_ids, 1)", "delegation_chain_length")
   85.80 +end
   85.81 +
   85.82 +function doit()
   85.83 +
   85.84 +  local last_event_id
   85.85 +
   85.86 +  local items = selector:exec()
   85.87 +
   85.88 +  if #items < 1 then
   85.89 +    ui.section( function()
   85.90 +      ui.sectionRow( function()
   85.91 +        ui.heading{ level = 2, content = _"No results for this selection" }
   85.92 +      end )
   85.93 +    end )
   85.94 +    return
   85.95 +  end
   85.96 +  
   85.97 +  local row_class = "sectionRow"
   85.98 +  if for_sidebar then
   85.99 +    row_class = "sidebarRow"
  85.100 +  end
  85.101 +  
  85.102 +  if mode == "timeline" then
  85.103 +    local issues = items:load ( "issue" )
  85.104 +    local initiative = items:load ( "initiative" )
  85.105 +    items:load ( "suggestion" )
  85.106 +    items:load ( "member" )
  85.107 +    issues:load_everything_for_member_id ( app.session.member_id )
  85.108 +    initiative:load_everything_for_member_id ( app.session.member_id )
  85.109 +  elseif mode == "issue" then
  85.110 +    items:load_everything_for_member_id ( app.session.member_id )
  85.111 +  end
  85.112 +
  85.113 +  local class = "section"
  85.114 +  if mode == "timeline" then
  85.115 +    class = class .. " events"
  85.116 +  elseif mode == "issue" then
  85.117 +    class = class .. " issues"
  85.118 +  end
  85.119 +  
  85.120 +  ui.container{ attr = { class = class }, content = function()
  85.121 +
  85.122 +    local last_event_date
  85.123 +    for i, item in ipairs(items) do
  85.124 +      local event
  85.125 +      local issue
  85.126 +      if mode == "timeline" then
  85.127 +        event = item
  85.128 +        issue = item.issue
  85.129 +      elseif mode == "issue" then
  85.130 +        event = {}
  85.131 +        issue = item
  85.132 +      end
  85.133 +      
  85.134 +      last_event_id = event.id
  85.135 +
  85.136 +      local class = "event " .. row_class
  85.137 +      if event.suggestion_id then
  85.138 +        class = class .. " suggestion"
  85.139 +      end
  85.140 +      
  85.141 +      ui.container{ attr = { class = class }, content = function()
  85.142 +        local event_name 
  85.143 +        local negative_event = false
  85.144 +        
  85.145 +        local days_ago_text
  85.146 +  
  85.147 +        if mode == "timeline" then
  85.148 +          event_name = event.event_name
  85.149 +                  
  85.150 +            if event.event == "issue_state_changed" then
  85.151 +              if event.state == "discussion" then
  85.152 +                event_name = _"Discussion started"
  85.153 +              elseif event.state == "verification" then
  85.154 +                event_name = _"Verification started"
  85.155 +              elseif event.state == "voting" then
  85.156 +                event_name = _"Voting started"
  85.157 +              elseif event.state == "finished_with_winner" then
  85.158 +                event_name = event.state_name
  85.159 +              elseif event.state == "finished_without_winner" then
  85.160 +                event_name = event.state_name
  85.161 +                negative_event = true
  85.162 +              else
  85.163 +                event_name = event.state_name
  85.164 +                negative_event = true
  85.165 +              end
  85.166 +            elseif event.event == "initiative_revoked" then
  85.167 +              negative_event = true
  85.168 +            end
  85.169 +
  85.170 +          if event.time_ago == 0 then
  85.171 +            days_ago_text = _("today at #{time}", { time = format.time(event.occurrence) })
  85.172 +          elseif event.time_ago == 1 then
  85.173 +            days_ago_text = _("yesterday at #{time}", { time = format.time(event.occurrence) })
  85.174 +          else
  85.175 +            days_ago_text = _("#{interval} ago", { interval = format.interval_text ( event.time_ago ) } )
  85.176 +          end
  85.177 +          
  85.178 +        elseif mode == "issue" then
  85.179 +          event_name = issue.state_name
  85.180 +          if issue.state_time_left:sub(1,1) ~= "-" then
  85.181 +            days_ago_text = _( "#{interval} left", {
  85.182 +              interval = format.interval_text ( issue.state_time_left )
  85.183 +            })
  85.184 +          elseif issue.closed then
  85.185 +            days_ago_text = _( "#{interval} ago", {
  85.186 +              interval = format.interval_text ( issue.closed_ago )
  85.187 +            })
  85.188 +          else
  85.189 +            days_ago_text = _"phase ends soon" 
  85.190 +          end
  85.191 +          if issue.closed and not issue.fully_frozen then
  85.192 +            negative_event = true
  85.193 +          end
  85.194 +          if issue.state == "finished_without_winner" then
  85.195 +            negative_event = true
  85.196 +          end
  85.197 +          if issue.state == "canceled_no_initiative_admitted" then
  85.198 +            negative_event = true
  85.199 +          end
  85.200 +          if issue.state == "canceled_by_admin" then
  85.201 +            negative_event = true
  85.202 +          end
  85.203 +        end
  85.204 +
  85.205 +        local class= "event_info"
  85.206 +        
  85.207 +        if negative_event then
  85.208 +          class = class .. " negative"
  85.209 +        end
  85.210 +
  85.211 +        if mode == "timeline" then
  85.212 +          ui.container{ attr = { class = class }, content = function ()
  85.213 +            ui.tag { content = event_name }
  85.214 +            slot.put ( " " )
  85.215 +            ui.tag{ attr = { class = "event_time" }, content = days_ago_text }
  85.216 +          end }
  85.217 +        end
  85.218 +
  85.219 +        if not for_issue and not for_initiative then
  85.220 +          ui.container{ attr = { class = "issue_context" }, content = function()
  85.221 +            ui.link{
  85.222 +              module = "unit", view = "show", id = issue.area.unit_id,
  85.223 +              attr = { class = "unit" }, text = issue.area.unit.name
  85.224 +            }
  85.225 +            slot.put ( " " )
  85.226 +            ui.link{
  85.227 +              module = "area", view = "show", id = issue.area_id,
  85.228 +              attr = { class = "area" }, text = issue.area.name
  85.229 +            }
  85.230 +            slot.put ( " " )
  85.231 +            execute.view{ 
  85.232 +              module = "delegation", view = "_info", params = { 
  85.233 +                issue = issue, member = for_member 
  85.234 +              }
  85.235 +            }
  85.236 +          end }
  85.237 +          ui.container{ attr = { class = "issue_info" }, content = function()
  85.238 +            ui.link{
  85.239 +              attr = { class = "issue" },
  85.240 +              text = _("#{policy} ##{id}", { policy = issue.policy.name, id = issue.id }),
  85.241 +              module = "issue",
  85.242 +              view = "show",
  85.243 +              id = issue.id
  85.244 +            }
  85.245 +
  85.246 +          end }
  85.247 +        end
  85.248 +        
  85.249 +        if mode ~= "timeline"
  85.250 +            or event.state == "finished_with_winner"
  85.251 +            or event.state == "finished_without_winner"
  85.252 +        then
  85.253 +          local initiative = issue.initiatives[1]
  85.254 +          if initiative then
  85.255 +            util.initiative_pie(initiative)
  85.256 +          end
  85.257 +        end
  85.258 +        
  85.259 +        if mode == "issue" then
  85.260 +          ui.container{ attr = { class = class }, content = function ()
  85.261 +            ui.tag { content = event_name }
  85.262 +            slot.put ( " " )
  85.263 +            ui.tag{ attr = { class = "event_time" }, content = days_ago_text }
  85.264 +          end }
  85.265 +        elseif mode == "timeline"
  85.266 +          and not for_issue
  85.267 +          and event.event ~= "issue_state_changed"
  85.268 +        then
  85.269 +          slot.put("<br />")
  85.270 +        end
  85.271 +
  85.272 +        if event.suggestion_id then
  85.273 +          ui.container{ attr = { class = "suggestion" }, content = function()
  85.274 +            ui.link{
  85.275 +              text = format.string(event.suggestion.name, {
  85.276 +                truncate_at = 160, truncate_suffix = true
  85.277 +              }),
  85.278 +              module = "initiative", view = "show", id = event.initiative.id,
  85.279 +              params = { suggestion_id = event.suggestion_id },
  85.280 +              anchor = "s" .. event.suggestion_id
  85.281 +            }
  85.282 +          end }
  85.283 +        end
  85.284 +
  85.285 +        if not for_initiative and (not for_issue or event.initiative_id) then
  85.286 +          
  85.287 +          ui.container{ attr = { class = "initiative_list" }, content = function()
  85.288 +            if event.initiative_id then
  85.289 +              local initiative = event.initiative
  85.290 +                
  85.291 +              execute.view{ module = "initiative", view = "_list", params = { 
  85.292 +                issue = issue,
  85.293 +                initiative = initiative,
  85.294 +                for_event = mode == "timeline" and not (event.state == issue.state)
  85.295 +
  85.296 +              } }
  85.297 +            else
  85.298 +              local initiatives = issue.initiatives
  85.299 +              execute.view{ module = "initiative", view = "_list", params = { 
  85.300 +                issue = issue,
  85.301 +                initiatives = initiatives,
  85.302 +                for_event = mode == "timeline" and not (event.state == issue.state)
  85.303 +              } }
  85.304 +            end
  85.305 +          end }
  85.306 +        end
  85.307 +        
  85.308 +      end }
  85.309 +    end
  85.310 +    
  85.311 +    if mode == "timeline" then
  85.312 +      if for_sidebar then
  85.313 +        ui.container { attr = { class = row_class }, content = function ()
  85.314 +          ui.link{
  85.315 +            attr = { class = "moreLink" },
  85.316 +            text = _"Show full history",
  85.317 +            module = "initiative", view = "history", id = for_initiative.id
  85.318 +          }
  85.319 +        end }
  85.320 +      elseif #items > limit then
  85.321 +        ui.container { attr = { class = row_class }, content = function ()
  85.322 +          ui.link{
  85.323 +            attr = { class = "moreLink" },
  85.324 +            text = _"Show older events",
  85.325 +            module = request.get_module(),
  85.326 +            view = request.get_view(),
  85.327 +            id = for_unit and for_unit.id or for_area and for_area.id or for_issue and for_issue.id or for_member and for_member.id,
  85.328 +            params = {
  85.329 +              mode = "timeline",
  85.330 +              event_max_id = last_event_id,
  85.331 +              tab = param.get_all_cgi()["tab"],
  85.332 +              phase = param.get_all_cgi()["phase"],
  85.333 +              closed = param.get_all_cgi()["closed"]
  85.334 +            }
  85.335 +          }
  85.336 +        end }
  85.337 +      elseif #items < 1 then
  85.338 +        ui.container { attr = { class = row_class }, content = _"No more events available" }
  85.339 +      end
  85.340 +    end
  85.341 +    
  85.342 +  end }
  85.343 +
  85.344 +end
  85.345 +
  85.346 +
  85.347 +local filters = {}
  85.348 +
  85.349 +if not for_initiative and not for_issue and not no_filter then
  85.350 +  filters = execute.load_chunk{module="issue", chunk="_filters.lua", params = {
  85.351 +    for_events = mode == "timeline" and true or false,
  85.352 +    member = app.session.member, 
  85.353 +    for_member = for_member, 
  85.354 +    state = for_state, 
  85.355 +    for_unit = for_unit and true or false, 
  85.356 +    for_area = for_area and true or false
  85.357 +  }}
  85.358 +end
  85.359 +
  85.360 +filters.opened = true
  85.361 +filters.selector = selector
  85.362 +
  85.363 +if mode == "timeline" then
  85.364 +  filters.content = doit
  85.365 +else
  85.366 +  filters.content = function()
  85.367 +    ui.paginate{
  85.368 +      selector = selector,
  85.369 +      per_page = 25,
  85.370 +      content = doit
  85.371 +    }
  85.372 +  end
  85.373 +end
  85.374 +
  85.375 +ui.filters(filters)
  85.376 +      
  85.377 \ No newline at end of file
    86.1 --- a/app/main/issue/_show.lua	Thu Jul 10 01:02:43 2014 +0200
    86.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.3 @@ -1,310 +0,0 @@
    86.4 -local issue = param.get("issue", "table")
    86.5 -local initiative_limit = param.get("initiative_limit", atom.integer)
    86.6 -local for_member = param.get("for_member", "table")
    86.7 -local for_listing = param.get("for_listing", atom.boolean)
    86.8 -local for_initiative = param.get("for_initiative", "table")
    86.9 -local for_initiative_id = for_initiative and for_initiative.id or nil
   86.10 -
   86.11 -local direct_voter
   86.12 -if app.session.member_id then
   86.13 -  direct_voter = issue.member_info.direct_voted
   86.14 -end
   86.15 -
   86.16 -local voteable = app.session.member_id and issue.state == 'voting' and
   86.17 -       app.session.member:has_voting_right_for_unit_id(issue.area.unit_id)
   86.18 -
   86.19 -local vote_comment_able = app.session.member_id and issue.closed and direct_voter
   86.20 -
   86.21 -local vote_link_text
   86.22 -if voteable then 
   86.23 -  vote_link_text = direct_voter and _"Change vote" or _"Vote now"
   86.24 -elseif vote_comment_able then
   86.25 -  vote_link_text = direct_voter and _"Update voting comment"
   86.26 -end  
   86.27 -
   86.28 -
   86.29 -local class = "issue"
   86.30 -if issue.is_interested then
   86.31 -  class = class .. " interested"
   86.32 -elseif issue.is_interested_by_delegation_to_member_id then
   86.33 -  class = class .. " interested_by_delegation"
   86.34 -end
   86.35 -
   86.36 -ui.container{ attr = { class = class }, content = function()
   86.37 -
   86.38 -  execute.view{ module = "delegation", view = "_info", params = { issue = issue, member = for_member } }
   86.39 -
   86.40 -  if for_listing then
   86.41 -    ui.container{ attr = { class = "content" }, content = function()
   86.42 -      ui.link{
   86.43 -        module = "unit", view = "show", id = issue.area.unit_id,
   86.44 -        attr = { class = "unit_link" }, text = issue.area.unit.name
   86.45 -      }
   86.46 -      slot.put(" ")
   86.47 -      ui.link{
   86.48 -        module = "area", view = "show", id = issue.area_id,
   86.49 -        attr = { class = "area_link" }, text = issue.area.name
   86.50 -      }
   86.51 -    end }
   86.52 -  end
   86.53 -
   86.54 -  ui.container{ attr = { class = "title" }, content = function()
   86.55 -    
   86.56 -    ui.link{
   86.57 -      attr = { class = "issue_id" },
   86.58 -      text = _("#{policy_name} ##{issue_id}", {
   86.59 -        policy_name = issue.policy.name,
   86.60 -        issue_id = issue.id
   86.61 -      }),
   86.62 -      module = "issue",
   86.63 -      view = "show",
   86.64 -      id = issue.id
   86.65 -    }
   86.66 -  end }
   86.67 -  
   86.68 -  ui.tag{
   86.69 -    attr = { class = "content issue_policy_info" },
   86.70 -    tag = "div",
   86.71 -    content = function()
   86.72 -    
   86.73 -      ui.tag{ attr = { class = "event_name" }, content = issue.state_name }
   86.74 -
   86.75 -      if issue.closed then
   86.76 -        slot.put(" &middot; ")
   86.77 -        ui.tag{ content = format.interval_text(issue.closed_ago, { mode = "ago" }) }
   86.78 -      elseif issue.state_time_left then
   86.79 -        slot.put(" &middot; ")
   86.80 -        if issue.state_time_left:sub(1,1) == "-" then
   86.81 -          if issue.state == "admission" then
   86.82 -            ui.tag{ content = _("Discussion starts soon") }
   86.83 -          elseif issue.state == "discussion" then
   86.84 -            ui.tag{ content = _("Verification starts soon") }
   86.85 -          elseif issue.state == "verification" then
   86.86 -            ui.tag{ content = _("Voting starts soon") }
   86.87 -          elseif issue.state == "voting" then
   86.88 -            ui.tag{ content = _("Counting starts soon") }
   86.89 -          end
   86.90 -        else
   86.91 -          ui.tag{ content = format.interval_text(issue.state_time_left, { mode = "time_left" }) }
   86.92 -        end
   86.93 -      end
   86.94 -
   86.95 -    end
   86.96 -  }
   86.97 -
   86.98 -  local links = {}
   86.99 -  
  86.100 -  if vote_link_text then
  86.101 -    links[#links+1] ={
  86.102 -      content = vote_link_text,
  86.103 -      module = "vote",
  86.104 -      view = "list",
  86.105 -      params = { issue_id = issue.id }
  86.106 -    }
  86.107 -  end
  86.108 -  
  86.109 -  if voteable and not direct_voter then
  86.110 -    if not issue.member_info.non_voter then
  86.111 -      links[#links+1] ={
  86.112 -        content = _"Do not vote directly",
  86.113 -        module = "vote",
  86.114 -        action = "non_voter",
  86.115 -        params = { issue_id = issue.id },
  86.116 -        routing = {
  86.117 -          default = {
  86.118 -            mode = "redirect",
  86.119 -            module = request.get_module(),
  86.120 -            view = request.get_view(),
  86.121 -            id = param.get_id_cgi(),
  86.122 -            params = param.get_all_cgi()
  86.123 -          }
  86.124 -        }
  86.125 -      }
  86.126 -    else
  86.127 -      links[#links+1] = { attr = { class = "action" }, content = _"Do not vote directly" }
  86.128 -      links[#links+1] ={
  86.129 -        in_brackets = true,
  86.130 -        content = _"Cancel [nullify]",
  86.131 -        module = "vote",
  86.132 -        action = "non_voter",
  86.133 -        params = { issue_id = issue.id, delete = true },
  86.134 -        routing = {
  86.135 -          default = {
  86.136 -            mode = "redirect",
  86.137 -            module = request.get_module(),
  86.138 -            view = request.get_view(),
  86.139 -            id = param.get_id_cgi(),
  86.140 -            params = param.get_all_cgi()
  86.141 -          }
  86.142 -        }
  86.143 -      }
  86.144 -    end
  86.145 -  end
  86.146 -
  86.147 -  if not for_member or for_member.id == app.session.member_id then
  86.148 -    
  86.149 -    if app.session.member_id then
  86.150 -
  86.151 -      if issue.member_info.own_participation then
  86.152 -        if issue.closed then
  86.153 -          links[#links+1] = { content = _"You were interested" }
  86.154 -        else
  86.155 -          links[#links+1] = { content = _"You are interested" }
  86.156 -        end
  86.157 -      end
  86.158 -      
  86.159 -      if not issue.closed and not issue.fully_frozen then
  86.160 -        if issue.member_info.own_participation then
  86.161 -          links[#links+1] = {
  86.162 -            in_brackets = true,
  86.163 -            text    = _"Withdraw",
  86.164 -            module  = "interest",
  86.165 -            action  = "update",
  86.166 -            params  = { issue_id = issue.id, delete = true },
  86.167 -            routing = {
  86.168 -              default = {
  86.169 -                mode = "redirect",
  86.170 -                module = request.get_module(),
  86.171 -                view = request.get_view(),
  86.172 -                id = param.get_id_cgi(),
  86.173 -                params = param.get_all_cgi()
  86.174 -              }
  86.175 -            }
  86.176 -          }
  86.177 -        elseif app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then
  86.178 -          links[#links+1] = {
  86.179 -            text    = _"Add my interest",
  86.180 -            module  = "interest",
  86.181 -            action  = "update",
  86.182 -            params  = { issue_id = issue.id },
  86.183 -            routing = {
  86.184 -              default = {
  86.185 -                mode = "redirect",
  86.186 -                module = request.get_module(),
  86.187 -                view = request.get_view(),
  86.188 -                id = param.get_id_cgi(),
  86.189 -                params = param.get_all_cgi()
  86.190 -              }
  86.191 -            }
  86.192 -          }
  86.193 -        end
  86.194 -      end
  86.195 -
  86.196 -      if not issue.closed and app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then
  86.197 -        if issue.member_info.own_delegation_scope ~= "issue" then
  86.198 -          links[#links+1] = { text = _"Delegate issue", module = "delegation", view = "show", params = { issue_id = issue.id, initiative_id = for_initiative_id } }
  86.199 -        else
  86.200 -          links[#links+1] = { text = _"Change issue delegation", module = "delegation", view = "show", params = { issue_id = issue.id, initiative_id = for_initiative_id } }
  86.201 -        end
  86.202 -      end
  86.203 -    end
  86.204 -
  86.205 -    if config.issue_discussion_url_func then
  86.206 -      local url = config.issue_discussion_url_func(issue)
  86.207 -      links[#links+1] = {
  86.208 -        attr = { target = "_blank" },
  86.209 -        external = url,
  86.210 -        content = _"Discussion on issue"
  86.211 -      }
  86.212 -    end
  86.213 -
  86.214 -    if config.etherpad and app.session.member then
  86.215 -      links[#links+1] = {
  86.216 -        attr = { target = "_blank" },
  86.217 -        external = issue.etherpad_url,
  86.218 -        content = _"Issue pad"
  86.219 -      }
  86.220 -    end
  86.221 -
  86.222 -
  86.223 -    if app.session.member_id and app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then
  86.224 -      if not issue.fully_frozen and not issue.closed then
  86.225 -      links[#links+1] = {
  86.226 -          attr   = { class = "action" },
  86.227 -          text   = _"Create alternative initiative",
  86.228 -          module = "initiative",
  86.229 -          view   = "new",
  86.230 -          params = { issue_id = issue.id }
  86.231 -        }
  86.232 -      end
  86.233 -    end
  86.234 -
  86.235 -  end
  86.236 -    
  86.237 -  ui.container{ attr = { class = "content actions" }, content = function()
  86.238 -    for i, link in ipairs(links) do
  86.239 -      if link.in_brackets then
  86.240 -        slot.put(" (")
  86.241 -      elseif i > 1 then
  86.242 -        slot.put(" &middot; ")
  86.243 -      end
  86.244 -      if link.module or link.external then
  86.245 -        ui.link(link)
  86.246 -      else
  86.247 -        ui.tag(link)
  86.248 -      end
  86.249 -      if link.in_brackets then
  86.250 -        slot.put(")")
  86.251 -      end
  86.252 -    end
  86.253 -  end }
  86.254 -
  86.255 -  if not for_listing then
  86.256 -    if issue.state == "canceled_by_admin" then
  86.257 -      ui.container{
  86.258 -        attr = { class = "not_admitted_info" },
  86.259 -        content = function()
  86.260 -          ui.container{ content = _("This issue has been canceled by administrative intervention.") }
  86.261 -          slot.put("<br />")
  86.262 -          if issue.admin_notice then
  86.263 -            ui.container{ content = function() slot.put(encode.html_newlines(issue.admin_notice)) end }
  86.264 -          end
  86.265 -        end
  86.266 -      }
  86.267 -    elseif issue.admin_notice then
  86.268 -      ui.container{
  86.269 -        attr = { class = "not_admitted_info" },
  86.270 -        content = function() slot.put(encode.html_newlines(issue.admin_notice)) end
  86.271 -      }
  86.272 -    end
  86.273 -    
  86.274 -    if issue.state == "canceled_issue_not_accepted" then
  86.275 -      local policy = issue.policy
  86.276 -      ui.container{
  86.277 -        attr = { class = "not_admitted_info" },
  86.278 -        content = _("This issue has been canceled. It failed the quorum of #{quorum}.", { quorum = format.percentage(policy.issue_quorum_num / policy.issue_quorum_den) })
  86.279 -      }
  86.280 -    elseif
  86.281 -      issue.state:sub(1, #("canceled_")) == "canceled_" and 
  86.282 -      issue.state ~= "canceled_by_admin"
  86.283 -    then
  86.284 -      ui.container{
  86.285 -        attr = { class = "not_admitted_info" },
  86.286 -        content = _("This issue has been canceled.")
  86.287 -      }
  86.288 -    end
  86.289 -  end
  86.290 -
  86.291 -  ui.container{ attr = { class = "initiative_list content" }, content = function()
  86.292 -
  86.293 -    local initiatives_selector = issue:get_reference_selector("initiatives")
  86.294 -    local highlight_string = param.get("highlight_string")
  86.295 -    if highlight_string then
  86.296 -      initiatives_selector:add_field( {'"highlight"("initiative"."name", ?)', highlight_string }, "name_highlighted")
  86.297 -    end
  86.298 -    execute.view{
  86.299 -      module = "initiative",
  86.300 -      view = "_list",
  86.301 -      params = {
  86.302 -        issue = issue,
  86.303 -        initiatives_selector = initiatives_selector,
  86.304 -        highlight_initiative = for_initiative,
  86.305 -        highlight_string = highlight_string,
  86.306 -        no_sort = true,
  86.307 -        limit = (for_listing or for_initiative) and 5 or nil,
  86.308 -        for_member = for_member
  86.309 -      }
  86.310 -    }
  86.311 -  end }
  86.312 -end }
  86.313 -
    87.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.2 +++ b/app/main/issue/_sidebar_issue.lua	Thu Jul 10 01:19:48 2014 +0200
    87.3 @@ -0,0 +1,39 @@
    87.4 +local issue = param.get("issue", "table")
    87.5 +local hide_initiatives = param.get("hide_initiatives", atom.boolean)
    87.6 +local highlight_initiative_id = param.get ( "highlight_initiative_id", "number" )
    87.7 +
    87.8 +ui.sidebar ( "tab-whatcanido", function ()
    87.9 +
   87.10 +  ui.sidebarHead( function()
   87.11 +    ui.heading {
   87.12 +      level = 2,
   87.13 +      content = _"Competing initiatives"
   87.14 +    }
   87.15 +  end )
   87.16 +  
   87.17 +  execute.view {
   87.18 +    module = "initiative", view = "_list",
   87.19 +    params = {
   87.20 +      issue = issue,
   87.21 +      initiatives = issue.initiatives,
   87.22 +      highlight_initiative_id = highlight_initiative_id
   87.23 +    }
   87.24 +  }
   87.25 +  if #issue.initiatives == 1 then
   87.26 +    ui.sidebarSection( function ()
   87.27 +    
   87.28 +      if not issue.closed and not (issue.state == "voting") then
   87.29 +        ui.container { content = function()
   87.30 +        ui.tag { content = _"Currently this is the only initiative in this issue, because nobody started a competing initiative (yet)." }
   87.31 +          if app.session.member and app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then
   87.32 +            slot.put(" ")
   87.33 +            ui.tag { content = _"To create a competing initiative see below." }
   87.34 +          end
   87.35 +        end }
   87.36 +      else
   87.37 +        ui.container { content = _"This is the only initiative in this issue, because nobody started a competing initiative." }
   87.38 +      end
   87.39 +    end )
   87.40 +  end
   87.41 +
   87.42 +end ) -- ui.sidebar
    88.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.2 +++ b/app/main/issue/_sidebar_members.lua	Thu Jul 10 01:19:48 2014 +0200
    88.3 @@ -0,0 +1,65 @@
    88.4 +local issue = param.get("issue", "table")
    88.5 +local initiative = param.get("initiative", "table")
    88.6 +
    88.7 +if app.session:has_access("all_pseudonymous") then
    88.8 +  ui.sidebar ( "tab-members", function ()
    88.9 +
   88.10 +    local text = _"Interested members"
   88.11 +    if issue.state == "finished_with_winner" or issue.state == "finished_without_winner" then
   88.12 +      text = _"Voters"
   88.13 +    end
   88.14 +    
   88.15 +    ui.sidebarHead( function()
   88.16 +      ui.heading{
   88.17 +        level = 2, content = text
   88.18 +      }
   88.19 +    end )
   88.20 +    
   88.21 +    local interested_members_selector
   88.22 +    
   88.23 +    if issue.state == "finished_with_winner" or issue.state == "finished_without_winner" then
   88.24 +      if initiative then
   88.25 +        interested_members_selector = Member:new_selector()
   88.26 +          :join("issue", nil, { "issue.id = ?", issue.id })
   88.27 +          :join("direct_voter", nil, { "direct_voter.issue_id = ? AND direct_voter.member_id = member.id", issue.id })
   88.28 +          :join("vote", nil, { "vote.member_id = member.id AND vote.initiative_id = ?", initiative.id })
   88.29 +          :add_field("direct_voter.weight", "voter_weight")
   88.30 +          :add_field("vote.grade")
   88.31 +          :add_field("direct_voter.comment", "voter_comment")
   88.32 +      else
   88.33 +        interested_members_selector = Member:new_selector()
   88.34 +          :join("issue", nil, { "issue.id = ?", issue.id })
   88.35 +          :join("direct_voter", nil, { "direct_voter.issue_id = ? AND direct_voter.member_id = member.id", issue.id })
   88.36 +          :add_field("direct_voter.weight", "voter_weight")
   88.37 +          :add_field("direct_voter.comment", "voter_comment")
   88.38 +      end
   88.39 +    else
   88.40 +      interested_members_selector= issue:get_reference_selector("interested_members_snapshot")
   88.41 +        :join("issue", nil, "issue.id = direct_interest_snapshot.issue_id")
   88.42 +        :add_field("direct_interest_snapshot.weight")
   88.43 +        :add_where("direct_interest_snapshot.event = issue.latest_snapshot_event")
   88.44 +        :limit(25)
   88.45 +
   88.46 +      if initiative then
   88.47 +        interested_members_selector:left_join("direct_supporter_snapshot", nil, { "direct_supporter_snapshot.initiative_id = ? AND direct_interest_snapshot.issue_id = direct_supporter_snapshot.issue_id AND direct_supporter_snapshot.member_id = direct_interest_snapshot.member_id AND direct_supporter_snapshot.event = issue.latest_snapshot_event", initiative.id })
   88.48 +        interested_members_selector:add_field("direct_supporter_snapshot.member_id NOTNULL", "supporter")
   88.49 +        interested_members_selector:add_field("satisfied", "supporter_satisfied")
   88.50 +      end
   88.51 +    end
   88.52 +    
   88.53 +    execute.view{
   88.54 +      module = "member",
   88.55 +      view = "_list",
   88.56 +      params = {
   88.57 +        issue = issue,
   88.58 +        initiative = initiative,
   88.59 +        members_selector = interested_members_selector,
   88.60 +        no_filter = true, no_paginate = true,
   88.61 +        member_class = "sidebarRow sidebarRowNarrow",
   88.62 +        for_votes = issue.state == "finished_with_winner" or issue.state == "finished_without_winner"
   88.63 +      }
   88.64 +    }
   88.65 +
   88.66 +  end )
   88.67 +  
   88.68 +end
    89.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.2 +++ b/app/main/issue/_sidebar_state.lua	Thu Jul 10 01:19:48 2014 +0200
    89.3 @@ -0,0 +1,171 @@
    89.4 +local issue = param.get("issue", "table")
    89.5 +local initiative = param.get("initiative", "table")
    89.6 +
    89.7 +local view_module
    89.8 +local view_id
    89.9 +
   89.10 +if initiative then
   89.11 +  issue = initiative.issue
   89.12 +  view_module = "initiative"
   89.13 +  view_id = initiative.id
   89.14 +else
   89.15 +  view_module = "issue"
   89.16 +  view_id = issue.id
   89.17 +end
   89.18 +
   89.19 +ui.sidebar( "tab-whatcanido", function()
   89.20 +
   89.21 +  ui.sidebarHead( function()
   89.22 +    ui.heading{ level = 2, content = function()
   89.23 +      ui.link{ 
   89.24 +        content = issue.name,
   89.25 +        module = "issue", view = "show", id = issue.id
   89.26 +      }
   89.27 +    end }
   89.28 +  end )
   89.29 +
   89.30 +  local current_occured = false
   89.31 +  local failed = false
   89.32 +  
   89.33 +  for i, state in ipairs{ "admission", "discussion", "verification", "voting" } do
   89.34 +    local current = state == issue.state
   89.35 +    
   89.36 +    if current then
   89.37 +      current_occured = true
   89.38 +    end
   89.39 +    
   89.40 +    local phase_success = (
   89.41 +      (state == "admission" and issue.accepted)
   89.42 +        or (state == "discussion" and issue.half_frozen)
   89.43 +        or (state == "verification" and issue.fully_frozen and issue.state ~= "canceled_no_initiative_admitted")
   89.44 +        or (state == "voting" and issue.closed and issue.state ~= "canceled_no_initiative_admitted" and issue.state ~= "canceled_by_admin")
   89.45 +    )
   89.46 +    
   89.47 +    if not failed then
   89.48 +      ui.sidebarSection( "sidebarRowNarrow" .. (current and " highlightedx" or ""), function()
   89.49 +      
   89.50 +        local state_names = {
   89.51 +          admission = _"Admission",
   89.52 +          discussion = _"Discussion",
   89.53 +          verification = _"Verification",
   89.54 +          voting = _"Voting"
   89.55 +        }
   89.56 +        
   89.57 +        local state_name = "(" .. i .. ") " .. state_names[state] or state
   89.58 +
   89.59 +        local function quorum_text(policy, quorum)
   89.60 +          local num
   89.61 +          local den
   89.62 +          
   89.63 +          if quorum == 1 then
   89.64 +            num = policy.issue_quorum_num
   89.65 +            den = policy.issue_quorum_den
   89.66 +          elseif quorum == 2 then
   89.67 +            num = policy.initiative_quorum_num
   89.68 +            den = policy.initiative_quorum_den
   89.69 +          end
   89.70 +          
   89.71 +          if den == 100 then
   89.72 +            return _("#{percentage}%", { percentage = num })
   89.73 +          else
   89.74 +            return num .. "/" .. den
   89.75 +          end
   89.76 +          
   89.77 +        end
   89.78 +        
   89.79 +        local quorum
   89.80 +        if state == "admission" then
   89.81 +          quorum = quorum_text(issue.policy, 1)
   89.82 +        elseif state == "verification" then
   89.83 +          quorum = quorum_text(issue.policy, 2)
   89.84 +        end
   89.85 +
   89.86 +        if current then
   89.87 +          local time_left
   89.88 +          if issue.state_time_left:sub(1,1) ~= "-" then
   89.89 +            time_left = format.interval_text(issue.state_time_left, { mode = "time_left" })
   89.90 +          else
   89.91 +            time_left = "phase ends soon"
   89.92 +          end
   89.93 +          
   89.94 +          ui.tag{ attr = { class = "right" },
   89.95 +            content = time_left
   89.96 +          }
   89.97 +        elseif current_occured then
   89.98 +          local phase_duration = issue[state .. "_time"]
   89.99 +          ui.tag{ attr = { class = "right" },
  89.100 +            content = _("#{duration}", {
  89.101 +              duration = format.interval_text(phase_duration)
  89.102 +            } )
  89.103 +          }
  89.104 +        else
  89.105 +          local text = "failed"
  89.106 +          if quorum then
  89.107 +            text = _("failed #{quorum}", { quorum = quorum })
  89.108 +          end
  89.109 +          if phase_success then
  89.110 +            if quorum then
  89.111 +              text = _("reached #{quorum}", { quorum = quorum })
  89.112 +            else
  89.113 +              text = _"finished"
  89.114 +            end
  89.115 +          elseif issue.state == "canceled_revoked_before_accepted" or
  89.116 +              issue.state == "canceled_after_revocation_during_discussion" or
  89.117 +              issue.state == "canceled_after_revocation_during_verification"
  89.118 +          then
  89.119 +            text = _"revoked"
  89.120 +          elseif issue.state == "canceled_by_admin" then
  89.121 +            text = _"canceled"
  89.122 +          end
  89.123 +          
  89.124 +          ui.tag{ attr = { class = "right" },
  89.125 +            content = text
  89.126 +          }
  89.127 +        end
  89.128 +
  89.129 +        ui.heading{ level = 3, content = function()
  89.130 +          if current then
  89.131 +            ui.image{ attr = { class = "icon16" }, static = "icons/32/phase_current.png" }
  89.132 +          elseif not current_occured and not phase_success then
  89.133 +            ui.image{ attr = { class = "icon16" }, static = "icons/32/phase_failed.png" }
  89.134 +          elseif current_occured then
  89.135 +            ui.image{ attr = { class = "icon16" }, static = "icons/32/empty.png" }
  89.136 +          else
  89.137 +            ui.image{ attr = { class = "icon16" }, static = "icons/32/phase_finished.png" }
  89.138 +          end
  89.139 +          slot.put(" ")
  89.140 +          ui.tag{ content = state_name }
  89.141 +        end }
  89.142 +        
  89.143 +        local help_texts = {
  89.144 +          admission = _"As soon as one initiative of this issue reaches #{quorum} support, the issue will go into discussion phase.",
  89.145 +          discussion = _"During the discussion phase the issue is debated between initiators while the initiatives are improved by suggestions from the supporters.",
  89.146 +          verification = _"During the verification phase the initiative drafts cannot be changed anymore.",
  89.147 +          voting = _"On this issue can be voted now."
  89.148 +        }
  89.149 +        if current then
  89.150 +        --  ui.container { content = help_texts[state] }
  89.151 +        end
  89.152 +          
  89.153 +
  89.154 +      end )
  89.155 +    end
  89.156 +    
  89.157 +    if not phase_success and not current and not current_occured then
  89.158 +      failed = true
  89.159 +    end
  89.160 +  end
  89.161 +    
  89.162 +  if issue.closed then
  89.163 +    ui.sidebarSection( function()
  89.164 +      ui.heading { level = 1, content = issue.state_name }
  89.165 +    end )
  89.166 +    if issue.admin_notice then
  89.167 +      ui.sidebarSection( function()
  89.168 +        ui.heading { level = 3, content = _"Administrative notice:" }
  89.169 +        slot.put(encode.html_newlines(issue.admin_notice)) 
  89.170 +      end )
  89.171 +    end
  89.172 +  end
  89.173 +      
  89.174 +end )
  89.175 \ No newline at end of file
    90.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    90.2 +++ b/app/main/issue/_sidebar_whatcanido.lua	Thu Jul 10 01:19:48 2014 +0200
    90.3 @@ -0,0 +1,631 @@
    90.4 +local issue = param.get("issue", "table")
    90.5 +local initiative = param.get("initiative", "table")
    90.6 +local member = param.get("member", "table") or app.session.member
    90.7 +
    90.8 +if initiative then
    90.9 +  issue = initiative.issue
   90.10 +end
   90.11 +
   90.12 +local privileged_to_vote = app.session.member and app.session.member:has_voting_right_for_unit_id(issue.area.unit_id)
   90.13 +
   90.14 +local active_trustee_id
   90.15 +if member then
   90.16 +  if not issue.member_info.own_participation then
   90.17 +    if issue.member_info.first_trustee_participation then
   90.18 +      active_trustee_id = issue.member_info.first_trustee_id
   90.19 +    elseif issue.member_info.other_trustee_participation then
   90.20 +      active_trustee_id = issue.member_info.other_trustee_id
   90.21 +    end
   90.22 +  end
   90.23 +end
   90.24 +
   90.25 +ui.sidebar ( "tab-whatcanido", function ()
   90.26 +
   90.27 +  ui.sidebarHeadWhatCanIDo()
   90.28 +      
   90.29 +  local supporter
   90.30 +
   90.31 +  if initiative and app.session.member_id then
   90.32 +    supporter = app.session.member:get_reference_selector("supporters")
   90.33 +      :add_where{ "initiative_id = ?", initiative.id }
   90.34 +      :optional_object_mode()
   90.35 +      :exec()
   90.36 +  end
   90.37 +
   90.38 +  local view_module
   90.39 +  local view_id
   90.40 +
   90.41 +  if initiative then
   90.42 +    issue = issue
   90.43 +    view_module = "initiative"
   90.44 +    view_id = initiative.id
   90.45 +  else
   90.46 +    view_module = "issue"
   90.47 +    view_id = issue.id
   90.48 +  end
   90.49 +  
   90.50 +  local initiator
   90.51 +  if initiative and app.session.member_id then
   90.52 +    initiator = Initiator:by_pk(initiative.id, app.session.member.id)
   90.53 +  end
   90.54 +
   90.55 +  local initiators 
   90.56 +  
   90.57 +  if initiative then
   90.58 +    local initiators_members_selector = initiative:get_reference_selector("initiating_members")
   90.59 +      :add_field("initiator.accepted", "accepted")
   90.60 +      :add_order_by("member.name")
   90.61 +    if initiator and initiator.accepted then
   90.62 +      initiators_members_selector:add_where("initiator.accepted ISNULL OR initiator.accepted")
   90.63 +    else
   90.64 +      initiators_members_selector:add_where("initiator.accepted")
   90.65 +    end
   90.66 +    
   90.67 +    initiators = initiators_members_selector:exec()
   90.68 +  end
   90.69 +
   90.70 +  if initiator and 
   90.71 +    initiator.accepted and 
   90.72 +    not issue.fully_frozen and 
   90.73 +    not issue.closed and 
   90.74 +    not initiative.revoked 
   90.75 +  then
   90.76 +
   90.77 +    ui.container { attr = { class = "sidebarRow" }, content = function ()
   90.78 +      ui.heading { level = 3, content = function()
   90.79 +        ui.tag { content = _"You are initiator of this initiative" }
   90.80 +      end }
   90.81 +      ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
   90.82 +        ui.tag { tag = "li", content = function ()
   90.83 +          ui.link{
   90.84 +            module = "draft", view = "new",
   90.85 +            params = { initiative_id = initiative.id },
   90.86 +            content = _"edit proposal and/or reasons"
   90.87 +          }
   90.88 +        end }
   90.89 +        ui.tag { tag = "li", content = function ()
   90.90 +          ui.link{
   90.91 +            attr = { class = "action" },
   90.92 +            module = "initiative", view = "add_initiator",
   90.93 +            params = { initiative_id = initiative.id },
   90.94 +            content = _"invite another initiator"
   90.95 +          }
   90.96 +        end }
   90.97 +        if #initiative.initiators > 1 then
   90.98 +          ui.tag { tag = "li", content = function ()
   90.99 +            ui.link{
  90.100 +              module = "initiative", view = "remove_initiator",
  90.101 +              params = { initiative_id = initiative.id },
  90.102 +              content = _"remove an initiator"
  90.103 +            }
  90.104 +          end }
  90.105 +        end
  90.106 +        ui.tag { tag = "li", content = function ()
  90.107 +          ui.link{
  90.108 +            module = "initiative", view = "revoke", id = initiative.id,
  90.109 +            content = _"revoke initiative"
  90.110 +          }
  90.111 +        end }
  90.112 +      end }
  90.113 +    end }
  90.114 +  end
  90.115 +
  90.116 +  -- invited as initiator
  90.117 +  if initiator and initiator.accepted == nil and not initiative.issue.half_frozen and not initiative.issue.closed then
  90.118 +    ui.container { attr = { class = "sidebarRow highlighted" }, content = function ()
  90.119 +      ui.heading { level = 3, content = function()
  90.120 +        ui.tag { content = _"You are invited to become initiator of this initiative" }
  90.121 +      end }
  90.122 +      ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  90.123 +        ui.tag{ tag = "li", content = function ()
  90.124 +          ui.link{
  90.125 +            content = _"accept invitation",
  90.126 +            module = "initiative",
  90.127 +            action = "accept_invitation",
  90.128 +            id     = initiative.id,
  90.129 +            routing = {
  90.130 +              default = {
  90.131 +                mode = "redirect",
  90.132 +                module = request.get_module(),
  90.133 +                view = request.get_view(),
  90.134 +                id = param.get_id_cgi(),
  90.135 +                params = param.get_all_cgi()
  90.136 +              }
  90.137 +            }
  90.138 +          }
  90.139 +        end }
  90.140 +        
  90.141 +        ui.tag{ tag = "li", content = function ()
  90.142 +          ui.link{
  90.143 +            content = _"refuse invitation",
  90.144 +            module = "initiative",
  90.145 +            action = "reject_initiator_invitation",
  90.146 +            params = {
  90.147 +              initiative_id = initiative.id,
  90.148 +              member_id = app.session.member.id
  90.149 +            },
  90.150 +            routing = {
  90.151 +              default = {
  90.152 +                mode = "redirect",
  90.153 +                module = request.get_module(),
  90.154 +                view = request.get_view(),
  90.155 +                id = param.get_id_cgi(),
  90.156 +                params = param.get_all_cgi()
  90.157 +              }
  90.158 +            }
  90.159 +          }
  90.160 +        end }
  90.161 +      end }
  90.162 +    end }
  90.163 +  end
  90.164 +
  90.165 +
  90.166 +  if privileged_to_vote and issue.member_info.first_trustee_id then
  90.167 +    local member = Member:by_id(issue.member_info.first_trustee_id)
  90.168 +    ui.sidebarSection( function ()
  90.169 +      ui.container { attr = { class = "right" }, content = function()
  90.170 +        execute.view{
  90.171 +          module = "member_image",
  90.172 +          view = "_show",
  90.173 +          params = {
  90.174 +            member = member,
  90.175 +            image_type = "avatar",
  90.176 +            show_dummy = true
  90.177 +          }
  90.178 +        }
  90.179 +      end }
  90.180 +      if issue.member_info.own_delegation_scope == "unit" then
  90.181 +        ui.heading{ level = 3, content = _"You delegated this organizational unit" }
  90.182 +      elseif issue.member_info.own_delegation_scope == "area" then
  90.183 +        ui.heading{ level = 3, content = _"You delegated this subject area" }
  90.184 +      elseif issue.member_info.own_delegation_scope == "issue" then
  90.185 +        ui.heading{ level = 3, content = _"You delegated this issue" }
  90.186 +      end
  90.187 +
  90.188 +      ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  90.189 +        if issue.member_info.own_delegation_scope == "area" or
  90.190 +           issue.member_info.own_delegation_scope == "unit" then
  90.191 +          ui.tag { tag = "li", content = function ()
  90.192 +            ui.link {
  90.193 +              module = "delegation", view = "show", params = {
  90.194 +                issue_id = issue.id,
  90.195 +                initiative_id = initiative and initiative.id or nil
  90.196 +              },
  90.197 +              content = _"change/revoke delegation only for this issue" 
  90.198 +            }
  90.199 +          end }
  90.200 +        end
  90.201 +        if issue.member_info.own_delegation_scope == "unit" then
  90.202 +          ui.tag { tag = "li", content = function ()
  90.203 +            ui.link {
  90.204 +              module = "delegation", view = "show", params = {
  90.205 +                unit_id = issue.area.unit_id,
  90.206 +              },
  90.207 +              content = _("change/revoke delegation of organizational unit", {
  90.208 +                unit_name = issue.area.unit.name
  90.209 +              })
  90.210 +            }
  90.211 +          end }
  90.212 +        elseif issue.member_info.own_delegation_scope == "area" then
  90.213 +          ui.tag { tag = "li", content = function ()
  90.214 +            ui.link {
  90.215 +              module = "delegation", view = "show", params = {
  90.216 +                area_id = issue.area_id,
  90.217 +              },
  90.218 +              content = _"change/revoke delegation of subject area" 
  90.219 +            }
  90.220 +          end }
  90.221 +        end
  90.222 +        if issue.member_info.own_delegation_scope == nil then
  90.223 +          ui.tag { tag = "li", content = function ()
  90.224 +            ui.link {
  90.225 +              module = "delegation", view = "show", params = {
  90.226 +                issue_id = issue.id,
  90.227 +                initiative_id = initiative and initiative.id or nil
  90.228 +              },
  90.229 +              content = _"choose issue delegatee" 
  90.230 +            }
  90.231 +          end }
  90.232 +        elseif issue.member_info.own_delegation_scope == "issue" then
  90.233 +          ui.tag { tag = "li", content = function ()
  90.234 +            ui.link {
  90.235 +              module = "delegation", view = "show", params = {
  90.236 +                issue_id = issue.id,
  90.237 +                initiative_id = initiative and initiative.id or nil
  90.238 +              },
  90.239 +              content = _"change/revoke issue delegation" 
  90.240 +            }
  90.241 +          end }
  90.242 +        end
  90.243 +      end }
  90.244 +
  90.245 +      if issue.member_info.first_trustee_id and issue.member_info.own_participation then
  90.246 +        local text = _"As long as you are interested in this issue yourself, the delegation is suspended for this issue, but it will be applied again in the voting phase unless you vote yourself."
  90.247 +        if issue.state == "voting" then
  90.248 +          text = _"This delegation is suspended, because you voted yourself."
  90.249 +        end
  90.250 +        ui.container { content = text }
  90.251 +      end
  90.252 +    end )
  90.253 +  end
  90.254 +  
  90.255 +  if privileged_to_vote and not issue.closed and not issue.fully_frozen then
  90.256 +    if issue.member_info.own_participation then
  90.257 +      ui.sidebarSection( function ()
  90.258 +        ui.container{ attr = { class = "right" }, content = function()
  90.259 +          ui.image{ attr = { class = "right" }, static = "icons/48/eye.png" }
  90.260 +          if issue.member_info.weight and issue.member_info.weight > 1 then
  90.261 +            slot.put("<br />")
  90.262 +            ui.tag{ 
  90.263 +              attr = { class = "right" },
  90.264 +              content = "+" .. issue.member_info.weight - 1
  90.265 +           }
  90.266 +          end
  90.267 +        end }
  90.268 +        ui.heading{ level = 3, content = _("You are interested in this issue", { id = issue.id }) }
  90.269 +        ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  90.270 +          if issue.member_info.weight and issue.member_info.weight > 1 then
  90.271 +            ui.tag { tag = "li", content = function ()
  90.272 +              ui.link {
  90.273 +                module = "delegation", view = "show_incoming",
  90.274 +                params = { issue_id = issue.id, member_id = app.session.member_id },
  90.275 +                content = _("you have #{count} incoming delegations", {
  90.276 +                  count = issue.member_info.weight - 1
  90.277 +                })
  90.278 +              }
  90.279 +            end }
  90.280 +          end
  90.281 +          ui.tag { tag = "li", content = function ()
  90.282 +            ui.link {
  90.283 +              module = "interest", action = "update",
  90.284 +              routing = { default = {
  90.285 +                mode = "redirect", module = view_module, view = "show", id = view_id
  90.286 +              } },
  90.287 +              params = { issue_id = issue.id, delete = true },
  90.288 +              text = _"remove my interest"
  90.289 +            }
  90.290 +          end }
  90.291 +        end }
  90.292 +      end )
  90.293 +    else
  90.294 +      ui.sidebarSection( function ()
  90.295 +        ui.heading{ level = 3, content = _("I want to participate in this issue", { id = issue.id }) }
  90.296 +        ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  90.297 +          ui.tag { tag = "li", content = function ()
  90.298 +            ui.link {
  90.299 +              module = "interest", action = "update", 
  90.300 +              params = { issue_id = issue.id },
  90.301 +              routing = { default = {
  90.302 +                mode = "redirect", module = view_module, view = "show", id = view_id
  90.303 +              } },
  90.304 +              text = _"add my interest"
  90.305 +            }
  90.306 +          end }
  90.307 +          ui.tag { tag = "li", content = _"browse through the competing initiatives" }
  90.308 +        end }
  90.309 +      end )
  90.310 +    end
  90.311 +
  90.312 +    if initiative then
  90.313 +      
  90.314 +      if not initiative.member_info.supported or active_trustee_id then
  90.315 +        ui.container { attr = { class = "sidebarRow" }, content = function ()
  90.316 +          ui.heading { level = 3, content = function()
  90.317 +            ui.tag { content = _"I like this initiative and I want to support it" }
  90.318 +          end }
  90.319 +          ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  90.320 +            ui.tag { tag = "li", content = function ()
  90.321 +              ui.link {
  90.322 +                module = "initiative", action = "add_support", 
  90.323 +                routing = { default = {
  90.324 +                  mode = "redirect", module = "initiative", view = "show", id = initiative.id
  90.325 +                } },
  90.326 +                id = initiative.id,
  90.327 +                text = _"add my support"
  90.328 +              }
  90.329 +            end }
  90.330 +          end }
  90.331 +        end }
  90.332 +          
  90.333 +      else -- if not supported
  90.334 +        ui.container { attr = { class = "sidebarRow" }, content = function ()
  90.335 +          if initiative.member_info.satisfied then
  90.336 +            ui.image{ attr = { class = "right icon48" }, static = "icons/32/support_satisfied.png" }
  90.337 +          else
  90.338 +            ui.image{ attr = { class = "right icon48" }, static = "icons/32/support_unsatisfied.png" }
  90.339 +          end
  90.340 +          ui.heading { level = 3, content = _"You are supporting this initiative" }
  90.341 +          ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  90.342 +            if not initiative.member_info.satisfied then
  90.343 +              ui.tag { tag = "li", content = function ()
  90.344 +                ui.tag { content = function ()
  90.345 +                  ui.link {
  90.346 +                    external = "#suggestions",
  90.347 +                    content = _"you restricted your support by rating suggestions as must or must not"
  90.348 +                  }
  90.349 +                end }
  90.350 +              end }
  90.351 +            end
  90.352 +            ui.tag { tag = "li", content = function ()
  90.353 +              ui.tag { content = function ()
  90.354 +                ui.link {
  90.355 +                  xattr = { class = "btn btn-remove" },
  90.356 +                  module = "initiative", action = "remove_support", 
  90.357 +                  routing = { default = {
  90.358 +                    mode = "redirect", module = "initiative", view = "show", id = initiative.id
  90.359 +                  } },
  90.360 +                  id = initiative.id,
  90.361 +                  text = _"remove my support"
  90.362 +                }
  90.363 +              end }
  90.364 +            end }
  90.365 +          end }
  90.366 +        end }
  90.367 +
  90.368 +      end -- not supported
  90.369 +      
  90.370 +      ui.container { attr = { class = "sidebarRow" }, content = function ()
  90.371 +        ui.heading { level = 3, content = _"I want to improve this initiative" }
  90.372 +        ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  90.373 +          if issue.state == "verification" then
  90.374 +            ui.tag { tag = "li", content = _"this issue is in verification phase, therefore the initiative text cannot be updated anymore" }
  90.375 +          elseif issue.state == "voting" then
  90.376 +            ui.tag { tag = "li", content = _"this issue is in voting phase, therefore the initiative text cannot be updated anymore" }
  90.377 +          else
  90.378 +            
  90.379 +            if initiative.member_info.initiated then
  90.380 +              ui.tag { tag = "li", content =_"take a look at the suggestions of your supporters" }
  90.381 +              ui.tag { tag = "li", content =_"if you like to implement a suggestion in your proposal and/or reasons, update your initiative draft" }
  90.382 +              ui.tag { tag = "li", content =_"to argue about suggestions, just add your arguments to your reasons in the initiative draft, so your supporters can learn about your opinion" }
  90.383 +            end
  90.384 +            
  90.385 +            if not initiative.member_info.supported or active_trustee_id then
  90.386 +              ui.tag { tag = "li", content =_"add your support (see above) and rate or write new suggestions (and thereby restrict your support to certain conditions if necessary)" }
  90.387 +            else
  90.388 +              ui.tag { tag = "li", content = _"take a look at the suggestions (see left) and rate them" }
  90.389 +              ui.tag { tag = "li", content = function ()
  90.390 +                ui.link {
  90.391 +                  module = "suggestion", view = "new", params = {
  90.392 +                    initiative_id = initiative.id
  90.393 +                  },
  90.394 +                  content = _"write a new suggestion" 
  90.395 +                }
  90.396 +              end }
  90.397 +            end
  90.398 +          end
  90.399 +        end }
  90.400 +      end }
  90.401 +      
  90.402 +    end
  90.403 +    
  90.404 +    if 
  90.405 +      (issue.state == "admission" or 
  90.406 +      issue.state == "discussion" or
  90.407 +      issue.state == "verification")
  90.408 +    then
  90.409 +      ui.sidebarSection( function ()
  90.410 +        if initiative then
  90.411 +          ui.heading{ level = 3, content = _"I don't like this initiative and I want to add my opinion or counter proposal" }
  90.412 +        else
  90.413 +          ui.heading{ level = 3, content = _"I don't like any of the initiative in this issue and I want to add my opinion or counter proposal" }
  90.414 +        end
  90.415 +        ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  90.416 +          ui.tag { tag = "li", content = function ()
  90.417 +            ui.link {
  90.418 +              module = "issue", view = "show", id = issue.id,
  90.419 +              content = _"take a look at the competing initiatives"
  90.420 +            }
  90.421 +          end }
  90.422 +          ui.tag { tag = "li", content = function ()
  90.423 +            ui.link {
  90.424 +              module = "initiative", view = "new", 
  90.425 +              params = { issue_id = issue.id },
  90.426 +              content = _"start a new competing initiative"
  90.427 +            }
  90.428 +          end }
  90.429 +        end }
  90.430 +      end )
  90.431 +    end 
  90.432 +    
  90.433 +    if not issue.member_info.first_trustee_id then
  90.434 +      ui.sidebarSection( function ()
  90.435 +        ui.heading{ level = 3, content = _"I want to delegate this issue" }
  90.436 +      
  90.437 +        ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  90.438 +          ui.tag { tag = "li", content = function ()
  90.439 +            ui.link {
  90.440 +              module = "delegation", view = "show", params = {
  90.441 +                issue_id = issue.id,
  90.442 +                initiative_id = initiative and initiative.id or nil
  90.443 +              },
  90.444 +              content = _"choose issue delegatee" 
  90.445 +            }
  90.446 +          end }
  90.447 +        end }
  90.448 +      end )
  90.449 +    end
  90.450 +    
  90.451 +  end
  90.452 +  
  90.453 +  if initiator and initiator.accepted == false then
  90.454 +    ui.container { attr = { class = "sidebarRow" }, content = function ()
  90.455 +      ui.heading { level = 3, content = function()
  90.456 +        ui.tag { content = _"You refused to become initiator of this initiative" }
  90.457 +      end }
  90.458 +      ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  90.459 +        ui.tag{ tag = "li", content = function ()
  90.460 +          ui.link{
  90.461 +            text   = _"allow invitation again",
  90.462 +            module = "initiative",
  90.463 +            action = "remove_initiator",
  90.464 +            params = {
  90.465 +              initiative_id = initiative.id,
  90.466 +              member_id = app.session.member.id
  90.467 +            },
  90.468 +            routing = {
  90.469 +              ok = {
  90.470 +                mode = "redirect",
  90.471 +                module = "initiative",
  90.472 +                view = "show",
  90.473 +                id = initiative.id
  90.474 +              }
  90.475 +            }
  90.476 +          }
  90.477 +        end }
  90.478 +      end }
  90.479 +    end }
  90.480 +  end
  90.481 +    
  90.482 +
  90.483 +  
  90.484 +  if privileged_to_vote then
  90.485 +    
  90.486 +    if initiative and
  90.487 +      (issue.state == "admission" or 
  90.488 +      issue.state == "discussion" or
  90.489 +      issue.state == "verification")
  90.490 +    then
  90.491 +      
  90.492 +    elseif issue.state == "verification" then
  90.493 +      
  90.494 +    elseif issue.state == "voting" then
  90.495 +      if not issue.member_info.direct_voted then
  90.496 +        if not issue.member_info.non_voter then
  90.497 +          ui.container { attr = { class = "sidebarRow" }, content = function ()
  90.498 +            ui.heading { level = 3, content = _"I like to vote on this issue:" }
  90.499 +            ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  90.500 +              ui.tag { tag = "li", content = function ()
  90.501 +                ui.tag { content = function ()
  90.502 +                  if not issue.closed then
  90.503 +                    ui.link {
  90.504 +                      xattr = { class = "btn btn-vote" },
  90.505 +                      module = "vote", view = "list", 
  90.506 +                      params = { issue_id = issue.id },
  90.507 +                      text = _"vote now"
  90.508 +                    }
  90.509 +                  end
  90.510 +                end }
  90.511 +              end }
  90.512 +            end }
  90.513 +          end }
  90.514 +        end
  90.515 +        ui.container { attr = { class = "sidebarRow" }, content = function ()
  90.516 +          if not issue.member_info.non_voter then
  90.517 +            ui.heading { level = 3, content = _"I don't like to vote this issue (myself):" }
  90.518 +            ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  90.519 +              ui.tag { tag = "li", content = function ()
  90.520 +                ui.link{
  90.521 +                  content = _"do not notify me about this voting anymore",
  90.522 +                  module = "vote",
  90.523 +                  action = "non_voter",
  90.524 +                  params = { issue_id = issue.id },
  90.525 +                  routing = {
  90.526 +                    default = {
  90.527 +                      mode = "redirect",
  90.528 +                      module = request.get_module(),
  90.529 +                      view = request.get_view(),
  90.530 +                      id = param.get_id_cgi(),
  90.531 +                      params = param.get_all_cgi()
  90.532 +                    }
  90.533 +                  }
  90.534 +                }
  90.535 +              end }
  90.536 +            end }
  90.537 +          else
  90.538 +            ui.heading { level = 3, content = _"You do not like to vote this issue (yourself)" }
  90.539 +            ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  90.540 +              ui.tag { tag = "li", content = function ()
  90.541 +                ui.link{
  90.542 +                  in_brackets = true,
  90.543 +                  content = _"discard",
  90.544 +                  module = "vote",
  90.545 +                  action = "non_voter",
  90.546 +                  params = { issue_id = issue.id, delete = true },
  90.547 +                  routing = {
  90.548 +                    default = {
  90.549 +                      mode = "redirect",
  90.550 +                      module = request.get_module(),
  90.551 +                      view = request.get_view(),
  90.552 +                      id = param.get_id_cgi(),
  90.553 +                      params = param.get_all_cgi()
  90.554 +                    }
  90.555 +                  }
  90.556 +                }
  90.557 +              end }
  90.558 +            end }
  90.559 +          end
  90.560 +        end }
  90.561 +      else
  90.562 +        ui.container { attr = { class = "sidebarRow" }, content = function ()
  90.563 +          ui.heading { level = 3, content = _"I like to change/revoke my vote:" }
  90.564 +          ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  90.565 +            ui.tag { tag = "li", content = function ()
  90.566 +              ui.tag { content = function ()
  90.567 +                if not issue.closed then
  90.568 +                  ui.link {
  90.569 +                    xattr = { class = "btn btn-vote" },
  90.570 +                    module = "vote", view = "list", 
  90.571 +                    params = { issue_id = issue.id },
  90.572 +                    text = _"change my vote"
  90.573 +                  }
  90.574 +                end
  90.575 +              end }
  90.576 +            end }
  90.577 +            ui.tag { tag = "li", content = function ()
  90.578 +              ui.tag { content = function ()
  90.579 +                if not issue.closed then
  90.580 +                  ui.link {
  90.581 +                    module = "vote", action = "update",
  90.582 +                    params = {
  90.583 +                      issue_id = issue.id,
  90.584 +                      discard = true
  90.585 +                    },
  90.586 +                    routing = {
  90.587 +                      default = {
  90.588 +                        mode = "redirect",
  90.589 +                        module = "issue",
  90.590 +                        view = "show",
  90.591 +                        id = issue.id
  90.592 +                      }
  90.593 +                    },
  90.594 +                    text = _"discard my vote"
  90.595 +                  }
  90.596 +                end
  90.597 +              end }
  90.598 +            end }
  90.599 +          end } 
  90.600 +
  90.601 +        end } 
  90.602 +        
  90.603 +      end
  90.604 +    end
  90.605 +  end
  90.606 +  
  90.607 +  if app.session.member and not privileged_to_vote then
  90.608 +    ui.sidebarSection( _"You are not entitled to vote in this unit" )
  90.609 +  end
  90.610 +  
  90.611 +  if issue.closed then
  90.612 +    ui.container { attr = { class = "sidebarRow" }, content = function ()
  90.613 +      ui.heading { level = 3, content = _"This issue is closed" }
  90.614 +    end }
  90.615 +  end
  90.616 +  
  90.617 +  if initiative and config.tell_others and config.tell_others.initiative then
  90.618 +    ui.container { attr = { class = "sidebarRow" }, content = function ()
  90.619 +        
  90.620 +      ui.heading { level = 3, content = _"Tell others about this initiative:" }
  90.621 +      ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  90.622 +        
  90.623 +        for i, link in ipairs (config.tell_others.initiative(initiative)) do
  90.624 +          ui.tag { tag = "li", content = function ()
  90.625 +            ui.link ( link )
  90.626 +          end }
  90.627 +        end
  90.628 +      
  90.629 +      end }
  90.630 +    end }
  90.631 +  end
  90.632 +  
  90.633 +  
  90.634 +end )
    91.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    91.2 +++ b/app/main/issue/history.lua	Thu Jul 10 01:19:48 2014 +0200
    91.3 @@ -0,0 +1,47 @@
    91.4 +local issue = Issue:by_id(param.get_id())
    91.5 +issue:load_everything_for_member_id ( app.session.member_id )
    91.6 +
    91.7 +execute.view {
    91.8 +  module = "issue", view = "_head", 
    91.9 +  params = { issue = issue, member = app.session.member }
   91.10 +}
   91.11 +
   91.12 +execute.view { 
   91.13 +  module = "issue", view = "_sidebar_issue", params = {
   91.14 +    issue = issue,
   91.15 +    hide_initiatives = true
   91.16 +  }
   91.17 +}
   91.18 +
   91.19 +execute.view{ module = "issue", view = "_sidebar_state", params = {
   91.20 +  issue = issue
   91.21 +} }
   91.22 +
   91.23 +execute.view { 
   91.24 +  module = "issue", view = "_sidebar_whatcanido", params = {
   91.25 +    issue = issue
   91.26 +  }
   91.27 +}
   91.28 +
   91.29 +execute.view { 
   91.30 +  module = "issue", view = "_sidebar_members", params = {
   91.31 +    issue = issue
   91.32 +  }
   91.33 +}
   91.34 +
   91.35 +
   91.36 +
   91.37 +ui.section( function()
   91.38 +
   91.39 +  execute.view{ 
   91.40 +    module = "issue", view = "_head2", params = {
   91.41 +      issue = issue, for_history = true
   91.42 +    }
   91.43 +  }
   91.44 +  
   91.45 +  execute.view {
   91.46 +    module = "issue", view = "_list2", params = { for_issue = issue }
   91.47 +  }
   91.48 +
   91.49 +end )
   91.50 +  
    92.1 --- a/app/main/issue/list.lua	Thu Jul 10 01:02:43 2014 +0200
    92.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.3 @@ -1,7 +0,0 @@
    92.4 -local issues_selector = Issue:new_selector()
    92.5 -
    92.6 -execute.view{
    92.7 -  module = "issue",
    92.8 -  view = "_list",
    92.9 -  params = { issues_selector = issues_selector }
   92.10 -}
   92.11 \ No newline at end of file
    93.1 --- a/app/main/issue/show.lua	Thu Jul 10 01:02:43 2014 +0200
    93.2 +++ b/app/main/issue/show.lua	Thu Jul 10 01:19:48 2014 +0200
    93.3 @@ -1,52 +1,126 @@
    93.4 -local issue = Issue:by_id(param.get_id())
    93.5 +local issue = Issue:by_id ( param.get_id () )
    93.6 +
    93.7 +if not issue then
    93.8 +  execute.view { module = "index", view = "404" }
    93.9 +  request.set_status("404 Not Found")
   93.10 +  return
   93.11 +end
   93.12 +
   93.13 +local initiatives = issue.initiatives
   93.14 +
   93.15  if app.session.member_id then
   93.16 -  issue:load_everything_for_member_id(app.session.member_id)
   93.17 +  issue:load_everything_for_member_id ( app.session.member_id )
   93.18 +  initiatives:load_everything_for_member_id ( app.session.member_id )
   93.19  end
   93.20  
   93.21  if not app.html_title.title then
   93.22 -	app.html_title.title = _("Issue ##{id}", { id = issue.id })
   93.23 +  app.html_title.title = _("Issue ##{id}", { id = issue.id })
   93.24  end
   93.25  
   93.26 -slot.select("head", function()
   93.27 -  execute.view{ module = "area", view = "_head", params = { area = issue.area } }
   93.28 -end)
   93.29 -
   93.30 -util.help("issue.show")
   93.31 +execute.view {
   93.32 +  module = "issue", view = "_head", 
   93.33 +  params = { issue = issue, member = app.session.member }
   93.34 +}
   93.35  
   93.36 -slot.select("head", function()
   93.37 -  execute.view{ module = "issue", view = "_show", params = { issue = issue } }
   93.38 -end )
   93.39 -
   93.40 -if app.session:has_access("all_pseudonymous") then
   93.41 +execute.view{ module = "issue", view = "_sidebar_state", params = {
   93.42 +  issue = issue
   93.43 +} }
   93.44  
   93.45 -  ui.container{ attr = { class = "heading" }, content = _"Interested members" }
   93.46 -  
   93.47 -  local interested_members_selector = issue:get_reference_selector("interested_members_snapshot")
   93.48 -    :join("issue", nil, "issue.id = direct_interest_snapshot.issue_id")
   93.49 -    :add_field("direct_interest_snapshot.weight")
   93.50 -    :add_where("direct_interest_snapshot.event = issue.latest_snapshot_event")
   93.51 +execute.view { 
   93.52 +  module = "issue", view = "_sidebar_whatcanido", params = {
   93.53 +    issue = issue
   93.54 +  }
   93.55 +}
   93.56  
   93.57 -  execute.view{
   93.58 -    module = "member",
   93.59 -    view = "_list",
   93.60 -    params = {
   93.61 -      issue = issue,
   93.62 -      members_selector = interested_members_selector
   93.63 +execute.view { 
   93.64 +  module = "issue", view = "_sidebar_members", params = {
   93.65 +    issue = issue
   93.66 +  }
   93.67 +}
   93.68 +
   93.69 +ui.section( function ()
   93.70 +  
   93.71 +  execute.view{ 
   93.72 +    module = "issue", view = "_head2", params = {
   93.73 +      issue = issue
   93.74      }
   93.75    }
   93.76  
   93.77 -  ui.container{ attr = { class = "heading" }, content = _"Details" }
   93.78 -  
   93.79 -  execute.view{
   93.80 -    module = "issue",
   93.81 -    view = "_details",
   93.82 -    params = { issue = issue }
   93.83 -  }
   93.84 +  if issue.initiatives[1].rank == 1 then
   93.85 +    execute.view{ module = "initiative", view = "_sidebar_state", params = {
   93.86 +      initiative = issue.initiatives[1]
   93.87 +    } }
   93.88 +  end
   93.89    
   93.90 -end
   93.91 +  ui.sectionRow( function ()
   93.92 +    execute.view {
   93.93 +      module = "initiative", view = "_list",
   93.94 +      params = { 
   93.95 +        issue = issue,
   93.96 +        initiatives = initiatives
   93.97 +      }
   93.98 +    }
   93.99 +  end )
  93.100 +
  93.101 +end )
  93.102  
  93.103 -if issue.snapshot then
  93.104 -  slot.put("<br />")
  93.105 -  ui.field.timestamp{ label = _"Last snapshot:", value = issue.snapshot }
  93.106 -end
  93.107 +ui.section(function()
  93.108 +  ui.sectionHead( function()
  93.109 +    ui.heading { level = 1, content = _"Details" }
  93.110 +  end )
  93.111 +  local policy = issue.policy
  93.112 +  ui.form{
  93.113 +    record = issue,
  93.114 +    readonly = true,
  93.115 +    attr = { class = "sectionRow form" },
  93.116 +    content = function()
  93.117 +      if issue.snapshot then
  93.118 +        ui.field.timestamp{ label = _"Last counting:", value = issue.snapshot }
  93.119 +      end
  93.120 +      ui.field.text{       label = _"Population",            name = "population" }
  93.121 +      ui.field.timestamp{  label = _"Created at",            name = "created" }
  93.122 +      if policy.polling then
  93.123 +        ui.field.text{       label = _"Admission time",        value = _"Implicitly admitted" }
  93.124 +      else
  93.125 +        ui.field.text{       label = _"Admission time",        value = format.interval_text(issue.admission_time_text) }
  93.126 +        ui.field.text{
  93.127 +          label = _"Issue quorum",
  93.128 +          value = format.percentage(policy.issue_quorum_num / policy.issue_quorum_den)
  93.129 +        }
  93.130 +        if issue.population then
  93.131 +          ui.field.text{
  93.132 +            label = _"Currently required",
  93.133 +            value = math.ceil(issue.population * policy.issue_quorum_num / policy.issue_quorum_den)
  93.134 +          }
  93.135 +        end
  93.136 +      end
  93.137 +      if issue.accepted then
  93.138 +        ui.field.timestamp{  label = _"Accepted at",           name = "accepted" }
  93.139 +      end
  93.140 +      ui.field.text{       label = _"Discussion time",       value = format.interval_text(issue.discussion_time_text) }
  93.141 +      if issue.half_frozen then
  93.142 +        ui.field.timestamp{  label = _"Half frozen at",        name = "half_frozen" }
  93.143 +      end
  93.144 +      ui.field.text{       label = _"Verification time",     value = format.interval_text(issue.verification_time_text) }
  93.145 +      ui.field.text{
  93.146 +        label   = _"Initiative quorum",
  93.147 +        value = format.percentage(policy.initiative_quorum_num / policy.initiative_quorum_den)
  93.148 +      }
  93.149 +      if issue.population then
  93.150 +        ui.field.text{
  93.151 +          label   = _"Currently required",
  93.152 +          value = math.ceil(issue.population * (issue.policy.initiative_quorum_num / issue.policy.initiative_quorum_den)),
  93.153 +        }
  93.154 +      end
  93.155 +      if issue.fully_frozen then
  93.156 +        ui.field.timestamp{  label = _"Fully frozen at",       name = "fully_frozen" }
  93.157 +      end
  93.158 +      ui.field.text{       label = _"Voting time",           value = format.interval_text(issue.voting_time_text) }
  93.159 +      if issue.closed then
  93.160 +        ui.field.timestamp{  label = _"Closed",                name = "closed" }
  93.161 +      end
  93.162 +    end
  93.163 +  }
  93.164  
  93.165 +end )
  93.166 +
    94.1 --- a/app/main/member/_action/update.lua	Thu Jul 10 01:02:43 2014 +0200
    94.2 +++ b/app/main/member/_action/update.lua	Thu Jul 10 01:19:48 2014 +0200
    94.3 @@ -23,11 +23,11 @@
    94.4  end
    94.5  
    94.6  if not config.locked_profile_fields.statement then
    94.7 -  local formatting_engine = param.get("formatting_engine")
    94.8 +  local formatting_engine = param.get("formatting_engine") or config.enforce_formatting_engine
    94.9  
   94.10    local formatting_engine_valid = false
   94.11 -  for fe, dummy in pairs(config.formatting_engine_executeables) do
   94.12 -    if formatting_engine == fe then
   94.13 +  for i, fe in pairs(config.formatting_engines) do
   94.14 +    if formatting_engine == fe.id then
   94.15        formatting_engine_valid = true
   94.16      end
   94.17    end
    95.1 --- a/app/main/member/_event_list.lua	Thu Jul 10 01:02:43 2014 +0200
    95.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.3 @@ -1,31 +0,0 @@
    95.4 -local member = param.get("member", "table")
    95.5 -local events = param.get_all_cgi()["events"] or "personal"
    95.6 -
    95.7 -ui.container{ attr = { class = "ui_filter" }, content = function()
    95.8 -  ui.container{ attr = { class = "ui_filter_head" }, content = function()
    95.9 -
   95.10 -    ui.link{
   95.11 -      attr = { class = events == "personal" and "ui_tabs_link active" or nil },
   95.12 -      text = _"My areas and issues",
   95.13 -      module = "index", view = "index", params = { tab = "timeline", events = "personal" }
   95.14 -    }
   95.15 -    
   95.16 -    slot.put(" ")
   95.17 -
   95.18 -    ui.link{
   95.19 -      attr = { class = events == "global" and "active" or nil },
   95.20 -      text = _"Everything",
   95.21 -      module = "index", view = "index", params = { tab = "timeline", events = "global" }
   95.22 -    }
   95.23 -  end }
   95.24 -end }
   95.25 -
   95.26 -if events == "personal" then
   95.27 -  execute.view{
   95.28 -    module = "event", view = "_list"
   95.29 -  }
   95.30 -elseif events == "global" then
   95.31 -  execute.view{
   95.32 -    module = "event", view = "_list", params = { global = true } 
   95.33 -  }
   95.34 -end
    96.1 --- a/app/main/member/_list.lua	Thu Jul 10 01:02:43 2014 +0200
    96.2 +++ b/app/main/member/_list.lua	Thu Jul 10 01:19:48 2014 +0200
    96.3 @@ -6,16 +6,20 @@
    96.4  local trustee = param.get("trustee", "table")
    96.5  local initiator = param.get("initiator", "table")
    96.6  local for_votes = param.get("for_votes", atom.boolean)
    96.7 +local no_filter = param.get ( "no_filter",  atom.boolean )
    96.8 +local no_paginate = param.get ( "no_paginate",  atom.boolean )
    96.9  
   96.10  local paginator_name = param.get("paginator_name")
   96.11  
   96.12 +local member_class = param.get("member_class")
   96.13 +
   96.14  if initiative or issue then
   96.15    if for_votes then
   96.16      members_selector:left_join("delegating_voter", "_member_list__delegating_voter", { "_member_list__delegating_voter.issue_id = issue.id AND _member_list__delegating_voter.member_id = ?", app.session.member_id })
   96.17 -    members_selector:add_field("_member_list__delegating_voter.delegate_member_ids", "delegate_member_ids")
   96.18 +    members_selector:add_field("member.id = ANY(_member_list__delegating_voter.delegate_member_ids)", "in_delegation_chain")
   96.19    else
   96.20      members_selector:left_join("delegating_interest_snapshot", "_member_list__delegating_interest", { "_member_list__delegating_interest.event = issue.latest_snapshot_event AND _member_list__delegating_interest.issue_id = issue.id AND _member_list__delegating_interest.member_id = ?", app.session.member_id })
   96.21 -    members_selector:add_field("_member_list__delegating_interest.delegate_member_ids", "delegate_member_ids")
   96.22 +    members_selector:add_field("member.id = ANY(_member_list__delegating_interest.delegate_member_ids)", "in_delegation_chain")
   96.23    end
   96.24  end
   96.25  
   96.26 @@ -23,9 +27,11 @@
   96.27  
   96.28  local filter = { name = "member_list" }
   96.29  
   96.30 -if issue or initiative then
   96.31 -end
   96.32 -
   96.33 +filter[#filter+1] = {
   96.34 +  name = "last_activity",
   96.35 +  label = _"Latest activity",
   96.36 +  selector_modifier = function(selector) selector:add_order_by("last_login DESC NULLS LAST, id DESC") end
   96.37 +}
   96.38  filter[#filter+1] = {
   96.39    name = "newest",
   96.40    label = _"Newest",
   96.41 @@ -48,9 +54,8 @@
   96.42    selector_modifier = function(selector) selector:add_order_by("name DESC") end
   96.43  }
   96.44  
   96.45 -local ui_filters = ui.filters
   96.46  if issue or initiative then
   96.47 -  ui_filters = function(args) args.content() end
   96.48 +  no_filter = true
   96.49    if for_votes then
   96.50        members_selector:add_order_by("voter_weight DESC, name, id")
   96.51    else
   96.52 @@ -58,27 +63,30 @@
   96.53    end
   96.54  end
   96.55  
   96.56 -ui_filters{
   96.57 -  label = _"Change order",
   96.58 -  selector = members_selector,
   96.59 -  filter,
   96.60 -  content = function()
   96.61 -    ui.paginate{
   96.62 -      name = paginator_name,
   96.63 -      anchor = paginator_name,
   96.64 -      selector = members_selector,
   96.65 -      per_page = 50,
   96.66 -      content = function() 
   96.67 -        ui.container{
   96.68 -          attr = { class = "member_list" },
   96.69 -          content = function()
   96.70 -            local members = members_selector:exec()
   96.71  
   96.72 -            for i, member in ipairs(members) do
   96.73 +function list_members()
   96.74 +  local ui_paginate = ui.paginate
   96.75 +  if no_paginate then
   96.76 +    ui_paginate = function (args) args.content() end
   96.77 +  end
   96.78 +  ui_paginate{
   96.79 +    name = paginator_name,
   96.80 +    anchor = paginator_name,
   96.81 +    selector = members_selector,
   96.82 +    per_page = 50,
   96.83 +    content = function() 
   96.84 +      ui.container{
   96.85 +        attr = { class = "member_list" },
   96.86 +        content = function()
   96.87 +          local members = members_selector:exec()
   96.88 +
   96.89 +          for i, member in ipairs(members) do
   96.90 +            ui.sectionRow( function()
   96.91                execute.view{
   96.92                  module = "member",
   96.93                  view = "_show_thumb",
   96.94                  params = {
   96.95 +                  class = member_class,
   96.96                    member = member,
   96.97                    initiative = initiative,
   96.98                    issue = issue,
   96.99 @@ -86,13 +94,24 @@
  96.100                    initiator = initiator
  96.101                  }
  96.102                }
  96.103 -            end
  96.104 +            end )
  96.105 +          end
  96.106  
  96.107  
  96.108 -          end
  96.109 -        }
  96.110 -        slot.put('<br style="clear: left;" />')
  96.111 -      end
  96.112 -    }
  96.113 -  end
  96.114 -}
  96.115 +        end
  96.116 +      }
  96.117 +    end
  96.118 +  }
  96.119 +end
  96.120 +
  96.121 +  
  96.122 +if no_filter then
  96.123 +  list_members()
  96.124 +else
  96.125 +  ui.filters {
  96.126 +    label = _"Change order",
  96.127 +    selector = members_selector,
  96.128 +    content = list_members,
  96.129 +    filter
  96.130 +  }
  96.131 +end
  96.132 \ No newline at end of file
    97.1 --- a/app/main/member/_profile.lua	Thu Jul 10 01:02:43 2014 +0200
    97.2 +++ b/app/main/member/_profile.lua	Thu Jul 10 01:19:48 2014 +0200
    97.3 @@ -1,6 +1,6 @@
    97.4  local member = param.get("member", "table")
    97.5  
    97.6 -local include_private_data = param.get("include_private_data", atom.boolean)
    97.7 +local for_registration = param.get("for_registration", atom.boolean)
    97.8  
    97.9  if not member then
   97.10    local member_id = param.get("member_id", atom.integer)
   97.11 @@ -10,34 +10,23 @@
   97.12  end
   97.13  
   97.14  ui.form{
   97.15 -  attr = { class = "member_statement member vertical" },
   97.16 +  attr = { class = "form" },
   97.17    record = member,
   97.18    readonly = true,
   97.19    content = function()
   97.20  
   97.21 -    slot.put("<br />")
   97.22 -
   97.23 -    ui.container{
   97.24 -      attr = { class = "right" },
   97.25 -      content = function()
   97.26 -
   97.27 -      execute.view{
   97.28 -        module = "member_image",
   97.29 -        view = "_show",
   97.30 -        params = {
   97.31 -          member = member,
   97.32 -          image_type = "photo"
   97.33 +    if not for_registration then
   97.34 +      ui.container { attr = { class = "member_photo" }, content = function()
   97.35 +        execute.view{
   97.36 +          module = "member_image",
   97.37 +          view = "_show",
   97.38 +          params = {
   97.39 +            member = member,
   97.40 +            image_type = "photo"
   97.41 +          }
   97.42          }
   97.43 -      }
   97.44 -
   97.45 -      ui.container{
   97.46 -        attr = { class = "contact_data" },
   97.47 -        content = function()
   97.48 -        end
   97.49 -      }
   97.50 -
   97.51 -      end
   97.52 -    }
   97.53 +      end }
   97.54 +    end
   97.55      
   97.56      if member.identification then
   97.57        ui.field.text{    label = _"Identification", name = "identification" }
   97.58 @@ -45,8 +34,11 @@
   97.59      if member.name then
   97.60        ui.field.text{ label = _"Screen name", name = "name" }
   97.61      end
   97.62 -    if include_private_data and member.login then
   97.63 +    if for_registration and member.login then
   97.64        ui.field.text{    label = _"Login name", name = "login" }
   97.65 +    end
   97.66 +    
   97.67 +    if for_registration and member.notify_email then
   97.68        ui.field.text{    label = _"Notification email", name = "notify_email" }
   97.69      end
   97.70      
    98.1 --- a/app/main/member/_show.lua	Thu Jul 10 01:02:43 2014 +0200
    98.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.3 @@ -1,108 +0,0 @@
    98.4 -local member = param.get("member", "table")
    98.5 -
    98.6 -local tabs = {
    98.7 -  module = "member",
    98.8 -  view = "show_tab",
    98.9 -  static_params = {
   98.10 -    member_id = member.id
   98.11 -  }
   98.12 -}
   98.13 -
   98.14 -tabs[#tabs+1] = {
   98.15 -  name = "profile",
   98.16 -  label = _"Profile",
   98.17 -  icon = { static = "icons/16/application_form.png" },
   98.18 -  module = "member",
   98.19 -  view = "_profile",
   98.20 -  params = { member = member },
   98.21 -}
   98.22 -
   98.23 -local areas_selector = member:get_reference_selector("areas")
   98.24 -tabs[#tabs+1] = {
   98.25 -  name = "areas",
   98.26 -  label = _"Units and areas",
   98.27 -  icon = { static = "icons/16/package.png" },
   98.28 -  module = "index",
   98.29 -  view = "_member_home",
   98.30 -  params = { areas_selector = areas_selector, member = member, for_member = true },
   98.31 -}
   98.32 -  
   98.33 -tabs[#tabs+1] = {
   98.34 -  name = "timeline",
   98.35 -  label = _"Latest events",
   98.36 -  module = "event",
   98.37 -  view = "_list",
   98.38 -  params = { for_member = member }
   98.39 -}
   98.40 -
   98.41 -tabs[#tabs+1] = {
   98.42 -  name = "open",
   98.43 -  label = _"Open issues",
   98.44 -  module = "issue",
   98.45 -  view = "_list",
   98.46 -  link_params = { 
   98.47 -    filter_interest = "issue",
   98.48 -  },
   98.49 -  params = {
   98.50 -    for_state = "open",
   98.51 -    for_member = member,
   98.52 -    issues_selector = Issue:new_selector()
   98.53 -      :add_where("issue.closed ISNULL")
   98.54 -      :add_order_by("coalesce(issue.fully_frozen + issue.voting_time, issue.half_frozen + issue.verification_time, issue.accepted + issue.discussion_time, issue.created + issue.admission_time) - now()")
   98.55 -  }
   98.56 -}
   98.57 -
   98.58 -tabs[#tabs+1] = {
   98.59 -  name = "closed",
   98.60 -  label = _"Closed issues",
   98.61 -  module = "issue",
   98.62 -  view = "_list",
   98.63 -  link_params = { 
   98.64 -    filter_interest = "issue",
   98.65 -  },
   98.66 -  params = {
   98.67 -    for_state = "closed",
   98.68 -    for_member = member,
   98.69 -    issues_selector = Issue:new_selector()
   98.70 -      :add_where("issue.closed NOTNULL")
   98.71 -      :add_order_by("issue.closed DESC")
   98.72 -
   98.73 -  }
   98.74 -}
   98.75 -
   98.76 -
   98.77 -local outgoing_delegations_selector = member:get_reference_selector("outgoing_delegations")
   98.78 -  :left_join("issue", "_member_showtab_issue", "_member_showtab_issue.id = delegation.issue_id")
   98.79 -  :add_where("_member_showtab_issue.closed ISNULL")
   98.80 -tabs[#tabs+1] = {
   98.81 -  name = "outgoing_delegations",
   98.82 -  label = _"Outgoing delegations" .. " (" .. tostring(outgoing_delegations_selector:count()) .. ")",
   98.83 -  icon = { static = "icons/16/table_go.png" },
   98.84 -  module = "delegation",
   98.85 -  view = "_list",
   98.86 -  params = { delegations_selector = outgoing_delegations_selector, outgoing = true },
   98.87 -}
   98.88 -
   98.89 -local incoming_delegations_selector = member:get_reference_selector("incoming_delegations")
   98.90 -  :left_join("issue", "_member_showtab_issue", "_member_showtab_issue.id = delegation.issue_id")
   98.91 -  :add_where("_member_showtab_issue.closed ISNULL")
   98.92 -tabs[#tabs+1] = {
   98.93 -  name = "incoming_delegations",
   98.94 -  label = _"Incoming delegations" .. " (" .. tostring(incoming_delegations_selector:count()) .. ")",
   98.95 -  icon = { static = "icons/16/table_go.png" },
   98.96 -  module = "delegation",
   98.97 -  view = "_list",
   98.98 -  params = { delegations_selector = incoming_delegations_selector, incoming = true },
   98.99 -}
  98.100 -
  98.101 -local contacts_selector = member:get_reference_selector("saved_members"):add_where("public")
  98.102 -tabs[#tabs+1] = {
  98.103 -  name = "contacts",
  98.104 -  label = _"Contacts" .. " (" .. tostring(contacts_selector:count()) .. ")",
  98.105 -  icon = { static = "icons/16/book_edit.png" },
  98.106 -  module = "member",
  98.107 -  view = "_list",
  98.108 -  params = { members_selector = contacts_selector },
  98.109 -}
  98.110 -
  98.111 -ui.tabs(tabs)
    99.1 --- a/app/main/member/_show_thumb.lua	Thu Jul 10 01:02:43 2014 +0200
    99.2 +++ b/app/main/member/_show_thumb.lua	Thu Jul 10 01:19:48 2014 +0200
    99.3 @@ -5,6 +5,8 @@
    99.4  local initiative = param.get("initiative", "table")
    99.5  local trustee = param.get("trustee", "table")
    99.6  
    99.7 +local class = param.get("class")
    99.8 +
    99.9  local name_html
   99.10  if member.name_highlighted then
   99.11    name_html = encode.highlight(member.name_highlighted)
   99.12 @@ -21,15 +23,19 @@
   99.13    container_class = container_class .. " not_informed"
   99.14  end
   99.15  
   99.16 -local in_delegation_chain = false 
   99.17 -if member.delegate_member_ids then
   99.18 +if class then
   99.19 +  container_class = container_class .. " " .. class
   99.20 +end
   99.21 +
   99.22 +local in_delegation_chain = member.in_delegation_chain
   99.23 +--[[if member.delegate_member_ids then
   99.24    for member_id in member.delegate_member_ids:gmatch("(%w+)") do
   99.25      if tonumber(member_id) == member.id then
   99.26        in_delegation_chain = true
   99.27      end
   99.28    end
   99.29  end
   99.30 -
   99.31 +--]]
   99.32  if in_delegation_chain or ((issue or initiative) and member.id == app.session.member_id) then
   99.33    container_class = container_class .. " in_delegation_chain"
   99.34  end
   99.35 @@ -37,140 +43,165 @@
   99.36  ui.container{
   99.37    attr = { class = container_class },
   99.38    content = function()
   99.39 -    ui.container{
   99.40 -      attr = { class = "flags" },
   99.41 -      content = function()
   99.42 +
   99.43 +    local function doit()
   99.44 +      execute.view{
   99.45 +        module = "member_image",
   99.46 +        view = "_show",
   99.47 +        params = {
   99.48 +          member = member,
   99.49 +          image_type = "avatar",
   99.50 +          show_dummy = true
   99.51 +        }
   99.52 +      }
   99.53 +      ui.tag{
   99.54 +        attr = { class = "member_name" },
   99.55 +        content = function() slot.put(name_html) end
   99.56 +      }
   99.57 +    end
   99.58 +    
   99.59 +    if app.session:has_access("everything") then
   99.60 +      ui.link{
   99.61 +        attr = { title = _"Show member" },
   99.62 +        module = "member",
   99.63 +        view = "show",
   99.64 +        id = member.id,
   99.65 +        content = doit
   99.66 +      }
   99.67 +    else
   99.68 +      ui.tag{ content = doit }
   99.69 +    end
   99.70  
   99.71 -        if not member.active then
   99.72 -          local text = _"inactive"
   99.73 -          ui.tag{ content = text }
   99.74 +    if member.grade then
   99.75 +      slot.put ( " " )
   99.76 +      ui.link{
   99.77 +        module = "vote",
   99.78 +        view = "list",
   99.79 +        params = {
   99.80 +          issue_id = initiative.issue.id,
   99.81 +          member_id = member.id,
   99.82 +        },
   99.83 +        content = function()
   99.84 +          if member.grade > 0 then
   99.85 +            ui.image{
   99.86 +              attr = { 
   99.87 +                alt   = _"Voted yes",
   99.88 +                title = _"Voted yes",
   99.89 +                class = "icon24 right"
   99.90 +              },
   99.91 +              static = "icons/32/support_satisfied.png"
   99.92 +            }
   99.93 +          elseif member.grade < 0 then
   99.94 +            ui.image{
   99.95 +              attr = { 
   99.96 +                alt   = _"Voted no",
   99.97 +                title = _"Voted no",
   99.98 +                class = "icon24 right"
   99.99 +              },
  99.100 +              static = "icons/32/voted_no.png"
  99.101 +            }
  99.102 +          else
  99.103 +            ui.image{
  99.104 +              attr = { 
  99.105 +                alt   = _"Abstention",
  99.106 +                title = _"Abstention",
  99.107 +                class = "icon24 right"
  99.108 +              },
  99.109 +              static = "icons/16/bullet_yellow.png"
  99.110 +            }
  99.111 +          end
  99.112 +        end
  99.113 +      }
  99.114 +    end
  99.115 +
  99.116 +    if (member.voter_comment) then
  99.117 +      ui.link{
  99.118 +        module = "vote",
  99.119 +        view = "list",
  99.120 +        params = {
  99.121 +          issue_id = issue.id,
  99.122 +          member_id = member.id,
  99.123 +        },
  99.124 +        content = function()
  99.125            ui.image{
  99.126 -            attr = { alt = text, title = text },
  99.127 -            static = "icons/16/cross.png"
  99.128 -          }
  99.129 -        end
  99.130 -
  99.131 -        if member.grade then
  99.132 -          ui.link{
  99.133 -            module = "vote",
  99.134 -            view = "list",
  99.135 -            params = {
  99.136 -              issue_id = initiative.issue.id,
  99.137 -              member_id = member.id,
  99.138 +            attr = { 
  99.139 +              alt   = _"Voting comment available",
  99.140 +              title = _"Voting comment available",
  99.141 +              class = "icon24 right"
  99.142              },
  99.143 -            content = function()
  99.144 -              if (member.voter_comment) then
  99.145 -                ui.image{
  99.146 -                  attr = { 
  99.147 -                    alt   = _"Voting comment available",
  99.148 -                    title = _"Voting comment available"
  99.149 -                  },
  99.150 -                  static = "icons/16/comment.png"
  99.151 -                }
  99.152 -              end
  99.153 -
  99.154 -              if member.grade > 0 then
  99.155 -                ui.image{
  99.156 -                  attr = { 
  99.157 -                    alt   = _"Voted yes",
  99.158 -                    title = _"Voted yes"
  99.159 -                  },
  99.160 -                  static = "icons/16/thumb_up_green.png"
  99.161 -                }
  99.162 -              elseif member.grade < 0 then
  99.163 -                ui.image{
  99.164 -                  attr = { 
  99.165 -                    alt   = _"Voted no",
  99.166 -                    title = _"Voted no"
  99.167 -                  },
  99.168 -                  static = "icons/16/thumb_down_red.png"
  99.169 -                }
  99.170 -              else
  99.171 -                ui.image{
  99.172 -                  attr = { 
  99.173 -                    alt   = _"Abstention",
  99.174 -                    title = _"Abstention"
  99.175 -                  },
  99.176 -                  static = "icons/16/bullet_yellow.png"
  99.177 -                }
  99.178 -              end
  99.179 -            end
  99.180 +            static = "icons/16/comment.png"
  99.181            }
  99.182          end
  99.183 +      }
  99.184 +    end
  99.185  
  99.186 -        local weight = 0
  99.187 -        if member.weight then
  99.188 -          weight = member.weight
  99.189 -        end
  99.190 -        if member.voter_weight then
  99.191 -          weight = member.voter_weight
  99.192 -        end
  99.193 -        if (issue or initiative) and weight > 1 then
  99.194 -          local module
  99.195 -          if issue then
  99.196 -            module = "interest"
  99.197 -          elseif initiative then
  99.198 -            if member.voter_weight then
  99.199 -               module = "vote"
  99.200 -            else
  99.201 -              module = "supporter"
  99.202 -            end
  99.203 -          end
  99.204 -          ui.link{
  99.205 -            attr = { 
  99.206 -              class = in_delegation_chain and "in_delegation_chain" or nil,
  99.207 -              title = _"Number of incoming delegations, follow link to see more details"
  99.208 -            },
  99.209 -            content = _("+ #{weight}", { weight = weight - 1 }),
  99.210 -            module = module,
  99.211 -            view = "show_incoming",
  99.212 -            params = { 
  99.213 -              member_id = member.id, 
  99.214 -              initiative_id = initiative and initiative.id or nil,
  99.215 -              issue_id = issue and issue.id or nil
  99.216 -            }
  99.217 -          }
  99.218 -        end
  99.219 +    local weight = 0
  99.220 +    if member.weight then
  99.221 +      weight = member.weight
  99.222 +    end
  99.223 +    if member.voter_weight then
  99.224 +      weight = member.voter_weight
  99.225 +    end
  99.226 +
  99.227 +    if (issue or initiative) and weight > 1 then
  99.228 +      local module = "interest"
  99.229 +      if member.voter_weight then
  99.230 +        module = "vote"
  99.231 +      end
  99.232          
  99.233 -        if initiator and initiator.accepted then
  99.234 -          if member.accepted == nil then
  99.235 -            slot.put(_"Invited")
  99.236 -          elseif member.accepted == false then
  99.237 -            slot.put(_"Rejected")
  99.238 -          end
  99.239 -        end
  99.240 -
  99.241 -        if member.is_informed == false then
  99.242 -          local text = _"Member has not approved latest draft"
  99.243 -          ui.image{
  99.244 -            attr = { alt = text, title = text },
  99.245 -            static = "icons/16/help_yellow.png"
  99.246 -          }
  99.247 -        end
  99.248 -
  99.249 +      slot.put ( " " )
  99.250 +      ui.link{
  99.251 +        attr = { 
  99.252 +          class = in_delegation_chain and "in_delegation_chain" or nil,
  99.253 +          title = _"Number of incoming delegations, follow link to see more details"
  99.254 +        },
  99.255 +        content = _("+ #{weight}", { weight = weight - 1 }),
  99.256 +        module = module,
  99.257 +        view = "show_incoming",
  99.258 +        params = { 
  99.259 +          member_id = member.id, 
  99.260 +          initiative_id = initiative and initiative.id or nil,
  99.261 +          issue_id = issue and issue.id or nil
  99.262 +        }
  99.263 +      }
  99.264 +    end
  99.265 +    
  99.266 +    if member.supporter then
  99.267 +      slot.put ( " " )
  99.268 +      if member.supporter_satisfied then
  99.269 +        local text = _"supporter"
  99.270 +        ui.image{ attr = { class = "icon24 right", alt = text, title = text }, static = "icons/32/support_satisfied.png" }
  99.271 +      else
  99.272 +        local text = _"supporter with restricting suggestions"
  99.273 +        ui.image{ attr = { class = "icon24 right", alt = text, title = text }, static = "icons/32/support_unsatisfied.png" }
  99.274        end
  99.275 -    }
  99.276 +    end
  99.277  
  99.278 -    ui.link{
  99.279 -      attr = { title = _"Show member" },
  99.280 -      module = "member",
  99.281 -      view = "show",
  99.282 -      id = member.id,
  99.283 -      content = function()
  99.284 -        execute.view{
  99.285 -          module = "member_image",
  99.286 -          view = "_show",
  99.287 -          params = {
  99.288 -            member = member,
  99.289 -            image_type = "avatar",
  99.290 -            show_dummy = true
  99.291 -          }
  99.292 -        }
  99.293 -        ui.container{
  99.294 -          attr = { class = "member_name" },
  99.295 -          content = function() slot.put(name_html) end
  99.296 -        }
  99.297 +    if not member.active then
  99.298 +      slot.put ( " " )
  99.299 +      local text = _"member inactive"
  99.300 +      ui.image{
  99.301 +        attr = { alt = text, title = text },
  99.302 +        static = "icons/16/cross.png"
  99.303 +      }
  99.304 +      ui.tag{ content = _"inactive" }
  99.305 +    end
  99.306 +
  99.307 +    if initiator and initiator.accepted then
  99.308 +      if member.accepted == nil then
  99.309 +        slot.put(_"Invited")
  99.310 +      elseif member.accepted == false then
  99.311 +        slot.put(_"Rejected")
  99.312        end
  99.313 -    }
  99.314 +    end
  99.315 +
  99.316 +    if member.is_informed == false then
  99.317 +      local text = _"Member has not approved latest draft"
  99.318 +      ui.image{
  99.319 +        attr = { alt = text, title = text },
  99.320 +        static = "icons/16/help_yellow.png"
  99.321 +      }
  99.322 +    end
  99.323 +
  99.324    end
  99.325  }
   100.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   100.2 +++ b/app/main/member/_sidebar_contacts.lua	Thu Jul 10 01:19:48 2014 +0200
   100.3 @@ -0,0 +1,86 @@
   100.4 +local member = param.get("member", "table")
   100.5 +
   100.6 +local public_contacts_selector = Contact:build_selector{
   100.7 +  public = true,
   100.8 +  member_id = member.id,
   100.9 +  order = "name"
  100.10 +}
  100.11 +
  100.12 +local private_contacts_selector = Contact:build_selector{
  100.13 +  public = false,
  100.14 +  member_id = member.id,
  100.15 +  order = "name"
  100.16 +}
  100.17 +
  100.18 +ui.sidebar( "tab-members", function()
  100.19 +
  100.20 +  ui.sidebarHead( function()
  100.21 +    ui.heading { level = 2, content = _"Published contacts" }
  100.22 +  end )
  100.23 +  
  100.24 +  --ui.sidebarSection( function()
  100.25 +
  100.26 +    if public_contacts_selector:count() == 0 then
  100.27 +      ui.sidebarSection( function()
  100.28 +        ui.field.text{ value = _"No published contacts" }
  100.29 +      end )
  100.30 +    else
  100.31 +      ui.paginate{
  100.32 +        selector = public_contacts_selector,
  100.33 +        name = "contacts",
  100.34 +        content = function()
  100.35 +          local contacts = public_contacts_selector:exec()
  100.36 +          for i, contact in ipairs(contacts) do
  100.37 +            ui.sidebarSection( "sidebarRowNarrow", function()
  100.38 +              execute.view{ module = "member_image", view = "_show", params = {
  100.39 +                member_id = contact.other_member.id, class = "micro_avatar", 
  100.40 +                popup_text = contact.other_member.name,
  100.41 +                image_type = "avatar", show_dummy = true,
  100.42 +              } }
  100.43 +              slot.put(" ")
  100.44 +              ui.link{
  100.45 +                content = contact.other_member.name,
  100.46 +                module = "member",
  100.47 +                view = "show",
  100.48 +                id = contact.other_member.id
  100.49 +              }
  100.50 +            end )
  100.51 +          end
  100.52 +        end
  100.53 +      }
  100.54 +    end
  100.55 +  --end )
  100.56 +    
  100.57 +    
  100.58 +  if member.id == app.session.member.id and private_contacts_selector:count() > 0 then
  100.59 +
  100.60 +    ui.sidebarHead( function()
  100.61 +      ui.heading { level = 2, content = _"Private contacts" }
  100.62 +    end )
  100.63 +    
  100.64 +    ui.paginate{
  100.65 +      selector = private_contacts_selector,
  100.66 +      name = "contacts",
  100.67 +      content = function()
  100.68 +        local contacts = private_contacts_selector:exec()
  100.69 +        for i, contact in ipairs(contacts) do
  100.70 +          ui.sidebarSection( "sidebarRowNarrow", function()
  100.71 +            execute.view{ module = "member_image", view = "_show", params = {
  100.72 +              member_id = contact.other_member.id, class = "micro_avatar", 
  100.73 +              popup_text = contact.other_member.name,
  100.74 +              image_type = "avatar", show_dummy = true,
  100.75 +            } }
  100.76 +            slot.put(" ")
  100.77 +            ui.link{
  100.78 +              content = contact.other_member.name,
  100.79 +              module = "member",
  100.80 +              view = "show",
  100.81 +              id = contact.other_member.id
  100.82 +            }
  100.83 +          end )
  100.84 +        end
  100.85 +      end
  100.86 +    }
  100.87 +
  100.88 +  end
  100.89 +end )
  100.90 \ No newline at end of file
   101.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.2 +++ b/app/main/member/_sidebar_whatcanido.lua	Thu Jul 10 01:19:48 2014 +0200
   101.3 @@ -0,0 +1,326 @@
   101.4 +local member = param.get("member", "table")
   101.5 +
   101.6 +ui.sidebar( "tab-whatcanido", function()
   101.7 +
   101.8 +  if not member.active then
   101.9 +    ui.container{ attr = { class = "sidebarSection" }, content = function()
  101.10 +      slot.put(" &middot; ")
  101.11 +      ui.tag{
  101.12 +        attr = { class = "interest deactivated_member_info" },
  101.13 +        content = _"This member is inactive"
  101.14 +      }
  101.15 +    end }   
  101.16 +  end
  101.17 +  
  101.18 +  if member.locked then
  101.19 +    ui.container{ attr = { class = "sidebarSection" }, content = function()
  101.20 +      slot.put(" &middot; ")
  101.21 +      ui.tag{
  101.22 +        attr = { class = "interest deactivated_member_info" },
  101.23 +        content = _"This member is locked"
  101.24 +      }
  101.25 +    end }   
  101.26 +  end
  101.27 +
  101.28 +  
  101.29 +  ui.sidebarHeadWhatCanIDo()
  101.30 +
  101.31 +  if member.id == app.session.member_id and not app.session.needs_delegation_check then
  101.32 +    ui.sidebarSection( function()
  101.33 +      ui.heading { level = 3, content = _"I want to customize my profile" }
  101.34 +      ui.tag{ tag = "ul", attr = { class = "ul" }, content = function()
  101.35 +        ui.tag{ tag = "li", content = function()
  101.36 +          ui.link{
  101.37 +            content = _"edit profile data",
  101.38 +            module  = "member",
  101.39 +            view    = "edit"
  101.40 +          }
  101.41 +        end }
  101.42 +        ui.tag{ tag = "li", content = function()
  101.43 +          ui.link{
  101.44 +            content = _"change avatar/photo",
  101.45 +            module  = "member",
  101.46 +            view    = "edit_images"
  101.47 +          }
  101.48 +        end }
  101.49 +      end }
  101.50 +    end )
  101.51 +    --[[
  101.52 +    ui.sidebarSection( function()
  101.53 +      ui.heading { level = 3, content = _"I want to manage my saved contacts" }
  101.54 +      ui.tag{ tag = "ul", attr = { class = "ul" }, content = function()
  101.55 +        ui.tag{ tag = "li", content = function()
  101.56 +
  101.57 +          ui.link{
  101.58 +            content = _"show saved contacts",
  101.59 +            module = 'contact',
  101.60 +            view   = 'list'
  101.61 +          }
  101.62 +
  101.63 +        end }
  101.64 +      end }
  101.65 +    end )
  101.66 +    --]]
  101.67 +    
  101.68 +    ui.sidebarSection( function()
  101.69 +
  101.70 +      ui.heading { level = 3, content = _"I want to change account settings" }
  101.71 +
  101.72 +      local pages = {}
  101.73 +
  101.74 +      pages[#pages+1] = { view = "settings_notification", text = _"notification settings" }
  101.75 +      if not config.locked_profile_fields.notify_email then
  101.76 +        pages[#pages+1] = { view = "settings_email",          text = _"change your notification email address" }
  101.77 +      end
  101.78 +      if not config.locked_profile_fields.name then
  101.79 +        pages[#pages+1] = { view = "settings_name",           text = _"change your screen name" }
  101.80 +      end
  101.81 +      if not config.locked_profile_fields.login then
  101.82 +        pages[#pages+1] = { view = "settings_login",          text = _"change your login" }
  101.83 +      end
  101.84 +      pages[#pages+1] = { view = "settings_password",       text = _"change your password" }
  101.85 +      pages[#pages+1] = { view = "developer_settings",      text = _"developer settings" }
  101.86 +
  101.87 +      if config.download_dir then
  101.88 +        pages[#pages+1] = { module = "index", view = "download",      text = _"database download" }
  101.89 +      end
  101.90 +
  101.91 +      ui.tag{ tag = "ul", attr = { class = "ul" }, content = function()
  101.92 +        for i, page in ipairs(pages) do
  101.93 +          ui.tag{ tag = "li", content = function()
  101.94 +            ui.link{
  101.95 +              module = page.module or "member",
  101.96 +              view = page.view,
  101.97 +              text = page.text
  101.98 +            }
  101.99 +          end }
 101.100 +        end
 101.101 +      end }
 101.102 +    end )
 101.103 +    
 101.104 +    ui.sidebarSection( function()
 101.105 +      ui.heading { level = 3, content = _"I want to logout" }
 101.106 +      ui.tag{ tag = "ul", attr = { class = "ul" }, content = function()
 101.107 +        ui.tag{ tag = "li", content = function()
 101.108 +          ui.link{
 101.109 +            text   = _"logout",
 101.110 +            module = 'index',
 101.111 +            action = 'logout',
 101.112 +            routing = {
 101.113 +              default = {
 101.114 +                mode = "redirect",
 101.115 +                module = "index",
 101.116 +                view = "index"
 101.117 +              }
 101.118 +            }
 101.119 +          }
 101.120 +        end }
 101.121 +      end }
 101.122 +    end )
 101.123 +    
 101.124 +    ui.sidebarSection( function()
 101.125 +      ui.heading { level = 3, content = _"I want to change the interface language" }
 101.126 +      ui.tag{ tag = "ul", attr = { class = "ul" }, content = function()
 101.127 +        for i, lang in ipairs(config.enabled_languages) do
 101.128 +          
 101.129 +          local langcode
 101.130 +          
 101.131 +          locale.do_with({ lang = lang }, function()
 101.132 +            langcode = _("[Name of Language]")
 101.133 +          end)
 101.134 +          
 101.135 +          ui.tag{ tag = "li", content = function()
 101.136 +            ui.link{
 101.137 +              content = _('Select language "#{langcode}"', { langcode = langcode }),
 101.138 +              module = "index",
 101.139 +              action = "set_lang",
 101.140 +              params = { lang = lang },
 101.141 +              routing = {
 101.142 +                default = {
 101.143 +                  mode = "redirect",
 101.144 +                  module = request.get_module(),
 101.145 +                  view = request.get_view(),
 101.146 +                  id = param.get_id_cgi(),
 101.147 +                  params = param.get_all_cgi()
 101.148 +                }
 101.149 +              }
 101.150 +            }
 101.151 +          end }
 101.152 +        end
 101.153 +      end }
 101.154 +    end )
 101.155 +  elseif app.session.member_id and not (member.id == app.session.member.id) then
 101.156 +    
 101.157 +    ui.sidebarSection( function ()
 101.158 +
 101.159 +      local contact = Contact:by_pk(app.session.member.id, member.id)
 101.160 +      if not contact then
 101.161 +        ui.heading { level = 3, content = _"I want to save this member as contact (i.e. to use as delegatee)" }
 101.162 +        ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
 101.163 +          ui.tag { tag = "li", content = function ()
 101.164 +            ui.link{
 101.165 +              text    = _"add to my list of public contacts",
 101.166 +              module  = "contact",
 101.167 +              action  = "add_member",
 101.168 +              id      = member.id,
 101.169 +              params = { public = true },
 101.170 +              routing = {
 101.171 +                default = {
 101.172 +                  mode = "redirect",
 101.173 +                  module = request.get_module(),
 101.174 +                  view = request.get_view(),
 101.175 +                  id = param.get_id_cgi(),
 101.176 +                  params = param.get_all_cgi()
 101.177 +                }
 101.178 +              }
 101.179 +            }
 101.180 +          end }
 101.181 +          ui.tag { tag = "li", content = function ()
 101.182 +            ui.link{
 101.183 +              text    = _"add to my list of private contacts",
 101.184 +              module  = "contact",
 101.185 +              action  = "add_member",
 101.186 +              id      = member.id,
 101.187 +              routing = {
 101.188 +                default = {
 101.189 +                  mode = "redirect",
 101.190 +                  module = request.get_module(),
 101.191 +                  view = request.get_view(),
 101.192 +                  id = param.get_id_cgi(),
 101.193 +                  params = param.get_all_cgi()
 101.194 +                }
 101.195 +              }
 101.196 +            }
 101.197 +          end }
 101.198 +        end }
 101.199 +      elseif contact.public then
 101.200 +        ui.heading { level = 3, content = _"You saved this member as contact (i.e. to use as delegatee) and others can see it" }
 101.201 +        ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
 101.202 +          ui.tag { tag = "li", content = function ()
 101.203 +            ui.link{
 101.204 +              text   = _"make this contact private",
 101.205 +              module = "contact",
 101.206 +              action = "add_member",
 101.207 +              id     = contact.other_member_id,
 101.208 +              params = { public = false },
 101.209 +              routing = {
 101.210 +                default = {
 101.211 +                  mode = "redirect",
 101.212 +                  module = request.get_module(),
 101.213 +                  view = request.get_view(),
 101.214 +                  id = param.get_id_cgi(),
 101.215 +                  params = param.get_all_cgi()
 101.216 +                }
 101.217 +              }
 101.218 +            }
 101.219 +          end }
 101.220 +          ui.tag { tag = "li", content = function ()
 101.221 +            ui.link{
 101.222 +              text   = _"remove from my contact list",
 101.223 +              module = "contact",
 101.224 +              action = "remove_member",
 101.225 +              id     = contact.other_member_id,
 101.226 +              routing = {
 101.227 +                default = {
 101.228 +                  mode = "redirect",
 101.229 +                  module = request.get_module(),
 101.230 +                  view = request.get_view(),
 101.231 +                  id = param.get_id_cgi(),
 101.232 +                  params = param.get_all_cgi()
 101.233 +                }
 101.234 +              }
 101.235 +            }
 101.236 +          end }
 101.237 +        end }
 101.238 +      else
 101.239 +        ui.heading { level = 3, content = _"You saved this member as contact (i.e. to use as delegatee)" }
 101.240 +        ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
 101.241 +          ui.tag { tag = "li", content = function ()
 101.242 +            ui.link{
 101.243 +              text   = _"make this contact public",
 101.244 +              module = "contact",
 101.245 +              action = "add_member",
 101.246 +              id     = contact.other_member_id,
 101.247 +              params = { public = true },
 101.248 +              routing = {
 101.249 +                default = {
 101.250 +                  mode = "redirect",
 101.251 +                  module = request.get_module(),
 101.252 +                  view = request.get_view(),
 101.253 +                  id = param.get_id_cgi(),
 101.254 +                  params = param.get_all_cgi()
 101.255 +                }
 101.256 +              }
 101.257 +            }
 101.258 +          end }
 101.259 +          ui.tag { tag = "li", content = function ()
 101.260 +            ui.link{
 101.261 +              text   = _"remove from my contact list",
 101.262 +              module = "contact",
 101.263 +              action = "remove_member",
 101.264 +              id     = contact.other_member_id,
 101.265 +              routing = {
 101.266 +                default = {
 101.267 +                  mode = "redirect",
 101.268 +                  module = request.get_module(),
 101.269 +                  view = request.get_view(),
 101.270 +                  id = param.get_id_cgi(),
 101.271 +                  params = param.get_all_cgi()
 101.272 +                }
 101.273 +              }
 101.274 +            }
 101.275 +          end }
 101.276 +        end }
 101.277 +      end
 101.278 +    end )
 101.279 +    
 101.280 +    ui.sidebarSection( function()
 101.281 +      local ignored_member = IgnoredMember:by_pk(app.session.member.id, member.id)
 101.282 +      if not ignored_member then
 101.283 +        ui.heading { level = 3, content = _"I do not like to hear from this member" }
 101.284 +        ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
 101.285 +          ui.tag { tag = "li", content = function ()
 101.286 +            ui.link{
 101.287 +              attr = { class = "interest" },
 101.288 +              text    = _"block this member",
 101.289 +              module  = "member",
 101.290 +              action  = "update_ignore_member",
 101.291 +              id      = member.id,
 101.292 +              routing = {
 101.293 +                default = {
 101.294 +                  mode = "redirect",
 101.295 +                  module = request.get_module(),
 101.296 +                  view = request.get_view(),
 101.297 +                  id = param.get_id_cgi(),
 101.298 +                  params = param.get_all_cgi()
 101.299 +                }
 101.300 +              }
 101.301 +            }
 101.302 +          end }
 101.303 +        end }
 101.304 +      else
 101.305 +        ui.heading { level = 3, content = _"You blocked this member (i.e. you will not be notified about this members actions)" }
 101.306 +        ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
 101.307 +          ui.tag { tag = "li", content = function ()
 101.308 +            ui.link{
 101.309 +              text   = _"unblock member",
 101.310 +              module = "member",
 101.311 +              action = "update_ignore_member",
 101.312 +              id     = member.id,
 101.313 +              params = { delete = true },
 101.314 +              routing = {
 101.315 +                default = {
 101.316 +                  mode = "redirect",
 101.317 +                  module = request.get_module(),
 101.318 +                  view = request.get_view(),
 101.319 +                  id = param.get_id_cgi(),
 101.320 +                  params = param.get_all_cgi()
 101.321 +                }
 101.322 +              }
 101.323 +            }
 101.324 +          end }
 101.325 +        end }
 101.326 +      end
 101.327 +    end )
 101.328 +  end
 101.329 +end )
 101.330 \ No newline at end of file
   102.1 --- a/app/main/member/developer_settings.lua	Thu Jul 10 01:02:43 2014 +0200
   102.2 +++ b/app/main/member/developer_settings.lua	Thu Jul 10 01:19:48 2014 +0200
   102.3 @@ -1,96 +1,116 @@
   102.4  ui.title(_"Developer settings")
   102.5  
   102.6 +execute.view {
   102.7 +  module = "member", view = "_sidebar_whatcanido", params = {
   102.8 +    member = app.session.member
   102.9 +  }
  102.10 +}
  102.11  
  102.12  local setting_key = "liquidfeedback_frontend_developer_features"
  102.13  local setting = Setting:by_pk(app.session.member.id, setting_key)
  102.14  
  102.15 -if setting then
  102.16 -  ui.form{
  102.17 -    attr = { class = "vertical" },
  102.18 -    module = "member",
  102.19 -    action = "update_stylesheet_url",
  102.20 -    routing = {
  102.21 -      ok = {
  102.22 -        mode = "redirect",
  102.23 -        module = "index",
  102.24 -        view = "index"
  102.25 +if true or setting then
  102.26 +  ui.section( function()
  102.27 +    ui.sectionHead( function ()
  102.28 +      ui.heading{ content = "CSS development settings" }
  102.29 +    end )
  102.30 +
  102.31 +    ui.sectionRow( function()
  102.32 +      ui.form{
  102.33 +        attr = { class = "vertical" },
  102.34 +        module = "member",
  102.35 +        action = "update_stylesheet_url",
  102.36 +        routing = {
  102.37 +          ok = {
  102.38 +            mode = "redirect",
  102.39 +            module = "member",
  102.40 +            view = "show",
  102.41 +            id = app.session.member_id
  102.42 +          }
  102.43 +        },
  102.44 +        content = function()
  102.45 +          local setting_key = "liquidfeedback_frontend_stylesheet_url"
  102.46 +          local setting = Setting:by_pk(app.session.member.id, setting_key)
  102.47 +          local value = setting and setting.value
  102.48 +          ui.field.text{ 
  102.49 +            label = "stylesheet URL",
  102.50 +            name = "stylesheet_url",
  102.51 +            value = value
  102.52 +          }
  102.53 +          ui.submit{ value = _"Set URL" }
  102.54 +        end
  102.55        }
  102.56 -    },
  102.57 -    content = function()
  102.58 -      local setting_key = "liquidfeedback_frontend_stylesheet_url"
  102.59 -      local setting = Setting:by_pk(app.session.member.id, setting_key)
  102.60 -      local value = setting and setting.value
  102.61 -      ui.field.text{ 
  102.62 -        label = _"Stylesheet URL",
  102.63 -        name = "stylesheet_url",
  102.64 -        value = value
  102.65 -      }
  102.66 -      ui.submit{ value = _"Set URL" }
  102.67 -    end
  102.68 -  }
  102.69 +    end )
  102.70 +  end )
  102.71  end
  102.72  
  102.73 -ui.heading{ content = _"API keys" }
  102.74 +ui.section( function()
  102.75 +  ui.sectionHead( function ()
  102.76 +    ui.heading{ content = "API keys" }
  102.77 +  end )
  102.78  
  102.79 -local member_applications = MemberApplication:new_selector()
  102.80 -  :add_where{ "member_id = ?", app.session.member.id }
  102.81 -  :add_order_by("name, id")
  102.82 -  :exec()
  102.83 -  
  102.84 -if #member_applications > 0 then
  102.85 +  ui.sectionRow( function()
  102.86 +    local member_applications = MemberApplication:new_selector()
  102.87 +      :add_where{ "member_id = ?", app.session.member.id }
  102.88 +      :add_order_by("name, id")
  102.89 +      :exec()
  102.90 +      
  102.91 +    if #member_applications > 0 then
  102.92  
  102.93 -  ui.list{
  102.94 -    records = member_applications,
  102.95 -    columns = {
  102.96 -      {
  102.97 -        name = "name",
  102.98 -        label = _"Name"
  102.99 -      },
 102.100 -      {
 102.101 -        name = "access_level",
 102.102 -        label = _"Access level"
 102.103 -      },
 102.104 -      {
 102.105 -        name = "key",
 102.106 -        label = _"API Key"
 102.107 -      },
 102.108 -      {
 102.109 -        name = "last_usage",
 102.110 -        label = "Last usage"
 102.111 -      },
 102.112 -      {
 102.113 -        content = function(member_application)
 102.114 -          ui.link{
 102.115 -            text = _"Delete",
 102.116 -            module = "member", action = "update_api_key", id = member_application.id,
 102.117 -            params = { delete = true },
 102.118 -            routing = {
 102.119 -              default = {
 102.120 -                mode = "redirect",
 102.121 -                module = "member",
 102.122 -                view = "developer_settings"
 102.123 +      ui.list{
 102.124 +        records = member_applications,
 102.125 +        columns = {
 102.126 +          {
 102.127 +            name = "name",
 102.128 +            label = "Name"
 102.129 +          },
 102.130 +          {
 102.131 +            name = "access_level",
 102.132 +            label = "Access level"
 102.133 +          },
 102.134 +          {
 102.135 +            name = "key",
 102.136 +            label = "API Key"
 102.137 +          },
 102.138 +          {
 102.139 +            name = "last_usage",
 102.140 +            label = "Last usage"
 102.141 +          },
 102.142 +          {
 102.143 +            content = function(member_application)
 102.144 +              ui.link{
 102.145 +                text = "delete",
 102.146 +                module = "member", action = "update_api_key", id = member_application.id,
 102.147 +                params = { delete = true },
 102.148 +                routing = {
 102.149 +                  default = {
 102.150 +                    mode = "redirect",
 102.151 +                    module = "member",
 102.152 +                    view = "developer_settings"
 102.153 +                  }
 102.154 +                }
 102.155                }
 102.156 -            }
 102.157 -          }
 102.158 -        end
 102.159 -      },
 102.160 -    }
 102.161 -  }
 102.162 +            end
 102.163 +          },
 102.164 +        }
 102.165 +      }
 102.166  
 102.167 -else
 102.168 -  
 102.169 -  slot.put(_"Currently no API key is set.")
 102.170 -  slot.put(" ")
 102.171 -  ui.link{
 102.172 -    text = _"Generate API key",
 102.173 -    module = "member",
 102.174 -    action = "update_api_key",
 102.175 -    routing = {
 102.176 -      default = {
 102.177 -        mode = "redirect",
 102.178 +    else
 102.179 +      
 102.180 +      slot.put(_"Currently no API key is set.")
 102.181 +      slot.put(" ")
 102.182 +      ui.link{
 102.183 +        text = _"Generate API key",
 102.184          module = "member",
 102.185 -        view = "developer_settings"
 102.186 +        action = "update_api_key",
 102.187 +        routing = {
 102.188 +          default = {
 102.189 +            mode = "redirect",
 102.190 +            module = "member",
 102.191 +            view = "developer_settings"
 102.192 +          }
 102.193 +        }
 102.194        }
 102.195 -    }
 102.196 -  }
 102.197 -end
 102.198 +    end
 102.199 +  end )
 102.200 +end )
 102.201 \ No newline at end of file
   103.1 --- a/app/main/member/edit.lua	Thu Jul 10 01:02:43 2014 +0200
   103.2 +++ b/app/main/member/edit.lua	Thu Jul 10 01:19:48 2014 +0200
   103.3 @@ -1,6 +1,10 @@
   103.4 -ui.title(_"Edit my profile")
   103.5 +ui.titleMember(_"Edit your profile data")
   103.6  
   103.7 -util.help("member.edit", _"Edit my page")
   103.8 +execute.view {
   103.9 +  module = "member", view = "_sidebar_whatcanido", params = {
  103.10 +    member = app.session.member
  103.11 +  }
  103.12 +}
  103.13  
  103.14  ui.form{
  103.15    record = app.session.member,
  103.16 @@ -16,73 +20,98 @@
  103.17      }
  103.18    },
  103.19    content = function()
  103.20 -    ui.field.text{ label = _"Identification", name = "identification", readonly = true }
  103.21 -    ui.field.text{ label = _"Organizational unit", name = "organizational_unit", readonly = config.locked_profile_fields.organizational_unit }
  103.22 -    ui.field.text{ label = _"Internal posts", name = "internal_posts", readonly = config.locked_profile_fields.internal_posts }
  103.23 -    ui.field.text{ label = _"Real name", name = "realname", readonly = config.locked_profile_fields.realname }
  103.24 -    ui.field.text{ label = _"Birthday" .. " YYYY-MM-DD ", name = "birthday", attr = { id = "profile_birthday" }, readonly = config.locked_profile_fields.birthday }
  103.25 -    ui.script{ static = "gregor.js/gregor.js" }
  103.26 -    util.gregor("profile_birthday", "document.getElementById('timeline_search_date').form.submit();")
  103.27 -    ui.field.text{ label = _"Address", name = "address", multiline = true, readonly = config.locked_profile_fields.address }
  103.28 -    ui.field.text{ label = _"email", name = "email", readonly = config.locked_profile_fields.email }
  103.29 -    ui.field.text{ label = _"xmpp", name = "xmpp_address", readonly = config.locked_profile_fields.xmpp_address }
  103.30 -    ui.field.text{ label = _"Website", name = "website", readonly = config.locked_profile_fields.website }
  103.31 -    ui.field.text{ label = _"Phone", name = "phone", readonly = config.locked_profile_fields.phone }
  103.32 -    ui.field.text{ label = _"Mobile phone", name = "mobile_phone", readonly = config.locked_profile_fields.mobile_phone }
  103.33 -    ui.field.text{ label = _"Profession", name = "profession", readonly = config.locked_profile_fields.profession }
  103.34 -    ui.field.text{ label = _"External memberships", name = "external_memberships", multiline = true, readonly = config.locked_profile_fields.external_memberships }
  103.35 -    ui.field.text{ label = _"External posts", name = "external_posts", multiline = true, readonly = config.locked_profile_fields.external_posts }
  103.36 +  
  103.37 +    ui.section( function()
  103.38 +    
  103.39 +      ui.sectionHead( function()
  103.40 +        ui.heading{ level = 1, content = _"Edit your profile data" }
  103.41 +      end )
  103.42 +      
  103.43 +      ui.sectionRow( _"All fields are optional. Please enter only data which should be published." )
  103.44 +      
  103.45 +      ui.sectionRow( function()
  103.46 +  
  103.47 +        ui.field.text{ label = _"Organizational unit", name = "organizational_unit", readonly = config.locked_profile_fields.organizational_unit }
  103.48 +        ui.field.text{ label = _"Internal posts", name = "internal_posts", readonly = config.locked_profile_fields.internal_posts }
  103.49 +        ui.field.text{ label = _"Real name", name = "realname", readonly = config.locked_profile_fields.realname }
  103.50 +        ui.field.text{ label = _"Birthday" .. " YYYY-MM-DD ", name = "birthday", attr = { id = "profile_birthday" }, readonly = config.locked_profile_fields.birthday }
  103.51 +        ui.script{ static = "gregor.js/gregor.js" }
  103.52 +        util.gregor("profile_birthday", "document.getElementById('timeline_search_date').form.submit();")
  103.53 +        ui.field.text{ label = _"Address", name = "address", multiline = true, readonly = config.locked_profile_fields.address }
  103.54 +        ui.field.text{ label = _"email", name = "email", readonly = config.locked_profile_fields.email }
  103.55 +        ui.field.text{ label = _"xmpp", name = "xmpp_address", readonly = config.locked_profile_fields.xmpp_address }
  103.56 +        ui.field.text{ label = _"Website", name = "website", readonly = config.locked_profile_fields.website }
  103.57 +        ui.field.text{ label = _"Phone", name = "phone", readonly = config.locked_profile_fields.phone }
  103.58 +        ui.field.text{ label = _"Mobile phone", name = "mobile_phone", readonly = config.locked_profile_fields.mobile_phone }
  103.59 +        ui.field.text{ label = _"Profession", name = "profession", readonly = config.locked_profile_fields.profession }
  103.60 +        ui.field.text{ label = _"External memberships", name = "external_memberships", multiline = true, readonly = config.locked_profile_fields.external_memberships }
  103.61 +        ui.field.text{ label = _"External posts", name = "external_posts", multiline = true, readonly = config.locked_profile_fields.external_posts }
  103.62  
  103.63 -    ui.field.select{
  103.64 -      label = _"Wiki engine for statement",
  103.65 -      name = "formatting_engine",
  103.66 -      foreign_records = {
  103.67 -        { id = "rocketwiki", name = "RocketWiki" },
  103.68 -        { id = "compat", name = _"Traditional wiki syntax" }
  103.69 -      },
  103.70 -      attr = {id = "formatting_engine"},
  103.71 -      foreign_id = "id",
  103.72 -      foreign_name = "name",
  103.73 -      value = param.get("formatting_engine")
  103.74 -    }
  103.75 -    ui.tag{
  103.76 -      tag = "div",
  103.77 -      content = function()
  103.78 -        ui.tag{
  103.79 -          tag = "label",
  103.80 -          attr = { class = "ui_field_label" },
  103.81 -          content = function() slot.put("&nbsp;") end,
  103.82 +        if not config.enforce_formatting_engine then
  103.83 +          ui.field.select{
  103.84 +            label = _"Wiki engine for statement",
  103.85 +            name = "formatting_engine",
  103.86 +            foreign_records = config.formatting_engines,
  103.87 +            attr = {id = "formatting_engine"},
  103.88 +            foreign_id = "id",
  103.89 +            foreign_name = "name",
  103.90 +            value = param.get("formatting_engine")
  103.91 +          }
  103.92 +          ui.tag{
  103.93 +            tag = "div",
  103.94 +            content = function()
  103.95 +              ui.tag{
  103.96 +                tag = "label",
  103.97 +                attr = { class = "ui_field_label" },
  103.98 +                content = function() slot.put("&nbsp;") end,
  103.99 +              }
 103.100 +              ui.tag{
 103.101 +                content = function()
 103.102 +                  ui.link{
 103.103 +                    text = _"Syntax help",
 103.104 +                    module = "help",
 103.105 +                    view = "show",
 103.106 +                    id = "wikisyntax",
 103.107 +                    attr = {onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"}
 103.108 +                  }
 103.109 +                  slot.put(" ")
 103.110 +                  ui.link{
 103.111 +                    text = _"(new window)",
 103.112 +                    module = "help",
 103.113 +                    view = "show",
 103.114 +                    id = "wikisyntax",
 103.115 +                    attr = {target = "_blank", onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"}
 103.116 +                  }
 103.117 +                end
 103.118 +              }
 103.119 +            end
 103.120 +          }
 103.121 +        end
 103.122 +        ui.field.text{
 103.123 +          label = _"Statement",
 103.124 +          name = "statement",
 103.125 +          multiline = true, 
 103.126 +          attr = { style = "height: 50ex;" },
 103.127 +          value = param.get("statement")
 103.128          }
 103.129 -        ui.tag{
 103.130 -          content = function()
 103.131 -            ui.link{
 103.132 -              text = _"Syntax help",
 103.133 -              module = "help",
 103.134 -              view = "show",
 103.135 -              id = "wikisyntax",
 103.136 -              attr = {onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"}
 103.137 -            }
 103.138 -            slot.put(" ")
 103.139 -            ui.link{
 103.140 -              text = _"(new window)",
 103.141 -              module = "help",
 103.142 -              view = "show",
 103.143 -              id = "wikisyntax",
 103.144 -              attr = {target = "_blank", onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"}
 103.145 -            }
 103.146 -          end
 103.147 -        }
 103.148 -      end
 103.149 -    }
 103.150 -    ui.field.text{
 103.151 -      label = _"Statement",
 103.152 -      name = "statement",
 103.153 -      multiline = true, 
 103.154 -      attr = { style = "height: 50ex;" },
 103.155 -      value = param.get("statement")
 103.156 -    }
 103.157 -
 103.158 -    
 103.159 -    ui.submit{ value = _"Save" }
 103.160 +        slot.put("<br />")
 103.161 +        ui.container{ attr = { class = "actions" }, content = function()
 103.162 +          ui.tag{
 103.163 +            tag = "input",
 103.164 +            attr = {
 103.165 +              type = "submit",
 103.166 +              class = "btn btn-default",
 103.167 +              value = _"publish profile data"
 103.168 +            },
 103.169 +            content = ""
 103.170 +          }
 103.171 +          slot.put("<br /><br /><br />")
 103.172 +          ui.link{
 103.173 +            content = _"cancel",
 103.174 +            module = "member", view = "show", id = app.session.member.id
 103.175 +          }
 103.176 +        end }
 103.177 +      end )
 103.178 +    end )
 103.179    end
 103.180  }
 103.181 \ No newline at end of file
   104.1 --- a/app/main/member/edit_images.lua	Thu Jul 10 01:02:43 2014 +0200
   104.2 +++ b/app/main/member/edit_images.lua	Thu Jul 10 01:19:48 2014 +0200
   104.3 @@ -1,11 +1,15 @@
   104.4 -ui.title(_"Upload images")
   104.5 +ui.titleMember(_"avatar/photo")
   104.6  
   104.7 -util.help("member.edit_images", _"Images")
   104.8 +execute.view {
   104.9 +  module = "member", view = "_sidebar_whatcanido", params = {
  104.10 +    member = app.session.member
  104.11 +  }
  104.12 +}
  104.13  
  104.14  ui.form{
  104.15    record = app.session.member,
  104.16    attr = { 
  104.17 -    class = "vertical",
  104.18 +    class = "vertical section",
  104.19      enctype = 'multipart/form-data'
  104.20    },
  104.21    module = "member",
  104.22 @@ -19,24 +23,52 @@
  104.23      }
  104.24    },
  104.25    content = function()
  104.26 -    execute.view{
  104.27 -      module = "member_image",
  104.28 -      view = "_show",
  104.29 -      params = {
  104.30 -        member = app.session.member, 
  104.31 -        image_type = "avatar"
  104.32 +    ui.sectionHead( function()
  104.33 +      ui.heading { level = 1, content = _"Upload avatar/photo" }
  104.34 +    end )
  104.35 +    ui.sectionRow( function()
  104.36 +      execute.view{
  104.37 +        module = "member_image",
  104.38 +        view = "_show",
  104.39 +        params = {
  104.40 +          class = "right",
  104.41 +          member = app.session.member, 
  104.42 +          image_type = "avatar"
  104.43 +        }
  104.44        }
  104.45 -    }
  104.46 -    ui.field.image{ field_name = "avatar", label = _"Avatar" }
  104.47 -    execute.view{
  104.48 -      module = "member_image",
  104.49 -      view = "_show",
  104.50 -      params = {
  104.51 -        member = app.session.member, 
  104.52 -        image_type = "photo"
  104.53 +      ui.heading { level = 2, content = _"Avatar"}
  104.54 +      ui.container { content = _"Your avatar is a small photo, which will be shown always next to your name." }
  104.55 +      slot.put("<br />")
  104.56 +      ui.field.image{ field_name = "avatar" }
  104.57 +      slot.put("<br /><br />")
  104.58 +      execute.view{
  104.59 +        module = "member_image",
  104.60 +        view = "_show",
  104.61 +        params = {
  104.62 +          class = "right",
  104.63 +          member = app.session.member, 
  104.64 +          image_type = "photo"
  104.65 +        }
  104.66        }
  104.67 -    }
  104.68 -    ui.field.image{ field_name = "photo", label = _"Photo" }
  104.69 -    ui.submit{ value = _"Save" }
  104.70 +      ui.heading { level = 2, content = _"Photo"}
  104.71 +      ui.container { content = _"Your photo will be shown in your profile." }
  104.72 +      slot.put("<br />")
  104.73 +      ui.field.image{ field_name = "photo" }
  104.74 +      slot.put("<br style='clear: right;' />")
  104.75 +      ui.tag{
  104.76 +        tag = "input",
  104.77 +        attr = {
  104.78 +          type = "submit",
  104.79 +          class = "btn btn-default",
  104.80 +          value = _"publish avatar/photo"
  104.81 +        },
  104.82 +        content = ""
  104.83 +      }
  104.84 +      slot.put("<br /><br /><br />")
  104.85 +      ui.link{
  104.86 +        content = _"cancel",
  104.87 +        module = "member", view = "show", id = app.session.member.id
  104.88 +      }
  104.89 +    end )
  104.90    end
  104.91  }
  104.92 \ No newline at end of file
   105.1 --- a/app/main/member/history.lua	Thu Jul 10 01:02:43 2014 +0200
   105.2 +++ b/app/main/member/history.lua	Thu Jul 10 01:19:48 2014 +0200
   105.3 @@ -1,76 +1,72 @@
   105.4  local member = Member:by_id(param.get_id())
   105.5  
   105.6 -slot.select("head", function()
   105.7 -  ui.container{
   105.8 -    attr = { class = "title" }, 
   105.9 -    content = _("Member name history for '#{name}'", { name = member.name })
  105.10 -  }
  105.11 -  ui.container{ attr = { class = "actions" }, content = function()
  105.12 -    ui.link{
  105.13 +ui.titleMember(member)
  105.14 +
  105.15 +ui.section( function()
  105.16 +
  105.17 +  ui.sectionHead( function()
  105.18 +    ui.heading{ level = 1, content = _"Account history" }
  105.19 +  end)
  105.20 +
  105.21 +  ui.sectionRow( function()
  105.22 +    ui.form{
  105.23 +      attr = { class = "vertical" },
  105.24        content = function()
  105.25 -          ui.image{ static = "icons/16/cancel.png" }
  105.26 -          slot.put(_"Back")
  105.27 -      end,
  105.28 -      module = "member",
  105.29 -      view = "show",
  105.30 -      id = member.id
  105.31 +        ui.field.text{ label = _"Current name", value = member.name }
  105.32 +        ui.field.text{ label = _"Current status", value = member.active and _'activated' or _'deactivated' }
  105.33 +      end
  105.34      }
  105.35 -  end }
  105.36 -end)
  105.37 -
  105.38 -ui.form{
  105.39 -  attr = { class = "vertical" },
  105.40 -  content = function()
  105.41 -    ui.field.text{ label = _"Current name", value = member.name }
  105.42 -    ui.field.text{ label = _"Current status", value = member.active and _'activated' or _'deactivated' }
  105.43 -  end
  105.44 -}
  105.45  
  105.46  
  105.47 -local entries = member:get_reference_selector("history_entries"):add_order_by("id DESC"):exec()
  105.48 -
  105.49 -ui.tag{
  105.50 -  tag = "table",
  105.51 -  content = function()
  105.52 -    ui.tag{
  105.53 -      tag = "tr",
  105.54 -      content = function()
  105.55 -        ui.tag{
  105.56 -          tag = "th",
  105.57 -          content = _("Name")
  105.58 -        }
  105.59 -        ui.tag{
  105.60 -          tag = "th",
  105.61 -          content = _("Status")
  105.62 -        }
  105.63 -        ui.tag{
  105.64 -          tag = "th",
  105.65 -          content = _("until")
  105.66 -        }
  105.67 -      end
  105.68 -    }
  105.69 -    for i, entry in ipairs(entries) do
  105.70 +    local entries = member:get_reference_selector("history_entries"):add_order_by("id DESC"):exec()
  105.71 +    
  105.72 +    if #entries > 0 then
  105.73        ui.tag{
  105.74 -        tag = "tr",
  105.75 +        tag = "table",
  105.76          content = function()
  105.77            ui.tag{
  105.78 -            tag = "td",
  105.79 -            content = entry.name
  105.80 +            tag = "tr",
  105.81 +            content = function()
  105.82 +              ui.tag{
  105.83 +                tag = "th",
  105.84 +                content = _("Name")
  105.85 +              }
  105.86 +              ui.tag{
  105.87 +                tag = "th",
  105.88 +                content = _("Status")
  105.89 +              }
  105.90 +              ui.tag{
  105.91 +                tag = "th",
  105.92 +                content = _("until")
  105.93 +              }
  105.94 +            end
  105.95            }
  105.96 -          ui.tag{
  105.97 -            tag = "td",
  105.98 -            content = entry.active and _'activated' or _'deactivated',
  105.99 -          }
 105.100 -          ui.tag{
 105.101 -            tag = "td",
 105.102 -            content = format.timestamp(entry["until"])
 105.103 -          }
 105.104 +          for i, entry in ipairs(entries) do
 105.105 +            ui.tag{
 105.106 +              tag = "tr",
 105.107 +              content = function()
 105.108 +                ui.tag{
 105.109 +                  tag = "td",
 105.110 +                  content = entry.name
 105.111 +                }
 105.112 +                ui.tag{
 105.113 +                  tag = "td",
 105.114 +                  content = entry.active and _'activated' or _'deactivated',
 105.115 +                }
 105.116 +                ui.tag{
 105.117 +                  tag = "td",
 105.118 +                  content = format.timestamp(entry["until"])
 105.119 +                }
 105.120 +              end
 105.121 +            }
 105.122 +          end
 105.123          end
 105.124        }
 105.125      end
 105.126 -  end
 105.127 -}
 105.128 -slot.put("<br />")
 105.129 -ui.container{
 105.130 -  content = _("This member account has been created at #{created}", { created = format.timestamp(member.activated)})
 105.131 -}
 105.132 +    slot.put("<br />")
 105.133 +    ui.container{
 105.134 +      content = _("This member account has been created at #{created}", { created = format.timestamp(member.activated)})
 105.135 +    }
 105.136 +  end)
 105.137 +
 105.138 +end)
 105.139 \ No newline at end of file
   106.1 --- a/app/main/member/list.lua	Thu Jul 10 01:02:43 2014 +0200
   106.2 +++ b/app/main/member/list.lua	Thu Jul 10 01:19:48 2014 +0200
   106.3 @@ -1,12 +1,19 @@
   106.4 -slot.put_into("title", _"Member list")
   106.5 -
   106.6 -util.help("member.list")
   106.7 +ui.title(_"Member list")
   106.8  
   106.9  local members_selector = Member:new_selector()
  106.10    :add_where("activated NOTNULL")
  106.11  
  106.12 -execute.view{
  106.13 -  module = "member",
  106.14 -  view = "_list",
  106.15 -  params = { members_selector = members_selector }
  106.16 -}
  106.17 +ui.section( function()
  106.18 +
  106.19 +  ui.sectionHead( function()
  106.20 +    ui.heading { level = 1, content = _"Member list" }
  106.21 +  end )
  106.22 +
  106.23 +  ui.sectionRow( function()
  106.24 +    execute.view{
  106.25 +      module = "member",
  106.26 +      view = "_list",
  106.27 +      params = { members_selector = members_selector }
  106.28 +    }
  106.29 +  end )
  106.30 +end )
   107.1 --- a/app/main/member/settings.lua	Thu Jul 10 01:02:43 2014 +0200
   107.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   107.3 @@ -1,38 +0,0 @@
   107.4 -ui.title(_"Settings")
   107.5 -
   107.6 -local pages = {}
   107.7 -
   107.8 -if not config.locked_profile_fields.name then
   107.9 -  pages[#pages+1] = { view = "settings_name",           text = _"Change your screen name" }
  107.10 -end
  107.11 -if not config.locked_profile_fields.login then
  107.12 -  pages[#pages+1] = { view = "settings_login",          text = _"Change your login" }
  107.13 -end
  107.14 -pages[#pages+1] = { view = "settings_password",       text = _"Change your password" }
  107.15 -if not config.locked_profile_fields.notify_email then
  107.16 -  pages[#pages+1] = { view = "settings_email",          text = _"Change your notification email address" }
  107.17 -end
  107.18 -pages[#pages+1] = { view = "settings_notification", text = _"Notification settings" }
  107.19 -pages[#pages+1] = { view = "developer_settings",      text = _"Developer settings" }
  107.20 -
  107.21 -if config.download_dir then
  107.22 -  pages[#pages+1] = { module = "index", view = "download",      text = _"Database download" }
  107.23 -end
  107.24 -
  107.25 -ui.list{
  107.26 -  attr = { class = "menu_list" },
  107.27 -  style = "ulli",
  107.28 -  records = pages,
  107.29 -  columns = {
  107.30 -    {
  107.31 -      content = function(page)
  107.32 -        ui.link{
  107.33 -          module = page.module or "member",
  107.34 -          view = page.view,
  107.35 -          text = page.text
  107.36 -        }
  107.37 -      end
  107.38 -    }
  107.39 -  }
  107.40 -}
  107.41 -
   108.1 --- a/app/main/member/settings_email.lua	Thu Jul 10 01:02:43 2014 +0200
   108.2 +++ b/app/main/member/settings_email.lua	Thu Jul 10 01:19:48 2014 +0200
   108.3 @@ -1,6 +1,10 @@
   108.4 -ui.title(_"Change your notification email address")
   108.5 +ui.titleMember(_"Email address")
   108.6  
   108.7 -util.help("member.settings.email_address", _"Change email")
   108.8 +execute.view {
   108.9 +  module = "member", view = "_sidebar_whatcanido", params = {
  108.10 +    member = app.session.member
  108.11 +  }
  108.12 +}
  108.13  
  108.14  ui.form{
  108.15    attr = { class = "vertical" },
  108.16 @@ -9,19 +13,47 @@
  108.17    routing = {
  108.18      ok = {
  108.19        mode = "redirect",
  108.20 -      module = "index",
  108.21 -      view = "index"
  108.22 +      module = "member",
  108.23 +      view = "show",
  108.24 +      id = app.session.member_id
  108.25      }
  108.26    },
  108.27    content = function()
  108.28 -    if app.session.member.notify_email then
  108.29 -      ui.field.text{ label = _"Confirmed address", value = app.session.member.notify_email, readonly = true }
  108.30 -    end
  108.31 -    if app.session.member.notify_email_unconfirmed then
  108.32 -      ui.field.text{ label = _"Unconfirmed address", value = app.session.member.notify_email_unconfirmed, readonly = true }
  108.33 -    end
  108.34 -    ui.field.text{ label = _"New address", name = "email" }
  108.35 -    ui.submit{ value = _"Change email" }
  108.36 +    ui.section( function()
  108.37 +
  108.38 +      ui.sectionHead( function()
  108.39 +        ui.heading { level = 1, content = _"Email address for notifications" }
  108.40 +      end )
  108.41 +
  108.42 +      ui.sectionRow( function()
  108.43 +        if app.session.member.notify_email then
  108.44 +          ui.field.text{ label = _"confirmed address", value = app.session.member.notify_email, readonly = true }
  108.45 +        end
  108.46 +        if app.session.member.notify_email_unconfirmed then
  108.47 +          ui.field.text{ label = _"unconfirmed address", value = app.session.member.notify_email_unconfirmed, readonly = true }
  108.48 +        end
  108.49 +        if app.session.member.notify_email or app.session.member.notify_email_unconfirmed then
  108.50 +          slot.put("<br />")
  108.51 +        end
  108.52 +        ui.heading { level = 2, content = _"Enter a new email address:" }
  108.53 +        ui.field.text{ name = "email" }
  108.54 +        slot.put("<br />")
  108.55 +        ui.tag{
  108.56 +          tag = "input",
  108.57 +          attr = {
  108.58 +            type = "submit",
  108.59 +            class = "btn btn-default",
  108.60 +            value = _"Save"
  108.61 +          },
  108.62 +          content = ""
  108.63 +        }
  108.64 +        slot.put("<br /><br /><br />")
  108.65 +        ui.link{
  108.66 +          content = _"Cancel",
  108.67 +          module = "member", view = "show", id = app.session.member.id
  108.68 +        }
  108.69 +      end )
  108.70 +    end )
  108.71    end
  108.72  }
  108.73  
   109.1 --- a/app/main/member/settings_login.lua	Thu Jul 10 01:02:43 2014 +0200
   109.2 +++ b/app/main/member/settings_login.lua	Thu Jul 10 01:19:48 2014 +0200
   109.3 @@ -1,21 +1,52 @@
   109.4 -ui.title(_"Change your login")
   109.5 +ui.titleMember(_"login name")
   109.6  
   109.7 -util.help("member.settings.login", _"Change login")
   109.8 +execute.view {
   109.9 +  module = "member", view = "_sidebar_whatcanido", params = {
  109.10 +    member = app.session.member
  109.11 +  }
  109.12 +}
  109.13  
  109.14  ui.form{
  109.15 -  attr = { class = "vertical" },
  109.16 +  attr = { class = "wide" },
  109.17    module = "member",
  109.18    action = "update_login",
  109.19    routing = {
  109.20      ok = {
  109.21        mode = "redirect",
  109.22 -      module = "index",
  109.23 -      view = "index"
  109.24 +      module = "member",
  109.25 +      view = "show",
  109.26 +      id = app.session.member_id
  109.27      }
  109.28    },
  109.29    content = function()
  109.30 -    ui.field.text{ label = _"Login", name = "login", value = app.session.member.login }
  109.31 -    ui.submit{ value = _"Change login" }
  109.32 +    ui.section( function()
  109.33 +      ui.sectionHead( function()
  109.34 +        ui.heading { level = 1, content = _"Login name" }
  109.35 +      end )
  109.36 +
  109.37 +      ui.sectionRow( function()
  109.38 +        ui.heading { level = 2, content = _"Enter a new login name" }
  109.39 +        ui.field.text{ name = "login", value = app.session.member.login }
  109.40 +        
  109.41 +        slot.put("<br />")
  109.42 +        
  109.43 +        ui.tag{
  109.44 +          tag = "input",
  109.45 +          attr = {
  109.46 +            type = "submit",
  109.47 +            class = "btn btn-default",
  109.48 +            value = _"Save"
  109.49 +          },
  109.50 +          content = ""
  109.51 +        }
  109.52 +        slot.put("<br /><br /><br />")
  109.53 +
  109.54 +        ui.link {
  109.55 +          module = "member", view = "show", id = app.session.member_id, 
  109.56 +          content = _"Cancel"
  109.57 +        }
  109.58 +      end )
  109.59 +    end )
  109.60    end
  109.61  }
  109.62  
   110.1 --- a/app/main/member/settings_name.lua	Thu Jul 10 01:02:43 2014 +0200
   110.2 +++ b/app/main/member/settings_name.lua	Thu Jul 10 01:19:48 2014 +0200
   110.3 @@ -1,20 +1,50 @@
   110.4 -ui.title(_"Change your screen name")
   110.5 +ui.titleMember(_"Screen name")
   110.6  
   110.7 -util.help("member.settings.name", _"Change name")
   110.8 +execute.view {
   110.9 +  module = "member", view = "_sidebar_whatcanido", params = {
  110.10 +    member = app.session.member
  110.11 +  }
  110.12 +}
  110.13  
  110.14  ui.form{
  110.15 -  attr = { class = "vertical" },
  110.16 +  attr = { class = "wide" },
  110.17    module = "member",
  110.18    action = "update_name",
  110.19    routing = {
  110.20      ok = {
  110.21        mode = "redirect",
  110.22 -      module = "index",
  110.23 -      view = "index"
  110.24 +      module = "member",
  110.25 +      view = "show",
  110.26 +      id = app.session.member_id
  110.27      }
  110.28    },
  110.29    content = function()
  110.30 -    ui.field.text{ label = _"Name", name = "name", value = app.session.member.name }
  110.31 -    ui.submit{ value = _"Change name" }
  110.32 +    ui.section( function()
  110.33 +      ui.sectionHead( function()
  110.34 +        ui.heading { level = 1, content = _"Screen name" }
  110.35 +      end )
  110.36 +
  110.37 +      ui.sectionRow( function()
  110.38 +        ui.heading { level = 2, content = _"Enter a new screen name:" }
  110.39 +        ui.field.text{ name = "name", value = app.session.member.name }
  110.40 +        
  110.41 +        slot.put("<br />")
  110.42 +        
  110.43 +        ui.tag{
  110.44 +          tag = "input",
  110.45 +          attr = {
  110.46 +            type = "submit",
  110.47 +            class = "btn btn-default",
  110.48 +            value = _"Save"
  110.49 +          },
  110.50 +          content = ""
  110.51 +        }
  110.52 +        slot.put("<br /><br /><br />")
  110.53 +        ui.link {
  110.54 +          module = "member", view = "show", id = app.session.member_id, 
  110.55 +          content = _"Cancel"
  110.56 +        }
  110.57 +      end )
  110.58 +    end )
  110.59    end
  110.60  }
   111.1 --- a/app/main/member/settings_notification.lua	Thu Jul 10 01:02:43 2014 +0200
   111.2 +++ b/app/main/member/settings_notification.lua	Thu Jul 10 01:19:48 2014 +0200
   111.3 @@ -1,6 +1,12 @@
   111.4 -ui.title(_"Notification settings")
   111.5 +local return_to = param.get("return_to")
   111.6 +
   111.7 +ui.titleMember("notification settings")
   111.8  
   111.9 -util.help("member.settings.notification", _"Notification settings")
  111.10 +execute.view {
  111.11 +  module = "member", view = "_sidebar_whatcanido", params = {
  111.12 +    member = app.session.member
  111.13 +  }
  111.14 +}
  111.15  
  111.16  ui.form{
  111.17    attr = { class = "vertical" },
  111.18 @@ -9,99 +15,138 @@
  111.19    routing = {
  111.20      ok = {
  111.21        mode = "redirect",
  111.22 -      module = "index",
  111.23 -      view = "index"
  111.24 +      module = return_to == "home" and "index" or "member",
  111.25 +      view = return_to == "home" and "index" or "show",
  111.26 +      id = return_to ~= "home" and app.session.member_id or nil
  111.27      }
  111.28    },
  111.29    content = function()
  111.30 -    ui.tag{ tag = "p", content = _"I like to receive notifications by email about events in my areas and issues:" }
  111.31 -  
  111.32 -    ui.container{ content = function()
  111.33 -      ui.tag{
  111.34 -        tag = "input", 
  111.35 -        attr = {
  111.36 -          id = "notify_level_none",
  111.37 -          type = "radio", name = "notify_level", value = "none",
  111.38 -          checked = app.session.member.notify_level == 'none' and "checked" or nil
  111.39 -        }
  111.40 -      }
  111.41 -      ui.tag{
  111.42 -        tag = "label", attr = { ['for'] = "notify_level_none" },
  111.43 -        content = _"No notifications at all"
  111.44 -      }
  111.45 -    end }
  111.46 -     
  111.47 -    slot.put("<br />")
  111.48 -  
  111.49 -    ui.container{ content = function()
  111.50 -      ui.tag{
  111.51 -        tag = "input", 
  111.52 -        attr = {
  111.53 -          id = "notify_level_all",
  111.54 -          type = "radio", name = "notify_level", value = "all",
  111.55 -          checked = app.session.member.notify_level == 'all' and "checked" or nil
  111.56 -        }
  111.57 -      }
  111.58 -      ui.tag{
  111.59 -        tag = "label", attr = { ['for'] = "notify_level_all" },
  111.60 -        content = _"All of them"
  111.61 -      }
  111.62 -    end }
  111.63 +
  111.64 +    ui.section( function()
  111.65 +
  111.66 +      ui.sectionHead( function()
  111.67 +        ui.heading { level = 1, content = _"For which issue phases do you like to receive notification emails?" }
  111.68 +      end )
  111.69 +
  111.70      
  111.71 -    slot.put("<br />")
  111.72 +      ui.sectionRow( function()
  111.73 +      
  111.74 +        ui.container{ content = function()
  111.75 +          ui.tag{
  111.76 +            tag = "input", 
  111.77 +            attr = {
  111.78 +              id = "notify_level_all",
  111.79 +              type = "radio", name = "notify_level", value = "all",
  111.80 +              checked = app.session.member.notify_level == 'all' and "checked" or nil
  111.81 +            }
  111.82 +          }
  111.83 +          ui.tag{
  111.84 +            tag = "label", attr = { ['for'] = "notify_level_all" },
  111.85 +            content = _"I like to receive notifications"
  111.86 +          }
  111.87 +        end }
  111.88 +        
  111.89 +        slot.put("<br />")
  111.90 +
  111.91 +        ui.container{ content = function()
  111.92 +          ui.tag{
  111.93 +            tag = "input", 
  111.94 +            attr = {
  111.95 +              id = "notify_level_discussion",
  111.96 +              type = "radio", name = "notify_level", value = "discussion",
  111.97 +              checked = app.session.member.notify_level == 'discussion' and "checked" or nil
  111.98 +            }
  111.99 +          }
 111.100 +          ui.tag{
 111.101 +            tag = "label", attr = { ['for'] = "notify_level_discussion" },
 111.102 +            content = _"Only for issues reaching the discussion phase"
 111.103 +          }
 111.104 +        end }
 111.105 +
 111.106 +        slot.put("<br />")
 111.107  
 111.108 -    ui.container{ content = function()
 111.109 -      ui.tag{
 111.110 -        tag = "input", 
 111.111 -        attr = {
 111.112 -          id = "notify_level_discussion",
 111.113 -          type = "radio", name = "notify_level", value = "discussion",
 111.114 -          checked = app.session.member.notify_level == 'discussion' and "checked" or nil
 111.115 +        ui.container{ content = function()
 111.116 +          ui.tag{
 111.117 +            tag = "input", 
 111.118 +            attr = {
 111.119 +              id = "notify_level_verification",
 111.120 +              type = "radio", name = "notify_level", value = "verification",
 111.121 +              checked = app.session.member.notify_level == 'verification' and "checked" or nil
 111.122 +            }
 111.123 +          }
 111.124 +          ui.tag{
 111.125 +            tag = "label", attr = { ['for'] = "notify_level_verification" },
 111.126 +            content = _"Only for issues reaching the verification phase"
 111.127 +          }
 111.128 +        end }
 111.129 +        
 111.130 +        slot.put("<br />")
 111.131 +
 111.132 +        ui.container{ content = function()
 111.133 +          ui.tag{
 111.134 +            tag = "input", 
 111.135 +            attr = {
 111.136 +              id = "notify_level_voting",
 111.137 +              type = "radio", name = "notify_level", value = "voting",
 111.138 +              checked = app.session.member.notify_level == 'voting' and "checked" or nil
 111.139 +            }
 111.140 +          }
 111.141 +          ui.tag{
 111.142 +            tag = "label", attr = { ['for'] = "notify_level_voting" },
 111.143 +            content = _"Only for issues reaching the voting phase"
 111.144 +          }
 111.145 +        end }
 111.146 +
 111.147 +        slot.put("<br />")
 111.148 +
 111.149 +        ui.container{ content = function()
 111.150 +          ui.tag{
 111.151 +            tag = "input", 
 111.152 +            attr = {
 111.153 +              id = "notify_level_none",
 111.154 +              type = "radio", name = "notify_level", value = "none",
 111.155 +              checked = app.session.member.notify_level == 'none' and "checked" or nil
 111.156 +            }
 111.157 +          }
 111.158 +          ui.tag{
 111.159 +            tag = "label", attr = { ['for'] = "notify_level_none" },
 111.160 +            content = _"I do not like to receive notifications by email"
 111.161 +          }
 111.162 +        end }
 111.163 +        
 111.164 +        slot.put("<br />")
 111.165 +      
 111.166 +        ui.container { content = _"Notifications are only send to you about events in the subject areas you subscribed, the issues you are interested in and the initiatives you are supporting." }
 111.167 +
 111.168 +
 111.169 +        slot.put("<br />")
 111.170 +        
 111.171 +        ui.tag{
 111.172 +          tag = "input",
 111.173 +          attr = {
 111.174 +            type = "submit",
 111.175 +            class = "btn btn-default",
 111.176 +            value = _"Save"
 111.177 +          },
 111.178 +          content = ""
 111.179          }
 111.180 -      }
 111.181 -      ui.tag{
 111.182 -        tag = "label", attr = { ['for'] = "notify_level_discussion" },
 111.183 -        content = _"Only for issues reaching the discussion phase"
 111.184 -      }
 111.185 -    end }
 111.186 -
 111.187 -    slot.put("<br />")
 111.188 -
 111.189 -    ui.container{ content = function()
 111.190 -      ui.tag{
 111.191 -        tag = "input", 
 111.192 -        attr = {
 111.193 -          id = "notify_level_verification",
 111.194 -          type = "radio", name = "notify_level", value = "verification",
 111.195 -          checked = app.session.member.notify_level == 'verification' and "checked" or nil
 111.196 -        }
 111.197 -      }
 111.198 -      ui.tag{
 111.199 -        tag = "label", attr = { ['for'] = "notify_level_verification" },
 111.200 -        content = _"Only for issues reaching the frozen phase"
 111.201 -      }
 111.202 -    end }
 111.203 +        slot.put("<br /><br /><br />")
 111.204 +        
 111.205 +        slot.put(" ")
 111.206 +        if return_to == "home" then
 111.207 +          ui.link {
 111.208 +            module = "index", view = "index",
 111.209 +            content = _"cancel"
 111.210 +          }
 111.211 +        else
 111.212 +          ui.link {
 111.213 +            module = "member", view = "show", id = app.session.member_id, 
 111.214 +            content = _"cancel"
 111.215 +          }
 111.216 +        end
 111.217 +      end ) 
 111.218 +    end )
 111.219      
 111.220 -    slot.put("<br />")
 111.221 -
 111.222 -    ui.container{ content = function()
 111.223 -      ui.tag{
 111.224 -        tag = "input", 
 111.225 -        attr = {
 111.226 -          id = "notify_level_voting",
 111.227 -          type = "radio", name = "notify_level", value = "voting",
 111.228 -          checked = app.session.member.notify_level == 'voting' and "checked" or nil
 111.229 -        }
 111.230 -      }
 111.231 -      ui.tag{
 111.232 -        tag = "label", attr = { ['for'] = "notify_level_voting" },
 111.233 -        content = _"Only for issues reaching the voting phase"
 111.234 -      }
 111.235 -    end }
 111.236 -
 111.237 -    slot.put("<br />")
 111.238 -
 111.239 -    ui.submit{ value = _"Change notification settings" }
 111.240    end
 111.241  }
 111.242   
   112.1 --- a/app/main/member/settings_password.lua	Thu Jul 10 01:02:43 2014 +0200
   112.2 +++ b/app/main/member/settings_password.lua	Thu Jul 10 01:19:48 2014 +0200
   112.3 @@ -1,22 +1,58 @@
   112.4 -ui.title(_"Change your password")
   112.5 +ui.titleMember(_"Password")
   112.6  
   112.7 -util.help("member.settings.password", _"Change password")
   112.8 +execute.view {
   112.9 +  module = "member", view = "_sidebar_whatcanido", params = {
  112.10 +    member = app.session.member
  112.11 +  }
  112.12 +}
  112.13  
  112.14  ui.form{
  112.15 -  attr = { class = "vertical" },
  112.16 +  attr = { class = "wide" },
  112.17    module = "member",
  112.18    action = "update_password",
  112.19    routing = {
  112.20      ok = {
  112.21        mode = "redirect",
  112.22 -      module = "index",
  112.23 -      view = "index"
  112.24 +      module = "member",
  112.25 +      view = "show",
  112.26 +      id = app.session.member_id
  112.27      }
  112.28    },
  112.29    content = function()
  112.30 -    ui.field.password{ label = _"Old password", name = "old_password" }
  112.31 -    ui.field.password{ label = _"New password", name = "new_password1" }
  112.32 -    ui.field.password{ label = _"Repeat new password", name = "new_password2" }
  112.33 -    ui.submit{ value = _"Change password" }
  112.34 +    ui.section( function()
  112.35 +      ui.sectionHead( function()
  112.36 +        ui.heading { level = 1, content = _"Password" }
  112.37 +      end )
  112.38 +
  112.39 +      ui.sectionRow( function()
  112.40 +        ui.heading { level = 2, content = _"Enter your current password:" }
  112.41 +        ui.field.password{ name = "old_password" }
  112.42 +
  112.43 +        slot.put("<br />")
  112.44 +        
  112.45 +        ui.heading { level = 2, content = _"Enter a new password:" }
  112.46 +        ui.field.password{ name = "new_password1" }
  112.47 +
  112.48 +        ui.heading { level = 2, content = _"Enter your new password again please:" }
  112.49 +        ui.field.password{ name = "new_password2" }
  112.50 +
  112.51 +        slot.put("<br />")
  112.52 +        
  112.53 +        ui.tag{
  112.54 +          tag = "input",
  112.55 +          attr = {
  112.56 +            type = "submit",
  112.57 +            class = "btn btn-default",
  112.58 +            value = _"Save"
  112.59 +          },
  112.60 +          content = ""
  112.61 +        }
  112.62 +        slot.put("<br /><br /><br />")
  112.63 +        ui.link {
  112.64 +          module = "member", view = "show", id = app.session.member_id, 
  112.65 +          content = _"Cancel"
  112.66 +        }
  112.67 +      end )
  112.68 +    end )
  112.69    end
  112.70  }
  112.71 \ No newline at end of file
   113.1 --- a/app/main/member/show.lua	Thu Jul 10 01:02:43 2014 +0200
   113.2 +++ b/app/main/member/show.lua	Thu Jul 10 01:19:48 2014 +0200
   113.3 @@ -1,150 +1,185 @@
   113.4  local member = Member:by_id(param.get_id())
   113.5  
   113.6  if not member or not member.activated then
   113.7 -  error("access denied")
   113.8 +  execute.view { module = "index", view = "404" }
   113.9 +  request.set_status("404 Not Found")
  113.10 +  return
  113.11  end
  113.12  
  113.13 +local limit = 25
  113.14 +
  113.15 +local initiated_initiatives = Initiative:new_selector()
  113.16 +  :join("initiator", nil, { "initiator.initiative_id = initiative.id and initiator.member_id = ?", member.id })
  113.17 +  :join("issue", nil, "issue.id = initiative.issue_id")
  113.18 +  :add_where("issue.closed ISNULL")
  113.19 +  :add_order_by("initiative.id DESC")
  113.20 +  :limit(limit+1)
  113.21 +  :exec()
  113.22 +  
  113.23 +initiated_initiatives:load("issue")
  113.24 +initiated_initiatives:load_everything_for_member_id(member.id)
  113.25 +
  113.26 +local supported_initiatives = Initiative:new_selector()
  113.27 +  :join("supporter", nil, { "supporter.initiative_id = initiative.id and supporter.member_id = ?", member.id })
  113.28 +  :join("issue", nil, "issue.id = initiative.issue_id")
  113.29 +  :add_where("issue.closed ISNULL")
  113.30 +  :add_order_by("initiative.id DESC")
  113.31 +  :limit(limit+1)
  113.32 +  :exec()
  113.33 +
  113.34 +supported_initiatives:load("issue")
  113.35 +supported_initiatives:load_everything_for_member_id(member.id)
  113.36 +
  113.37 +local voted_initiatives = Initiative:new_selector()
  113.38 +  :add_where("initiative.rank = 1")
  113.39 +  :join("direct_voter", nil, { "direct_voter.issue_id = initiative.issue_id and direct_voter.member_id = ?", member.id })
  113.40 +  :join("vote", nil, { "vote.initiative_id = initiative.id and vote.member_id = ?", member.id })
  113.41 +  :join("issue", nil, "issue.id = initiative.issue_id")
  113.42 +  :add_order_by("issue.closed DESC, initiative.id DESC")
  113.43 +  :add_field("vote.grade", "vote_grade")
  113.44 +  :add_field("vote.first_preference", "vote_first_preference")
  113.45 +  :limit(limit+1)
  113.46 +  :exec()
  113.47 +
  113.48 +voted_initiatives:load("issue")
  113.49 +voted_initiatives:load_everything_for_member_id(member.id)
  113.50 +  
  113.51 +local incoming_delegations_selector = member:get_reference_selector("incoming_delegations")
  113.52 +  :left_join("issue", "_member_showtab_issue", "_member_showtab_issue.id = delegation.issue_id AND _member_showtab_issue.closed ISNULL")
  113.53 +  :add_where("_member_showtab_issue.closed ISNULL")
  113.54 +  :add_order_by("delegation.unit_id, delegation.area_id, delegation.issue_id")
  113.55 +  :limit(limit+1)
  113.56 +
  113.57 +local outgoing_delegations_selector = member:get_reference_selector("outgoing_delegations")
  113.58 +  :left_join("issue", "_member_showtab_issue", "_member_showtab_issue.id = delegation.issue_id AND _member_showtab_issue.closed ISNULL")
  113.59 +  :add_where("_member_showtab_issue.closed ISNULL")
  113.60 +  :add_order_by("delegation.unit_id, delegation.area_id, delegation.issue_id")
  113.61 +  :limit(limit+1)
  113.62 +
  113.63 +
  113.64  app.html_title.title = member.name
  113.65  app.html_title.subtitle = _("Member")
  113.66  
  113.67 -slot.select("head", function()
  113.68 -  ui.container{
  113.69 -    attr = { class = "title" },
  113.70 -    content = _("Member '#{member}'", { member =  member.name })
  113.71 +ui.titleMember(member)
  113.72 +
  113.73 +execute.view {
  113.74 +  module = "member", view = "_sidebar_whatcanido", params = {
  113.75 +    member = member
  113.76    }
  113.77 -
  113.78 -  ui.container{ attr = { class = "actions" }, content = function()
  113.79 +}
  113.80  
  113.81 -    if member.id == app.session.member_id then
  113.82 -      ui.link{
  113.83 -        content = function()
  113.84 -          slot.put(encode.html(_"Edit profile"))
  113.85 -        end,
  113.86 -        module  = "member",
  113.87 -        view    = "edit"
  113.88 +execute.view {
  113.89 +  module = "member", view = "_sidebar_contacts", params = {
  113.90 +    member = member
  113.91 +  }
  113.92 +}
  113.93 +
  113.94 +
  113.95 +ui.section( function() 
  113.96 +  ui.sectionHead( function()
  113.97 +    execute.view{
  113.98 +      module = "member_image",
  113.99 +      view = "_show",
 113.100 +      params = {
 113.101 +        member = member,
 113.102 +        image_type = "avatar",
 113.103 +        show_dummy = true,
 113.104 +        class = "left"
 113.105        }
 113.106 -      slot.put(" &middot; ")
 113.107 -      ui.link{
 113.108 -        content = function()
 113.109 -          slot.put(encode.html(_"Upload avatar/photo"))
 113.110 -        end,
 113.111 -        module  = "member",
 113.112 -        view    = "edit_images"
 113.113 -      }
 113.114 -      slot.put(" &middot; ")
 113.115 -    end
 113.116 -    ui.link{
 113.117 +    }
 113.118 +    ui.heading{ level = 1, content = member.name }
 113.119 +    slot.put("<br />")
 113.120 +    ui.container {
 113.121 +      attr = { class = "right" },
 113.122        content = function()
 113.123 -        slot.put(encode.html(_"Show member history"))
 113.124 -      end,
 113.125 -      module  = "member",
 113.126 -      view    = "history",
 113.127 -      id      = member.id
 113.128 +        ui.link{
 113.129 +          content = _"Account history",
 113.130 +          module = "member", view = "history", id = member.id
 113.131 +        }
 113.132 +      end
 113.133      }
 113.134 -    if not member.active then
 113.135 -      slot.put(" &middot; ")
 113.136 -      ui.tag{
 113.137 -        attr = { class = "interest deactivated_member_info" },
 113.138 -        content = _"This member is inactive"
 113.139 -      }
 113.140 +    if member.identification then
 113.141 +      ui.container{ content = member.identification }
 113.142      end
 113.143 -    if member.locked then
 113.144 -      slot.put(" &middot; ")
 113.145 -      ui.tag{
 113.146 -        attr = { class = "interest deactivated_member_info" },
 113.147 -        content = _"This member is locked"
 113.148 +  end )
 113.149 +  ui.sectionRow( function()
 113.150 +    execute.view{
 113.151 +      module = "member",
 113.152 +      view = "_profile",
 113.153 +      params = { member = member }
 113.154 +    }
 113.155 +  end )
 113.156 +end )
 113.157 +
 113.158 +
 113.159 +ui.section( function()
 113.160 +  ui.sectionHead( function()
 113.161 +    ui.heading { level = 2, content = _"Initiatives created by this member" }
 113.162 +  end )
 113.163 +  ui.sectionRow( function()
 113.164 +    for i, initiative in ipairs(initiated_initiatives) do
 113.165 +      execute.view {
 113.166 +        module = "initiative", view = "_list",
 113.167 +        params = { initiative = initiative },
 113.168 +        member = member
 113.169        }
 113.170      end
 113.171 -    if app.session.member_id and not (member.id == app.session.member.id) then
 113.172 -      slot.put(" &middot; ")
 113.173 -      --TODO performance
 113.174 -      local contact = Contact:by_pk(app.session.member.id, member.id)
 113.175 -      if contact then
 113.176 -        ui.link{
 113.177 -          text   = _"Remove from contacts",
 113.178 -          module = "contact",
 113.179 -          action = "remove_member",
 113.180 -          id     = contact.other_member_id,
 113.181 -          routing = {
 113.182 -            default = {
 113.183 -              mode = "redirect",
 113.184 -              module = request.get_module(),
 113.185 -              view = request.get_view(),
 113.186 -              id = param.get_id_cgi(),
 113.187 -              params = param.get_all_cgi()
 113.188 -            }
 113.189 -          }
 113.190 -        }
 113.191 -      elseif member.activated then
 113.192 -        ui.link{
 113.193 -          text    = _"Add to my contacts",
 113.194 -          module  = "contact",
 113.195 -          action  = "add_member",
 113.196 -          id      = member.id,
 113.197 -          routing = {
 113.198 -            default = {
 113.199 -              mode = "redirect",
 113.200 -              module = request.get_module(),
 113.201 -              view = request.get_view(),
 113.202 -              id = param.get_id_cgi(),
 113.203 -              params = param.get_all_cgi()
 113.204 -            }
 113.205 -          }
 113.206 -        }
 113.207 -      end
 113.208 +  end )
 113.209 +end )
 113.210 +
 113.211 +ui.section( function()
 113.212 +  ui.sectionHead( function()
 113.213 +    ui.heading { level = 2, content = _"What this member is currently supporting" }
 113.214 +  end )
 113.215 +  ui.sectionRow( function()
 113.216 +    for i, initiative in ipairs(supported_initiatives) do
 113.217 +      execute.view {
 113.218 +        module = "initiative", view = "_list",
 113.219 +        params = { initiative = initiative },
 113.220 +        member = member
 113.221 +      }
 113.222 +    end
 113.223 +  end )
 113.224 +end )
 113.225 +
 113.226 +ui.section( function()
 113.227 +  ui.sectionHead( function()
 113.228 +    ui.heading { level = 2, content = _"How this member voted" }
 113.229 +  end )
 113.230 +  ui.sectionRow( function()
 113.231 +    for i, initiative in ipairs(voted_initiatives) do
 113.232 +      execute.view {
 113.233 +        module = "initiative", view = "_list",
 113.234 +        params = { initiative = initiative }
 113.235 +      }
 113.236      end
 113.237 -    if app.session.member_id then
 113.238 -      local ignored_member = IgnoredMember:by_pk(app.session.member.id, member.id)
 113.239 -      slot.put(" &middot; ")
 113.240 -      if ignored_member then
 113.241 -        ui.tag{
 113.242 -          attr = { class = "interest" },
 113.243 -          content = _"You have ignored this member"
 113.244 -        }
 113.245 -        slot.put(" &middot; ")
 113.246 -        ui.link{
 113.247 -          text   = _"Stop ignoring member",
 113.248 -          module = "member",
 113.249 -          action = "update_ignore_member",
 113.250 -          id     = member.id,
 113.251 -          params = { delete = true },
 113.252 -          routing = {
 113.253 -            default = {
 113.254 -              mode = "redirect",
 113.255 -              module = request.get_module(),
 113.256 -              view = request.get_view(),
 113.257 -              id = param.get_id_cgi(),
 113.258 -              params = param.get_all_cgi()
 113.259 -            }
 113.260 -          }
 113.261 -        }
 113.262 -      elseif member.activated then
 113.263 -        ui.link{
 113.264 -          attr = { class = "interest" },
 113.265 -          text    = _"Ignore member",
 113.266 -          module  = "member",
 113.267 -          action  = "update_ignore_member",
 113.268 -          id      = member.id,
 113.269 -          routing = {
 113.270 -            default = {
 113.271 -              mode = "redirect",
 113.272 -              module = request.get_module(),
 113.273 -              view = request.get_view(),
 113.274 -              id = param.get_id_cgi(),
 113.275 -              params = param.get_all_cgi()
 113.276 -            }
 113.277 -          }
 113.278 -        }
 113.279 -      end
 113.280 -    end
 113.281 -  end }
 113.282 -end)
 113.283 +  end )
 113.284 +end )
 113.285 +
 113.286  
 113.287 -util.help("member.show", _"Member page")
 113.288 +ui.section( function()
 113.289 +  ui.sectionHead( function()
 113.290 +    ui.heading { level = 2, content = _"Outgoing delegations" }
 113.291 +  end )
 113.292 +  ui.sectionRow( function()
 113.293 +    execute.view {
 113.294 +      module = "delegation", view = "_list",
 113.295 +      params = { delegations_selector = outgoing_delegations_selector, outgoing = true },
 113.296 +    }
 113.297 +  end )
 113.298 +end )
 113.299 +
 113.300  
 113.301 -execute.view{
 113.302 -  module = "member",
 113.303 -  view = "_show",
 113.304 -  params = { member = member }
 113.305 -}
 113.306 -
 113.307 +ui.section( function()
 113.308 +   
 113.309 +  ui.sectionHead( function()
 113.310 +    ui.heading { level = 2, content = _"Incoming delegations" }
 113.311 +  end )
 113.312 +  ui.sectionRow( function()
 113.313 +    execute.view {
 113.314 +      module = "delegation", view = "_list",
 113.315 +      params = { delegations_selector = incoming_delegations_selector, incoming = true },
 113.316 +    }
 113.317 +  end )
 113.318 +  
 113.319 +end )
   114.1 --- a/app/main/membership/_action/update.lua	Thu Jul 10 01:02:43 2014 +0200
   114.2 +++ b/app/main/membership/_action/update.lua	Thu Jul 10 01:19:48 2014 +0200
   114.3 @@ -1,26 +1,26 @@
   114.4  local area_id = assert(param.get("area_id", atom.integer), "no area id given")
   114.5  local membership = Membership:by_pk(area_id, app.session.member.id)
   114.6  
   114.7 +local area = Area:by_id(area_id)
   114.8  if param.get("delete", atom.boolean) then
   114.9    if membership then
  114.10      membership:destroy()
  114.11 -    --slot.put_into("notice", _"Membership removed")
  114.12 +    slot.put_into("notice", _"Subscription removed")
  114.13    else
  114.14 -    --slot.put_into("notice", _"Membership not existent")
  114.15 +    slot.put_into("notice", _"Subscription already removed")
  114.16    end
  114.17    return
  114.18  end
  114.19  
  114.20 +if not app.session.member:has_voting_right_for_unit_id(area.unit_id) then
  114.21 +  slot.put_into("error", _"You are not eligible to participate")
  114.22 +  return false
  114.23 +end
  114.24 +
  114.25  if not membership then
  114.26 -  local area = Area:by_id(area_id)
  114.27 -  if not app.session.member:has_voting_right_for_unit_id(area.unit_id) then
  114.28 -    error("access denied")
  114.29 -  end
  114.30    membership = Membership:new()
  114.31    membership.area_id    = area_id
  114.32    membership.member_id  = app.session.member_id
  114.33 +  membership:save()
  114.34 +  slot.put_into("notice", _"Subject area subscribed")
  114.35  end
  114.36 -
  114.37 -membership:save()
  114.38 -
  114.39 ---slot.put_into("notice", _"Membership updated")
   115.1 --- a/app/main/opinion/_action/update.lua	Thu Jul 10 01:02:43 2014 +0200
   115.2 +++ b/app/main/opinion/_action/update.lua	Thu Jul 10 01:19:48 2014 +0200
   115.3 @@ -6,6 +6,10 @@
   115.4  
   115.5  local suggestion = Suggestion:by_id(suggestion_id)
   115.6  
   115.7 +local degree = param.get("degree", atom.number)
   115.8 +local fulfilled = param.get("fulfilled", atom.boolean)
   115.9 +
  115.10 +
  115.11  if not suggestion then
  115.12    slot.put_into("error", _"This suggestion has been meanwhile deleted")
  115.13    return false
  115.14 @@ -28,7 +32,7 @@
  115.15    return false
  115.16  end
  115.17  
  115.18 -if param.get("delete") then
  115.19 +if degree == 0 then
  115.20    if opinion then
  115.21      opinion:destroy()
  115.22    end
  115.23 @@ -36,9 +40,6 @@
  115.24    return
  115.25  end
  115.26  
  115.27 -local degree = param.get("degree", atom.number)
  115.28 -local fulfilled = param.get("fulfilled", atom.boolean)
  115.29 -
  115.30  if degree ~= 0 and not app.session.member:has_voting_right_for_unit_id(suggestion.initiative.issue.area.unit_id) then
  115.31    error("access denied")
  115.32  end
   116.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   116.2 +++ b/app/main/policy/_list.lua	Thu Jul 10 01:19:48 2014 +0200
   116.3 @@ -0,0 +1,90 @@
   116.4 +local for_area = param.get("for_area", "table")
   116.5 +
   116.6 +local selector = Policy:new_selector()
   116.7 +  :add_where("policy.active")
   116.8 +  :add_order_by("policy.index")
   116.9 +
  116.10 +if for_area then
  116.11 +  selector:join("allowed_policy", nil,
  116.12 +    { "allowed_policy.policy_id = policy.id AND allowed_policy.area_id = ?", for_area.id }
  116.13 +  )
  116.14 +end
  116.15 +
  116.16 +local policies = selector:exec()
  116.17 +
  116.18 +
  116.19 +for i, policy in ipairs(policies) do
  116.20 +  ui.container { 
  116.21 +    attr = { class = "sidebarRow", id = "policy" .. policy.id },
  116.22 +    content = function ()
  116.23 +
  116.24 +      ui.heading { level = 3, content = policy.name }
  116.25 +      
  116.26 +      ui.tag{
  116.27 +        content = policy.description
  116.28 +      }
  116.29 +
  116.30 +      slot.put ( "<br />" )
  116.31 +      
  116.32 +      ui.link {
  116.33 +        attr = {
  116.34 +          class = "policy-show-details",
  116.35 +          onclick = "$('#policy" .. policy.id .. " .policy-details').show(); $('#policy" .. policy.id .. " .policy-show-details').hide(); $('#policy" .. policy.id .. " .policy-hide-details').show(); return false;"
  116.36 +        },
  116.37 +        content = _"show details"
  116.38 +      }
  116.39 +      
  116.40 +      ui.link {
  116.41 +        attr = {
  116.42 +          class = "policy-hide-details",
  116.43 +          onclick = "$('#policy" .. policy.id .. " .policy-details').hide(); $('#policy" .. policy.id .. " .policy-show-details').show(); $('#policy" .. policy.id .. " .policy-hide-details').hide(); return false;",
  116.44 +          style = "display: none;"
  116.45 +        },
  116.46 +        content = _"hide details"
  116.47 +      }
  116.48 +      
  116.49 +      ui.container {
  116.50 +        attr = {
  116.51 +          class = "policy-details",
  116.52 +          style = "display: none;"
  116.53 +        },
  116.54 +        content = function ()
  116.55 +
  116.56 +          ui.heading { level = 4, content = _"Phase durations" }
  116.57 +
  116.58 +          if policy.polling then
  116.59 +            ui.field.text{ label = _"New" .. ":", value = _"without" }
  116.60 +          else
  116.61 +            ui.field.text{ label = _"New" .. ":", value = "≤ " .. policy.admission_time }
  116.62 +          end
  116.63 +          ui.field.text{ label = _"Discussion" .. ":", value = policy.discussion_time or _"variable" }
  116.64 +          ui.field.text{ label = _"Frozen" .. ":", value = policy.verification_time or _"variable" }
  116.65 +          ui.field.text{ label = _"Voting" .. ":", value = policy.voting_time or _"variable" }
  116.66 +
  116.67 +          ui.heading { level = 4, content = _"Quorums" }
  116.68 +          
  116.69 +          if policy.polling then
  116.70 +            ui.field.text{ label = _"Issue quorum" .. ":", value = _"without" }
  116.71 +          else
  116.72 +            ui.field.text{
  116.73 +              label = _"Issue quorum" .. ":", 
  116.74 +              value = "≥ " .. tostring(policy.issue_quorum_num) .. "/" .. tostring(policy.issue_quorum_den)
  116.75 +            }
  116.76 +          end
  116.77 +          ui.field.text{
  116.78 +            label = _"Initiative quorum" .. ":", 
  116.79 +            value = "≥ " .. tostring(policy.initiative_quorum_num) .. "/" .. tostring(policy.initiative_quorum_den)
  116.80 +          }
  116.81 +          ui.field.text{
  116.82 +            label = _"Direct majority" .. ":", 
  116.83 +            value = (policy.direct_majority_strict and ">" or "≥" ) .. " " .. tostring(policy.direct_majority_num) .. "/" .. tostring(policy.direct_majority_den)
  116.84 +          }
  116.85 +          ui.field.text{
  116.86 +            label = _"Indirect majority" .. ":", 
  116.87 +            value = (policy.indirect_majority_strict and ">" or "≥" ) .. " " .. tostring(policy.indirect_majority_num) .. "/" .. tostring(policy.indirect_majority_den)
  116.88 +          }
  116.89 +        end
  116.90 +      }
  116.91 +    end
  116.92 +  }
  116.93 +end
  116.94 \ No newline at end of file
   117.1 --- a/app/main/policy/list.lua	Thu Jul 10 01:02:43 2014 +0200
   117.2 +++ b/app/main/policy/list.lua	Thu Jul 10 01:19:48 2014 +0200
   117.3 @@ -1,73 +1,3 @@
   117.4  ui.title(_"Policies")
   117.5  
   117.6 -util.help("policy.list", _"Policies")
   117.7 -local policies = Policy:new_selector()
   117.8 -  :add_where("active")
   117.9 -  :add_order_by("index")
  117.10 -  :exec()
  117.11 -
  117.12 -ui.list{
  117.13 -  records = policies,
  117.14 -  columns = {
  117.15 -    {
  117.16 -      label_attr = { width = "500" },
  117.17 -      label = _"Policy",
  117.18 -      content = function(policy)
  117.19 -        ui.link{
  117.20 -          module = "policy", view = "show", id = policy.id,
  117.21 -          attr = { style = "font-weight: bold" },
  117.22 -          content = function()
  117.23 -            slot.put(encode.html(policy.name))
  117.24 -            if not policy.active then
  117.25 -              slot.put(" (", _"disabled", ")")
  117.26 -            end
  117.27 -          end
  117.28 -        }
  117.29 -        ui.tag{
  117.30 -          tag = "div",
  117.31 -          content = policy.description
  117.32 -        }
  117.33 -      end
  117.34 -    },
  117.35 -    {
  117.36 -      label_attr = { width = "200" },
  117.37 -      label = _"Phases",
  117.38 -      content = function(policy)
  117.39 -        if policy.polling then
  117.40 -          ui.field.text{ label = _"New" .. ":", value = _"without" }
  117.41 -        else
  117.42 -          ui.field.text{ label = _"New" .. ":", value = "≤ " .. policy.admission_time }
  117.43 -        end
  117.44 -        ui.field.text{ label = _"Discussion" .. ":", value = policy.discussion_time or _"variable" }
  117.45 -        ui.field.text{ label = _"Frozen" .. ":", value = policy.verification_time or _"variable" }
  117.46 -        ui.field.text{ label = _"Voting" .. ":", value = policy.voting_time or _"variable" }
  117.47 -      end
  117.48 -    },
  117.49 -    {
  117.50 -      label_attr = { width = "200" },
  117.51 -      label = _"Quorum",
  117.52 -      content = function(policy)
  117.53 -        if policy.polling then
  117.54 -          ui.field.text{ label = _"Issue quorum" .. ":", value = _"without" }
  117.55 -        else
  117.56 -          ui.field.text{
  117.57 -            label = _"Issue quorum" .. ":", 
  117.58 -            value = "≥ " .. tostring(policy.issue_quorum_num) .. "/" .. tostring(policy.issue_quorum_den)
  117.59 -          }
  117.60 -        end
  117.61 -        ui.field.text{
  117.62 -          label = _"Initiative quorum" .. ":", 
  117.63 -          value = "≥ " .. tostring(policy.initiative_quorum_num) .. "/" .. tostring(policy.initiative_quorum_den)
  117.64 -        }
  117.65 -        ui.field.text{
  117.66 -          label = _"Direct majority" .. ":", 
  117.67 -          value = (policy.direct_majority_strict and ">" or "≥" ) .. " " .. tostring(policy.direct_majority_num) .. "/" .. tostring(policy.direct_majority_den)
  117.68 -        }
  117.69 -        ui.field.text{
  117.70 -          label = _"Indirect majority" .. ":", 
  117.71 -          value = (policy.indirect_majority_strict and ">" or "≥" ) .. " " .. tostring(policy.indirect_majority_num) .. "/" .. tostring(policy.indirect_majority_den)
  117.72 -        }
  117.73 -      end
  117.74 -    },
  117.75 -  }
  117.76 -}
  117.77 \ No newline at end of file
  117.78 +execute.view { module = "policy", view = "_list" }
  117.79 \ No newline at end of file
   118.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   118.2 +++ b/app/main/slideshow/_index.lua	Thu Jul 10 01:19:48 2014 +0200
   118.3 @@ -0,0 +1,64 @@
   118.4 +local unit = param.get( "unit", "table" )
   118.5 +local area = param.get( "area", "table" )
   118.6 +
   118.7 +local args = {
   118.8 +  unit_id = unit and unit.id or nil,
   118.9 +  area_id = area and area.id or nil
  118.10 +}
  118.11 +
  118.12 +local lastWinner = Initiative:getLastWinner( args )
  118.13 +local lastLooser = Initiative:getLastLoser( args )
  118.14 +local nextEndingVoting = Initiative:getNextEndingVoting( args )
  118.15 +local nextEndingVerification = Initiative:getNextEndingVerification( args )
  118.16 +local nextEndingDiscussion = Initiative:getNextEndingDiscussion( args )
  118.17 +local bestInAdmission = Initiative:getBestInAdmission( args )
  118.18 +
  118.19 +local slides = { }
  118.20 +
  118.21 +if lastWinner then
  118.22 +  slides[#slides+1] = {
  118.23 +    title = _"Latest approved issue",
  118.24 +    initiative = lastWinner
  118.25 +  }
  118.26 +end
  118.27 +
  118.28 +if lastLooser then
  118.29 +  slides[#slides+1] = {
  118.30 +    title = _"Latest disapproved issue",
  118.31 +    initiative = lastLooser
  118.32 +  }
  118.33 +end
  118.34 +
  118.35 +if nextEndingVoting then
  118.36 +  slides[#slides+1] = {
  118.37 +    title = _("Voting #{time_info}", { time_info = nextEndingVoting.issue.state_time_text }),
  118.38 +    initiative = nextEndingVoting
  118.39 +  }
  118.40 +end
  118.41 +
  118.42 +if nextEndingVerification then
  118.43 +  slides[#slides+1] = {
  118.44 +    title = _("Verification #{time_info}", { time_info = nextEndingVerification.issue.state_time_text }),
  118.45 +    initiative = nextEndingVerification
  118.46 +  }
  118.47 +end
  118.48 +
  118.49 +if nextEndingDiscussion then
  118.50 +  slides[#slides+1] = {
  118.51 +    title = _("Discussion #{time_info}", { time_info = nextEndingDiscussion.issue.state_time_text }),
  118.52 +    initiative = nextEndingDiscussion
  118.53 +  }
  118.54 +end
  118.55 +
  118.56 +if bestInAdmission then
  118.57 +  slides[#slides+1] = {
  118.58 +    title = _"Best not admitted initiative",
  118.59 +    initiative = bestInAdmission
  118.60 +  }
  118.61 +end
  118.62 +
  118.63 +execute.view { 
  118.64 +  module = "slideshow", view = "_slideshow", params = {
  118.65 +    slides = slides
  118.66 +  }
  118.67 +}
   119.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   119.2 +++ b/app/main/slideshow/_slideshow.lua	Thu Jul 10 01:19:48 2014 +0200
   119.3 @@ -0,0 +1,79 @@
   119.4 +local slides = param.get( "slides", "table" )
   119.5 +
   119.6 +local show_slides = {}
   119.7 +
   119.8 +for i, slide in ipairs( slides ) do
   119.9 +  
  119.10 +  if slide.initiative then
  119.11 +    show_slides[ #show_slides + 1 ] = slide
  119.12 +  end
  119.13 +  
  119.14 +end
  119.15 +  
  119.16 +slot.select( "slideshow", function ()
  119.17 +  
  119.18 +  ui.container { attr = { class = "slideshow" }, content = function ()
  119.19 +    
  119.20 +    for i, slide in ipairs( show_slides ) do
  119.21 +      
  119.22 +      if slide.initiative.issue.closed then
  119.23 +        view = "finished"
  119.24 +      elseif slide.initiative.issue.fully_frozen then
  119.25 +        view = "voting"
  119.26 +      elseif slide.initiative.issue.half_frozen then
  119.27 +        view = "verification"
  119.28 +      elseif slide.initiative.issue.admitted then
  119.29 +        view = "discussion"
  119.30 +      else
  119.31 +        view = "admission"
  119.32 +      end
  119.33 +      
  119.34 +      ui.container { attr = { class = "slide slide-" .. i }, content = function ()
  119.35 +
  119.36 +        if slide.initiative.issue.closed then
  119.37 +          util.initiative_pie(slide.initiative, 150)
  119.38 +        end
  119.39 +
  119.40 +        ui.container {
  119.41 +          attr = { class = "slideshowTitle" },
  119.42 +          content = slide.title
  119.43 +        }
  119.44 +
  119.45 +        execute.view {
  119.46 +          module = "initiative", view = "_list_element", params = {
  119.47 +            initiative = slide.initiative
  119.48 +          }
  119.49 +        }
  119.50 +
  119.51 +      end }
  119.52 +      
  119.53 +    end
  119.54 +
  119.55 +    
  119.56 +  end }
  119.57 +    
  119.58 +end )
  119.59 +
  119.60 +ui.script{ script = [[
  119.61 +
  119.62 +var slideshowCurrent = 0;
  119.63 +var slideshowCount = ]] .. #show_slides .. [[ ;
  119.64 +function slideshowShowSlide(i) {
  119.65 +  $(".slideshow .slide").slideUp();
  119.66 +  $(".slideshow .slide-" + i).slideDown();
  119.67 +  slideshowCurrent = i;
  119.68 +}
  119.69 +
  119.70 +function slideshowShowNext() {
  119.71 +  var next = slideshowCurrent + 1;
  119.72 +  if (next > slideshowCount) {
  119.73 +    next = 1;
  119.74 +  }
  119.75 +  slideshowShowSlide(next);
  119.76 +  window.setTimeout(slideshowShowNext, 7500);
  119.77 +}
  119.78 +
  119.79 +slideshowShowNext();
  119.80 +
  119.81 +  
  119.82 +  ]]}
  119.83 \ No newline at end of file
   120.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   120.2 +++ b/app/main/slideshow/index.lua	Thu Jul 10 01:19:48 2014 +0200
   120.3 @@ -0,0 +1,26 @@
   120.4 +local unit = param.get( "unit", "table" )
   120.5 +local area = param.get( "area", "table" )
   120.6 +
   120.7 +local args = {
   120.8 +  unit_id = unit and unit.id or nil,
   120.9 +  area_id = area and area.id or nil
  120.10 +}
  120.11 +
  120.12 +local issues = Issue:new_selector():exec()
  120.13 +
  120.14 +
  120.15 +local slides = {}
  120.16 +
  120.17 +for i, issue in ipairs( issues ) do
  120.18 +  slides[ #slides+1 ] = {
  120.19 +    title = issue.state_name,
  120.20 +    initiative = issue.initiatives[1]
  120.21 +  }
  120.22 +end
  120.23 +
  120.24 +
  120.25 +execute.view { 
  120.26 +  module = "slideshow", view = "_slideshow", params = {
  120.27 +    slides = slides
  120.28 +  }
  120.29 +}
  120.30 \ No newline at end of file
   121.1 --- a/app/main/suggestion/_action/add.lua	Thu Jul 10 01:02:43 2014 +0200
   121.2 +++ b/app/main/suggestion/_action/add.lua	Thu Jul 10 01:19:48 2014 +0200
   121.3 @@ -18,11 +18,11 @@
   121.4    return false
   121.5  end
   121.6  
   121.7 -local formatting_engine = param.get("formatting_engine")
   121.8 +local formatting_engine = param.get("formatting_engine") or config.enforce_formatting_engine
   121.9  
  121.10  local formatting_engine_valid = false
  121.11 -for fe, dummy in pairs(config.formatting_engine_executeables) do
  121.12 -  if formatting_engine == fe then
  121.13 +for i, fe in ipairs(config.formatting_engines) do
  121.14 +  if formatting_engine == fe.id then
  121.15      formatting_engine_valid = true
  121.16    end
  121.17  end
   122.1 --- a/app/main/suggestion/new.lua	Thu Jul 10 01:02:43 2014 +0200
   122.2 +++ b/app/main/suggestion/new.lua	Thu Jul 10 01:19:48 2014 +0200
   122.3 @@ -1,20 +1,5 @@
   122.4  local initiative_id = param.get("initiative_id")
   122.5  
   122.6 -slot.put_into("title", _"Add new suggestion")
   122.7 -
   122.8 -ui.actions(function()
   122.9 -  ui.link{
  122.10 -    content = function()
  122.11 -        ui.image{ static = "icons/16/cancel.png" }
  122.12 -        slot.put(_"Cancel")
  122.13 -    end,
  122.14 -    module = "initiative",
  122.15 -    view = "show",
  122.16 -    id = initiative_id,
  122.17 -    params = { tab = "suggestions" }
  122.18 -  }
  122.19 -end)
  122.20 -
  122.21  ui.form{
  122.22    module = "suggestion",
  122.23    action = "add",
  122.24 @@ -28,76 +13,94 @@
  122.25        params = { tab = "suggestions" }
  122.26      }
  122.27    },
  122.28 -  attr = { class = "vertical" },
  122.29 +  attr = { class = "section vertical" },
  122.30    content = function()
  122.31 -    local supported = Supporter:by_pk(initiative_id, app.session.member.id) and true or false
  122.32 -    if not supported then
  122.33 -      ui.field.text{
  122.34 -        attr = { class = "warning" },
  122.35 -        value = _"You are currently not supporting this initiative directly. By adding suggestions to this initiative you will automatically become a potential supporter."
  122.36 -      }
  122.37 -    end
  122.38 -    ui.field.select{
  122.39 -      label = _"Degree",
  122.40 -      name = "degree",
  122.41 -      foreign_records = {
  122.42 -        { id =  1, name = _"should"},
  122.43 -        { id =  2, name = _"must"},
  122.44 -      },
  122.45 -      foreign_id = "id",
  122.46 -      foreign_name = "name"
  122.47 -    }
  122.48 -    ui.field.text{ label = _"Title (80 chars max)", name = "name" }
  122.49 -    ui.field.select{
  122.50 -      label = _"Wiki engine",
  122.51 -      name = "formatting_engine",
  122.52 -      foreign_records = {
  122.53 -        { id = "rocketwiki", name = "RocketWiki" },
  122.54 -        { id = "compat", name = _"Traditional wiki syntax" }
  122.55 -      },
  122.56 -      attr = {id = "formatting_engine"},
  122.57 -      foreign_id = "id",
  122.58 -      foreign_name = "name",
  122.59 -      value = param.get("formatting_engine")
  122.60 -    }
  122.61 -    ui.tag{
  122.62 -      tag = "div",
  122.63 -      content = function()
  122.64 -        ui.tag{
  122.65 -          tag = "label",
  122.66 -          attr = { class = "ui_field_label" },
  122.67 -          content = function() slot.put("&nbsp;") end,
  122.68 +  
  122.69 +    ui.sectionHead( function()
  122.70 +      ui.heading { level = 1, content = _"Add a new suggestion for improvement" }
  122.71 +    end)
  122.72 +    
  122.73 +    ui.sectionRow( function()
  122.74 +    
  122.75 +      local supported = Supporter:by_pk(initiative_id, app.session.member.id) and true or false
  122.76 +      if not supported then
  122.77 +        ui.field.text{
  122.78 +          attr = { class = "warning" },
  122.79 +          value = _"You are currently not supporting this initiative directly. By adding suggestions to this initiative you will automatically become a potential supporter."
  122.80 +        }
  122.81 +      end
  122.82 +      ui.field.text{ label = _"A short title (80 chars max)", name = "name" }
  122.83 +      
  122.84 +      if not config.enforce_formatting_engine then
  122.85 +        ui.field.select{
  122.86 +          label = _"Wiki engine",
  122.87 +          name = "formatting_engine",
  122.88 +          foreign_records = config.formatting_engines,
  122.89 +          attr = {id = "formatting_engine"},
  122.90 +          foreign_id = "id",
  122.91 +          foreign_name = "name",
  122.92 +          value = param.get("formatting_engine")
  122.93          }
  122.94          ui.tag{
  122.95 +          tag = "div",
  122.96            content = function()
  122.97 -            ui.link{
  122.98 -              text = _"Syntax help",
  122.99 -              module = "help",
 122.100 -              view = "show",
 122.101 -              id = "wikisyntax",
 122.102 -              attr = {onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"}
 122.103 +            ui.tag{
 122.104 +              tag = "label",
 122.105 +              attr = { class = "ui_field_label" },
 122.106 +              content = function() slot.put("&nbsp;") end,
 122.107              }
 122.108 -            slot.put(" ")
 122.109 -            ui.link{
 122.110 -              text = _"(new window)",
 122.111 -              module = "help",
 122.112 -              view = "show",
 122.113 -              id = "wikisyntax",
 122.114 -              attr = {target = "_blank", onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"}
 122.115 +            ui.tag{
 122.116 +              content = function()
 122.117 +                ui.link{
 122.118 +                  text = _"Syntax help",
 122.119 +                  module = "help",
 122.120 +                  view = "show",
 122.121 +                  id = "wikisyntax",
 122.122 +                  attr = {onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"}
 122.123 +                }
 122.124 +                slot.put(" ")
 122.125 +                ui.link{
 122.126 +                  text = _"(new window)",
 122.127 +                  module = "help",
 122.128 +                  view = "show",
 122.129 +                  id = "wikisyntax",
 122.130 +                  attr = {target = "_blank", onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"}
 122.131 +                }
 122.132 +              end
 122.133              }
 122.134            end
 122.135          }
 122.136        end
 122.137 -    }
 122.138 -    ui.field.text{
 122.139 -      label = _"Description",
 122.140 -      name = "content",
 122.141 -      multiline = true, 
 122.142 -      attr = { style = "height: 50ex;" },
 122.143 -      value = param.get("content")
 122.144 -    }
 122.145 +
 122.146 +      ui.field.text{
 122.147 +        label = _"Describe how the proposal and/or the reasons of the initiative could be improved",
 122.148 +        name = "content",
 122.149 +        multiline = true, 
 122.150 +        attr = { style = "height: 50ex;" },
 122.151 +        value = param.get("content")
 122.152 +      }
 122.153  
 122.154 -    
 122.155 -    ui.submit{ text = _"Commit suggestion" }
 122.156 +      ui.field.select{
 122.157 +        label = _"How important is your suggestions for you?",
 122.158 +        name = "degree",
 122.159 +        foreign_records = {
 122.160 +          { id =  1, name = _"should be implemented"},
 122.161 +          { id =  2, name = _"must be implemented"},
 122.162 +        },
 122.163 +        foreign_id = "id",
 122.164 +        foreign_name = "name"
 122.165 +      }
 122.166 +      
 122.167 +      ui.submit{ text = _"publish suggestion" }
 122.168 +      slot.put(" ")
 122.169 +      ui.link{
 122.170 +        content = _"cancel",
 122.171 +        module = "initiative",
 122.172 +        view = "show",
 122.173 +        id = initiative_id,
 122.174 +        params = { tab = "suggestions" }
 122.175 +      }
 122.176 +
 122.177 +    end )
 122.178    end
 122.179  }
   123.1 --- a/app/main/supporter/show_incoming.lua	Thu Jul 10 01:02:43 2014 +0200
   123.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   123.3 @@ -1,21 +0,0 @@
   123.4 -local initiative = Initiative:by_id(param.get("initiative_id", atom.integer))
   123.5 -local issue = initiative.issue
   123.6 -local member = Member:by_id(param.get("member_id", atom.integer))
   123.7 -
   123.8 -local members_selector = Member:new_selector()
   123.9 -  :join("delegating_interest_snapshot", nil, "delegating_interest_snapshot.member_id = member.id")
  123.10 -  :join("issue", nil, "issue.id = delegating_interest_snapshot.issue_id")
  123.11 -  :add_where{ "delegating_interest_snapshot.issue_id = ?", issue.id }
  123.12 -  :add_where{ "delegating_interest_snapshot.event = ?", issue.latest_snapshot_event }
  123.13 -  :add_where{ "delegating_interest_snapshot.delegate_member_ids[1] = ?", member.id }
  123.14 -  :add_field{ "delegating_interest_snapshot.weight" }
  123.15 -
  123.16 -execute.view{
  123.17 -  module = "member",
  123.18 -  view = "_list",
  123.19 -  params = { 
  123.20 -    members_selector = members_selector,
  123.21 -    issue = issue,
  123.22 -    trustee = member
  123.23 -  }
  123.24 -}
  123.25 \ No newline at end of file
   124.1 --- a/app/main/timeline/_action/delete_filter.lua	Thu Jul 10 01:02:43 2014 +0200
   124.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   124.3 @@ -1,3 +0,0 @@
   124.4 -local timeline_filter = app.session.member:get_setting_map_by_key_and_subkey("timeline_filters", param.get("name"))
   124.5 -
   124.6 -timeline_filter:destroy()
   124.7 \ No newline at end of file
   125.1 --- a/app/main/timeline/_action/save.lua	Thu Jul 10 01:02:43 2014 +0200
   125.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   125.3 @@ -1,45 +0,0 @@
   125.4 -local id = param.get("id", atom.number)
   125.5 -
   125.6 -local setting_key = "liquidfeedback_frontend_timeline_current_options"
   125.7 -local setting = Setting:by_pk(app.session.member.id, setting_key)
   125.8 -local options_string = setting.value
   125.9 -
  125.10 -local timeline_filter
  125.11 -
  125.12 -local subkey = param.get("name")
  125.13 -
  125.14 -if not subkey or subkey == "" then
  125.15 -  slot.put_into("error", _"This name is really too short!")
  125.16 -  request.redirect{
  125.17 -    module = "timeline",
  125.18 -    view = "save_filter",
  125.19 -  }
  125.20 -  return
  125.21 -end
  125.22 -
  125.23 -app.session.member:set_setting_map("timeline_filters", subkey, options_string)
  125.24 -
  125.25 -local timeline_params = {}
  125.26 -if options_string then
  125.27 -  for event_ident, filter_idents in setting.value:gmatch("(%S+):(%S+)") do
  125.28 -    timeline_params["option_" .. event_ident] = true
  125.29 -    if filter_idents ~= "*" then
  125.30 -      for filter_ident in filter_idents:gmatch("([^\|]+)") do
  125.31 -        timeline_params["option_" .. event_ident .. "_" .. filter_ident] = true
  125.32 -      end
  125.33 -    end
  125.34 -  end
  125.35 -end
  125.36 -
  125.37 -local setting_key = "liquidfeedback_frontend_timeline_current_date"
  125.38 -local setting = Setting:by_pk(app.session.member.id, setting_key)
  125.39 -
  125.40 -if setting then
  125.41 -  timeline_params.date = setting.value
  125.42 -end
  125.43 -
  125.44 -request.redirect{
  125.45 -  module = "timeline",
  125.46 -  view = "index",
  125.47 -  params = timeline_params
  125.48 -}
  125.49 \ No newline at end of file
   126.1 --- a/app/main/timeline/_action/update.lua	Thu Jul 10 01:02:43 2014 +0200
   126.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   126.3 @@ -1,112 +0,0 @@
   126.4 -execute.view{
   126.5 -  module = "timeline",
   126.6 -  view = "_constants"
   126.7 -}
   126.8 -
   126.9 -local options_string = param.get("options_string")
  126.10 -
  126.11 -if not options_string then
  126.12 -  local active_options = ""
  126.13 -  for event_ident, event_name in pairs(event_names) do
  126.14 -    if param.get("option_" .. event_ident, atom.boolean) then
  126.15 -      active_options = active_options .. event_ident .. ":"
  126.16 -      local filter_idents = {}
  126.17 -      for filter_ident, filter_name in pairs(filter_names) do
  126.18 -        if param.get("option_" .. event_ident .. "_" .. filter_ident, atom.boolean) then
  126.19 -          filter_idents[#filter_idents+1] = filter_ident
  126.20 -        end
  126.21 -      end
  126.22 -      if #filter_idents > 0 then
  126.23 -        active_options = active_options .. table.concat(filter_idents, "|") .. " "
  126.24 -      else
  126.25 -        active_options = active_options .. "* "
  126.26 -      end
  126.27 -    end
  126.28 -  end
  126.29 -  if #active_options > 0 then
  126.30 -    options_string = active_options
  126.31 -  end
  126.32 -end
  126.33 -
  126.34 -if not options_string then
  126.35 -  options_string = "issue_created:* issue_finished_after_voting:* issue_accepted:* issue_voting_started:* suggestion_created:* issue_canceled:* initiative_created:* issue_finished_without_voting:* draft_created:* initiative_revoked:* issue_half_frozen:* "
  126.36 -end
  126.37 -
  126.38 -if param.get_list("option_ignore_area", atom.string) then
  126.39 -  options_string = options_string.." ignore_area:"..table.concat(param.get_list("option_ignore_area", atom.string), "|")
  126.40 -end
  126.41 -
  126.42 -local setting_key = "liquidfeedback_frontend_timeline_current_options"
  126.43 -local setting = Setting:by_pk(app.session.member.id, setting_key)
  126.44 -
  126.45 -if not setting or setting.value ~= options_string then
  126.46 -  if not setting then
  126.47 -    setting = Setting:new()
  126.48 -    setting.member_id = app.session.member_id
  126.49 -    setting.key = setting_key
  126.50 -  end
  126.51 -  if options_string then
  126.52 -    setting.value = options_string
  126.53 -    setting:save()
  126.54 -  end
  126.55 -end
  126.56 -
  126.57 -local date = param.get("date")
  126.58 -
  126.59 -if param.get("search_from") == "last_24h" then
  126.60 -  date = "last_24h"
  126.61 -end
  126.62 -
  126.63 -if date and #date > 0 then
  126.64 -  local setting_key = "liquidfeedback_frontend_timeline_current_date"
  126.65 -  local setting = Setting:by_pk(app.session.member.id, setting_key)
  126.66 -  if not setting or setting.value ~= date then
  126.67 -    if not setting then
  126.68 -      setting = Setting:new()
  126.69 -      setting.member_id = app.session.member.id
  126.70 -      setting.key = setting_key
  126.71 -    end
  126.72 -    setting.value = date
  126.73 -    setting:save()
  126.74 -  end
  126.75 -end
  126.76 -
  126.77 -local setting_key = "liquidfeedback_frontend_timeline_current_options"
  126.78 -local setting = Setting:by_pk(app.session.member.id, setting_key)
  126.79 -
  126.80 -local timeline_params = {}
  126.81 -if setting and setting.value then
  126.82 -  for event_ident, filter_idents in setting.value:gmatch("(%S+):(%S+)") do
  126.83 -    timeline_params["option_" .. event_ident] = true
  126.84 -    if filter_idents ~= "*" then
  126.85 -      for filter_ident in filter_idents:gmatch("([^\|]+)") do
  126.86 -        timeline_params["option_" .. event_ident .. "_" .. filter_ident] = true
  126.87 -      end
  126.88 -    end
  126.89 -  end
  126.90 -end
  126.91 -
  126.92 -local setting_key = "liquidfeedback_frontend_timeline_current_date"
  126.93 -local setting = Setting:by_pk(app.session.member.id, setting_key)
  126.94 -
  126.95 -if setting then
  126.96 -  timeline_params.date = setting.value
  126.97 -end
  126.98 -
  126.99 -timeline_params.show_options = param.get("show_options", atom.boolean)
 126.100 -
 126.101 -if param.get("save", atom.boolean) then
 126.102 -  request.redirect{
 126.103 -    module = "timeline",
 126.104 -    view = "save_filter",
 126.105 -    params = {
 126.106 -      current_name = param.get("current_name")
 126.107 -    }
 126.108 -  }
 126.109 -else
 126.110 -  request.redirect{
 126.111 -    module = "timeline",
 126.112 -    view = "index",
 126.113 -    params = timeline_params
 126.114 -  }
 126.115 -end
 126.116 \ No newline at end of file
   127.1 --- a/app/main/timeline/_constants.lua	Thu Jul 10 01:02:43 2014 +0200
   127.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   127.3 @@ -1,31 +0,0 @@
   127.4 -event_names = {
   127.5 -  issue_created                 = _"New issue",
   127.6 -  issue_canceled                = _"Issue canceled",
   127.7 -  issue_accepted                = _"Issue accepted",
   127.8 -  issue_half_frozen             = _"Issue frozen",
   127.9 -  issue_finished_without_voting = _"Issue finished without voting",
  127.10 -  issue_voting_started          = _"Voting started",
  127.11 -  issue_finished_after_voting   = _"Issue finished",
  127.12 -  initiative_created            = _"New initiative",
  127.13 -  initiative_revoked            = _"Initiative revoked",
  127.14 -  draft_created                 = _"New draft",
  127.15 -  suggestion_created            = _"New suggestion"
  127.16 -}
  127.17 -
  127.18 -filter_names = {
  127.19 -  contact = _"Saved as contact",
  127.20 -  interested = _"Interested",
  127.21 -  supporter = _"Supported",
  127.22 -  potential_supporter = _"Potential supported",
  127.23 -  initiator = _"Initiated",
  127.24 -  membership = _"Member of area"
  127.25 -}
  127.26 -
  127.27 -option_names = {}
  127.28 -for key, val in pairs(event_names) do
  127.29 -  option_names[key] = val
  127.30 -end
  127.31 -for key, val in pairs(filter_names) do
  127.32 -  option_names[key] = val
  127.33 -end
  127.34 -
   128.1 --- a/app/main/timeline/_filter/29_filter.lua	Thu Jul 10 01:02:43 2014 +0200
   128.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   128.3 @@ -1,42 +0,0 @@
   128.4 -if request.get_view() == "index" and not param.get("date") then
   128.5 -  local setting
   128.6 -  local setting_key = "liquidfeedback_frontend_timeline_current_options"
   128.7 -  if app.session.member_id then
   128.8 -    setting = Setting:by_pk(app.session.member.id, setting_key)
   128.9 -  end
  128.10 -
  128.11 -  local timeline_params = {}
  128.12 -  if setting and setting.value then
  128.13 -    for event_ident, filter_idents in setting.value:gmatch("(%S+):(%S+)") do
  128.14 -      timeline_params["option_" .. event_ident] = true
  128.15 -      if filter_idents ~= "*" then
  128.16 -        for filter_ident in filter_idents:gmatch("([^\|]+)") do
  128.17 -          timeline_params["option_" .. event_ident .. "_" .. filter_ident] = true
  128.18 -        end
  128.19 -      end
  128.20 -    end
  128.21 -  end
  128.22 -
  128.23 -  local setting
  128.24 -  local setting_key = "liquidfeedback_frontend_timeline_current_date"
  128.25 -  if app.session.member_id then
  128.26 -    setting = Setting:by_pk(app.session.member.id, setting_key)
  128.27 -  end
  128.28 -
  128.29 -  if setting then
  128.30 -    timeline_params.date = setting.value
  128.31 -  else
  128.32 -    timeline_params.date = "last_24h"
  128.33 -  end
  128.34 -
  128.35 -  timeline_params.show_options = param.get("show_options", atom.boolean)
  128.36 -
  128.37 -  request.redirect{
  128.38 -    module = "timeline",
  128.39 -    view = "index",
  128.40 -    params = timeline_params
  128.41 -  }
  128.42 -else
  128.43 -  execute.inner()
  128.44 -end
  128.45 -
   129.1 --- a/app/main/timeline/_list.lua	Thu Jul 10 01:02:43 2014 +0200
   129.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   129.3 @@ -1,145 +0,0 @@
   129.4 -local timeline_selector = param.get("timeline_selector", "table")
   129.5 -local event_names = param.get("event_names", "table")
   129.6 -local initiatives_per_page = param.get("initiatives_per_page", atom.number) or 3
   129.7 -
   129.8 -
   129.9 --- test if selector is valid
  129.10 -local test_selector = timeline_selector:get_db_conn():new_selector()
  129.11 -test_selector:add_field('count(1)')
  129.12 -test_selector:add_from(timeline_selector)
  129.13 -test_selector:single_object_mode()
  129.14 -
  129.15 -err, x = test_selector:try_exec()
  129.16 -
  129.17 -if err then
  129.18 -  slot.put_into("error", _"Invalid query")
  129.19 -else
  129.20 -  ui.paginate{
  129.21 -    per_page = param.get("per_page", atom.number) or 25,
  129.22 -    selector = timeline_selector,
  129.23 -    container_attr = { class = "ui_paginate timeline_results" },
  129.24 -    content = function()
  129.25 -      local timelines = timeline_selector:exec()
  129.26 -      timelines:load("issue")
  129.27 -      timelines:load("initiative")
  129.28 -      timelines:load("member")
  129.29 -      ui.list{
  129.30 -        attr = { class = "nohover" },
  129.31 -        records = timelines,
  129.32 -        columns = {
  129.33 -          {
  129.34 -            field_attr = { style = "width: 10em;" },
  129.35 -            content = function(timeline)
  129.36 -              ui.field.text{
  129.37 -                attr = { style = "font-size: 75%; font-weight: bold; background-color: #ccc; display: block; margin-bottom: 1ex;"},
  129.38 -                value = format.time(timeline.occurrence)
  129.39 -              }
  129.40 -
  129.41 -              ui.field.text{
  129.42 -                attr = { style = "font-size: 75%; font-weight: bold;"},
  129.43 -                value = event_names[timeline.event] or timeline.event
  129.44 -              }
  129.45 -              if timeline.event == "draft_created" and timeline.count > 1 then
  129.46 -                ui.field.text{
  129.47 -                  attr = { style = "font-size: 75%;"},
  129.48 -                  value = _("(#{more_count} duplicates removed)", { more_count = timeline.count - 1 })
  129.49 -                }
  129.50 -              end
  129.51 -            end
  129.52 -          },
  129.53 -          {
  129.54 -            content = function(timeline)
  129.55 -              local issue
  129.56 -              local initiative
  129.57 -              if timeline.issue then
  129.58 -                issue = timeline.issue
  129.59 -              elseif timeline.initiative then
  129.60 -                initiative = timeline.initiative
  129.61 -                issue = initiative.issue
  129.62 -              elseif timeline.draft then
  129.63 -                initiative = timeline.draft.initiative
  129.64 -                issue = initiative.issue
  129.65 -              elseif timeline.suggestion then
  129.66 -                initiative = timeline.suggestion.initiative
  129.67 -                issue = initiative.issue
  129.68 -              end
  129.69 -              if issue then
  129.70 -                if timeline.is_interested then
  129.71 -                  local label = _"You are interested in this issue",
  129.72 -                  ui.image{
  129.73 -                    attr = { alt = label, title = label, style = "float: left; margin-right: 0.5em;" },
  129.74 -                    static = "icons/16/eye.png"
  129.75 -                  }
  129.76 -                end
  129.77 -                slot.put(" ")
  129.78 -                ui.tag{
  129.79 -                  tag = "span",
  129.80 -                  attr = { style = "font-size: 75%; font-weight: bold; background-color: #ccc; display: block; margin-bottom: 1ex;"},
  129.81 -                  content = issue.area.name_with_unit_name .. ", " .. _("Issue ##{id}", { id = issue.id })
  129.82 -                }
  129.83 -              else
  129.84 -                ui.tag{
  129.85 -                  tag = "span",
  129.86 -                  attr = { style = "font-size: 75%; background-color: #ccc; display: block; margin-bottom: 1ex;"},
  129.87 -                  content = function() slot.put("&nbsp;") end
  129.88 -                }
  129.89 -              end
  129.90 -
  129.91 -              if timeline.member then
  129.92 -                execute.view{
  129.93 -                  module = "member_image",
  129.94 -                  view = "_show",
  129.95 -                  params = {
  129.96 -                    member = timeline.member,
  129.97 -                    image_type = "avatar",
  129.98 -                    show_dummy = true
  129.99 -                  }
 129.100 -                }
 129.101 -                ui.link{
 129.102 -                  content = timeline.member.name,
 129.103 -                  module = "member",
 129.104 -                  view = "show",
 129.105 -                  id = timeline.member.id
 129.106 -                }
 129.107 -              end
 129.108 -              if timeline.issue then
 129.109 -                local initiatives_selector = timeline.issue
 129.110 -                  :get_reference_selector("initiatives")
 129.111 -                execute.view{
 129.112 -                  module = "initiative",
 129.113 -                  view = "_list",
 129.114 -                  params = {
 129.115 -                    issue = timeline.issue,
 129.116 -                    initiatives_selector = initiatives_selector,
 129.117 -                    per_page = initiatives_per_page,
 129.118 -                    no_sort = true,
 129.119 -                    limit = initiatives_per_page
 129.120 -                  }
 129.121 -                }
 129.122 -              elseif initiative then
 129.123 -                execute.view{
 129.124 -                  module = "initiative",
 129.125 -                  view = "_list",
 129.126 -                  params = {
 129.127 -                    issue = initiative.issue,
 129.128 -                    initiatives_selector = Initiative:new_selector():add_where{ "initiative.id = ?", initiative.id },
 129.129 -                    per_page = initiatives_per_page,
 129.130 -                    no_sort = true
 129.131 -                  }
 129.132 -                }
 129.133 -              end
 129.134 -              if timeline.suggestion then
 129.135 -                ui.link{
 129.136 -                  module = "suggestion",
 129.137 -                  view = "show",
 129.138 -                  id = timeline.suggestion.id,
 129.139 -                  content = timeline.suggestion.name
 129.140 -                }
 129.141 -              end
 129.142 -            end
 129.143 -          },
 129.144 -        }
 129.145 -      }
 129.146 -    end
 129.147 -  }
 129.148 -end
   130.1 --- a/app/main/timeline/index.lua	Thu Jul 10 01:02:43 2014 +0200
   130.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   130.3 @@ -1,449 +0,0 @@
   130.4 -execute.view{
   130.5 -  module = "timeline",
   130.6 -  view = "_constants"
   130.7 -}
   130.8 -
   130.9 -local active_name = ""
  130.10 -local areas_ignored = {}
  130.11 -local options_box_count = param.get("options_box_count", atom.number) or 1
  130.12 -if options_box_count > 10 then
  130.13 -  options_box_count = 10
  130.14 -end
  130.15 -
  130.16 -local function format_dow(dow)
  130.17 -  local dows = {
  130.18 -    _"Monday",
  130.19 -    _"Tuesday",
  130.20 -    _"Wednesday",
  130.21 -    _"Thursday",
  130.22 -    _"Friday",
  130.23 -    _"Saturday",
  130.24 -    _"Sunday"
  130.25 -  }
  130.26 -  return dows[dow+1]
  130.27 -end
  130.28 -slot.put_into("title", _"Timeline")
  130.29 -
  130.30 -slot.select("actions", function()
  130.31 -  local setting_key = "liquidfeedback_frontend_timeline_current_options"
  130.32 -  local setting = Setting:by_pk(app.session.member.id, setting_key)
  130.33 -  local current_options = ""
  130.34 -  if setting then
  130.35 -    current_options = setting.value
  130.36 -  end
  130.37 -  local setting_maps = app.session.member:get_setting_maps_by_key("timeline_filters")
  130.38 -  for i, setting_map in ipairs(setting_maps) do
  130.39 -    local active
  130.40 -    local options_string = setting_map.value
  130.41 -    local name = setting_map.subkey
  130.42 -    if options_string == current_options then
  130.43 -      active = true
  130.44 -      active_name = name
  130.45 -    end
  130.46 -    ui.link{
  130.47 -      image  = { static = "icons/16/time.png" },
  130.48 -      attr   = { class = active and "action_active" or nil },
  130.49 -      text   = name,
  130.50 -      form_attr = { class = "inline" },
  130.51 -      module = 'timeline',
  130.52 -      action = 'update',
  130.53 -      params = {
  130.54 -        options_string = options_string
  130.55 -      },
  130.56 -    }
  130.57 -  end
  130.58 -  if #setting_maps > 0 then
  130.59 -    ui.link{
  130.60 -      content = function()
  130.61 -        ui.image{ static = "icons/16/wrench.png" }
  130.62 -        slot.put(_"Manage filter")
  130.63 -      end,
  130.64 -      module = "timeline",
  130.65 -      view = "list_filter",
  130.66 -    }
  130.67 -  end
  130.68 -  ui.link{
  130.69 -    content = function()
  130.70 -      ui.image{ static = "icons/16/bullet_disk.png" }
  130.71 -      slot.put(_"Save current filter")
  130.72 -    end,
  130.73 -    module = "timeline",
  130.74 -    view = "save_filter",
  130.75 -    params = {
  130.76 -      current_name = active_name
  130.77 -    },
  130.78 -    attr = { 
  130.79 -      onclick = "el=document.getElementById('timeline_save');el.checked=true;el.form.submit();return(false);"
  130.80 -    }
  130.81 -  }
  130.82 -end)
  130.83 -
  130.84 -util.help("timeline.index", _"Timeline")
  130.85 -
  130.86 -ui.form{
  130.87 -  module = "timeline",
  130.88 -  action = "update",
  130.89 -  content = function()
  130.90 -    ui.container{
  130.91 -
  130.92 -      content = function()
  130.93 -
  130.94 -        ui.tag{
  130.95 -          tag = "input",
  130.96 -          attr = {
  130.97 -            type = "radio",
  130.98 -            id = "timeline_search_last_24h",
  130.99 -            name = "search_from",
 130.100 -            value = "last_24h",
 130.101 -            checked = param.get("date") == "last_24h" and "checked" or nil
 130.102 -          },
 130.103 -        }
 130.104 -
 130.105 -        ui.tag{
 130.106 -          tag = "label",
 130.107 -          attr = {
 130.108 -            ["for"] = "timeline_search_last_24h" 
 130.109 -          },
 130.110 -          content = " " .. _"last 24 hours" .. " "
 130.111 -        }
 130.112 -
 130.113 -        ui.tag{
 130.114 -          tag = "input",
 130.115 -          attr = {
 130.116 -            type = "radio",
 130.117 -            id = "timeline_search_from_date",
 130.118 -            name = "search_from",
 130.119 -            value = "date",
 130.120 -            checked = not (param.get("date") == "last_24h") and "checked" or nil
 130.121 -          },
 130.122 -        }
 130.123 -
 130.124 -        slot.put(" ")
 130.125 -        local current_date = param.get("date")
 130.126 -        if not current_date or #current_date == 0 or current_date == "last_24h" then
 130.127 -          current_date = tostring(db:query("select now()::date as date")[1].date)
 130.128 -        end
 130.129 -        ui.tag{
 130.130 -          tag = "input",
 130.131 -          attr = {
 130.132 -            type = "text",
 130.133 -            id = "timeline_search_date",
 130.134 -            style = "width: 10em;",
 130.135 -            onchange = "this.form.submit();",
 130.136 -            onclick = "document.getElementById('timeline_search_from_date').checked = true;",
 130.137 -            name = "date",
 130.138 -            value = current_date
 130.139 -          },
 130.140 -          content = function() end
 130.141 -        }
 130.142 -    
 130.143 -        ui.script{ static = "gregor.js/gregor.js" }
 130.144 -        util.gregor("timeline_search_date", true)
 130.145 -    
 130.146 -    
 130.147 -        ui.link{
 130.148 -          attr = { style = "margin-left: 1em; font-weight: bold;", onclick = "document.getElementById('timeline_search_date').form.submit();return(false);" },
 130.149 -          content = function()
 130.150 -            ui.image{
 130.151 -              attr = { style = "margin-right: 0.25em;" },
 130.152 -              static = "icons/16/magnifier.png"
 130.153 -            }
 130.154 -            slot.put(_"Search")
 130.155 -          end,
 130.156 -          external = "#",
 130.157 -        }
 130.158 -        local show_options = param.get("show_options", atom.boolean)
 130.159 -        ui.link{
 130.160 -          attr = { style = "margin-left: 1em;", onclick = "el=document.getElementById('timeline_show_options');el.checked=" .. tostring(not show_options) .. ";el.form.submit();return(false);" },
 130.161 -          content = function()
 130.162 -            ui.image{
 130.163 -              attr = { style = "margin-right: 0.25em;" },
 130.164 -              static = "icons/16/text_list_bullets.png"
 130.165 -            }
 130.166 -            slot.put(not show_options and _"Show filter details" or _"Hide filter details")
 130.167 -          end,
 130.168 -          external = "#",
 130.169 -        }
 130.170 -
 130.171 -        ui.field.boolean{
 130.172 -          attr = { id = "timeline_show_options", style = "display: none;", onchange="this.form.submit();" },
 130.173 -          name = "show_options",
 130.174 -          value = param.get("show_options", atom.boolean)
 130.175 -        }
 130.176 -        ui.hidden_field{ name = "current_name", value = active_name }
 130.177 -        ui.field.boolean{
 130.178 -          attr = { id = "timeline_save", style = "display: none;", onchange="this.form.submit();" },
 130.179 -          name = "save",
 130.180 -          value = false
 130.181 -        }
 130.182 -
 130.183 -      end
 130.184 -    }
 130.185 -
 130.186 -    ui.container{
 130.187 -      attr = { 
 130.188 -        id = "timeline_options_boxes",
 130.189 -        class = "vertical",
 130.190 -        style = not param.get("show_options", atom.boolean) and "display: none;" or nil
 130.191 -      },
 130.192 -      content = function()
 130.193 -
 130.194 -        local function option_field(event_ident, filter_ident)
 130.195 -          local param_name
 130.196 -          if not filter_ident then
 130.197 -            param_name = "option_" .. event_ident
 130.198 -          else
 130.199 -            param_name = "option_" .. event_ident .. "_" .. filter_ident
 130.200 -          end
 130.201 -          local value = param.get(param_name, atom.boolean)
 130.202 -          ui.field.boolean{
 130.203 -            attr = { id = param_name },
 130.204 -            name = param_name,
 130.205 -            value = value,
 130.206 -          }
 130.207 -        end
 130.208 -
 130.209 -        local function filter_option_fields(event_ident, filter_idents)
 130.210 -
 130.211 -          for i, filter_ident in ipairs(filter_idents) do
 130.212 -              slot.put("<td>")
 130.213 -              option_field(event_ident, filter_ident)
 130.214 -              slot.put("</td><td><div class='ui_field_label label_right'>")
 130.215 -              ui.tag{
 130.216 -                attr = { ["for"] = "option_" .. event_ident .. "_" .. filter_ident },
 130.217 -                tag = "label",
 130.218 -                content = filter_names[filter_ident]
 130.219 -              }
 130.220 -              slot.put("</div></td>")
 130.221 -          end
 130.222 -
 130.223 -        end
 130.224 -
 130.225 -        local event_groups = {
 130.226 -          {
 130.227 -            title = _"Issue events",
 130.228 -            event_idents = {
 130.229 -              "issue_created",
 130.230 -              "issue_canceled",
 130.231 -              "issue_accepted",
 130.232 -              "issue_half_frozen",
 130.233 -              "issue_finished_without_voting",
 130.234 -              "issue_voting_started",
 130.235 -              "issue_finished_after_voting",
 130.236 -            },
 130.237 -            filter_idents = {
 130.238 -              "membership",
 130.239 -              "interested"
 130.240 -            }
 130.241 -          },
 130.242 -          {
 130.243 -            title = _"Initiative events",
 130.244 -            event_idents = {
 130.245 -              "initiative_created",
 130.246 -              "initiative_revoked",
 130.247 -              "draft_created",
 130.248 -              "suggestion_created",
 130.249 -            },
 130.250 -            filter_idents = {
 130.251 -              "membership",
 130.252 -              "interested",
 130.253 -              "supporter",
 130.254 -              "potential_supporter",
 130.255 -              "initiator"
 130.256 -            }
 130.257 -          }
 130.258 -        }
 130.259 -
 130.260 -        slot.put("<table>")
 130.261 -
 130.262 -        for i_event_group, event_group in ipairs(event_groups) do
 130.263 -          slot.put("<tr>")
 130.264 -          slot.put("<th colspan='2'>")
 130.265 -          slot.put(event_group.title)
 130.266 -          slot.put("</th><th colspan='10'>")
 130.267 -          slot.put(_"Show only events which match... (or associtated)")
 130.268 -          slot.put("</th>")
 130.269 -          slot.put("</tr>")
 130.270 -          local event_idents = event_group.event_idents
 130.271 -          for i, event_ident in ipairs(event_idents) do
 130.272 -            slot.put("<tr><td>")
 130.273 -            option_field(event_ident)
 130.274 -            slot.put("</td><td><div class='ui_field_label label_right'>")
 130.275 -            ui.tag{
 130.276 -              attr = { ["for"] = "option_" .. event_ident },
 130.277 -              tag = "label",
 130.278 -              content = event_names[event_ident]
 130.279 -            }
 130.280 -            slot.put("</div></td>")
 130.281 -            filter_option_fields(event_ident, event_group.filter_idents)
 130.282 -            slot.put("</tr>")
 130.283 -          end
 130.284 -        end
 130.285 -
 130.286 -        slot.put("</table>")
 130.287 -
 130.288 -        local areas = Area:new_selector():add_where("active='t'"):exec()
 130.289 -        for i, area in ipairs(areas) do
 130.290 -          if param.get("option_ignore_area_"..tostring(area.id)) then
 130.291 -            areas_ignored[#areas_ignored+1] = area.id
 130.292 -          end
 130.293 -        end
 130.294 -
 130.295 -        ui.multiselect{
 130.296 -          style = "checkbox",
 130.297 -          selected_ids = areas_ignored, 
 130.298 -          container_attr = { class = "ignore_area_list" },
 130.299 -          container2_attr = { class = "ignore_area_item" },
 130.300 -          label = _"Ignore Areas",
 130.301 -          name = "option_ignore_area[]",
 130.302 -          foreign_records = areas,
 130.303 -          foreign_id      = "id",
 130.304 -          foreign_name    = "name"
 130.305 -        }
 130.306 -
 130.307 -      end
 130.308 -    }
 130.309 -  end
 130.310 -}
 130.311 -
 130.312 -local date = param.get("date")
 130.313 -
 130.314 -if not date or #date == 0 then
 130.315 -  date = "today"
 130.316 -end
 130.317 -
 130.318 -local timeline_selector
 130.319 -
 130.320 -for event, event_name in pairs(event_names) do
 130.321 -
 130.322 -  if param.get("option_" .. event, atom.boolean) then
 130.323 -
 130.324 -    local tmp = Timeline:new_selector()
 130.325 -      if event == "draft_created" then
 130.326 -        tmp
 130.327 -          :reset_fields()
 130.328 -          :add_field("max(timeline.occurrence)", "occurrence")
 130.329 -          :add_field("timeline.event", nil,  { "grouped" })
 130.330 -          :add_field("timeline.issue_id", nil, { "grouped" })
 130.331 -          :add_field("draft.initiative_id", nil, { "grouped" })
 130.332 -          :add_field("max(timeline.draft_id)", "draft_id")
 130.333 -          :add_field("timeline.suggestion_id", nil, { "grouped" })
 130.334 -          :add_field("COUNT(*)", "count")
 130.335 -      else
 130.336 -        tmp
 130.337 -          :add_field("1", "count")
 130.338 -      end
 130.339 -
 130.340 -      if date == "last_24h" then
 130.341 -        tmp:add_where{ "occurrence > now() - '24 hours'::interval" }
 130.342 -      else
 130.343 -        local start,stop = string.gmatch(date, "(%d+-%d+-%d+):(%d+-%d+-%d+)")()
 130.344 -        if start and stop then
 130.345 -          tmp:add_where{ "occurrence::date >= ?::date AND occurrence::date <= ?::date", start, stop }
 130.346 -        else
 130.347 -          local age = string.gmatch(date, "age:(.+)")()
 130.348 -          if age then
 130.349 -            tmp:add_where{ "occurrence >= now() - ?::interval", age }
 130.350 -          else 
 130.351 -            local since = string.gmatch(date, "since:%s*(%d+-%d+-%d+)%s*")()
 130.352 -            if since then
 130.353 -              tmp:add_where{ "occurrence::date >= ?::date", since }
 130.354 -            else
 130.355 -              tmp:add_where{ "occurrence::date = ?::date", date }
 130.356 -            end
 130.357 -          end
 130.358 -        end
 130.359 -      end
 130.360 -      tmp
 130.361 -        :left_join("draft", nil, "draft.id = timeline.draft_id")
 130.362 -        :left_join("suggestion", nil, "suggestion.id = timeline.suggestion_id")
 130.363 -        :left_join("initiative", nil, "initiative.id = timeline.initiative_id or initiative.id = draft.initiative_id or initiative.id = suggestion.initiative_id")
 130.364 -        :left_join("issue", nil, "issue.id = timeline.issue_id or issue.id = initiative.issue_id")
 130.365 -        :left_join("area", nil, "area.id = issue.area_id")
 130.366 -
 130.367 -        :left_join("interest", "_interest", { "_interest.issue_id = issue.id AND _interest.member_id = ?", app.session.member.id} )
 130.368 -        :left_join("initiator", "_initiator", { "_initiator.initiative_id = initiative.id AND _initiator.member_id = ?", app.session.member.id} )
 130.369 -        :left_join("membership", "_membership", { "_membership.area_id = area.id AND _membership.member_id = ?", app.session.member.id} )
 130.370 -        :left_join("supporter", "_supporter", { "_supporter.initiative_id = initiative.id AND _supporter.member_id = ?", app.session.member.id} )
 130.371 -
 130.372 -      local group
 130.373 -      if event == "draft_created" then
 130.374 -        group = { "grouped" }
 130.375 -        tmp:add_where{"EXISTS(SELECT 1 from draft as cdraft WHERE draft.initiative_id = cdraft.initiative_id AND cdraft.id != draft.id ORDER BY cdraft.id DESC)"}
 130.376 -      end
 130.377 -
 130.378 -      tmp
 130.379 -        :add_field("(_interest.member_id NOTNULL)", "is_interested", group)
 130.380 -        :add_field("(_initiator.member_id NOTNULL)", "is_initiator", group)
 130.381 -        :add_field({"(_supporter.member_id NOTNULL) AND NOT EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1)", app.session.member.id }, "is_supporter", group)
 130.382 -        :add_field({"EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1)", app.session.member.id }, "is_potential_supporter", group)
 130.383 -  --    :left_join("member", nil, "member.id = timeline.member_id", group)
 130.384 -
 130.385 -      if #areas_ignored > 0 then
 130.386 -        tmp:add_where{"area.id NOT IN ($)", areas_ignored}
 130.387 -      end
 130.388 -
 130.389 -    tmp:add_where{ "event = ?", event }
 130.390 -
 130.391 -    local filters = {}
 130.392 -    if param.get("option_" .. event .. "_membership", atom.boolean) then
 130.393 -      filters[#filters+1] = "(timeline.initiative_id ISNULL AND timeline.issue_id ISNULL AND timeline.draft_id ISNULL AND timeline.suggestion_id ISNULL) OR _membership.member_id NOTNULL"
 130.394 -    end
 130.395 -
 130.396 -    if param.get("option_" .. event .. "_supporter", atom.boolean) then
 130.397 -      filters[#filters+1] = "(timeline.initiative_id ISNULL AND timeline.issue_id ISNULL AND timeline.draft_id ISNULL AND timeline.suggestion_id ISNULL) OR ((_supporter.member_id NOTNULL) AND NOT EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1))"
 130.398 -    end
 130.399 -
 130.400 -    if param.get("option_" .. event .. "_potential_supporter", atom.boolean) then
 130.401 -      filters[#filters+1] = "(timeline.initiative_id ISNULL AND timeline.issue_id ISNULL AND timeline.draft_id ISNULL AND timeline.suggestion_id ISNULL) OR ((_supporter.member_id NOTNULL) AND EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1))"
 130.402 -    end
 130.403 -
 130.404 -    if param.get("option_" .. event .. "_interested", atom.boolean) then
 130.405 -      filters[#filters+1] = "(timeline.initiative_id ISNULL AND timeline.issue_id ISNULL AND timeline.draft_id ISNULL AND timeline.suggestion_id ISNULL) OR _interest.member_id NOTNULL"
 130.406 -    end
 130.407 -
 130.408 -    if param.get("option_" .. event .. "_initiator", atom.boolean) then
 130.409 -      filters[#filters+1] = "(timeline.initiative_id ISNULL AND timeline.issue_id ISNULL AND timeline.draft_id ISNULL AND timeline.suggestion_id ISNULL) OR _initiator.member_id NOTNULL"
 130.410 -    end
 130.411 -
 130.412 -    if #filters > 0 then
 130.413 -      local filter_string = "(" .. table.concat(filters, ") OR (") .. ")"
 130.414 -      tmp:add_where{ filter_string, app.session.member.id, app.session.member.id }
 130.415 -    end
 130.416 -  
 130.417 -    if not timeline_selector then
 130.418 -      timeline_selector = tmp
 130.419 -    else
 130.420 -      timeline_selector:union_all(tmp)
 130.421 -    end
 130.422 -  end
 130.423 -end
 130.424 -
 130.425 -if timeline_selector then
 130.426 -  
 130.427 -  local initiatives_per_page = param.get("initiatives_per_page", atom.number)
 130.428 -  
 130.429 -  local outer_timeline_selector = db:new_selector()
 130.430 -  outer_timeline_selector._class = Timeline
 130.431 -  outer_timeline_selector
 130.432 -    :add_field{ "timeline.*" }
 130.433 -    :from({"($)", { timeline_selector }}, "timeline" )
 130.434 -    :add_order_by("occurrence DESC")
 130.435 -
 130.436 -  slot.put("<br />")
 130.437 -  execute.view{
 130.438 -    module = "timeline",
 130.439 -    view = "_list",
 130.440 -    params = {
 130.441 -      timeline_selector = outer_timeline_selector,
 130.442 -      per_page = param.get("per_page", atom.number),
 130.443 -      event_names = event_names,
 130.444 -      initiatives_per_page = initiatives_per_page
 130.445 -    }
 130.446 -  }
 130.447 -
 130.448 -else
 130.449 -
 130.450 -  slot.put(_"No events selected to list")
 130.451 -
 130.452 -end
 130.453 \ No newline at end of file
   131.1 --- a/app/main/timeline/list_filter.lua	Thu Jul 10 01:02:43 2014 +0200
   131.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   131.3 @@ -1,34 +0,0 @@
   131.4 -slot.put_into("title", _"Manage timeline filters")
   131.5 -
   131.6 -slot.select("actions", function()
   131.7 -  ui.link{
   131.8 -    image  = { static = "icons/16/cancel.png" },
   131.9 -    text   = _"Back to timeline",
  131.10 -    module = "timeline",
  131.11 -    action = "update"
  131.12 -  }
  131.13 -end)
  131.14 -
  131.15 -local timeline_filters = app.session.member:get_setting_maps_by_key("timeline_filters")
  131.16 -
  131.17 -ui.list{
  131.18 -  records = timeline_filters,
  131.19 -  columns = {
  131.20 -    {
  131.21 -      name = "subkey"
  131.22 -    },
  131.23 -    {
  131.24 -      content = function(timeline_filter)
  131.25 -        ui.link{
  131.26 -          attr   = { class = "action" },
  131.27 -          text   = _"Delete filter",
  131.28 -          module = "timeline",
  131.29 -          action = "delete_filter",
  131.30 -          params = { 
  131.31 -            name = timeline_filter.subkey
  131.32 -          }
  131.33 -        }
  131.34 -      end
  131.35 -    }
  131.36 -  }
  131.37 -}
  131.38 \ No newline at end of file
   132.1 --- a/app/main/timeline/save_filter.lua	Thu Jul 10 01:02:43 2014 +0200
   132.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   132.3 @@ -1,28 +0,0 @@
   132.4 -slot.put_into("title", _"Save timeline filters")
   132.5 -
   132.6 -slot.select("actions", function()
   132.7 -  ui.link{
   132.8 -    content = function()
   132.9 -        ui.image{ static = "icons/16/cancel.png" }
  132.10 -        slot.put(_"Cancel")
  132.11 -    end,
  132.12 -    module = "timeline",
  132.13 -    view = "index"
  132.14 -  }
  132.15 -end)
  132.16 -
  132.17 -ui.form{
  132.18 -  attr = { class = "vertical" },
  132.19 -  module = "timeline",
  132.20 -  action = "save",
  132.21 -  content = function()
  132.22 -    ui.field.text{
  132.23 -      label = _"Name",
  132.24 -      name = "name",
  132.25 -      value = param.get("current_name")
  132.26 -    }
  132.27 -    ui.submit{
  132.28 -      text = _"Save"
  132.29 -    }
  132.30 -  end
  132.31 -}
   133.1 --- a/app/main/unit/_head.lua	Thu Jul 10 01:02:43 2014 +0200
   133.2 +++ b/app/main/unit/_head.lua	Thu Jul 10 01:19:48 2014 +0200
   133.3 @@ -1,49 +1,32 @@
   133.4  local unit = param.get("unit", "table")
   133.5 -local member = param.get("member", "table")
   133.6 -
   133.7 -local show_content = param.get("show_content", atom.boolean)
   133.8  
   133.9 -if app.session.member_id then
  133.10 -  unit:load_delegation_info_once_for_member_id(app.session.member_id)
  133.11 -end
  133.12 -
  133.13 -ui.container{ attr = { class = "unit_head" }, content = function()
  133.14 +ui.title ( function ()
  133.15  
  133.16 -  execute.view{ module = "delegation", view = "_info", params = { unit = unit, member = member } }
  133.17 +  ui.tag{ attr = { class = "unit" }, content = function()
  133.18 +    -- unit link
  133.19 +    ui.link {
  133.20 +      attr = { class = "unit" },
  133.21 +      content = function()
  133.22 +        ui.tag{ attr = { class = "name" }, content = unit.name }
  133.23 +      end,
  133.24 +      module = "unit", view = "show",
  133.25 +      id = unit.id
  133.26 +    }
  133.27  
  133.28 -  ui.container{ attr = { class = "title" }, content = function()
  133.29 -    if not config.single_unit_id then
  133.30 -      ui.link{ 
  133.31 -        module = "unit", view = "show", id = unit.id,
  133.32 -        attr = { class = "unit_name" }, content = unit.name
  133.33 +    execute.view {
  133.34 +      module = "delegation", view = "_info", params = { 
  133.35 +        unit = unit, member = member
  133.36        }
  133.37 -    else
  133.38 -      ui.link{ 
  133.39 -        module = "unit", view = "show", id = unit.id,
  133.40 -        attr = { class = "unit_name" }, content = _"LiquidFeedback" .. " &middot; " .. config.instance_name
  133.41 +    }
  133.42 +
  133.43 +    if config.single_unit_id and not app.session.member_id and config.motd_public then
  133.44 +      ui.container{
  133.45 +        attr = { class = "wiki motd" },
  133.46 +        content = function()
  133.47 +          slot.put(config.motd_public)
  133.48 +        end
  133.49        }
  133.50      end
  133.51    end }
  133.52 -
  133.53 -  if show_content then
  133.54 -    ui.container{ attr = { class = "content" }, content = function()
  133.55 -
  133.56 -      if member and member:has_voting_right_for_unit_id(unit.id) then
  133.57 -        if app.session.member_id == member.id then
  133.58 -          ui.tag{ content = _"You have voting privileges for this unit" }
  133.59 -          slot.put(" &middot; ")
  133.60 -          if unit.delegation_info.first_trustee_id == nil then
  133.61 -            ui.link{ text = _"Delegate unit", module = "delegation", view = "show", params = { unit_id = unit.id } }
  133.62 -          else
  133.63 -            ui.link{ text = _"Change unit delegation", module = "delegation", view = "show", params = { unit_id = unit.id } }
  133.64 -          end
  133.65 -        else
  133.66 -          ui.tag{ content = _"Member has voting privileges for this unit" }
  133.67 -        end
  133.68 -      end
  133.69 -    end }
  133.70 -  else
  133.71 -    slot.put("<br />")
  133.72 -  end
  133.73 -    
  133.74 -end }
  133.75 +  
  133.76 +end )
  133.77 \ No newline at end of file
   134.1 --- a/app/main/unit/_list.lua	Thu Jul 10 01:02:43 2014 +0200
   134.2 +++ b/app/main/unit/_list.lua	Thu Jul 10 01:19:48 2014 +0200
   134.3 @@ -1,3 +1,4 @@
   134.4 +local for_admin = param.get("for_admin", atom.boolean)
   134.5  local units = Unit:get_flattened_tree{ active = true }
   134.6  
   134.7  ui.container{ attr = { class = "box" }, content = function()
   134.8 @@ -11,7 +12,11 @@
   134.9            for i = 1, unit.depth - 1 do
  134.10              slot.put("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;")
  134.11            end
  134.12 -          ui.link{ text = unit.name, module = "unit", view = "show", id = unit.id }
  134.13 +          if for_admin then
  134.14 +            ui.link{ text = unit.name, module = "admin", view = "unit_edit", id = unit.id }
  134.15 +          else
  134.16 +            ui.link{ text = unit.name, module = "unit", view = "show", id = unit.id }
  134.17 +          end
  134.18          end 
  134.19        }
  134.20      }
   135.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   135.2 +++ b/app/main/unit/_sidebar.lua	Thu Jul 10 01:19:48 2014 +0200
   135.3 @@ -0,0 +1,80 @@
   135.4 +local member = param.get ( "member", "table" ) or app.session.member
   135.5 +
   135.6 +local unit = param.get ( "unit", "table" )
   135.7 +
   135.8 +local areas_selector = Area:new_selector()
   135.9 +  :reset_fields()
  135.10 +  :add_field("area.id", nil, { "grouped" })
  135.11 +  :add_field("area.unit_id", nil, { "grouped" })
  135.12 +  :add_field("area.name", nil, { "grouped" })
  135.13 +  :add_where{ "area.unit_id = ?", unit.id }
  135.14 +  :add_where{ "area.active" }
  135.15 +  :add_order_by("area.name")
  135.16 +  
  135.17 +if member then
  135.18 +  areas_selector:left_join ( 
  135.19 +    "membership", nil, 
  135.20 +    { "membership.area_id = area.id AND membership.member_id = ?", member.id } 
  135.21 +  )
  135.22 +  areas_selector:add_field("membership.member_id NOTNULL", "subscribed", { "grouped" })
  135.23 +end
  135.24 +
  135.25 +
  135.26 +local areas = areas_selector:exec()
  135.27 +if member then
  135.28 +  unit:load_delegation_info_once_for_member_id(member.id)
  135.29 +  areas:load_delegation_info_once_for_member_id(member.id)
  135.30 +end
  135.31 +
  135.32 +  
  135.33 +ui.sidebar ( "tab-whatcanido", function ()
  135.34 +
  135.35 +  ui.sidebarHead( function ()
  135.36 +    ui.heading {
  135.37 +      level = 2, content = _"Subject areas"
  135.38 +    }
  135.39 +  end )
  135.40 +  
  135.41 +  if #areas > 0 then
  135.42 +    
  135.43 +    ui.container { class = "areas", content = function ()
  135.44 +      
  135.45 +      for i, area in ipairs ( areas ) do
  135.46 +        
  135.47 +        ui.container { attr = { class = "sidebarRow" }, content = function ()
  135.48 +        
  135.49 +          if member then
  135.50 +            local delegation = Delegation:by_pk(member.id, nil, area.id, nil)
  135.51 +      
  135.52 +            if delegation then
  135.53 +              ui.link { 
  135.54 +                module = "delegation", view = "show", params = {
  135.55 +                  area_id = area.id
  135.56 +                },
  135.57 +                attr = { class = "delegation_info" }, 
  135.58 +                content = function ()
  135.59 +                  ui.delegation(delegation.trustee_id, delegation.trustee_id and delegation.trustee.name)
  135.60 +                end
  135.61 +              }
  135.62 +            end
  135.63 +          end
  135.64 +        
  135.65 +          if area.subscribed then
  135.66 +            ui.image { attr = { class = "icon24 star" }, static = "icons/48/star.png" }
  135.67 +          end
  135.68 +          
  135.69 +          ui.link {
  135.70 +            attr = { class = "area" },
  135.71 +            module = "area", view = "show", id = area.id,
  135.72 +            content = area.name
  135.73 +          }
  135.74 +          
  135.75 +        end } -- ui.tag "li"
  135.76 +        
  135.77 +      end -- for i, area
  135.78 +      
  135.79 +    end } -- ui.tag "ul"
  135.80 +    
  135.81 +  end -- if #areas > 0
  135.82 +
  135.83 +end ) -- ui.sidebar
  135.84 \ No newline at end of file
   136.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   136.2 +++ b/app/main/unit/_sidebar_members.lua	Thu Jul 10 01:19:48 2014 +0200
   136.3 @@ -0,0 +1,33 @@
   136.4 +if not app.session:has_access("all_pseudonymous") then
   136.5 +  return
   136.6 +end
   136.7 +
   136.8 +local unit = param.get("unit", "table")
   136.9 +local members_selector = Member:new_selector()
  136.10 +  :join("privilege", nil, { "privilege.member_id = member.id AND privilege.unit_id = ? AND privilege.voting_right", unit.id })
  136.11 +  :add_where("active")
  136.12 +  :limit(50)
  136.13 +
  136.14 +local member_count = unit.member_count or 0
  136.15 +  
  136.16 +ui.sidebar ( "tab-members", function ()
  136.17 +  ui.sidebarHead( function ()
  136.18 +    ui.heading {
  136.19 +      level = 2,
  136.20 +      content = _("Eligible members (#{count})", { count = member_count })
  136.21 +    }
  136.22 +  end )
  136.23 +  execute.view {
  136.24 +    module = 'member', view   = '_list', params = {
  136.25 +      members_selector = members_selector,
  136.26 +      no_filter = true, no_paginate = true,
  136.27 +      member_class = "sidebarRow sidebarRowNarrow"
  136.28 +    }
  136.29 +  }
  136.30 +  if member_count > members_selector:count() then
  136.31 +    ui.link {
  136.32 +      text = _"Show all members",
  136.33 +      module = "member", view = "list"
  136.34 +    }
  136.35 +  end
  136.36 +end )
   137.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   137.2 +++ b/app/main/unit/_sidebar_whatcanido.lua	Thu Jul 10 01:19:48 2014 +0200
   137.3 @@ -0,0 +1,69 @@
   137.4 +local unit = param.get ( "unit", "table" )
   137.5 +
   137.6 +ui.sidebar ( "tab-whatcanido", function ()
   137.7 +
   137.8 +  ui.sidebarHeadWhatCanIDo()
   137.9 +  
  137.10 +  if app.session.member then
  137.11 +  
  137.12 +    if app.session.member:has_voting_right_for_unit_id ( unit.id ) then
  137.13 +      ui.sidebarSection( function ()
  137.14 +        
  137.15 +        if not unit.delegation_info.first_trustee_id then
  137.16 +          ui.heading{ level = 3, content = _"I want to delegate this organizational unit" }
  137.17 +          ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  137.18 +            ui.tag { tag = "li", content = function ()
  137.19 +              ui.link {
  137.20 +                module = "delegation", view = "show", params = {
  137.21 +                  unit_id = unit.id,
  137.22 +                },
  137.23 +                content = _("choose delegatee", {
  137.24 +                  unit_name = unit.name
  137.25 +                })
  137.26 +              }
  137.27 +            end }
  137.28 +          end }
  137.29 +        else
  137.30 +          ui.container { attr = { class = "right" }, content = function()
  137.31 +            local member = Member:by_id(unit.delegation_info.first_trustee_id)
  137.32 +            execute.view{
  137.33 +              module = "member_image",
  137.34 +              view = "_show",
  137.35 +              params = {
  137.36 +                member = member,
  137.37 +                image_type = "avatar",
  137.38 +                show_dummy = true
  137.39 +              }
  137.40 +            }
  137.41 +          end }
  137.42 +          ui.heading{ level = 3, content = _"You delegated this unit" }
  137.43 +
  137.44 +          ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  137.45 +            ui.tag { tag = "li", content = function ()
  137.46 +              ui.link {
  137.47 +                module = "delegation", view = "show", params = {
  137.48 +                  unit_id = unit.id,
  137.49 +                },
  137.50 +                content = _("change/revoke delegation", {
  137.51 +                  unit_name = unit.name
  137.52 +                })
  137.53 +              }
  137.54 +            end }
  137.55 +          end }
  137.56 +        end
  137.57 +      end )
  137.58 +
  137.59 +      ui.sidebarSection( function()
  137.60 +        ui.heading { level = 3, content = _"I want to start a new initiative" }
  137.61 +        ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  137.62 +          ui.tag { tag = "li", content = _"Open the appropriate subject area where your issue fits in and follow the instruction on that page." }
  137.63 +        end } 
  137.64 +      end )
  137.65 +    
  137.66 +    else
  137.67 +      ui.sidebarSection( _"You are not entitled to vote in this unit" )
  137.68 +    end
  137.69 +
  137.70 +  end
  137.71 +  
  137.72 +end )
  137.73 \ No newline at end of file
   138.1 --- a/app/main/unit/list.lua	Thu Jul 10 01:02:43 2014 +0200
   138.2 +++ b/app/main/unit/list.lua	Thu Jul 10 01:19:48 2014 +0200
   138.3 @@ -1,10 +1,10 @@
   138.4 -slot.put_into("title", _"Unit list")
   138.5 -
   138.6 -util.help("unit.list", _"Unit list")
   138.7 +ui.title(_"Unit list")
   138.8  
   138.9 -slot.put("<br />")
  138.10 +ui.section( function()
  138.11 +  ui.sectionRow( function()
  138.12 +    execute.view{ module = "unit", view = "_list" }
  138.13 +  end)
  138.14 +end )
  138.15  
  138.16 -execute.view{ module = "unit", view = "_list" }
  138.17  
  138.18 -slot.put("<br />")
  138.19  
   139.1 --- a/app/main/unit/show.lua	Thu Jul 10 01:02:43 2014 +0200
   139.2 +++ b/app/main/unit/show.lua	Thu Jul 10 01:19:48 2014 +0200
   139.3 @@ -2,19 +2,14 @@
   139.4  
   139.5  local unit = Unit:by_id(unit_id)
   139.6  
   139.7 -slot.select("head", function()
   139.8 -  execute.view{ module = "unit", view = "_head", params = { unit = unit, show_content = true, member = app.session.member } }
   139.9 -end)
  139.10 +if not unit then
  139.11 +  execute.view { module = "index", view = "404" }
  139.12 +  request.set_status("404 Not Found")
  139.13 +  return
  139.14 +end
  139.15  
  139.16 -if config.single_unit_id and not app.session.member_id and config.motd_public then
  139.17 -  local help_text = config.motd_public
  139.18 -  ui.container{
  139.19 -    attr = { class = "wiki motd" },
  139.20 -    content = function()
  139.21 -      slot.put(format.wiki_text(help_text))
  139.22 -    end
  139.23 -  }
  139.24 -end
  139.25 +
  139.26 +unit:load_delegation_info_once_for_member_id(app.session.member_id)
  139.27  
  139.28  local areas_selector = Area:build_selector{ active = true, unit_id = unit_id }
  139.29  areas_selector:add_order_by("member_weight DESC")
  139.30 @@ -43,49 +38,38 @@
  139.31    :add_where("issue.closed NOTNULL")
  139.32    :add_order_by("issue.closed DESC")
  139.33  
  139.34 -local tabs = {
  139.35 -  module = "unit",
  139.36 -  view = "show",
  139.37 -  id = unit.id
  139.38 -}
  139.39 +  
  139.40  
  139.41 -tabs[#tabs+1] = {
  139.42 -  name = "areas",
  139.43 -  label = _"Areas",
  139.44 -  module = "area",
  139.45 -  view = "_list",
  139.46 -  params = { areas_selector = areas_selector, member = app.session.member }
  139.47 -}
  139.48 +execute.view { module = "unit", view = "_head", params = { unit = unit } }
  139.49  
  139.50 -tabs[#tabs+1] = {
  139.51 -  name = "timeline",
  139.52 -  label = _"Latest events",
  139.53 -  module = "event",
  139.54 -  view = "_list",
  139.55 -  params = { for_unit = unit }
  139.56 -}
  139.57  
  139.58 -tabs[#tabs+1] = {
  139.59 -  name = "open",
  139.60 -  label = _"Open issues",
  139.61 -  module = "issue",
  139.62 -  view = "_list",
  139.63 -  params = {
  139.64 -    for_state = "open",
  139.65 -    issues_selector = open_issues_selector, for_unit = true
  139.66 -  }
  139.67 -}
  139.68 -tabs[#tabs+1] = {
  139.69 -  name = "closed",
  139.70 -  label = _"Closed issues",
  139.71 -  module = "issue",
  139.72 -  view = "_list",
  139.73 -  params = {
  139.74 -    for_state = "closed",
  139.75 -    issues_selector = closed_issues_selector, for_unit = true
  139.76 +execute.view { 
  139.77 +  module = "unit", view = "_sidebar", params = { 
  139.78 +    unit = unit
  139.79    }
  139.80  }
  139.81  
  139.82 +execute.view { 
  139.83 +  module = "unit", view = "_sidebar_whatcanido", params = { 
  139.84 +    unit = unit
  139.85 +  }
  139.86 +}
  139.87 +
  139.88 +execute.view { 
  139.89 +  module = "unit", view = "_sidebar_members", params = { 
  139.90 +    unit = unit
  139.91 +  }
  139.92 +}
  139.93 +
  139.94 +execute.view {
  139.95 +  module = "issue",
  139.96 +  view = "_list2",
  139.97 +  params = { for_unit = unit, head = function ()
  139.98 +    ui.heading { attr = { class = "left" }, level = 1, content = unit.name }
  139.99 +  end }
 139.100 +}
 139.101 +
 139.102 +--[[
 139.103  if app.session:has_access("all_pseudonymous") then
 139.104    tabs[#tabs+1] = {
 139.105      name = "eligible_voters",
 139.106 @@ -104,4 +88,6 @@
 139.107    }
 139.108  end
 139.109  
 139.110 -ui.tabs(tabs)
 139.111 \ No newline at end of file
 139.112 +ui.tabs(tabs)
 139.113 +
 139.114 +--]]
 139.115 \ No newline at end of file
   140.1 --- a/app/main/vote/_action/update.lua	Thu Jul 10 01:02:43 2014 +0200
   140.2 +++ b/app/main/vote/_action/update.lua	Thu Jul 10 01:19:48 2014 +0200
   140.3 @@ -3,19 +3,23 @@
   140.4  
   140.5  local issue = Issue:new_selector():add_where{ "id = ?", param.get("issue_id", atom.integer) }:for_share():single_object_mode():exec()
   140.6  
   140.7 -local preview = param.get("preview") and true or false
   140.8 +local preview = (param.get("preview") or param.get("edit")) and true or false
   140.9  
  140.10  if not app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then
  140.11    error("access denied")
  140.12  end
  140.13  
  140.14 -local update_comment = param.get("update_comment") == "1" and true or false
  140.15 +local update_comment = param.get("update_comment") and true or false
  140.16  
  140.17  if issue.state ~= "voting" and not issue.closed then
  140.18    slot.put_into("error", _"Voting has not started yet.")
  140.19    return false
  140.20  end
  140.21  
  140.22 +if (issue.phase_finished or issue.closed) and preview then
  140.23 +  return
  140.24 +end
  140.25 +
  140.26  if issue.phase_finished or issue.closed and not update_comment then
  140.27    slot.put_into("error", _"This issue is already closed.")
  140.28    return false
  140.29 @@ -66,7 +70,22 @@
  140.30        end
  140.31      end
  140.32      
  140.33 -    local formatting_engine = param.get("formatting_engine")
  140.34 +    local formatting_engine
  140.35 +    if config.enforce_formatting_engine then
  140.36 +      formatting_engine = config.enforce_formatting_engine
  140.37 +    else
  140.38 +      formatting_engine = param.get("formatting_engine")
  140.39 +      local formatting_engine_valid = false
  140.40 +      for i, fe in ipairs(config.formatting_engines) do
  140.41 +        if formatting_engine == fe.id then
  140.42 +          formatting_engine_valid = true
  140.43 +        end
  140.44 +      end
  140.45 +      if not formatting_engine_valid then
  140.46 +        error("invalid formatting engine!")
  140.47 +      end
  140.48 +    end
  140.49 +
  140.50      local comment = param.get("comment")
  140.51  
  140.52      if comment ~= direct_voter.comment then
   141.1 --- a/app/main/vote/list.lua	Thu Jul 10 01:02:43 2014 +0200
   141.2 +++ b/app/main/vote/list.lua	Thu Jul 10 01:19:48 2014 +0200
   141.3 @@ -21,69 +21,29 @@
   141.4    readonly = true
   141.5  end
   141.6  
   141.7 +if preview then
   141.8 +  readonly = true
   141.9 +end
  141.10 +
  141.11  local submit_button_text = _"Finish voting"
  141.12 +local edit_button_text = _"Edit again"
  141.13  
  141.14  if issue.closed then
  141.15 -  submit_button_text = _"Update voting comment"
  141.16 +  submit_button_text = _"Save voting comment"
  141.17 +  edit_button_text = _"Edit voting comment"
  141.18  end
  141.19  
  141.20 +execute.view {
  141.21 +  module = "issue", view = "_head", params = { issue = issue }
  141.22 +}
  141.23 +
  141.24  local direct_voter
  141.25  
  141.26  if member then
  141.27    direct_voter = DirectVoter:by_pk(issue.id, member.id)
  141.28 -  local str = _("Ballot of '#{member_name}' for issue ##{issue_id}",
  141.29 -                  {member_name = string.format('<a href="%s">%s</a>',
  141.30 -                                          encode.url{
  141.31 -                                            module    = "member",
  141.32 -                                            view      = "show",
  141.33 -                                            id        = member.id,
  141.34 -                                          },
  141.35 -                                          encode.html(member.name)),
  141.36 -                   issue_id = string.format('<a href="%s">%s</a>',
  141.37 -                                          encode.url{
  141.38 -                                            module    = "issue",
  141.39 -                                            view      = "show",
  141.40 -                                            id        = issue.id,
  141.41 -                                          },
  141.42 -                                          encode.html(tostring(issue.id)))
  141.43 -                  }
  141.44 -              )
  141.45 -  ui.raw_title(str)
  141.46  else
  141.47    member = app.session.member
  141.48 -
  141.49    direct_voter = DirectVoter:by_pk(issue.id, member.id)
  141.50 -
  141.51 -  ui.title(_"Voting")
  141.52 -
  141.53 -  ui.actions(function()
  141.54 -    ui.link{
  141.55 -      text = _"Cancel",
  141.56 -      module = "issue",
  141.57 -      view = "show",
  141.58 -      id = issue.id
  141.59 -    }
  141.60 -    if direct_voter then
  141.61 -      slot.put(" &middot; ")
  141.62 -      ui.link{
  141.63 -        text = _"Discard voting",
  141.64 -        module = "vote",
  141.65 -        action = "update",
  141.66 -        params = {
  141.67 -          issue_id = issue.id,
  141.68 -          discard = true
  141.69 -        },
  141.70 -        routing = {
  141.71 -          default = {
  141.72 -            mode = "redirect",
  141.73 -            module = "issue",
  141.74 -            view = "show",
  141.75 -            id = issue.id
  141.76 -          }
  141.77 -        }
  141.78 -      }
  141.79 -    end
  141.80 -  end)
  141.81  end
  141.82  
  141.83  
  141.84 @@ -144,10 +104,7 @@
  141.85    end
  141.86  end
  141.87  
  141.88 -
  141.89 -
  141.90  if not readonly then
  141.91 -  util.help("vote.list", _"Voting")
  141.92    slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/dragdrop.js"></script>')
  141.93    slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/voting.js"></script>')
  141.94  end
  141.95 @@ -179,321 +136,436 @@
  141.96    end
  141.97  }
  141.98  
  141.99 -ui.form{
 141.100 -  record = direct_voter,
 141.101 -  attr = {
 141.102 -    id = "voting_form",
 141.103 -    class = readonly and "voting_form_readonly" or "voting_form_active"
 141.104 -  },
 141.105 -  module = "vote",
 141.106 -  action = "update",
 141.107 -  params = { issue_id = issue.id },
 141.108 -  content = function()
 141.109 -    if not readonly or preview then
 141.110 -      local scoring = param.get("scoring")
 141.111 -      if not scoring then
 141.112 -        for i, initiative in ipairs(initiatives) do
 141.113 -          local vote = initiative.vote
 141.114 -          if vote then
 141.115 -            tempvotings[initiative.id] = vote.grade
 141.116 -          else
 141.117 -            tempvotings[initiative.id] = 0
 141.118 -          end
 141.119 -        end
 141.120 -        local tempvotings_list = {}
 141.121 -        for key, val in pairs(tempvotings) do
 141.122 -          tempvotings_list[#tempvotings_list+1] = tostring(key) .. ":" .. tostring(val)
 141.123 -        end
 141.124 -        if #tempvotings_list > 0 then
 141.125 -          scoring = table.concat(tempvotings_list, ";")
 141.126 -        else
 141.127 -          scoring = ""
 141.128 -        end
 141.129 -      end
 141.130 -      slot.put('<input type="hidden" name="scoring" value="' .. scoring .. '"/>')
 141.131 -      -- TODO abstrahieren
 141.132 -      ui.tag{
 141.133 -        tag = "input",
 141.134 -        attr = {
 141.135 -          type = "submit",
 141.136 -          class = "voting_done1",
 141.137 -          value = submit_button_text
 141.138 -        }
 141.139 +if issue.state == "finished_with_winner" 
 141.140 +  or issue.state == "finished_without_winner" 
 141.141 +then
 141.142 +
 141.143 +  local members_selector = Member:new_selector()
 141.144 +    :join("delegating_voter", nil, "delegating_voter.member_id = member.id")
 141.145 +    :add_where{ "delegating_voter.issue_id = ?", issue.id }
 141.146 +    :add_where{ "delegating_voter.delegate_member_ids[1] = ?", member.id }
 141.147 +    :add_field("delegating_voter.weight", "voter_weight")
 141.148 +    :join("issue", nil, "issue.id = delegating_voter.issue_id")
 141.149 +    
 141.150 +  ui.sidebar( "tab-members", function()
 141.151 +    ui.sidebarHead(function()
 141.152 +      ui.heading{ level = 2, content = _"Incoming delegations" }
 141.153 +    end)
 141.154 +    execute.view{
 141.155 +      module = "member",
 141.156 +      view = "_list",
 141.157 +      params = {
 141.158 +        members_selector = members_selector,
 141.159 +        trustee = member,
 141.160 +        issue = issue,
 141.161 +        initiative = initiative,
 141.162 +        for_votes = true, no_filter = true,
 141.163 +        member_class = "sidebarRow sidebarRowNarrow",
 141.164        }
 141.165 +    }
 141.166 +  end)
 141.167 +end
 141.168 +
 141.169 +
 141.170 +ui.section( function()
 141.171 +
 141.172 +  ui.sectionHead( function()
 141.173 +    if preview then
 141.174 +      ui.heading { level = 1, content = _"Preview of voting ballot" }
 141.175 +    elseif readonly then
 141.176 +      local str = _("Ballot of '#{member_name}'",
 141.177 +                      {member_name = string.format('<a href="%s">%s</a>',
 141.178 +                                              encode.url{
 141.179 +                                                module    = "member",
 141.180 +                                                view      = "show",
 141.181 +                                                id        = member.id,
 141.182 +                                              },
 141.183 +                                              encode.html(member.name))
 141.184 +                      }
 141.185 +                  )
 141.186 +      ui.heading { level = 1, content = function () slot.put ( str ) end }
 141.187 +    else
 141.188 +      ui.heading { level = 1, content = _"Voting" }
 141.189      end
 141.190 -    ui.container{
 141.191 -      attr = { id = "voting" },
 141.192 +  end )
 141.193 +  
 141.194 +  ui.sectionRow( function()
 141.195 +
 141.196 +    ui.form{
 141.197 +      record = direct_voter,
 141.198 +      attr = {
 141.199 +        id = "voting_form",
 141.200 +        class = readonly and "voting_form_readonly" or "voting_form_active"
 141.201 +      },
 141.202 +      module = "vote",
 141.203 +      action = "update",
 141.204 +      params = { issue_id = issue.id },
 141.205        content = function()
 141.206 -        local approval_index, disapproval_index = 0, 0
 141.207 -        for grade = max_grade, min_grade, -1 do 
 141.208 -          local entries = sections[grade]
 141.209 -          local class
 141.210 -          if grade > 0 then
 141.211 -            class = "approval"
 141.212 -          elseif grade < 0 then
 141.213 -            class = "disapproval"
 141.214 -          else
 141.215 -            class = "abstention"
 141.216 +        if not readonly or preview then
 141.217 +          local scoring = param.get("scoring")
 141.218 +          if not scoring then
 141.219 +            for i, initiative in ipairs(initiatives) do
 141.220 +              local vote = initiative.vote
 141.221 +              if vote then
 141.222 +                tempvotings[initiative.id] = vote.grade
 141.223 +              else
 141.224 +                tempvotings[initiative.id] = 0
 141.225 +              end
 141.226 +            end
 141.227 +            local tempvotings_list = {}
 141.228 +            for key, val in pairs(tempvotings) do
 141.229 +              tempvotings_list[#tempvotings_list+1] = tostring(key) .. ":" .. tostring(val)
 141.230 +            end
 141.231 +            if #tempvotings_list > 0 then
 141.232 +              scoring = table.concat(tempvotings_list, ";")
 141.233 +            else
 141.234 +              scoring = ""
 141.235 +            end
 141.236            end
 141.237 -          if
 141.238 -            #entries > 0 or
 141.239 -            (grade == 1 and not approval_used) or
 141.240 -            (grade == -1 and not disapproval_used) or
 141.241 -            grade == 0
 141.242 -          then
 141.243 -            ui.container{
 141.244 -              attr = { class = class },
 141.245 -              content = function()
 141.246 -                local heading
 141.247 -                if class == "approval" then
 141.248 -                  approval_used = true
 141.249 -                  approval_index = approval_index + 1
 141.250 -                  if approval_count > 1 then
 141.251 -                    if approval_index == 1 then
 141.252 -                      if #entries == 1 then
 141.253 -                        heading = _"Approval (first preference) [single entry]"
 141.254 +          slot.put('<input type="hidden" name="scoring" value="' .. scoring .. '"/>')
 141.255 +        end
 141.256 +        if preview then
 141.257 +          ui.heading{ level = 2, content = _"Your choice" }
 141.258 +        elseif not readonly then
 141.259 +          ui.heading{ level = 2, content = _"Make your choice by placing the initiatives" }
 141.260 +        end
 141.261 +        
 141.262 +        ui.container{
 141.263 +          attr = { id = "voting" },
 141.264 +          content = function()
 141.265 +            local approval_index, disapproval_index = 0, 0
 141.266 +            for grade = max_grade, min_grade, -1 do 
 141.267 +              local entries = sections[grade]
 141.268 +              local class
 141.269 +              if grade > 0 then
 141.270 +                class = "approval"
 141.271 +              elseif grade < 0 then
 141.272 +                class = "disapproval"
 141.273 +              else
 141.274 +                class = "abstention"
 141.275 +              end
 141.276 +              if
 141.277 +                #entries > 0 or
 141.278 +                (grade == 1 and not approval_used) or
 141.279 +                (grade == -1 and not disapproval_used) or
 141.280 +                grade == 0
 141.281 +              then
 141.282 +                ui.container{
 141.283 +                  attr = { class = class },
 141.284 +                  content = function()
 141.285 +                    local heading
 141.286 +                    if class == "approval" then
 141.287 +                      approval_used = true
 141.288 +                      approval_index = approval_index + 1
 141.289 +                      if approval_count > 1 then
 141.290 +                        if approval_index == 1 then
 141.291 +                          if #entries == 1 then
 141.292 +                            heading = _"Approval (first preference) [single entry]"
 141.293 +                          else
 141.294 +                            heading = _"Approval (first preference) [many entries]"
 141.295 +                          end
 141.296 +                        elseif approval_index == 2 then
 141.297 +                          if #entries == 1 then
 141.298 +                            heading = _"Approval (second preference) [single entry]"
 141.299 +                          else
 141.300 +                            heading = _"Approval (second preference) [many entries]"
 141.301 +                          end
 141.302 +                        elseif approval_index == 3 then
 141.303 +                          if #entries == 1 then
 141.304 +                            heading = _"Approval (third preference) [single entry]"
 141.305 +                          else
 141.306 +                            heading = _"Approval (third preference) [many entries]"
 141.307 +                          end
 141.308 +                        else
 141.309 +                          if #entries == 1 then
 141.310 +                            heading = _"Approval (#th preference) [single entry]"
 141.311 +                          else
 141.312 +                            heading = _"Approval (#th preference) [many entries]"
 141.313 +                          end
 141.314 +                        end
 141.315                        else
 141.316 -                        heading = _"Approval (first preference) [many entries]"
 141.317 -                      end
 141.318 -                    elseif approval_index == 2 then
 141.319 -                      if #entries == 1 then
 141.320 -                        heading = _"Approval (second preference) [single entry]"
 141.321 -                      else
 141.322 -                        heading = _"Approval (second preference) [many entries]"
 141.323 +                        if #entries == 1 then
 141.324 +                          heading = _"Approval [single entry]"
 141.325 +                        else
 141.326 +                          heading = _"Approval [many entries]"
 141.327 +                        end
 141.328                        end
 141.329 -                    elseif approval_index == 3 then
 141.330 -                      if #entries == 1 then
 141.331 -                        heading = _"Approval (third preference) [single entry]"
 141.332 +                    elseif class == "abstention" then
 141.333 +                        if #entries == 1 then
 141.334 +                          heading = _"Abstention [single entry]"
 141.335 +                        else
 141.336 +                          heading = _"Abstention [many entries]"
 141.337 +                        end
 141.338 +                    elseif class == "disapproval" then
 141.339 +                      disapproval_used = true
 141.340 +                      disapproval_index = disapproval_index + 1
 141.341 +                      if disapproval_count > disapproval_index + 1 then
 141.342 +                        if #entries == 1 then
 141.343 +                          heading = _"Disapproval (prefer to lower blocks) [single entry]"
 141.344 +                        else
 141.345 +                          heading = _"Disapproval (prefer to lower blocks) [many entries]"
 141.346 +                        end
 141.347 +                      elseif disapproval_count == 2 and disapproval_index == 1 then
 141.348 +                        if #entries == 1 then
 141.349 +                          heading = _"Disapproval (prefer to lower block) [single entry]"
 141.350 +                        else
 141.351 +                          heading = _"Disapproval (prefer to lower block) [many entries]"
 141.352 +                        end
 141.353 +                      elseif disapproval_index == disapproval_count - 1 then
 141.354 +                        if #entries == 1 then
 141.355 +                          heading = _"Disapproval (prefer to last block) [single entry]"
 141.356 +                        else
 141.357 +                          heading = _"Disapproval (prefer to last block) [many entries]"
 141.358 +                        end
 141.359                        else
 141.360 -                        heading = _"Approval (third preference) [many entries]"
 141.361 -                      end
 141.362 -                    else
 141.363 -                      if #entries == 1 then
 141.364 -                        heading = _"Approval (#th preference) [single entry]"
 141.365 -                      else
 141.366 -                        heading = _"Approval (#th preference) [many entries]"
 141.367 +                        if #entries == 1 then
 141.368 +                          heading = _"Disapproval [single entry]"
 141.369 +                        else
 141.370 +                          heading = _"Disapproval [many entries]"
 141.371 +                        end
 141.372                        end
 141.373                      end
 141.374 -                  else
 141.375 -                    if #entries == 1 then
 141.376 -                      heading = _"Approval [single entry]"
 141.377 -                    else
 141.378 -                      heading = _"Approval [many entries]"
 141.379 -                    end
 141.380 -                  end
 141.381 -                elseif class == "abstention" then
 141.382 -                    if #entries == 1 then
 141.383 -                      heading = _"Abstention [single entry]"
 141.384 -                    else
 141.385 -                      heading = _"Abstention [many entries]"
 141.386 -                    end
 141.387 -                elseif class == "disapproval" then
 141.388 -                  disapproval_used = true
 141.389 -                  disapproval_index = disapproval_index + 1
 141.390 -                  if disapproval_count > disapproval_index + 1 then
 141.391 -                    if #entries == 1 then
 141.392 -                      heading = _"Disapproval (prefer to lower blocks) [single entry]"
 141.393 -                    else
 141.394 -                      heading = _"Disapproval (prefer to lower blocks) [many entries]"
 141.395 -                    end
 141.396 -                  elseif disapproval_count == 2 and disapproval_index == 1 then
 141.397 -                    if #entries == 1 then
 141.398 -                      heading = _"Disapproval (prefer to lower block) [single entry]"
 141.399 -                    else
 141.400 -                      heading = _"Disapproval (prefer to lower block) [many entries]"
 141.401 -                    end
 141.402 -                  elseif disapproval_index == disapproval_count - 1 then
 141.403 -                    if #entries == 1 then
 141.404 -                      heading = _"Disapproval (prefer to last block) [single entry]"
 141.405 -                    else
 141.406 -                      heading = _"Disapproval (prefer to last block) [many entries]"
 141.407 -                    end
 141.408 -                  else
 141.409 -                    if #entries == 1 then
 141.410 -                      heading = _"Disapproval [single entry]"
 141.411 -                    else
 141.412 -                      heading = _"Disapproval [many entries]"
 141.413 -                    end
 141.414 -                  end
 141.415 -                end
 141.416 -                ui.tag {
 141.417 -                  tag     = "div",
 141.418 -                  attr    = { class = "cathead" },
 141.419 -                  content = heading
 141.420 -                }
 141.421 -                for i, initiative in ipairs(entries) do
 141.422 -                  ui.container{
 141.423 -                    attr = {
 141.424 -                      class = "movable",
 141.425 -                      id = "entry_" .. tostring(initiative.id)
 141.426 -                    },
 141.427 -                    content = function()
 141.428 -                      local initiators_selector = initiative:get_reference_selector("initiating_members")
 141.429 -                        :add_where("accepted")
 141.430 -                      local initiators = initiators_selector:exec()
 141.431 -                      local initiator_names = {}
 141.432 -                      for i, initiator in ipairs(initiators) do
 141.433 -                        initiator_names[#initiator_names+1] = initiator.name
 141.434 -                      end
 141.435 -                      local initiator_names_string = table.concat(initiator_names, ", ")
 141.436 +                    ui.tag {
 141.437 +                      tag     = "div",
 141.438 +                      attr    = { class = "cathead" },
 141.439 +                      content = heading
 141.440 +                    }
 141.441 +                    for i, initiative in ipairs(entries) do
 141.442                        ui.container{
 141.443 -                        attr = { style = "float: right; position: relative;" },
 141.444 +                        attr = {
 141.445 +                          class = "movable",
 141.446 +                          id = "entry_" .. tostring(initiative.id)
 141.447 +                        },
 141.448                          content = function()
 141.449 -                          ui.link{
 141.450 -                            attr = { class = "clickable" },
 141.451 -                            content = _"Show",
 141.452 -                            module = "initiative",
 141.453 -                            view = "show",
 141.454 -                            id = initiative.id
 141.455 -                          }
 141.456 -                          slot.put(" ")
 141.457 -                          ui.link{
 141.458 -                            attr = { class = "clickable", target = "_blank" },
 141.459 -                            content = _"(new window)",
 141.460 -                            module = "initiative",
 141.461 -                            view = "show",
 141.462 -                            id = initiative.id
 141.463 +                          local initiators_selector = initiative:get_reference_selector("initiating_members")
 141.464 +                            :add_where("accepted")
 141.465 +                          local initiators = initiators_selector:exec()
 141.466 +                          local initiator_names = {}
 141.467 +                          for i, initiator in ipairs(initiators) do
 141.468 +                            initiator_names[#initiator_names+1] = initiator.name
 141.469 +                          end
 141.470 +                          local initiator_names_string = table.concat(initiator_names, ", ")
 141.471 +                          ui.container{
 141.472 +                            attr = { style = "float: right; position: relative;" },
 141.473 +                            content = function()
 141.474 +                              ui.link{
 141.475 +                                attr = { class = "clickable" },
 141.476 +                                content = _"Show",
 141.477 +                                module = "initiative",
 141.478 +                                view = "show",
 141.479 +                                id = initiative.id
 141.480 +                              }
 141.481 +                              slot.put(" ")
 141.482 +                              ui.link{
 141.483 +                                attr = { class = "clickable", target = "_blank" },
 141.484 +                                content = _"(new window)",
 141.485 +                                module = "initiative",
 141.486 +                                view = "show",
 141.487 +                                id = initiative.id
 141.488 +                              }
 141.489 +                              if not readonly then
 141.490 +                                slot.put(" ")
 141.491 +                                ui.image{ attr = { class = "grabber" }, static = "icons/grabber.png" }
 141.492 +                              end
 141.493 +                            end
 141.494                            }
 141.495                            if not readonly then
 141.496 -                            slot.put(" ")
 141.497 -                            ui.image{ attr = { class = "grabber" }, static = "icons/grabber.png" }
 141.498 -                          end
 141.499 -                        end
 141.500 -                      }
 141.501 -                      if not readonly then
 141.502 -                        ui.container{
 141.503 -                          attr = { style = "float: left; position: relative;" },
 141.504 -                          content = function()
 141.505 -                            ui.tag{
 141.506 -                              tag = "input",
 141.507 -                              attr = {
 141.508 -                                onclick = "if (jsFail) return true; voting_moveUp(this.parentNode.parentNode); return(false);",
 141.509 -                                name = "move_up_" .. tostring(initiative.id),
 141.510 -                                class = not disabled and "clickable" or nil,
 141.511 -                                type = "image",
 141.512 -                                src = encode.url{ static = "icons/move_up.png" },
 141.513 -                                alt = _"Move up"
 141.514 -                              }
 141.515 -                            }
 141.516 -                            slot.put("&nbsp;")
 141.517 -                            ui.tag{
 141.518 -                              tag = "input",
 141.519 -                              attr = {
 141.520 -                                onclick = "if (jsFail) return true; voting_moveDown(this.parentNode.parentNode); return(false);",
 141.521 -                                name = "move_down_" .. tostring(initiative.id),
 141.522 -                                class = not disabled and "clickable" or nil,
 141.523 -                                type = "image",
 141.524 -                                src = encode.url{ static = "icons/move_down.png" },
 141.525 -                                alt = _"Move down"
 141.526 -                              }
 141.527 -                            }
 141.528 -                            slot.put("&nbsp;")
 141.529 -                          end
 141.530 -                        }
 141.531 -                      end
 141.532 -                      ui.container{
 141.533 -                        content = function()
 141.534 -                          ui.tag{ content = "i" .. initiative.id .. ": " }
 141.535 -                          ui.tag{ content = initiative.shortened_name }
 141.536 -                          slot.put("<br />")
 141.537 -                          for i, initiator in ipairs(initiators) do
 141.538 -                            ui.link{
 141.539 -                              attr = { class = "clickable" },
 141.540 -                              content = function ()
 141.541 -                                execute.view{
 141.542 -                                  module = "member_image",
 141.543 -                                  view = "_show",
 141.544 -                                  params = {
 141.545 -                                    member = initiator,
 141.546 -                                    image_type = "avatar",
 141.547 -                                    show_dummy = true,
 141.548 -                                    class = "micro_avatar",
 141.549 -                                    popup_text = text
 141.550 +                            ui.container{
 141.551 +                              attr = { style = "float: left; position: relative;" },
 141.552 +                              content = function()
 141.553 +                                ui.tag{
 141.554 +                                  tag = "input",
 141.555 +                                  attr = {
 141.556 +                                    onclick = "if (jsFail) return true; voting_moveUp(this.parentNode.parentNode); return(false);",
 141.557 +                                    name = "move_up_" .. tostring(initiative.id),
 141.558 +                                    class = not disabled and "clickable" or nil,
 141.559 +                                    type = "image",
 141.560 +                                    src = encode.url{ static = "icons/move_up.png" },
 141.561 +                                    alt = _"Move up"
 141.562 +                                  }
 141.563 +                                }
 141.564 +                                slot.put("&nbsp;")
 141.565 +                                ui.tag{
 141.566 +                                  tag = "input",
 141.567 +                                  attr = {
 141.568 +                                    onclick = "if (jsFail) return true; voting_moveDown(this.parentNode.parentNode); return(false);",
 141.569 +                                    name = "move_down_" .. tostring(initiative.id),
 141.570 +                                    class = not disabled and "clickable" or nil,
 141.571 +                                    type = "image",
 141.572 +                                    src = encode.url{ static = "icons/move_down.png" },
 141.573 +                                    alt = _"Move down"
 141.574                                    }
 141.575                                  }
 141.576 -                              end,
 141.577 -                              module = "member", view = "show", id = initiator.id
 141.578 +                                slot.put("&nbsp;")
 141.579 +                              end
 141.580                              }
 141.581 -                            slot.put(" ")
 141.582 -                            ui.tag{ content = initiator.name }
 141.583 -                            slot.put(" ")
 141.584                            end
 141.585 +                          ui.container{
 141.586 +                            content = function()
 141.587 +                              ui.tag{ content = "i" .. initiative.id .. ": " }
 141.588 +                              ui.tag{ content = initiative.shortened_name }
 141.589 +                              slot.put("<br />")
 141.590 +                              for i, initiator in ipairs(initiators) do
 141.591 +                                ui.link{
 141.592 +                                  attr = { class = "clickable" },
 141.593 +                                  content = function ()
 141.594 +                                    execute.view{
 141.595 +                                      module = "member_image",
 141.596 +                                      view = "_show",
 141.597 +                                      params = {
 141.598 +                                        member = initiator,
 141.599 +                                        image_type = "avatar",
 141.600 +                                        show_dummy = true,
 141.601 +                                        class = "micro_avatar",
 141.602 +                                        popup_text = text
 141.603 +                                      }
 141.604 +                                    }
 141.605 +                                  end,
 141.606 +                                  module = "member", view = "show", id = initiator.id
 141.607 +                                }
 141.608 +                                slot.put(" ")
 141.609 +                                ui.tag{ content = initiator.name }
 141.610 +                                slot.put(" ")
 141.611 +                              end
 141.612 +                            end
 141.613 +                          }
 141.614                          end
 141.615                        }
 141.616                      end
 141.617 +                  end
 141.618 +                }
 141.619 +              end
 141.620 +            end
 141.621 +          end
 141.622 +        }
 141.623 +        if app.session.member_id and preview then
 141.624 +          local formatting_engine = param.get("formatting_engine") or config.enforce_formatting_engine
 141.625 +          local comment = param.get("comment")
 141.626 +          if comment and #comment > 0 then
 141.627 +            local rendered_comment = format.wiki_text(comment, formatting_engine)
 141.628 +            ui.heading{ level = "2", content = _"Voting comment" }
 141.629 +            ui.container { attr = { class = "member_statement" }, content = function()
 141.630 +              slot.put(rendered_comment)
 141.631 +            end }
 141.632 +            slot.put("<br />")
 141.633 +          end
 141.634 +        end
 141.635 +        if (readonly or direct_voter and direct_voter.comment) and not preview and not (app.session.member_id == member.id) then
 141.636 +          local text
 141.637 +          if direct_voter and direct_voter.comment_changed then
 141.638 +            text = _("Voting comment (last updated: #{timestamp})", { timestamp = format.timestamp(direct_voter.comment_changed) })
 141.639 +          elseif direct_voter and direct_voter.comment then
 141.640 +            text = _"Voting comment"
 141.641 +          end
 141.642 +          if text then
 141.643 +            ui.heading{ level = "2", content = text }
 141.644 +          end
 141.645 +          if direct_voter and direct_voter.comment then
 141.646 +            local rendered_comment = direct_voter:get_content('html')
 141.647 +            ui.container { attr = { class = "member_statement" }, content = function()
 141.648 +              slot.put(rendered_comment)
 141.649 +            end }
 141.650 +            slot.put("<br />")
 141.651 +          end
 141.652 +        end
 141.653 +        if app.session.member_id and app.session.member_id == member.id then
 141.654 +          if (not readonly or direct_voter) and not preview then
 141.655 +            ui.container{ content = function()
 141.656 +              if not config.enforce_formatting_engine then
 141.657 +                ui.field.select{
 141.658 +                  label = _"Wiki engine for statement",
 141.659 +                  name = "formatting_engine",
 141.660 +                  foreign_records = config.formatting_engines,
 141.661 +                  attr = {id = "formatting_engine"},
 141.662 +                  foreign_id = "id",
 141.663 +                  foreign_name = "name",
 141.664 +                  value = param.get("formatting_engine") or direct_voter and direct_voter.formatting_engine
 141.665 +                }
 141.666 +              end
 141.667 +              ui.heading { level = 2, content = _"Voting comment (optional)" }
 141.668 +              ui.field.text{
 141.669 +                name = "comment",
 141.670 +                multiline = true,
 141.671 +                value = param.get("comment") or direct_voter and direct_voter.comment,
 141.672 +                attr = { style = "height: 10ex; width: 100%;" },
 141.673 +              }
 141.674 +            end }
 141.675 +          end
 141.676 +
 141.677 +          if preview then
 141.678 +            if not config.enforce_formatting_engine then
 141.679 +              ui.field.hidden{ name = "formatting_engine", value = param.get("formatting_engine") }
 141.680 +            end
 141.681 +            ui.field.hidden{ name = "comment", value = param.get("comment") or direct_voter and direct_voter.comment }
 141.682 +          end
 141.683 +          
 141.684 +          if not readonly or direct_voter or preview then
 141.685 +            ui.container{ content = function()
 141.686 +              if preview  then
 141.687 +                slot.put(" ")
 141.688 +                ui.tag{
 141.689 +                  tag = "input",
 141.690 +                  attr = {
 141.691 +                    type = "submit",
 141.692 +                    class = "btn btn-default",
 141.693 +                    name = issue.closed and "update_comment" or nil,
 141.694 +                    value = submit_button_text -- finish voting / update comment
 141.695                    }
 141.696 -                end
 141.697 +                }
 141.698                end
 141.699 -            }
 141.700 +              if not preview then
 141.701 +                ui.tag{
 141.702 +                  tag = "input",
 141.703 +                  attr = {
 141.704 +                    type = "submit",
 141.705 +                    name = "preview",
 141.706 +                    class = "btn btn-default",
 141.707 +                    value = _"Preview",
 141.708 +                  }
 141.709 +                }
 141.710 +              else
 141.711 +                slot.put(" ")
 141.712 +                ui.tag{
 141.713 +                  tag = "input",
 141.714 +                  attr = {
 141.715 +                    type = "submit",
 141.716 +                    name = "edit",
 141.717 +                    class = "btn-link",
 141.718 +                    value = edit_button_text,
 141.719 +                  }
 141.720 +                }
 141.721 +              end
 141.722 +            end }
 141.723            end
 141.724          end
 141.725        end
 141.726      }
 141.727 -    if app.session.member_id and preview then
 141.728 -      local formatting_engine = param.get("formatting_engine")
 141.729 -      local comment = param.get("comment")
 141.730 -      local rendered_comment = format.wiki_text(comment, formatting_engine)
 141.731 -      slot.put(rendered_comment)
 141.732 -    end
 141.733 -    if (readonly or direct_voter and direct_voter.comment) and not preview then
 141.734 -      local text
 141.735 -      if direct_voter and direct_voter.comment_changed then
 141.736 -        text = _("Voting comment (last updated: #{timestamp})", { timestamp = format.timestamp(direct_voter.comment_changed) })
 141.737 -      elseif direct_voter and direct_voter.comment then
 141.738 -        text = _"Voting comment"
 141.739 -      end
 141.740 -      if text then
 141.741 -        ui.heading{ level = "2", content = text }
 141.742 -      end
 141.743 -      if direct_voter and direct_voter.comment then
 141.744 -        local rendered_comment = direct_voter:get_content('html')
 141.745 -        ui.container{ attr = { class = "member_statement" }, content = function()
 141.746 -          slot.put(rendered_comment)
 141.747 -        end }
 141.748 -        slot.put("<br />")
 141.749 -      end
 141.750 +    slot.put("<br />")
 141.751 +    ui.link{
 141.752 +      text = _"Cancel",
 141.753 +      module = "issue",
 141.754 +      view = "show",
 141.755 +      id = issue.id
 141.756 +    }
 141.757 +    if direct_voter then
 141.758 +      slot.put(" | ")
 141.759 +      ui.link {
 141.760 +        module = "vote", action = "update",
 141.761 +        params = {
 141.762 +          issue_id = issue.id,
 141.763 +          discard = true
 141.764 +        },
 141.765 +        routing = {
 141.766 +          default = {
 141.767 +            mode = "redirect",
 141.768 +            module = "issue",
 141.769 +            view = "show",
 141.770 +            id = issue.id
 141.771 +          }
 141.772 +        },
 141.773 +        text = _"Discard my vote"
 141.774 +      }
 141.775      end
 141.776 -    if app.session.member_id and app.session.member_id == member.id then
 141.777 -      if not readonly or direct_voter then
 141.778 -        ui.field.hidden{ name = "update_comment", value = param.get("update_comment") or issue.closed and "1" }
 141.779 -        ui.field.select{
 141.780 -          label = _"Wiki engine for statement",
 141.781 -          name = "formatting_engine",
 141.782 -          foreign_records = {
 141.783 -            { id = "rocketwiki", name = "RocketWiki" },
 141.784 -            { id = "compat", name = _"Traditional wiki syntax" }
 141.785 -          },
 141.786 -          attr = {id = "formatting_engine"},
 141.787 -          foreign_id = "id",
 141.788 -          foreign_name = "name",
 141.789 -          value = param.get("formatting_engine") or direct_voter and direct_voter.formatting_engine
 141.790 -        }
 141.791 -        ui.field.text{
 141.792 -          label = _"Voting comment (optional)",
 141.793 -          name = "comment",
 141.794 -          multiline = true,
 141.795 -          value = param.get("comment") or direct_voter and direct_voter.comment,
 141.796 -          attr = { style = "height: 20ex;" },
 141.797 -        }
 141.798 -        ui.submit{
 141.799 -          name = "preview",
 141.800 -          value = _"Preview voting comment",
 141.801 -          attr = { class = "preview" }
 141.802 -        }
 141.803 -      end
 141.804 -      if not readonly or preview or direct_voter then
 141.805 -        slot.put(" ")
 141.806 -        ui.tag{
 141.807 -          tag = "input",
 141.808 -          attr = {
 141.809 -            type = "submit",
 141.810 -            class = "voting_done2",
 141.811 -            value = submit_button_text
 141.812 -          }
 141.813 -        }
 141.814 -      end
 141.815 -    end
 141.816 -  end
 141.817 -}
 141.818  
 141.819 -
 141.820 +  end )
 141.821 +end )
 141.822 \ No newline at end of file
   142.1 --- a/app/main/vote/show_incoming.lua	Thu Jul 10 01:02:43 2014 +0200
   142.2 +++ b/app/main/vote/show_incoming.lua	Thu Jul 10 01:19:48 2014 +0200
   142.3 @@ -1,5 +1,20 @@
   142.4 -local initiative = Initiative:by_id(param.get("initiative_id", atom.integer))
   142.5 -local issue = initiative.issue
   142.6 +local initiative = Initiative:by_id(param.get("initiative_id"))
   142.7 +
   142.8 +local issue
   142.9 +
  142.10 +if initiative then
  142.11 +  issue = initiative.issue
  142.12 +else
  142.13 +  issue = Issue:by_id(param.get("issue_id"))
  142.14 +end
  142.15 +
  142.16 +if app.session.member_id then
  142.17 +  if initiative then
  142.18 +    initiative:load_everything_for_member_id(app.session.member.id)
  142.19 +  end
  142.20 +  issue:load_everything_for_member_id(app.session.member.id)
  142.21 +end
  142.22 +
  142.23  local member = Member:by_id(param.get("member_id", atom.integer))
  142.24  
  142.25  local members_selector = Member:new_selector()
  142.26 @@ -9,13 +24,55 @@
  142.27    :add_field("delegating_voter.weight", "voter_weight")
  142.28    :join("issue", nil, "issue.id = delegating_voter.issue_id")
  142.29  
  142.30 +
  142.31  execute.view{
  142.32 -  module = "member",
  142.33 -  view = "_list",
  142.34 -  params = {
  142.35 -    members_selector = members_selector,
  142.36 -    initiative = initiative,
  142.37 -    trustee = member,
  142.38 -    for_votes = true
  142.39 +  module = "issue", view = "_head", params = {
  142.40 +    issue = issue, initiative = initiative
  142.41 +  }
  142.42 +}
  142.43 +
  142.44 +execute.view{ module = "issue", view = "_sidebar_state", params = {
  142.45 +  issue = issue,
  142.46 +} }
  142.47 +
  142.48 +execute.view { 
  142.49 +  module = "issue", view = "_sidebar_issue", params = {
  142.50 +    issue = issue,
  142.51 +    highlight_initiative_id = initiative and initiative.id or nil,
  142.52 +  }
  142.53 +}
  142.54 +
  142.55 +execute.view { 
  142.56 +  module = "issue", view = "_sidebar_whatcanido", params = {
  142.57 +    issue = issue
  142.58    }
  142.59 -}
  142.60 \ No newline at end of file
  142.61 +}
  142.62 +
  142.63 +execute.view { 
  142.64 +  module = "issue", view = "_sidebar_members", params = {
  142.65 +    issue = issue,
  142.66 +    initiative = initiative
  142.67 +  }
  142.68 +}
  142.69 +
  142.70 +
  142.71 +ui.section( function()
  142.72 +    
  142.73 +  ui.sectionHead( function()
  142.74 +    ui.heading{ level = 1, content = _("Incoming delegations for '#{member}'", { member = member.name }) }
  142.75 +  end)
  142.76 +
  142.77 +  execute.view{
  142.78 +    module = "member",
  142.79 +    view = "_list",
  142.80 +    params = {
  142.81 +      members_selector = members_selector,
  142.82 +      trustee = member,
  142.83 +      issue = issue,
  142.84 +      initiative = initiative,
  142.85 +      for_votes = true, no_filter = true,
  142.86 +      
  142.87 +    }
  142.88 +  }
  142.89 +  
  142.90 +end )
   143.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   143.2 +++ b/config/devel.lua	Thu Jul 10 01:19:48 2014 +0200
   143.3 @@ -0,0 +1,288 @@
   143.4 +-- ========================================================================
   143.5 +-- MANDATORY (MUST BE CAREFULLY CHECKED AND PROPERLY SET!)
   143.6 +-- ========================================================================
   143.7 +
   143.8 +-- Name of this instance, defaults to name of config file
   143.9 +-- ------------------------------------------------------------------------
  143.10 +config.instance_name = "Public Software Group e.V."
  143.11 +
  143.12 +
  143.13 +-- Information about service provider (HTML)
  143.14 +-- ------------------------------------------------------------------------
  143.15 +config.app_service_provider = "Snake Oil<br/>10000 Berlin<br/>Germany"
  143.16 +
  143.17 +
  143.18 +-- A HTML formatted text the user has to accept while registering
  143.19 +-- ------------------------------------------------------------------------
  143.20 +config.use_terms = "<h1>Terms of Use</h1><p>Insert terms here</p>"
  143.21 +
  143.22 +
  143.23 +-- Checkbox(es) the user has to accept while registering
  143.24 +-- ------------------------------------------------------------------------
  143.25 +config.use_terms_checkboxes = {
  143.26 +  {
  143.27 +    name = "terms_of_use_v1",
  143.28 +    html = "I accept the terms of use.",
  143.29 +    not_accepted_error = "You have to accept the terms of use to be able to register."
  143.30 +  },
  143.31 +--  {
  143.32 +--    name = "extra_terms_of_use_v1",
  143.33 +--    html = "I accept the extra terms of use.",
  143.34 +--    not_accepted_error = "You have to accept the extra terms of use to be able to register."
  143.35 +--  }
  143.36 +}
  143.37 +
  143.38 +  
  143.39 +-- Absolute base url of application
  143.40 +-- ------------------------------------------------------------------------
  143.41 +config.absolute_base_url = "http://192.168.1.34/lf3/"
  143.42 +
  143.43 +
  143.44 +-- Connection information for the LiquidFeedback database
  143.45 +-- ------------------------------------------------------------------------
  143.46 +config.database = { engine='postgresql', dbname='liquid_feedback' }
  143.47 +config.database = { engine='postgresql', dbname='lftest' }
  143.48 +
  143.49 +
  143.50 +-- Location of the rocketwiki binaries
  143.51 +-- ------------------------------------------------------------------------
  143.52 +config.enforce_formatting_engine = "markdown2"
  143.53 +
  143.54 +config.formatting_engines = {
  143.55 +  { id = "markdown2",
  143.56 +    name = "python-markdown2",
  143.57 +    executable = "markdown2",
  143.58 +    args = {'-s', 'escape', '-x', 'cuddled-lists,nofollow,wiki-tables'},
  143.59 +    remove_images = true
  143.60 +  },
  143.61 +  { id = "markdown_py",
  143.62 +    name = "Python Markdown",
  143.63 +    executable = "markdown_py",
  143.64 +    args = {'-s', 'escape', '-x', 'extra', '-x', 'nl2br', '-x', 'sane_lists'},
  143.65 +    remove_images = true
  143.66 +  },
  143.67 +  { id = "rocketwiki",
  143.68 +    name = "RocketWiki",
  143.69 +    executable = "/opt/rocketwiki-lqfb/rocketwiki-lqfb",
  143.70 +    remove_images = false
  143.71 +  },
  143.72 +  { id = "compat",
  143.73 +    name = "Traditional WIKI syntax",
  143.74 +    executable = "/opt/rocketwiki-lqfb/rocketwiki-lqfb-compat",
  143.75 +    remove_images = false
  143.76 +  }
  143.77 +}
  143.78 +
  143.79 +-- Public access level
  143.80 +-- ------------------------------------------------------------------------
  143.81 +-- Available options:
  143.82 +-- "none" 
  143.83 +--     -> Closed user group, no public access at all
  143.84 +--        (except login/registration/password reset)
  143.85 +-- "anonymous"
  143.86 +--     -> Shows only initiative/suggestions texts and aggregated
  143.87 +--        supporter/voter counts
  143.88 +-- "authors_pseudonymous" 
  143.89 +--     -> Like anonymous, but shows screen names of authors
  143.90 +-- "all_pseudonymous" 
  143.91 +--     -> Show everything a member can see, except profile pages
  143.92 +-- "everything"
  143.93 +--     -> Show everything a member can see, including profile pages
  143.94 +-- ------------------------------------------------------------------------
  143.95 +config.public_access = "all_pseudonymous"
  143.96 +
  143.97 +
  143.98 +
  143.99 +-- ========================================================================
 143.100 +-- OPTIONAL
 143.101 +-- Remove leading -- to use a option
 143.102 +-- ========================================================================
 143.103 +
 143.104 +-- List of enabled languages, defaults to available languages
 143.105 +-- ------------------------------------------------------------------------
 143.106 +-- config.enabled_languages = { 'en', 'de', 'eo', 'el', 'hu', 'it', 'nl', 'zh-TW' }
 143.107 +
 143.108 +-- Default language, defaults to "en"
 143.109 +-- ------------------------------------------------------------------------
 143.110 +-- config.default_lang = "de"
 143.111 +
 143.112 +-- after how long is a user considered inactive and the trustee will see warning,
 143.113 +-- notation is according to postgresql intervals, default: no warning at all
 143.114 +-- ------------------------------------------------------------------------
 143.115 +config.delegation_warning_time = '1 hour'
 143.116 +
 143.117 +-- after which time a user is suggested to (_soft) or forced to (_hard) 
 143.118 +-- confirm unit and area delegations. default: no confirmation at all
 143.119 +-- ------------------------------------------------------------------------
 143.120 +-- config.check_delegations_interval_hard = "1 day"
 143.121 +-- config.check_delegations_interval_soft = "3 seconds"
 143.122 +
 143.123 +-- default options should be checked when confirming delegations
 143.124 +-- options: "confirm", "revoke" and "none"
 143.125 +-- ------------------------------------------------------------------------
 143.126 +-- config.check_delegations_default = "confirm"
 143.127 +
 143.128 +-- Prefix of all automatic mails, defaults to "[Liquid Feedback] "
 143.129 +-- ------------------------------------------------------------------------
 143.130 +-- config.mail_subject_prefix = "[LiquidFeedback] "
 143.131 +
 143.132 +-- Sender of all automatic mails, defaults to system defaults
 143.133 +-- ------------------------------------------------------------------------
 143.134 +-- config.mail_envelope_from = "liquidfeedback@example.com"
 143.135 +-- config.mail_from = { name = "LiquidFeedback", address = "liquidfeedback@example.com" }
 143.136 +-- config.mail_reply_to = { name = "Support", address = "support@example.com" }
 143.137 +
 143.138 +-- Configuration of password hashing algorithm (defaults to "crypt_sha512")
 143.139 +-- ------------------------------------------------------------------------
 143.140 +-- config.password_hash_algorithm = "crypt_sha512"
 143.141 +-- config.password_hash_algorithm = "crypt_sha256"
 143.142 +-- config.password_hash_algorithm = "crypt_md5"
 143.143 +
 143.144 +-- Number of rounds for crypt_sha* algorithms, minimum and maximum
 143.145 +-- (defaults to minimum 10000 and maximum 20000)
 143.146 +-- ------------------------------------------------------------------------
 143.147 +-- config.password_hash_min_rounds = 10000
 143.148 +-- config.password_hash_max_rounds = 20000
 143.149 +
 143.150 +-- Supply custom url for avatar/photo delivery
 143.151 +-- ------------------------------------------------------------------------
 143.152 +-- config.fastpath_url_func = nil
 143.153 +
 143.154 +-- Local directory for database dumps offered for download
 143.155 +-- ------------------------------------------------------------------------
 143.156 +-- config.download_dir = nil
 143.157 +
 143.158 +-- Special use terms for database dump download
 143.159 +-- ------------------------------------------------------------------------
 143.160 +-- config.download_use_terms = "=== Download use terms ===\n"
 143.161 +
 143.162 +-- Use custom image conversion, defaults to ImageMagick's convert
 143.163 +-- ------------------------------------------------------------------------
 143.164 +--config.member_image_content_type = "image/jpeg"
 143.165 +--config.member_image_convert_func = {
 143.166 +--  avatar = function(data) return extos.pfilter(data, "convert", "jpeg:-", "-thumbnail",   "48x48", "jpeg:-") end,
 143.167 +--  photo =  function(data) return extos.pfilter(data, "convert", "jpeg:-", "-thumbnail", "240x240", "jpeg:-") end
 143.168 +--}
 143.169 +
 143.170 +config.member_image_content_type = "image/jpeg"
 143.171 +config.member_image_convert_func = {
 143.172 +  avatar = function(data) return extos.pfilter(data, "convert",
 143.173 +    "jpeg:-",
 143.174 +    "-set", "option:distort:viewport", 
 143.175 +    "%[fx:min(w,h)]x%[fx:min(w,h)]+%[fx:max((w-h)/2,0)]+%[fx:max((h-w)/2,0)]",
 143.176 +    "-filter", "point",
 143.177 +    "-distort", "SRT", "0", 
 143.178 +    "+repage",
 143.179 +    "-define", "filter:filter=Sinc", 
 143.180 +    "-define", "filter:window=Jinc",
 143.181 +    "-define", "filter:lobes=3",
 143.182 +    "-thumbnail", "48x48",
 143.183 +    "jpeg:-"
 143.184 +  ) end,
 143.185 +  photo =  function(data) return extos.pfilter(data, "convert",
 143.186 +    "jpeg:-",
 143.187 +    "-define", "filter:filter=Sinc", 
 143.188 +    "-define", "filter:window=Jinc",
 143.189 +    "-define", "filter:lobes=3",
 143.190 +    "-thumbnail", "240x240",
 143.191 +    "jpeg:-"
 143.192 +  ) end
 143.193 +}
 143.194 +
 143.195 +
 143.196 +-- Display a html formatted public message of the day
 143.197 +-- ------------------------------------------------------------------------
 143.198 +-- config.motd_public = "<h1>Message of the day (public)</h1><p>The MOTD is formatted with HTML</p>"
 143.199 +
 143.200 +-- Display a html formatted internal message of the day
 143.201 +-- ------------------------------------------------------------------------
 143.202 +-- config.motd_intern = "<h1>Message of the day (intern)</h1><p>The MOTD is formatted with HTML</p>"
 143.203 +
 143.204 +-- Automatic issue related discussion URL
 143.205 +-- ------------------------------------------------------------------------
 143.206 +-- config.issue_discussion_url_func = function(issue)
 143.207 +--   return "http://example.com/discussion/issue_" .. tostring(issue.id)
 143.208 +-- end
 143.209 +
 143.210 +-- Configuration of "tell others"
 143.211 +-- ------------------------------------------------------------------------
 143.212 +config.tell_others = {
 143.213 +  initiative = function (initiative)
 143.214 +    local text = "i" .. initiative.id .. ": " .. initiative.name .. " " .. request.get_absolute_baseurl() .. "initiative/" .. initiative.id .. ".html"
 143.215 +    return {
 143.216 +      { content = "tweet this initiative", external = "https://twitter.com/intent/tweet?text=" .. encode.url_part(text) },
 143.217 +      { content = "send link with e-mail", external = "mailto:?subject=" .. encode.url_part(initiative.display_name) .. "&body=" .. encode.url_part(text) }
 143.218 +    }
 143.219 +  end
 143.220 +}
 143.221 +
 143.222 +-- Integration of Etherpad, disabled by default
 143.223 +-- ------------------------------------------------------------------------
 143.224 +--config.etherpad = {
 143.225 +--  base_url = "http://example.com:9001/",
 143.226 +--  api_base = "http://localhost:9001/",
 143.227 +--  api_key = "mysecretapikey",
 143.228 +--  group_id = "mygroupname",
 143.229 +--  cookie_path = "/"
 143.230 +--}
 143.231 +
 143.232 +-- Free timings, may be used together with polling policies
 143.233 +-- ------------------------------------------------------------------------
 143.234 +-- This example expects a date string entered in the free timing field
 143.235 +-- by the user creating a poll, interpreting it as target date for then
 143.236 +-- poll and splits the remainig time at the ratio of 4:1:2
 143.237 +-- Please note, polling policies never have an admission phase
 143.238 +
 143.239 +
 143.240 +config.free_timing = {
 143.241 +  calculate_func = function(policy, timing_string)
 143.242 +    function interval_by_seconds(secs)
 143.243 +      local secs_per_day = 60 * 60 * 24
 143.244 +      local days
 143.245 +      days = math.floor(secs / secs_per_day)
 143.246 +      secs = secs - days * secs_per_day
 143.247 +      return days .. " days " .. secs .. " seconds"
 143.248 +    end
 143.249 +    local target_date = parse.date(timing_string, atom.date)
 143.250 +    if not target_date then
 143.251 +      return false
 143.252 +    end
 143.253 +    local target_timestamp = target_date.midday
 143.254 +    local now = atom.timestamp:get_current()
 143.255 +    trace.debug(target_timestamp, now)
 143.256 +    local duration = target_timestamp - now
 143.257 +    if duration < 0 then
 143.258 +      return false
 143.259 +    end
 143.260 +    return {
 143.261 +      discussion = interval_by_seconds(duration / 7 * 4),
 143.262 +      verification = interval_by_seconds(duration / 7 * 1),
 143.263 +      voting = interval_by_seconds(duration / 7 * 2)
 143.264 +    }
 143.265 +  end,
 143.266 +  available_func = function(policy)
 143.267 +    return { 
 143.268 +      { name = "End of 2013", id = '2013-12-31' },
 143.269 +      { name = "End of 2014", id = '2014-12-31' },
 143.270 +      { name = "End of 2015", id = '2015-12-31' }
 143.271 +    }
 143.272 +  end
 143.273 +}
 143.274 +
 143.275 +
 143.276 +config.enable_debug_trace = true
 143.277 +
 143.278 +-- WebMCP accelerator
 143.279 +-- uncomment the following two lines to use C implementations of chosen
 143.280 +-- functions and to disable garbage collection during the request, to
 143.281 +-- increase speed:
 143.282 +-- ------------------------------------------------------------------------
 143.283 +-- require 'webmcp_accelerator'
 143.284 +-- if cgi then collectgarbage("stop") end
 143.285 +
 143.286 +
 143.287 +-- ========================================================================
 143.288 +-- Do main initialisation (DO NOT REMOVE FOLLOWING SECTION)
 143.289 +-- ========================================================================
 143.290 +
 143.291 +execute.config("init")
   144.1 --- a/config/example.lua	Thu Jul 10 01:02:43 2014 +0200
   144.2 +++ b/config/example.lua	Thu Jul 10 01:19:48 2014 +0200
   144.3 @@ -12,9 +12,9 @@
   144.4  config.app_service_provider = "Snake Oil<br/>10000 Berlin<br/>Germany"
   144.5  
   144.6  
   144.7 --- A rocketwiki formatted text the user has to accept while registering
   144.8 +-- A HTML formatted text the user has to accept while registering
   144.9  -- ------------------------------------------------------------------------
  144.10 -config.use_terms = "=== Terms of Use ==="
  144.11 +config.use_terms = "<h1>Terms of Use</h1><p>Insert terms here</p>"
  144.12  
  144.13  
  144.14  -- Checkbox(es) the user has to accept while registering
  144.15 @@ -45,9 +45,29 @@
  144.16  
  144.17  -- Location of the rocketwiki binaries
  144.18  -- ------------------------------------------------------------------------
  144.19 -config.formatting_engine_executeables = {
  144.20 -  rocketwiki= "/opt/rocketwiki-lqfb/rocketwiki-lqfb",
  144.21 -  compat = "/opt/rocketwiki-lqfb/rocketwiki-lqfb-compat"
  144.22 +config.enforce_formatting_engine = "markdown2"
  144.23 +config.formatting_engines = {
  144.24 +  { id = "markdown2",
  144.25 +    name = "python-markdown2",
  144.26 +    executable = "markdown2",
  144.27 +    args = {'-s', 'escape', '-x', 'cuddled-lists,nofollow,wiki-tables'},
  144.28 +    remove_images = true
  144.29 +  },
  144.30 +  { id = "markdown_py",
  144.31 +    name = "Python Markdown",
  144.32 +    executable = "markdown_py",
  144.33 +    args = {'-s', 'escape', '-x', 'extra', '-x', 'nl2br', '-x', 'sane_lists'},
  144.34 +    remove_images = true
  144.35 +  },
  144.36 +  { id = "rocketwiki",
  144.37 +    name = "RocketWiki",
  144.38 +    executable = "/opt/rocketwiki-lqfb/rocketwiki-lqfb"
  144.39 +  },
  144.40 +  { id = "compat",
  144.41 +    name = "Traditional WIKI syntax",
  144.42 +    executable = "/opt/rocketwiki-lqfb/rocketwiki-lqfb-compat"
  144.43 +  },
  144.44 +
  144.45  }
  144.46  
  144.47  
  144.48 @@ -143,9 +163,13 @@
  144.49  --  photo =  function(data) return extos.pfilter(data, "convert", "jpeg:-", "-thumbnail", "240x240", "jpeg:-") end
  144.50  --}
  144.51  
  144.52 --- Display a public message of the day
  144.53 +-- Display a html formatted public message of the day
  144.54  -- ------------------------------------------------------------------------
  144.55 --- config.motd_public = "===Message of the day===\nThe MOTD is formatted with rocket wiki"
  144.56 +-- config.motd_public = "<h1>Message of the day (public)</h1><p>The MOTD is formatted with HTML</p>"
  144.57 +
  144.58 +-- Display a html formatted internal message of the day
  144.59 +-- ------------------------------------------------------------------------
  144.60 +-- config.motd_intern = "<h1>Message of the day (intern)</h1><p>The MOTD is formatted with HTML</p>"
  144.61  
  144.62  -- Automatic issue related discussion URL
  144.63  -- ------------------------------------------------------------------------
   145.1 --- a/config/init.lua	Thu Jul 10 01:02:43 2014 +0200
   145.2 +++ b/config/init.lua	Thu Jul 10 01:19:48 2014 +0200
   145.3 @@ -3,7 +3,7 @@
   145.4  -- (except when you really know what you are doing!)
   145.5  -- ========================================================================
   145.6  
   145.7 -config.app_version = "2.2.6"
   145.8 +config.app_version = "3.0.0"
   145.9  
  145.10  if not config.password_hash_algorithm then
  145.11    config.password_hash_algorithm = "crypt_sha512"
  145.12 @@ -18,7 +18,7 @@
  145.13  end
  145.14  
  145.15  if config.enabled_languages == nil then
  145.16 -  config.enabled_languages = { 'en', 'de', 'eo', 'el', 'hu', 'it', 'nl', 'zh-Hans', 'zh-TW' }
  145.17 +  config.enabled_languages = { 'en', 'de' } --, 'eo', 'el', 'hu', 'it', 'nl', 'zh-Hans', 'zh-TW' }
  145.18  end
  145.19  
  145.20  if config.default_lang == nil then
   146.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   146.2 +++ b/config/lf3.lua	Thu Jul 10 01:19:48 2014 +0200
   146.3 @@ -0,0 +1,290 @@
   146.4 +-- ========================================================================
   146.5 +-- MANDATORY (MUST BE CAREFULLY CHECKED AND PROPERLY SET!)
   146.6 +-- ========================================================================
   146.7 +
   146.8 +-- Name of this instance, defaults to name of config file
   146.9 +-- ------------------------------------------------------------------------
  146.10 +config.instance_name = "Public Software Group e.V."
  146.11 +
  146.12 +
  146.13 +-- Information about service provider (HTML)
  146.14 +-- ------------------------------------------------------------------------
  146.15 +config.app_service_provider = [[
  146.16 +Public Software Group e. V.<br />
  146.17 +Johannisstr. 12<br />
  146.18 +10117 Berlin<br />
  146.19 +Germany<br /><br />
  146.20 +eingetragen im Vereinsregister des Amtsgerichtes Charlottenburg unter der
  146.21 +  Registernummer VR 28873 B<br />
  146.22 +vertreten durch die Vorstandsmitglieder Jan Behrens, Axel Kistner, Andreas
  146.23 +  Nitsche und Björn Swierczek jeweils mit Einzelvertretungsbefugnis
  146.24 +]]
  146.25 +
  146.26 +
  146.27 +-- A HTML formatted text the user has to accept while registering
  146.28 +-- ------------------------------------------------------------------------
  146.29 +config.use_terms = [[
  146.30 +<h1>Terms of Use</h1>
  146.31 +<p>
  146.32 +  All data display below and all data you enter later while using the system
  146.33 +  and all data you are submitting via the programming interface will be
  146.34 +  stored in the LiquidFeedback database and published. Every access to the
  146.35 +  system is subject of tracing and logging for development purposes.
  146.36 +</p>
  146.37 +<p>  
  146.38 +  Please notice, this is a **public test dedicated to developers**: serious
  146.39 +  errors can happen or private data unintentionally published.
  146.40 +</p>
  146.41 +<p>
  146.42 +  Everything is <b>ON YOUR OWN RISK</b>
  146.43 +</p>
  146.44 +]]
  146.45 +
  146.46 +-- Checkbox(es) the user has to accept while registering
  146.47 +-- ------------------------------------------------------------------------
  146.48 +config.use_terms_checkboxes = {
  146.49 +  {
  146.50 +    name = "terms_of_use_20140514",
  146.51 +    html = "I accept the terms of use.",
  146.52 +    not_accepted_error = "You have to accept the terms of use to be able to register."
  146.53 +  },
  146.54 +--  {
  146.55 +--    name = "extra_terms_of_use_v1",
  146.56 +--    html = "I accept the extra terms of use.",
  146.57 +--    not_accepted_error = "You have to accept the extra terms of use to be able to register."
  146.58 +--  }
  146.59 +}
  146.60 +
  146.61 +  
  146.62 +-- Absolute base url of application
  146.63 +-- ------------------------------------------------------------------------
  146.64 +config.absolute_base_url = "http://dev.liquidfeedback.org/lf3/"
  146.65 +
  146.66 +
  146.67 +-- Connection information for the LiquidFeedback database
  146.68 +-- ------------------------------------------------------------------------
  146.69 +config.database = { engine='postgresql', dbname='lf3' }
  146.70 +
  146.71 +
  146.72 +-- Location of the rocketwiki binaries
  146.73 +-- ------------------------------------------------------------------------
  146.74 +config.enforce_formatting_engine = "markdown2"
  146.75 +
  146.76 +config.formatting_engines = {
  146.77 +  { id = "markdown_py",
  146.78 +    name = "Python Markdown",
  146.79 +    executable = "markdown_py",
  146.80 +    args = {'/dev/stdin', '-s', 'escape', '-x', 'extra', '-x', 'nl2br', '-x', 'sane_lists'},
  146.81 +    remove_images = true
  146.82 +  },
  146.83 +  { id = "markdown2",
  146.84 +    name = "markdown2",
  146.85 +    executable = "markdown2",
  146.86 +    args = {'-s', 'escape', '-x', 'cuddled-lists,nofollow,wiki-tables'},
  146.87 +    remove_images = true
  146.88 +  },
  146.89 +  { id = "multimarkdown",
  146.90 +    name = "MultiMarkdown",
  146.91 +    executable = "multimarkdown",
  146.92 +    args = {'--filter-html', '--filter-styles', '--nolabels' ,'-x'}
  146.93 +  },
  146.94 +  { id = "rocketwiki",
  146.95 +    name = "RocketWiki",
  146.96 +    executable = "/opt/liquid_feedback3/rocketwiki-lqfb/rocketwiki-lqfb",
  146.97 +    remove_images = false
  146.98 +  },
  146.99 +  { id = "compat",
 146.100 +    name = "Traditional WIKI syntax",
 146.101 +    executable = "/opt/liquid_feedback3/rocketwiki-lqfb/rocketwiki-lqfb-compat",
 146.102 +    remove_images = false
 146.103 +  }
 146.104 +}
 146.105 +
 146.106 +-- Public access level
 146.107 +-- ------------------------------------------------------------------------
 146.108 +-- Available options:
 146.109 +-- "none" 
 146.110 +--     -> Closed user group, no public access at all
 146.111 +--        (except login/registration/password reset)
 146.112 +-- "anonymous"
 146.113 +--     -> Shows only initiative/suggestions texts and aggregated
 146.114 +--        supporter/voter counts
 146.115 +-- "authors_pseudonymous" 
 146.116 +--     -> Like anonymous, but shows screen names of authors
 146.117 +-- "all_pseudonymous" 
 146.118 +--     -> Show everything a member can see, except profile pages
 146.119 +-- "everything"
 146.120 +--     -> Show everything a member can see, including profile pages
 146.121 +-- ------------------------------------------------------------------------
 146.122 +config.public_access = "none"
 146.123 +
 146.124 +
 146.125 +
 146.126 +-- ========================================================================
 146.127 +-- OPTIONAL
 146.128 +-- Remove leading -- to use a option
 146.129 +-- ========================================================================
 146.130 +
 146.131 +-- List of enabled languages, defaults to available languages
 146.132 +-- ------------------------------------------------------------------------
 146.133 +-- config.enabled_languages = { 'en', 'de', 'eo', 'el', 'hu', 'it', 'nl', 'zh-TW' }
 146.134 +config.enabled_languages = { 'en', 'de' }
 146.135 +
 146.136 +-- Default language, defaults to "en"
 146.137 +-- ------------------------------------------------------------------------
 146.138 +-- config.default_lang = "de"
 146.139 +
 146.140 +-- after how long is a user considered inactive and the trustee will see warning,
 146.141 +-- notation is according to postgresql intervals, default: no warning at all
 146.142 +-- ------------------------------------------------------------------------
 146.143 +config.delegation_warning_time = '3 month'
 146.144 +
 146.145 +-- after which time a user is suggested to (_soft) or forced to (_hard) 
 146.146 +-- confirm unit and area delegations. default: no confirmation at all
 146.147 +-- ------------------------------------------------------------------------
 146.148 +-- config.check_delegations_interval_hard = "1 day"
 146.149 +-- config.check_delegations_interval_soft = "3 seconds"
 146.150 +
 146.151 +-- default options should be checked when confirming delegations
 146.152 +-- options: "confirm", "revoke" and "none"
 146.153 +-- ------------------------------------------------------------------------
 146.154 +-- config.check_delegations_default = "confirm"
 146.155 +
 146.156 +-- Prefix of all automatic mails, defaults to "[Liquid Feedback] "
 146.157 +-- ------------------------------------------------------------------------
 146.158 +config.mail_subject_prefix = "[LiquidFeedback 3.0 Test] "
 146.159 +
 146.160 +-- Sender of all automatic mails, defaults to system defaults
 146.161 +-- ------------------------------------------------------------------------
 146.162 +config.mail_envelope_from = "lqfb-maintainers@public-software-group.org"
 146.163 +config.mail_from = { name = "LiquidFeedback", address = "lqfb-maintainers@public-software-group.org" }
 146.164 +--config.mail_reply_to = { name = "Support", address = "support@example.com" }
 146.165 +
 146.166 +-- Configuration of password hashing algorithm (defaults to "crypt_sha512")
 146.167 +-- ------------------------------------------------------------------------
 146.168 +-- config.password_hash_algorithm = "crypt_sha512"
 146.169 +-- config.password_hash_algorithm = "crypt_sha256"
 146.170 +-- config.password_hash_algorithm = "crypt_md5"
 146.171 +
 146.172 +-- Number of rounds for crypt_sha* algorithms, minimum and maximum
 146.173 +-- (defaults to minimum 10000 and maximum 20000)
 146.174 +-- ------------------------------------------------------------------------
 146.175 +-- config.password_hash_min_rounds = 10000
 146.176 +-- config.password_hash_max_rounds = 20000
 146.177 +
 146.178 +-- Supply custom url for avatar/photo delivery
 146.179 +-- ------------------------------------------------------------------------
 146.180 +-- config.fastpath_url_func = nil
 146.181 +
 146.182 +-- Local directory for database dumps offered for download
 146.183 +-- ------------------------------------------------------------------------
 146.184 +-- config.download_dir = nil
 146.185 +
 146.186 +-- Special use terms for database dump download
 146.187 +-- ------------------------------------------------------------------------
 146.188 +-- config.download_use_terms = "=== Download use terms ===\n"
 146.189 +
 146.190 +-- Use custom image conversion, defaults to ImageMagick's convert
 146.191 +-- ------------------------------------------------------------------------
 146.192 +--config.member_image_content_type = "image/jpeg"
 146.193 +--config.member_image_convert_func = {
 146.194 +--  avatar = function(data) return extos.pfilter(data, "convert", "jpeg:-", "-thumbnail",   "48x48", "jpeg:-") end,
 146.195 +--  photo =  function(data) return extos.pfilter(data, "convert", "jpeg:-", "-thumbnail", "240x240", "jpeg:-") end
 146.196 +--}
 146.197 +
 146.198 +-- Display a html formatted public message of the day
 146.199 +-- ------------------------------------------------------------------------
 146.200 +-- config.motd_public = "<h1>Message of the day (public)</h1><p>The MOTD is formatted with HTML</p>"
 146.201 +
 146.202 +-- Display a html formatted internal message of the day
 146.203 +-- ------------------------------------------------------------------------
 146.204 +-- config.motd_public = "<h1>Message of the day (intern)</h1><p>The MOTD is formatted with HTML</p>"
 146.205 +
 146.206 +-- Automatic issue related discussion URL
 146.207 +-- ------------------------------------------------------------------------
 146.208 +-- config.issue_discussion_url_func = function(issue)
 146.209 +--   return "http://example.com/discussion/issue_" .. tostring(issue.id)
 146.210 +-- end
 146.211 +
 146.212 +-- Configuration of "tell others"
 146.213 +-- ------------------------------------------------------------------------
 146.214 +config.tell_others = {
 146.215 +  initiative = function (initiative)
 146.216 +    local text = "i" .. initiative.id .. ": " .. initiative.name .. " " .. request.get_absolute_baseurl() .. "initiative/" .. initiative.id .. ".html"
 146.217 +    return {
 146.218 +      { content = "Tweet this initiative", external = "https://twitter.com/intent/tweet?text=" .. encode.url_part(text) },
 146.219 +      { content = "Send an eMail", external = "mailto:?subject=" .. encode.url_part(initiative.display_name) .. "&body=" .. encode.url_part(text) }
 146.220 +    }
 146.221 +  end
 146.222 +}
 146.223 +
 146.224 +-- Integration of Etherpad, disabled by default
 146.225 +-- ------------------------------------------------------------------------
 146.226 +--config.etherpad = {
 146.227 +--  base_url = "http://example.com:9001/",
 146.228 +--  api_base = "http://localhost:9001/",
 146.229 +--  api_key = "mysecretapikey",
 146.230 +--  group_id = "mygroupname",
 146.231 +--  cookie_path = "/"
 146.232 +--}
 146.233 +
 146.234 +-- Free timings, may be used together with polling policies
 146.235 +-- ------------------------------------------------------------------------
 146.236 +-- This example expects a date string entered in the free timing field
 146.237 +-- by the user creating a poll, interpreting it as target date for then
 146.238 +-- poll and splits the remainig time at the ratio of 4:1:2
 146.239 +-- Please note, polling policies never have an admission phase
 146.240 +
 146.241 +
 146.242 +config.free_timing = {
 146.243 +  calculate_func = function(policy, timing_string)
 146.244 +    function interval_by_seconds(secs)
 146.245 +      local secs_per_day = 60 * 60 * 24
 146.246 +      local days
 146.247 +      days = math.floor(secs / secs_per_day)
 146.248 +      secs = secs - days * secs_per_day
 146.249 +      return days .. " days " .. secs .. " seconds"
 146.250 +    end
 146.251 +    local target_date = parse.date(timing_string, atom.date)
 146.252 +    if not target_date then
 146.253 +      return false
 146.254 +    end
 146.255 +    local target_timestamp = target_date.midday
 146.256 +    local now = atom.timestamp:get_current()
 146.257 +    trace.debug(target_timestamp, now)
 146.258 +    local duration = target_timestamp - now
 146.259 +    if duration < 0 then
 146.260 +      return false
 146.261 +    end
 146.262 +    return {
 146.263 +      discussion = interval_by_seconds(duration / 7 * 4),
 146.264 +      verification = interval_by_seconds(duration / 7 * 1),
 146.265 +      voting = interval_by_seconds(duration / 7 * 2)
 146.266 +    }
 146.267 +  end,
 146.268 +  available_func = function(policy)
 146.269 +    return { 
 146.270 +      { name = "End of 2014", id = '2014-12-31' },
 146.271 +      { name = "End of 2015", id = '2015-12-31' },
 146.272 +      { name = "End of 2016", id = '2016-12-31' }
 146.273 +    }
 146.274 +  end
 146.275 +}
 146.276 +
 146.277 +
 146.278 +config.enable_debug_trace = true
 146.279 +
 146.280 +-- WebMCP accelerator
 146.281 +-- uncomment the following two lines to use C implementations of chosen
 146.282 +-- functions and to disable garbage collection during the request, to
 146.283 +-- increase speed:
 146.284 +-- ------------------------------------------------------------------------
 146.285 +-- require 'webmcp_accelerator'
 146.286 +-- if cgi then collectgarbage("stop") end
 146.287 +
 146.288 +
 146.289 +-- ========================================================================
 146.290 +-- Do main initialisation (DO NOT REMOVE FOLLOWING SECTION)
 146.291 +-- ========================================================================
 146.292 +
 146.293 +execute.config("init")
   147.1 --- a/env/format/interval_text.lua	Thu Jul 10 01:02:43 2014 +0200
   147.2 +++ b/env/format/interval_text.lua	Thu Jul 10 01:19:48 2014 +0200
   147.3 @@ -7,7 +7,7 @@
   147.4      :gsub("day", "{DAY}")
   147.5      :gsub("mons", "{MONS}")
   147.6      :gsub("mon", "{MON}")
   147.7 -    :gsub("yeas", "{YEARS}")
   147.8 +    :gsub("years", "{YEARS}")
   147.9      :gsub("year", "{YEAR}")
  147.10  
  147.11    if (options.mode == "time_left") then
  147.12 @@ -42,4 +42,4 @@
  147.13      return _("#{interval_text} [interval]", { interval_text = interval_text })
  147.14  
  147.15    end
  147.16 -end
  147.17 \ No newline at end of file
  147.18 +end
   148.1 --- a/env/format/wiki_text.lua	Thu Jul 10 01:02:43 2014 +0200
   148.2 +++ b/env/format/wiki_text.lua	Thu Jul 10 01:19:48 2014 +0200
   148.3 @@ -1,12 +1,38 @@
   148.4  function format.wiki_text(wiki_text, formatting_engine)
   148.5 -  local formatting_engine = formatting_engine or "rocketwiki"
   148.6 +
   148.7 +  if not formatting_engine then
   148.8 +    error("Formatting engine identifier required")
   148.9 +  end
  148.10 +
  148.11 +  local fe
  148.12 +  
  148.13 +  for i, fe_entry in ipairs(config.formatting_engines) do
  148.14 +    if fe_entry.id == formatting_engine then
  148.15 +      fe = fe_entry
  148.16 +      break
  148.17 +    end
  148.18 +  end
  148.19 +
  148.20 +  if not fe then
  148.21 +    error("Formatting engine not found")
  148.22 +  end
  148.23 +  
  148.24    local html, errmsg, exitcode = assert(
  148.25 -    extos.pfilter(wiki_text, config.formatting_engine_executeables[formatting_engine])
  148.26 +    extos.pfilter(wiki_text, fe.executable, table.unpack(fe.args or {}))
  148.27    )
  148.28 +  
  148.29    if exitcode > 0 then
  148.30 +    trace.debug(html, errmsg)
  148.31      error("Wiki parser process returned with error code " .. tostring(exitcode))
  148.32    elseif exitcode < 0 then
  148.33 +    trace.debug(html, errmsg)
  148.34      error("Wiki parser process was terminated by signal " .. tostring(-exitcode))
  148.35    end
  148.36 +
  148.37 +  if fe.remove_images then
  148.38 +    html = string.gsub(html, '<img [^>]*>', '')
  148.39 +  end
  148.40 +  
  148.41    return html
  148.42 +  
  148.43  end
   149.1 --- a/env/model/has_rendered_content.lua	Thu Jul 10 01:02:43 2014 +0200
   149.2 +++ b/env/model/has_rendered_content.lua	Thu Jul 10 01:19:48 2014 +0200
   149.3 @@ -47,7 +47,11 @@
   149.4        rendered[class.table .. "_id"] = self.id
   149.5      end
   149.6      rendered.format = "html"
   149.7 -    rendered.content = format.wiki_text(self[content_field_name], self.formatting_engine)
   149.8 +    if self.formatting_engine then
   149.9 +      rendered.content = format.wiki_text(self[content_field_name], self.formatting_engine)
  149.10 +    else
  149.11 +      rendered.content = self[content_field_name]
  149.12 +    end
  149.13      rendered:save()
  149.14      -- and return it
  149.15      return rendered
   150.1 --- a/env/ui/actions.lua	Thu Jul 10 01:02:43 2014 +0200
   150.2 +++ b/env/ui/actions.lua	Thu Jul 10 01:19:48 2014 +0200
   150.3 @@ -1,5 +1,5 @@
   150.4  function ui.actions(content)
   150.5 -  slot.select("head", function()
   150.6 +  slot.select("actions", function()
   150.7      ui.container{ attr = { class = "actions" }, content = content }
   150.8    end)
   150.9  end
  150.10 \ No newline at end of file
   151.1 --- a/env/ui/bargraph.lua	Thu Jul 10 01:02:43 2014 +0200
   151.2 +++ b/env/ui/bargraph.lua	Thu Jul 10 01:19:48 2014 +0200
   151.3 @@ -35,7 +35,7 @@
   151.4                  attr = {
   151.5                    style = "width: " .. tostring(dlength_abs) .. "px; background-color: " .. bar.color .. ";",
   151.6                  },
   151.7 -                content = function() slot.put("&nbsp;") end
   151.8 +                content = ""
   151.9                }
  151.10              end
  151.11              ui.container{
  151.12 @@ -43,7 +43,7 @@
  151.13                  class = "quorum",
  151.14                  style = "width: 1px; background-color: " .. (args.quorum_color or "blue") ..";",
  151.15                },
  151.16 -              content = function() slot.put("") end
  151.17 +              content = ""
  151.18              }
  151.19              length = dlength + 1
  151.20              value = value - dlength
  151.21 @@ -59,7 +59,7 @@
  151.22              attr = {
  151.23                style = "width: " .. tostring(value_abs) .. "px; background-color: " .. bar.color .. ";",
  151.24              },
  151.25 -            content = function() slot.put("&nbsp;") end
  151.26 +            content = ""
  151.27            }
  151.28          end
  151.29        end
   152.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   152.2 +++ b/env/ui/contextbar.lua	Thu Jul 10 01:19:48 2014 +0200
   152.3 @@ -0,0 +1,17 @@
   152.4 +function ui.contextbar ( arg1, arg2 )
   152.5 +
   152.6 +  local class = "sidebarSection"
   152.7 +  local content
   152.8 +  
   152.9 +  if arg2 then
  152.10 +    class = class .. " " .. arg1
  152.11 +    content = arg2
  152.12 +  else
  152.13 +    content = arg1
  152.14 +  end
  152.15 +
  152.16 +  slot.select ( "contextbar", function ()
  152.17 +    ui.container { attr = { class = class }, content = content }
  152.18 +  end )
  152.19 +
  152.20 +end
   153.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   153.2 +++ b/env/ui/delegation.lua	Thu Jul 10 01:19:48 2014 +0200
   153.3 @@ -0,0 +1,19 @@
   153.4 +function ui.delegation(to_member_id, to_member_name)
   153.5 +  local text = _"delegates to"
   153.6 +  ui.image{
   153.7 +    attr = { class = "delegation_arrow", alt = text, title = text },
   153.8 +    static = "delegation_arrow_24_horizontal.png"
   153.9 +  }
  153.10 +
  153.11 +  if to_member_id and to_member_name then
  153.12 +    execute.view{
  153.13 +      module = "member_image", view = "_show", params = {
  153.14 +        member_id = to_member_id, 
  153.15 +        class = "micro_avatar", 
  153.16 +        image_type = "avatar",
  153.17 +        popup_text = to_member_name,
  153.18 +        show_dummy = true
  153.19 +      }
  153.20 +    }
  153.21 +  end
  153.22 +end
  153.23 \ No newline at end of file
   154.1 --- a/env/ui/filters.lua	Thu Jul 10 01:02:43 2014 +0200
   154.2 +++ b/env/ui/filters.lua	Thu Jul 10 01:19:48 2014 +0200
   154.3 @@ -20,8 +20,12 @@
   154.4          end
   154.5          local id     = param.get_id_cgi()
   154.6          local params = param.get_all_cgi()
   154.7 +        local class = "ui_filter_head"
   154.8 +        if filter.class then
   154.9 +          class = class .. " " .. filter.class
  154.10 +        end
  154.11          ui.container{
  154.12 -          attr = { class = "ui_filter_head" },
  154.13 +          attr = { class = class },
  154.14            content = function()
  154.15              slot.put(filter.label)
  154.16              for idx, option in ipairs(filter) do
   155.1 --- a/env/ui/raw_title.lua	Thu Jul 10 01:02:43 2014 +0200
   155.2 +++ b/env/ui/raw_title.lua	Thu Jul 10 01:19:48 2014 +0200
   155.3 @@ -1,7 +1,20 @@
   155.4 -function ui.raw_title(content)
   155.5 -  slot.select("head", function()
   155.6 -    ui.container{ attr = { class = "title" }, content = function()
   155.7 -      slot.put(content)
   155.8 -    end }
   155.9 -  end)
  155.10 -end
  155.11 \ No newline at end of file
  155.12 +function ui.raw_title ( content )
  155.13 +  
  155.14 +  slot.select ( "title", function ()
  155.15 +  
  155.16 +    -- home link
  155.17 +    ui.link {
  155.18 +      module = "index", view = "index",
  155.19 +      attr = { class = "home" },
  155.20 +      content = function ()
  155.21 +        ui.image { static = "icons/16/house.png" }
  155.22 +      end
  155.23 +    }
  155.24 +    
  155.25 +    slot.put ( " " )
  155.26 +    
  155.27 +    slot.put ( content )
  155.28 +    
  155.29 +  end )
  155.30 +  
  155.31 +end
   156.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   156.2 +++ b/env/ui/section.lua	Thu Jul 10 01:19:48 2014 +0200
   156.3 @@ -0,0 +1,15 @@
   156.4 +function ui.section ( arg1, arg2 )
   156.5 +
   156.6 +  local class = "section"
   156.7 +  local content
   156.8 +  
   156.9 +  if arg2 then
  156.10 +    class = class .. " " .. arg1
  156.11 +    content = arg2
  156.12 +  else
  156.13 +    content = arg1
  156.14 +  end
  156.15 +
  156.16 +  ui.container { attr = { class = class }, content = content }
  156.17 +
  156.18 +end
   157.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   157.2 +++ b/env/ui/sectionHead.lua	Thu Jul 10 01:19:48 2014 +0200
   157.3 @@ -0,0 +1,15 @@
   157.4 +function ui.sectionHead ( arg1, arg2 )
   157.5 +
   157.6 +  local class = "sectionHead"
   157.7 +  local content
   157.8 +  
   157.9 +  if arg2 then
  157.10 +    class = class .. " " .. arg1
  157.11 +    content = arg2
  157.12 +  else
  157.13 +    content = arg1
  157.14 +  end
  157.15 +
  157.16 +  ui.container { attr = { class = class }, content = content }
  157.17 +
  157.18 +end
   158.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   158.2 +++ b/env/ui/sectionRow.lua	Thu Jul 10 01:19:48 2014 +0200
   158.3 @@ -0,0 +1,15 @@
   158.4 +function ui.sectionRow ( arg1, arg2 )
   158.5 +
   158.6 +  local class = "sectionRow"
   158.7 +  local content
   158.8 +  
   158.9 +  if arg2 then
  158.10 +    class = class .. " " .. arg1
  158.11 +    content = arg2
  158.12 +  else
  158.13 +    content = arg1
  158.14 +  end
  158.15 +
  158.16 +  ui.container { attr = { class = class }, content = content }
  158.17 +
  158.18 +end
   159.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   159.2 +++ b/env/ui/sidebar.lua	Thu Jul 10 01:19:48 2014 +0200
   159.3 @@ -0,0 +1,17 @@
   159.4 +function ui.sidebar ( arg1, arg2 )
   159.5 +
   159.6 +  local class = "sidebarSection"
   159.7 +  local content
   159.8 +  
   159.9 +  if arg2 then
  159.10 +    class = class .. " " .. arg1
  159.11 +    content = arg2
  159.12 +  else
  159.13 +    content = arg1
  159.14 +  end
  159.15 +
  159.16 +  slot.select ( "sidebar", function ()
  159.17 +    ui.container { attr = { class = class }, content = content }
  159.18 +  end )
  159.19 +
  159.20 +end
   160.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   160.2 +++ b/env/ui/sidebarHead.lua	Thu Jul 10 01:19:48 2014 +0200
   160.3 @@ -0,0 +1,15 @@
   160.4 +function ui.sidebarHead ( arg1, arg2 )
   160.5 +
   160.6 +  local class = "sidebarHead"
   160.7 +  local content
   160.8 +  
   160.9 +  if arg2 then
  160.10 +    class = class .. " " .. arg1
  160.11 +    content = arg2
  160.12 +  else
  160.13 +    content = arg1
  160.14 +  end
  160.15 +
  160.16 +  ui.container { attr = { class = class }, content = content }
  160.17 +
  160.18 +end
   161.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   161.2 +++ b/env/ui/sidebarHeadWhatCanIDo.lua	Thu Jul 10 01:19:48 2014 +0200
   161.3 @@ -0,0 +1,21 @@
   161.4 +function ui.sidebarHeadWhatCanIDo ()
   161.5 +  ui.sidebarHead( function ()
   161.6 +    --ui.image{ attr = { class = "right icon24" }, static = "icons/48/info.png" }
   161.7 +    ui.heading {
   161.8 +      level = 2, content = _"What can I do here?"
   161.9 +    }
  161.10 +  end )
  161.11 +  if not app.session.member then
  161.12 +    ui.sidebarSection( function()
  161.13 +      ui.heading { level = 3, content = _"Closed user group" }
  161.14 +      ui.tag { tag = "ul", attr = { class = "ul" }, content = function ()
  161.15 +        ui.tag { tag = "li", content = function ()
  161.16 +          ui.link {
  161.17 +            content = _"login to participate",
  161.18 +            module = "index", view = "login"
  161.19 +          }
  161.20 +        end }
  161.21 +      end } 
  161.22 +    end )
  161.23 +  end
  161.24 +end
   162.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   162.2 +++ b/env/ui/sidebarSection.lua	Thu Jul 10 01:19:48 2014 +0200
   162.3 @@ -0,0 +1,15 @@
   162.4 +function ui.sidebarSection ( arg1, arg2 )
   162.5 +
   162.6 +  local class = "sidebarRow"
   162.7 +  local content
   162.8 +  
   162.9 +  if arg2 then
  162.10 +    class = class .. " " .. arg1
  162.11 +    content = arg2
  162.12 +  else
  162.13 +    content = arg1
  162.14 +  end
  162.15 +
  162.16 +  ui.container { attr = { class = class }, content = content }
  162.17 +
  162.18 +end
   163.1 --- a/env/ui/title.lua	Thu Jul 10 01:02:43 2014 +0200
   163.2 +++ b/env/ui/title.lua	Thu Jul 10 01:19:48 2014 +0200
   163.3 @@ -1,5 +1,31 @@
   163.4 -function ui.title(content)
   163.5 -  slot.select("head", function()
   163.6 -    ui.container{ attr = { class = "title" }, content = content }
   163.7 -  end)
   163.8 -end
   163.9 \ No newline at end of file
  163.10 +function ui.title ( content )
  163.11 +  
  163.12 +  slot.select ( "title", function ()
  163.13 +    
  163.14 +    -- home link
  163.15 +    ui.link {
  163.16 +      module = "index", view = "index",
  163.17 +      attr = { class = "home", title = _"Home" },
  163.18 +      content = function ()
  163.19 +        ui.image { 
  163.20 +          attr = { class = "icon24", alt = title },
  163.21 +          static = "icons/48/home.png"
  163.22 +        }
  163.23 +      end
  163.24 +    }
  163.25 +  
  163.26 +    if content then
  163.27 +      ui.tag { attr = { class = "spacer" }, content = function()
  163.28 +        slot.put ( " » " )
  163.29 +      end }
  163.30 +      ui.tag { tag = "span", content = content }
  163.31 +    else
  163.32 +      ui.tag { attr = { class = "spacer" }, content = function()
  163.33 +        slot.put ( " " )
  163.34 +      end }
  163.35 +      ui.tag { tag = "span", content = _"Home" }
  163.36 +    end
  163.37 +    
  163.38 +  end )
  163.39 +  
  163.40 +end
   164.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   164.2 +++ b/env/ui/titleAdmin.lua	Thu Jul 10 01:19:48 2014 +0200
   164.3 @@ -0,0 +1,8 @@
   164.4 +function ui.titleAdmin(title)
   164.5 +  ui.title(function()
   164.6 +    ui.link { module = "admin", view = "index", content = _"System administration" }
   164.7 +    if title then
   164.8 +      ui.tag { tag = "span", content = content }
   164.9 +    end
  164.10 +  end)
  164.11 +end
  164.12 \ No newline at end of file
   165.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   165.2 +++ b/env/ui/titleMember.lua	Thu Jul 10 01:19:48 2014 +0200
   165.3 @@ -0,0 +1,17 @@
   165.4 +function ui.titleMember(title, title2)
   165.5 +  local member = app.session.member
   165.6 +  if type(title) == "table" then
   165.7 +    member = title
   165.8 +    title = title2
   165.9 +  end
  165.10 +  ui.title(function()
  165.11 +    if member then
  165.12 +      ui.link { module = "member", view = "show", id = member.id, content = member.name }
  165.13 +    end
  165.14 +    if title then
  165.15 +      ui.tag { attr = { class = "member" }, content = function()
  165.16 +        ui.tag{ tag = "span", content = title }
  165.17 +      end }
  165.18 +    end
  165.19 +  end)
  165.20 +end
  165.21 \ No newline at end of file
   166.1 --- a/env/util/help.lua	Thu Jul 10 01:02:43 2014 +0200
   166.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   166.3 @@ -1,68 +0,0 @@
   166.4 -function util.help(id, title)
   166.5 -  if not app.session.member_id then
   166.6 -    return
   166.7 -  end
   166.8 -  local setting_key = "liquidfeedback_frontend_hidden_help_" .. id
   166.9 -  local setting = Setting:by_pk(app.session.member.id, setting_key)
  166.10 -  if not setting then
  166.11 -    ui.container{
  166.12 -      attr = { class = "help help_visible" },
  166.13 -      content = function()
  166.14 -        ui.image{
  166.15 -          attr = { class = "help_icon" },
  166.16 -          static = "icons/16/help.png"
  166.17 -        }
  166.18 -        ui.container{
  166.19 -          attr = { class = "help_actions" },
  166.20 -          content = function()
  166.21 -            ui.link{
  166.22 -              text   = _"Hide this help message",
  166.23 -              module = "help",
  166.24 -              action = "update",
  166.25 -              params = {
  166.26 -                help_ident = id,
  166.27 -                hide = true
  166.28 -              },
  166.29 -              routing = {
  166.30 -                default = {
  166.31 -                  mode = "redirect",
  166.32 -                  module = request.get_module(),
  166.33 -                  view = request.get_view(),
  166.34 -                  id = param.get_id_cgi(),
  166.35 -                  params = param.get_all_cgi()
  166.36 -                }
  166.37 -              }
  166.38 -            }
  166.39 -          end
  166.40 -        }
  166.41 -        local lang = locale.get("lang")
  166.42 -        local basepath = request.get_app_basepath() 
  166.43 -        local file_name = basepath .. "/locale/help/" .. id .. "." .. lang .. ".txt.html"
  166.44 -        local file = io.open(file_name)
  166.45 -        if file ~= nil then
  166.46 -          local help_text = file:read("*a")
  166.47 -          if #help_text > 0 then
  166.48 -            ui.container{
  166.49 -              attr = { class = "wiki" },
  166.50 -              content = function()
  166.51 -                slot.put(help_text)
  166.52 -              end
  166.53 -            }
  166.54 -          else
  166.55 -            ui.field.text{ value = _("Empty help text: #{id}.#{lang}.txt", { id = id, lang = lang }) }
  166.56 -          end
  166.57 -        else
  166.58 -          ui.field.text{ value = _("Missing help text: #{id}.#{lang}.txt", { id = id, lang = lang }) }
  166.59 -        end
  166.60 -      end
  166.61 -    }
  166.62 -  else
  166.63 -    if util._hidden_helps == nil then
  166.64 -      util._hidden_helps = {}
  166.65 -    end
  166.66 -    util._hidden_helps[#util._hidden_helps+1] = {
  166.67 -      id = id,
  166.68 -      title = title
  166.69 -    }
  166.70 -  end
  166.71 -end
  166.72 \ No newline at end of file
   167.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   167.2 +++ b/env/util/initiative_pie.lua	Thu Jul 10 01:19:48 2014 +0200
   167.3 @@ -0,0 +1,137 @@
   167.4 +function util.initiative_pie(initiative, d, gap)
   167.5 +  if not initiative.issue.closed or not initiative.admitted then
   167.6 +    return
   167.7 +  end
   167.8 +  
   167.9 +  if initiative.issue.voter_count == 0 or initiative.positive_votes == nil or initiative.negative_votes == nil then
  167.10 +    return
  167.11 +  end
  167.12 +  
  167.13 +  local first_preference_votes = initiative.first_preference_votes
  167.14 +  if first_preference_votes == nil then
  167.15 +    first_preference_votes = 0
  167.16 +  end
  167.17 +    
  167.18 +  local d = d or 100
  167.19 +  local gap = gap or d / 20
  167.20 +  
  167.21 +  local r = d/2
  167.22 +  local r_circle = r - gap
  167.23 +  
  167.24 +  local function circle(p)
  167.25 +    return
  167.26 +      gap + 2 * r_circle * ( 1 + math.sin( 2 * math.pi * p ) ) / 2,
  167.27 +      gap + 2 * r_circle * ( 1 - math.cos( 2 * math.pi * p ) ) / 2
  167.28 +  end
  167.29 +  
  167.30 +  local function getpath(start, stop)
  167.31 +    local start_x, start_y = circle(start)
  167.32 +    local stop_x, stop_y = circle(stop)
  167.33 +    local large = stop - start > 0.5 and "1" or "0"
  167.34 +    return "M" .. r .. "," .. r .. " "
  167.35 +        .. "L" .. start_x .. ",".. start_y .. " " .. " "
  167.36 +        .. "A" .. r_circle .. "," .. r_circle .. " 0 " .. large .. ",1 " .. stop_x .. "," .. stop_y .. " "
  167.37 +        .. "z"
  167.38 +  end
  167.39 +  
  167.40 +  local function uniPie(color, content)
  167.41 +    ui.tag {
  167.42 +      tag = "svg",
  167.43 +      attr = {
  167.44 +        class = "initiative_pie",
  167.45 +        width = d .. "px",
  167.46 +        height = d .. "px",
  167.47 +      },
  167.48 +      content = function ()
  167.49 +        ui.tag { tag = "circle", attr = {
  167.50 +          cx=r, cy=r, r=r_circle, fill = color, stroke = "#fff", ["stroke-width"] = "2"
  167.51 +        }, content = function () ui.tag { tag = "title", content = content } end  }
  167.52 +      end
  167.53 +    }
  167.54 +  end
  167.55 +  
  167.56 +  local function piePiece(path, fill, content)
  167.57 +    ui.tag {
  167.58 +      tag = "path",
  167.59 +      attr = {
  167.60 +        d = path,
  167.61 +        fill = fill,
  167.62 +        stroke = "#fff",
  167.63 +        ["stroke-width"] = "2",
  167.64 +        ["stroke-linecap"] = "butt"
  167.65 +      }, 
  167.66 +      content = function ()
  167.67 +        ui.tag {
  167.68 +          tag = "title", 
  167.69 +          content = content
  167.70 +        }
  167.71 +      end  
  167.72 +    }
  167.73 +  end
  167.74 +  
  167.75 +  local function pie(args)
  167.76 +    local offset = args.offset or 0
  167.77 +    local list = {}
  167.78 +    local sum = 0
  167.79 +    for i, element in ipairs(args) do
  167.80 +      element.start = sum + offset
  167.81 +      list[#list+1] = element
  167.82 +      sum = sum + element.value
  167.83 +    end
  167.84 +    
  167.85 +    for i, element in ipairs(list) do
  167.86 +      if element.value == sum then
  167.87 +        uniPie(element.fill, _(element.label, { count = element.value } ))
  167.88 +        return
  167.89 +      end
  167.90 +    end
  167.91 +    ui.tag {
  167.92 +      tag = "svg",
  167.93 +      attr = {
  167.94 +        class = "initiative_pie",
  167.95 +        width = d .. "px",
  167.96 +        height = d .. "px"
  167.97 +      },
  167.98 +      content = function ()
  167.99 +        table.sort(list, function (a, b)
 167.100 +          return a.value < b.value
 167.101 +        end )
 167.102 +        for i, element in ipairs(list) do
 167.103 +          local path = getpath(element.start / sum, (element.start + element.value) / sum)
 167.104 +          local content = _(element.label, { count = element.value })
 167.105 +          piePiece(path, element.fill, content)
 167.106 +        end
 167.107 +      end
 167.108 +    }
 167.109 +  end
 167.110 +  
 167.111 +  local yes1 = first_preference_votes
 167.112 +  local yes = initiative.positive_votes - first_preference_votes
 167.113 +  local neutral = initiative.issue.voter_count - initiative.positive_votes - initiative.negative_votes
 167.114 +  local no = initiative.negative_votes
 167.115 +  
 167.116 +  local sum = yes1 + yes + neutral + no
 167.117 +  
 167.118 +  local q = initiative.issue.policy.direct_majority_num / initiative.issue.policy.direct_majority_den
 167.119 +      
 167.120 +  
 167.121 +  local maxrot = sum * 7 / 12 - no
 167.122 +  
 167.123 +  local offset = 0
 167.124 +  
 167.125 +  if maxrot > 0 then
 167.126 +    offset = math.min (
 167.127 +      maxrot, 
 167.128 +      no * ( 1 / ( 1 / q - 1 ) -1 ) / 2
 167.129 +    )
 167.130 +  end
 167.131 +    
 167.132 +  pie{
 167.133 +    { value = yes1,    fill = "#0a0", label = _"#{count} Yes, first choice" },
 167.134 +    { value = yes,     fill = "#6c6", label = _"#{count} Yes, alternative choice" },
 167.135 +    { value = neutral, fill = "#ccc", label = _"#{count} Neutral" },
 167.136 +    { value = no,      fill = "#c00", label = _"#{count} No" },
 167.137 +    offset = - offset
 167.138 +  }
 167.139 +    
 167.140 +end
 167.141 \ No newline at end of file
   168.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   168.2 +++ b/env/util/micro_avatar.lua	Thu Jul 10 01:19:48 2014 +0200
   168.3 @@ -0,0 +1,49 @@
   168.4 +function util.micro_avatar(member, member_name)
   168.5 +  if type ( member ) == "number" then
   168.6 +    member = {
   168.7 +      id = member,
   168.8 +      name = member_name
   168.9 +    }
  168.10 +  end
  168.11 +  
  168.12 +  function doit()
  168.13 +    if config.fastpath_url_func then
  168.14 +      ui.image{
  168.15 +        attr = {
  168.16 +          title = member.name,
  168.17 +          class = "microAvatar"
  168.18 +        },
  168.19 +        external = config.fastpath_url_func(member.id, "avatar")
  168.20 +      }
  168.21 +    else
  168.22 +      ui.image {
  168.23 +        attr = {
  168.24 +          title = member.name,
  168.25 +          class = "microAvatar"
  168.26 +        },
  168.27 +        module = "member_image",
  168.28 +        view = "show",
  168.29 +        extension = "jpg",
  168.30 +        id = member.id,
  168.31 +        params = {
  168.32 +          image_type = "avatar"
  168.33 +        }
  168.34 +      } 
  168.35 +    end
  168.36 +    ui.tag { tag = "span", content = member.name }
  168.37 +  end
  168.38 +  
  168.39 +  ui.tag {
  168.40 +    attr = { class = "microAvatar" },
  168.41 +    content = function ()
  168.42 +      if app.session:has_access("everything") then
  168.43 +        ui.link {
  168.44 +          module = "member", view = "show", id = member.id,
  168.45 +          content = doit
  168.46 +        }
  168.47 +      else
  168.48 +        ui.tag{ content = doit }
  168.49 +      end
  168.50 +    end
  168.51 +  }
  168.52 +end
   169.1 --- a/locale/Makefile	Thu Jul 10 01:02:43 2014 +0200
   169.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   169.3 @@ -1,18 +0,0 @@
   169.4 -PATH:=$(PATH):/opt/rocketwiki/
   169.5 -
   169.6 -DIRS = help
   169.7 -HTML_SOURCE := $(foreach DIR,$(DIRS),$(wildcard $(DIR)/*.txt))
   169.8 -HTML_HELP := $(HTML_SOURCE:.txt=.txt.html)
   169.9 -TARGET = all
  169.10 -
  169.11 -
  169.12 -%.txt.html: %.txt
  169.13 -	rocketwiki-lqfb < $< > $@
  169.14 -
  169.15 -
  169.16 -help_html: $(HTML_HELP)
  169.17 -
  169.18 -clean:
  169.19 -	rm -f $(HTML_HELP)
  169.20 -
  169.21 -all: help_html
   170.1 --- a/locale/help/area.show.de.txt	Thu Jul 10 01:02:43 2014 +0200
   170.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   170.3 @@ -1,15 +0,0 @@
   170.4 -= Themenbereich =
   170.5 -
   170.6 -Hier finden sich jeweils unter:
   170.7 -- **Letzte Ereignisse:** Alle Ereignisse im Themenbereich
   170.8 -- **Offene Themen:** Alle Themen des Themenbereichs, die zur Zeit offen sind, also Neu, in Diskussion, Eingefroren oder in Abstimmung
   170.9 -- **Geschlossene Themen:** Alle Themen des Themenbereichs, die bereits abgestimmt sind oder die abgebrochen wurden
  170.10 -- **Teilnehmer:** Stimmberechtigte, die sich dazu entschieden haben, sich im Themenbereich einzubringen
  170.11 -- **Delegationen:** Auf Themenbereichsebene gesetzte Delegationen (Delegationen auf darüberliegender Gliederungsebene, sowie Delegationen auf darunterliegender Themenebene werden hier nicht aufgeführt)
  170.12 -
  170.13 -Sofern die Stimmberechtigung in der Gliederung vorhanden ist, kann man sich durch einen Klick auf "An diesem Themengebiet teilnehmen" als Teilnehmer des Themengebietes eintragen. Dies hat folgende Konsequenzen:
  170.14 -- Der jeweilige Themenbereich wird auf der Startseite unter "Meine Themengebiete" angezeigt.
  170.15 -- Man zählt zur Grundgesamtheit der Diskussionsteilnehmer von Themen im Themengebiet. Dies wirkt sich auf das von Initiativen zu erreichende Unterstützerquorum aus.
  170.16 -- Benachrichtigungen zu Ereignissen im jeweiligen Themenbereich werden verschickt, sofern die Benachrichtigungseinstellungen entsprechend eingestellt sind. Die Benachrichtigungseinstellungen finden sich unter "Einstellungen" im Benutzermenü ganz rechts oben.
  170.17 -
  170.18 -Delegationen im Themenbereich wirken sich auf alle Themen aus, bei denen keine abweichende Delegationseinstellung vermerkt ist. Ist keine Delegationseinstellung im Themenbereich vorhanden, gilt ggf. eine Delegation auf Gliederungsebene. Bei eigenem Interesse an einem Thema, wird eine eventuell vorhandene Delegation zunächst ausgesetzt. Ebenso werden Delegationen dort ausgesetzt, wo man selbst an der Endabstimmung teilnimmt.
   171.1 --- a/locale/help/area.show.el.txt	Thu Jul 10 01:02:43 2014 +0200
   171.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   171.3 @@ -1,21 +0,0 @@
   171.4 -==Τομέας==
   171.5 -Παρουσίαση ενός τομέα με τα θέματα που υπάγονται σ' αυτόν. Μπορείτε να αναθέσετε έναν ολόκληρο τομέα σε κάποιο άλλο μέλος από τις επαφές σας, ώστε να σας αντιπροσωπεύει με την ψήφο του στα θέματα του τομέα αυτού. Μπορείτε να ακυρώσετε ή να αλλάξετε τέτοια ανάθεση οποιαδήποτε στιγμή, για όλο τον τομέα ή μόνο για συγκεκριμένα θέματα.
   171.6 -
   171.7 -Εδώ μπορείτε επίσης να δηλώσετε συμμετοχή στον τομέα ή και να ανοίξετε ένα νέο θέμα και να εισηγηθείτε μία πρωτοβουλία.
   171.8 -
   171.9 -Η δήλωση συμμετοχής στον τομέα έχει τις εξής συνέπειες:
  171.10 -- Ο τομέας θα εμφανίζεται στην κεντρική σας σελίδα κάτω από το "Οι τομείς μου"
  171.11 -- Προσμετράστε στο βασικό σύνολο για τις συζητήσεις των θεμάτων. Αυτό έχει επιπτώσεις στην απαρτία υποστηρικτών που πρέπει να συμπληρώσουν οι πρωτοβουλίες.
  171.12 -- Θα λαμβάνετε ειδοποιήσεις μέσω email για τα συμβάντα στον τομέα, εφόσον το έχετε επιλέξει και στις ρυθμίσεις ειδοποιήσεων. Μπορείτε να δείτε και να αλλάξετε τις ρυθμίσεις ειδοποιήσεων πηγαίνοντας στο "Επιλογές", στο μενού χρήστη στην πάνω δεξιά γωνία.
  171.13 -
  171.14 -=Συμβάντα=
  171.15 -Παρουσίαση των γεγονότων στον τομέα, με χρονολογική σειρά.
  171.16 -
  171.17 -=Θέματα=
  171.18 -Όλα τα θέματα που ανήκουν σ' αυτόν τον τομέα, διαχωρισμένα σε <<κλειστά>> που έχουν καταλήξει και σε <<ανοιχτά>>, που βρίσκονται σε διαβούλευση ή ψηφοφορία ή σε κάποιο άλλο στάδιο.
  171.19 -
  171.20 -=Συμμετέχοντες=
  171.21 -Κατάλογος όλων των μελών που έχουν δηλώσει συμμετοχή σε αυτόν τον τομέα.
  171.22 -
  171.23 -=Αναθέσεις=
  171.24 -Παρουσίαση των αναθέσεων για αυτόν τον τομέα. Δείχνει τα μέλη και τους αντιπροσώπους που έχουν ορίσει.
  171.25 \ No newline at end of file
   172.1 --- a/locale/help/area.show.en.txt	Thu Jul 10 01:02:43 2014 +0200
   172.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   172.3 @@ -1,15 +0,0 @@
   172.4 -= Subject area =
   172.5 -
   172.6 -Here you find:
   172.7 -- **Latest events:** Events in this subject area
   172.8 -- **Open issues:** Issues of this subject area, which are currently open, i.e. new, in discussion, frozen or for voting
   172.9 -- **Closed issues:** Issues of this subject area, where voting has been finished, or which have been canceled
  172.10 -- **Participants:** Eligible voters, who decided to participate in this subject area
  172.11 -- **Delegations:** Delegation settings of other members for this subject area (unit delegations and issue delegations are not listed here)
  172.12 -
  172.13 -As long as you're an eligible voter, you can indicate that you want to participate in this subject area. Click on "Participate in this area", if you want to do that. This has the following consequences:
  172.14 -- The subject area will be shown on your homepage under the tab "My areas".
  172.15 -- You are counted for the basic population for issue discussions. This has an impact on the supporter quorum, which initiatives have to reach.
  172.16 -- E-mail notifies about events in the subject area will be sent, as long as your notification settings are configured respectively. Your notification settings can be changed by clicking on "Settings" in the user menu at the upper right corner.
  172.17 -
  172.18 -Your delegation of the subject area has an effect on all issues, where no divergent issue delegation has been set by you. When you do not set a delegation in the subject area, your delegation for the organizational unit may be in effect. If you're interested in an issue yourself, then potentially existent delegations will be postponed until voting. Voting on an issue cancels an existent delegation.
   173.1 --- a/locale/help/area.show.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   173.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   173.3 @@ -1,15 +0,0 @@
   173.4 -= 领域 =
   173.5 -
   173.6 -您所看到的:
   173.7 -- **最新动态:** 此领域的新动态
   173.8 -- **开放性议题:** 目前在此领域仍开放的议题,可能处于新增、讨论中、底定或表决阶段。
   173.9 -- **已结案议题:** 在此领域已经表决或被撤销的议题
  173.10 -- **参与者:** 决定参与此领域的合格投票人
  173.11 -- **委任清单:** 本领域的其他参与者所设置的委任(单位及议题委任不在此列)
  173.12 -
  173.13 -只要您是一个合格投票人,您可设定您是否要参与此领域。若您有此意愿,请点选「参与此领域」。之后将有下列变化:
  173.14 -- 此领域将被显示在您首页的「我的领域」标签下。
  173.15 -- 您将被计入此议题的讨论人数。这将影响提案必须通过的支持者决定门槛。
  173.16 -- 只要您的通知设定允许,您将收到此领域的动态电邮通知。您可点选右上方使用者目录的「设定」连结以更改通知设定。
  173.17 -
  173.18 -您对此领域的委任将影响所有您未设定个别委任的议题,当您不对此领域设定委任,您对组织单位的委任设定将生效。若您关心个别议题,则潜在存在的委任将延后至表决。对个别议题进行表决则取消已设定的委任。
  173.19 \ No newline at end of file
   174.1 --- a/locale/help/area.show.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   174.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   174.3 @@ -1,15 +0,0 @@
   174.4 -= 領域 =
   174.5 -
   174.6 -您所看到的:
   174.7 -- **最新動態:** 此領域的新動態
   174.8 -- **開放性議題:** 目前在此領域仍開放的議題,可能處於新增、討論中、底定或表決階段。
   174.9 -- **已結案議題:** 在此領域已經表決或被撤銷的議題
  174.10 -- **參與者:** 決定參與此領域的合格投票人
  174.11 -- **委任清單:** 本領域的其他參與者所設置的委任(單位及議題委任不在此列)
  174.12 -
  174.13 -只要您是一個合格投票人,您可設定您是否要參與此領域。若您有此意願,請點選「參與此領域」。之後將有下列變化:
  174.14 -- 此領域將被顯示在您首頁的「我的領域」標籤下。
  174.15 -- 您將被計入此議題的討論人數。這將影響提案必須通過的支持者決定門檻。
  174.16 -- 只要您的通知設定允許,您將收到此領域的動態電郵通知。您可點選右上方使用者目錄的「設定」連結以更改通知設定。
  174.17 -
  174.18 -您對此領域的委任將影響所有您未設定個別委任的議題,當您不對此領域設定委任,您對組織單位的委任設定將生效。若您關心個別議題,則潛在存在的委任將延後至表決。對個別議題進行表決則取消已設定的委任。
  174.19 \ No newline at end of file
   175.1 --- a/locale/help/contact.list.de.txt	Thu Jul 10 01:02:43 2014 +0200
   175.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   175.3 @@ -1,4 +0,0 @@
   175.4 -=persönliche Kontaktliste=
   175.5 -Um sie schneller auffinden zu können, kann man andere Mitglieder deiner persönlichen Kontaktliste hinzufügen. Auf der Profilseite des jeweiligen Mitglieds findet sich ein Link zum Hinzufügen. Falls man diesen Kontakt veröffentlicht, können andere sehen, dass dieses Mitglied auf der Kontaktliste vermerkt wurde.
   175.6 -
   175.7 -**Wichtig:** Zur Verbesserung des Bedienkomforts wird beim Delegieren die persönliche Kontaktliste angezeigt. Um an ein Mitglied delegieren zu können, musst es zunächst als Kontakt hinzugefügt werden. Das Löschen eines Kontaktes führt jedoch nicht zum Widerruf der Delegation.
   176.1 --- a/locale/help/contact.list.el.txt	Thu Jul 10 01:02:43 2014 +0200
   176.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   176.3 @@ -1,10 +0,0 @@
   176.4 -==Προσωπική λίστα επαφών==
   176.5 -Μπορείτε να προσθέσετε μέλη στις επαφές σας ώστε να τα βρίσκετε γρηγορότερα. Αυτό γίνεται με ένα σύνδεσμο που θα βρείτε στη σελίδα προφίλ του κάθε μέλους.
   176.6 -
   176.7 -//Για να δείτε όλα τα εγγεγραμμένα μέλη πηγαίνετε στην κεντρική σελίδα και πατήστε στο <<Μέλη>>.//
   176.8 -
   176.9 -=Δημοσίευση=
  176.10 -Η λίστα των επαφών σας είναι προσωπική και δεν εμφανίζεται σε άλλους. Εάν επιλέξετε να δημοσιεύσετε κάποια από τα μέλη στις επαφές σας, τα μέλη αυτά θα εμφανίζονται δημόσια στη λίστα των επαφών σας.
  176.11 -
  176.12 -=Αναθέσεις=
  176.13 -Για να μπορέσετε να αναθέσετε κάποια <<ενότητα>>, <<τομέα>> ή <<θέμα>> σε ένα μέλος θα πρέπει να το προσθέσετε πρώτα στις επαφές σας ώστε να εμφανίζεται στη λίστα της εντολής ανάθεσης. Αφαίρεση μελών από τις επαφές σας δεν ακυρώνει αναθέσεις που μπορεί να έχουν γίνει.
   177.1 --- a/locale/help/contact.list.en.txt	Thu Jul 10 01:02:43 2014 +0200
   177.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   177.3 @@ -1,4 +0,0 @@
   177.4 -=personal list of contacts=
   177.5 -In order to find other members more quickly, you can add them to your personal list of contacts. On the profile page of the respective member you will find a link for doing so. If you publish a contact, others can see this member as listed on your list of contacts.
   177.6 -
   177.7 -**Important:** For improved ease-of-use your list of contacts will be shown to you when you delegate. In order to delegate to a member, you must first add him or her to your contacts. Removing a contact does not revoke the delegation, though.
   178.1 --- a/locale/help/contact.list.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   178.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   178.3 @@ -1,4 +0,0 @@
   178.4 -=Persona kontaktlisto=
   178.5 -Vi povas aldoni aliajn membrojn al via persona kontaktlisto, por ke vi trovu ilin pli rapide. En la profilpaĝo de la respektiva membro vi trovas ligilon por aldoni. Se vi publikigas kontakton, aliaj povas vidi, ke tiu ĉi membro estas en via kontaktlisto. 
   178.6 -
   178.7 -**Grave:** Por pliigi vian komforton, oni montras al vi dum delegado vian personan kontaktliston. Por povi delegi al membro vi devas unue aldoni lin kiel kontakton. Nuligi kontakton tamen ne kaŭzas revokon de la delegacio.
   179.1 --- a/locale/help/contact.list.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   179.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   179.3 @@ -1,4 +0,0 @@
   179.4 -=个人通讯录列表=
   179.5 -为了更快速找到其他成员,您可将他们加入您的个人通讯录。您可在个别成员的个人简介页找到连结以加入。若您公开一个连络人,其他人将可看到这位成员被列在您的通讯录中。
   179.6 -
   179.7 -**重要事项:** 为了使用方便,您的通讯录列表将会在您指定委任时显示。要委任一位成员,您必须先加他为您的联络人。但将委任人自通讯录移除并不会撤回委任。
   179.8 \ No newline at end of file
   180.1 --- a/locale/help/contact.list.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   180.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   180.3 @@ -1,4 +0,0 @@
   180.4 -=個人通訊錄列表=
   180.5 -為了更快速找到其他成員,您可將他們加入您的個人通訊錄。您可在個別成員的個人簡介頁找到連結以加入。若您公開一個連絡人,其他人將可看到這位成員被列在您的通訊錄中。
   180.6 -
   180.7 -**重要事項:** 為了使用方便,您的通訊錄列表將會在您指定委任時顯示。要委任一位成員,您必須先加他為您的聯絡人。但將委任人自通訊錄移除並不會撤回委任。
   180.8 \ No newline at end of file
   181.1 --- a/locale/help/delegation.new.area.de.txt	Thu Jul 10 01:02:43 2014 +0200
   181.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   181.3 @@ -1,5 +0,0 @@
   181.4 -= Delegation für diesen Themenbereich =
   181.5 -
   181.6 -Man kann die eigene Stimme für diesen Themenbereich (unabhängig von der Mitgliedschaft im Themenbereich) an eine Person in der persönlichen Kontaktliste delegieren. Diese Delegation hat gegenüber einer eventuell vorhandenen Gliederungsdelegation Vorrang, gilt jedoch nur dann, wenn keine eigene Beteiligung am Thema besteht bzw. nicht selbst abgestimmt wird und man für das jeweilige Thema keine themenspezifische Delegation erteilt hat.
   181.7 -
   181.8 -**Achtung:** Delegieren kann man nur an Mitglieder in der eigenen Kontaktliste. Um ein Mitglied zur Kontaktliste hinzuzufügen ist die Seite des jeweiligen Mitglieds aufzurufen. Diese findet man z.B. in der jeweiligen Gliederung unter dem Reiter ,,Stimmberechtigte''. Durch einen Klick auf den Benutzer gelangt man zur Seite des jeweiligen Mitglieds, auf der man dieses Mitglied zu den persönlichen Kontakten hinzufügen kann.
   182.1 --- a/locale/help/delegation.new.area.el.txt	Thu Jul 10 01:02:43 2014 +0200
   182.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   182.3 @@ -1,4 +0,0 @@
   182.4 -=Ανάθεση τομέα=
   182.5 -Μπορείτε να εκχωρήσετε την ψήφο σας για αυτόν τον τομέα (ανεξάρτητα από τη συμμετοχή σας στον τομέα) σε ένα άτομο από τη λίστα επαφών σας. Μπορείτε να προσθέσετε άτομα στις επαφές σας πηγαίνοντας στην περιοχή <<Μέλη>>, στην κεντρική σελίδα ή στην περιοχή <<Συμμετέχοντες>> του τρέχοντος τομέα.
   182.6 -
   182.7 -Η ανάθεση αυτή υπερισχύει μιας πιθανής καθολικής ανάθεσης αλλά μόνο στην περίπτωση που δεν συμμετέχετε προσωπικά και όταν πρόκειται για κάποιο <<θέμα>> το οποίο δεν έχετε αναθέσει πιο συγκεκριμένα. Για να αναθέσετε συγκεκριμένα θέματα του τομέα, παρακαλώ πηγαίνετε στη σελίδα τους.
   182.8 \ No newline at end of file
   183.1 --- a/locale/help/delegation.new.area.en.txt	Thu Jul 10 01:02:43 2014 +0200
   183.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   183.3 @@ -1,5 +0,0 @@
   183.4 -= Delegation for this area =
   183.5 -
   183.6 -You can delegate your vote for this area (independent of your membership in the area) to a person on your contact list. This delegation takes precedence over a potentially existing global delegation, but only, if you don't participate yourself and if you have not given a issue-specific delegation for the respective issue. Please go to the respective issue page for making issue-specific delegations.
   183.7 -
   183.8 -**Notice:** You can only delegate to members, who you have added to your list of contacts. You can find other members under the tabulator ""Eligible voters"" in their corresponding unit. Click on the member to visit their member page, then click on ""Add to my contacts"" to add this member to your personal contact list.
   184.1 --- a/locale/help/delegation.new.area.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   184.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   184.3 @@ -1,5 +0,0 @@
   184.4 -= Delegacio pri tiu ĉi temaro =
   184.5 -
   184.6 -Vi povas delegi vian voĉon por tiu ĉi temaro (sendepende de via membreco en tiu ĉi temaro) al persono en via kontaktlisto. Tiu ĉi delegacio rangas antaŭ ebla ĝenerala delegacio, sed nur se vi ne mem partoprenas kaj vi ne delegis teman delegacion pri la respektiva temo. Por tema delegado bonvolu ŝanĝi al la respektiva tempaĝo. Vi povas delegi nur al membroj de via kontaktlisto.
   184.7 -
   184.8 -**Notice:** You can only delegate to members, who you have added to your list of contacts. You can find other members under the tabulator ""Eligible voters"" in their corresponding unit. Click on the member to visit their member page, then click on ""Add to my contacts"" to add this member to your personal contact list.
   185.1 --- a/locale/help/delegation.new.area.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   185.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   185.3 @@ -1,5 +0,0 @@
   185.4 -= 领域委任 =
   185.5 -
   185.6 -不论您是否有此领域的成员身份,您可委任您的表决给您通讯录中的一位联络人。此委任,在您本身不参与表决或您并未对个别议题指定委任的状况下,会优先于一个可能已存在的全面委任。若您要对个别议题进行委任,请前往该议题页面。
   185.7 -
   185.8 -**注意:** 您只可委任给您已加入通讯录的成员。 ?您可在各相关单位页面的「合格投票人」页签找到其他成员。点击各成员连结以拜访他们的成员专页,然后点击「加入通讯录」将此成员加入您的个人联络人列表。
   185.9 \ No newline at end of file
   186.1 --- a/locale/help/delegation.new.area.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   186.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   186.3 @@ -1,5 +0,0 @@
   186.4 -= 領域委任 =
   186.5 -
   186.6 -不論您是否有此領域的成員身份,您可委任您的表決給您通訊錄中的一位聯絡人。此委任,在您本身不參與表決或您並未對個別議題指定委任的狀況下,會優先於一個可能已存在的全面委任。若您要對個別議題進行委任,請前往該議題頁面。
   186.7 -
   186.8 -**注意:** 您只可委任給您已加入通訊錄的成員。您可在各相關單位頁面的「合格投票人」頁籤找到其他成員。點擊各成員連結以拜訪他們的成員專頁,然後點擊「加入通訊錄」將此成員加入您的個人聯絡人列表。
   186.9 \ No newline at end of file
   187.1 --- a/locale/help/delegation.new.issue.de.txt	Thu Jul 10 01:02:43 2014 +0200
   187.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   187.3 @@ -1,4 +0,0 @@
   187.4 -= Delegation für dieses Thema =
   187.5 -Eine Delegation zu diesem Thema geht einer eventuell vorhandenen globalen Delegation und/oder Delegation für den übergeordneten Themenbereich vor. Bei angemeldetem Interesse werden ausgehende Delegationen während der Phasen ,,Neu'', ,,Diskussion'' und ,,Eingefroren'' ausgesetzt, gelten aber in der Endabstimmung, sofern nicht selbst abgestimmt wird.
   187.6 -
   187.7 -**Achtung:** Delegieren kannst man nur an Mitglieder in der eigenen Kontaktliste. Um ein Mitglied zur Kontaktliste hinzuzufügen ist die Seite des jeweiligen Mitglieds aufzurufen. Diese findet man z.B. in der jeweiligen Gliederung unter dem Reiter ,,Stimmberechtigte''. Durch einen Klick auf den Benutzer gelangt man zur Seite des jeweiligen Mitglieds, auf der man dieses Mitglied zu den persönlichen Kontakten hinzufügen kann.
   188.1 --- a/locale/help/delegation.new.issue.el.txt	Thu Jul 10 01:02:43 2014 +0200
   188.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   188.3 @@ -1,4 +0,0 @@
   188.4 -=Ανάθεση θέματος=
   188.5 -Μπορείτε να εκχωρήσετε την ψήφο σας για αυτό το θέμα σε κάποιο άτομο από τη λίστα επαφών σας. Για να προσθέσετε άτομα στις επαφές σας πηγαίνετε στην περιοχή <<Μέλη>>, στην κεντρική σελίδα.
   188.6 -
   188.7 -Η ανάθεση αυτή υπερισχύει μιας πιθανής καθολικής ανάθεσης ή ανάθεσης τομέα ή ενότητας που μπορεί να ισχύει. Εάν έχετε δηλώσει το ενδιαφέρον σας για αυτό το θέμα, η εξερχόμενη ανάθεση //(δηλαδή όταν εσείς επιλέγετε κάποιον άλλο ως αντιπρόσωπό σας για το <<θέμα>>)// θα ανασταλεί κατά το στάδιο συζήτησης, αλλά θα είναι ενεργή κατά την ψηφοφορία.
   189.1 --- a/locale/help/delegation.new.issue.en.txt	Thu Jul 10 01:02:43 2014 +0200
   189.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   189.3 @@ -1,5 +0,0 @@
   189.4 -= Delegation for this issue =
   189.5 -
   189.6 -A delegation for this issue takes precedence over a potentially existing global delegation and/or a delegation for the superior area. If you added your interest outgoing delegations will be suspended during the discussion phase, but will be active during the final voting. You can only delegate to members on your contact list. You can extend the contact list anytime in the ,,Members'' area.
   189.7 -
   189.8 -**Notice:** You can only delegate to members, who you have added to your list of contacts. You can find other members under the tabulator ""Eligible voters"" in their corresponding unit. Click on the member to visit their member page, then click on ""Add to my contacts"" to add this member to your personal contact list.
   190.1 --- a/locale/help/delegation.new.issue.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   190.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   190.3 @@ -1,5 +0,0 @@
   190.4 -= Delegacio pri tiu ĉi temo =
   190.5 -
   190.6 -Delegacio pri tiu ĉi temo rangas antaŭ ebla ĝenerala delegacio kaŭ delegacio pri la supera temaro. Kaze de anoncita intereso, la elirantaj delegacioj estas malebligitaj dum la diskutfazo, sed validas ĉe la fina voĉdono. Vi povas delegi nur al membroj de via kontaktlisto.
   190.7 -
   190.8 -**Notice:** You can only delegate to members, who you have added to your list of contacts. You can find other members under the tabulator ""Eligible voters"" in their corresponding unit. Click on the member to visit their member page, then click on ""Add to my contacts"" to add this member to your personal contact list.
   191.1 --- a/locale/help/delegation.new.issue.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   191.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   191.3 @@ -1,5 +0,0 @@
   191.4 -= 议题委任 =
   191.5 -
   191.6 -对此议题的委任会优先于可能已存在的全面委任或更高阶的领域委任。若您关心此议题,则所送出的委任将在讨论期被暂停,直到最后表决时再次启用。您只能委任给您通讯录中的联络人。您可在任何时候自「成员」页面延伸您的通讯录。
   191.7 -
   191.8 -**注意:** 您只可委任给您已加入通讯录的成员。 ?您可在各相关单位页面的「合格投票人」页签找到其他成员。点击各成员连结以拜访他们的成员专页,然后点击「加入通讯录」将此成员加入您的个人联络人列表。
   191.9 \ No newline at end of file
   192.1 --- a/locale/help/delegation.new.issue.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   192.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   192.3 @@ -1,5 +0,0 @@
   192.4 -= 議題委任 =
   192.5 -
   192.6 -對此議題的委任會優先於可能已存在的全面委任或更高階的領域委任。若您關心此議題,則所送出的委任將在討論期被暫停,直到最後表決時再次啟用。您只能委任給您通訊錄中的聯絡人。您可在任何時候自「成員」頁面延伸您的通訊錄。
   192.7 -
   192.8 -**注意:** 您只可委任給您已加入通訊錄的成員。您可在各相關單位頁面的「合格投票人」頁籤找到其他成員。點擊各成員連結以拜訪他們的成員專頁,然後點擊「加入通訊錄」將此成員加入您的個人聯絡人列表。
   192.9 \ No newline at end of file
   193.1 --- a/locale/help/delegation.new.unit.de.txt	Thu Jul 10 01:02:43 2014 +0200
   193.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   193.3 @@ -1,5 +0,0 @@
   193.4 -= Delegation für Gliederung =
   193.5 -
   193.6 -Die Delegation für eine Gliederung gilt immer dann, wenn man sich nicht selbst beteiligt und es keine Delegation auf der Ebene des jeweiligen Themenbereichs oder des Themas gibt. Beachte, dass Delegationen für eine übergeordnete Gliederungsebene nicht automatisch für untergeordnete Gliederungsebenen gelten. 
   193.7 -
   193.8 -**Achtung:** Delegieren kannst man nur an Mitglieder in der eigenen Kontaktliste. Um ein Mitglied zur Kontaktliste hinzuzufügen ist die Seite des jeweiligen Mitglieds aufzurufen. Diese findet man z.B. in der jeweiligen Gliederung unter dem Reiter ,,Stimmberechtigte''. Durch einen Klick auf den Benutzer gelangt man zur Seite des jeweiligen Mitglieds, auf der man dieses Mitglied zu den persönlichen Kontakten hinzufügen kann.
   194.1 --- a/locale/help/delegation.new.unit.el.txt	Thu Jul 10 01:02:43 2014 +0200
   194.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   194.3 @@ -1,6 +0,0 @@
   194.4 -=Ανάθεση ενότητας=
   194.5 -Μπορείτε να εκχωρήσετε την ψήφο σας για αυτήν την ενότητα σε κάποιο άτομο από τη λίστα επαφών σας. Για να προσθέσετε άτομα στις επαφές σας πηγαίνετε στην περιοχή <<Μέλη>>, στην κεντρική σελίδα.
   194.6 -
   194.7 -Η ανάθεση αυτή ισχύει σε κάθε περίπτωση που δεν συμμετέχετε προσωπικά και δεν υπάρχει πιο εξειδικευμένη ανάθεση σε επίπεδο <<τομέα>> ή <<θέματος>>.
   194.8 -
   194.9 -Η ανάθεση μίας ενότητας δεν κληρονομείται αυτόματα από πιθανές υπο-ενότητές της.
  194.10 \ No newline at end of file
   195.1 --- a/locale/help/delegation.new.unit.en.txt	Thu Jul 10 01:02:43 2014 +0200
   195.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   195.3 @@ -1,5 +0,0 @@
   195.4 -= Unit delegation =
   195.5 -
   195.6 -A unit delegation is always active if you don't participate yourself and there is no delegation on the level of the respective area or issue. Note that unit delegations for a superordinate unit are not automatically inherited to subdivisions.
   195.7 -
   195.8 -**Notice:** You can only delegate to members, who you have added to your list of contacts. You can find other members under the tabulator ""Eligible voters"" in their corresponding unit. Click on the member to visit their member page, then click on ""Add to my contacts"" to add this member to your personal contact list.
   196.1 --- a/locale/help/delegation.new.unit.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   196.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   196.3 @@ -1,5 +0,0 @@
   196.4 -= 单位委任 =
   196.5 -
   196.6 -若您本身并未直接参与(关心)特定议题或是设定特定领域或议题的委任,单位委任就总是有效的。请注意对一个较高层的单位委任并不自动传承给其次级单位。
   196.7 -
   196.8 -**注意:** 您只可委任给您已加入通讯录的成员。 ?您可在各相关单位页面的「合格投票人」页签找到其他成员。点击各成员连结以拜访他们的成员专页,然后点击「加入通讯录」将此成员加入您的个人联络人列表。
   196.9 \ No newline at end of file
   197.1 --- a/locale/help/delegation.new.unit.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   197.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   197.3 @@ -1,5 +0,0 @@
   197.4 -= 單位委任 =
   197.5 -
   197.6 -若您本身並未直接參與(關心)特定議題或是設定特定領域或議題的委任,單位委任就總是有效的。請注意對一個較高層的單位委任並不自動傳承給其次級單位。
   197.7 -
   197.8 -**注意:** 您只可委任給您已加入通訊錄的成員。您可在各相關單位頁面的「合格投票人」頁籤找到其他成員。點擊各成員連結以拜訪他們的成員專頁,然後點擊「加入通訊錄」將此成員加入您的個人聯絡人列表。
   198.1 --- a/locale/help/index.check_delegations.de.txt	Thu Jul 10 01:02:43 2014 +0200
   198.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   198.3 @@ -1,1 +0,0 @@
   198.4 -Dieses System ist so konfiguriert, dass Teilnehmer aufgefordert werden ihre Delegationen für Gliederungen und Themengebiete regelmäßig zu überprüfen und zu bestätigen. Hierzu sind diese in der folgenden Liste aufgeführt. Ein Klick auf "Delegationsprüfung abschließen" vervollständigt den Vorgang.
   198.5 \ No newline at end of file
   199.1 --- a/locale/help/index.check_delegations.en.txt	Thu Jul 10 01:02:43 2014 +0200
   199.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   199.3 @@ -1,1 +0,0 @@
   199.4 -This system is configured to advise members to check and confirm their unit and area delegations regularly. To do so please check your outgoing delegations for units and areas as listed below. Click on "Finish delegation check" to complete this procedure.
   199.5 \ No newline at end of file
   200.1 --- a/locale/help/index.check_delegations_hard.de.txt	Thu Jul 10 01:02:43 2014 +0200
   200.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   200.3 @@ -1,1 +0,0 @@
   200.4 -Dieses System ist so konfiguriert, dass Teilnehmer gezwungen sind ihre Delegationen für Gliederungen und Themengebiete regelmäßig zu überprüfen und zu bestätigen. Hierzu sind diese in der folgenden Liste aufgeführt. Ein Klick auf "Delegationsprüfung abschließen" vervollständigt den Vorgang.
   200.5 \ No newline at end of file
   201.1 --- a/locale/help/index.check_delegations_hard.en.txt	Thu Jul 10 01:02:43 2014 +0200
   201.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   201.3 @@ -1,1 +0,0 @@
   201.4 -This system is configured to enforce members to check and confirm their unit and area delegations regularly. To do so please check your outgoing delegations for units and areas as listed below. Click on "Finish delegation check" to complete this procedure. 
   201.5 \ No newline at end of file
   202.1 --- a/locale/help/index.download.de.txt	Thu Jul 10 01:02:43 2014 +0200
   202.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   202.3 @@ -1,3 +0,0 @@
   202.4 -= Download der Datenbank =
   202.5 -
   202.6 -Im Interesse der Nachvollziehbarkeit ist es jedem Mitglied möglich, eine Kopie der gesamten Datenbank herunterzuladen. Hierbei werden jedoch aus Sicherheits- und Datenschutzgründen bestimmte Informationen (z.B. Passwörter und E-Mail-Adressen) entfernt. Das Dateiformat ist gzip-komprimiertes SQL für die Datenbank PostgreSQL.
   203.1 --- a/locale/help/index.download.el.txt	Thu Jul 10 01:02:43 2014 +0200
   203.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   203.3 @@ -1,4 +0,0 @@
   203.4 -==Λήψη βάσης δεδομένων==
   203.5 -Οποιοδήποτε μέλος μπορεί να κατεβάσει ένα αντίγραφο ολόκληρης της βάσης δεδομένων και να το ελέγξει. Για λόγους ασφαλείας και προστασίας προσωπικών δεδομένων, κάποια στοιχεία (π.χ. κωδικοί πρόσβασης και διευθύνσεις email) θα λείπουν.
   203.6 -
   203.7 -Τα δεδομένα είναι σε μορφή SQL (για PostgreSQL) και είναι συμπιεσμένα με το gzip.
   204.1 --- a/locale/help/index.download.en.txt	Thu Jul 10 01:02:43 2014 +0200
   204.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   204.3 @@ -1,3 +0,0 @@
   204.4 -= Database download =
   204.5 -
   204.6 -For auditability reasons all members can download a copy of the entire database. But for security and data privacy reasons certain data (e.g. passwords and email addresses) will be lacking. The data format is SQL as used for the PostgreSQL database compressed with gzip.
   205.1 --- a/locale/help/index.download.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   205.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   205.3 @@ -1,3 +0,0 @@
   205.4 -= Elŝuto de la datumbazo =
   205.5 -
   205.6 -Por plua evaluado ĉiu membro povas elŝuti kopion de la tuta datumbazo. Ĉe tio tamen certaj informoj (ekzemple pasvortoj kaj retpoŝtadresoj) estas forviŝitaj pro sekurecaj kaj datumprotektaj kialoj. La datumformato estas gzip-kunpremita SQL por la datumbazo PostgreSQL.
   206.1 --- a/locale/help/index.download.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   206.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   206.3 @@ -1,3 +0,0 @@
   206.4 -= 下载资料库 =
   206.5 -
   206.6 -为了可审查性考量,所有成员可下载整个资料库的一份备份。但为了安全及资料隐私考量,某些资料(例如:密码及电邮地址)将从缺。资料格式为如同 PostgreSQL 资料库所使用的 SQL,并使用 gzip 压缩。
   206.7 \ No newline at end of file
   207.1 --- a/locale/help/index.download.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   207.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   207.3 @@ -1,3 +0,0 @@
   207.4 -= 下載資料庫 =
   207.5 -
   207.6 -為了可審查性考量,所有成員可下載整個資料庫的一份備份。但為了安全及資料隱私考量,某些資料(例如:密碼及電郵地址)將從缺。資料格式為如同 PostgreSQL 資料庫所使用的 SQL,並使用 gzip 壓縮。
   207.7 \ No newline at end of file
   208.1 --- a/locale/help/index.index.de.txt	Thu Jul 10 01:02:43 2014 +0200
   208.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   208.3 @@ -1,12 +0,0 @@
   208.4 -= Willkommen bei LiquidFeedback und auf deiner Startseite =
   208.5 -Überall im System finden sich Kästen wie dieser mit Hilfetexten. Man kann jeden Hilfetext mit einem Klick auf "Diesen Hilfetext ausblenden" rechts oben im gelben Kasten ausblenden und durch einen Klick auf das kleine blaue Fragezeichen oben in der Menüzeile wieder einblenden.
   208.6 -
   208.7 -Unten finden sich folgende Ansichten:
   208.8 -- **Startseite:** Eine Unterauswahl zwischen:
   208.9 --- **Meine Themengebiete:** Themenbereiche, an denen teilgenommen wird
  208.10 --- **Alle Themengebiete in meinen Gliederungen:** alle Themenbereiche in Gliederungen mit Stimmberechtigung
  208.11 --- **Alle Gliederungen:** Alle Gliederungen, unabhängig von der Stimmberechtigung
  208.12 -- **Letzte Ereignisse:** Ereignisse aus den eigenen Themenbereichen und Themen sowie die globale Zeitlinie
  208.13 -- **Offene Themen:** Alle Themen, die zur Zeit offen sind, also Neu, in Diskussion, Eingefroren oder in Abstimmung
  208.14 -- **Geschlossene Themen:** Alle Themen, die bereits abgestimmt sind oder die abgebrochen wurden
  208.15 -- **Mitglieder:** Alle aktiven Mitglieder. Nach einem Klick auf ein bestimmtes Mitglied kann man dieses zur persönlichen Kontaktliste hinzufügen, um später an dieses Mitglied delegieren zu können.
   209.1 --- a/locale/help/index.index.el.txt	Thu Jul 10 01:02:43 2014 +0200
   209.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   209.3 @@ -1,12 +0,0 @@
   209.4 -=Καλώς ήρθατε στο Liquid Feedback και στην αρχική σας σελίδα=
   209.5 -Αυτά τα κίτρινα πλαίσια με τα βοηθητικά κείμενα θα σας ακολουθούν μέχρι να τα αποκρύψετε σταδιακά, ενώ αν χρειαστεί μπορείτε να τα επαναφέρετε εύκολα κάνοντας κλικ στο εικονίδιο βοήθειας.
   209.6 -
   209.7 -Εδώ θα βρείτε:
   209.8 -
   209.9 -- Κεντρική Σελίδα
  209.10 --- Τους τομείς που σας ενδιαφέρουν
  209.11 --- Όλους τους τομείς στις ενότητες που έχετε δικαίωμα ψήφου
  209.12 --- Όλες τις ενότητες
  209.13 -- Πρόσφατα συμβάντα από τους τομείς που σας ενδιαφέρουν καθώς και σε όλο το σύστημα
  209.14 -- Όλα τα θέματα, διαχωρισμένα σε <<κλειστά>> που έχουν καταλήξει και σε <<ανοιχτά>> που βρίσκονται σε διαβούλευση ή ψηφοφορία ή σε κάποιο άλλο στάδιο.
  209.15 -- Όλα τα ενεργά μέλη, τα οποία μπορείτε να προσθέσετε στις επαφές σας ώστε να μπορείτε να τους ορίσετε ως αντιπροσώπους σας αναθέτοντάς τους κάποια ενότητα, τομέα ή συγκεκριμένο θέμα.
   210.1 --- a/locale/help/index.index.en.txt	Thu Jul 10 01:02:43 2014 +0200
   210.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   210.3 @@ -1,12 +0,0 @@
   210.4 -= Welcome to LiquidFeedback and your homepage =
   210.5 -All over the system, you'll find these boxes with help texts. You can switch off each help text, by clicking on "hide this help message" in the upper right corner of the yellow box, and switch it on again, by clicking on the small blue question mark in the menu bar above.
   210.6 -
   210.7 -Below you find: 
   210.8 -- **Home:**
   210.9 --- **My areas:** subject areas you want to participate in
  210.10 --- **All areas in my units:** All subject areas of those organizational units you're eligible voter in
  210.11 --- **All units:** All organizational units
  210.12 -- **Latest events:** Events in your subject areas and your issues, as well as the global timeline
  210.13 -- **Open issues:** All issues, which are currently open, i.e. new, in discussion, frozen or for voting
  210.14 -- **Closed issues:** All issues, where voting has been finished, or which have been canceled
  210.15 -- **Members:** All active members. After you clicking on a particular member, you can add this member to your personal contact list, in order to be able to delegate to that member.
   211.1 --- a/locale/help/index.index.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   211.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   211.3 @@ -1,12 +0,0 @@
   211.4 -= 欢迎莅临 LiquidFeedback 及您的首页 =
   211.5 -在整个系统内,您将看到这些说明文件的框架。您可点击黄色框架右上角的「隐藏此说明文件」来个别关闭说明文件,或点击上方选单栏的小蓝问号圈以再次启用。
   211.6 -
   211.7 -以下您将看到:
   211.8 -- **首页:**
   211.9 --- **我的领域:** 您想参与的主题领域
  211.10 --- **我单位中所有领域:** 所有您为合格投票人的组织单位中的主题领域
  211.11 --- **所有单位:** 所有的组织性单位
  211.12 -- **最新动态:** 您的领域及议题的动态,以及完整的时间轴显示。
  211.13 -- **开放性议题:** 所有目前仍开放的议题,意即:递交期议题、讨论期议题、底定期议题或表决中议题。
  211.14 -- **已结案议题:** 所有表决已完成或是已被取消的议题。
  211.15 -- **成员** 所有活动的成员。您可点选特定成员,加入您的通讯录,便得以委任给该成员。
  211.16 \ No newline at end of file
   212.1 --- a/locale/help/index.index.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   212.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   212.3 @@ -1,12 +0,0 @@
   212.4 -= 歡迎蒞臨 LiquidFeedback 及您的首頁 =
   212.5 -在整個系統內,您將看到這些說明文件的框架。您可點擊黃色框架右上角的「隱藏此說明文件」來個別關閉說明文件,或點擊上方選單欄的小藍問號圈以再次啓用。
   212.6 -
   212.7 -以下您將看到: 
   212.8 -- **首頁:**
   212.9 --- **我的領域:** 您想參與的主題領域
  212.10 --- **我單位中所有領域:** 所有您為合格投票人的組織單位中的主題領域
  212.11 --- **所有單位:** 所有的組織性單位
  212.12 -- **最新動態:** 您的領域及議題的動態,以及完整的時間軸顯示。
  212.13 -- **開放性議題:** 所有目前仍開放的議題,意即:遞交期議題、討論期議題、底定期議題或表決中議題。
  212.14 -- **已結案議題:** 所有表決已完成或是已被取消的議題。
  212.15 -- **成員** 所有活動的成員。您可點選特定成員,加入您的通訊錄,便得以委任給該成員。
   213.1 --- a/locale/help/initiative.add_initiator.de.txt	Thu Jul 10 01:02:43 2014 +0200
   213.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   213.3 @@ -1,3 +0,0 @@
   213.4 -= Initiator einladen =
   213.5 -
   213.6 -Hier kannst du eine Person aus deiner Kontaktliste zur gleichberechtigten Mitarbeit am Entwurf einladen. Der eingeladene muss die Einladung erst akzeptieren, bevor er als weiterer Initiator gilt (und angezeigt wird). **Vorsicht:** Alle Initiatoren haben die gleichen Rechte und können andere Initiatoren entfernen.
   214.1 --- a/locale/help/initiative.add_initiator.el.txt	Thu Jul 10 01:02:43 2014 +0200
   214.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   214.3 @@ -1,4 +0,0 @@
   214.4 -==Πρόσκληση νέου εισηγητή==
   214.5 -Εδώ μπορείτε να προσκαλέσετε ένα άτομο από τη λίστα επαφών σας για να συνεργαστείτε με ίσα δικαιώματα στο προσχέδιο. Το μέλος που θα καλέσετε πρέπει πρώτα να αποδεχτεί την πρόσκληση για να γίνει και να εμφανίζεται ως εισηγητής.
   214.6 -
   214.7 -**Προσοχή:** Όλοι οι εισηγητές έχουν τα ίδια δικαιώματα και μπορούν να αφαιρέσουν άλλους εισηγητές.
   214.8 \ No newline at end of file
   215.1 --- a/locale/help/initiative.add_initiator.en.txt	Thu Jul 10 01:02:43 2014 +0200
   215.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   215.3 @@ -1,3 +0,0 @@
   215.4 -= Invite initiator =
   215.5 -
   215.6 -Here you can invite a person on your contact list to collaborate with equal rights on the draft. The invited member must first accept the invitation in order to become an initiator (and be displayed as such). **Attention:** All initiators have the same rights and can remove other initiators.
   216.1 --- a/locale/help/initiative.add_initiator.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   216.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   216.3 @@ -1,3 +0,0 @@
   216.4 -= Inviti inicionton =
   216.5 -
   216.6 -Ĉi tie vi povas inviti personon de via kontaklisto al samrajta kunlaboro pri via skizo. La invitito devas unue akcepti la inviton, antaŭ ol li estas plua iniciinto (kaj estas listigita). **Atentu:** Ĉiuj iniciintoj havas la samajn rajtojn kaj povas forviŝi aliajn iniciintojn. 
   217.1 --- a/locale/help/initiative.add_initiator.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   217.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   217.3 @@ -1,3 +0,0 @@
   217.4 -= 邀请发起者 =
   217.5 -
   217.6 -在此您可邀请一位在您通讯录中的联络人来平权合作草案的编辑。被邀请的成员必须首先接受邀请才会成为(并被列为)发起者。 **注意:** 所有发起者有一样的权利并可移除其他发起者。
   217.7 \ No newline at end of file
   218.1 --- a/locale/help/initiative.add_initiator.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   218.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   218.3 @@ -1,3 +0,0 @@
   218.4 -= 邀請發起者 =
   218.5 -
   218.6 -在此您可邀請一位在您通訊錄中的聯絡人來平權合作草案的編輯。被邀請的成員必須首先接受邀請才會成為(並被列為)發起者。 **注意:** 所有發起者有一樣的權利並可移除其他發起者。
   219.1 --- a/locale/help/initiative.remove_initiator.de.txt	Thu Jul 10 01:02:43 2014 +0200
   219.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   219.3 @@ -1,3 +0,0 @@
   219.4 -= Initiator entfernen =
   219.5 -
   219.6 -Du kannst dich oder einen anderen Initiator entfernen, sofern nach dem Entfernen noch mindestens ein Initiator existiert. Um die Initiative insgesamt aufzugeben, wähle bitte ,,Initiative zurückziehen''.
   220.1 --- a/locale/help/initiative.remove_initiator.el.txt	Thu Jul 10 01:02:43 2014 +0200
   220.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   220.3 @@ -1,2 +0,0 @@
   220.4 -==Αφαίρεση εισηγητή==
   220.5 -Μπορείτε να αφαιρέσετε τον εαυτό σας ή κάποιον άλλο εισηγητή μόνο εάν θα παραμείνει τουλάχιστον ένας. Για να ανακαλέσετε όλη την πρωτοβουλία, παρακαλώ επιλέξτε <<Ανάκληση πρωτοβουλίας>>.
   220.6 \ No newline at end of file
   221.1 --- a/locale/help/initiative.remove_initiator.en.txt	Thu Jul 10 01:02:43 2014 +0200
   221.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   221.3 @@ -1,3 +0,0 @@
   221.4 -= Remove initiator =
   221.5 -
   221.6 -You can remove yourself or another initiator, as long as after the removal there will be at least one initiator left. In order to abandon the entire initiative as such, please select ,,Revoke initiative''.
   222.1 --- a/locale/help/initiative.remove_initiator.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   222.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   222.3 @@ -1,3 +0,0 @@
   222.4 -= Forigi iniciinton =
   222.5 -
   222.6 -Vi povas forigi vin aŭ alian iniciinton, se post la forigo almenaŭ unu iniciinto ekzistos. Por nuligi la iniciaton entute, bonvolu elekti „nuligi iniciaton“.
   223.1 --- a/locale/help/initiative.remove_initiator.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   223.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   223.3 @@ -1,3 +0,0 @@
   223.4 -= 移除发起者 =
   223.5 -
   223.6 -只要在移除后仍至少还有一位发起者,您可移除您自己或另一位发起者。若要停止整个提案,请选择「撤销提案」。
   223.7 \ No newline at end of file
   224.1 --- a/locale/help/initiative.remove_initiator.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   224.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   224.3 @@ -1,3 +0,0 @@
   224.4 -= 移除發起者 =
   224.5 -
   224.6 -只要在移除後仍至少還有一位發起者,您可移除您自己或另一位發起者。若要停止整個提案,請選擇「撤銷提案」。
   225.1 --- a/locale/help/initiative.revoke.de.txt	Thu Jul 10 01:02:43 2014 +0200
   225.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   225.3 @@ -1,3 +0,0 @@
   225.4 -= Initiative zurückziehen =
   225.5 -
   225.6 -Du kannst diese Initiative zurückziehen. Dies kann nicht rückgängig gemacht werden. Natürlich hast du jederzeit die Möglichkeit, eine neue Initiative zu starten. Den Unterstützern kannst du eine alternative Initiative empfehlen. Angeboten werden dir hierfür alle von dir unterstützten Initiativen.
   226.1 --- a/locale/help/initiative.revoke.el.txt	Thu Jul 10 01:02:43 2014 +0200
   226.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   226.3 @@ -1,4 +0,0 @@
   226.4 -==Ανάκληση πρωτοβουλίας==
   226.5 -Μπορείτε να ανακαλέσετε αυτή την πρωτοβουλία. Αυτή η ανάκληση δεν είναι αναστρέψιμη, αλλά μπορείτε πάντα να ξεκινήσετε μία νέα πρωτοβουλία.
   226.6 -
   226.7 -Σας δίνεται η δυνατότητα να προτείνετε στους υποστηρικτές μία εναλλακτική πρωτοβουλία, από αυτές που εσείς υποστηρίζετε.
   226.8 \ No newline at end of file
   227.1 --- a/locale/help/initiative.revoke.en.txt	Thu Jul 10 01:02:43 2014 +0200
   227.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   227.3 @@ -1,3 +0,0 @@
   227.4 -= Revoke initiative =
   227.5 -
   227.6 -You can revoke this initiative. This cannot be rolled back, but you can, of course, start a new initiative anytime. You can recommend the supporters an alternative initiative. For doing so you are offered all initiatives supported by you.
   228.1 --- a/locale/help/initiative.revoke.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   228.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   228.3 @@ -1,4 +0,0 @@
   228.4 -= Nuligi iniciaton =
   228.5 -
   228.6 -Vi povas nuligi iniciaton. Tio estas nemaligebla. Kompreneble, vi havas ĉiumomente la eblecon komenci novan iniciaton. Vi povas rekomendi alternativan iniciaton al la subtenintoj. Por tio vi povas elekti el ĉiuj viaj subtenataj iniciatoj.
   228.7 -
   229.1 --- a/locale/help/initiative.revoke.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   229.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   229.3 @@ -1,3 +0,0 @@
   229.4 -= 撤销提案 =
   229.5 -
   229.6 -您可撤销此提案。此动作不可复原,但您当然可在任何时间发起另一个新提案。您可向提案支持者推荐另一个提案。您可自所有所支持的提案中选择要推荐的提案。
   229.7 \ No newline at end of file
   230.1 --- a/locale/help/initiative.revoke.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   230.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   230.3 @@ -1,3 +0,0 @@
   230.4 -= 撤銷提案 =
   230.5 -
   230.6 -您可撤銷此提案。此動作不可復原,但您當然可在任何時間發起另一個新提案。您可向提案支持者推薦另一個提案。您可自所有所支持的提案中選擇要推薦的提案。
   231.1 --- a/locale/help/initiative.show.de.txt	Thu Jul 10 01:02:43 2014 +0200
   231.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   231.3 @@ -1,12 +0,0 @@
   231.4 -=Initiative, Unterstützung, Anregungen=
   231.5 -Während der Diskussionsphase kannst du diese Initiative unterstützen und gibst damit den Initiatoren eine wichtige Rückmeldung, inwieweit der aktuelle Entwurf auf Zustimmung stößt. Darüber hinaus kannst du durch Anregungen (Änderungsvorschläge) mitteilen, was noch verbessert werden kann bzw. unter welchen Bedingungen du dir eine Unterstützung vorstellen kannst. 
   231.6 -
   231.7 -Du kannst dich den Anregungen anderer Mitglieder anschließen (und damit das Gewicht dieser Anregungen erhöhen) und eigene (zusätzliche) Anregungen einbringen. Anregungen, die aus deiner Sicht unbedingt eingearbeitet werden müssen, damit du zustimmst, kennzeichnest du mit ,,muss'', wünschenswerte mit ,,soll''. Du kannst Anregungen auch kritisch gegenüber stehen und sie mit ,,soll nicht'' kennzeichnen. Eine Anregung, die bei Umsetzung zum Entzug deiner Zustimmung führen würde, kennzeichnest du mit ,,darf nicht''. 
   231.8 -=überarbeiteter Entwurf, Umsetzungsvermerk=
   231.9 -Anhand der (klassifizierten und quantifizierten) Anregungen entscheiden die Initiatoren, was sie in einem neuen Entwurf besser darstellen, ergänzen oder ändern. Der geänderte Entwurf wird den Unterstützern zur Bestätigung vorgelegt. Unterstützer können Anregungen als umgesetzt markieren, wenn die Anregung aus ihrer Sicht (hinreichend) umgesetzt wurde. Die einzelnen Unterstützer können diese Frage durchaus unterschiedlich beurteilen.
  231.10 -=weitere Initiatoren einladen, Zurückziehen einer Initiative=
  231.11 -Ein Initiator kann weitere Initiatoren einladen und verleiht ihnen damit gleiche Rechte für die Bearbeitung des Entwurfs. Jeder Initiator einer Initiative kann die Initiative zurückziehen und auf Wunsch den Unterstützern eine andere Initiative als Alternative empfehlen.
  231.12 -=wenn du nicht gehört wirst=
  231.13 -Wenn die Initiatoren deine Anregungen aus für dich nicht nachvollziehbaren Gründen nicht berücksichtigen, kannst du natürlich jederzeit eine eigene Initiative starten.
  231.14 -=wenn du diese Initiative ablehnst=
  231.15 -Wenn du diese Initiative grundsätzlich ablehnst, solltest du auf dieser Seite gar nichts machen, sondern die Initiative(n), der/denen du positiv gegenüber stehst, unterstützen und/oder deine eigene Initiative zu diesem Thema starten. Sofern du nicht ohnehin schon Mitglied des Themenbereichs bist, kannst du durch eine Mitgliedschaft im Themenbereich oder durch Anmeldung von Interesse am Thema die den erforderlichen Unterstützerquorum zugrundeliegende Grundgesamtheit erhöhen. Den gleichen Effekt erreichst du auch, wenn du an ein Mitglied des Themenbereichs oder einen Interessenten am Thema delegierst. **Nur bei Status ,,Neu'':** Falls das Thema, zu dem diese Initiative gehört, noch im Zustand ,,Neu'' ist und du dieses Thema eigentlich gar nicht diskutieren möchtest, solltest du zunächst nur Mitglied des Themenbereichs werden oder Interesse am Thema anmelden und keine Anregungen eingeben, die dich zum (potentiellen) Unterstützer machen würden. Ebenso solltest du noch keine Gegeninitiative starten, die das Thema über die Zulassungshürde heben könnte.
   232.1 --- a/locale/help/initiative.show.el.txt	Thu Jul 10 01:02:43 2014 +0200
   232.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   232.3 @@ -1,24 +0,0 @@
   232.4 -==Πρωτοβουλία==
   232.5 -Κάθε πρωτοβουλία έχει ως στόχο της την αντιμετώπιση και το κλείσιμο του θέματος στο οποίο αναφέρεται. Για να το πετύχουν αυτό, οι εισηγητές τους, παρέχουν μία ολοκληρωμένη πρόταση μέσω του <<προσχεδίου>> της πρωτοβουλίας και τις αναθεωρήσεις του, ζητούν την υποστήριξη του εκλογικού σώματος και λαμβάνουν υπόψη τους τις προτάσεις που τους γίνονται για την βελτίωση του <<προσχεδίου>>.
   232.6 -
   232.7 -=Υποστήριξη και προτάσεις=
   232.8 -Κατά το στάδιο της συζήτησης μπορείτε να υποστηρίξετε αυτήν την πρωτοβουλία και να κάνετε γνωστό, στους εισηγητές, το επίπεδο συμφωνίας σας με το τρέχον <<προσχέδιο>>. Μπορείτε επίσης να κάνετε συγκεκριμένες προτάσεις για βελτιωτικές αλλαγές ή να υποδείξετε τους όρους και τις συνθήκες υπό τις οποίες θα μπορούσατε να υποστηρίξετε την πρωτοβουλία.
   232.9 -
  232.10 -Μπορείτε να ακολουθήσετε τις προτάσεις των άλλων μελών (αυξάνοντας έτσι το βάρος αυτών των προτάσεων) και να καταθέσετε δικές σας (επιπρόσθετες) προτάσεις. Μαρκάρετε τις προτάσεις που θεωρείτε πως είναι απαραίτητες από την πλευρά σας για να εγκρίνετε την πρωτοβουλία με <<οπωσδήποτε>> κι αυτές που θα ήταν καλό να υλοποιηθούν ως <<καλό θα ήταν>>. Μαρκάρετε τις προτάσεις που είστε δύσπιστοι ως <<καλύτερα όχι>> ενώ αυτές που, εάν ενσωματωθούν, θα σας οδηγήσουν να αποδοκιμάσετε την πρωτοβουλία με <<με τίποτα>>.
  232.11 -
  232.12 -=Αναθεωρημένο προσχέδιο και επανέγκριση=
  232.13 -Με βάση τις προτάσεις και την υποστήριξη που συγκεντρώνουν, οι εισηγητές της πρωτοβουλίας αποφασίζουν τι πρέπει να παρουσιάσουν καλύτερα, τι να προσθέσουν ή τι να αλλάξουν στο προσχέδιο ώστε να τύχει ευρύτερης αποδοχής.
  232.14 -Το βελτιωμένο προσχέδιο θα υποβληθεί στους υποστηρικτές της πρωτοβουλίας για επιβεβαίωση. Στη φάση αυτή θα πρέπει να χαρακτηρίσετε τις προτάσεις ως υλοποιημένες ή μη, ανάλογα με το πως κρίνεται το νέο προσχέδιο. Κάθε υποστηρικτής μπορεί να κρίνει τις αλλαγές διαφορετικά.
  232.15 -
  232.16 -=Πρόσκληση επιπλέον εισηγητών, ανάκληση πρωτοβουλίας=
  232.17 -Οι εισηγητές μπορούν να προσκαλέσουν επιπλέον εισηγητές, δίνοντάς τους έτσι ίσα δικαιώματα στην πρωτοβουλία και στην συγγραφή του προσχεδίου. Κάθε εισηγητής μπορεί να ανακαλέσει την πρωτοβουλία, προτείνοντας στους υποστηρικτές της μία εναλλακτική.
  232.18 -
  232.19 -=Εάν δεν εισακουστείτε=
  232.20 -Αν οι εισηγητές, για ανεξήγητους λόγους, δεν λάβουν υπόψη την πρότασή σας, μπορείτε, ασφαλώς, να ξεκινήσετε τη δική σας πρωτοβουλία ανά πάσα στιγμή.
  232.21 -
  232.22 -=Εάν αποδοκιμάζετε αυτή την πρωτοβουλία=
  232.23 -Εάν διαφωνείτε επί της αρχής με αυτή την πρωτοβουλία, δεν πρέπει να κάνετε απολύτως τίποτα σε αυτή την σελίδα. Αντιθέτως, υποστηρίξτε πρωτοβουλίες που βλέπετε θετικά ή/και ξεκινήστε τη δική σας πρωτοβουλία για αυτό το θέμα.
  232.24 -
  232.25 -Αν δεν είστε ήδη μέλος αυτού το τομέα, μπορείτε να αυξήσετε το πλήθος των απαραίτητων υποστηρικτών με το να γίνετε μέλος του τομέα ή με το να δηλώσετε ενδιαφέρον για αυτό το θέμα. Μπορείτε να επιτύχετε το ίδιο με το να αναθέσετε το θέμα σε κάποιο μέλος που ήδη ενδιαφέρεται για το θέμα ή είναι μέλος του τομέα.
  232.26 -
  232.27 -**//Μόνο για το στάδιο <<Νέο>>://** Αν το θέμα αυτής της πρωτοβουλίας είναι ακόμη στο στάδιο <<Νέο>> και, πράγματι, δεν θέλετε ούτε να το συζητήσετε, θα έπρεπε πρώτα να γίνετε μέλος του τομέα ή να δηλώσετε το ενδιαφέρον σας για το θέμα αλλά να μην κάνετε καθόλου προτάσεις, οι οποίες θα σας χαρακτήριζαν (δυνητικό) υποστηρικτή. Επίσης, καλύτερα να μην ξεκινήσετε ακόμη (αντιμέτωπη) εναλλακτική πρωτοβουλία, γιατί θα μπορούσε να βοηθήσει το θέμα να ξεπεράσει το ελάχιστο όριο αποδοχής.
  232.28 \ No newline at end of file
   233.1 --- a/locale/help/initiative.show.en.txt	Thu Jul 10 01:02:43 2014 +0200
   233.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   233.3 @@ -1,12 +0,0 @@
   233.4 -=Initiative, support, suggestion=
   233.5 -During the discussion phase you can support this initiative giving the initiators important feed-back about the approval level of the current draft. Apart from that you can communicate via suggestions (for making changes), what can still be improved, or indicate conditions under which you can imagine to give your support. 
   233.6 -
   233.7 -You can follow suggestions of other members (thereby increasing the weight of these suggestions) and come up with your own (additional) suggestions. You can mark suggestions that you believe to be mandatory changes from your point of view, for you to approve with ,,must'', and nice-to-have ones with ,,should''. You can also be skeptical of suggestions and mark them with ,,should not''. You can mark a suggestion that, if realized, would lead you to disapprove, with ,,must not''. 
   233.8 -=revised draft, realization notes=
   233.9 -Based on the (classified and quantified) suggestions the initiators decide what to present better, add or change in a new draft. The improved draft will be submitted to the supporters to ask for confirmation. Supporters can mark suggestions as implemented, if from their point of view the suggestions has been (sufficiently) implemented. Individual supporters can judge this quite differently.
  233.10 -=invite further initiators, revoke an initiative=
  233.11 -An initiator can invite further initiators thereby granting them equal rights on editing the draft. Every initiator of an initiative can revoke the initiative and recommend another alternative initiative to the supporters on request.
  233.12 -=if you don't get heard=
  233.13 -If the initiators, for inexplicable reasons, do not consider your suggestion, you can, of course, start your own initiative anytime.
  233.14 -=if you disapprove this initiative=
  233.15 -If you disapprove this initiative fundamentally, you should do nothing at all on this page, but support the initiative(s), that you are positive about, and/or start your own initiative related to this issue. If you are not already a member of the area you can increase the population of the necessary support quorum by becoming a member of the area or by adding your interest to the issue. You can achieve the same effect by delegating to a member of the area or a member interested at the issue. **Only for state ,,New'':** If the issue of this initiative is still in the state ,,New'' and, in fact, you do not want to discuss this issue at all, you should first only become a member of the area or add interest to the issue, but not give any suggestions, making you a (potential) supporter. Also, you should not yet start a counter initiative, which might raise the issue above the minimum admission level.
   234.1 --- a/locale/help/initiative.show.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   234.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   234.3 @@ -1,12 +0,0 @@
   234.4 -=Iniciato, subteno, sugestoj=
   234.5 -Dum la diskutfazo vi povas subteni tiun ĉi iniciaton kaj donas per tio al la iniciintoj gravajn prijuĝajn rimarkojn, kiom da subteno la aktuala skizo ricevas. Plue vi povas komuniki per sugestoj (plibonigaj sugestoj) tion, kio povas esti plibonigota respektive laŭ kiuj kondiĉoj vi povas pripensi subtenon.
   234.6 -
   234.7 -Vi povas aliĝi al la sugestoj de aliaj membroj (kaj pligrandigi la signifon de tiuj ĉi sugestoj) kaj sugesti (pliajn) proprajn ideojn. Sugestojn, kiuj laŭ via vidpunkto nepre devas esti realigotaj, por ke vi konsentu, vi signas per „devas“, dezirindajn per „devus“. Vi ankaŭ povas kritike kontraŭstari sugestojn kaj signi ilin per „ne devus“. Sugestojn, kies realigo kaŭzus la revokon de via konsento, vi signas per „ne rajtas“.
   234.8 -=Prilaborita skizo, realigrimarko=
   234.9 -Laŭ la (klasifikitaj kaj kvantumitaj) sugestoj, la iniciintoj decidas, kion en nova skizo ili prezentas pli bone, aldonas aŭ ŝanĝas. Oni antaŭmetas la ŝanĝitan skizon al la subtenantoj por aprobi. Subtenantoj povas signi sugestojn kiel realigitajn, se la sugestoj laŭ ilia vidpunkto (sufiĉe) realiĝis. La individuaj subtenantoj povas juĝi tiun demandon tute diference.
  234.10 -=Inviti pliajn iniciontojn, nuligi iniciaton=
  234.11 -Iniciinto povas inviti pliajn iniciontojn kaj donas per tio al ili samajn rajtojn por la prilaboro de la skizo. Ĉiu iniciinto povas nuligi la iniciaton kaj laŭdezire rekomendi alian iniciaton al la subtenintoj.
  234.12 -=Se vi ne estas aŭdita=
  234.13 -Se la iniciintoj ne konsideras viajn sugestojn laŭ por vi neakcepteblaj kialoj, vi povas memkompreneble ĉiumomente komenci propran iniciaton.
  234.14 -=Se vi malkonsentas kun tiu ĉi iniciato=
  234.15 -Se vi entute malkonsentas kun tiu ĉi iniciato, vi faru nenion en tiu ĉi paĝo, sed subtenu iniciato(j)n, kun kiu(j) vi konsentas, aŭ komencu propran iniciaton pri tiu ĉi temo. Se vi ne sen tio jam estas membro de la temaro, vi povas pligrandigi la taksobazon de la atingebla kvorumo de subtenantoj per membreco en la temaro aŭ per anonco de intereso pri la temo. Vi atingas la saman efekton, se vi delegas al membro de la temaro aŭ al interesato pri la temo. **Nur ĉe stato „nova“:** Se la temo, al kiu apartenas la iniciato, ankoraŭ estas en la stato „nova“ kaj vi efektive ne ŝatus diskuti la temon, vi unue nur membriĝu ĉe la temaro aŭ anoncu intereson kaj ne enmetu sugestojn, kiuj farus vin (ebla) subtenanto. Same vi ne komencu kontraŭiniciaton, kiu povus puŝi la temon trans la kvorumon. 
   235.1 --- a/locale/help/initiative.show.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   235.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   235.3 @@ -1,12 +0,0 @@
   235.4 -=提案、支持、建议=
   235.5 -在讨论期您可藉由提供发起者关于您对提案接受程度的重要回馈来支持提案。除了建议可改进处,您可指出您可能给予此提案支持的特定条件。
   235.6 -
   235.7 -您可遵循其他成员的建议(并增加这些建议的份量),并加入您自己额外的建议。在您观点中,您相信是为必须的改变,可标示为「必须」;您相信是为好的建议,可标示为「应当」;您有所质疑的建议,可标示为「不应」;您在理解后所不赞同的建议,可标示为「不可」。
   235.8 -=已修改草案、更新注记=
   235.9 -根据(已分类并量化的)建议,发起者决定发表更好的、新增或更改一份新的草案。改进过的草案将被送给支持者以请求确认。若支持者认为这些建议已经被充分地采纳,他们可将这些建议标示为被采纳。个别支持者对此的判断可能有极大差异。
  235.10 -=邀请更多发起者、撤销提案=
  235.11 -发起者可邀请更多发起者,给予他们同等的权限来编辑草案。每个发起者可撤销此提案并应要求推荐另一个替代的提案给支持者。
  235.12 -=若您的意见未被采纳=
  235.13 -若发起者不知原因地不考虑您的建议,您当然可在任何时候发起您自己的提案。
  235.14 -=若您不赞同此提案=
  235.15 -若您根本不赞同此提案,请勿在此页面做任何动作。请去支持您所肯定的提案,并/或发起您自己与此议题相关的提案。若您并非此领域的成员,您可成为此领域的成员或关心此议题以提高此提案的必备支持门槛。你可委任给一个领域成员或一个关心此议题的成员以达到同样效果。 **只在「递交期」的状态:** 若此提案的议题仍在「递交期」的状态,并且您实际上一点也不想讨论此议题,您应先成员此领域成员或关心此议题,但不给予任何建议,而成为一个(可能的)支持者。再者,您不应发起一个相对的提案,因为如此可能将此议题提升过最低递交层级。
  235.16 \ No newline at end of file
   236.1 --- a/locale/help/initiative.show.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   236.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   236.3 @@ -1,12 +0,0 @@
   236.4 -=提案、支持、建議=
   236.5 -在討論期您可藉由提供發起者關於您對提案接受程度的重要回饋來支持提案。除了建議可改進處,您可指出您可能給予此提案支持的特定條件。 
   236.6 -
   236.7 -您可遵循其他成員的建議(並增加這些建議的份量),並加入您自己額外的建議。在您觀點中,您相信是為必須的改變,可標示為「必須」;您相信是為好的建議,可標示為「應當」;您有所質疑的建議,可標示為「不應」;您在理解後所不贊同的建議,可標示為「不可」。  
   236.8 -=已修改草案、更新註記=
   236.9 -根據(已分類並量化的)建議,發起者決定發表更好的、新增或更改一份新的草案。改進過的草案將被送給支持者以請求確認。若支持者認為這些建議已經被充分地採納,他們可將這些建議標示為被採納。個別支持者對此的判斷可能有極大差異。 
  236.10 -=邀請更多發起者、撤銷提案=
  236.11 -發起者可邀請更多發起者,給予他們同等的權限來編輯草案。每個發起者可撤銷此提案並應要求推薦另一個替代的提案給支持者。
  236.12 -=若您的意見未被採納=
  236.13 -若發起者不知原因地不考慮您的建議,您當然可在任何時候發起您自己的提案。
  236.14 -=若您不贊同此提案=
  236.15 -若您根本不贊同此提案,請勿在此頁面做任何動作。請去支持您所肯定的提案,並/或發起您自己與此議題相關的提案。若您並非此領域的成員,您可成為此領域的成員或關心此議題以提高此提案的必備支持門檻。你可委任給一個領域成員或一個關心此議題的成員以達到同樣效果。**只在「遞交期」的狀態:** 若此提案的議題仍在「遞交期」的狀態,並且您實際上一點也不想討論此議題,您應先成員此領域成員或關心此議題,但不給予任何建議,而成為一個(可能的)支持者。再者,您不應發起一個相對的提案,因為如此可能將此議題提升過最低遞交層級。
   237.1 --- a/locale/help/issue.show.de.txt	Thu Jul 10 01:02:43 2014 +0200
   237.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   237.3 @@ -1,11 +0,0 @@
   237.4 -= Thema =
   237.5 -
   237.6 -Auf dieser Seite werden alle Initiativen zu diesem Thema aufgelistet. Durch Klicken auf ,,Mein Interesse anmelden'' wird man für dieses Thema den Teilnehmern des übergeordneten Themenbereichs gleichgestellt, wodurch man zur Grundgesamtheit der Diskussionsteilnehmer gezählt wird, was sich auf das von Initiativen zu erreichende Unterstützerquorum auswirkt.
   237.7 -
   237.8 -Angemeldetes Interesse am Thema ist Voraussetzung dafür, dass eine Initiative des Themas direkt unterstützt wird, oder eigene Anregungen gegeben werden. Bei angemeldetem Interesse kommen ausgehende Delegationen für dieses Thema bis zum Abschluss der Phase ,,Eingefroren'' nicht zum tragen. Sobald man eine Initiative des Themas (direkt, nicht durch Delegation) unterstützt, wird das Interesse automatisch angemeldet. Das Zurückziehen des angemeldeten Interesses, entzieht auch die direkten Unterstützerstimmen für Initiativen dieses Themas und aktiviert ggf. ausgesetzte Delegationen.
   237.9 -
  237.10 -Themen durchlaufen die Phasen ,,Neu'', ,,Diskussion'', ,,Eingefroren'', ,,Abstimmung'' und ,,Abgeschlossen'', außer sie gehen bei mangelnden Unterstützerzahlen in den Zustand ,,Abgebrochen'' über.
  237.11 -
  237.12 -Während der Phasen ,,Neu'' und ,,Diskussion'' sollte man **allen** Initiativen, die man grundsätzlich (oder unter bestimmten Bedingungen) für zustimmungsfähig hält, unterstützen und Anregungen zur Verbesserung geben (Näheres dazu findest du auf der Initiativenseite). Hierdurch gibt man den Initiatoren die Chance, den Entwurf zu verbessern. Während dieser Phase hast man auch die Möglichkeit, eine eigene (konkurrierende) Initiative zu diesem Thema zu starten und um Unterstützung zu ringen.
  237.13 -
  237.14 -Initiativen des Themas, die ein bestimmtes Quorum erreichen, werden in die Endabstimmung übernommen. Die Unterstützung für eine Initiative während der Phasen ,,Neu'', ,,Diskussion'' und ,,Eingefroren'' bedeutet keine Festlegung auf das Verhalten in der Endabstimmung.
   238.1 --- a/locale/help/issue.show.el.txt	Thu Jul 10 01:02:43 2014 +0200
   238.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   238.3 @@ -1,21 +0,0 @@
   238.4 -==Θέμα==
   238.5 -Κάθε θέμα έχει μία ή παραπάνω <<πρωτοβουλίες>> τις οποίες καλείστε να υποστηρίξετε, να βελτιώσετε με τις προτάσεις σας και να ψηφίσετε.
   238.6 -
   238.7 -Δηλώνοντας το ενδιαφέρον σας για το θέμα αυξάνετε την βάση αξιολόγησης για την επίτευξη απαρτίας που απαιτείται για κάθε πρωτοβουλία. Το ενδιαφέρον σας για το θέμα θα δηλωθεί αυτόματα εάν υποστηρίξετε μια πρωτοβουλία για αυτό, αλλά δεν θα αφαιρεθεί παρά μόνο αν το επιλέξετε ρητά.
   238.8 -
   238.9 -=Ανάθεση=
  238.10 -Μπορείτε να αναθέσετε το θέμα σε κάποιο άλλο μέλος από τις επαφές σας. Ανάθεση για το θέμα αυτό υπερισχύει πιθανής ανάθεσης για ολόκληρο τομέα ή ενότητα. Επίσης, πιθανή εντολή αυτόματης απόρριψης ισχύει μόνο στην περίπτωση που δεν συμμετάσχετε ο ίδιος στο τελικό στάδιο ψηφοφορίας και δεν γίνει εφαρμογή της ανάθεσης.
  238.11 -
  238.12 -Εάν έχετε δηλώσει ενδιαφέρον για το θέμα, πιθανή εξερχόμενη ανάθεση σας θα ανασταλεί κατά τη διάρκεια του σταδίου συζήτησης αλλά θα είναι ενεργή κατά στην τελική ψηφοφορία.
  238.13 -
  238.14 -=Συζήτηση=
  238.15 -Κατά το στάδιο συζήτησης (κατάσταση <<Νέο>> και <<Συζήτηση>>) είναι σημαντικό **να υποστηρίξετε όλες τις πρωτοβουλίες** οι οποίες σας βρίσκουν γενικά σύμφωνους (ή υπό ορισμένες προϋποθέσεις) και να κάνετε προτάσεις για βελτιώσεις. Μ' αυτό τον τρόπο δίνετε στους εισηγητές την ευκαιρία να βελτιώσουν το προσχέδιο συμπεριλαμβάνοντας τις προτάσεις σας.
  238.16 -
  238.17 -Σε αυτή τη φάση σας δίνεται επίσης η δυνατότητα να ξεκινήσετε την δική σας (ανταγωνιστική) πρωτοβουλία για το θέμα και να ζητήσετε από τα μέλη να την υποστηρίξουν.
  238.18 -
  238.19 -=Ψηφοφορία=
  238.20 -Θέματα που συμπληρώνουν την ορισμένη (από τον ισχύοντα κανονισμό) απαρτία, πηγαίνουν στο στάδιο της ψηφοφορίας. Εκεί μπορείτε να βάλετε τις πρωτοβουλίες που εγκρίνετε σε σειρά προτίμησης, ενώ για άλλες μπορείτε να απέχετε. Τέλος, μπορείτε να βάλετε με σειρά προτίμησης κι αυτές με τις οποίες διαφωνείτε.
  238.21 -
  238.22 -**//Σημαντικό//:** Δεν υπάρχει λόγος να προτιμήσετε μια πρόταση που θεωρείτε κατώτερη άλλης, φοβούμενοι ότι θα <<χαθεί>> η ψήφος σας εξαιτίας προβλεπόμενης πλειοψηφίας μιας άλλης. Για να το θέσουμε απλά, το σύστημα ψηφοφορίας λαμβάνει πλήρως υπόψη του τις προτιμήσεις σας ώστε όταν η πρώτη σας προτίμηση δεν έχει πιθανότητες, η ψήφος σας μετριέται εξ' ολοκλήρου προς την πρώτη σας εναλλακτική, μετά στην δεύτερη, κ.ο.κ.
  238.23 -
  238.24 -Για πληροφορίες σχετικά με την εκλογική διαδικασία που χρησιμοποιείται δείτε: [https://en.wikipedia.org/wiki/Schulze_method]
   239.1 --- a/locale/help/issue.show.en.txt	Thu Jul 10 01:02:43 2014 +0200
   239.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   239.3 @@ -1,11 +0,0 @@
   239.4 -= Issue =
   239.5 -
   239.6 -This page lists all initiatives belonging to this issue. If you click on ""Add my interest"", you will be treated as equal to the members of the superior areas of this issue, which means that you count for the basic population for discussion in this issue. This has an impact on the supporter quorum, which initiatives have to reach.
   239.7 -
   239.8 -Declared interest is required to be able to directly support initiatives in this issue or to propose suggestions. As long as you are marked as interested in this issue, your outgoing delegations are postponed until the phases ""new"", ""discussion"" and ""frozen"" are finished and the issue is in voting. As soon as you support an initiative of this issue, your interest will be automatically added. Removing your interest also removes all direct support for initiatives of this issues and re-activates a previously postponed delegation.
   239.9 -
  239.10 -Issues run through the phases ""new"", ""discussion"", ""frozen"", ""voting"", and ""finished"", except when they are canceled beforehand due to lack of supporters of initiatives.
  239.11 -
  239.12 -During the phases ""new"" and ""discussion"" you should support **all** initiatives that you can agree with generally (or under certain conditions), and make suggestions for improvements (you can find details on the initiative page). Hereby you give the initiators the chance to improve the draft. During this phase you can also start your own (competing) initiative for this issue and ask people to support it.
  239.13 -
  239.14 -Initiatives reaching a certain quorum, will be taken into the final voting. Support of an initiative during the phases ""new"", ""discussion"" and ""frozen"" does not imply the same decision during final voting.
   240.1 --- a/locale/help/issue.show.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   240.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   240.3 @@ -1,11 +0,0 @@
   240.4 -= 议题 =
   240.5 -
   240.6 -此页面列出所有属于此议题的提案。若您点击「关心此议题」,您将被与其他此议题上层领域的其他成员同等对待,代表您被计入讨论此议题的基本人数。这将影响提案所需达到的支持者门槛。
   240.7 -
   240.8 -您必须先关心此议题才可直接支持此议题中的提案或提出建议。只要您关心此议题,您所送出的委任将延后至「递交期」、「讨论期」、「底定期」都结束而此议题已开始表决之时。只要您支持此议题中的一个提案,您将自动关心此议题。移除对此议题的关心也将移除对此议题所有提案的直接支持,并重新启用之前所送出的委任。
   240.9 -
  240.10 -议题会经历下列阶段:「递交期」、「讨论期」、「底定期」、「表决期」以及「已结束」,除非他们因为提案缺乏支持者而提早被取消。
  240.11 -
  240.12 -在「递交期」及「讨论期」您应支持**所有**您大致上同意的提案(您可在提案页面上找到细节)。借此您给发起者机会去改进草案。在这时期您也可为此议题发起您自己(相竞争的)提案并请人们去支持。
  240.13 -
  240.14 -达特定门槛的提案将被列入最终表决。在「递交期」、「讨论期」及「底定期」支持一个提案不代表在最终表决时持相同决定。
  240.15 \ No newline at end of file
   241.1 --- a/locale/help/issue.show.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   241.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   241.3 @@ -1,11 +0,0 @@
   241.4 -= 議題 =
   241.5 -
   241.6 -此頁面列出所有屬於此議題的提案。若您點擊「關心此議題」,您將被與其他此議題上層領域的其他成員同等對待,代表您被計入討論此議題的基本人數。這將影響提案所需達到的支持者門檻。
   241.7 -
   241.8 -您必須先關心此議題才可直接支持此議題中的提案或提出建議。只要您關心此議題,您所送出的委任將延後至「遞交期」、「討論期」、「底定期」都結束而此議題已開始表決之時。只要您支持此議題中的一個提案,您將自動關心此議題。移除對此議題的關心也將移除對此議題所有提案的直接支持,並重新啓用之前所送出的委任。
   241.9 -
  241.10 -議題會經歷下列階段:「遞交期」、「討論期」、「底定期」、「表決期」以及「已結束」,除非他們因為提案缺乏支持者而提早被取消。
  241.11 -
  241.12 -在「遞交期」及「討論期」您應支持**所有**您大致上同意的提案(您可在提案頁面上找到細節)。 藉此您給發起者機會去改進草案。在這時期您也可為此議題發起您自己(相競爭的)提案並請人們去支持。
  241.13 -
  241.14 -達特定門檻的提案將被列入最終表決。在「遞交期」、「討論期」及「底定期」支持一個提案不代表在最終表決時持相同決定。
   242.1 --- a/locale/help/member.edit.de.txt	Thu Jul 10 01:02:43 2014 +0200
   242.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   242.3 @@ -1,5 +0,0 @@
   242.4 -= Profil =
   242.5 -
   242.6 -Alle Angaben sind freiwillig. Im Profil erscheinen nur die Felder, die nicht leer sind.
   242.7 -
   242.8 -Screen-Name, Anmeldename sowie das Kennwort lassen sich im Benutzermenü unter Einstellungen ändern.
   243.1 --- a/locale/help/member.edit.el.txt	Thu Jul 10 01:02:43 2014 +0200
   243.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   243.3 @@ -1,4 +0,0 @@
   243.4 -=Προφίλ=
   243.5 -Όλες οι πληροφορίες συμπληρώνονται εθελοντικά. Μόνο μη κενά πεδία θα εμφανίζονται στο προφίλ σας.
   243.6 -
   243.7 -Για να αλλάξετε το ψευδώνυμο, το όνομα σύνδεσης ή τον κωδικό πρόσβασής σας πηγαίνετε στη σελίδα 'Επιλογές' από το μενού χρήστη πάνω δεξιά. Για να αλλάξετε την φωτογραφία και την εικόνα σας επιλέξτε 'Ανέβασμα εικόνων'.
   244.1 --- a/locale/help/member.edit.en.txt	Thu Jul 10 01:02:43 2014 +0200
   244.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   244.3 @@ -1,5 +0,0 @@
   244.4 -= Profile =
   244.5 -
   244.6 -All information entered here is voluntary. Only non-empty fields will be shown in your profile.
   244.7 -
   244.8 -You can change your name, login name and password in your user menu at the upper right corner under ""settings"".
   245.1 --- a/locale/help/member.edit.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   245.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   245.3 @@ -1,5 +0,0 @@
   245.4 -= Profilo =
   245.5 -
   245.6 -Ĉiuj deklaroj estas libervolaj. En via profilo nur tiuj kampoj, kiuj ne estas malplenaj, estas videblaj.
   245.7 -
   245.8 -You can change your name, login name and password in your user menu at the upper right corner under ""settings"".
   246.1 --- a/locale/help/member.edit.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   246.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   246.3 @@ -1,5 +0,0 @@
   246.4 -= 个人简介 =
   246.5 -
   246.6 -所有在此的资讯都是自愿输入的。只有非空白内容会被显示在您的个人简介。
   246.7 -
   246.8 -您可在右上角「设定」的使用者选单中改变您的使用者代号、帐号以及密码。
   246.9 \ No newline at end of file
   247.1 --- a/locale/help/member.edit.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   247.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   247.3 @@ -1,5 +0,0 @@
   247.4 -= 個人簡介 =
   247.5 -
   247.6 -所有在此的資訊都是自願輸入的。只有非空白內容會被顯示在您的個人簡介。
   247.7 -
   247.8 -您可在右上角「設定」的使用者選單中改變您的使用者代號、帳號以及密碼。
   248.1 --- a/locale/help/member.edit_images.de.txt	Thu Jul 10 01:02:43 2014 +0200
   248.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   248.3 @@ -1,6 +0,0 @@
   248.4 -= Bilder =
   248.5 -
   248.6 -Format: JPG
   248.7 -Avatar:  max. 48 x 48 Pixel, für den Avatar bevorzugt ein quadratisches Bild
   248.8 -Foto: max. 250 x 250 Pixel
   248.9 -Größere Bilder werden herunterskaliert, alle Bilder werden recodiert und von Profilen befreit.
   249.1 --- a/locale/help/member.edit_images.el.txt	Thu Jul 10 01:02:43 2014 +0200
   249.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   249.3 @@ -1,6 +0,0 @@
   249.4 -=Εικόνες=
   249.5 -Μορφή: JPG
   249.6 -Εικόνα (Avatar): μεγ. 48 x 48 pixels, μια τετράγωνη εικόνα κατά προτίμηση.
   249.7 -Φωτογραφία: μεγ. 250 x 250 pixels
   249.8 -
   249.9 -Μεγαλύτερες εικόνες θα σμικρυνθούν. Όλες οι εικόνες θα επανακωδικοποιηθούν και τα δεδομένα προφίλ τους θα αφαιρεθούν.
   250.1 --- a/locale/help/member.edit_images.en.txt	Thu Jul 10 01:02:43 2014 +0200
   250.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   250.3 @@ -1,6 +0,0 @@
   250.4 -= Images =
   250.5 -
   250.6 -Format: JPG
   250.7 -Avatar: max. 48 x 48 pixels, an image in square format is preferred for your avatar
   250.8 -Picture: max. 250 x 250 pixels
   250.9 -Larger images will be scaled down, all images will be recoded and profile data be removed.
   251.1 --- a/locale/help/member.edit_images.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   251.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   251.3 @@ -1,6 +0,0 @@
   251.4 -= Bildoj =
   251.5 -
   251.6 -Formato: JPG
   251.7 -Avataro: maksimume 48 × 48 rastrumeroj, por la avataro prefereble kvadrata bildo
   251.8 -Foto: maksimume 250 × 250 rastrumeroj
   251.9 -Pli grandaj bildoj reduktiĝas; ĉiuj bildoj rekodiĝas kaj liberiĝas de profiloj. 
   252.1 --- a/locale/help/member.edit_images.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   252.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   252.3 @@ -1,6 +0,0 @@
   252.4 -= 图片 =
   252.5 -
   252.6 -格式:JPG
   252.7 -头像:最大 48 x 48 画素,一张横式的图片较适合做为您的头像。
   252.8 -照片: 最大 250 x 250 画素
   252.9 -更大的图片会被缩小,所有的图片将被重新编码,而图片附属资讯将被去除。
  252.10 \ No newline at end of file
   253.1 --- a/locale/help/member.edit_images.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   253.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   253.3 @@ -1,6 +0,0 @@
   253.4 -= 圖片 =
   253.5 -
   253.6 -格式:JPG
   253.7 -頭像:最大 48 x 48 畫素,一張橫式的圖片較適合做為您的頭像。
   253.8 -照片: 最大 250 x 250 畫素
   253.9 -更大的圖片會被縮小,所有的圖片將被重新編碼,而圖片附屬資訊將被去除。
   254.1 --- a/locale/help/member.settings.email_address.de.txt	Thu Jul 10 01:02:43 2014 +0200
   254.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   254.3 @@ -1,1 +0,0 @@
   254.4 -Diese E-Mail-Adresse kann für automatische Nachrichten des Systems sowie für die Kontaktaufnahme durch die Administratoren verwendet werden und wird anderen Benutzern nicht angezeigt. Wenn Du die Adresse änderst, erhältst Du eine E-Mail mit einem Bestätigungslink, den du anklicken musst.
   255.1 --- a/locale/help/member.settings.email_address.el.txt	Thu Jul 10 01:02:43 2014 +0200
   255.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   255.3 @@ -1,1 +0,0 @@
   255.4 -Αυτή η διεύθυνση email μπορεί να χρησιμοποιηθεί για αυτοματοποιημένα μηνύματα από το σύστημα ή για επικοινωνία από τους διαχειριστές του συστήματος. Δεν εμφανίζεται σε άλλους χρήστες. Αν αλλάξετε αυτή την διεύθυνση θα λάβετε ένα μήνυμα επιβεβαίωσης της νέας διεύθυνσης με έναν σύνδεσμο που πρέπει να ακολουθήσετε.
   255.5 \ No newline at end of file
   256.1 --- a/locale/help/member.settings.email_address.en.txt	Thu Jul 10 01:02:43 2014 +0200
   256.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   256.3 @@ -1,1 +0,0 @@
   256.4 -This e-mail address can be used for automatic messages from the system as well as for approach by the administrators of the system. It is not displayed to other users. If you change this address, you receive an e-mail with a verification link, which you have to follow.
   257.1 --- a/locale/help/member.settings.email_address.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   257.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   257.3 @@ -1,1 +0,0 @@
   257.4 -此电邮地址可被系统用来发送自动讯息,或被系统管理员用来联络您。此电邮地址将不公开显示。若您更改此地址,您会收到一封有认证连结的电邮,您必须遵循上面的指示。
   257.5 \ No newline at end of file
   258.1 --- a/locale/help/member.settings.email_address.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   258.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   258.3 @@ -1,1 +0,0 @@
   258.4 -此電郵地址可被系統用來發送自動訊息,或被系統管理員用來聯絡您。此電郵地址將不公開顯示。若您更改此地址,您會收到一封有認證連結的電郵,您必須遵循上面的指示。
   259.1 --- a/locale/help/member.settings.login.de.txt	Thu Jul 10 01:02:43 2014 +0200
   259.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   259.3 @@ -1,1 +0,0 @@
   259.4 -Bitte wähle einen Anmeldenamen. Dieser wird anderen nicht gezeigt und nur von Dir zum Anmelden verwendet. Groß- und Kleinschreibung wird berücksichtigt.
   259.5 \ No newline at end of file
   260.1 --- a/locale/help/member.settings.login.el.txt	Thu Jul 10 01:02:43 2014 +0200
   260.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   260.3 @@ -1,1 +0,0 @@
   260.4 -Παρακαλώ επιλέξτε ένα όνομα σύνδεσης. Αυτό το όνομα δεν θα εμφανίζεται σε άλλους και χρησιμοποιείται μόνο για την σύνδεσή σας στο σύστημα. Προσοχή στα κεφαλαία/πεζά γράμματα, έχουν σημασία.
   260.5 \ No newline at end of file
   261.1 --- a/locale/help/member.settings.login.en.txt	Thu Jul 10 01:02:43 2014 +0200
   261.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   261.3 @@ -1,1 +0,0 @@
   261.4 -Please choose a login name. It will not be visible for other users and you will only use it for logging in. The login name is case-sensitive.
   261.5 \ No newline at end of file
   262.1 --- a/locale/help/member.settings.login.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   262.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   262.3 @@ -1,1 +0,0 @@
   262.4 -Bonvolu elekti salutnomon. Tiu ne montriĝas al aliaj kaj estas uzata nur de vi por ensaluti. Uskleco estas konsiderata.
   263.1 --- a/locale/help/member.settings.login.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   263.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   263.3 @@ -1,1 +0,0 @@
   263.4 -请选择一个帐号。此帐号将不会显示给其他使用者,而只由您在登入时使用。帐号的大小写是有区别的。
   263.5 \ No newline at end of file
   264.1 --- a/locale/help/member.settings.login.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   264.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   264.3 @@ -1,1 +0,0 @@
   264.4 -請選擇一個帳號。此帳號將不會顯示給其他使用者,而只由您在登入時使用。帳號的大小寫是有區別的。
   264.5 \ No newline at end of file
   265.1 --- a/locale/help/member.settings.name.de.txt	Thu Jul 10 01:02:43 2014 +0200
   265.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   265.3 @@ -1,1 +0,0 @@
   265.4 -Wähle einen Namen, z. B. Deinen Real- oder Nicknamen. Dieser wird anderen angezeigt um Dich zu identifizieren. Aus Gründen der Transparenz können alte Namen in Deiner Namenshistorie im Profil abgerufen werden.
   265.5 \ No newline at end of file
   266.1 --- a/locale/help/member.settings.name.el.txt	Thu Jul 10 01:02:43 2014 +0200
   266.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   266.3 @@ -1,3 +0,0 @@
   266.4 -Παρακαλώ επιλέξτε ένα όνομα, π.χ. το πραγματικό σας ή κάποιο ψευδόνυμο. Το όνομα αυτό θα εμφανίζεται στους άλλους για να σας αναγνωρίζουν.
   266.5 -
   266.6 -Για λόγους διαφάνειας, το ιστορικό του ονόματός σας είναι διαθέσιμο σε άλλους και φαίνεται στη σελίδα του προφίλ σας.
   266.7 \ No newline at end of file
   267.1 --- a/locale/help/member.settings.name.en.txt	Thu Jul 10 01:02:43 2014 +0200
   267.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   267.3 @@ -1,1 +0,0 @@
   267.4 -Choose a name, e.g. your real name or a nick name. This name will be visible for other users, in order to identify you. For reasons of transparency the history of your names is available for others looking at your profile.
   267.5 \ No newline at end of file
   268.1 --- a/locale/help/member.settings.name.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   268.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   268.3 @@ -1,1 +0,0 @@
   268.4 -Elektu nomon, ekzemple vian veran aŭ kaŝnomon. Tiu montriĝas por identigi vin. Pro kialoj de travideblo malnovaj nomoj montriĝas en la nomhistorio de via profilo.
   269.1 --- a/locale/help/member.settings.name.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   269.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   269.3 @@ -1,1 +0,0 @@
   269.4 -请选择一个使用者代号,例如您的真名或绰号。此使用者代号将会显示给其他使用者,以便辨​​认您。为了维持透明度,其他使用者可在您的个人简介看到您使用者代号的更改纪录。
   269.5 \ No newline at end of file
   270.1 --- a/locale/help/member.settings.name.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   270.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   270.3 @@ -1,1 +0,0 @@
   270.4 -請選擇一個使用者代號,例如您的真名或綽號。此使用者代號將會顯示給其他使用者,以便辨認您。為了維持透明度,其他使用者可在您的個人簡介看到您使用者代號的更改紀錄。
   270.5 \ No newline at end of file
   271.1 --- a/locale/help/member.settings.notification.de.txt	Thu Jul 10 01:02:43 2014 +0200
   271.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   271.3 @@ -1,2 +0,0 @@
   271.4 -=Benachrichtigungseinstellungen=
   271.5 -Hier kannst du einstellen, ob du überhaupt und wenn ja welche Benachrichtigungen du vom System per E-Mail erhalten möchtest.
   272.1 --- a/locale/help/member.settings.notification.el.txt	Thu Jul 10 01:02:43 2014 +0200
   272.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   272.3 @@ -1,1 +0,0 @@
   272.4 -Επιλέξτε τα γεγονότα για τα οποία θέλετε να λαμβάνετε ειδοποιήσεις μέσω email.
   272.5 \ No newline at end of file
   273.1 --- a/locale/help/member.settings.notification.en.txt	Thu Jul 10 01:02:43 2014 +0200
   273.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   273.3 @@ -1,2 +0,0 @@
   273.4 -=Notification settings=
   273.5 -Please choose which notifications you like to receive from the system by email.
   273.6 \ No newline at end of file
   274.1 --- a/locale/help/member.settings.notification.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   274.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   274.3 @@ -1,2 +0,0 @@
   274.4 -=通知设定=
   274.5 -请选择您想从系统收到的电邮通知种类。
   274.6 \ No newline at end of file
   275.1 --- a/locale/help/member.settings.notification.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   275.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   275.3 @@ -1,2 +0,0 @@
   275.4 -=通知設定=
   275.5 -請選擇您想從系統收到的電郵通知種類。
   275.6 \ No newline at end of file
   276.1 --- a/locale/help/member.settings.password.de.txt	Thu Jul 10 01:02:43 2014 +0200
   276.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   276.3 @@ -1,1 +0,0 @@
   276.4 -Dein neues Kennwort muss mindestens 8 Zeichen lang sein.
   277.1 --- a/locale/help/member.settings.password.el.txt	Thu Jul 10 01:02:43 2014 +0200
   277.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   277.3 @@ -1,4 +0,0 @@
   277.4 -Ο νέος σας κωδικός πρέπει να έχει τουλάχιστον 8 χαρακτήρες. Δώστε προσοχή στα κεφαλαία/πεζά γράμματα, έχουν σημασία.
   277.5 -
   277.6 -**Προσοχή:** Μη δίνετε ποτέ τον κωδικό πρόσβασής σας σε άλλους, ακόμη κι αν ισχυρίζονται πως είναι διαχειριστές.
   277.7 -
   278.1 --- a/locale/help/member.settings.password.en.txt	Thu Jul 10 01:02:43 2014 +0200
   278.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   278.3 @@ -1,1 +0,0 @@
   278.4 -Your new password must have at least 8 characters.
   279.1 --- a/locale/help/member.settings.password.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   279.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   279.3 @@ -1,1 +0,0 @@
   279.4 -Via nova pasvorto devas esti minimume ok signojn longa.
   280.1 --- a/locale/help/member.settings.password.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   280.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   280.3 @@ -1,1 +0,0 @@
   280.4 -您的新密码必须至少有 8 个符号。
   280.5 \ No newline at end of file
   281.1 --- a/locale/help/member.settings.password.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   281.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   281.3 @@ -1,1 +0,0 @@
   281.4 -您的新密碼必須至少有 8 個符號。
   281.5 \ No newline at end of file
   282.1 --- a/locale/help/member.show.de.txt	Thu Jul 10 01:02:43 2014 +0200
   282.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   282.3 @@ -1,9 +0,0 @@
   282.4 -=Profilseite=
   282.5 -Hier kann man erfahren,
   282.6 -- was dieses Mitglied über sich selbst mitteilt,
   282.7 -- in welchen Themenbereichen es Mitglied ist,
   282.8 -- an welchen Themen und Initiativen es sich beteiligt
   282.9 -- welche Delegationen das Mitglied erhalten und erteilt und
  282.10 -- welche Kontakte das Mitglied veröffentlicht hat.
  282.11 -=zu den Kontakten hinzufügen=
  282.12 -Hier kann man das Mitglied außerdem zur eigenen Kontaktliste hinzufügen (und es natürlich auch wieder von dieser entfernen). Bitte beachte, dass man nur an Mitglieder delegieren kann, die man auf die eigene Kontaktliste gesetzt hat.
   283.1 --- a/locale/help/member.show.el.txt	Thu Jul 10 01:02:43 2014 +0200
   283.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   283.3 @@ -1,9 +0,0 @@
   283.4 -==Σελίδα προφίλ==
   283.5 -Εδώ μπορείτε να δείτε:
   283.6 -- Τι λέει αυτό το μέλος για τον εαυτό του και τα στοιχεία που επέλεξε να μοιραστεί
   283.7 -- Σε ποιες ενότητες, τομείς και θέματα συμμετέχει
   283.8 -- Τις αναθέσεις που έχει ορίσει και έχει δεχτεί
   283.9 -- Τις επαφές του επέλεξε να δημοσιεύσει
  283.10 -
  283.11 -=Προσθήκη στις επαφές σας=
  283.12 -Μπορείτε να αποθηκεύσετε αυτό το μέλος στις επαφές σας (και να το αφαιρέσετε πάλι, βεβαίως). Αυτό είναι απαραίτητο όταν, για παράδειγμα, θέλετε να ορίσετε το μέλος ως αντιπρόσωπό σας, αναθέτοντάς του κάποια <<ενότητα>>, <<τομέα>> ή <<θέμα>>.
   284.1 --- a/locale/help/member.show.en.txt	Thu Jul 10 01:02:43 2014 +0200
   284.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   284.3 @@ -1,9 +0,0 @@
   284.4 -=Profile page=
   284.5 -Here you can learn,
   284.6 -- what this member says about him- or herself,
   284.7 -- which areas he or she is a member of,
   284.8 -- in which issues and initiatives he or she participates
   284.9 -- which delegations the member has received and given, and
  284.10 -- which contacts the member has published.
  284.11 -=add to contacts=
  284.12 -You can add this member to your list of contacts (and also remove him or her from it, again, of course). Please note that you can only delegate to members, who are on your list of contacts.
   285.1 --- a/locale/help/member.show.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   285.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   285.3 @@ -1,9 +0,0 @@
   285.4 -=Profilpaĝo=
   285.5 -Ĉi tie vi povas ekscii,
   285.6 -– kion tiu ĉi membro komunikas pri si mem,
   285.7 -– de kiuj temaroj li estas membro,
   285.8 -– kiujn temojn kaj iniciatojn li partoprenas,
   285.9 -– kiujn delegaciojn la membro ricevas kaj donas kaj
  285.10 -– kiujn kontaktojn la membro publikigis.
  285.11 -=Aldoni al la kontaktoj=
  285.12 -Vi povas aldoni tiun ĉi membron al via kontaktlisto (kaj kompreneble denove forigi lin de ĝi). Bonvolu atenti, ke vi povas delegi nur al membroj, kiuj estas en via kontaktlisto.
   286.1 --- a/locale/help/member.show.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   286.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   286.3 @@ -1,9 +0,0 @@
   286.4 -=个人简介=
   286.5 -在此您可了解:
   286.6 -- 此成员对个人的描述
   286.7 -- 他或她是哪些领域的成员
   286.8 -- 他或她参与哪些议题或提案
   286.9 -- 此成员所送出或收到的委任
  286.10 -- 此成员公开的联络人
  286.11 -=加入通讯录=
  286.12 -您可将此成员加入您的通讯录(当然之后可再移除之)。请注意,您只可委任给在您通讯录中的成员。
  286.13 \ No newline at end of file
   287.1 --- a/locale/help/member.show.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   287.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   287.3 @@ -1,9 +0,0 @@
   287.4 -=個人簡介=
   287.5 -在此您可瞭解:
   287.6 -- 此成員對個人的描述
   287.7 -- 他或她是哪些領域的成員
   287.8 -- 他或她參與哪些議題或提案
   287.9 -- 此成員所送出或收到的委任
  287.10 -- 此成員公開的聯絡人
  287.11 -=加入通訊錄=
  287.12 -您可將此成員加入您的通訊錄(當然之後可再移除之)。請注意,您只可委任給在您通訊錄中的成員。
   288.1 --- a/locale/help/policy.list.de.txt	Thu Jul 10 01:02:43 2014 +0200
   288.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   288.3 @@ -1,1 +0,0 @@
   288.4 -Die folgenden Regelwerke sind zur Zeit konfiguriert. Nicht alle Regelwerke müssen in jedem Themengebiet verfügbar sein.
   289.1 --- a/locale/help/policy.list.el.txt	Thu Jul 10 01:02:43 2014 +0200
   289.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   289.3 @@ -1,4 +0,0 @@
   289.4 -==Κανονισμοί==
   289.5 -Οι κανονισμοί καθορίζουν τη διάρκεια των σταδίων των θεμάτων και τις ποσοτικές παραμέτρους πλειοψηφίας και απαρτίας. Κάθε θέμα υπόκειται σε έναν από τους παρακάτω κανονισμούς.
   289.6 -
   289.7 -//Σημείωση:// Μπορεί κάποιοι κανονισμοί να μην είναι διαθέσιμοι σε όλους τους τομείς και κατ' επέκταση στα θέματα τους.
   289.8 \ No newline at end of file
   290.1 --- a/locale/help/policy.list.en.txt	Thu Jul 10 01:02:43 2014 +0200
   290.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   290.3 @@ -1,1 +0,0 @@
   290.4 -The following policies are currently configured. Not all policies are available in every subject area.
   291.1 --- a/locale/help/policy.list.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   291.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   291.3 @@ -1,1 +0,0 @@
   291.4 -La sekvontaj regularoj estas nuntempe agorditaj. Ne ĉiuj regularoj devas esti atingeblaj ĉe ĉiu temaro.
   292.1 --- a/locale/help/policy.list.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   292.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   292.3 @@ -1,1 +0,0 @@
   292.4 -下列规则是目前所设定的。并非所有规则在每个主题领域都适用。
   292.5 \ No newline at end of file
   293.1 --- a/locale/help/policy.list.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   293.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   293.3 @@ -1,1 +0,0 @@
   293.4 -下列規則是目前所設定的。並非所有規則在每個主題領域都適用。
   293.5 \ No newline at end of file
   294.1 --- a/locale/help/vote.list.de.txt	Thu Jul 10 01:02:43 2014 +0200
   294.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   294.3 @@ -1,11 +0,0 @@
   294.4 -= Abstimmung =
   294.5 -
   294.6 -Zu Beginn der Abstimmung befinden sich alle Initiativen im Feld Enthaltung. Beginne am besten mit deinem Favoriten und ziehe ihn mit der Maus in das Feld Zustimmung. Danach wählst du die nächste Initiative, der du zustimmen möchtest und ziehst sie
   294.7 -- in die gleiche grüne Box, falls du dieser Initiative gleichberechtigt zustimmen möchtest oder
   294.8 -- zwischen die Zustimmungs- und Enthaltungsbox, falls diese Initiative dein Ersatzwunsch sein soll.
   294.9 -
  294.10 -Auf diese Weise fährst du fort und legst die Präferenzreihenfolge der Initiativen, denen du zustimmen möchtest fest, wobei du gleichwertige Initiativen jeweils in die gleiche Box hineinziehst. Dann legst du deine Enthaltungen und Ablehnungen fest, wobei du auch die Ablehnungen in eine Rangreihenfolge bringen kannst, falls eine der Initiativen so etwas wie das ,,kleinere Übel'' darstellen sollte.
  294.11 -
  294.12 -**Wichtig:** Verlasse diese Seite über die Schaltfläche ,,Stimmabgabe abschließen''. Bis zum Ende der Abstimmung kannst du deine Angaben jederzeit ändern. Es werden keine Zwischenergebnisse der Abstimmung veröffentlicht. Die Unterstützerangaben auf der Themenübersichtsseite beziehen sich auf die abgeschlossene Diskussion, beziehen sich jeweils auf die einzelne Initiative und sind nur sehr bedingt geeignet, zwischen den Initiativen zu vergleichen. Insbesondere enthalten sie keinerlei Informationen über Präferenzen. Darüber hinaus kann sich der Teilnehmerkreis von Diskussion und Abstimmung erheblich unterscheiden.
  294.13 -
  294.14 -**Achtung:** Auf einigen Plattformen (zum Beispiel Smartphones oder Tablet-Computern) ist das Ziehen von Initiativen mit der Maus nicht möglich. In diesem Falle können die Pfeile links neben den jeweiligen Initiativen verwendet werden.
   295.1 --- a/locale/help/vote.list.el.txt	Thu Jul 10 01:02:43 2014 +0200
   295.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   295.3 @@ -1,13 +0,0 @@
   295.4 -==Ψηφοφορία==
   295.5 -Κατά την έναρξη της ψηφοφορίας όλες οι πρωτοβουλίες θα είναι στο πλαίσιο <<Αποχή>>. Συνιστάται να ξεκινήσετε με την αγαπημένη σας και την σύρετε με το ποντίκι σας στο πλαίσιο <<Επιδοκιμασίας>>. Στη συνέχεια επιλέξτε την επόμενη πρωτοβουλία που θέλετε να εγκρίνετε και σύρετέ την είτε:
   295.6 -- Στο ίδιο πράσινο κουτί, αν θέλετε να την εγκρίνετε εξίσου ή
   295.7 -- Μεταξύ του πλαισίου <<Επιδοκιμασίας>> και <<Αποχής>>, αν θέλετε αυτή η πρωτοβουλία να είναι δεύτερη επιλογή σας.
   295.8 -
   295.9 -Συνεχίζοντας έτσι καθορίζετε τη σειρά προτίμησης των πρωτοβουλιών που θέλετε να εγκρίνετε, δηλαδή σέρνετε ίσης προτίμησης πρωτοβουλίες στο ίδιο κουτί. Στη συνέχεια, καθορίζετε αυτές που απέχετε και αυτές που αποδοκιμάζετε, πράγμα που σημαίνει ότι μπορείτε επίσης να ορίσετε τη σειρά προτίμησης για τις απορρίψεις, για την περίπτωση που μία από τις πρωτοβουλίες αντιπροσωπεύει το "μικρότερο κακό''.
  295.10 -
  295.11 -**Σημαντικό:** Για να φύγετε από αυτή την σελίδα πατήστε το κουμπί <<Ολοκλήρωση ψήφου>>. Μπορείτε να αλλάξετε τις ψήφους σας οποιαδήποτε στιγμή μέχρι το τέλος της ψηφοφορίας.
  295.12 -
  295.13 -=Αποτελέσματα κατά τη διάρκεια της ψηφοφορίας=
  295.14 -Κατά τη διάρκεια της ψηφοφορίας δεν δημοσιεύονται ενδιάμεσα αποτελέσματα. Τα στοιχεία που παρουσιάζονται στη σελίδα επισκόπησης αναφέρονται μόνο στην αντίστοιχη πρωτοβουλία και είναι κατάλληλα μόνο για συγκρίσεις σε περιορισμένο βαθμό. Ειδικότερα, δεν περιέχουν καμία πληροφορία σχετικά με τις προτιμήσεις και επιπλέον η ομάδα των ατόμων που συμμετέχουν στη συζήτηση μπορεί να είναι πολύ διαφορετική από αυτούς που πραγματικά ψηφίζουν.
  295.15 -
  295.16 -//Σημείωση:// Σε ορισμένες πλατφόρμες (π.χ. κινητά τηλέφωνα ή υπολογιστές tablet) μπορεί να μην είναι δυνατό να σύρετε τις πρωτοβουλίες. Σε αυτές τις περιπτώσεις, χρησιμοποιήστε το πάνω και το κάτω βέλος αριστερά της κάθε πρωτοβουλίας.
  295.17 \ No newline at end of file
   296.1 --- a/locale/help/vote.list.en.txt	Thu Jul 10 01:02:43 2014 +0200
   296.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   296.3 @@ -1,11 +0,0 @@
   296.4 -= Voting =
   296.5 -
   296.6 -At the beginning of the voting all initiatives will be in the Abstention field. It is recommended to start with your favourite and drag it with your mouse into the Approval field. Then you select the next initiative that you want to approve and drag it either
   296.7 -- into the same green box, if you want to approve it equally  or
   296.8 -- between the Approval and Abstention box, if you want this initiative to be your second choice.
   296.9 -
  296.10 -Continuing like this you define the preference list of the initiatives, that you want to approve, i.e. you drag equal initiatives into the same box. Then you specify your abstentions and disapprovals, meaning that you can also define a preference list for disapprovals, just in case one of the initiatives should represent something like a ,,minor evil''.
  296.11 -
  296.12 -**Important:** Leave this page via the ,,Finish voting'' button. You can change your votes anytime until the end of the voting. During the voting no interim results are published. The support data on the issue overview page refers to the single respective initiative and is only suited to a very limited extent to compare different initiatives. Especially, it contains no information whatsoever about preferences. Moreover, the group of those  participating in the discussion can be very different from those who actually vote.
  296.13 -
  296.14 -**Notice:** On some platforms (e.g. smartphones or tablet computers) "drag and drop" via mouse is not possible. In these cases use the up and down arrows left of each initiative.
   297.1 --- a/locale/help/vote.list.eo.txt	Thu Jul 10 01:02:43 2014 +0200
   297.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   297.3 @@ -1,8 +0,0 @@
   297.4 -=Voĉdono=
   297.5 -Depende, kiujn agordojn vi elektis, ĉiuj iniciatoj troviĝas komence en la kampo „sindeteno“ aŭ en la kampo „malkonsento“. Komencu pli bone kun via favorato kaj tiru ĝin permuse en la kampon „konsento“. Poste vi elektas la sekvan iniciaton, kiun vi volas konsenti kaj tiras ĝin
   297.6 -– en la saman verdan ujon, se vi ŝatus samrajte konsenti kun tiu ĉi iniciato aŭ
   297.7 -– inter la konsento- kaj la sindetenujojn, se tiu ĉi iniciato estu via anstataŭa deziro.
   297.8 -
   297.9 -Tiamaniere, vi daŭrigas kaj decidas la prefervicon de la iniciatoj, kun kiuj vi ŝatus konsenti, ĉe kio vi tiras samrangajn iniciatojn en la saman ujon. Tiam vi decidas la sindetenojn kaj la malkonsentojn, ĉe kio vi povas meti ankaŭ la malkonsentojn en prefervicon, se unu el la iniciatoj ŝajnus „la pli malgranda malbono“.
  297.10 -
  297.11 -**Grave:** Forlasu tiun ĉi paĝon per la butono „fini voĉdonadon“. Ĝis la fino de la voĉdonado vi povas ĉiutempe ŝanĝi viajn deklarojn. Provizoraj rezultoj de la voĉdono ne publikiĝas. La indiko de subtenantoj rilatas al finitaj diskutoj, rilatas al la aparta iniciato kaj nur tre relative taŭgas por kompari inter iniciatoj. Precipe, ili ne enhavas informojn pri preferoj. Krome, la partoprenantaroj de diskuto kaj voĉdono povas konsiderinde malsami.
   298.1 --- a/locale/help/vote.list.zh-Hans.txt	Thu Jul 10 01:02:43 2014 +0200
   298.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   298.3 @@ -1,12 +0,0 @@
   298.4 -= 表决 =
   298.5 -
   298.6 -在表决开始时所有提案都放置在弃权区。我们建议您从您最喜爱的提案开始,并以滑鼠将其拖移至赞同区。然后选择下一个您所赞同的提案并将其拖移
   298.7 -- 若您对两者同样赞同,拖移至同个绿盒子内
   298.8 -- 若您想将此提案成为第二选择,就拖移至赞同与弃权区间
   298.9 -
  298.10 -
  298.11 -如此继续,您便指定了您所赞同的提案的偏好列表,也就是您将一样赞同的提案都拖移到同个盒子里。然后您指定您所要弃权或否决的提案,也就是在某个提案对您来说只是个「小恶魔」时,您也指定您所否决的提案的偏好列表。
  298.12 -
  298.13 -**重要:** 请藉由「完成投票」按钮离开本页面。直到表决结束您都可更改您的投票。在表决期间不会有临时结果被公开。议题概观页面所显示的支持统计资料只针对单一提案,并且对于比较不同的提案只有非常局限的用途。特别是,它并不含有任何关于偏好的资讯。再者,参与讨论的成员组成可能与实际参与表决的成员组成非常不同。
  298.14 -
  298.15 -**注意:** 在某些平台(例如智慧型手机或平板电脑)以滑鼠拖放是不可能的。在此状况下请使用个案左侧的上下箭头。
  298.16 \ No newline at end of file
   299.1 --- a/locale/help/vote.list.zh-TW.txt	Thu Jul 10 01:02:43 2014 +0200
   299.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   299.3 @@ -1,12 +0,0 @@
   299.4 -= 表決 =
   299.5 -
   299.6 -在表決開始時所有提案都放置在棄權區。我們建議您從您最喜愛的提案開始,並以滑鼠將其拖移至贊同區。然後選擇下一個您所贊同的提案並將其拖移
   299.7 -- 若您對兩者同樣贊同,拖移至同個綠盒子內
   299.8 -- 若您想將此提案成為第二選擇,就拖移至贊同與棄權區間
   299.9 -
  299.10 -
  299.11 -如此繼續,您便指定了您所贊同的提案的偏好列表,也就是您將一樣贊同的提案都拖移到同個盒子裡。然後您指定您所要棄權或否決的提案,也就是在某個提案對您來說只是個「小惡魔」時,您也指定您所否決的提案的偏好列表。
  299.12 -
  299.13 -**重要:** 請藉由「完成投票」按鈕離開本頁面。直到表決結束您都可更改您的投票。在表決期間不會有臨時結果被公開。議題概觀頁面所顯示的支持統計資料只針對單一提案,並且對於比較不同的提案只有非常侷限的用途。特別是,它並不含有任何關於偏好的資訊。再者,參與討論的成員組成可能與實際參與表決的成員組成非常不同。
  299.14 -
  299.15 -**注意:** 在某些平台(例如智慧型手機或平板電腦)以滑鼠拖放是不可能的。在此狀況下請使用個案左側的上下箭頭。 
   300.1 --- a/locale/help/wikisyntax.en.txt	Thu Jul 10 01:02:43 2014 +0200
   300.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   300.3 @@ -1,6 +0,0 @@
   300.4 -==== Wiki Help ====
   300.5 -
   300.6 -You can choose between this different syntaxes:
   300.7 -
   300.8 -[wikisyntax_rocketwiki.html RocketWiki]
   300.9 -[wikisyntax_compat.html Traditional wiki syntax]
   301.1 --- a/locale/help/wikisyntax_compat.en.txt	Thu Jul 10 01:02:43 2014 +0200
   301.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   301.3 @@ -1,31 +0,0 @@
   301.4 -<- [wikisyntax.html Wiki Help]
   301.5 -
   301.6 -==== Traditional Wiki-Syntax ====
   301.7 -- ++Headings++
   301.8 --- = Main Heading (H1) =
   301.9 --- == Heading (H2) ==
  301.10 --- === Sub-Heading (H3) ===
  301.11 --- ==== Sub-Sub-Heading (H4) ====
  301.12 -- ++Horizontal line++
  301.13 --- ---
  301.14 -- ++Unnumbered lists++
  301.15 --- * Toplevel Entry
  301.16 --- ** Sub Entry
  301.17 -- ++Numbered list++
  301.18 --- # Toplevel Entry
  301.19 --- ## Sub Entry
  301.20 -- ++Font style++
  301.21 --- {{'''bold'''}}
  301.22 --- {{''italic''}}
  301.23 --- {{<tag>possible tags: big, small, sup, sub, tt, nobr</tag>}}
  301.24 --- {{{{no special interpretation of formatting characters}}}}
  301.25 -- ++Text flow++
  301.26 --- non-breaking(_)space
  301.27 --- soft(-)hypen
  301.28 -- ++Dashes++
  301.29 --- En{{{--}}}Dash
  301.30 --- Em{{{---}}}Dash
  301.31 -- ++Line break++
  301.32 --- {{<br>}}
  301.33 -- ++Links++
  301.34 --- {{[http://example.org/ link text]}}
   302.1 --- a/locale/help/wikisyntax_rocketwiki.en.txt	Thu Jul 10 01:02:43 2014 +0200
   302.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   302.3 @@ -1,52 +0,0 @@
   302.4 -<- [wikisyntax.html Wiki Help]
   302.5 -
   302.6 -==== RocketWiki ====
   302.7 -- ++Headings++
   302.8 --- ==== Main Heading (H1) ====
   302.9 --- === Heading (H2) ===
  302.10 --- == Sub-Heading (H3) ==
  302.11 --- = Sub-Sub-Heading (H4) =
  302.12 -- ++Horizontal line++
  302.13 --- ---
  302.14 -- ++Unnumbered lists++
  302.15 --- - Toplevel Entry
  302.16 --- -- Sub Entry
  302.17 -- ++Numbered list++
  302.18 --- # Toplevel Entry
  302.19 --- ## Sub Entry
  302.20 -- ++Font style++
  302.21 --- {{**bold**}}
  302.22 --- {{//italic//}}
  302.23 --- {{__underlined__}}
  302.24 --- {{++big++}}
  302.25 --- {{%%small%%}}
  302.26 --- {{||monospaced||}}
  302.27 --- {{&&no line break&&}}
  302.28 --- {{{{no special interpretation of formatting characters}}}}
  302.29 -- ++Quotes++
  302.30 --- {{""normal english quotes""}}
  302.31 --- {{"""single english quotes"""}}
  302.32 --- {{,,normal german quotes''}}
  302.33 --- {{,,,single german quotes'''}}
  302.34 --- {{<<normal french quotes>>}}
  302.35 --- {{<<<single french quotes>>>}}
  302.36 -- ++Text flow++
  302.37 --- non-breaking(_)space
  302.38 --- soft(-)hypen
  302.39 -- ++Special characters++
  302.40 --- {{{EUR}}} sign
  302.41 --- German umlauts: {{{Ae} {Oe} {Ue} {ae} {oe} {ue}}}
  302.42 --- German SZ-ligature: {{{sz} or {ss}}}
  302.43 --- Mid{{{.}}}dot
  302.44 --- Ellipsis {{{...}}}
  302.45 --- Arrows {{{->} {=>} {<->}}} etc. 
  302.46 --- {{{C} 2009, Registered{R}, Trademark{TM}}}
  302.47 --- {{360{deg} 0{'} 0{''}}} **=>** 360{deg} 0{'} 0{''}
  302.48 --- {{{1/4} + {1/2} = {3/4}}} **=>** {1/4} + {1/2} = {3/4}
  302.49 --- {{10{%o} = 1%}} **=>** 10{%o} = 1%
  302.50 --- {{(5 {-} 1) {x} 3 {/} 4 {=} 3}} **=>** (5 {-} 1) {x} 3 {/} 4 {=} 3
  302.51 -- ++Dashes++
  302.52 --- En{{{--}}}Dash
  302.53 --- Em{{{---}}}Dash
  302.54 -- ++Links++
  302.55 --- {{[http://example.org/ link text]}}
   303.1 --- a/locale/translations.de.lua	Thu Jul 10 01:02:43 2014 +0200
   303.2 +++ b/locale/translations.de.lua	Thu Jul 10 01:19:48 2014 +0200
   303.3 @@ -1,36 +1,61 @@
   303.4  #!/usr/bin/env lua
   303.5  return {
   303.6 +["#{closed_ago} ago"] = "vor #{closed_ago}";
   303.7 +["#{count} Neutral"] = "#{count} Enthaltung";
   303.8 +["#{count} No"] = "#{count} Nein";
   303.9 +["#{count} Yes, alternative choice"] = "#{count} Ja, Alternativstimme";
  303.10 +["#{count} Yes, first choice"] = "#{count} Ja, Erststimme";
  303.11  ["#{count} canceled"] = "#{count} abgebrochen";
  303.12 -["#{count} days ago"] = "vor #{count} Tagen";
  303.13  ["#{count} finished"] = "#{count} abgeschlossen";
  303.14  ["#{count} in discussion"] = "#{count} in Diskussion";
  303.15  ["#{count} in verification"] = "#{count} eingefroren";
  303.16  ["#{count} in voting"] = "#{count} in Abstimmung";
  303.17 -["#{count} more areas in this unit"] = "#{count} weitere Themengebiete in dieser Gliederung";
  303.18 +["#{count} matching issues found"] = "#{count} passende Themen gefunden";
  303.19 +["#{count} matching members found"] = "#{count} passende Mitglieder gefunden";
  303.20 +["#{count} more areas in this unit"] = "#{count} weitere Themenbereiche in dieser Gliederung";
  303.21  ["#{count} new"] = "#{count} neue";
  303.22  ["#{count} of them have an area delegation set"] = "bei #{count} davon ist eine Delegation für den Themenbereichs gesetzt";
  303.23  ["#{count} of your outgoing delegation(s) are broken"] = "#{count} deiner ausgehenden Delegationen sind kaputt";
  303.24 -["#{date} at #{time}"] = "am #{date} um #{time}";
  303.25 +["#{count} supporter"] = "#{count} Unterstützer";
  303.26 +["#{duration}"] = false;
  303.27  ["#{interested_issues_to_vote_count} issue(s) you are interested in"] = "#{interested_issues_to_vote_count} Themen, die Dich interessieren";
  303.28  ["#{interval_text} [interval]"] = "#{interval_text}";
  303.29  ["#{interval_text} ago"] = "vor #{interval_text}";
  303.30  ["#{interval_text} left"] = "noch #{interval_text}";
  303.31 +["#{interval} ago"] = "vor #{interval}";
  303.32  ["#{issues_to_vote_count} issue(s)"] = "#{issues_to_vote_count} Themen";
  303.33 +["#{issue} is in voting"] = "#{issue} ist in Abstimmung";
  303.34  ["#{name}\n\n"] = "#{name}\n\n";
  303.35  ["#{number} Image(s) has been deleted"] = "Es wurde(n) #{number} Bild(er) gelöscht";
  303.36  ["#{number} Image(s) has been updated"] = "Es wurde(n) #{number} Bild(er) aktualisiert";
  303.37 +["#{percentage}%"] = false;
  303.38  ["#{policy_name} ##{issue_id}"] = false;
  303.39  ["#{policy} ##{id}"] = false;
  303.40 -["(#{more_count} duplicates removed)"] = "(#{more_count} Duplikate entfernt)";
  303.41 +["#{result}: #{yes_count} Yes (#{yes_percent}), #{no_count} No (#{no_percent}), #{neutral_count} Abstention (#{neutral_percent})"] = "#{result}: #{yes_count} Ja (#{yes_percent}), #{no_count} Nein (#{no_percent}), #{neutral_count} Enthaltung (#{neutral_percent})";
  303.42 +["#{result}: No votes (0)"] = "#{result}: Keine Stimmen (0)";
  303.43 +["(+ #{count} potential)"] = "(+ #{count} potentielle)";
  303.44 +["(1) Admission"] = "(1) Zulassung";
  303.45 +["(1) Admission phase"] = "(1) Zulassungsphase";
  303.46 +["(2) Discussion"] = "(2) Diskussion";
  303.47 +["(2) Discussion phase"] = "(2) Diskussionsphase";
  303.48 +["(3) Verification"] = "(3) Überprüfung";
  303.49 +["(3) Verification phase"] = "(3) Überprüfungsphase";
  303.50 +["(4) Voting"] = "(4) Abstimmung";
  303.51 +["(4) Voting phase"] = "(4) Abstimmungsphase";
  303.52 +["(5) Result"] = "(5) Ergebnis";
  303.53 +["(invited)"] = "(eingeladen)";
  303.54  ["(new window)"] = "(neues Fenster)";
  303.55 -[")) == "] = false;
  303.56  ["+ #{weight}"] = "+ #{weight}";
  303.57 +["+ add new organizational unit"] = "+ neue Gliederung hinzufügen";
  303.58 +["+ add new subject area"] = "neuen Themenbereich hinzufügen";
  303.59  ["+getElementById("] = false;
  303.60 +["1 matching issue found"] = "1 passendes Thema gefunden";
  303.61 +["1 matching member found"] = "1 passendes Mitglied gefunden";
  303.62 +["4 phases of a decision"] = "4 Phasen einer Entscheidung";
  303.63 +["A short title (80 chars max)"] = "Ein kurzer Titel (max. 80 Zeichen)";
  303.64  ["A-Z"] = "A-Z";
  303.65 -["API Key"] = "API-Key";
  303.66  ["API key has been created"] = "API-Schlüssel wurde erzeugt";
  303.67  ["API key has been deleted"] = "API-Schlüssel wurde gelöscht";
  303.68 -["API keys"] = "API-Schlüssel";
  303.69  ["Abandon global delegation for this area"] = "Aussetzen der globale Delegation";
  303.70  ["Abandon unit and area delegations for this issue"] = "Aussetzen der Gliederungs-/Themenbereichsdelegation";
  303.71  ["Abandon unit delegation"] = "Aussetzen der Gliederungsdelegation";
  303.72 @@ -39,30 +64,22 @@
  303.73  ["Abstention"] = "Enthaltung";
  303.74  ["Abstention [many entries]"] = "Enthaltung";
  303.75  ["Abstention [single entry]"] = "Enthaltung";
  303.76 -["Accept invitation"] = "Einladung annehmen";
  303.77  ["Accepted at"] = "Angenommen am/um";
  303.78 -["Access level"] = "Berechtigung";
  303.79 -["Activate account"] = "Account aktivieren";
  303.80 +["Account history"] = "Kontoverlauf";
  303.81  ["Active?"] = "Aktiv?";
  303.82 -["Add alternative initiative to issue"] = "Alternative Initiative zum Thema hinzufügen";
  303.83 -["Add my interest"] = "Mein Interesse anmelden";
  303.84 -["Add new suggestion"] = "Neue Anregung hinzufügen";
  303.85 -["Add new unit"] = "Neue Gliederung";
  303.86 -["Add to my contacts"] = "Zu meinen Kontakten hinzufügen";
  303.87 +["Add a new competing initiative to issue"] = "Eine neue konkurrierende Initiative hinzufügen";
  303.88 +["Add a new suggestion for improvement"] = "Einen neuen Verbesserungsvorschlag";
  303.89  ["Address"] = "Anschrift";
  303.90 -["Admin"] = "Admin";
  303.91 -["Admin menu"] = "Admin Menü";
  303.92  ["Admin?"] = "Admin?";
  303.93 +["Administrative notice:"] = "Administrativer Kommentar";
  303.94 +["Admission"] = "Zulassung";
  303.95  ["Admission time"] = "Zeit für die Zulassung";
  303.96  ["Admitted"] = "zugelassen";
  303.97 -["All areas"] = "Alle Themenbereiche";
  303.98 -["All areas in my units"] = "Alle Themengebiete in meinen Gliederungen";
  303.99 -["All issues"] = "Alle Themen";
 303.100 -["All of them"] = "Alle Benachrichtigungen";
 303.101 +["All areas in my units"] = "Alle Themenbereiche in meinen Gliederungen";
 303.102 +["All fields are optional. Please enter only data which should be published."] = "Alle Felder sind optional. Bitte nur Daten eingeben, die veröffentlicht werden sollen.";
 303.103 +["All initiatives failed 2nd quorum"] = "Alle Initiativen sind am 2. Quorum gescheitert";
 303.104  ["All units"] = "Alle Gliederungen";
 303.105 -["Any"] = "Alle";
 303.106 -["Any phase"] = "Alle Phasen";
 303.107 -["Any state"] = "Alle Zustände";
 303.108 +["Allowed policies"] = "Erlaubte Regelwerke";
 303.109  ["Apply global delegation for this area (Currently: #{delegate_name} [#{scope}])"] = "Anwenden der globalen Delegation (Zur Zeit: #{delegate_name} [#{scope}])";
 303.110  ["Apply global or area delegation for this issue (Currently: #{delegate_name} [#{scope}])"] = "Anwenden der globalen bzw. Themenbereichsdelegation (Zur Zeit: #{delegate_name} [#{scope}])";
 303.111  ["Apply unit delegation for this area (Currently: #{delegate_name} [#{scope}])"] = "Anwenden der Gliederungsdelegation (Zur Zeit: #{delegate_name} [#{scope}])";
 303.112 @@ -78,111 +95,91 @@
 303.113  ["Approval [many entries]"] = "Zustimmung";
 303.114  ["Approval [single entry]"] = "Zustimmung";
 303.115  ["Approved"] = "Angenommen";
 303.116 -["Are you sure?"] = "Sicher?";
 303.117 +["Are you aware that revoking an initiative is irrevocable?"] = "Bist du dir bewusst, dass das Zurückziehen unwiderrufbar ist?";
 303.118  ["Area"] = "Themenbereich";
 303.119 -["Area '#{name}'"] = "Themenbereich '#{name}'";
 303.120  ["Area delegation"] = "Delegation für Themenbereich";
 303.121  ["Area list of '#{unit_name}'"] = "Themenbereiche in '#{unit_name}'";
 303.122 -["Areas"] = "Themenbereiche";
 303.123 +["As long as you are interested in this issue yourself, the delegation is suspended for this issue, but it will be applied again in the voting phase unless you vote yourself."] = "Solange du selber am Thema interessiert bist, wird die Delegation für dieses Thema ausgesetzt, jedoch während der Abstimmung erneut aktiv, es sei denn du stimmst selber ab.";
 303.124 +["As soon as one initiative of this issue reaches #{quorum} support, the issue will go into discussion phase."] = "Sobald eine Initiative des Themas das 1. Quorum von #{quorum} Unterstützern erreicht, geht das Thema in die Diskussionsphase über.";
 303.125  ["Author"] = "Autor";
 303.126 +["Available policies"] = "Verfügbare Regelwerke";
 303.127  ["Avatar"] = "Avatar";
 303.128  ["Back"] = "Zurück";
 303.129 -["Back to initiative"] = "Zurück zur Initiative";
 303.130 -["Back to timeline"] = "Zurück zur Zeitachse";
 303.131 -["Ballot of '#{member_name}' for issue ##{issue_id}"] = "Stimmzettel von '#{member_name}' für Thema ##{issue_id}";
 303.132 +["Ballot of '#{member_name}'"] = "Stimmzettel von '#{member_name}'";
 303.133  ["Become a member"] = "Mitglied werden";
 303.134 +["Before creating a new issue, please check any existant issues before, if the topic is already in discussion."] = "Bitte vor dem Erstellen prüfen, ob ein anderes existierendes Thema passt!";
 303.135 +["Best not admitted initiative"] = "Beste nicht zugelassene Initiative";
 303.136  ["Birthday"] = "Geburtstag";
 303.137  ["Broken delegations"] = "Kaputte Delegationen";
 303.138 -["By delegation"] = "Durch Delegationen";
 303.139  ["Calculation"] = "Auszählung";
 303.140  ["Can't remove last initiator"] = "Der letzte Initiator kann nicht entfernt werden";
 303.141  ["Can't send confirmation email"] = "Bestätigungs-E-Mail kann nicht versendet werden.";
 303.142  ["Cancel"] = "Abbrechen";
 303.143  ["Cancel [nullify]"] = "Aufheben";
 303.144  ["Cancel issue"] = "Thema abbrechen";
 303.145 -["Cancel issue #{id}"] = "Thema #{id} abbrechen";
 303.146 -["Cancel issue now"] = "Thema jetzt abbrechen";
 303.147 -["Cancel refuse of invitation"] = "Ablehnung der Einladung aufheben";
 303.148 -["Cancel registration"] = "Registrierung abbrechen";
 303.149 -["Canceled"] = "Abgebrochen";
 303.150 -["Canceled (before accepted due to revocation)"] = "Abgebrochen (in Neu-Phase, wegen Rückzug)";
 303.151 -["Canceled (during discussion due to revocation)"] = "Abgebrochen (während Diskussion, wegen Rückzug)";
 303.152 -["Canceled (during verification due to revocation)"] = "Abgebrochen (während Eingefroren-Phase, wegen Rückzug)";
 303.153 -["Canceled (issue not accepted)"] = "Abgebrochen (Thema nicht akzeptiert)";
 303.154 -["Canceled (no initiative admitted)"] = "Abgebrochen (Keine Initiative zugelassen)";
 303.155 +["Cancel issue ##{id}"] = "Thema ##{id} abbrechen";
 303.156  ["Canceled by administrative intervention"] = "Durch administrativen Eingriff abgebrochen";
 303.157 -["Change area delegation"] = "Delegation für Themenbereich ändern";
 303.158 -["Change email"] = "E-Mail-Adresse ändern";
 303.159  ["Change email address"] = "E-Mail-Adresse ändern";
 303.160 -["Change issue delegation"] = "Delegation für Thema ändern";
 303.161 -["Change login"] = "Login ändern";
 303.162 -["Change name"] = "Name ändern";
 303.163 -["Change notification settings"] = "Benachrichtigungseinstellungen ändern";
 303.164  ["Change order"] = "Sortierung ändern";
 303.165 -["Change password"] = "Kennwort ändern";
 303.166 -["Change unit delegation"] = "Delegation für Gliederung ändern";
 303.167 -["Change vote"] = "Abstimmung ändern";
 303.168 -["Change your login"] = "Deinen Anmeldenamen ändern";
 303.169 -["Change your notification email address"] = "Deine E-Mail-Adresse für Benachrichtigungen ändern";
 303.170 -["Change your password"] = "Dein Kennwort ändern";
 303.171 -["Change your screen name"] = "Deinen Screen-Namen ändern";
 303.172 -["Check delegations"] = "Delegationen pr\000fen";
 303.173 -["Check your delegations!"] = "Delegationen pr\000fen!";
 303.174 -["Choose initiator"] = "Initiator auswählen";
 303.175 +["Check and enter personal data"] = "Persönliche Daten prüfen und eingeben";
 303.176 +["Check your #{scope} delegation to '#{trustee_name}' for '#{context}'"] = "Delegation für #{scope} '#{context}' an '#{trustee_name}' prüfen";
 303.177 +["Check your delegations!"] = "Delegationen prüfen!";
 303.178 +["Check your outgoing delegations"] = "Ausgehende Delegation prüfen!";
 303.179 +["Choose a formatting engine:"] = "Formatierungsmethode auswählen";
 303.180 +["Choose a member to invite"] = "Wer soll eingeladen werden?";
 303.181 +["Choose an initiator to remove"] = "Wer soll entfernt werden?";
 303.182  ["Choose member"] = "Mitglied auswählen";
 303.183 +["Choose your delegatee"] = "Delegierten ausw\000hlen";
 303.184  ["Closed"] = "geschlossen";
 303.185  ["Closed issues"] = "Geschlossene Themen";
 303.186 -["Closed user group, please login to participate."] = "Geschlossene Benutzergruppe: Bitte melde dich an um teilzunehmen.";
 303.187 +["Closed user group"] = "Geschlossene Benutzergruppe";
 303.188  ["Collective opinion of supporters"] = "Meinungsbild der Unterstützer";
 303.189 -["Commit suggestion"] = "Anregung speichern";
 303.190  ["Compare"] = "Vergleichen";
 303.191 +["Comparision of revisions #{id1} and #{id2}"] = "Vergleich der Revisionen #{id1} und #{id2}";
 303.192 +["Competing initiatives"] = "Konkurrierende Initiativen";
 303.193 +["Competing initiatives failed the 2nd quorum (#{num}/#{den}):"] = "Konkurrierende Initiativen, die am 2. Quorum (#{num}/#{den}) scheiterten:";
 303.194 +["Competing initiatives in pairwise comparison to best initiative:"] = "Konkurrierende Initiativen im Vergleich zur besten:";
 303.195 +["Competing initiatives in pairwise comparison to winner:"] = "Konkurrierende Initiativen im Vergleich zum Gewinner";
 303.196  ["Configure notifications now"] = "Benachrichtigungen jetzt konfigurieren";
 303.197  ["Confirm"] = "Bestätigen";
 303.198 +["Confirm notification address"] = "Benachrichtungsadresse bestätigen";
 303.199 +["Confirm your email address"] = "E-Mail-Adresse bestätigen";
 303.200  ["Confirmation code"] = "Bestätigungscode";
 303.201  ["Confirmation code invalid!"] = "Bestätigungscode ist ungültig!";
 303.202 -["Confirmed address"] = "Bestätigte E-Mail";
 303.203  ["Contacts"] = "Kontakte";
 303.204 -["Content"] = "Inhalt";
 303.205 -["Counting starts soon"] = "Auszählung beginnt in Kürze";
 303.206 -["Create / edit area"] = "Themengebiet anlegen / bearbeiten";
 303.207 -["Create / edit policy"] = "Regelwerk anlegen / bearbeiten";
 303.208 -["Create alternative initiative"] = "Alternative Initiative hinzufügen";
 303.209 +["Create a new issue"] = "Neues Thema erstellen";
 303.210  ["Create new area"] = "Neuen Themenbereich anlegen";
 303.211 -["Create new issue"] = "Neues Thema anlegen";
 303.212  ["Create new policy"] = "Neues Regelwerk anlegen";
 303.213  ["Create new unit"] = "Neue Gliederung anlegen";
 303.214  ["Created at"] = "Erzeugt am/um";
 303.215 +["Current delegatee"] = "Aktueller Delegierter";
 303.216  ["Current name"] = "Aktueller Name";
 303.217  ["Current phase is already closed."] = "Die aktuelle Phase ist schon abgeschlossen.";
 303.218  ["Current status"] = "Aktueller Status";
 303.219 -["Current trustee"] = "Aktueller Delegierter";
 303.220  ["Current unit and area delegations need confirmation"] = "Aktuelle Gliederungs- und Themenbereichsdelegationen benötigen Bestätigung";
 303.221  ["Current votings in areas you are member of and issues you are interested in:"] = "Jetzt laufende Abstimmungen zu Themen aus Deinen Themenbereichen oder solchen an denen Du interessiert bist:";
 303.222  ["Currently no API key is set."] = "Zur Zeit ist kein API-Schlüssel festgelegt.";
 303.223  ["Currently required"] = "Zur Zeit benötigt";
 303.224 -["Database download"] = "Datenbank herunterladen";
 303.225 +["Currently this is the only initiative in this issue, because nobody started a competing initiative (yet)."] = "Zur Zeit ist dies die einzige Initiative in diesem Thema, da (noch) keine konkurrierende Initiative gestartet wurde.";
 303.226  ["Date format is not valid. Please use following format: YYYY-MM-DD"] = "Datumsformat nicht korrekt. Bitte verwende: JJJJ-MM-TT, also z.B. 1945-05-23";
 303.227  ["Default Policy"] = "Standard-Regelwerk";
 303.228  ["Degree"] = "Grad";
 303.229 -["Delegate area"] = "Themengebiet delegieren";
 303.230 +["Delegate area"] = "Themenbereich delegieren";
 303.231  ["Delegate issue"] = "Thema delegieren";
 303.232  ["Delegate unit"] = "Gliederung delegieren";
 303.233  ["Delegation abandoned"] = "Delegation ausgesetzt";
 303.234 -["Delegation turned off for area"] = "Delegation für Themengebiet ausgesetzt";
 303.235 +["Delegation turned off for area"] = "Delegation für Themenbereich ausgesetzt";
 303.236  ["Delegation turned off for issue"] = "Delegation für Thema ausgesetzt";
 303.237  ["Delegations"] = "Delegationen";
 303.238 -["Delete"] = "Löschen";
 303.239 -["Delete filter"] = "Filter löschen";
 303.240 +["Describe how the proposal and/or the reasons of the initiative could be improved"] = "Beschreibe, wie der Antrag und/oder die Begründung verbessert werden könnten";
 303.241  ["Description"] = "Beschreibung";
 303.242  ["Details"] = "Details";
 303.243  ["Developer settings"] = "Einstellungen für Entwickler";
 303.244 -["Diff"] = "Differenz";
 303.245 -["Direct"] = "Direkt";
 303.246 -["Direct and by delegation"] = "Direkt und delegiert";
 303.247 +["Did the initiator implement this suggestion?"] = "Hat der Initiatior die Anregung umgesetzt?";
 303.248  ["Direct majority"] = "Direkte Mehrheit";
 303.249 -["Direct majority denumerator"] = "Direkte Mehrheit Denumerator";
 303.250 +["Direct majority denominator"] = "Direkte Mehrheit Nenner";
 303.251  ["Direct majority non negative"] = "Direkte Mehrheit Nicht-Negative";
 303.252 -["Direct majority numerator"] = "Direkte Mehrheit Numerator";
 303.253 +["Direct majority numerator"] = "Direkte Mehrheit Zähler";
 303.254  ["Direct majority positive"] = "Direkte Mehrheit Positv";
 303.255  ["Disapproval (prefer to last block) [many entries]"] = "Ablehnung (jedoch Bevorzugung gegenüber letztem Ablehnungsblock)";
 303.256  ["Disapproval (prefer to last block) [single entry]"] = "Ablehnung (jedoch Bevorzugung gegenüber letztem Ablehnungsblock)";
 303.257 @@ -192,57 +189,71 @@
 303.258  ["Disapproval (prefer to lower blocks) [single entry]"] = "Ablehnung (jedoch Bevorzugung gegenüber unteren Ablehnungsblöcken)";
 303.259  ["Disapproval [many entries]"] = "Ablehnung";
 303.260  ["Disapproval [single entry]"] = "Ablehnung";
 303.261 -["Discard voting"] = "Abstimmung zurückziehen";
 303.262 -["Discuss with initiators"] = "Diskussion mit den Initiatoren";
 303.263 +["Disapproved"] = "Abgelehnt";
 303.264 +["Discard my vote"] = "Meine Stimme zurückziehen";
 303.265  ["Discussion"] = "Diskussion";
 303.266 +["Discussion #{time_info}"] = false;
 303.267  ["Discussion URL"] = "Diskussions-URL";
 303.268 -["Discussion on issue"] = "Diskussion zum Thema";
 303.269  ["Discussion started"] = "Diskussion gestartet";
 303.270 -["Discussion starts soon"] = "Diskussion startet in Kürze";
 303.271  ["Discussion time"] = "Zeit für die Diskussion";
 303.272 -["Discussion with initiators"] = "Diskussion mit den Initiatoren";
 303.273 -["Do not vote directly"] = "Nicht selbst abstimmen";
 303.274 +["Do you want to suggest to support another initiative?"] = "Möchtest du eine andere Initiative empfehlen?";
 303.275  ["Download"] = "Download";
 303.276  ["Download database export"] = "Datenbankexport herunterladen";
 303.277  ["Download documents"] = "Dokumente herunterladen";
 303.278 -["Draft"] = "Entwurf";
 303.279 +["Draft history"] = "Entwurfshistorie";
 303.280 +["Draft revision #{id}"] = "Entwurf Revision #{id}";
 303.281 +["During the discussion phase the issue is debated between initiators while the initiatives are improved by suggestions from the supporters."] = "Während der Diskussionsphase wird das Thema zwischen den Initiatoren debattiert, während die Entwurfstext der Initiativen durch Verbesserungsvorschläge der Unterstützer weiterentwickelt wird.";
 303.282 +["During the verification phase the initiative drafts cannot be changed anymore."] = "Während der Überprüfungsphase kann der Text der Initiative nicht mehr geändert werden.";
 303.283  ["Edit"] = "Bearbeiten";
 303.284 +["Edit again"] = "Nochmal bearbeiten";
 303.285  ["Edit areas"] = "Themenbereiche bearbeiten";
 303.286 -["Edit draft"] = "Entwurf bearbeiten";
 303.287  ["Edit initiative"] = "Initiative bearbeiten";
 303.288 -["Edit my page"] = "Meine Seite bearbeiten";
 303.289 -["Edit my profile"] = "Mein Profil bearbeiten";
 303.290  ["Edit profile"] = "Profil bearbeiten";
 303.291 +["Edit voting comment"] = "Abstimmungskommentar bearbeiten";
 303.292 +["Edit your profile data"] = "Profildaten bearbeiten";
 303.293  ["Eligible as winner"] = "Als Gewinner qualifiziert";
 303.294 +["Eligible members (#{count})"] = "Stimmberechtigte Teilnehmer (#{count})";
 303.295  ["Eligible voters"] = "Stimmberechtigte";
 303.296  ["Email address"] = "E-Mail-Adresse";
 303.297  ["Email address confirmation"] = "Bestätigung der E-Mail-Adresse";
 303.298 +["Email address for notifications"] = "E-Mail-Adresse für Benachrichtungen";
 303.299  ["Email address is confirmed now"] = "E-Mail-Adresse ist jetzt bestätigt";
 303.300  ["Email address too short!"] = "E-Mail-Adresse ist zu kurz!";
 303.301  ["Email confirmation request"] = "Bestätigung deiner E-Mail-Adresse";
 303.302 -["Empty help text: #{id}.#{lang}.txt"] = "Leerer Hilfe-Text: #{id}.#{lang}.txt";
 303.303 +["Emphasis"] = "Hervorhebung";
 303.304 +["Enter a new email address:"] = "Neue E-Mail-Adresse eingeben:";
 303.305 +["Enter a new login name"] = "Neuen Anmeldenamen eingeben:";
 303.306 +["Enter a new password:"] = "Neues Kennwort eingeben";
 303.307 +["Enter a new screen name:"] = "Neuen Screen-Namen eingeben";
 303.308 +["Enter a title for your initiative (max. 140 chars):"] = "Einen Titel für die Iniative eingeben (max. 140 Zeichen)";
 303.309 +["Enter your current password:"] = "Bisheriges Kennwort eingeben:";
 303.310 +["Enter your new password again please:"] = "Das neue Kennwort bitte nocheinmal eingeben:";
 303.311 +["Enter your proposal and/or reasons"] = "Antrag und/oder Begründung eingeben";
 303.312 +["Enter your proposal and/or reasons:"] = "Antrag und/oder Begründung eingeben:";
 303.313  ["Error while converting image. Please note, that only JPG files are supported!"] = "Fehler beim Konvertieren des Bilds. Bitte beachte, dass nur JPG-Dateien unterstützt werden.";
 303.314  ["Error while updating member, database reported:<br /><br /> (#{errormessage})"] = "Fehler beim aktualisieren des Mitglieds, die Datenbank berichtet folgenden Fehler:<br /><br /> (#{errormessage})";
 303.315  ["Etherpad authentication failed"] = "Etherpad-Anmeldung fehlgeschlagen";
 303.316  ["Event #{id} -> #{num} members"] = false;
 303.317 -["Everything"] = "Alles";
 303.318  ["External memberships"] = "Externe Mitgliedschaften";
 303.319  ["External posts"] = "Externe Ämter";
 303.320 +["Failed  #{sign}#{num}/#{den}"] = "Gescheitert #{sign}#{num}/#{den}";
 303.321 +["Failed 1st quorum"] = "Am 1. Quorum gescheitert";
 303.322  ["Finish delegation check"] = "Delegationsprüfung abschließen";
 303.323  ["Finish voting"] = "Stimmabgabe abschließen";
 303.324 -["Finished"] = "Abgeschlossen";
 303.325 -["Finished (with winner)"] = "Abgeschlossen (mit Gewinner)";
 303.326 -["Finished (without winner)"] = "Abgeschlossen (ohne Gewinner)";
 303.327 -["Forgot login name?"] = "Anmeldename vergessen?";
 303.328 +["Finished with winner"] = "Mit Gewinner abgeschlossen";
 303.329 +["For numbered items use a digit (e.g. 1) followed by a dot (.) and a space"] = "Für nummerierte Listen verwende eine Ziffer (e.g. 1) gefolgt von einem Punkt (.) und einem Leerschritt";
 303.330 +["For which issue phases do you like to receive notification emails?"] = "Für welche Themenphasen sollen E-Mail-Benachrichtigungen versendet werden?";
 303.331 +["Forgot login name?"] = "Anmeldenamen vergessen?";
 303.332  ["Forgot password?"] = "Kennwort vergessen?";
 303.333 -["Free timing"] = "Freie Zeitsteuerung";
 303.334 -["Friday"] = "Freitag";
 303.335 +["Formatting help"] = "Hilfe zur Formatierung";
 303.336 +["Free timing:"] = "Freie Zeitsteuerung:";
 303.337  ["Frozen"] = "Eingefroren";
 303.338  ["Fully frozen at"] = "Ganz eingefroren am/um";
 303.339  ["Generate API key"] = "API-Schlüssel erzeugen";
 303.340  ["Global delegation"] = "Globale Delegation";
 303.341 -["Global search"] = "Globale Suche";
 303.342 +["Go back to home page"] = "Zurück zur Startseite";
 303.343  ["Half frozen at"] = "Halb eingefroren am/um";
 303.344 +["Headlines"] = "Überschriften";
 303.345  ["Hello\n\n"] = "Hallo\n\n";
 303.346  ["Hello "] = "Hallo ";
 303.347  ["Hello,\n\n"] = "Hallo, ";
 303.348 @@ -250,85 +261,112 @@
 303.349  ["Help for: #{text}"] = "Hilfe zu: #{text}";
 303.350  ["Hide"] = "Verstecken";
 303.351  ["Hide active units"] = "Aktive units ausblenden";
 303.352 -["Hide filter details"] = "Filter-Details verstecken";
 303.353 -["Hide this help message"] = "Diesen Hilfetext ausblenden";
 303.354  ["Hint"] = "Hinweis";
 303.355 -["History"] = "Historie";
 303.356 +["History"] = "Zeitlicher Verlauf";
 303.357  ["Home"] = "Startseite";
 303.358 +["How important is your suggestions for you?"] = "Wie wichtig ist diese Anregung?";
 303.359 +["How this member voted"] = "Wie dieses Mitglied abgestimmt hat";
 303.360  ["I consider suggestion as"] = "Ich halte die Anregung für";
 303.361 -["I like to receive notifications by email about events in my areas and issues:"] = "Ich möchte per E-Mail über die folgenden Ereignisse in meinen Themenbereichen und Themen informiert werden:";
 303.362 +["I do not like to hear from this member"] = "Ich möchte nichts mehr von diesem Mitglied mitbekommen";
 303.363 +["I do not like to receive notifications by email"] = "Ich möchte keine Benachrichtigungen per E-Mail erhalten";
 303.364 +["I don't like any of the initiative in this issue and I want to add my opinion or counter proposal"] = "Ich mag keine der Initiativen in diesem Thema und möchte meine Meinung oder Gegenvorschlag einbringen";
 303.365 +["I don't like this initiative and I want to add my opinion or counter proposal"] = "Ich mag diese Initiative nicht und möchte meine Meinung oder Gegenvorschlag einbringen";
 303.366 +["I don't like to vote this issue (myself):"] = "Ich möchte für dieses Thema nicht (selber) abstimmen:";
 303.367 +["I like this initiative and I want to support it"] = "Ich mag diese Initiative und möchte sie unterstützen";
 303.368 +["I like to change/revoke my vote:"] = "Ich möchte meine Stimme ändern/widerrufen";
 303.369 +["I like to receive notifications"] = "Ich möchte Benachrichtigungen erhalten";
 303.370 +["I like to vote on this issue:"] = "Ich möchte für dieses Thema abstimmen";
 303.371 +["I understand, that this is not revocable"] = "Ich verstehe, dass dies nicht widerrufbar ist";
 303.372 +["I want to change account settings"] = "Ich möchte meine Kontoeinstellungen ändern";
 303.373 +["I want to change the interface language"] = "Ich möchte die Sprache ändern";
 303.374 +["I want to customize my profile"] = "Ich möchte mein Profil anpassen";
 303.375 +["I want to delegate my vote"] = "Ich möchte meine Stimme delegieren";
 303.376 +["I want to delegate this issue"] = "Ich möchte dieses Thema delegieren";
 303.377 +["I want to delegate this organizational unit"] = "Ich möchte diese Gliederung delegieren";
 303.378 +["I want to delegate this subject area"] = "Ich möchte diesen Themenbereich delegieren";
 303.379 +["I want to improve this initiative"] = "Ich möchte die Initiative verbessern";
 303.380 +["I want to know whats going on"] = "Ich möchte wissen was los ist";
 303.381 +["I want to learn more about LiquidFeedback"] = "Ich möchte mehr über LiquidFeedback lernen";
 303.382 +["I want to logout"] = "Ich möchte mich ausloggen";
 303.383 +["I want to manage my saved contacts"] = "Ich möchte meine gespeicherten Kontakte bearbeiten";
 303.384 +["I want to participate in this issue"] = "Ich möchte an diesem Thema teilnehmen";
 303.385 +["I want to participate in this subject area"] = "Ich möchte an diesem Themenbereich teilnehmen";
 303.386 +["I want to save this member as contact (i.e. to use as delegatee)"] = "Ich möchte dieses Mitglied als Kontakt speichern (z.B. als Delegationsempfänger)";
 303.387 +["I want to start a new initiative"] = "Ich möchte eine neue Initiative starten";
 303.388 +["I want to stay informed"] = "Ich möchte informiert bleiben";
 303.389 +["I want to take a look at other organizational units"] = "Ich möchte einen Blick auf andere Gliederungen werfen";
 303.390 +["I'm interested in this issue"] = "Ich bin an diesem Thema interessiert";
 303.391 +["I'm supporting this initiative"] = "Ich unterstütze diese Initiative";
 303.392  ["Id"] = "Id";
 303.393  ["Identification"] = "Identifikation";
 303.394  ["If this link is not working, please open following url in your web browser:\n\n"] = "Sollte der Link nicht funktionieren, öffne bitte die folgenden URL in Deinem Web-Browser:\n\n";
 303.395 -["Ignore Areas"] = "Ignoriere Bereiche";
 303.396 +["If you cannot find any appropriate existing issue, "] = "Wenn kein passendes Thema existiert, ";
 303.397  ["Ignore initiative"] = "Initiative ignorieren";
 303.398 -["Ignore member"] = "Mitglied ignorieren";
 303.399 -["Images"] = "Bilder";
 303.400  ["Implicitly admitted"] = "Implizit zugelassen";
 303.401  ["Incoming delegations"] = "Eingehende Delegationen";
 303.402 +["Incoming delegations for '#{member_name}'"] = "Eingehende Delegationen für '#{member_name}'";
 303.403 +["Incoming delegations for '#{member}'"] = "Eingehende Delegationen für '#{member}'";
 303.404 +["Indent sub items with spaces"] = "Unterpunkte mit Leerschritt einrücken";
 303.405  ["Index"] = "Positionsnummer";
 303.406  ["Indirect majority"] = "Indirekte Mehrheit";
 303.407 -["Indirect majority denumerator"] = "Indirekte Mehrheit Denumerator";
 303.408 +["Indirect majority denominator"] = "Indirekte Mehrheit Nenner";
 303.409  ["Indirect majority non negative"] = "Indirekte Mehrheit Nicht-Negativ";
 303.410 -["Indirect majority numerator"] = "Indirekte Mehrheit Numerator";
 303.411 +["Indirect majority numerator"] = "Indirekte Mehrheit Zähler";
 303.412  ["Indirect majority positive"] = "Indirekte Mehrheit Positiv";
 303.413 -["Information about the available policies"] = "Informationen zu den verfügbaren Regelwerken";
 303.414 -["Initiated"] = "Initiiert";
 303.415 -["Initiative"] = "Initiative";
 303.416 -["Initiative ##{id}"] = "Initiative ##{id}";
 303.417 -["Initiative events"] = "Initiativen-Ereignisse";
 303.418 -["Initiative i#{id}: #{name}"] = "Initiative i#{id}: #{name}";
 303.419  ["Initiative is revoked now"] = "Initiative ist jetzt zurückgezogen";
 303.420 +["Initiative not admitted"] = "Initiative nicht zugelassen";
 303.421  ["Initiative quorum"] = "Quorum Initiative";
 303.422 -["Initiative quorum denumerator"] = "Initiativ-Quorum Nenner";
 303.423 +["Initiative quorum denominator"] = "Initiative-Quroum Nenner";
 303.424  ["Initiative quorum numerator"] = "Initiativ-Quorum Zähler";
 303.425  ["Initiative revoked"] = "Initiative zurückgezogen";
 303.426  ["Initiative successfully created"] = "Initiative erfolgreich erzeugt";
 303.427  ["Initiative successfully updated"] = "Initiative erfolgreich aktualisiert";
 303.428  ["Initiative: "] = "Initiative: ";
 303.429 +["Initiatives"] = "Initiativen";
 303.430 +["Initiatives and issues"] = "Initiativen und Themen";
 303.431 +["Initiatives created by this member"] = "Initiativen von diesem Mitglied";
 303.432  ["Initiatives that invited you to become initiator:"] = "Initiative, die Dich eingeladen haben, Initiator zu werden:";
 303.433  ["Initiator invites"] = "Einladungen";
 303.434  ["Initiators"] = "Initiatoren";
 303.435 -["Interest not existent"] = "Interesse existiert nicht";
 303.436 +["Interest already removed"] = "Interesse wurde bereits abgemeldet";
 303.437  ["Interest removed"] = "Interesse entfernt";
 303.438  ["Interest updated"] = "Interesse aktualisiert";
 303.439 -["Interested"] = "Interessiert";
 303.440 -["Interested members"] = "Interessierte Mitglieder";
 303.441 +["Interested members"] = "Interessierte Teilnehmer";
 303.442  ["Internal posts"] = "Interne Ämter";
 303.443  ["Interval format:"] = "Intervall-Format";
 303.444 +["Introduction"] = "Einführung";
 303.445  ["Invalid login name or password!"] = "Anmeldename oder Kennwort ungültig";
 303.446 -["Invalid query"] = "Ungültige Anfrage";
 303.447  ["Invitation has been refused"] = "Einladung wurde widerrufen";
 303.448  ["Invitation to LiquidFeedback"] = "Einladung zu LiquidFeedback";
 303.449  ["Invite an initiator to initiative"] = "Initiator zur Initiative einladen";
 303.450  ["Invite code"] = "Einladungscode";
 303.451 -["Invite initiator"] = "Initiator einladen";
 303.452 +["Invite member"] = "Mitglied einladen";
 303.453  ["Invited"] = "Eingeladen";
 303.454 -["Issue"] = "Thema";
 303.455 +["Issue #"] = "Thema #";
 303.456  ["Issue ##{id}"] = "Thema ##{id}";
 303.457 -["Issue ID"] = "Thema #";
 303.458 -["Issue accepted"] = "Thema akzeptiert";
 303.459 -["Issue canceled"] = "Thema abgebrochen";
 303.460 +["Issue ##{issue_id}: #{initiative_name}"] = "Thema ##{issue_id}: #{initiative_name}";
 303.461  ["Issue delegation"] = "Issue-Delegation";
 303.462 -["Issue events"] = "Themen-Ereignisse";
 303.463 -["Issue finished"] = "Thema abgeschlossen";
 303.464 -["Issue finished without voting"] = "Thema ohne Abstimmung abgeschlossen";
 303.465 -["Issue frozen"] = "Thema eingefroren";
 303.466  ["Issue has been canceled"] = "Thema wurde abgebrochen";
 303.467 -["Issue pad"] = "Pad zum Thema";
 303.468  ["Issue quorum"] = "Quorum Thema";
 303.469 -["Issue quorum denumerator"] = "Themen-Quorum Nenner";
 303.470 +["Issue quorum denominator"] = "Themen-Quroum Nenner";
 303.471  ["Issue quorum numerator"] = "Themen-Quorum Zähler";
 303.472  ["Issue reached next phase"] = "Thema hat die nächste Phase erreicht";
 303.473 +["Issues in admission phase"] = "Themen in Zulassung";
 303.474 +["Issues in discussion phase"] = "Themen in Diskussion";
 303.475 +["Issues in verification phase"] = "Themen in Überprüfung";
 303.476 +["Issues in voting phase"] = "Themen in Abstimmung";
 303.477  ["Issues:"] = "Themen:";
 303.478  ["JavaScript is disabled or not available."] = "JavaScript ist abgeschaltet oder nicht verfügbar.";
 303.479  ["Last activity (updated daily)"] = "Letzte Aktivität (täglich aktualisiert)";
 303.480 -["Last snapshot:"] = "Letzte Auszählung:";
 303.481 -["Latest draft created at #{date} #{time}"] = "Letzter Entwurf vom #{date} um #{time}";
 303.482 +["Last counting:"] = "Letzte Auszählung";
 303.483 +["Latest activity"] = "Letzte Aktivität";
 303.484 +["Latest approved issue"] = false;
 303.485 +["Latest disapproved issue"] = false;
 303.486  ["Latest events"] = "Letzte Ereignisse";
 303.487 -["License"] = "Lizenz";
 303.488 +["Links"] = "Links";
 303.489  ["LiquidFeedback"] = "LiquidFeedback";
 303.490 -["List all revisions (#{count})"] = "Zeige alle Versionen (#{count})";
 303.491 +["Lists"] = "Listen";
 303.492 +["Lists must be preceeded and followed by at least one blank line"] = "Listen müssen von Leerzeilen umgeben sein";
 303.493  ["Lock member?"] = "Mitglied sperren?";
 303.494  ["Locked?"] = "Gesperrt?";
 303.495  ["Login"] = "Anmeldung";
 303.496 @@ -337,117 +375,102 @@
 303.497  ["Login-Name: "] = "Anmeldename: ";
 303.498  ["Logout"] = "Abmelden";
 303.499  ["Logout successful"] = "Abmeldung erfolgreich";
 303.500 -["Manage filter"] = "Filter verwalten";
 303.501 -["Manage timeline filters"] = "Zeitachsen-Filter verwalten";
 303.502 +["Make your choice by placing the initiatives"] = "Treffe eine Wahl indem du die Initiativen verschiebst";
 303.503 +["Manage system settings"] = "Systemeinstellungen verwalten";
 303.504  ["Member"] = "Mitglied";
 303.505 -["Member '#{member}'"] = "Mitglied '#{member}'";
 303.506  ["Member has been removed from initiators"] = "Mitglied wurde von den Initiatoren entfernt";
 303.507  ["Member has been removed from your contacts"] = "Mitglied wurde aus Deinen Kontakten entfernt";
 303.508  ["Member has not approved latest draft"] = "Mitglied hat den letzten Entwurf noch nicht angenommen";
 303.509 -["Member has voting privileges for this unit"] = "Mitglied hat Stimmrecht in dieser Gliederung";
 303.510  ["Member inactive?"] = "Mitglied inaktiv?";
 303.511  ["Member is already saved in your contacts!"] = "Mitglied ist schon in Deinen Kontakten!";
 303.512  ["Member is not participating in any of the #{count} areas in this unit"] = "Mitglied nimmt an keinem der #{count} Themenbereiche dieser Gliederung teil";
 303.513  ["Member is not participating in the only area of the unit"] = "Mitglied nimmt am einzigen Themenbereich der Gliederung nicht teil";
 303.514  ["Member is now invited to be initiator"] = "Mitglied ist jetzt als Initiator eingeladen";
 303.515 -["Member is participating in this area"] = "Mitglied ist Teilnehmer im Themenbereich";
 303.516  ["Member list"] = "Mitgliederliste";
 303.517  ["Member menu"] = "Mitglieds-Menü";
 303.518  ["Member name"] = "Mitglied Name";
 303.519 -["Member name history for '#{name}'"] = "Namenshistorie für '#{name}'";
 303.520 -["Member of area"] = "Mitglied des Themenbereichs";
 303.521 -["Member page"] = "Mitgliederseite";
 303.522  ["Member successfully registered"] = "Mitglied erfolgreich registriert";
 303.523  ["Member successfully updated"] = "Mitglied erfolgreich aktualisert";
 303.524 -["Member: '#{identification}' (#{name})"] = "Mitglied: '#{identification}' (#{name})";
 303.525  ["Members"] = "Mitglieder";
 303.526 -["Membership not existent"] = "Mitgliedschaft existiert nicht";
 303.527 -["Membership removed"] = "Mitgliedschaft entfernt";
 303.528 -["Membership updated"] = "Mitgliedschaft aktualisiert";
 303.529  ["Memberships"] = "Mitgliedschaften";
 303.530  ["Missing help text: #{id}.#{lang}.txt"] = "Fehlender Hilfetext: #{id}.#{lang}.txt";
 303.531  ["Mobile phone"] = "Mobiltelefon";
 303.532 -["Monday"] = "Montag";
 303.533  ["Move down"] = "Runter schieben";
 303.534  ["Move up"] = "Hoch schieben";
 303.535 -["My areas"] = "Meine Themengebiete";
 303.536 -["My areas and issues"] = "Meine Themengebiete und Themen";
 303.537 +["My areas"] = "Meine Themenbereiche";
 303.538  ["My opinion"] = "Meine Meinung";
 303.539 -["My units"] = "Meine Gliederungen";
 303.540  ["Name"] = "Name";
 303.541  ["New"] = "Neu";
 303.542 -["New address"] = "Neue E-Mail-Adresse";
 303.543 -["New draft"] = "Neuer Entwurf";
 303.544 -["New draft has been added to initiative"] = "Neuer Entwurf wurde der Initiative hinzugefügt";
 303.545 +["New area"] = "Neues Themenbereich";
 303.546 +["New draft for initiative '#{initiative_name}'"] = "Neuer Entwurfstext von Initiative '#{initiative_name}'";
 303.547  ["New drafts for #{count} initiative(s) you are supporting"] = "Für #{count} von dir unterstützte Iniativen gibt es neue Entwürfe";
 303.548  ["New initiative"] = "Neue Initiative";
 303.549  ["New initiative draft"] = "Neuer Entwurfstext der Initiative";
 303.550  ["New issue"] = "Neues Thema";
 303.551 -["New password"] = "Neues Kennwort";
 303.552 +["New member"] = "Neues Mitglied";
 303.553 +["New organizational unit"] = "Neue Gliederung";
 303.554  ["New passwords does not match."] = "Du hast nicht zweimal das gleiche Kennwort eingegeben";
 303.555  ["New passwords is too short."] = "Das neue Kennwort ist zu kurz";
 303.556 +["New policy"] = "Neues Regelwerk";
 303.557  ["New suggestion"] = "Neue Anregung";
 303.558  ["Newest"] = "Neueste";
 303.559  ["No"] = "Nein";
 303.560 +["No (not yet)"] = "Nein (noch nicht)";
 303.561  ["No admission needed"] = "Keine Zulassung nötig";
 303.562  ["No changes to your images were made"] = "An Deinen Bildern wurde nichts geändert";
 303.563  ["No default"] = "Kein Standard";
 303.564  ["No delegation"] = "Keine Delegation";
 303.565 -["No events selected to list"] = "Keine Ereignisse ausgewählt";
 303.566 +["No matching issues found"] = "Keine passenden Themen gefunden";
 303.567 +["No matching members found"] = "Keine passenden Mitglieder gefunden";
 303.568  ["No more events available"] = "Keine weiteren Ereignisse verfügbar";
 303.569  ["No multistage majority"] = "Keine mehrstufigen Mehrheiten";
 303.570 -["No notifications at all"] = "Gar keine Benachrichtigungen";
 303.571 -["No potential supporters"] = "Keine potentiellen Unterstützer";
 303.572 -["No potential supporters (before begin of voting)"] = "Keine potentiellen Unterstützer (zum Abstimmungsbeginn)";
 303.573 +["No published contacts"] = "Keiner Kontakte veröffentlicht";
 303.574 +["No results for this selection"] = "Keine Ergebnisse für diese Auswahl";
 303.575  ["No reverse beat path"] = "Kein rückwärtsgerichteter Schlagpfad";
 303.576  ["No suggestions"] = "Keine Anregungen";
 303.577  ["No suggestions yet"] = "Noch keine Anregungen";
 303.578 -["No supporters"] = "Keine Unterstützer";
 303.579 -["No supporters (before begin of voting)"] = "Keine Unterstützer (zum Abstimmungsbeginn)";
 303.580  ["Not a member"] = "Kein Mitglied";
 303.581 -["Not accepted yet"] = "Bisher nicht angenommen";
 303.582 -["Not approved"] = "Nicht angenommen";
 303.583 -["Not approved (rank #{rank})"] = "Nicht angenommen (Rang #{rank})";
 303.584 -["Not voted"] = "Nicht abgestimmt";
 303.585  ["Not voted issues"] = "Nicht abgestimmt";
 303.586  ["Notification address unconfirmed"] = "E-Mail-Adresse für Benachrichtigungen unbestätigt";
 303.587  ["Notification email"] = "E-Mail für Benachrichtigungs";
 303.588  ["Notification level not set yet"] = "Benachrichtigungseinstellungen noch nicht vorgenommen";
 303.589 -["Notification settings"] = "Benachrichtigungseinstellungen";
 303.590 +["Notifications"] = "Benachrichtigungen";
 303.591 +["Notifications are only send to you about events in the subject areas you subscribed, the issues you are interested in and the initiatives you are supporting."] = "Benachrichtigungen werden nur für Ereignisse versendet, die deine Themenbereiche, Themen, und unterstützten Intiativen betreffen.";
 303.592  ["Number of incoming delegations, follow link to see more details"] = "Anzahl eingehender Delegationen, Link folgen für mehr Details";
 303.593  ["OK"] = "OK";
 303.594 -["Old password"] = "Altes Kennwort";
 303.595  ["Old password is wrong"] = "Das alte Kennwort ist falsch";
 303.596  ["Oldest"] = "Älteste";
 303.597  ["On that page please enter the confirmation code:\n\n"] = "Auf dieser Seite gib bitten den folgenden Code ein:\n\n";
 303.598  ["On that page please enter the invite key:\n\n"] = "Auf dieser Seite gib den folgenden Code ein:\n\n";
 303.599  ["On that page please enter the reset code:\n\n"] = "Auf dieser Seite gib bitte den folgenden Rücksetzcode ein:\n\n";
 303.600 +["On this issue can be voted now."] = "Über dieses Thema kann jetzt abgestimmt werden.";
 303.601  ["One issue"] = "Ein Thema";
 303.602  ["One issue you are interested in"] = "Ein Thema, das Dich interessiert";
 303.603 -["One more area in this unit"] = "Ein weiteres Themengebiet in dieser Gliederung";
 303.604 +["One more area in this unit"] = "Ein weiterer Themenbereich in dieser Gliederung";
 303.605  ["One of them have an area delegation set"] = "Bei einem davon ist eine Delegation für den Themenbereich gesetzt";
 303.606 -["One step back"] = "Ein Schritt zurück";
 303.607  ["Only for issues reaching the discussion phase"] = "Nur für Themen, die die Diskussion erreichen.";
 303.608 -["Only for issues reaching the frozen phase"] = "Nur für Themen, die die Phase Eingefroren erreichen.";
 303.609 +["Only for issues reaching the verification phase"] = "Nur für Themen, die die Überprüfung erreichen";
 303.610  ["Only for issues reaching the voting phase"] = "Nur für Themen, die die Abstimmung erreichen.";
 303.611 -["Open"] = "Offen";
 303.612  ["Open initiatives you are supporting which has been updated their draft:"] = "Offene, von dir unterstützte Initiativen, deren Antragstext aktualisiert wurde:";
 303.613  ["Open issues"] = "Offene Themen";
 303.614 +["Open the appropriate subject area where your issue fits in and follow the instruction on that page."] = "Den passenden Themenbereich öffnen und dort den Anweisungen folgen.";
 303.615  ["Opinions"] = "Meinungen";
 303.616  ["Options"] = "Optionen";
 303.617  ["Organizational unit"] = "Organisationseinheit";
 303.618 +["Organizational units"] = "Organisationseinheiten";
 303.619 +["Organizational units and subject areas"] = "Organisationseinheiten und Themenbereiche";
 303.620  ["Other failures"] = "Weitere Mängel";
 303.621  ["Outgoing delegations"] = "Ausgehende Delegationen";
 303.622 +["Page not found"] = "Seite nicht gefunden";
 303.623 +["Paragraphs"] = "Absätze";
 303.624  ["Parent unit"] = "Übergeordnete Gliederung";
 303.625 -["Participants"] = "Teilnehmer";
 303.626 -["Participate in this area"] = "An diesem Themengebiet teilnehmen";
 303.627  ["Password"] = "Kennwort";
 303.628  ["Password (repeat)"] = "Kennwort (wiederholen)";
 303.629  ["Password has been reset successfully"] = "Kennwort wurde erfolgreich zurückgesetzt";
 303.630  ["Password reset request"] = "Kennwort-Rücksetzung anfordern";
 303.631  ["Passwords don't match!"] = "Kennwörter stimmen nicht überein!";
 303.632  ["Passwords must consist of at least 8 characters!"] = "Das Kennwort muss zumindest 8 Zeichen lang sein!";
 303.633 -["Phases"] = "Phasen";
 303.634 +["Phase durations"] = "Phasendauer";
 303.635  ["Phone"] = "Telefon";
 303.636  ["Photo"] = "Foto";
 303.637  ["Please choose a login name. This name will not be shown to others and is used only by you to login into the system. The login name is case sensitive."] = "Bitte wähle einen Anmeldenamen. Dieser wird anderen nicht gezeigt und nur von Dir zum Anmelden verwendet. Groß- und Kleinschreibung wird berücksichtigt.";
 303.638 @@ -455,13 +478,15 @@
 303.639  ["Please choose a name, i.e. your real name or your nick name. This name will be shown to others to identify you."] = "Wähle einen Namen, z. B. Deinen Real- oder Nicknamen. Dieser wird anderen angezeigt um Dich zu identifizieren.";
 303.640  ["Please choose a password and enter it twice. The password is case sensitive."] = "Bitte wähle ein Kennwort und gib es zweimal ein. Groß- und Kleinschreibung wird berücksichtigt.";
 303.641  ["Please choose a policy"] = "Bitte wähle ein Regelwerk";
 303.642 +["Please choose a policy for the new issue:"] = "Bitte ein Regelwerk für das neue Thema auswählen:";
 303.643 +["Please choose an area name"] = "Bitte einen Namen für den Themenbereich wählen";
 303.644  ["Please choose two different versions of the draft to compare"] = "Bitte wähle zwei verschiedene Versionen des Entwurfs, um sie zu vergleichen.";
 303.645 -["Please choose two versions of the draft to compare"] = "Bitte wähle zwei Versionen des Entwurfs, um sie zu vergleichen.";
 303.646  ["Please confirm your email address"] = "Bitte bestätige Deine E-Mail-Adresse";
 303.647  ["Please confirm your email address by clicking the following link:\n\n"] = "Bitte bestätige Deine E-Mail-Adresse durch Klick auf folgenden Link:\n\n";
 303.648  ["Please decide for each delegation to confirm or to revoke it!"] = "Für jede Delegation muss eine Entscheidung getroffen werden!";
 303.649 +["Please enter a meaningful title for your initiative!"] = "Bitte einen aussagekräftigen Titel für die Initiative eingeben!";
 303.650  ["Please enter the email reset code you have received:"] = "Bitte gib den Rücksetzcode ein, den Du erhalten hast:";
 303.651 -["Please enter the invite code you've received."] = "Bitte gib den Einladungscode ein, den Du erhalten hast.";
 303.652 +["Please enter the invite code you've received"] = "Bitte den erhaltenen Einladungscode eingeben";
 303.653  ["Please enter your email address. This address will be used for automatic notifications (if you request them) and in case you've lost your password. This address will not be published. After registration you will receive an email with a confirmation link."] = "Bitte gib Deine E-Mail-Adresse ein. Diese Adresse wird für automatische Benachrichtigungen (wenn Du diese anforderst) sowie zum Zurücksetzen des Kennworts verwendet. Diese Adresse wird nicht veröffentlicht. Nach Abschluss der Registrierung wirst Du eine E-Mail mit einem Link zum Bestätigen der Adresse erhalten.";
 303.654  ["Please enter your email address. You will receive an email with your login name."] = "Bitte die E-Mail-Adresse eingeben. An diese wird eine Nachricht mit dem zugehörigen Anmeldenamen versendet.";
 303.655  ["Please enter your login name. You will receive an email with a link to reset your password."] = "Bitte gib Deinen Anmeldenamen ein. Du wirst eine E-Mail mit einem Link zum Zurücksetzen des Kennworts erhalten.";
 303.656 @@ -474,102 +499,110 @@
 303.657  ["Polling mode"] = "Befragungsmodus";
 303.658  ["Population"] = "Grundgesamtheit";
 303.659  ["Posts"] = "Ämter";
 303.660 -["Potential supported"] = "Potentiell unterstützt";
 303.661 -["Potential supporters"] = "Potentielle Unterstützer";
 303.662 -["Potential supporters (before begin of voting)"] = "Potentielle Unterstützer (zum Abstimmungsbeginn)";
 303.663 -["Potentially supported"] = "Potentiell unterstützt";
 303.664 +["Preference comparison"] = "Präferenzvergleich";
 303.665 +["Preference voting"] = "Präferenzabstimmung";
 303.666  ["Preview"] = "Vorschau";
 303.667 -["Preview voting comment"] = "Vorschau Abstimmmungskommentar";
 303.668 -["Proceed with registration"] = "Registrierung fortsetzen";
 303.669 +["Preview of delegation"] = "Vorschau der Delegation";
 303.670 +["Preview of voting ballot"] = "Vorschau des Stimmzettels";
 303.671 +["Private contacts"] = "Kontakte (nicht veröffentlicht)";
 303.672  ["Profession"] = "Beruf";
 303.673 -["Profile"] = "Profil";
 303.674 -["Public administrative notice:"] = "Administrativer Hinweistext (öffentlich)";
 303.675  ["Publish"] = "Veröffentlichen";
 303.676 +["Publish now"] = "Jetzt veröffentlichen";
 303.677  ["Published"] = "veröffentlicht";
 303.678 -["Quorum"] = "Quorum";
 303.679 +["Published contacts"] = "Veröffentlichte Kontakte";
 303.680 +["Put **double asterisks** around a phrase to make it bold"] = "Für fetten Text, diesen in **doppelten Sternchen** einschließen";
 303.681 +["Put *asterisks* or around a phrase to make it italic"] = "Für kursiven Text, diesen in *einfache Sternchen* einschließen";
 303.682 +["Put a hypen (-) or asterisk (*) followed by a space in front of each item"] = "Einen Strich (-) oder Sternchen (*) gefolgt von einem Leerschritt vor jeden Listenpunkt setzen";
 303.683 +["Quorums"] = "Quoren";
 303.684 +["Reached #{sign}#{num}/#{den}"] = "#{sign}#{num}/#{den} erreicht";
 303.685 +["Read and accept the terms and choose a password"] = "Nutzungsbedingungen akzeptieren und ein Kennwort wählen";
 303.686 +["Read more"] = "Mehr lesen";
 303.687  ["Real name"] = "Realname";
 303.688 -["Refresh support to current draft"] = "Unterstützung auf aktuellen Entwurf aktualisieren";
 303.689 -["Refuse invitation"] = "Einladung ablehnen";
 303.690 +["Recover login name"] = "Login-Namen wiederherstellen";
 303.691  ["Register new member"] = "Neues Mitglied registrieren";
 303.692 +["Registered members (#{count})"] = "Registrierte Teilnehmer (#{count})";
 303.693  ["Registration"] = "Registrierung";
 303.694  ["Registration (step 1 of 3: Invite code)"] = "Registrierung (Schritt 1 von 3: Einladungscode)";
 303.695  ["Registration (step 2 of 3: Personal information)"] = "Registrierung (Schritt 2 von 3: Persönliche Daten)";
 303.696  ["Registration (step 3 of 3: Terms of use and password)"] = "Registrierung (Schritt 3 von 3: Nutzungsbedingungen und Kennwort)";
 303.697  ["Rejected"] = "Abgelehnt";
 303.698 +["Rejected (rank #{rank})"] = "Abgelehnt (#{rank}. Platz)";
 303.699  ["Remove"] = "Entfernen";
 303.700 -["Remove from contacts"] = "Aus den Kontakten entfernen";
 303.701 +["Remove an initiator from initiative"] = "Einen Initiator entfernen";
 303.702  ["Remove initiator"] = "Initiator entfernen";
 303.703 -["Remove initiator from initiative"] = "Initiator von der Initiative entfernen";
 303.704  ["Rendered"] = "Formatiert";
 303.705 -["Repeat new password"] = "Neues Kennwort wiederholen";
 303.706  ["Request email with login name"] = "E-Mail mit Anmeldename anfordern";
 303.707 -["Request password reset link"] = "Link zum Rücksetzen des Kennworts anfordern";
 303.708 +["Request password reset link"] = "Rücksetzlink per E-Mail anfordern";
 303.709  ["Resend activation email to '#{email}'"] = "E-Mail mit Aktivierungslink erneut an '#{email}' senden";
 303.710  ["Reset code"] = "Rücksetzcode";
 303.711  ["Reset code is invalid!"] = "Rücksetzcode ist ungültig";
 303.712  ["Reset password"] = "Kennwort zurücksetzen";
 303.713  ["Revoke initiative"] = "Initiative zurückziehen";
 303.714 +["Revoke now"] = "Jetzt zurückziehen";
 303.715 +["Revoked (during admission)"] = "Zurückgezogen (während der Zulassung)";
 303.716 +["Revoked (during discussion)"] = "Zurückgezogen (während der Diskussion)";
 303.717 +["Revoked (during verification)"] = "Zurückgezogen (während der Überprüfung)";
 303.718  ["Revoked at"] = "Zurückgezogen am/um";
 303.719 -["Saturday"] = "Samstag";
 303.720 +["Rules of procedure"] = "Regelwerke";
 303.721  ["Save"] = "Speichern";
 303.722 -["Save current filter"] = "Aktuellen Filter speichern";
 303.723 -["Save timeline filters"] = "Zeitachsen-Filter speichern";
 303.724 -["Saved as contact"] = "Als Kontakt gespeichert";
 303.725 +["Save new password"] = "Neues Kennwort speichern";
 303.726 +["Save voting comment"] = "Abstimmungskommentar speichern";
 303.727  ["Saved contacts"] = "Gespeicherte Kontakte";
 303.728  ["Schulze rank"] = "Schulze-Rang";
 303.729  ["Screen name"] = "Screen-Name";
 303.730  ["Search"] = "Suchen";
 303.731 -["Search context"] = "Suchkontext";
 303.732 -["Search for issues"] = "Nach Themen suchen";
 303.733 -["Search for members"] = "Nach Mitgliedern suchen";
 303.734  ["Search initiatives"] = "Suche Initiativen";
 303.735  ["Search issues"] = "Suche Themen";
 303.736  ["Search members"] = "Suche Mitglieder";
 303.737  ["Search results for: '#{search}'"] = "Suchergebnisse für: '#{search}'";
 303.738  ["Search term (only complete words)"] = "Suchbegriff(e) (nur ganze Wörter)";
 303.739 -["Select language"] = "Sprache wählen";
 303.740 +["Select a notification level"] = "Ein Meldestufe für Benachrichtigungen auswählen";
 303.741  ["Select language \"#{langcode}\""] = "Sprache \"#{langcode}\" wählen";
 303.742  ["Send invite?"] = "Einladung schicken?";
 303.743 +["Separate each paragraph with at least one blank line"] = "Jeden Absatz mit zumindest einer Leerzeile vom nächsten trennen";
 303.744  ["Set URL"] = "URL setzen";
 303.745 -["Set delegation for Area '#{name}'"] = "Delegation für Themenbereich '#{name}' festlegen";
 303.746 -["Set delegation for Issue ##{number} in Area '#{area_name}'"] = "Delegation für Thema ##{number} im Themenbereich '#{area_name}' festlegen";
 303.747 -["Set global delegation"] = "Globale Delegation festlegen";
 303.748 -["Set new password"] = "Neues Kennwort setzen";
 303.749 +["Set area delegation"] = "Themenbereich delegieren";
 303.750 +["Set issue delegation"] = "Thema delegieren";
 303.751  ["Set unit delegation"] = "Delegation für Gliederung setzen";
 303.752  ["Settings"] = "Einstellungen";
 303.753 +["Should the initiator implement this suggestion?"] = "Soll der Initiator diese Anregung umsetzen?";
 303.754  ["Show"] = "Zeige";
 303.755 +["Show all members"] = "Alle Mitglieder anzeigen";
 303.756  ["Show areas in use"] = "Zeige verwendete Themenbereiche";
 303.757  ["Show areas not in use"] = "Zeige nicht verwendete Themenbereiche";
 303.758 -["Show diff"] = "Änderungen anzeigen";
 303.759 -["Show filter details"] = "Zeige Filter-Details";
 303.760 +["Show full history"] = "Komlette Historie anzeigen";
 303.761 +["Show full member list"] = "Komplette Mitgliederliste anzeigen";
 303.762  ["Show help text"] = "Zeige Hilfe-Text";
 303.763  ["Show inactive units"] = "Zeige deaktivierte Gliederungen";
 303.764 +["Show less"] = "Weniger anzeigen";
 303.765  ["Show member"] = "Mitglied anzeigen";
 303.766 -["Show member history"] = "Historie des Mitglieds anzeigen";
 303.767 +["Show more and rate this"] = "Mehr zeigen und bewerten";
 303.768 +["Show my voting ballot"] = "Meinen Stimmzettel anzeigen";
 303.769  ["Show older events"] = "Zeige ältere Ereignisse";
 303.770 -["Show only events which match... (or associtated)"] = "Zeige nur Ereignisse welche folgendes erfüllen... (oder-verknüpft)";
 303.771  ["Show policies in use"] = "Zeige Regelwerke in Verwendung";
 303.772  ["Show policies not in use"] = "Zeige deaktivierte Regelwerke";
 303.773  ["Show profile"] = "Profil anzeigen";
 303.774 +["Show voting ballot"] = "Stimmzettel anzeigen";
 303.775  ["So I'm"] = "Also bin ich";
 303.776 -["Software"] = "Software";
 303.777  ["Sorry, but there is not confirmed email address for your account. Please contact the administrator or support."] = "Sorry, aber für diesen Account ist keine bestätigte E-Mail-Adresse hinterlegt. Bitte wende Dich an den Administrator oder den Support.";
 303.778  ["Sorry, but you are currently not invited"] = "Sorry, aber Du bist zur Zeit nicht eingeladen";
 303.779  ["Sorry, you have reached your personal flood limit. Please be slower..."] = "Sorry, Du hast Dein persönliches Flood-Limit erreicht. Bitte sei langsamer...";
 303.780  ["Sorry, your contingent for creating initiatives has been used up. Please try again later."] = "Sorry, Dein Antragskontingent ist zur Zeit ausgeschöpft. Bitte versuche es später erneut!";
 303.781  ["Source"] = "Quelltext";
 303.782  ["Standard policies"] = "Standardverfahren";
 303.783 -["Start search"] = "Suche starten";
 303.784  ["Statement"] = "Statement";
 303.785  ["Status"] = "Status";
 303.786  ["Status quo: #{rank}"] = "Status quo: #{rank}";
 303.787 -["Stop ignoring member"] = "nicht mehr ignorieren";
 303.788  ["Strict direct majority"] = "Strenge direkte Mehrheit";
 303.789  ["Strict indirect majority"] = "Strenge indirekte Mehrheit";
 303.790 -["Stylesheet URL"] = "Stylesheet URL";
 303.791 +["Structured discussion"] = "Strukturierte Diskussion";
 303.792  ["Stylesheet URL has been updated"] = "Stylesheet URL wurde aktualisiert";
 303.793 +["Subject area subscribed"] = "für Themenbereich angemeldet";
 303.794 +["Subject areas"] = "Themenbereiche";
 303.795 +["Subscribed members (#{count})"] = "Angemeldete Teilnehmer (#{count})";
 303.796 +["Subscription already removed"] = "bereits abgemeldet";
 303.797 +["Subscription removed"] = "vom Themenbereich erfolgreich abgemeldet";
 303.798  ["Suggest no initiative"] = "Keine Initiative empfehlen";
 303.799 -["Suggested initiative"] = "Empfohlene Initiative";
 303.800  ["Suggestion"] = "Anregung";
 303.801  ["Suggestion ##{id}"] = "Anregung ##{id}";
 303.802  ["Suggestion currently implemented"] = "Anregung zur Zeit umgesetzt";
 303.803 @@ -577,86 +610,74 @@
 303.804  ["Suggestion does not exist anymore"] = "Anregung existiert nicht mehr";
 303.805  ["Suggestion for initiative: '#{name}'"] = "Anregung für Initiative '#{name}'";
 303.806  ["Suggestions"] = "Anregungen";
 303.807 -["Sunday"] = "Sonntag";
 303.808 +["Suggestions for improvement (#{count})"] = "Verbesserungsvorschläge (#{count})";
 303.809  ["Support this initiative"] = "Diese Initiative unterstützen";
 303.810 -["Supported"] = "Unterstützt";
 303.811 -["Supporters"] = "Unterstützer";
 303.812 -["Supporters (before begin of voting)"] = "Unterstützer (zum Abstimmungesbeginn)";
 303.813  ["Syntax help"] = "Syntax-Hilfe";
 303.814 +["System administration"] = "Systemadministration";
 303.815 +["System settings"] = "Systemeinstellungen";
 303.816 +["Take a look through the existing issues. Maybe someone else started a debate on your topic (and you can join it) or the topic has been decided already in the past."] = "Schau dir die bestehenden Themen an. Vielleicht hat schon jemand eine Debatte über dein Thema gestartet (und du kannst daran teilnehmen) oder über das Thema wurde bereits in der Vergangenheit entschieden.";
 303.817 +["Tell others about this initiative:"] = "Anderen von dieser Initiative berichten:";
 303.818  ["Terms of use"] = "Nutzungsbedingungen";
 303.819  ["The code you've entered is invalid"] = "Der Code, den Du eingeben hast, ist nicht gültig!";
 303.820  ["The draft of this initiative has been updated!"] = "Der Entwurfstext der Initiative wurde aktualisiert!";
 303.821  ["The drafts do not differ"] = "Die Entwürfe unterscheiden sich nicht";
 303.822 +["The initiative draft has been updated again in the meanwhile, support not updated!"] = "Der Entwurfstext der Initiative wurde zwischenzeitlich erneut geändert, die Unterstützung wurde daher nicht aktualisiert!";
 303.823 +["The initiative text has been updated"] = "Der Entwurfstext der Initiative wurde geändert";
 303.824  ["The initiators suggest to support the following initiative:"] = "Die Initiatoren empfehlen folgende Initiative zu unterstützen:";
 303.825 +["The title is the figurehead of your iniative. It should be short but meaningful! As others identifies your initiative by this title, you cannot change it later!"] = "Der Titel ist das Aushängeschild einer Initiative. Er sollte bedeutungsvoll sein! Da die Initiative durch den Titel identifiziert wird, kann er später nicht mehr geändert werden!";
 303.826 +["This delegation is suspended, because you voted yourself."] = "Die Delegation wurde durch eigenes Abstimmen ausgesetzt.";
 303.827  ["This email address is too short!"] = "Diese E-Mail-Adresse ist zu kurz!";
 303.828  ["This initiative"] = "Diese Initiative";
 303.829 -["This initiative has been revoked at #{revoked}"] = "Diese Initiative wurde am/um #{revoked} zurückgezogen";
 303.830 -["This initiative has not been admitted! It failed the quorum of #{quorum}."] = "Diese Initiative wurde nicht zugelassen. Sie hat das Quorum von #{quorum} nicht erreicht.";
 303.831 +["This initiative has been revoked at #{revoked} by:"] = "Diese Initiative wurde am/um #{revoked} zurückgezogen, von:";
 303.832 +["This initiative has not been admitted! It failed the 2nd quorum of #{quorum}."] = "Diese Initiative wurde nicht zugelassen! Sie ist am 2. Quorum (#{quorum}) gescheitert.";
 303.833  ["This initiative is already revoked"] = "Diese Initiative ist schon zurückgezogen";
 303.834  ["This initiative is revoked"] = "Diese Initiative wurde zurückgezogen";
 303.835  ["This invite key is connected with the following information:"] = "Dieser Einladungscode ist mit den folgenden Daten verknüpft:";
 303.836 -["This issue has been canceled by administrative intervention."] = "Dieses Thema wurde durch administrativen Eingriff abgebrochen.";
 303.837 -["This issue has been canceled."] = "Dieses Thema wurde abgebrochen";
 303.838 -["This issue has been canceled. It failed the quorum of #{quorum}."] = "Dieses Thema wurde abgebrochen. Es hat das Quorum von #{quorum} nicht erfüllt.";
 303.839 +["This is the only initiative in this issue, because nobody started a competing initiative."] = "Dies ist die einzige Initiative in diesem Thema, da niemand eine konkurrierende Initiative gestartet hat.";
 303.840  ["This issue is already closed."] = "Das Thema ist schon geschlossen.";
 303.841  ["This issue is already frozen."] = "Das Thema ist schon eingefroren";
 303.842 +["This issue is closed"] = "Das Thema ist geschlossen";
 303.843  ["This login is already taken, please choose another one!"] = "Dieser Anmeldename ist bereits vergeben, bitte wähle einen anderen!";
 303.844  ["This login is too short!"] = "Dieser Anmeldename ist zu kurz!";
 303.845  ["This member account has been created at #{created}"] = "Dieser Mitgliedszugang wurde am/um #{created} angelegt.";
 303.846  ["This member has rejected to become initiator of this initiative"] = "Dieses Mitglied hat die Einladung, Initiator zu werden, abgelehnt";
 303.847  ["This member is already initiator of this initiative"] = "Dieses Mitglied ist bereits Initiator dieser Initiative";
 303.848  ["This member is already invited to become initiator of this initiative"] = "Dieses Mitglied ist bereits eingeladen Initiator dieser Initiative zu werden";
 303.849 +["This member is currently participating in this issue."] = "Dieses Mitglied nimmt zur Zeit an diesem Thema teil.";
 303.850  ["This member is inactive"] = "Mitglied ist inaktiv";
 303.851 -["This member is initiator of this initiative"] = "Dieses Mitglied ist Initiator dieser Initiative";
 303.852  ["This member is locked"] = "Mitglied ist gesperrt";
 303.853 -["This member is participating, the rest of delegation chain is suspended while discussing"] = "Dieses Mitglied partizipiert, Rest der Delegationskette während der Diskussion ausgesetzt.";
 303.854 -["This member is potential supporter of this initiative"] = "Dieses Mitglied ist potentieller Unterstützer dieser Initiative";
 303.855 -["This member is potential supporter of this initiative via delegation"] = "Dieses Mitglied ist durch Delegation potentieller Unterstützer dieser Initiative";
 303.856 -["This member is supporter of this initiative"] = "Dieses Mitglied ist Unterstützer dieser Initiative";
 303.857 -["This member is supporter of this initiative via delegation"] = "Dieses Mitglied ist durch Delegation Unterstützer dieser Initiative";
 303.858 +["This member is participating, the remaining delegation chain is suspended during discussing."] = "Diese Mitglied nimmt am Thema teil, daher sind die folgenden Delegationen während der Diskussion ausgesetzt.";
 303.859  ["This name is already taken, please choose another one!"] = "Dieser Name ist bereits vergeben, bitte wähle einen anderen!";
 303.860 -["This name is really too short!"] = "Dieser Name ist wirklich zu kurz!";
 303.861  ["This name is too short!"] = "Dieser Name ist zu kurz!";
 303.862  ["This screen name is too short!"] = "Dieser Screen-Name ist zu kurz!";
 303.863  ["This service is provided by:"] = "Diensteanbieter:";
 303.864  ["This service is provided using the following software components:"] = "Dieser Dienst ist mit folgender Software realisiert worden:";
 303.865 -["This site is using"] = "Diese Seite benutzt";
 303.866  ["This suggestion has been meanwhile deleted"] = "Diese Anregung wurde zwischenzeitlich gelöscht";
 303.867  ["This title is really too short!"] = "Dieser Titel ist wirklich zu kurz!";
 303.868 -["Thursday"] = "Donnerstag";
 303.869 -["Timeline"] = "Zeitachse";
 303.870 +["This title is too long!"] = "Der Titel ist zu lang!";
 303.871  ["Title"] = "Titel";
 303.872 -["Title (80 chars max)"] = "Titel (max. 80 Zeichen)";
 303.873 -["Title of initiative"] = "Titel der Initiative";
 303.874 -["Today at #{time}"] = "Heute um #{time}";
 303.875 -["Traditional wiki syntax"] = "Traditionelle Wiki-Syntax";
 303.876 -["Trustee"] = "Bevollmächtigter";
 303.877 +["To create a competing initiative see below."] = "Um eine konkurrierende Initiative zu starten siehe unten.";
 303.878  ["Trustee has no voting right in this unit"] = "Bevollmächtigter hat kein Stimmrecht in dieser Gliederung";
 303.879 -["Tuesday"] = "Dienstag";
 303.880 -["Unconfirmed address"] = "Unbestätigte E-Mail";
 303.881 +["Underline main headlines with ==="] = "Haupt-Überschriften mit === unterstreichen";
 303.882 +["Underline sub headlines with ---"] = "Unter-Überschriften mit --- unterstreichen";
 303.883  ["Unit"] = "Gliederung";
 303.884 -["Unit '#{name}'"] = "Gliederung '#{name}'";
 303.885  ["Unit delegation"] = "Gliederungsdelegation";
 303.886  ["Unit list"] = "Liste der Gliederungen";
 303.887 -["Unit: '#{name}'"] = "Gliederung: '#{name}'";
 303.888 -["Units"] = "Gliederungen";
 303.889 -["Units and areas"] = "Gliederungen und Themengebiete";
 303.890  ["Unknown author"] = "Unbekannter Autor";
 303.891 -["Update voting comment"] = "Abstimmungskommentar ändern";
 303.892  ["Updated drafts"] = "Neue Entwürfe";
 303.893  ["Upload avatar/photo"] = "Avatar/Foto hochladen";
 303.894 -["Upload images"] = "Bilder hochladen";
 303.895 +["Use [Text](http://example.com/) for links"] = "[Text](http://example.com/) verwenden für Links";
 303.896  ["Use terms"] = "Nutzungsbedingungen";
 303.897 +["Verification"] = "Überprüfung";
 303.898 +["Verification #{time_info}"] = false;
 303.899  ["Verification started"] = "Phase Eingefroren gestartet";
 303.900 -["Verification starts soon"] = "Phase Eingefroren startet in Kürze";
 303.901  ["Verification time"] = "Zeit für Eingefroren";
 303.902 -["Version"] = "Version";
 303.903 -["Vote now"] = "Jetzt abstimmen";
 303.904 -["Voted"] = "Abgestimmt";
 303.905 +["Vote delegation"] = "Stimmdelegation";
 303.906  ["Voted no"] = "Mit Nein gestimmt";
 303.907  ["Voted yes"] = "Mit Ja gestimmt";
 303.908  ["Voters"] = "Abstimmende";
 303.909  ["Voting"] = "Abstimmung";
 303.910 +["Voting #{time_info}"] = false;
 303.911  ["Voting comment"] = "Abstimmungskommentar";
 303.912  ["Voting comment (last updated: #{timestamp})"] = "Abstimmmungskommentar (Letzte Änderung: #{timestamp})";
 303.913  ["Voting comment (optional)"] = "Abstimmmungskommentar (optional)";
 303.914 @@ -664,75 +685,87 @@
 303.915  ["Voting for this issue has already begun."] = "Die Abstimmung für dieses Thema hat schon begonnen.";
 303.916  ["Voting has not started yet."] = "Die Abstimmung hat noch nicht begonnen.";
 303.917  ["Voting started"] = "Abstimmung begonnen";
 303.918 -["Voting starts soon"] = "Abstimmung beginnt in Kürze";
 303.919  ["Voting time"] = "Zeit für die Abstimmung";
 303.920  ["We couldn't deliver a confirmation mail to this address. Please check entered email address."] = "Wir konnten keine Bestätigungs-E-Mail versenden. Bitte überprüfe die E-Mail-Adresse.";
 303.921  ["We have sent an email with activation link already in the last hour. Please try again later."] = "Wir haben bereits innerhalb der letzten Stunde eine E-Mail mit Bestätigungslink gesendet. Bitte versuche es später erneut.";
 303.922  ["Website"] = "Webseite";
 303.923 -["Wednesday"] = "Mittwoch";
 303.924 +["What can I do here?"] = "Was kann ich hier machen?";
 303.925 +["What this member is currently supporting"] = "Was dieses Mitglied zur Zeit unterstützt";
 303.926  ["Wiki engine"] = "Wiki engine";
 303.927  ["Wiki engine for statement"] = "Wiki engine für das Statement";
 303.928  ["Withdraw"] = "Zurückziehen";
 303.929  ["Withdraw membership"] = "Mitgliedschaft aufgeben";
 303.930  ["Yes"] = "Ja";
 303.931 -["Yesterday at #{time}"] = "Gestern um #{time}";
 303.932 +["Yes, it's implemented"] = "Ja, ist umgesetzt";
 303.933  ["You already voted this issue"] = "Du hast dieses Thema bereits abgestimmt";
 303.934  ["You are already initiator"] = "Du bist bereits Initiator";
 303.935 -["You are already not supporting this initiative"] = "Diese Initiative hat bereits keine Unterstützung von Dir";
 303.936  ["You are already supporting the latest draft"] = "Du unterstützt bereits den neuesten Entwurf";
 303.937  ["You are currently not invited to any initiative."] = "Du bist zur Zeit von keiner Initiative eingeladen.";
 303.938  ["You are currently not supporting this initiative directly. By adding suggestions to this initiative you will automatically become a potential supporter."] = "Du bist zur Zeit kein direkter Unterstützer dieser Initiative. Wenn Du eine Anregung hinzufügst wirst Du automatisch potentieller Unterstützer!";
 303.939  ["You are initiator of this initiative"] = "Du bist Initiator dieser Initiative";
 303.940 -["You are interested"] = "Du bist interessiert";
 303.941  ["You are interested in this issue"] = "Du bist an diesem Thema interessiert";
 303.942  ["You are invited to #{count} initiative(s)"] = "Du bist zu #{count} Initiativen als Initiator eingeladen";
 303.943  ["You are invited to LiquidFeedback. To register please click the following link:\n\n"] = "Du bist zu LiquidFeedback eingeladen. Bitte klicke auf den folgenden Link, um dich zu registrieren:\n\n";
 303.944 -["You are invited to become initiator of this initiative."] = "Du bist eingeladen Initiator dieser Initiative zu werden.";
 303.945 +["You are invited to become initiator of '#{initiative_name}'"] = "Einladung Initiator der Initiative '#{initiative_name}' zu werden";
 303.946 +["You are invited to become initiator of this initiative"] = "Du bist eingeladen Initiator dieser Initiative zu werden";
 303.947  ["You are member"] = "Du bist Mitglied";
 303.948 +["You are not eligible to participate"] = "Du bist nicht teilnahmeberechtigt";
 303.949 +["You are not entitled to vote in this unit"] = "Du bist in dieser Gliederung nicht stimmberechtigt";
 303.950  ["You are not participating in any of the #{count} areas in this unit"] = "Du nimmst an keinem der #{count} Themenbereiche dieser Gliederung teil";
 303.951  ["You are not participating in the only area of the unit"] = "Du nimmst am einzigen Themenbereich der Gliederung nicht teil";
 303.952  ["You are now initiator of this initiative"] = "Du bist jetzt Initiator dieser Initiative";
 303.953 -["You are participating in this area"] = "Du bist Teilnehmer im Themengebiet";
 303.954  ["You are potential supporter"] = "Du bist potentieller Unterstützer";
 303.955 -["You are potential supporter of this initiative"] = "Du bist potentieller Unterstützer der Initiative";
 303.956 -["You are potential supporter of this initiative via delegation"] = "Du bist durch Delegation potentieller Unterstützer der Initiative";
 303.957 +["You are subscribed for this subject area"] = "Du bist für diesen Themenbereich angemeldet";
 303.958  ["You are supporter"] = "Du bist Unterstützer";
 303.959 -["You are supporter of this initiative"] = "Du bist Unterstützer dieser Initiative";
 303.960 -["You are supporter of this initiative via delegation"] = "Du bist durch Delegation Unterstützer dieser Initiative";
 303.961 +["You are supporting this initiative"] = "Du unterstützt diese Initiative";
 303.962 +["You blocked this member (i.e. you will not be notified about this members actions)"] = "Du hast dieses Mitglied geblockt (d.h. du wirst nicht mehr über dessen Aktivitäten informiert)";
 303.963  ["You can change your email address only once per hour. Please try again later."] = "Du kannst die E-Mail-Adresse nur einmal in der Stunde ändern, bitte versuche es später erneut.";
 303.964 +["You can change your text again anytime during admission and discussion phase"] = "Du kannst den Text während der Zulassungs- und Diskussionsphase jederzeit wieder ändern";
 303.965 +["You can choose only members which you have been saved as contact before."] = "Du kannst nur Mitglieder ausählen, die du zuvor als Kontakt gespeichert hast.";
 303.966  ["You can't suggest the initiative you are revoking"] = "Du kannst nicht die Initiative empfehlen, die Du löschen möchtest";
 303.967 +["You cannot change your text again later, because this issue is already in verfication phase!"] = "Du kannst den Text später nicht mehr ändern, da das Thema bereits in der Überprüfungsphase ist!";
 303.968 +["You delegated this issue"] = "Du hast dieses Thema delegiert";
 303.969 +["You delegated this organizational unit"] = "Du hast diese Gliederung delegiert";
 303.970 +["You delegated this subject area"] = "Du hast diesen Themenbereich delegiert";
 303.971 +["You delegated this unit"] = "Du hast diese Gliederung delegiert";
 303.972  ["You didn't confirm your email address '#{email}' within 7 days."] = "Du hast die E-Mail-Adresse '#{email}' nicht innerhalb von 7 Tagen bestätigt.";
 303.973  ["You didn't confirm your email address '#{email}'. You have received an email with an activation link."] = "Du hast die E-Mail-Adresse '#{email}' nicht bestätigt. Du hast hierzu eine E-Mail mit einem Aktivierungslink erhalten.";
 303.974  ["You didn't save any member as contact yet."] = "Du hast noch kein Mitglied als Kontakt gespeichert!";
 303.975  ["You didn't set the level of notifications you like to receive"] = "Du hast noch nicht ausgewählt, ob und welche Benachrichtigungen du erhalten möchtest.";
 303.976 -["You have ignored this member"] = "Du ignorierst dieses Mitglied";
 303.977 +["You do not like to vote this issue (yourself)"] = "Du möchtest für dieses Thema nicht (selber) abstimmen";
 303.978 +["You have been voted"] = "Du hast abgestimmt";
 303.979  ["You have not voted #{count} issue(s) you were interested in"] = "Du hast für #{count} Themen, die dich interessieren, noch nicht abgestimmt";
 303.980  ["You have to mark 'Are you sure' to revoke!"] = "Zum Zurückziehen musst Du 'Sicher?' auswählen";
 303.981 -["You have voting privileges for this unit"] = "Du hast Stimmrecht in dieser Gliederung";
 303.982 -["You need to be logged in, to use all features of this system."] = "Du musst eingeloggt sein, um alle Funktionen dieses Systems nutzen zu können.";
 303.983 -["You were interested"] = "Du warst interessiert";
 303.984 +["You have voted"] = "Du hast abgestimmt";
 303.985 +["You have voted via delegation"] = "Du hast per Delegation abgestimmt";
 303.986 +["You may choose one of the ongoing initiatives you are currently supporting"] = "Du kannst eine der noch laufenden Initiativen auswählen, die du direkt unterstützt.";
 303.987 +["You refused to become initiator of this initiative"] = "Du hast abgelehnt Initiator dieser Initiative zu werden";
 303.988 +["You saved this member as contact (i.e. to use as delegatee)"] = "Du hast dieses Mitglied gespeichert (z.B. um es als Delegierten zu verwenden)";
 303.989 +["You saved this member as contact (i.e. to use as delegatee) and others can see it"] = "Du hast dieses Mitglied gespeichert (z.B. um es als Delegierten zu verwenden) und andere können das sehen";
 303.990  ["You were potential supporter"] = "Du bist potentieller Unterstützer";
 303.991  ["You were supporter"] = "Du bist Unterstützer";
 303.992  ["You've successfully registered and you can login now with your login and password!"] = "Du hast Dich erfolgreich registriert und kannst Dich jetzt mit Deinen Anmeldenamen und Kennwort anmelden!";
 303.993 +["Your avatar is a small photo, which will be shown always next to your name."] = "Dein Avatar ist ein kleines Bild, das überall neben deinem Namen angezeigt wird.";
 303.994 +["Your choice"] = "Deine Auswahl";
 303.995  ["Your email address has been changed, please check for confirmation email with activation link!"] = "Deine E-Mail-Adresse wurde geändert, du hast eine Bestätigungs-E-Mail mit Aktivierungslink erhalten.";
 303.996  ["Your login has been changed to '#{login}'"] = "Dein Anmeldename wurde auf '#{login}' geändert";
 303.997  ["Your name has been changed"] = "Dein Name wurde geändert";
 303.998  ["Your page has been updated"] = "Deine Seite wurde aktualisiert";
 303.999  ["Your password has been updated successfully"] = "Das Kennwort wurde erfolgreich geändert";
303.1000 +["Your photo will be shown in your profile."] = "Dein Foto wird deinem Profil angezeigt";
303.1001  ["Your rating has been deleted"] = "Deine Bewertung wurde gelöscht";
303.1002  ["Your rating has been updated"] = "Deine Bewertung wurde aktualisiert";
303.1003  ["Your request has been processed."] = "Die Anfrage wurde bearbeitet.";
303.1004  ["Your suggestion has been added"] = "Deine Anregung wurde hinzufügt";
303.1005 -["Your support has been added to this initiative"] = "Deine Unterstützung wurde der Initiative hinzugefügt";
303.1006 -["Your support has been removed from this initiative"] = "Deine Unterstützung wurde der Initiative entzogen";
303.1007  ["Your support has been updated to the latest draft"] = "Deine Unterstützung wurde auf den neuesten Entwurf aktualisiert";
303.1008  ["Your vote has been discarded. Delegation rules apply if set."] = "Deine Abstimmung wurde zurückgezogen. Delegationsregeln gelten sofern gesetzt.";
303.1009  ["Z-A"] = "Z-A";
303.1010  ["[Name of Language]"] = "Deutsch";
303.1011  ["[No voting privilege]"] = "[Kein Stimmrecht]";
303.1012  ["[Registered members only]"] = "[nur für Registrierte]";
303.1013 +["[calculating]"] = "[wird berechnet...]";
303.1014  ["[event mail]       URL: #{url}"] = "         URL: #{url}";
303.1015 -["[event mail]      Area: #{name}"] = "Themengebiet: #{name}";
303.1016 +["[event mail]      Area: #{name}"] = "Themenbereich: #{name}";
303.1017  ["[event mail]      Unit: #{name}"] = "  Gliederung: #{name}";
303.1018  ["[event mail]     Event: #{event}"] = "    Ereignis: #{event}";
303.1019  ["[event mail]     Issue: ##{id}"] = "       Thema: ##{id}";
303.1020 @@ -741,15 +774,58 @@
303.1021  ["[not displayed public]"] = "[nicht öffentlich]";
303.1022  ["a bit unsatisfied"] = "etwas unzufrieden";
303.1023  ["abandoned"] = "ausgesetzt";
303.1024 +["accept invitation"] = "Einladung annehmen";
303.1025  ["action"] = "Aktion";
303.1026 +["activate account"] = "Konto aktivieren";
303.1027  ["activated"] = "aktiviert";
303.1028 +["add my interest"] = "Interesse anmelden";
303.1029 +["add my support"] = "unterstützen";
303.1030 +["add to my list of private contacts"] = "Zur meiner Kontaktliste hinzufügen";
303.1031 +["add to my list of public contacts"] = "Zu meiner öffentlichen Kontaktliste hinzufügen";
303.1032 +["add your support (see above) and rate or write new suggestions (and thereby restrict your support to certain conditions if necessary)"] = "Die Initiative untersützen (siehe oben) und Verbesserungsvorschläge bewerten oder machen (und dabei ggfs. die Unterstützung beschränken)";
303.1033 +["all issues"] = "alle Themen";
303.1034 +["allow invitation again"] = "Einladen wieder erlauben";
303.1035 +["and"] = "und";
303.1036  ["and #{count} more initiatives"] = "und #{count} weitere Initiativen";
303.1037 -["and one more initiative"] = "und eine weitere Initiative";
303.1038 -["area"] = "Themengebiet";
303.1039 +["area"] = "Themenbereich";
303.1040  ["at least #{count} approvals"] = "mindestens #{count} Zustimmungen";
303.1041  ["at least #{count} approvals or abstentions"] = "mindestens #{count} Zustimmungen oder Enthaltungen";
303.1042 -["change discussion URL"] = "Diskussions-URL ändern";
303.1043 +["author"] = "Autor";
303.1044 +["avatar/photo"] = "Avatar/Foto";
303.1045 +["block this member"] = "Dieses Mitglied blocken";
303.1046 +["browse through the competing initiatives"] = "durch die konkurrierenden Initiativen sehen";
303.1047 +["but"] = "aber";
303.1048 +["by default only those issues are shown, for which your are eligible to participate (change filters on top of the list)"] = "Standardmäßig werden nur die Themen angezeigt, für die du teilnahmeberechtigt bist, Filter können am Anfang der Liste angepasst werden";
303.1049 +["cancel"] = "Abbrechen";
303.1050 +["cancel issue"] = "Thema abbrechen";
303.1051 +["cancel issue now"] = "Thema jetzt abbrechen";
303.1052 +["cancel registration"] = "Registrierung abbrechen";
303.1053 +["canceled"] = "abgebrochen";
303.1054 +["change avatar/photo"] = "Avatar/Foto ändern";
303.1055 +["change my vote"] = "Abstimmung ändern";
303.1056 +["change vote"] = "Abstimmung ändern";
303.1057 +["change your login"] = "Anmeldenamen ändern";
303.1058 +["change your notification email address"] = "E-Mail-Adresse für Benachrichtigungen ändern";
303.1059 +["change your password"] = "Kennwort ändern";
303.1060 +["change your screen name"] = "Screen name ändern";
303.1061 +["change/revoke area delegation"] = "Delegation für Themenbereich ändern/widerrufen";
303.1062 +["change/revoke delegation"] = "Delegation ändern/widerrufen";
303.1063 +["change/revoke delegation of organizational unit"] = "Delegation für Gliederung ändern/widerrufen";
303.1064 +["change/revoke delegation of subject area"] = "Delegation für Themenbereich ändern/widerrufen";
303.1065 +["change/revoke delegation only for this issue"] = "Delegation nur für dieses Thema ändern/widerrufen";
303.1066 +["change/revoke delegation only for this subject area"] = "Delegation nur für diesen Themenbereich ändern/widerrufen";
303.1067 +["change/revoke issue delegation"] = "Delegation für Thema ändern/widerrufen";
303.1068 +["check your "] = "überprüfe die ";
303.1069 +["choose delegatee"] = "Delegierten auswählen";
303.1070 +["choose issue delegatee"] = "Delegierten für Thema auswählen";
303.1071 +["choose subject area delegatee"] = "Delegierten für Themenbereich auswählen";
303.1072 +["collapse subject areas"] = "Themenbereiche einklappen";
303.1073 +["collective rating:"] = "kollektive Bewertung:";
303.1074 +["compare"] = "vergleichen";
303.1075 +["compare revisions"] = "Revisionen vergleichen";
303.1076  ["confirm"] = "bestätigen";
303.1077 +["confirmed address"] = "bestätigte Adresse";
303.1078 +["database download"] = "Datenbank herunterladen";
303.1079  ["day [interval ago]"] = "Tag";
303.1080  ["day [interval time left]"] = "Tag";
303.1081  ["day [interval]"] = "Tag";
303.1082 @@ -759,15 +835,47 @@
303.1083  ["deactivated"] = "deaktiviert";
303.1084  ["delegated to"] = "delegiert an";
303.1085  ["delegates to"] = "delegiert an";
303.1086 +["delegation suspended during discussion"] = "Delegation während der Diskussion ausgesetzt";
303.1087  ["delete<br /><br />"] = "löschen<br /><br />";
303.1088 -["disabled"] = "ausgeschaltet";
303.1089 +["developer settings"] = "Einstellungen für Entwickler";
303.1090 +["direct interest"] = "direktes Interesse";
303.1091 +["discard"] = "verwerfen";
303.1092 +["discard my vote"] = "Meine Stimme widerrufen";
303.1093 +["do not notify me about this voting anymore"] = "über diese Abstimmung nicht mehr benachrichtigen";
303.1094 +["draft ID"] = "Entwurf ID";
303.1095 +["draft history (#{count})"] = "Entwurfshistorie (#{count})";
303.1096 +["edit profile data"] = "Profildaten bearbeiten";
303.1097 +["edit proposal and/or reasons"] = "Antrag und/oder Begründung bearbeiten";
303.1098  ["email"] = "E-Mail";
303.1099 +["ends in #{state_time_left}"] = "endet in #{state_time_left}";
303.1100 +["ends soon"] = "endet bald";
303.1101 +["failed #{quorum}"] = "#{quorum} nicht erreicht";
303.1102 +["finished"] = "abgeschlossen";
303.1103  ["global"] = "Global";
303.1104 +["hide details"] = "Details ausblenden";
303.1105  ["i#{id}: #{name}"] = false;
303.1106 +["if you like to implement a suggestion in your proposal and/or reasons, update your initiative draft"] = "um einen Verbesserungsvorschlag umzusetzen, den Entwurfstext der Initiative aktualisieren";
303.1107  ["implemented"] = "umgesetzt";
303.1108 +["implemented:"] = "umgesetzt:";
303.1109 +["in all phases"] = "in allen Phasen";
303.1110 +["in my areas"] = "in meinen Themenbereichen";
303.1111 +["in my units"] = "in meinen Gliederungen";
303.1112  ["inactive"] = "inaktiv";
303.1113 -["last 24 hours"] = "letzte 24 Stunden";
303.1114 +["initiated by me"] = "von mir initiiert";
303.1115 +["interest via delegation"] = "Interesse per Delegation";
303.1116 +["interested directly or via delegation"] = "Interesse per Delegation oder direkt";
303.1117 +["invite another initiator"] = "weiteren Initiator einladen";
303.1118 +["is implemented"] = "ist umgesetzt";
303.1119 +["is not implemented"] = "ist nicht umgesetzt";
303.1120 +["issue"] = "Thema";
303.1121 +["issue view"] = "Themenansicht";
303.1122  ["login name"] = "Anmeldename";
303.1123 +["login to participate"] = "anmelden um teilzunehmen";
303.1124 +["logout"] = "abmelden";
303.1125 +["make this contact private"] = "diesen Kontakt nicht mehr öffentlich zeigen";
303.1126 +["make this contact public"] = "diesen Kontakt öffentlich zeigen";
303.1127 +["member"] = "Mitglied";
303.1128 +["member inactive"] = "Mitglied inaktiv";
303.1129  ["month [interval ago]"] = "Monat";
303.1130  ["month [interval time left]"] = "Monat";
303.1131  ["month [interval]"] = "Monat";
303.1132 @@ -776,28 +884,102 @@
303.1133  ["months [interval]"] = "Monate";
303.1134  ["more unsatisfied"] = "sehr unzufrieden";
303.1135  ["must"] = "muss";
303.1136 +["must be implemented"] = "muß umgesetzt werden";
303.1137  ["must not"] = "darf nicht";
303.1138 +["my issues"] = "meine Themen";
303.1139  ["neutral"] = "neutral";
303.1140  ["no reverse beat path to status quo (including ties)"] = "Kein rückwärtsgerichteter Schlagpfad zum Status Quo (Gleichstände eingeschlossen)";
303.1141  ["none"] = "kein";
303.1142 +["not admitted"] = "nicht zugelassen";
303.1143  ["not implemented"] = "nicht umgesetzt";
303.1144 +["not voted by me"] = "nicht von mir abgestimmt";
303.1145  ["not yet"] = "bis jetzt nicht";
303.1146 +["notification settings"] = "Benachrichtigungseinstellungen";
303.1147 +["notifications"] = "Benachrichtigungen";
303.1148 +["notifications settings"] = "Benachrichtigungseinstellungen";
303.1149 +["one step back"] = "einen Schritt zurück";
303.1150 +["open the appropriate subject area for your issue and follow the instruction on that page."] = "öffne das passende Themenbereich für dein Thema und folge dort den Anweisungen";
303.1151 +["open the organizational unit, subject area or issue you like to delegate and follow the instruction on that page."] = "öffne die Gliederung, den Themenbereich oder das Thema, das du delegieren möchtest und folge dort den Anweisungen";
303.1152 +["or swipe"] = "oder swipen";
303.1153 +["phase ends soon"] = "Phase endet bald";
303.1154  ["possibly instable result caused by multistage majority"] = "Möglicherweise instabiles Ergebnis aufgrund mehrstufiger Mehrheiten";
303.1155 +["preference voting"] = "Präferenzabstimmung";
303.1156 +["proceed with registration"] = "Registrierung fortsetzen";
303.1157  ["prohibit potentially instable results caused by multistage majorities"] = "Instabile Ergebnisse aufgrund mehrstufiger Mehrheiten verbieten";
303.1158 +["public administrative notice:"] = "Öffentlicher administrativer Kommentar";
303.1159 +["publish avatar/photo"] = "Avatar/Foto veröffentlichen";
303.1160 +["publish my rating"] = "Wertung veröffentlichen";
303.1161 +["publish profile data"] = "Profildaten veröffentlichen";
303.1162 +["publish suggestion"] = "Verbesserungsvorschlag veröffentlichen";
303.1163 +["published at"] = "veröffentlicht am/um";
303.1164 +["reached #{quorum}"] = "#{quorum} erreicht";
303.1165 +["refresh my support"] = "meine Unterstützung erneuern";
303.1166 +["refuse invitation"] = "Einladung ablehnen";
303.1167 +["remove an initiator"] = "Initiator entfernen";
303.1168 +["remove from my contact list"] = "aus meiner Kontaktliste entfernen";
303.1169 +["remove my interest"] = "Interesse abmelden";
303.1170 +["remove my support"] = "Unterstützung widerrufen";
303.1171  ["reverse beat path to status quo (including ties)"] = "Rückwärtsgerichteter Schlagpfad zum Status Quo (Gleichstände eingeschlossen)";
303.1172  ["revoke"] = "zurückziehen";
303.1173 +["revoke initiative"] = "Initiative zurückziehen";
303.1174 +["revoked"] = "zurückgezogen";
303.1175  ["satisfied"] = "zufrieden";
303.1176 +["search"] = "suchen";
303.1177 +["select tabs"] = "Andere Tabs auswählen";
303.1178  ["should"] = "soll";
303.1179 +["should be implemented"] = "soll umgesetzt werden";
303.1180  ["should not"] = "soll nicht";
303.1181 +["show all units"] = "Alle Gliederungen anzeigen";
303.1182 +["show details"] = "Details anzeigen";
303.1183 +["show differences"] = "Unterschiede anzeigen";
303.1184 +["show other subject areas"] = "andere Themenbereiche anzeigen";
303.1185 +["show saved contacts"] = "Gespeicherte Kontakte anzeigen";
303.1186 +["show subject areas"] = "Themenbereiche anzeigen";
303.1187 +["show vote"] = "Stimmzettel anzeigen";
303.1188 +["start a new competing initiative"] = "eine neue konkurrierende Initiative starten";
303.1189 +["start an initiative in a new issue"] = "eine Initiative in einem neuen Thema starten";
303.1190 +["structured discussion"] = "strukturierte Diskussion";
303.1191 +["subscribe"] = "Interesse anmelden";
303.1192 +["subscribe subject areas or add your interested to issues and you will be notified about changes (follow the instruction on the area or issue page)"] = "Melde dich für Themenbereiche an oder interessiere dich für Themen, damit du benachrichtigst wird (folge den Anweisungen auf der Themenbereichs- bzw. Themenseite)";
303.1193 +["subscribed"] = "am Themenbereich angemeldet";
303.1194 +["suggestions (#{count}) ↓"] = "Verbesserungsvorschläge (#{count}) ↓";
303.1195 +["supporter"] = "Unterstützer";
303.1196 +["supporter with restricting suggestions"] = "Unterstützer mit beschränkenden Verbesserungsvorschlägen";
303.1197 +["take a look at the competing initiatives"] = "schau dir die konkurrierenden Initiativen an";
303.1198 +["take a look at the suggestions (see left) and rate them"] = "schau dir die Anregungen (links) an und bewerte sie";
303.1199 +["take a look at the suggestions of your supporters"] = "schau die die Anregungen deiner Unterstützer an";
303.1200 +["take a look on the issues (see left)"] = "schau dir die Themen an (siehe links)";
303.1201  ["the following login is connected to this email address:\n\n"] = "der folgende Anmeldename ist mit dieser E-Mail-Adresse verknüpft:\n\n";
303.1202 +["this issue is in verification phase, therefore the initiative text cannot be updated anymore"] = "dieses Thema ist in der Überprüfungsphase, daher kann der Text nicht mehr geändert werden";
303.1203 +["this issue is in voting phase, therefore the initiative text cannot be updated anymore"] = "dieses Thema ist in Abstimmung, daher kann der Text nicht mehr geändert werden";
303.1204 +["timeline"] = "Zeitlicher Verlauf";
303.1205 +["to argue about suggestions, just add your arguments to your reasons in the initiative draft, so your supporters can learn about your opinion"] = "um Verbesserungsvorschlägen zu kommentieren, füge deine Argumente in den Text deiner Initiative ein, damit deine Untersützer deine Position verstehen können";
303.1206  ["to reset your password please click on the following link:\n\n"] = "um Dein Kennwort zurückzusetzen klicke bitte den folgenden Link an:\n\n";
303.1207 +["to show more info and learn what you can do"] = "für mehr Infos und 'Was kann ich tun?'";
303.1208 +["today at #{time}"] = "heute um #{time}";
303.1209 +["unblock member"] = "Blockierung aufheben";
303.1210 +["unconfirmed address"] = "unbestätigte Adresse";
303.1211  ["unit"] = "Gliederung";
303.1212 -["unit / area"] = "Gliederung / Themengebiet";
303.1213 +["unit / area"] = "Gliederung / Themenbereich";
303.1214 +["unsubscribe"] = "Interesse abmelden";
303.1215  ["until"] = "bis";
303.1216 +["update area"] = "Themenbereich aktualisiern";
303.1217 +["update member"] = "Mitglied aktualisieren";
303.1218 +["update policy"] = "Regelwerk aktualisieren";
303.1219 +["update unit"] = "Gliederung aktualisieren";
303.1220  ["variable"] = "variabel";
303.1221 -["with winner"] = "mit Gewinner";
303.1222 +["via delegation"] = "per Delegation";
303.1223 +["vote delegation"] = "Stimmdelegation";
303.1224 +["vote now"] = "jetzt abstimmen";
303.1225 +["voted and not voted by me"] = "von mir abgestimmt und nicht abgestimmt";
303.1226 +["voted by me"] = "von mir abgestimmt";
303.1227 +["voted directly by me"] = "von mir direkt abgestimmt";
303.1228 +["voted no"] = "mit Nein gestimmt";
303.1229 +["voted via delegation"] = "von mir per Delegation abgestimmt";
303.1230 +["voted yes"] = "mit Ja gestimmt";
303.1231  ["without"] = "ohne";
303.1232 -["without winner"] = "ohne Gewinner";
303.1233 +["write a new suggestion"] = "neuen Verbesserungsvorschlag einbringen";
303.1234 +["written and rated by the supportes of this initiative to improve the proposal and its reasons"] = "geschrieben und bewertet von Unterstützern dieser Initiative";
303.1235  ["xmpp"] = "Jabber (XMPP)";
303.1236  ["year [interval ago]"] = "Jahr";
303.1237  ["year [interval time left]"] = "Jahr";
303.1238 @@ -805,4 +987,10 @@
303.1239  ["years [interval ago]"] = "Jahren";
303.1240  ["years [interval time left]"] = "Jahre";
303.1241  ["years [interval]"] = "Jahre";
303.1242 +["yesterday at #{time}"] = "gestern um #{time}";
303.1243 +["you are interested"] = "du bist interessiert";
303.1244 +["you are subscribed"] = "du bist am Themembreich angemeldet";
303.1245 +["you have #{count} incoming delegations"] = "#{count} eingehende Delegationen";
303.1246 +["you restricted your support by rating suggestions as must or must not"] = "deine Untersützung ist aufgrund von 'muss'- oder 'darf nicht'-Anregungen beschränkt";
303.1247 +["you voted"] = "du hast abgestimmt";
303.1248  }
   304.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   304.2 +++ b/model/battle.lua	Thu Jul 10 01:19:48 2014 +0200
   304.3 @@ -0,0 +1,10 @@
   304.4 +Battle = mondelefant.new_class()
   304.5 +Battle.table = 'battle'
   304.6 +
   304.7 +function Battle:getByInitiativeIds(winning_id, losing_id)
   304.8 +  local selector = Battle:new_selector()
   304.9 +  selector:add_where { "winning_initiative_id = ?", winning_id }
  304.10 +  selector:add_where { "losing_initiative_id = ?", losing_id }
  304.11 +  selector:optional_object_mode()
  304.12 +  return selector:exec()
  304.13 +end
   305.1 --- a/model/contact.lua	Thu Jul 10 01:02:43 2014 +0200
   305.2 +++ b/model/contact.lua	Thu Jul 10 01:19:48 2014 +0200
   305.3 @@ -33,6 +33,9 @@
   305.4    if args.member_id then
   305.5      selector:add_where{ "member_id = ?", args.member_id }
   305.6    end
   305.7 +  if args.public ~= nil then
   305.8 +    selector:add_where{ "public = ?", args.public }
   305.9 +  end
  305.10    if args.order then
  305.11      if args.order == "name" then
  305.12        selector:add_order_by("member.name")
   306.1 --- a/model/initiative.lua	Thu Jul 10 01:02:43 2014 +0200
   306.2 +++ b/model/initiative.lua	Thu Jul 10 01:19:48 2014 +0200
   306.3 @@ -10,6 +10,14 @@
   306.4  }
   306.5  
   306.6  Initiative:add_reference{
   306.7 +  mode          = 'm1',
   306.8 +  to            = "Member",
   306.9 +  this_key      = 'revoked_by_member_id',
  306.10 +  that_key      = 'id',
  306.11 +  ref           = 'revoked_by_member',
  306.12 +}
  306.13 +
  306.14 +Initiative:add_reference{
  306.15    mode          = '1m',
  306.16    to            = "Draft",
  306.17    this_key      = 'id',
  306.18 @@ -26,6 +34,7 @@
  306.19    that_key      = 'initiative_id',
  306.20    ref           = 'suggestions',
  306.21    back_ref      = 'initiative',
  306.22 +  default_order = '"proportional_order" NULLS LAST, id'
  306.23  }
  306.24  
  306.25  Initiative:add_reference{
  306.26 @@ -223,6 +232,61 @@
  306.27      :add_where("initiative.revoked ISNULL")
  306.28  end
  306.29  
  306.30 +function Initiative:getSpecialSelector( args )
  306.31 +  local selector = Initiative:new_selector()
  306.32 +  selector:join( "issue", nil, "issue.id = initiative.issue_id" )
  306.33 +  selector:join( "area", nil, "area.id = issue.area_id" )
  306.34 +  if args.area_id then
  306.35 +    selector:add_where{ "area.id = ?", args.area_id }
  306.36 +  elseif args.unit_id then
  306.37 +    selector:add_where{ "area.unit_id = ?", args.unit_id }
  306.38 +  end
  306.39 +  selector:limit( 1 )
  306.40 +  selector:optional_object_mode()
  306.41 +  return selector
  306.42 +end
  306.43 +
  306.44 +function Initiative:getLastWinner( args )
  306.45 +  local selector = Initiative:getSpecialSelector( args )
  306.46 +  selector:add_where( "issue.state = 'finished_with_winner'" )
  306.47 +  selector:add_order_by( "issue.closed DESC, id DESC" )
  306.48 +  return selector:exec()
  306.49 +end
  306.50 +
  306.51 +function Initiative:getLastLoser( args )
  306.52 +  local selector = Initiative:getSpecialSelector( args )
  306.53 +  selector:add_where( "issue.state = 'finished_without_winner'" )
  306.54 +  selector:add_order_by( "issue.closed DESC, id DESC" )
  306.55 +  return selector:exec()
  306.56 +end
  306.57 +
  306.58 +function Initiative:getNextEndingVoting( args )
  306.59 +  local selector = Initiative:getSpecialSelector( args )
  306.60 +  selector:add_where( "issue.state = 'voting'" )
  306.61 +  selector:add_order_by( "issue.fully_frozen + issue.verification_time DESC, id DESC" )
  306.62 +  return selector:exec()
  306.63 +end
  306.64 +
  306.65 +function Initiative:getNextEndingVerification( args )
  306.66 +  local selector = Initiative:getSpecialSelector( args )
  306.67 +  selector:add_where( "issue.state = 'verification'" )
  306.68 +  selector:add_order_by( "issue.half_frozen + issue.verification_time DESC, id DESC" )
  306.69 +  return selector:exec()
  306.70 +end
  306.71 +
  306.72 +function Initiative:getNextEndingDiscussion( args )
  306.73 +  local selector = Initiative:getSpecialSelector( args )
  306.74 +  selector:add_where( "issue.state = 'discussion'" )
  306.75 +  selector:add_order_by( "issue.accepted + issue.discussion_time DESC, id DESC" )
  306.76 +  return selector:exec()
  306.77 +end
  306.78 +
  306.79 +function Initiative:getBestInAdmission( args )
  306.80 +  local selector = Initiative:getSpecialSelector( args )
  306.81 +  selector:add_where( "issue.state = 'admission'" )
  306.82 +  selector:add_order_by( "issue.created + issue.admission_time DESC, id DESC" )
  306.83 +  return selector:exec()
  306.84 +end
  306.85  
  306.86  function Initiative.object_get:current_draft()
  306.87    return Draft:new_selector()
  306.88 @@ -240,6 +304,10 @@
  306.89    return name
  306.90  end
  306.91  
  306.92 +function Initiative.object_get:display_name()
  306.93 +  return "i" .. self.id .. ": " .. self.name
  306.94 +end
  306.95 +
  306.96  function Initiative.object_get:initiator_names()
  306.97    local members = Member:new_selector()
  306.98      :join("initiator", nil, "initiator.member_id = member.id")
  306.99 @@ -254,3 +322,8 @@
 306.100    return member_names
 306.101  end
 306.102  
 306.103 +function Initiative.object_get:potential_supporter_count()
 306.104 +  if self.supporter_count and self.satisfied_supporter_count then
 306.105 +    return self.supporter_count - self.satisfied_supporter_count
 306.106 +  end
 306.107 +end
   307.1 --- a/model/issue.lua	Thu Jul 10 01:02:43 2014 +0200
   307.2 +++ b/model/issue.lua	Thu Jul 10 01:19:48 2014 +0200
   307.3 @@ -142,23 +142,29 @@
   307.4      if #ids == 0 then
   307.5        return sub_selector:empty_list_mode()
   307.6      end
   307.7 -    sub_selector:from("issue")
   307.8 -    sub_selector:add_field("issue.id", "issue_id")
   307.9 -    sub_selector:add_field{ '(delegation_info(?, null, null, issue.id, ?)).*', options.member_id, options.trustee_id }
  307.10 -    sub_selector:add_where{ 'issue.id IN ($)', ids }
  307.11 +    sub_selector:from ( "issue" )
  307.12 +    sub_selector:add_field ( "issue.id", "issue_id" )
  307.13 +    sub_selector:add_field { '(delegation_info(?, null, null, issue.id, ?)).*', options.member_id, options.trustee_id }
  307.14 +    sub_selector:add_where { 'issue.id IN ($)', ids }
  307.15  
  307.16      local selector = Issue:get_db_conn():new_selector()
  307.17 -    selector:add_from("issue")
  307.18 -    selector:join(sub_selector, "delegation_info", "delegation_info.issue_id = issue.id")
  307.19 -    selector:left_join("member", "first_trustee", "first_trustee.id = delegation_info.first_trustee_id")
  307.20 -    selector:left_join("member", "other_trustee", "other_trustee.id = delegation_info.other_trustee_id")
  307.21 -    selector:add_field("delegation_info.*")
  307.22 -    selector:add_field("first_trustee.name", "first_trustee_name")
  307.23 -    selector:add_field("other_trustee.name", "other_trustee_name")
  307.24 -    selector:left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", options.member_id })
  307.25 -    selector:add_field("direct_voter.member_id NOTNULL", "direct_voted")
  307.26 -    selector:left_join("non_voter", nil, { "non_voter.issue_id = issue.id AND non_voter.member_id = ?", options.member_id })
  307.27 -    selector:add_field("non_voter.member_id NOTNULL", "non_voter")
  307.28 +    selector:add_from ( "issue" )
  307.29 +    selector:join(sub_selector, "delegation_info", "delegation_info.issue_id = issue.id" )
  307.30 +    selector:left_join ( "member", "first_trustee", "first_trustee.id = delegation_info.first_trustee_id" )
  307.31 +    selector:left_join ( "member", "other_trustee", "other_trustee.id = delegation_info.other_trustee_id" )
  307.32 +    selector:add_field ( "delegation_info.*" )
  307.33 +    selector:add_field ( "first_trustee.name", "first_trustee_name" )
  307.34 +    selector:add_field ( "other_trustee.name", "other_trustee_name" )
  307.35 +    selector:left_join ( "direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", options.member_id })
  307.36 +    selector:add_field ( "direct_voter.member_id NOTNULL", "direct_voted")
  307.37 +    selector:left_join ( "non_voter", nil, { "non_voter.issue_id = issue.id AND non_voter.member_id = ?", options.member_id })
  307.38 +    selector:add_field ( "non_voter.member_id NOTNULL", "non_voter" )
  307.39 +    selector:left_join ( "direct_interest_snapshot", nil, { [[
  307.40 +      direct_interest_snapshot.issue_id = issue.id AND 
  307.41 +      direct_interest_snapshot.event = issue.latest_snapshot_event AND 
  307.42 +      direct_interest_snapshot.member_id = ?
  307.43 +    ]], options.member_id }) 
  307.44 +    selector:add_field ( "direct_interest_snapshot.weight", "weight" )
  307.45      return selector
  307.46    end
  307.47  }
  307.48 @@ -189,19 +195,19 @@
  307.49  
  307.50  function Issue:get_state_name_for_state(value)
  307.51    local state_name_table = {
  307.52 -    admission = _"New",
  307.53 +    admission = _"Admission",
  307.54      discussion = _"Discussion",
  307.55 -    verification = _"Frozen",
  307.56 +    verification = _"Verification",
  307.57      voting = _"Voting",
  307.58 -    canceled_revoked_before_accepted = _"Canceled (before accepted due to revocation)",
  307.59 -    canceled_issue_not_accepted = _"Canceled (issue not accepted)",
  307.60 -    canceled_after_revocation_during_discussion = _"Canceled (during discussion due to revocation)",
  307.61 -    canceled_after_revocation_during_verification = _"Canceled (during verification due to revocation)",
  307.62 +    canceled_revoked_before_accepted = _"Revoked (during admission)",
  307.63 +    canceled_issue_not_accepted = _"Failed 1st quorum",
  307.64 +    canceled_after_revocation_during_discussion = _"Revoked (during discussion)",
  307.65 +    canceled_after_revocation_during_verification = _"Revoked (during verification)",
  307.66      canceled_by_admin = _"Canceled by administrative intervention",
  307.67      calculation = _"Calculation",
  307.68 -    canceled_no_initiative_admitted = _"Canceled (no initiative admitted)",
  307.69 -    finished_without_winner = _"Finished (without winner)",
  307.70 -    finished_with_winner = _"Finished (with winner)",
  307.71 +    canceled_no_initiative_admitted = _"All initiatives failed 2nd quorum",
  307.72 +    finished_without_winner = _"Disapproved",
  307.73 +    finished_with_winner = _"Finished with winner",
  307.74    }
  307.75    return state_name_table[value] or value or ''
  307.76  end
  307.77 @@ -275,3 +281,17 @@
  307.78  function Issue.object_get:etherpad_url()
  307.79    return config.etherpad.base_url .. "p/" .. config.etherpad.group_id .. "$Issue" .. self.id
  307.80  end
  307.81 +
  307.82 +function Issue.object_get:name()
  307.83 +  return self.policy.name .. " #" .. self.id
  307.84 +end
  307.85 +
  307.86 +function Issue.object_get:state_time_text()
  307.87 +  if self.closed then
  307.88 +    return _("#{closed_ago} ago", { closed_ago = self.closed_ago })
  307.89 +  elseif string.sub(self.state_time_left, 1, 2) ~= "-" then
  307.90 +    return _("ends soon", { state_time_left = self.state_time_left })
  307.91 +  else
  307.92 +    return _("ends in #{state_time_left}", { state_time_left = self.state_time_left })
  307.93 +  end
  307.94 +end
   308.1 --- a/model/member.lua	Thu Jul 10 01:02:43 2014 +0200
   308.2 +++ b/model/member.lua	Thu Jul 10 01:19:48 2014 +0200
   308.3 @@ -124,7 +124,7 @@
   308.4    that_key      = 'truster_id',
   308.5    ref           = 'outgoing_delegations',
   308.6    back_ref      = 'truster',
   308.7 -  default_order = '"id"'
   308.8 +--  default_order = '"id"'
   308.9  }
  308.10  
  308.11  Member:add_reference{
  308.12 @@ -134,7 +134,7 @@
  308.13    that_key      = 'trustee_id',
  308.14    ref           = 'incoming_delegations',
  308.15    back_ref      = 'trustee',
  308.16 -  default_order = '"id"'
  308.17 +--  default_order = '"id"'
  308.18  }
  308.19  
  308.20  Member:add_reference{
   309.1 Binary file static/back.png has changed
   310.1 Binary file static/back50.png has changed
   311.1 Binary file static/icons/16/chart_organisation.png has changed
   312.1 Binary file static/icons/32/empty.png has changed
   313.1 Binary file static/icons/32/phase_current.png has changed
   314.1 Binary file static/icons/32/phase_failed.png has changed
   315.1 Binary file static/icons/32/phase_finished.png has changed
   316.1 Binary file static/icons/32/support_none.png has changed
   317.1 Binary file static/icons/32/support_satisfied.png has changed
   318.1 Binary file static/icons/32/support_satisfied_via_delegation.png has changed
   319.1 Binary file static/icons/32/support_unsatisfied.png has changed
   320.1 Binary file static/icons/32/support_unsatisfied_via_delegation.png has changed
   321.1 Binary file static/icons/32/voted_no.png has changed
   322.1 Binary file static/icons/48/bell.png has changed
   323.1 Binary file static/icons/48/eye.png has changed
   324.1 Binary file static/icons/48/home.png has changed
   325.1 Binary file static/icons/48/info.png has changed
   326.1 Binary file static/icons/48/lf_plus.png has changed
   327.1 Binary file static/icons/48/star.png has changed
   328.1 Binary file static/icons/48/star_empty.png has changed
   329.1 Binary file static/icons/48/voted_ok.png has changed
   330.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   330.2 +++ b/static/js/less-1.4.1.min.js	Thu Jul 10 01:19:48 2014 +0200
   330.3 @@ -0,0 +1,11 @@
   330.4 +/*
   330.5 + * LESS - Leaner CSS v1.4.1
   330.6 + * http://lesscss.org
   330.7 + *
   330.8 + * Copyright (c) 2009-2013, Alexis Sellier
   330.9 + * Licensed under the Apache 2.0 License.
  330.10 + *
  330.11 + * @licence
  330.12 + */(function(e,t){function n(t){return e.less[t.split("/")[1]]}function f(){r.env==="development"?(r.optimization=0,r.watchTimer=setInterval(function(){r.watchMode&&g(function(e,t,n,i,s){e?k(e,i.href):t&&S(t.toCSS(r),i,s.lastModified)})},r.poll)):r.optimization=3}function m(){var e=document.getElementsByTagName("style");for(var t=0;t<e.length;t++)if(e[t].type.match(p)){var n=new r.tree.parseEnv(r);n.filename=document.location.href.replace(/#.*$/,""),(new r.Parser(n)).parse(e[t].innerHTML||"",function(n,i){if(n)return k(n,"inline");var s=i.toCSS(r),o=e[t];o.type="text/css",o.styleSheet?o.styleSheet.cssText=s:o.innerHTML=s})}}function g(e,t){for(var n=0;n<r.sheets.length;n++)w(r.sheets[n],e,t,r.sheets.length-(n+1))}function y(e,t){var n=b(e),r=b(t),i,s,o,u,a="";if(n.hostPart!==r.hostPart)return"";s=Math.max(r.directories.length,n.directories.length);for(i=0;i<s;i++)if(r.directories[i]!==n.directories[i])break;u=r.directories.slice(i),o=n.directories.slice(i);for(i=0;i<u.length-1;i++)a+="../";for(i=0;i<o.length-1;i++)a+=o[i]+"/";return a}function b(e,t){var n=/^((?:[a-z-]+:)?\/+?(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/,r=e.match(n),i={},s=[],o,u;if(!r)throw new Error("Could not parse sheet href - '"+e+"'");if(!r[1]||r[2]){u=t.match(n);if(!u)throw new Error("Could not parse page url - '"+t+"'");r[1]=r[1]||u[1]||"",r[2]||(r[3]=u[3]+r[3])}if(r[3]){s=r[3].replace("\\","/").split("/");for(o=0;o<s.length;o++)s[o]==="."&&(s.splice(o,1),o-=1);for(o=0;o<s.length;o++)s[o]===".."&&o>0&&(s.splice(o-1,2),o-=2)}return i.hostPart=r[1],i.directories=s,i.path=r[1]+s.join("/"),i.fileUrl=i.path+(r[4]||""),i.url=i.fileUrl+(r[5]||""),i}function w(t,n,i,s){var o=b(t.href,e.location.href),u=o.url,a=l&&l.getItem(u),f=l&&l.getItem(u+":timestamp"),c={css:a,timestamp:f},h,p={relativeUrls:r.relativeUrls,currentDirectory:o.path,filename:u};t instanceof r.tree.parseEnv?(h=new r.tree.parseEnv(t),p.entryPath=h.currentFileInfo.entryPath,p.rootpath=h.currentFileInfo.rootpath,p.rootFilename=h.currentFileInfo.rootFilename):(h=new r.tree.parseEnv(r),h.mime=t.type,p.entryPath=o.path,p.rootpath=r.rootpath||o.path,p.rootFilename=u),h.relativeUrls&&(r.rootpath?p.rootpath=b(r.rootpath+y(o.path,p.entryPath)).path:p.rootpath=o.path),x(u,t.type,function(e,a){v+=e.replace(/@import .+?;/ig,"");if(!i&&c&&a&&(new Date(a)).valueOf()===(new Date(c.timestamp)).valueOf())S(c.css,t),n(null,null,e,t,{local:!0,remaining:s},u);else try{h.contents[u]=e,h.paths=[o.path],h.currentFileInfo=p,(new r.Parser(h)).parse(e,function(r,i){if(r)return n(r,null,null,t);try{n(r,i,e,t,{local:!1,lastModified:a,remaining:s},u),h.currentFileInfo.rootFilename===u&&N(document.getElementById("less-error-message:"+E(u)))}catch(r){n(r,null,null,t)}})}catch(f){n(f,null,null,t)}},function(e,r){n({type:"File",message:"'"+r+"' wasn't found ("+e+")"},null,null,t)})}function E(e){return e.replace(/^[a-z-]+:\/+?[^\/]+/,"").replace(/^\//,"").replace(/\.[a-zA-Z]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function S(e,t,n){var r=t.href||"",i="less:"+(t.title||E(r)),s=document.getElementById(i),o=!1,u=document.createElement("style");u.setAttribute("type","text/css"),t.media&&u.setAttribute("media",t.media),u.id=i;if(u.styleSheet)try{u.styleSheet.cssText=e}catch(a){throw new Error("Couldn't reassign styleSheet.cssText.")}else u.appendChild(document.createTextNode(e)),o=s!==null&&s.childNodes.length>0&&u.childNodes.length>0&&s.firstChild.nodeValue===u.firstChild.nodeValue;var f=document.getElementsByTagName("head")[0];if(s==null||o===!1){var c=t&&t.nextSibling||null;(c||document.getElementsByTagName("head")[0]).parentNode.insertBefore(u,c)}s&&o===!1&&f.removeChild(s);if(n&&l){C("saving "+r+" to cache.");try{l.setItem(r,e),l.setItem(r+":timestamp",n)}catch(a){C("failed to save")}}}function x(e,t,n,i){function a(t,n,r){t.status>=200&&t.status<300?n(t.responseText,t.getResponseHeader("Last-Modified")):typeof r=="function"&&r(t.status,e)}var s=T(),u=o?r.fileAsync:r.async;typeof s.overrideMimeType=="function"&&s.overrideMimeType("text/css"),s.open("GET",e,u),s.setRequestHeader("Accept",t||"text/x-less, text/css; q=0.9, */*; q=0.5"),s.send(null),o&&!r.fileAsync?s.status===0||s.status>=200&&s.status<300?n(s.responseText):i(s.status,e):u?s.onreadystatechange=function(){s.readyState==4&&a(s,n,i)}:a(s,n,i)}function T(){if(e.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(t){return C("browser doesn't support AJAX."),null}}function N(e){return e&&e.parentNode.removeChild(e)}function C(e){r.env=="development"&&typeof console!="undefined"&&console.log("less: "+e)}function k(e,n){var i="less-error-message:"+E(n||""),s='<li><label>{line}</label><pre class="{class}">{content}</pre></li>',o=document.createElement("div"),u,a,f=[],l=e.filename||n,c=l.match(/([^\/]+(\?.*)?)$/)[1];o.id=i,o.className="less-error-message",a="<h3>"+(e.type||"Syntax")+"Error: "+(e.message||"There is an error in your .less file")+"</h3>"+'<p>in <a href="'+l+'">'+c+"</a> ";var h=function(e,n,r){e.extract[n]!=t&&f.push(s.replace(/\{line\}/,(parseInt(e.line)||0)+(n-1)).replace(/\{class\}/,r).replace(/\{content\}/,e.extract[n]))};e.extract?(h(e,0,""),h(e,1,"line"),h(e,2,""),a+="on line "+e.line+", column "+(e.column+1)+":</p>"+"<ul>"+f.join("")+"</ul>"):e.stack&&(a+="<br/>"+e.stack.split("\n").slice(1).join("<br/>")),o.innerHTML=a,S([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),o.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),r.env=="development"&&(u=setInterval(function(){document.body&&(document.getElementById(i)?document.body.replaceChild(o,document.getElementById(i)):document.body.insertBefore(o,document.body.firstChild),clearInterval(u))},10))}var r,i,s;typeof environment=="object"&&{}.toString.call(environment)==="[object Environment]"?(typeof e=="undefined"?r={}:r=e.less={},i=r.tree={},r.mode="rhino"):typeof e=="undefined"?(r=exports,i=n("./tree"),r.mode="node"):(typeof e.less=="undefined"&&(e.less={}),r=e.less,i=e.less.tree={},r.mode="browser"),r.Parser=function(t){function m(){a=c[u],f=o,h=o}function g(){c[u]=a,o=f,h=o}function y(){o>h&&(c[u]=c[u].slice(o-h),h=o)}function b(e){var t=e.charCodeAt(0);return t===32||t===10||t===9}function w(e){var t,n,r,i,a;if(e instanceof Function)return e.call(p.parsers);if(typeof e=="string")t=s.charAt(o)===e?e:null,r=1,y();else{y();if(!(t=e.exec(c[u])))return null;r=t[0].length}if(t)return E(r),typeof t=="string"?t:t.length===1?t[0]:t}function E(e){var t=o,n=u,r=o+c[u].length,i=o+=e;while(o<r){if(!b(s.charAt(o)))break;o++}return c[u]=c[u].slice(e+(o-i)),h=o,c[u].length===0&&u<c.length-1&&u++,t!==o||n!==u}function S(e,t){var n=w(e);if(!!n)return n;x(t||(typeof e=="string"?"expected '"+e+"' got '"+s.charAt(o)+"'":"unexpected token"))}function x(e,t){var n=new Error(e);throw n.index=o,n.type=t||"Syntax",n}function T(e){return typeof e=="string"?s.charAt(o)===e:e.test(c[u])?!0:!1}function N(e,t){return e.filename&&t.currentFileInfo.filename&&e.filename!==t.currentFileInfo.filename?p.imports.contents[e.filename]:s}function C(e,t){for(var n=e,r=-1;n>=0&&t.charAt(n)!=="\n";n--)r++;return{line:typeof e=="number"?(t.slice(0,e).match(/\n/g)||"").length:null,column:r}}function k(e,t,i){var s=i.currentFileInfo.filename;return r.mode!=="browser"&&r.mode!=="rhino"&&(s=n("path").resolve(s)),{lineNumber:C(e,t).line+1,fileName:s}}function L(e,t){var n=N(e,t),r=C(e.index,n),i=r.line,s=r.column,o=n.split("\n");this.type=e.type||"Syntax",this.message=e.message,this.filename=e.filename||t.currentFileInfo.filename,this.index=e.index,this.line=typeof i=="number"?i+1:null,this.callLine=e.call&&C(e.call,n).line+1,this.callExtract=o[C(e.call,n).line],this.stack=e.stack,this.column=s,this.extract=[o[i-1],o[i],o[i+1]]}var s,o,u,a,f,l,c,h,p,d=this;t instanceof i.parseEnv||(t=new i.parseEnv(t));var v=this.imports={paths:t.paths||[],queue:[],files:t.files,contents:t.contents,mime:t.mime,error:null,push:function(e,n,i){var s=this;this.queue.push(e),r.Parser.importer(e,n,function(t,n,r){s.queue.splice(s.queue.indexOf(e),1);var o=r in s.files;s.files[r]=n,t&&!s.error&&(s.error=t),i(t,n,o)},t)}};return L.prototype=new Error,L.prototype.constructor=L,this.env=t=t||{},this.optimization="optimization"in this.env?this.env.optimization:1,p={imports:v,parse:function(e,a){var f,d,v,m,g,y,b=[],E,S=null;o=u=h=l=0,s=e.replace(/\r\n/g,"\n"),s=s.replace(/^\uFEFF/,""),c=function(e){var n=0,r=/(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,i=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,o=/"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,u=0,a,f=e[0],l;for(var c=0,h,p;c<s.length;){r.lastIndex=c,(a=r.exec(s))&&a.index===c&&(c+=a[0].length,f.push(a[0])),h=s.charAt(c),i.lastIndex=o.lastIndex=c;if(a=o.exec(s))if(a.index===c){c+=a[0].length,f.push(a[0]);continue}if(!l&&h==="/"){p=s.charAt(c+1);if(p==="/"||p==="*")if(a=i.exec(s))if(a.index===c){c+=a[0].length,f.push(a[0]);continue}}switch(h){case"{":if(!l){u++,f.push(h);break};case"}":if(!l){u--,f.push(h),e[++n]=f=[];break};case"(":if(!l){l=!0,f.push(h);break};case")":if(l){l=!1,f.push(h);break};default:f.push(h)}c++}return u!=0&&(S=new L({index:c-1,type:"Parse",message:u>0?"missing closing `}`":"missing opening `{`",filename:t.currentFileInfo.filename},t)),e.map(function(e){return e.join("")})}([[]]);if(S)return a(new L(S,t));try{f=new i.Ruleset([],w(this.parsers.primary)),f.root=!0,f.firstRoot=!0}catch(x){return a(new L(x,t))}f.toCSS=function(e){var s,o,u;return function(s,o){s=s||{};var u,a=new i.evalEnv(s);typeof o=="object"&&!Array.isArray(o)&&(o=Object.keys(o).map(function(e){var t=o[e];return t instanceof i.Value||(t instanceof i.Expression||(t=new i.Expression([t])),t=new i.Value([t])),new i.Rule("@"+e,t,!1,0)}),a.frames=[new i.Ruleset(null,o)]);try{var f=e.call(this,a);(new i.joinSelectorVisitor).run(f),(new i.processExtendsVisitor).run(f);var l=f.toCSS({compress:Boolean(s.compress),dumpLineNumbers:t.dumpLineNumbers,strictUnits:Boolean(s.strictUnits)})}catch(c){throw new L(c,t)}return s.yuicompress&&r.mode==="node"?n("ycssmin").cssmin(l,s.maxLineLen):s.compress?l.replace(/(\s)+/g,"$1"):l}}(f.eval);if(o<s.length-1){o=l,y=s.split("\n"),g=(s.slice(0,o).match(/\n/g)||"").length+1;for(var T=o,N=-1;T>=0&&s.charAt(T)!=="\n";T--)N++;S={type:"Parse",message:"Unrecognised input",index:o,filename:t.currentFileInfo.filename,line:g,column:N,extract:[y[g-2],y[g-1],y[g]]}}var C=function(e){e=S||e||p.imports.error,e?(e instanceof L||(e=new L(e,t)),a(e)):a(null,f)};t.processImports!==!1?(new i.importVisitor(this.imports,C)).run(f):C()},parsers:{primary:function(){var e,t=[];while((e=w(this.extendRule)||w(this.mixin.definition)||w(this.rule)||w(this.ruleset)||w(this.mixin.call)||w(this.comment)||w(this.directive))||w(/^[\s\n]+/)||w(/^;+/))e&&t.push(e);return t},comment:function(){var e;if(s.charAt(o)!=="/")return;if(s.charAt(o+1)==="/")return new i.Comment(w(/^\/\/.*/),!0);if(e=w(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new i.Comment(e)},entities:{quoted:function(){var e,n=o,r,u=o;s.charAt(n)==="~"&&(n++,r=!0);if(s.charAt(n)!=='"'&&s.charAt(n)!=="'")return;r&&w("~");if(e=w(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new i.Quoted(e[0],e[1]||e[2],r,u,t.currentFileInfo)},keyword:function(){var e;if(e=w(/^[_A-Za-z-][_A-Za-z0-9-]*/))return i.colors.hasOwnProperty(e)?new i.Color(i.colors[e].slice(1)):new i.Keyword(e)},call:function(){var e,n,r,s,a=o;if(!(e=/^([\w-]+|%|progid:[\w\.]+)\(/.exec(c[u])))return;e=e[1],n=e.toLowerCase();if(n==="url")return null;o+=e.length;if(n==="alpha"){s=w(this.alpha);if(typeof s!="undefined")return s}w("("),r=w(this.entities.arguments);if(!w(")"))return;if(e)return new i.Call(e,r,a,t.currentFileInfo)},arguments:function(){var e=[],t;while(t=w(this.entities.assignment)||w(this.expression)){e.push(t);if(!w(","))break}return e},literal:function(){return w(this.entities.dimension)||w(this.entities.color)||w(this.entities.quoted)||w(this.entities.unicodeDescriptor)},assignment:function(){var e,t;if((e=w(/^\w+(?=\s?=)/i))&&w("=")&&(t=w(this.entity)))return new i.Assignment(e,t)},url:function(){var e;if(s.charAt(o)!=="u"||!w(/^url\(/))return;return e=w(this.entities.quoted)||w(this.entities.variable)||w(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/)||"",S(")"),new i.URL(e.value!=null||e instanceof i.Variable?e:new i.Anonymous(e),t.currentFileInfo)},variable:function(){var e,n=o;if(s.charAt(o)==="@"&&(e=w(/^@@?[\w-]+/)))return new i.Variable(e,n,t.currentFileInfo)},variableCurly:function(){var e,n,r=o;if(s.charAt(o)==="@"&&(n=w(/^@\{([\w-]+)\}/)))return new i.Variable("@"+n[1],r,t.currentFileInfo)},color:function(){var e;if(s.charAt(o)==="#"&&(e=w(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/)))return new i.Color(e[1])},dimension:function(){var e,t=s.charCodeAt(o);if(t>57||t<43||t===47||t==44)return;if(e=w(/^([+-]?\d*\.?\d+)(%|[a-z]+)?/))return new i.Dimension(e[1],e[2])},unicodeDescriptor:function(){var e;if(e=w(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/))return new i.UnicodeDescriptor(e[0])},javascript:function(){var e,t=o,n;s.charAt(t)==="~"&&(t++,n=!0);if(s.charAt(t)!=="`")return;n&&w("~");if(e=w(/^`([^`]*)`/))return new i.JavaScript(e[1],o,n)}},variable:function(){var e;if(s.charAt(o)==="@"&&(e=w(/^(@[\w-]+)\s*:/)))return e[1]},extend:function(e){var t,n,r=o,s,u=[];if(!w(e?/^&:extend\(/:/^:extend\(/))return;do{s=null,t=[];for(;;){s=w(/^(all)(?=\s*(\)|,))/);if(s)break;n=w(this.element);if(!n)break;t.push(n)}s=s&&s[1],u.push(new i.Extend(new i.Selector(t),s,r))}while(w(","));return S(/^\)/),e&&S(/^;/),u},extendRule:function(){return this.extend(!0)},mixin:{call:function(){var e=[],n,r,u,a,f,l=o,c=s.charAt(o),h=!1;if(c!=="."&&c!=="#")return;m();while(n=w(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/))e.push(new i.Element(r,n,o)),r=w(">");w("(")&&(u=this.mixin.args.call(this,!0).args,S(")")),u=u||[],w(this.important)&&(h=!0);if(e.length>0&&(w(";")||T("}")))return new i.mixin.Call(e,u,l,t.currentFileInfo,h);g()},args:function(e){var t=[],n=[],r,u=[],a,f,l,c,h,p={args:null,variadic:!1};for(;;){if(e)h=w(this.expression);else{w(this.comment);if(s.charAt(o)==="."&&w(/^\.{3}/)){p.variadic=!0,w(";")&&!r&&(r=!0),(r?n:u).push({variadic:!0});break}h=w(this.entities.variable)||w(this.entities.literal)||w(this.entities.keyword)}if(!h)break;l=null,h.throwAwayComments&&h.throwAwayComments(),c=h;var d=null;if(e){if(h.value.length==1)var d=h.value[0]}else d=h;if(d&&d instanceof i.Variable)if(w(":"))t.length>0&&(r&&x("Cannot mix ; and , as delimiter types"),a=!0),c=S(this.expression),l=f=d.name;else{if(!e&&w(/^\.{3}/)){p.variadic=!0,w(";")&&!r&&(r=!0),(r?n:u).push({name:h.name,variadic:!0});break}e||(f=l=d.name,c=null)}c&&t.push(c),u.push({name:l,value:c});if(w(","))continue;if(w(";")||r)a&&x("Cannot mix ; and , as delimiter types"),r=!0,t.length>1&&(c=new i.Value(t)),n.push({name:f,value:c}),f=null,t=[],a=!1}return p.args=r?n:u,p},definition:function(){var e,t=[],n,r,u,a,f,c=!1;if(s.charAt(o)!=="."&&s.charAt(o)!=="#"||T(/^[^{]*\}/))return;m();if(n=w(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)){e=n[1];var h=this.mixin.args.call(this,!1);t=h.args,c=h.variadic,w(")")||(l=o,g()),w(this.comment),w(/^when/)&&(f=S(this.conditions,"expected condition")),r=w(this.block);if(r)return new i.mixin.Definition(e,t,r,f,c);g()}}},entity:function(){return w(this.entities.literal)||w(this.entities.variable)||w(this.entities.url)||w(this.entities.call)||w(this.entities.keyword)||w(this.entities.javascript)||w(this.comment)},end:function(){return w(";")||T("}")},alpha:function(){var e;if(!w(/^\(opacity=/i))return;if(e=w(/^\d+/)||w(this.entities.variable))return S(")"),new i.Alpha(e)},element:function(){var e,t,n,r;n=w(this.combinator),e=w(/^(?:\d+\.\d+|\d+)%/)||w(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)||w("*")||w("&")||w(this.attribute)||w(/^\([^()@]+\)/)||w(/^[\.#](?=@)/)||w(this.entities.variableCurly),e||w("(")&&(r=w(this.selector))&&w(")")&&(e=new i.Paren(r));if(e)return new i.Element(n,e,o)},combinator:function(){var e=s.charAt(o);if(e===">"||e==="+"||e==="~"||e==="|"){o++;while(s.charAt(o).match(/\s/))o++;return new i.Combinator(e)}return s.charAt(o-1).match(/\s/)?new i.Combinator(" "):new i.Combinator(null)},selector:function(){var e,t,n=[],r,u,a=[];while((u=w(this.extend))||(t=w(this.element))){u?a.push.apply(a,u):(a.length&&x("Extend can only be used at the end of selector"),r=s.charAt(o),n.push(t),t=null);if(r==="{"||r==="}"||r===";"||r===","||r===")")break}if(n.length>0)return new i.Selector(n,a);a.length&&x("Extend must be used to extend a selector, it cannot be used on its own")},attribute:function(){var e="",t,n,r;if(!w("["))return;(t=w(this.entities.variableCurly))||(t=S(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/));if(r=w(/^[|~*$^]?=/))n=w(this.entities.quoted)||w(/^[\w-]+/)||w(this.entities.variableCurly);return S("]"),new i.Attribute(t,r,n)},block:function(){var e;if(w("{")&&(e=w(this.primary))&&w("}"))return e},ruleset:function(){var e=[],n,r,u;m(),t.dumpLineNumbers&&(u=k(o,s,t));while(n=w(this.selector)){e.push(n),w(this.comment);if(!w(","))break;w(this.comment)}if(e.length>0&&(r=w(this.block))){var a=new i.Ruleset(e,r,t.strictImports);return t.dumpLineNumbers&&(a.debugInfo=u),a}l=o,g()},rule:function(e){var n,r,u=s.charAt(o),a;m();if(u==="."||u==="#"||u==="&")return;if(n=w(this.variable)||w(this.property)){r=!e&&(t.compress||n.charAt(0)==="@")?w(this.value)||w(this.anonymousValue):w(this.anonymousValue)||w(this.value),a=w(this.important);if(r&&w(this.end))return new i.Rule(n,r,a,f,t.currentFileInfo);l=o,g();if(r&&!e)return this.rule(!0)}},anonymousValue:function(){var e;if(e=/^([^@+\/'"*`(;{}-]*);/.exec(c[u]))return o+=e[0].length-1,new i.Anonymous(e[1])},"import":function(){var e,n,r=o;m();var s=w(/^@import?\s+/),u=(s?w(this.importOptions):null)||{};if(s&&(e=w(this.entities.quoted)||w(this.entities.url))){n=w(this.mediaFeatures);if(w(";"))return n=n&&new i.Value(n),new i.Import(e,n,u,r,t.currentFileInfo)}g()},importOptions:function(){var e,t={},n,r;if(!w("("))return null;do if(e=w(this.importOption)){n=e,r=!0;switch(n){case"css":n="less",r=!1;break;case"once":n="multiple",r=!1}t[n]=r;if(!w(","))break}while(e);return S(")"),t},importOption:function(){var e=w(/^(less|css|multiple|once)/);if(e)return e[1]},mediaFeature:function(){var e,n,r=[];do if(e=w(this.entities.keyword))r.push(e);else if(w("(")){n=w(this.property),e=w(this.value);if(!w(")"))return null;if(n&&e)r.push(new i.Paren(new i.Rule(n,e,null,o,t.currentFileInfo,!0)));else{if(!e)return null;r.push(new i.Paren(e))}}while(e);if(r.length>0)return new i.Expression(r)},mediaFeatures:function(){var e,t=[];do if(e=w(this.mediaFeature)){t.push(e);if(!w(","))break}else if(e=w(this.entities.variable)){t.push(e);if(!w(","))break}while(e);return t.length>0?t:null},media:function(){var e,n,r,u;t.dumpLineNumbers&&(u=k(o,s,t));if(w(/^@media/)){e=w(this.mediaFeatures);if(n=w(this.block))return r=new i.Media(n,e),t.dumpLineNumbers&&(r.debugInfo=u),r}},directive:function(){var e,n,r,u,a,f,l,c,h,p;if(s.charAt(o)!=="@")return;if(n=w(this["import"])||w(this.media))return n;m(),e=w(/^@[a-z-]+/);if(!e)return;l=e,e.charAt(1)=="-"&&e.indexOf("-",2)>0&&(l="@"+e.slice(e.indexOf("-",2)+1));switch(l){case"@font-face":c=!0;break;case"@viewport":case"@top-left":case"@top-left-corner":case"@top-center":case"@top-right":case"@top-right-corner":case"@bottom-left":case"@bottom-left-corner":case"@bottom-center":case"@bottom-right":case"@bottom-right-corner":case"@left-top":case"@left-middle":case"@left-bottom":case"@right-top":case"@right-middle":case"@right-bottom":c=!0;break;case"@page":case"@document":case"@supports":case"@keyframes":c=!0,h=!0;break;case"@namespace":p=!0}h&&(e+=" "+(w(/^[^{]+/)||"").trim());if(c){if(r=w(this.block))return new i.Directive(e,r)}else if((n=p?w(this.expression):w(this.entity))&&w(";")){var d=new i.Directive(e,n);return t.dumpLineNumbers&&(d.debugInfo=k(o,s,t)),d}g()},value:function(){var e,t=[],n;while(e=w(this.expression)){t.push(e);if(!w(","))break}if(t.length>0)return new i.Value(t)},important:function(){if(s.charAt(o)==="!")return w(/^! *important/)},sub:function(){var e,t;if(w("("))if(e=w(this.addition))return t=new i.Expression([e]),S(")"),t.parens=!0,t},multiplication:function(){var e,t,n,r,u,a=[];if(e=w(this.operand)){u=b(s.charAt(o-1));while(!T(/^\/[*\/]/)&&(n=w("/")||w("*"))){if(!(t=w(this.operand)))break;e.parensInOp=!0,t.parensInOp=!0,r=new i.Operation(n,[r||e,t],u),u=b(s.charAt(o-1))}return r||e}},addition:function(){var e,t,n,r,u;if(e=w(this.multiplication)){u=b(s.charAt(o-1));while((n=w(/^[-+]\s+/)||!u&&(w("+")||w("-")))&&(t=w(this.multiplication)))e.parensInOp=!0,t.parensInOp=!0,r=new i.Operation(n,[r||e,t],u),u=b(s.charAt(o-1));return r||e}},conditions:function(){var e,t,n=o,r;if(e=w(this.condition)){while(w(",")&&(t=w(this.condition)))r=new i.Condition("or",r||e,t,n);return r||e}},condition:function(){var e,t,n,r,s=o,u=!1;w(/^not/)&&(u=!0),S("(");if(e=w(this.addition)||w(this.entities.keyword)||w(this.entities.quoted))return(r=w(/^(?:>=|=<|[<=>])/))?(t=w(this.addition)||w(this.entities.keyword)||w(this.entities.quoted))?n=new i.Condition(r,e,t,s,u):x("expected expression"):n=new i.Condition("=",e,new i.Keyword("true"),s,u),S(")"),w(/^and/)?new i.Condition("and",n,w(this.condition)):n},operand:function(){var e,t=s.charAt(o+1);s.charAt(o)==="-"&&(t==="@"||t==="(")&&(e=w("-"));var n=w(this.sub)||w(this.entities.dimension)||w(this.entities.color)||w(this.entities.variable)||w(this.entities.call);return e&&(n.parensInOp=!0,n=new i.Negative(n)),n},expression:function(){var e,t,n=[],r;while(e=w(this.addition)||w(this.entity))n.push(e),!T(/^\/[\/*]/)&&(t=w("/"))&&n.push(new i.Anonymous(t));if(n.length>0)return new i.Expression(n)},property:function(){var e;if(e=w(/^(\*?-?[_a-z0-9-]+)\s*:/))return e[1]}}}};if(r.mode==="browser"||r.mode==="rhino")r.Parser.importer=function(e,t,n,r){!/^([a-z-]+:)?\//.test(e)&&t.currentDirectory&&(e=t.currentDirectory+e);var i=r.toSheet(e);i.processImports=!1,i.currentFileInfo=t,w(i,function(e,t,r,i,s,o){n.call(null,e,t,o)},!0)};(function(r){function u(e){return r.functions.hsla(e.h,e.s,e.l,e.a)}function a(e,t){return e instanceof r.Dimension&&e.unit.is("%")?parseFloat(e.value*t/100):f(e)}function f(e){if(e instanceof r.Dimension)return parseFloat(e.unit.is("%")?e.value/100:e.value);if(typeof e=="number")return e;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function l(e){return Math.min(1,Math.max(0,e))}r.functions={rgb:function(e,t,n){return this.rgba(e,t,n,1)},rgba:function(e,t,n,i){var s=[e,t,n].map(function(e){return a(e,256)});return i=f(i),new r.Color(s,i)},hsl:function(e,t,n){return this.hsla(e,t,n,1)},hsla:function(e,t,n,r){function o(e){return e=e<0?e+1:e>1?e-1:e,e*6<1?s+(i-s)*e*6:e*2<1?i:e*3<2?s+(i-s)*(2/3-e)*6:s}e=f(e)%360/360,t=l(f(t)),n=l(f(n)),r=l(f(r));var i=n<=.5?n*(t+1):n+t-n*t,s=n*2-i;return this.rgba(o(e+1/3)*255,o(e)*255,o(e-1/3)*255,r)},hsv:function(e,t,n){return this.hsva(e,t,n,1)},hsva:function(e,t,n,r){e=f(e)%360/360*360,t=f(t),n=f(n),r=f(r);var i,s;i=Math.floor(e/60%6),s=e/60-i;var o=[n,n*(1-t),n*(1-s*t),n*(1-(1-s)*t)],u=[[0,3,1],[2,0,1],[1,0,3],[1,2,0],[3,1,0],[0,1,2]];return this.rgba(o[u[i][0]]*255,o[u[i][1]]*255,o[u[i][2]]*255,r)},hue:function(e){return new r.Dimension(Math.round(e.toHSL().h))},saturation:function(e){return new r.Dimension(Math.round(e.toHSL().s*100),"%")},lightness:function(e){return new r.Dimension(Math.round(e.toHSL().l*100),"%")},hsvhue:function(e){return new r.Dimension(Math.round(e.toHSV().h))},hsvsaturation:function(e){return new r.Dimension(Math.round(e.toHSV().s*100),"%")},hsvvalue:function(e){return new r.Dimension(Math.round(e.toHSV().v*100),"%")},red:function(e){return new r.Dimension(e.rgb[0])},green:function(e){return new r.Dimension(e.rgb[1])},blue:function(e){return new r.Dimension(e.rgb[2])},alpha:function(e){return new r.Dimension(e.toHSL().a)},luma:function(e){return new r.Dimension(Math.round(e.luma()*e.alpha*100),"%")},saturate:function(e,t){var n=e.toHSL();return n.s+=t.value/100,n.s=l(n.s),u(n)},desaturate:function(e,t){var n=e.toHSL();return n.s-=t.value/100,n.s=l(n.s),u(n)},lighten:function(e,t){var n=e.toHSL();return n.l+=t.value/100,n.l=l(n.l),u(n)},darken:function(e,t){var n=e.toHSL();return n.l-=t.value/100,n.l=l(n.l),u(n)},fadein:function(e,t){var n=e.toHSL();return n.a+=t.value/100,n.a=l(n.a),u(n)},fadeout:function(e,t){var n=e.toHSL();return n.a-=t.value/100,n.a=l(n.a),u(n)},fade:function(e,t){var n=e.toHSL();return n.a=t.value/100,n.a=l(n.a),u(n)},spin:function(e,t){var n=e.toHSL(),r=(n.h+t.value)%360;return n.h=r<0?360+r:r,u(n)},mix:function(e,t,n){n||(n=new r.Dimension(50));var i=n.value/100,s=i*2-1,o=e.toHSL().a-t.toHSL().a,u=((s*o==-1?s:(s+o)/(1+s*o))+1)/2,a=1-u,f=[e.rgb[0]*u+t.rgb[0]*a,e.rgb[1]*u+t.rgb[1]*a,e.rgb[2]*u+t.rgb[2]*a],l=e.alpha*i+t.alpha*(1-i);return new r.Color(f,l)},greyscale:function(e){return this.desaturate(e,new r.Dimension(100))},contrast:function(e,t,n,r){if(!e.rgb)return null;typeof n=="undefined"&&(n=this.rgba(255,255,255,1)),typeof t=="undefined"&&(t=this.rgba(0,0,0,1));if(t.luma()>n.luma()){var i=n;n=t,t=i}return typeof r=="undefined"?r=.43:r=f(r),e.luma()*e.alpha<r?n:t},e:function(e){return new r.Anonymous(e instanceof r.JavaScript?e.evaluated:e)},escape:function(e){return new r.Anonymous(encodeURI(e.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(e){var t=Array.prototype.slice.call(arguments,1),n=e.value;for(var i=0;i<t.length;i++)n=n.replace(/%[sda]/i,function(e){var n=e.match(/s/i)?t[i].value:t[i].toCSS();return e.match(/[A-Z]$/)?encodeURIComponent(n):n});return n=n.replace(/%%/g,"%"),new r.Quoted('"'+n+'"',n)},unit:function(e,t){return new r.Dimension(e.value,t?t.toCSS():"")},convert:function(e,t){return e.convertTo(t.value)},round:function(e,t){var n=typeof t=="undefined"?0:t.value;return this._math(function(e){return e.toFixed(n)},null,e)},pi:function(){return new r.Dimension(Math.PI)},mod:function(e,t){return new r.Dimension(e.value%t.value,e.unit)},pow:function(e,t){if(typeof e=="number"&&typeof t=="number")e=new r.Dimension(e),t=new r.Dimension(t);else if(!(e instanceof r.Dimension)||!(t instanceof r.Dimension))throw{type:"Argument",message:"arguments must be numbers"};return new r.Dimension(Math.pow(e.value,t.value),e.unit)},_math:function(e,t,n){if(n instanceof r.Dimension)return new r.Dimension(e(parseFloat(n.value)),t==null?n.unit:t);if(typeof n=="number")return e(n);throw{type:"Argument",message:"argument must be a number"}},argb:function(e){return new r.Anonymous(e.toARGB())},percentage:function(e){return new r.Dimension(e.value*100,"%")},color:function(e){if(e instanceof r.Quoted)return new r.Color(e.value.slice(1));throw{type:"Argument",message:"argument must be a string"}},iscolor:function(e){return this._isa(e,r.Color)},isnumber:function(e){return this._isa(e,r.Dimension)},isstring:function(e){return this._isa(e,r.Quoted)},iskeyword:function(e){return this._isa(e,r.Keyword)},isurl:function(e){return this._isa(e,r.URL)},ispixel:function(e){return this.isunit(e,"px")},ispercentage:function(e){return this.isunit(e,"%")},isem:function(e){return this.isunit(e,"em")},isunit:function(e,t){return e instanceof r.Dimension&&e.unit.is(t.value||t)?r.True:r.False},_isa:function(e,t){return e instanceof t?r.True:r.False},multiply:function(e,t){var n=e.rgb[0]*t.rgb[0]/255,r=e.rgb[1]*t.rgb[1]/255,i=e.rgb[2]*t.rgb[2]/255;return this.rgb(n,r,i)},screen:function(e,t){var n=255-(255-e.rgb[0])*(255-t.rgb[0])/255,r=255-(255-e.rgb[1])*(255-t.rgb[1])/255,i=255-(255-e.rgb[2])*(255-t.rgb[2])/255;return this.rgb(n,r,i)},overlay:function(e,t){var n=e.rgb[0]<128?2*e.rgb[0]*t.rgb[0]/255:255-2*(255-e.rgb[0])*(255-t.rgb[0])/255,r=e.rgb[1]<128?2*e.rgb[1]*t.rgb[1]/255:255-2*(255-e.rgb[1])*(255-t.rgb[1])/255,i=e.rgb[2]<128?2*e.rgb[2]*t.rgb[2]/255:255-2*(255-e.rgb[2])*(255-t.rgb[2])/255;return this.rgb(n,r,i)},softlight:function(e,t){var n=t.rgb[0]*e.rgb[0]/255,r=n+e.rgb[0]*(255-(255-e.rgb[0])*(255-t.rgb[0])/255-n)/255;n=t.rgb[1]*e.rgb[1]/255;var i=n+e.rgb[1]*(255-(255-e.rgb[1])*(255-t.rgb[1])/255-n)/255;n=t.rgb[2]*e.rgb[2]/255;var s=n+e.rgb[2]*(255-(255-e.rgb[2])*(255-t.rgb[2])/255-n)/255;return this.rgb(r,i,s)},hardlight:function(e,t){var n=t.rgb[0]<128?2*t.rgb[0]*e.rgb[0]/255:255-2*(255-t.rgb[0])*(255-e.rgb[0])/255,r=t.rgb[1]<128?2*t.rgb[1]*e.rgb[1]/255:255-2*(255-t.rgb[1])*(255-e.rgb[1])/255,i=t.rgb[2]<128?2*t.rgb[2]*e.rgb[2]/255:255-2*(255-t.rgb[2])*(255-e.rgb[2])/255;return this.rgb(n,r,i)},difference:function(e,t){var n=Math.abs(e.rgb[0]-t.rgb[0]),r=Math.abs(e.rgb[1]-t.rgb[1]),i=Math.abs(e.rgb[2]-t.rgb[2]);return this.rgb(n,r,i)},exclusion:function(e,t){var n=e.rgb[0]+t.rgb[0]*(255-e.rgb[0]-e.rgb[0])/255,r=e.rgb[1]+t.rgb[1]*(255-e.rgb[1]-e.rgb[1])/255,i=e.rgb[2]+t.rgb[2]*(255-e.rgb[2]-e.rgb[2])/255;return this.rgb(n,r,i)},average:function(e,t){var n=(e.rgb[0]+t.rgb[0])/2,r=(e.rgb[1]+t.rgb[1])/2,i=(e.rgb[2]+t.rgb[2])/2;return this.rgb(n,r,i)},negation:function(e,t){var n=255-Math.abs(255-t.rgb[0]-e.rgb[0]),r=255-Math.abs(255-t.rgb[1]-e.rgb[1]),i=255-Math.abs(255-t.rgb[2]-e.rgb[2]);return this.rgb(n,r,i)},tint:function(e,t){return this.mix(this.rgb(255,255,255),e,t)},shade:function(e,t){return this.mix(this.rgb(0,0,0),e,t)},extract:function(e,t){return t=t.value-1,e.value[t]},"data-uri":function(t,i){if(typeof e!="undefined")return(new r.URL(i||t,this.currentFileInfo)).eval(this.env);var s=t.value,o=i&&i.value,u=n("fs"),a=n("path"),f=!1;arguments.length<2&&(o=s),this.env.isPathRelative(o)&&(this.currentFileInfo.relativeUrls?o=a.join(this.currentFileInfo.currentDirectory,o):o=a.join(this.currentFileInfo.entryPath,o));if(arguments.length<2){var l;try{l=n("mime")}catch(c){l=r._mime}s=l.lookup(o);var h=l.charsets.lookup(s);f=["US-ASCII","UTF-8"].indexOf(h)<0,f&&(s+=";base64")}else f=/;base64$/.test(s);var p=u.readFileSync(o),d=32,v=parseInt(p.length/1024,10);if(v>=d){if(this.env.ieCompat!==!1)return this.env.silent||console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!",o,v,d),(new r.URL(i||t,this.currentFileInfo)).eval(this.env);this.env.silent||console.warn("WARNING: Embedding %s (%dKB) exceeds IE8's data-uri size limit of %dKB!",o,v,d)}p=f?p.toString("base64"):encodeURIComponent(p);var m="'data:"+s+","+p+"'";return new r.URL(new r.Anonymous(m))}},r._mime={_types:{".htm":"text/html",".html":"text/html",".gif":"image/gif",".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png"},lookup:function(e){var i=n("path").extname(e),s=r._mime._types[i];if(s===t)throw new Error('Optional dependency "mime" is required for '+i);return s},charsets:{lookup:function(e){return e&&/^text\//.test(e)?"UTF-8":""}}};var i=[{name:"ceil"},{name:"floor"},{name:"sqrt"},{name:"abs"},{name:"tan",unit:""},{name:"sin",unit:""},{name:"cos",unit:""},{name:"atan",unit:"rad"},{name:"asin",unit:"rad"},{name:"acos",unit:"rad"}],s=function(e,t){return function(n){return t!=null&&(n=n.unify()),this._math(Math[e],t,n)}};for(var o=0;o<i.length;o++)r.functions[i[o].name]=s(i[o].name,i[o].unit);r.functionCall=function(e,t){this.env=e,this.currentFileInfo=t},r.functionCall.prototype=r.functions})(n("./tree")),function(e){e.colors={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgrey:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta
  330.13 +:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",grey:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"}}(n("./tree")),function(e){e.Alpha=function(e){this.value=e},e.Alpha.prototype={type:"Alpha",accept:function(e){this.value=e.visit(this.value)},eval:function(e){return this.value.eval&&(this.value=this.value.eval(e)),this},toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"}}}(n("../tree")),function(e){e.Anonymous=function(e){this.value=e.value||e},e.Anonymous.prototype={type:"Anonymous",toCSS:function(){return this.value},eval:function(){return this},compare:function(e){if(!e.toCSS)return-1;var t=this.toCSS(),n=e.toCSS();return t===n?0:t<n?-1:1}}}(n("../tree")),function(e){e.Assignment=function(e,t){this.key=e,this.value=t},e.Assignment.prototype={type:"Assignment",accept:function(e){this.value=e.visit(this.value)},toCSS:function(){return this.key+"="+(this.value.toCSS?this.value.toCSS():this.value)},eval:function(t){return this.value.eval?new e.Assignment(this.key,this.value.eval(t)):this}}}(n("../tree")),function(e){e.Call=function(e,t,n,r){this.name=e,this.args=t,this.index=n,this.currentFileInfo=r},e.Call.prototype={type:"Call",accept:function(e){this.args=e.visit(this.args)},eval:function(t){var n=this.args.map(function(e){return e.eval(t)}),r=this.name.toLowerCase(),i,s;if(r in e.functions)try{s=new e.functionCall(t,this.currentFileInfo),i=s[r].apply(s,n);if(i!=null)return i}catch(o){throw{type:o.type||"Runtime",message:"error evaluating function `"+this.name+"`"+(o.message?": "+o.message:""),index:this.index,filename:this.currentFileInfo.filename}}return new e.Anonymous(this.name+"("+n.map(function(e){return e.toCSS(t)}).join(", ")+")")},toCSS:function(e){return this.eval(e).toCSS()}}}(n("../tree")),function(e){e.Color=function(e,t){Array.isArray(e)?this.rgb=e:e.length==6?this.rgb=e.match(/.{2}/g).map(function(e){return parseInt(e,16)}):this.rgb=e.split("").map(function(e){return parseInt(e+e,16)}),this.alpha=typeof t=="number"?t:1},e.Color.prototype={type:"Color",eval:function(){return this},luma:function(){return.2126*this.rgb[0]/255+.7152*this.rgb[1]/255+.0722*this.rgb[2]/255},toCSS:function(e,t){var n=e&&e.compress&&!t;if(this.alpha<1)return"rgba("+this.rgb.map(function(e){return Math.round(e)}).concat(this.alpha).join(","+(n?"":" "))+")";var r=this.rgb.map(function(e){return e=Math.round(e),e=(e>255?255:e<0?0:e).toString(16),e.length===1?"0"+e:e}).join("");return n&&(r=r.split(""),r[0]==r[1]&&r[2]==r[3]&&r[4]==r[5]?r=r[0]+r[2]+r[4]:r=r.join("")),"#"+r},operate:function(t,n,r){var i=[];r instanceof e.Color||(r=r.toColor());for(var s=0;s<3;s++)i[s]=e.operate(t,n,this.rgb[s],r.rgb[s]);return new e.Color(i,this.alpha+r.alpha)},toHSL:function(){var e=this.rgb[0]/255,t=this.rgb[1]/255,n=this.rgb[2]/255,r=this.alpha,i=Math.max(e,t,n),s=Math.min(e,t,n),o,u,a=(i+s)/2,f=i-s;if(i===s)o=u=0;else{u=a>.5?f/(2-i-s):f/(i+s);switch(i){case e:o=(t-n)/f+(t<n?6:0);break;case t:o=(n-e)/f+2;break;case n:o=(e-t)/f+4}o/=6}return{h:o*360,s:u,l:a,a:r}},toHSV:function(){var e=this.rgb[0]/255,t=this.rgb[1]/255,n=this.rgb[2]/255,r=this.alpha,i=Math.max(e,t,n),s=Math.min(e,t,n),o,u,a=i,f=i-s;i===0?u=0:u=f/i;if(i===s)o=0;else{switch(i){case e:o=(t-n)/f+(t<n?6:0);break;case t:o=(n-e)/f+2;break;case n:o=(e-t)/f+4}o/=6}return{h:o*360,s:u,v:a,a:r}},toARGB:function(){var e=[Math.round(this.alpha*255)].concat(this.rgb);return"#"+e.map(function(e){return e=Math.round(e),e=(e>255?255:e<0?0:e).toString(16),e.length===1?"0"+e:e}).join("")},compare:function(e){return e.rgb?e.rgb[0]===this.rgb[0]&&e.rgb[1]===this.rgb[1]&&e.rgb[2]===this.rgb[2]&&e.alpha===this.alpha?0:-1:-1}}}(n("../tree")),function(e){e.Comment=function(e,t){this.value=e,this.silent=!!t},e.Comment.prototype={type:"Comment",toCSS:function(e){return e.compress?"":this.value},eval:function(){return this}}}(n("../tree")),function(e){e.Condition=function(e,t,n,r,i){this.op=e.trim(),this.lvalue=t,this.rvalue=n,this.index=r,this.negate=i},e.Condition.prototype={type:"Condition",accept:function(e){this.lvalue=e.visit(this.lvalue),this.rvalue=e.visit(this.rvalue)},eval:function(e){var t=this.lvalue.eval(e),n=this.rvalue.eval(e),r=this.index,i,i=function(e){switch(e){case"and":return t&&n;case"or":return t||n;default:if(t.compare)i=t.compare(n);else{if(!n.compare)throw{type:"Type",message:"Unable to perform comparison",index:r};i=n.compare(t)}switch(i){case-1:return e==="<"||e==="=<";case 0:return e==="="||e===">="||e==="=<";case 1:return e===">"||e===">="}}}(this.op);return this.negate?!i:i}}}(n("../tree")),function(e){e.Dimension=function(n,r){this.value=parseFloat(n),this.unit=r&&r instanceof e.Unit?r:new e.Unit(r?[r]:t)},e.Dimension.prototype={type:"Dimension",accept:function(e){this.unit=e.visit(this.unit)},eval:function(e){return this},toColor:function(){return new e.Color([this.value,this.value,this.value])},toCSS:function(e){if(e&&e.strictUnits&&!this.unit.isSingular())throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: "+this.unit.toString());var t=this.value,n=String(t);t!==0&&t<1e-6&&t>-0.000001&&(n=t.toFixed(20).replace(/0+$/,""));if(e&&e.compress){if(t===0&&!this.unit.isAngle())return n;t>0&&t<1&&(n=n.substr(1))}return n+this.unit.toCSS(e)},operate:function(t,n,r){var i=e.operate(t,n,this.value,r.value),s=this.unit.clone();if(n==="+"||n==="-"){if(s.numerator.length===0&&s.denominator.length===0)s.numerator=r.unit.numerator.slice(0),s.denominator=r.unit.denominator.slice(0);else if(r.unit.numerator.length!=0||s.denominator.length!=0){r=r.convertTo(this.unit.usedUnits());if(t.strictUnits&&r.unit.toString()!==s.toString())throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '"+s.toString()+"' and '"+r.unit.toString()+"'.");i=e.operate(t,n,this.value,r.value)}}else n==="*"?(s.numerator=s.numerator.concat(r.unit.numerator).sort(),s.denominator=s.denominator.concat(r.unit.denominator).sort(),s.cancel()):n==="/"&&(s.numerator=s.numerator.concat(r.unit.denominator).sort(),s.denominator=s.denominator.concat(r.unit.numerator).sort(),s.cancel());return new e.Dimension(i,s)},compare:function(t){if(t instanceof e.Dimension){var n=this.unify(),r=t.unify(),i=n.value,s=r.value;return s>i?-1:s<i?1:!r.unit.isEmpty()&&n.unit.compare(r.unit)!==0?-1:0}return-1},unify:function(){return this.convertTo({length:"m",duration:"s",angle:"rad"})},convertTo:function(t){var n=this.value,r=this.unit.clone(),i,s,o,u,a,f={};if(typeof t=="string"){for(i in e.UnitConversions)e.UnitConversions[i].hasOwnProperty(t)&&(f={},f[i]=t);t=f}for(s in t)t.hasOwnProperty(s)&&(a=t[s],o=e.UnitConversions[s],r.map(function(e,t){return o.hasOwnProperty(e)?(t?n/=o[e]/o[a]:n*=o[e]/o[a],a):e}));return r.cancel(),new e.Dimension(n,r)}},e.UnitConversions={length:{m:1,cm:.01,mm:.001,"in":.0254,pt:.0254/72,pc:.0254/72*12},duration:{s:1,ms:.001},angle:{rad:1/(2*Math.PI),deg:1/360,grad:.0025,turn:1}},e.Unit=function(e,t,n){this.numerator=e?e.slice(0).sort():[],this.denominator=t?t.slice(0).sort():[],this.backupUnit=n},e.Unit.prototype={type:"Unit",clone:function(){return new e.Unit(this.numerator.slice(0),this.denominator.slice(0),this.backupUnit)},toCSS:function(e){return this.numerator.length>=1?this.numerator[0]:this.denominator.length>=1?this.denominator[0]:(!e||!e.strictUnits)&&this.backupUnit?this.backupUnit:""},toString:function(){var e,t=this.numerator.join("*");for(e=0;e<this.denominator.length;e++)t+="/"+this.denominator[e];return t},compare:function(e){return this.is(e.toString())?0:-1},is:function(e){return this.toString()===e},isAngle:function(){return e.UnitConversions.angle.hasOwnProperty(this.toCSS())},isEmpty:function(){return this.numerator.length==0&&this.denominator.length==0},isSingular:function(){return this.numerator.length<=1&&this.denominator.length==0},map:function(e){var t;for(t=0;t<this.numerator.length;t++)this.numerator[t]=e(this.numerator[t],!1);for(t=0;t<this.denominator.length;t++)this.denominator[t]=e(this.denominator[t],!0)},usedUnits:function(){var t,n,r={};for(n in e.UnitConversions)e.UnitConversions.hasOwnProperty(n)&&(t=e.UnitConversions[n],this.map(function(e){return t.hasOwnProperty(e)&&!r[n]&&(r[n]=e),e}));return r},cancel:function(){var e={},t,n,r;for(n=0;n<this.numerator.length;n++)t=this.numerator[n],r||(r=t),e[t]=(e[t]||0)+1;for(n=0;n<this.denominator.length;n++)t=this.denominator[n],r||(r=t),e[t]=(e[t]||0)-1;this.numerator=[],this.denominator=[];for(t in e)if(e.hasOwnProperty(t)){var i=e[t];if(i>0)for(n=0;n<i;n++)this.numerator.push(t);else if(i<0)for(n=0;n<-i;n++)this.denominator.push(t)}this.numerator.length===0&&this.denominator.length===0&&r&&(this.backupUnit=r),this.numerator.sort(),this.denominator.sort()}}}(n("../tree")),function(e){e.Directive=function(t,n){this.name=t,Array.isArray(n)?(this.ruleset=new e.Ruleset([],n),this.ruleset.allowImports=!0):this.value=n},e.Directive.prototype={type:"Directive",accept:function(e){this.ruleset=e.visit(this.ruleset),this.value=e.visit(this.value)},toCSS:function(e){return this.ruleset?(this.ruleset.root=!0,this.name+(e.compress?"{":" {\n  ")+this.ruleset.toCSS(e).trim().replace(/\n/g,"\n  ")+(e.compress?"}":"\n}\n")):this.name+" "+this.value.toCSS()+";\n"},eval:function(t){var n=this;return this.ruleset&&(t.frames.unshift(this),n=new e.Directive(this.name),n.ruleset=this.ruleset.eval(t),t.frames.shift()),n},variable:function(t){return e.Ruleset.prototype.variable.call(this.ruleset,t)},find:function(){return e.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return e.Ruleset.prototype.rulesets.apply(this.ruleset)}}}(n("../tree")),function(e){e.Element=function(t,n,r){this.combinator=t instanceof e.Combinator?t:new e.Combinator(t),typeof n=="string"?this.value=n.trim():n?this.value=n:this.value="",this.index=r},e.Element.prototype={type:"Element",accept:function(e){this.combinator=e.visit(this.combinator),this.value=e.visit(this.value)},eval:function(t){return new e.Element(this.combinator,this.value.eval?this.value.eval(t):this.value,this.index)},toCSS:function(e){var t=this.value.toCSS?this.value.toCSS(e):this.value;return t==""&&this.combinator.value.charAt(0)=="&"?"":this.combinator.toCSS(e||{})+t}},e.Attribute=function(e,t,n){this.key=e,this.op=t,this.value=n},e.Attribute.prototype={type:"Attribute",accept:function(e){this.value=e.visit(this.value)},eval:function(t){return new e.Attribute(this.key.eval?this.key.eval(t):this.key,this.op,this.value&&this.value.eval?this.value.eval(t):this.value)},toCSS:function(e){var t=this.key.toCSS?this.key.toCSS(e):this.key;return this.op&&(t+=this.op,t+=this.value.toCSS?this.value.toCSS(e):this.value),"["+t+"]"}},e.Combinator=function(e){e===" "?this.value=" ":this.value=e?e.trim():""},e.Combinator.prototype={type:"Combinator",toCSS:function(e){return{"":""," ":" ",":":" :","+":e.compress?"+":" + ","~":e.compress?"~":" ~ ",">":e.compress?">":" > ","|":e.compress?"|":" | "}[this.value]}}}(n("../tree")),function(e){e.Expression=function(e){this.value=e},e.Expression.prototype={type:"Expression",accept:function(e){this.value=e.visit(this.value)},eval:function(t){var n,r=this.parens&&!this.parensInOp,i=!1;return r&&t.inParenthesis(),this.value.length>1?n=new e.Expression(this.value.map(function(e){return e.eval(t)})):this.value.length===1?(this.value[0].parens&&!this.value[0].parensInOp&&(i=!0),n=this.value[0].eval(t)):n=this,r&&t.outOfParenthesis(),this.parens&&this.parensInOp&&!t.isMathOn()&&!i&&(n=new e.Paren(n)),n},toCSS:function(e){return this.value.map(function(t){return t.toCSS?t.toCSS(e):""}).join(" ")},throwAwayComments:function(){this.value=this.value.filter(function(t){return!(t instanceof e.Comment)})}}}(n("../tree")),function(e){e.Extend=function(t,n,r){this.selector=t,this.option=n,this.index=r;switch(n){case"all":this.allowBefore=!0,this.allowAfter=!0;break;default:this.allowBefore=!1,this.allowAfter=!1}},e.Extend.prototype={type:"Extend",accept:function(e){this.selector=e.visit(this.selector)},eval:function(t){return new e.Extend(this.selector.eval(t),this.option,this.index)},clone:function(t){return new e.Extend(this.selector,this.option,this.index)},findSelfSelectors:function(e){var t=[],n;for(n=0;n<e.length;n++)t=t.concat(e[n].elements);this.selfSelectors=[{elements:t}]}}}(n("../tree")),function(e){e.Import=function(e,n,r,i,s){var o=this;this.options=r,this.index=i,this.path=e,this.features=n,this.currentFileInfo=s;if(this.options.less!==t)this.css=!this.options.less;else{var u=this.getPath();u&&/css([\?;].*)?$/.test(u)&&(this.css=!0)}},e.Import.prototype={type:"Import",accept:function(e){this.features=e.visit(this.features),this.path=e.visit(this.path),this.root=e.visit(this.root)},toCSS:function(e){var t=this.features?" "+this.features.toCSS(e):"";return this.css?"@import "+this.path.toCSS()+t+";\n":""},getPath:function(){if(this.path instanceof e.Quoted){var n=this.path.value;return this.css!==t||/(\.[a-z]*$)|([\?;].*)$/.test(n)?n:n+".less"}return this.path instanceof e.URL?this.path.value.value:null},evalForImport:function(t){return new e.Import(this.path.eval(t),this.features,this.options,this.index,this.currentFileInfo)},evalPath:function(t){var n=this.path.eval(t),r=this.currentFileInfo&&this.currentFileInfo.rootpath;if(r&&!(n instanceof e.URL)){var i=n.value;i&&t.isPathRelative(i)&&(n.value=r+i)}return n},eval:function(t){var n,r=this.features&&this.features.eval(t);if(this.skip)return[];if(this.css){var i=new e.Import(this.evalPath(t),r,this.options,this.index);if(!i.css&&this.error)throw this.error;return i}return n=new e.Ruleset([],this.root.rules.slice(0)),n.evalImports(t),this.features?new e.Media(n.rules,this.features.value):n.rules}}}(n("../tree")),function(e){e.JavaScript=function(e,t,n){this.escaped=n,this.expression=e,this.index=t},e.JavaScript.prototype={type:"JavaScript",eval:function(t){var n,r=this,i={},s=this.expression.replace(/@\{([\w-]+)\}/g,function(n,i){return e.jsify((new e.Variable("@"+i,r.index)).eval(t))});try{s=new Function("return ("+s+")")}catch(o){throw{message:"JavaScript evaluation error: `"+s+"`",index:this.index}}for(var u in t.frames[0].variables())i[u.slice(1)]={value:t.frames[0].variables()[u].value,toJS:function(){return this.value.eval(t).toCSS()}};try{n=s.call(i)}catch(o){throw{message:"JavaScript evaluation error: '"+o.name+": "+o.message+"'",index:this.index}}return typeof n=="string"?new e.Quoted('"'+n+'"',n,this.escaped,this.index):Array.isArray(n)?new e.Anonymous(n.join(", ")):new e.Anonymous(n)}}}(n("../tree")),function(e){e.Keyword=function(e){this.value=e},e.Keyword.prototype={type:"Keyword",eval:function(){return this},toCSS:function(){return this.value},compare:function(t){return t instanceof e.Keyword?t.value===this.value?0:1:-1}},e.True=new e.Keyword("true"),e.False=new e.Keyword("false")}(n("../tree")),function(e){e.Media=function(t,n){var r=this.emptySelectors();this.features=new e.Value(n),this.ruleset=new e.Ruleset(r,t),this.ruleset.allowImports=!0},e.Media.prototype={type:"Media",accept:function(e){this.features=e.visit(this.features),this.ruleset=e.visit(this.ruleset)},toCSS:function(e){var t=this.features.toCSS(e);return"@media "+t+(e.compress?"{":" {\n  ")+this.ruleset.toCSS(e).trim().replace(/\n/g,"\n  ")+(e.compress?"}":"\n}\n")},eval:function(t){t.mediaBlocks||(t.mediaBlocks=[],t.mediaPath=[]);var n=new e.Media([],[]);this.debugInfo&&(this.ruleset.debugInfo=this.debugInfo,n.debugInfo=this.debugInfo);var r=!1;t.strictMath||(r=!0,t.strictMath=!0);try{n.features=this.features.eval(t)}finally{r&&(t.strictMath=!1)}return t.mediaPath.push(n),t.mediaBlocks.push(n),t.frames.unshift(this.ruleset),n.ruleset=this.ruleset.eval(t),t.frames.shift(),t.mediaPath.pop(),t.mediaPath.length===0?n.evalTop(t):n.evalNested(t)},variable:function(t){return e.Ruleset.prototype.variable.call(this.ruleset,t)},find:function(){return e.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return e.Ruleset.prototype.rulesets.apply(this.ruleset)},emptySelectors:function(){var t=new e.Element("","&",0);return[new e.Selector([t])]},evalTop:function(t){var n=this;if(t.mediaBlocks.length>1){var r=this.emptySelectors();n=new e.Ruleset(r,t.mediaBlocks),n.multiMedia=!0}return delete t.mediaBlocks,delete t.mediaPath,n},evalNested:function(t){var n,r,i=t.mediaPath.concat([this]);for(n=0;n<i.length;n++)r=i[n].features instanceof e.Value?i[n].features.value:i[n].features,i[n]=Array.isArray(r)?r:[r];return this.features=new e.Value(this.permute(i).map(function(t){t=t.map(function(t){return t.toCSS?t:new e.Anonymous(t)});for(n=t.length-1;n>0;n--)t.splice(n,0,new e.Anonymous("and"));return new e.Expression(t)})),new e.Ruleset([],[])},permute:function(e){if(e.length===0)return[];if(e.length===1)return e[0];var t=[],n=this.permute(e.slice(1));for(var r=0;r<n.length;r++)for(var i=0;i<e[0].length;i++)t.push([e[0][i]].concat(n[r]));return t},bubbleSelectors:function(t){this.ruleset=new e.Ruleset(t.slice(0),[this.ruleset])}}}(n("../tree")),function(e){e.mixin={},e.mixin.Call=function(t,n,r,i,s){this.selector=new e.Selector(t),this.arguments=n,this.index=r,this.currentFileInfo=i,this.important=s},e.mixin.Call.prototype={type:"MixinCall",accept:function(e){this.selector=e.visit(this.selector),this.arguments=e.visit(this.arguments)},eval:function(t){var n,r,i,s=[],o=!1,u,a,f,l,c;i=this.arguments&&this.arguments.map(function(e){return{name:e.name,value:e.value.eval(t)}});for(u=0;u<t.frames.length;u++)if((n=t.frames[u].find(this.selector)).length>0){c=!0;for(a=0;a<n.length;a++){r=n[a],l=!1;for(f=0;f<t.frames.length;f++)if(!(r instanceof e.mixin.Definition)&&r===(t.frames[f].originalRuleset||t.frames[f])){l=!0;break}if(l)continue;if(r.matchArgs(i,t)){if(!r.matchCondition||r.matchCondition(i,t))try{Array.prototype.push.apply(s,r.eval(t,i,this.important).rules)}catch(h){throw{message:h.message,index:this.index,filename:this.currentFileInfo.filename,stack:h.stack}}o=!0}}if(o)return s}throw c?{type:"Runtime",message:"No matching definition was found for `"+this.selector.toCSS().trim()+"("+(i?i.map(function(e){var t="";return e.name&&(t+=e.name+":"),e.value.toCSS?t+=e.value.toCSS():t+="???",t}).join(", "):"")+")`",index:this.index,filename:this.currentFileInfo.filename}:{type:"Name",message:this.selector.toCSS().trim()+" is undefined",index:this.index,filename:this.currentFileInfo.filename}}},e.mixin.Definition=function(t,n,r,i,s){this.name=t,this.selectors=[new e.Selector([new e.Element(null,t)])],this.params=n,this.condition=i,this.variadic=s,this.arity=n.length,this.rules=r,this._lookups={},this.required=n.reduce(function(e,t){return!t.name||t.name&&!t.value?e+1:e},0),this.parent=e.Ruleset.prototype,this.frames=[]},e.mixin.Definition.prototype={type:"MixinDefinition",accept:function(e){this.params=e.visit(this.params),this.rules=e.visit(this.rules),this.condition=e.visit(this.condition)},toCSS:function(){return""},variable:function(e){return this.parent.variable.call(this,e)},variables:function(){return this.parent.variables.call(this)},find:function(){return this.parent.find.apply(this,arguments)},rulesets:function(){return this.parent.rulesets.apply(this)},evalParams:function(t,n,r,i){var s=new e.Ruleset(null,[]),o,u,a=this.params.slice(0),f,l,c,h,p,d;n=new e.evalEnv(n,[s].concat(n.frames));if(r){r=r.slice(0);for(f=0;f<r.length;f++){u=r[f];if(h=u&&u.name){p=!1;for(l=0;l<a.length;l++)if(!i[l]&&h===a[l].name){i[l]=u.value.eval(t),s.rules.unshift(new e.Rule(h,u.value.eval(t))),p=!0;break}if(p){r.splice(f,1),f--;continue}throw{type:"Runtime",message:"Named argument for "+this.name+" "+r[f].name+" not found"}}}}d=0;for(f=0;f<a.length;f++){if(i[f])continue;u=r&&r[d];if(h=a[f].name)if(a[f].variadic&&r){o=[];for(l=d;l<r.length;l++)o.push(r[l].value.eval(t));s.rules.unshift(new e.Rule(h,(new e.Expression(o)).eval(t)))}else{c=u&&u.value;if(c)c=c.eval(t);else{if(!a[f].value)throw{type:"Runtime",message:"wrong number of arguments for "+this.name+" ("+r.length+" for "+this.arity+")"};c=a[f].value.eval(n),s.resetCache()}s.rules.unshift(new e.Rule(h,c)),i[f]=c}if(a[f].variadic&&r)for(l=d;l<r.length;l++)i[l]=r[l].value.eval(t);d++}return s},eval:function(t,n,r){var i=[],s=this.frames.concat(t.frames),o=this.evalParams(t,new e.evalEnv(t,s),n,i),u,a,f,l;return o.rules.unshift(new e.Rule("@arguments",(new e.Expression(i)).eval(t))),a=r?this.parent.makeImportant.apply(this).rules:this.rules.slice(0),l=(new e.Ruleset(null,a)).eval(new e.evalEnv(t,[this,o].concat(s))),l.originalRuleset=this,l},matchCondition:function(t,n){return this.condition&&!this.condition.eval(new e.evalEnv(n,[this.evalParams(n,new e.evalEnv(n,this.frames.concat(n.frames)),t,[])].concat(n.frames)))?!1:!0},matchArgs:function(e,t){var n=e&&e.length||0,r,i;if(!this.variadic){if(n<this.required)return!1;if(n>this.params.length)return!1;if(this.required>0&&n>this.params.length)return!1}r=Math.min(n,this.arity);for(var s=0;s<r;s++)if(!this.params[s].name&&!this.params[s].variadic&&e[s].value.eval(t).toCSS()!=this.params[s].value.eval(t).toCSS())return!1;return!0}}}(n("../tree")),function(e){e.Negative=function(e){this.value=e},e.Negative.prototype={type:"Negative",accept:function(e){this.value=e.visit(this.value)},toCSS:function(e){return"-"+this.value.toCSS(e)},eval:function(t){return t.isMathOn()?(new e.Operation("*",[new e.Dimension(-1),this.value])).eval(t):new e.Negative(this.value.eval(t))}}}(n("../tree")),function(e){e.Operation=function(e,t,n){this.op=e.trim(),this.operands=t,this.isSpaced=n},e.Operation.prototype={type:"Operation",accept:function(e){this.operands=e.visit(this.operands)},eval:function(t){var n=this.operands[0].eval(t),r=this.operands[1].eval(t),i;if(t.isMathOn()){if(n instanceof e.Dimension&&r instanceof e.Color){if(this.op!=="*"&&this.op!=="+")throw{type:"Operation",message:"Can't substract or divide a color from a number"};i=r,r=n,n=i}if(!n.operate)throw{type:"Operation",message:"Operation on an invalid type"};return n.operate(t,this.op,r)}return new e.Operation(this.op,[n,r],this.isSpaced)},toCSS:function(e){var t=this.isSpaced?" ":"";return this.operands[0].toCSS()+t+this.op+t+this.operands[1].toCSS()}},e.operate=function(e,t,n,r){switch(t){case"+":return n+r;case"-":return n-r;case"*":return n*r;case"/":return n/r}}}(n("../tree")),function(e){e.Paren=function(e){this.value=e},e.Paren.prototype={type:"Paren",accept:function(e){this.value=e.visit(this.value)},toCSS:function(e){return"("+this.value.toCSS(e).trim()+")"},eval:function(t){return new e.Paren(this.value.eval(t))}}}(n("../tree")),function(e){e.Quoted=function(e,t,n,r,i){this.escaped=n,this.value=t||"",this.quote=e.charAt(0),this.index=r,this.currentFileInfo=i},e.Quoted.prototype={type:"Quoted",toCSS:function(){return this.escaped?this.value:this.quote+this.value+this.quote},eval:function(t){var n=this,r=this.value.replace(/`([^`]+)`/g,function(r,i){return(new e.JavaScript(i,n.index,!0)).eval(t).value}).replace(/@\{([\w-]+)\}/g,function(r,i){var s=(new e.Variable("@"+i,n.index,n.currentFileInfo)).eval(t,!0);return s instanceof e.Quoted?s.value:s.toCSS()});return new e.Quoted(this.quote+r+this.quote,r,this.escaped,this.index)},compare:function(e){if(!e.toCSS)return-1;var t=this.toCSS(),n=e.toCSS();return t===n?0:t<n?-1:1}}}(n("../tree")),function(e){e.Rule=function(t,n,r,i,s,o){this.name=t,this.value=n instanceof e.Value?n:new e.Value([n]),this.important=r?" "+r.trim():"",this.index=i,this.currentFileInfo=s,this.inline=o||!1,t.charAt(0)==="@"?this.variable=!0:this.variable=!1},e.Rule.prototype={type:"Rule",accept:function(e){this.value=e.visit(this.value)},toCSS:function(e){if(this.variable)return"";try{return this.name+(e.compress?":":": ")+this.value.toCSS(e)+this.important+(this.inline?"":";")}catch(t){throw t.index=this.index,t.filename=this.currentFileInfo.filename,t}},eval:function(t){var n=!1;this.name==="font"&&t.strictMath===!1&&(n=!0,t.strictMath=!0);try{return new e.Rule(this.name,this.value.eval(t),this.important,this.index,this.currentFileInfo,this.inline)}finally{n&&(t.strictMath=!1)}},makeImportant:function(){return new e.Rule(this.name,this.value,"!important",this.index,this.currentFileInfo,this.inline)}}}(n("../tree")),function(e){e.Ruleset=function(e,t,n){this.selectors=e,this.rules=t,this._lookups={},this.strictImports=n},e.Ruleset.prototype={type:"Ruleset",accept:function(e){this.selectors=e.visit(this.selectors),this.rules=e.visit(this.rules)},eval:function(t){var n=this.selectors&&this.selectors.map(function(e){return e.eval(t)}),r=new e.Ruleset(n,this.rules.slice(0),this.strictImports),i;r.originalRuleset=this,r.root=this.root,r.firstRoot=this.firstRoot,r.allowImports=this.allowImports,this.debugInfo&&(r.debugInfo=this.debugInfo),t.frames.unshift(r),t.selectors||(t.selectors=[]),t.selectors.unshift(this.selectors),(r.root||r.allowImports||!r.strictImports)&&r.evalImports(t);for(var s=0;s<r.rules.length;s++)r.rules[s]instanceof e.mixin.Definition&&(r.rules[s].frames=t.frames.slice(0));var o=t.mediaBlocks&&t.mediaBlocks.length||0;for(var s=0;s<r.rules.length;s++)r.rules[s]instanceof e.mixin.Call&&(i=r.rules[s].eval(t).filter(function(t){return t instanceof e.Rule&&t.variable?!r.variable(t.name):!0}),r.rules.splice.apply(r.rules,[s,1].concat(i)),s+=i.length-1,r.resetCache());for(var s=0,u;s<r.rules.length;s++)u=r.rules[s],u instanceof e.mixin.Definition||(r.rules[s]=u.eval?u.eval(t):u);t.frames.shift(),t.selectors.shift();if(t.mediaBlocks)for(var s=o;s<t.mediaBlocks.length;s++)t.mediaBlocks[s].bubbleSelectors(n);return r},evalImports:function(t){var n,r;for(n=0;n<this.rules.length;n++)this.rules[n]instanceof e.Import&&(r=this.rules[n].eval(t),typeof r.length=="number"?(this.rules.splice.apply(this.rules,[n,1].concat(r)),n+=r.length-1):this.rules.splice(n,1,r),this.resetCache())},makeImportant:function(){return new e.Ruleset(this.selectors,this.rules.map(function(e){return e.makeImportant?e.makeImportant():e}),this.strictImports)},matchArgs:function(e){return!e||e.length===0},resetCache:function(){this._rulesets=null,this._variables=null,this._lookups={}},variables:function(){return this._variables?this._variables:this._variables=this.rules.reduce(function(t,n){return n instanceof e.Rule&&n.variable===!0&&(t[n.name]=n),t},{})},variable:function(e){return this.variables()[e]},rulesets:function(){return this.rules.filter(function(t){return t instanceof e.Ruleset||t instanceof e.mixin.Definition})},find:function(t,n){n=n||this;var r=[],i,s,o=t.toCSS();return o in this._lookups?this._lookups[o]:(this.rulesets().forEach(function(i){if(i!==n)for(var o=0;o<i.selectors.length;o++)if(s=t.match(i.selectors[o])){t.elements.length>i.selectors[o].elements.length?Array.prototype.push.apply(r,i.find(new e.Selector(t.elements.slice(1)),n)):r.push(i);break}}),this._lookups[o]=r)},toCSS:function(t){var n=[],r=[],i=[],s=[],o,u,a;for(var f=0;f<this.rules.length;f++){a=this.rules[f];if(a.rules||a instanceof e.Media)s.push(a.toCSS(t));else if(a instanceof e.Directive){var l=a.toCSS(t);if(a.name==="@charset"){if(t.charset){a.debugInfo&&(s.push(e.debugInfo(t,a)),s.push((new e.Comment("/* "+l.replace(/\n/g,"")+" */\n")).toCSS(t)));continue}t.charset=!0}s.push(l)}else if(a instanceof e.Comment)a.silent||(this.root?s.push(a.toCSS(t)):r.push(a.toCSS(t)));else if(a.toCSS&&!a.variable){if(this.firstRoot&&a instanceof e.Rule)throw{message:"properties must be inside selector blocks, they cannot be in the root.",index:a.index,filename:a.currentFileInfo?a.currentFileInfo.filename:null};r.push(a.toCSS(t))}else a.value&&!a.variable&&r.push(a.value.toString())}t.compress&&r.length&&(a=r[r.length-1],a.charAt(a.length-1)===";"&&(r[r.length-1]=a.substring(0,a.length-1))),s=s.join("");if(this.root)n.push(r.join(t.compress?"":"\n"));else if(r.length>0){u=e.debugInfo(t,this),o=this.paths.map(function(e){return e.map(function(e){return e.toCSS(t)}).join("").trim()}).join(t.compress?",":",\n");for(var f=r.length-1;f>=0;f--)(r[f].slice(0,2)==="/*"||i.indexOf(r[f])===-1)&&i.unshift(r[f]);r=i,n.push(u+o+(t.compress?"{":" {\n  ")+r.join(t.compress?"":"\n  ")+(t.compress?"}":"\n}\n"))}return n.push(s),n.join("")+(t.compress?"\n":"")},joinSelectors:function(e,t,n){for(var r=0;r<n.length;r++)this.joinSelector(e,t,n[r])},joinSelector:function(t,n,r){var i,s,o,u,a,f,l,c,h,p,d,v,m,g,y;for(i=0;i<r.elements.length;i++)f=r.elements[i],f.value==="&"&&(u=!0);if(!u){if(n.length>0)for(i=0;i<n.length;i++)t.push(n[i].concat(r));else t.push([r]);return}g=[],a=[[]];for(i=0;i<r.elements.length;i++){f=r.elements[i];if(f.value!=="&")g.push(f);else{y=[],g.length>0&&this.mergeElementsOnToSelectors(g,a);for(s=0;s<a.length;s++){l=a[s];if(n.length==0)l.length>0&&(l[0].elements=l[0].elements.slice(0),l[0].elements.push(new e.Element(f.combinator,"",0))),y.push(l);else for(o=0;o<n.length;o++)c=n[o],h=[],p=[],v=!0,l.length>0?(h=l.slice(0),m=h.pop(),d=new e.Selector(m.elements.slice(0),r.extendList),v=!1):d=new e.Selector([],r.extendList),c.length>1&&(p=p.concat(c.slice(1))),c.length>0&&(v=!1,d.elements.push(new e.Element(f.combinator,c[0].elements[0].value,0)),d.elements=d.elements.concat(c[0].elements.slice(1))),v||h.push(d),h=h.concat(p),y.push(h)}a=y,g=[]}}g.length>0&&this.mergeElementsOnToSelectors(g,a);for(i=0;i<a.length;i++)a[i].length>0&&t.push(a[i])},mergeElementsOnToSelectors:function(t,n){var r,i,s;if(n.length==0){n.push([new e.Selector(t)]);return}for(r=0;r<n.length;r++)i=n[r],i.length>0?i[i.length-1]=new e.Selector(i[i.length-1].elements.concat(t),i[i.length-1].extendList):i.push(new e.Selector(t))}}}(n("../tree")),function(e){e.Selector=function(e,t){this.elements=e,this.extendList=t||[]},e.Selector.prototype={type:"Selector",accept:function(e){this.elements=e.visit(this.elements),this.extendList=e.visit(this.extendList)},match:function(e){var t=this.elements,n=t.length,r,i,s,o;r=e.elements.slice(e.elements.length&&e.elements[0].value==="&"?1:0),i=r.length,s=Math.min(n,i);if(i===0||n<i)return!1;for(o=0;o<s;o++)if(t[o].value!==r[o].value)return!1;return!0},eval:function(t){return new e.Selector(this.elements.map(function(e){return e.eval(t)}),this.extendList.map(function(e){return e.eval(t)}))},toCSS:function(e){return this._css?this._css:(this.elements[0].combinator.value===""?this._css=" ":this._css="",this._css+=this.elements.map(function(t){return typeof t=="string"?" "+t.trim():t.toCSS(e)}).join(""),this._css)}}}(n("../tree")),function(e){e.UnicodeDescriptor=function(e){this.value=e},e.UnicodeDescriptor.prototype={type:"UnicodeDescriptor",toCSS:function(e){return this.value},eval:function(){return this}
  330.14 +}}(n("../tree")),function(e){e.URL=function(e,t){this.value=e,this.currentFileInfo=t},e.URL.prototype={type:"Url",accept:function(e){this.value=e.visit(this.value)},toCSS:function(){return"url("+this.value.toCSS()+")"},eval:function(t){var n=this.value.eval(t),r;return r=this.currentFileInfo&&this.currentFileInfo.rootpath,r&&typeof n.value=="string"&&t.isPathRelative(n.value)&&(n.quote||(r=r.replace(/[\(\)'"\s]/g,function(e){return"\\"+e})),n.value=r+n.value),new e.URL(n,null)}}}(n("../tree")),function(e){e.Value=function(e){this.value=e},e.Value.prototype={type:"Value",accept:function(e){this.value=e.visit(this.value)},eval:function(t){return this.value.length===1?this.value[0].eval(t):new e.Value(this.value.map(function(e){return e.eval(t)}))},toCSS:function(e){return this.value.map(function(t){return t.toCSS(e)}).join(e.compress?",":", ")}}}(n("../tree")),function(e){e.Variable=function(e,t,n){this.name=e,this.index=t,this.currentFileInfo=n},e.Variable.prototype={type:"Variable",eval:function(t){var n,r,i=this.name;i.indexOf("@@")==0&&(i="@"+(new e.Variable(i.slice(1))).eval(t).value);if(this.evaluating)throw{type:"Name",message:"Recursive variable definition for "+i,filename:this.currentFileInfo.file,index:this.index};this.evaluating=!0;if(n=e.find(t.frames,function(e){if(r=e.variable(i))return r.value.eval(t)}))return this.evaluating=!1,n;throw{type:"Name",message:"variable "+i+" is undefined",filename:this.currentFileInfo.filename,index:this.index}}}}(n("../tree")),function(e){e.debugInfo=function(t,n){var r="";if(t.dumpLineNumbers&&!t.compress)switch(t.dumpLineNumbers){case"comments":r=e.debugInfo.asComment(n);break;case"mediaquery":r=e.debugInfo.asMediaQuery(n);break;case"all":r=e.debugInfo.asComment(n)+e.debugInfo.asMediaQuery(n)}return r},e.debugInfo.asComment=function(e){return"/* line "+e.debugInfo.lineNumber+", "+e.debugInfo.fileName+" */\n"},e.debugInfo.asMediaQuery=function(e){return"@media -sass-debug-info{filename{font-family:"+("file://"+e.debugInfo.fileName).replace(/([.:/\\])/g,function(e){return e=="\\"&&(e="/"),"\\"+e})+"}line{font-family:\\00003"+e.debugInfo.lineNumber+"}}\n"},e.find=function(e,t){for(var n=0,r;n<e.length;n++)if(r=t.call(e,e[n]))return r;return null},e.jsify=function(e){return Array.isArray(e.value)&&e.value.length>1?"["+e.value.map(function(e){return e.toCSS(!1)}).join(", ")+"]":e.toCSS(!1)}}(n("./tree")),function(e){var t=["paths","optimization","files","contents","relativeUrls","strictImports","dumpLineNumbers","compress","processImports","syncImport","mime","currentFileInfo"];e.parseEnv=function(e){r(e,this,t),this.contents||(this.contents={}),this.files||(this.files={});if(!this.currentFileInfo){var n=e&&e.filename||"input",i=n.replace(/[^\/\\]*$/,"");e&&(e.filename=null),this.currentFileInfo={filename:n,relativeUrls:this.relativeUrls,rootpath:e&&e.rootpath||"",currentDirectory:i,entryPath:i,rootFilename:n}}},e.parseEnv.prototype.toSheet=function(t){var n=new e.parseEnv(this);return n.href=t,n.type=this.mime,n};var n=["silent","verbose","compress","yuicompress","ieCompat","strictMath","strictUnits"];e.evalEnv=function(e,t){r(e,this,n),this.frames=t||[]},e.evalEnv.prototype.inParenthesis=function(){this.parensStack||(this.parensStack=[]),this.parensStack.push(!0)},e.evalEnv.prototype.outOfParenthesis=function(){this.parensStack.pop()},e.evalEnv.prototype.isMathOn=function(){return this.strictMath?this.parensStack&&this.parensStack.length:!0},e.evalEnv.prototype.isPathRelative=function(e){return!/^(?:[a-z-]+:|\/)/.test(e)};var r=function(e,t,n){if(!e)return;for(var r=0;r<n.length;r++)e.hasOwnProperty(n[r])&&(t[n[r]]=e[n[r]])}}(n("./tree")),function(e){e.visitor=function(e){this._implementation=e},e.visitor.prototype={visit:function(e){if(e instanceof Array)return this.visitArray(e);if(!e||!e.type)return e;var t="visit"+e.type,n=this._implementation[t],r,i;return n&&(r={visitDeeper:!0},i=n.call(this._implementation,e,r),this._implementation.isReplacing&&(e=i)),(!r||r.visitDeeper)&&e&&e.accept&&e.accept(this),t+="Out",this._implementation[t]&&this._implementation[t](e),e},visitArray:function(e){var t,n=[];for(t=0;t<e.length;t++){var r=this.visit(e[t]);r instanceof Array?n=n.concat(r):n.push(r)}return this._implementation.isReplacing?n:e}}}(n("./tree")),function(e){e.importVisitor=function(t,n,r){this._visitor=new e.visitor(this),this._importer=t,this._finish=n,this.env=r||new e.evalEnv,this.importCount=0},e.importVisitor.prototype={isReplacing:!0,run:function(e){var t;try{this._visitor.visit(e)}catch(n){t=n}this.isFinished=!0,this.importCount===0&&this._finish(t)},visitImport:function(t,n){var r=this,i;if(!t.css){try{i=t.evalForImport(this.env)}catch(s){s.filename||(s.index=t.index,s.filename=t.currentFileInfo.filename),t.css=!0,t.error=s}if(i&&!i.css){t=i,this.importCount++;var o=new e.evalEnv(this.env,this.env.frames.slice(0));this._importer.push(t.getPath(),t.currentFileInfo,function(n,i,s){n&&!n.filename&&(n.index=t.index,n.filename=t.currentFileInfo.filename),s&&!t.options.multiple&&(t.skip=s);var u=function(e){r.importCount--,r.importCount===0&&r.isFinished&&r._finish(e)};i?(t.root=i,(new e.importVisitor(r._importer,u,o)).run(i)):u()})}}return n.visitDeeper=!1,t},visitRule:function(e,t){return t.visitDeeper=!1,e},visitDirective:function(e,t){return this.env.frames.unshift(e),e},visitDirectiveOut:function(e){this.env.frames.shift()},visitMixinDefinition:function(e,t){return this.env.frames.unshift(e),e},visitMixinDefinitionOut:function(e){this.env.frames.shift()},visitRuleset:function(e,t){return this.env.frames.unshift(e),e},visitRulesetOut:function(e){this.env.frames.shift()},visitMedia:function(e,t){return this.env.frames.unshift(e.ruleset),e},visitMediaOut:function(e){this.env.frames.shift()}}}(n("./tree")),function(e){e.joinSelectorVisitor=function(){this.contexts=[[]],this._visitor=new e.visitor(this)},e.joinSelectorVisitor.prototype={run:function(e){return this._visitor.visit(e)},visitRule:function(e,t){t.visitDeeper=!1},visitMixinDefinition:function(e,t){t.visitDeeper=!1},visitRuleset:function(e,t){var n=this.contexts[this.contexts.length-1],r=[];this.contexts.push(r),e.root||(e.joinSelectors(r,n,e.selectors),e.paths=r)},visitRulesetOut:function(e){this.contexts.length=this.contexts.length-1},visitMedia:function(e,t){var n=this.contexts[this.contexts.length-1];e.ruleset.root=n.length===0||n[0].multiMedia}}}(n("./tree")),function(e){e.extendFinderVisitor=function(){this._visitor=new e.visitor(this),this.contexts=[],this.allExtendsStack=[[]]},e.extendFinderVisitor.prototype={run:function(e){return e=this._visitor.visit(e),e.allExtends=this.allExtendsStack[0],e},visitRule:function(e,t){t.visitDeeper=!1},visitMixinDefinition:function(e,t){t.visitDeeper=!1},visitRuleset:function(t,n){if(t.root)return;var r,i,s,o=[],u;for(r=0;r<t.rules.length;r++)t.rules[r]instanceof e.Extend&&o.push(t.rules[r]);for(r=0;r<t.paths.length;r++){var a=t.paths[r],f=a[a.length-1];u=f.extendList.slice(0).concat(o).map(function(e){return e.clone()});for(i=0;i<u.length;i++)this.foundExtends=!0,s=u[i],s.findSelfSelectors(a),s.ruleset=t,i===0&&(s.firstExtendOnThisSelectorPath=!0),this.allExtendsStack[this.allExtendsStack.length-1].push(s)}this.contexts.push(t.selectors)},visitRulesetOut:function(e){e.root||(this.contexts.length=this.contexts.length-1)},visitMedia:function(e,t){e.allExtends=[],this.allExtendsStack.push(e.allExtends)},visitMediaOut:function(e){this.allExtendsStack.length=this.allExtendsStack.length-1},visitDirective:function(e,t){e.allExtends=[],this.allExtendsStack.push(e.allExtends)},visitDirectiveOut:function(e){this.allExtendsStack.length=this.allExtendsStack.length-1}},e.processExtendsVisitor=function(){this._visitor=new e.visitor(this)},e.processExtendsVisitor.prototype={run:function(t){var n=new e.extendFinderVisitor;return n.run(t),n.foundExtends?(t.allExtends=t.allExtends.concat(this.doExtendChaining(t.allExtends,t.allExtends)),this.allExtendsStack=[t.allExtends],this._visitor.visit(t)):t},doExtendChaining:function(t,n,r){var i,s,o,u=[],a,f=this,l,c,h,p;r=r||0;for(i=0;i<t.length;i++)for(s=0;s<n.length;s++){c=t[i],h=n[s];if(this.inInheritanceChain(h,c))continue;l=[h.selfSelectors[0]],o=f.findMatch(c,l),o.length&&c.selfSelectors.forEach(function(t){a=f.extendSelector(o,l,t),p=new e.Extend(h.selector,h.option,0),p.selfSelectors=a,a[a.length-1].extendList=[p],u.push(p),p.ruleset=h.ruleset,p.parents=[h,c],h.firstExtendOnThisSelectorPath&&(p.firstExtendOnThisSelectorPath=!0,h.ruleset.paths.push(a))})}if(u.length){this.extendChainCount++;if(r>100){var d="{unable to calculate}",v="{unable to calculate}";try{d=u[0].selfSelectors[0].toCSS(),v=u[0].selector.toCSS()}catch(m){}throw{message:"extend circular reference detected. One of the circular extends is currently:"+d+":extend("+v+")"}}return u.concat(f.doExtendChaining(u,n,r+1))}return u},inInheritanceChain:function(e,t){if(e===t)return!0;if(t.parents){if(this.inInheritanceChain(e,t.parents[0]))return!0;if(this.inInheritanceChain(e,t.parents[1]))return!0}return!1},visitRule:function(e,t){t.visitDeeper=!1},visitMixinDefinition:function(e,t){t.visitDeeper=!1},visitSelector:function(e,t){t.visitDeeper=!1},visitRuleset:function(e,t){if(e.root)return;var n,r,i,s=this.allExtendsStack[this.allExtendsStack.length-1],o=[],u=this,a;for(i=0;i<s.length;i++)for(r=0;r<e.paths.length;r++){a=e.paths[r];if(a[a.length-1].extendList.length)continue;n=this.findMatch(s[i],a),n.length&&s[i].selfSelectors.forEach(function(e){o.push(u.extendSelector(n,a,e))})}e.paths=e.paths.concat(o)},findMatch:function(e,t){var n,r,i,s,o,u,a=this,f=e.selector.elements,l=[],c,h=[];for(n=0;n<t.length;n++){r=t[n];for(i=0;i<r.elements.length;i++){s=r.elements[i],(e.allowBefore||n==0&&i==0)&&l.push({pathIndex:n,index:i,matched:0,initialCombinator:s.combinator});for(u=0;u<l.length;u++)c=l[u],o=s.combinator.value,o==""&&i===0&&(o=" "),!a.isElementValuesEqual(f[c.matched].value,s.value)||c.matched>0&&f[c.matched].combinator.value!==o?c=null:c.matched++,c&&(c.finished=c.matched===f.length,c.finished&&!e.allowAfter&&(i+1<r.elements.length||n+1<t.length)&&(c=null)),c?c.finished&&(c.length=f.length,c.endPathIndex=n,c.endPathElementIndex=i+1,l.length=0,h.push(c)):(l.splice(u,1),u--)}}return h},isElementValuesEqual:function(t,n){if(typeof t=="string"||typeof n=="string")return t===n;if(t instanceof e.Attribute)return t.op!==n.op||t.key!==n.key?!1:!t.value||!n.value?t.value||n.value?!1:!0:(t=t.value.value||t.value,n=n.value.value||n.value,t===n);return!1},extendSelector:function(t,n,r){var i=0,s=0,o=[],u,a,f,l;for(u=0;u<t.length;u++)l=t[u],a=n[l.pathIndex],f=new e.Element(l.initialCombinator,r.elements[0].value,r.elements[0].index),l.pathIndex>i&&s>0&&(o[o.length-1].elements=o[o.length-1].elements.concat(n[i].elements.slice(s)),s=0,i++),o=o.concat(n.slice(i,l.pathIndex)),o.push(new e.Selector(a.elements.slice(s,l.index).concat([f]).concat(r.elements.slice(1)))),i=l.endPathIndex,s=l.endPathElementIndex,s>=a.elements.length&&(s=0,i++);return i<n.length&&s>0&&(o[o.length-1].elements=o[o.length-1].elements.concat(n[i].elements.slice(s)),s=0,i++),o=o.concat(n.slice(i,n.length)),o},visitRulesetOut:function(e){},visitMedia:function(e,t){var n=e.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);n=n.concat(this.doExtendChaining(n,e.allExtends)),this.allExtendsStack.push(n)},visitMediaOut:function(e){this.allExtendsStack.length=this.allExtendsStack.length-1},visitDirective:function(e,t){var n=e.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);n=n.concat(this.doExtendChaining(n,e.allExtends)),this.allExtendsStack.push(n)},visitDirectiveOut:function(e){this.allExtendsStack.length=this.allExtendsStack.length-1}}}(n("./tree"));var o=/^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);r.env=r.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||o?"development":"production"),r.async=r.async||!1,r.fileAsync=r.fileAsync||!1,r.poll=r.poll||(o?1e3:1500);if(r.functions)for(var u in r.functions)r.tree.functions[u]=r.functions[u];var a=/!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);a&&(r.dumpLineNumbers=a[1]),r.watch=function(){return r.watchMode||(r.env="development",f()),this.watchMode=!0},r.unwatch=function(){return clearInterval(r.watchTimer),this.watchMode=!1},/!watch/.test(location.hash)&&r.watch();var l=null;if(r.env!="development")try{l=typeof e.localStorage=="undefined"?null:e.localStorage}catch(c){}var h=document.getElementsByTagName("link"),p=/^text\/(x-)?less$/;r.sheets=[];for(var d=0;d<h.length;d++)(h[d].rel==="stylesheet/less"||h[d].rel.match(/stylesheet/)&&h[d].type.match(p))&&r.sheets.push(h[d]);var v="";r.modifyVars=function(e){var t=v;for(var n in e)t+=(n.slice(0,1)==="@"?"":"@")+n+": "+(e[n].slice(-1)===";"?e[n]:e[n]+";");(new r.Parser(new r.tree.parseEnv(r))).parse(t,function(e,t){e?k(e,"session_cache"):S(t.toCSS(r),r.sheets[r.sheets.length-1])})},r.refresh=function(e){var t,n;t=n=new Date,g(function(e,i,s,o,u){if(e)return k(e,o.href);u.local?C("loading "+o.href+" from cache."):(C("parsed "+o.href+" successfully."),S(i.toCSS(r),o,u.lastModified)),C("css for "+o.href+" generated in "+(new Date-n)+"ms"),u.remaining===0&&C("css generated in "+(new Date-t)+"ms"),n=new Date},e),m()},r.refreshStyles=m,r.refresh(r.env==="development"),typeof define=="function"&&define.amd&&define(function(){return r})})(window);
  330.15 \ No newline at end of file
   331.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   331.2 +++ b/static/lf3.css	Thu Jul 10 01:19:48 2014 +0200
   331.3 @@ -0,0 +1,1567 @@
   331.4 +html,
   331.5 +body,
   331.6 +div,
   331.7 +span,
   331.8 +applet,
   331.9 +object,
  331.10 +iframe,
  331.11 +h1,
  331.12 +h2,
  331.13 +h3,
  331.14 +h4,
  331.15 +h5,
  331.16 +h6,
  331.17 +p,
  331.18 +blockquote,
  331.19 +pre,
  331.20 +a,
  331.21 +abbr,
  331.22 +acronym,
  331.23 +address,
  331.24 +big,
  331.25 +cite,
  331.26 +code,
  331.27 +del,
  331.28 +dfn,
  331.29 +em,
  331.30 +img,
  331.31 +ins,
  331.32 +kbd,
  331.33 +q,
  331.34 +s,
  331.35 +samp,
  331.36 +small,
  331.37 +strike,
  331.38 +strong,
  331.39 +sub,
  331.40 +sup,
  331.41 +tt,
  331.42 +var,
  331.43 +b,
  331.44 +u,
  331.45 +i,
  331.46 +center,
  331.47 +dl,
  331.48 +dt,
  331.49 +dd,
  331.50 +ol,
  331.51 +ul,
  331.52 +li,
  331.53 +fieldset,
  331.54 +form,
  331.55 +label,
  331.56 +legend,
  331.57 +table,
  331.58 +caption,
  331.59 +tbody,
  331.60 +tfoot,
  331.61 +thead,
  331.62 +tr,
  331.63 +th,
  331.64 +td,
  331.65 +article,
  331.66 +aside,
  331.67 +canvas,
  331.68 +details,
  331.69 +embed,
  331.70 +figure,
  331.71 +figcaption,
  331.72 +footer,
  331.73 +header,
  331.74 +hgroup,
  331.75 +menu,
  331.76 +nav,
  331.77 +output,
  331.78 +ruby,
  331.79 +section,
  331.80 +summary,
  331.81 +time,
  331.82 +mark,
  331.83 +audio,
  331.84 +video {
  331.85 +  margin: 0;
  331.86 +  padding: 0;
  331.87 +  border: 0;
  331.88 +  font-size: 100%;
  331.89 +  font: inherit;
  331.90 +  vertical-align: baseline;
  331.91 +}
  331.92 +/* HTML5 display-role reset for older browsers */
  331.93 +article,
  331.94 +aside,
  331.95 +details,
  331.96 +figcaption,
  331.97 +figure,
  331.98 +footer,
  331.99 +header,
 331.100 +hgroup,
 331.101 +menu,
 331.102 +nav,
 331.103 +section {
 331.104 +  display: block;
 331.105 +}
 331.106 +body {
 331.107 +  line-height: 1;
 331.108 +}
 331.109 +ol,
 331.110 +ul {
 331.111 +  list-style: none;
 331.112 +}
 331.113 +blockquote,
 331.114 +q {
 331.115 +  quotes: none;
 331.116 +}
 331.117 +blockquote:before,
 331.118 +blockquote:after,
 331.119 +q:before,
 331.120 +q:after {
 331.121 +  content: '';
 331.122 +  content: none;
 331.123 +}
 331.124 +table {
 331.125 +  border-collapse: collapse;
 331.126 +  border-spacing: 0;
 331.127 +}
 331.128 +/* end reset */
 331.129 +/* color, fonts, gaps and border radius settings */
 331.130 +.list-style {
 331.131 +  list-style: disc;
 331.132 +  padding-left: 20px;
 331.133 +}
 331.134 +/*
 331.135 + * basic font settings
 331.136 + */
 331.137 +html {
 331.138 +  overflow-y: scroll;
 331.139 +}
 331.140 +body {
 331.141 +  font: normal 10pt / 125% sans-serif;
 331.142 +  background-color: #397ab6;
 331.143 +  color: #000000;
 331.144 +  background-attachment: fixed;
 331.145 +}
 331.146 +.page {
 331.147 +  background-image: url("back50.png");
 331.148 +  max-width: 1240px;
 331.149 +  border-radius: 0 0 2px 2px;
 331.150 +  margin: 0 auto;
 331.151 +  margin-bottom: 40px;
 331.152 +}
 331.153 +/*
 331.154 + * messages
 331.155 + */
 331.156 +.slot_notice,
 331.157 +.slot_warning,
 331.158 +.slot_error {
 331.159 +  font: bold 12pt / 125% sans-serif;
 331.160 +  padding: 12pt;
 331.161 +}
 331.162 +.slot_motd {
 331.163 +  background-color: #ccc;
 331.164 +  padding: 12pt;
 331.165 +}
 331.166 +.slot_notice {
 331.167 +  background-color: #0c0;
 331.168 +  color: #fff;
 331.169 +}
 331.170 +.slot_warning {
 331.171 +  background-color: #f80;
 331.172 +  color: #000;
 331.173 +}
 331.174 +.slot_error {
 331.175 +  background-color: #c00;
 331.176 +  color: #fff;
 331.177 +}
 331.178 +/*
 331.179 + * global styles
 331.180 + */
 331.181 +/* headlines */
 331.182 +h1 {
 331.183 +  font: bold 12pt / 125% sans-serif;
 331.184 +  margin-bottom: 1ex;
 331.185 +}
 331.186 +h1:last-child {
 331.187 +  margin-bottom: 0;
 331.188 +}
 331.189 +h2 {
 331.190 +  font: normal 12pt / 125% sans-serif;
 331.191 +}
 331.192 +h3 {
 331.193 +  font: bold 10pt / 125% sans-serif;
 331.194 +}
 331.195 +h1:first-child,
 331.196 +h2:first-child,
 331.197 +h3:first-child {
 331.198 +  margin-top: 0;
 331.199 +}
 331.200 +.right {
 331.201 +  float: right;
 331.202 +}
 331.203 +.left {
 331.204 +  float: left;
 331.205 +  margin-right: 9px;
 331.206 +}
 331.207 +/* paragraphs */
 331.208 +p {
 331.209 +  margin-bottom: 1.5ex;
 331.210 +}
 331.211 +p:last-child {
 331.212 +  margin-bottom: 0;
 331.213 +}
 331.214 +/* lists */
 331.215 +ul.ul {
 331.216 +  margin-left: 9px;
 331.217 +  margin-bottom: 1.5ex;
 331.218 +  list-style: disc;
 331.219 +  padding-left: 20px;
 331.220 +}
 331.221 +ul.ul li {
 331.222 +  margin: 3px 0;
 331.223 +}
 331.224 +ul.ul li:last-child {
 331.225 +  margin-bottom: 0;
 331.226 +}
 331.227 +ul.ul:last-child {
 331.228 +  margin-bottom: 0;
 331.229 +}
 331.230 +/* tables */
 331.231 +table td {
 331.232 +  padding: 0.3ex 0.3em;
 331.233 +}
 331.234 +/* links */
 331.235 +a {
 331.236 +  color: #222277;
 331.237 +}
 331.238 +a.disabled {
 331.239 +  color: #777777;
 331.240 +  cursor: default;
 331.241 +}
 331.242 +/* formulars */
 331.243 +form.inline {
 331.244 +  display: inline;
 331.245 +}
 331.246 +form.inline div {
 331.247 +  display: inline;
 331.248 +}
 331.249 +img {
 331.250 +  vertical-align: middle;
 331.251 +}
 331.252 +.icon16 {
 331.253 +  width: 16px;
 331.254 +  height: 16px;
 331.255 +}
 331.256 +.icon24 {
 331.257 +  width: 24px;
 331.258 +  height: 24px;
 331.259 +}
 331.260 +.icon32 {
 331.261 +  width: 32px;
 331.262 +  height: 32px;
 331.263 +}
 331.264 +.icon48 {
 331.265 +  width: 48px;
 331.266 +  height: 48px;
 331.267 +}
 331.268 +img.star {
 331.269 +  width: 24px;
 331.270 +  height: 24px;
 331.271 +}
 331.272 +/*
 331.273 + * Avatars
 331.274 + */
 331.275 +.microAvatar {
 331.276 +  text-wrap: nowrap;
 331.277 +}
 331.278 +.microAvatar img,
 331.279 +img.micro_avatar {
 331.280 +  vertical-align: middle;
 331.281 +  border-radius: 2px;
 331.282 +  width: 24px;
 331.283 +  height: 24px;
 331.284 +}
 331.285 +img.micro_avatar.highlighted {
 331.286 +  margin: 0;
 331.287 +  border: 2px solid #ff8800;
 331.288 +}
 331.289 +/*
 331.290 + * delegation info
 331.291 + */
 331.292 +.vote_info,
 331.293 +.delegation_info {
 331.294 +  white-space: nowrap;
 331.295 +  float: right;
 331.296 +  text-decoration: none;
 331.297 +  margin: -2px;
 331.298 +}
 331.299 +.vote_info img,
 331.300 +.delegation_info img {
 331.301 +  vertical-align: middle;
 331.302 +}
 331.303 +.delegation_info img {
 331.304 +  border-radius: 2px;
 331.305 +  margin: 2px;
 331.306 +}
 331.307 +.delegation_info.suspended {
 331.308 +  opacity: 0.3;
 331.309 +}
 331.310 +.slot_title .delegation_info.suspended {
 331.311 +  opacity: 1;
 331.312 +}
 331.313 +/*
 331.314 + * generic attributes
 331.315 + */
 331.316 +.hide {
 331.317 +  display: none;
 331.318 +}
 331.319 +.head_outer {
 331.320 +  background-color: #000000;
 331.321 +  color: #ffffff;
 331.322 +  overflow: auto;
 331.323 +  margin: 0 auto;
 331.324 +  max-width: 1240px;
 331.325 +}
 331.326 +.head {
 331.327 +  padding: 0.3ex 0;
 331.328 +  margin: 0 12pt;
 331.329 +  /* 
 331.330 +  * the logo and instance name
 331.331 +  */
 331.332 +  /*
 331.333 +  * navigation bar
 331.334 +  */
 331.335 +}
 331.336 +.head a {
 331.337 +  color: #ffffff;
 331.338 +}
 331.339 +.head .logo {
 331.340 +  display: block;
 331.341 +  padding: 9px 0;
 331.342 +  text-decoration: none;
 331.343 +  font: bold 10pt / 100% sans-serif;
 331.344 +}
 331.345 +.head .logo .liquid {
 331.346 +  color: #ffffff;
 331.347 +}
 331.348 +.head .logo .feedback {
 331.349 +  color: #00ee00;
 331.350 +}
 331.351 +.head .logo .instanceName {
 331.352 +  font: normal 10pt / 100% sans-serif;
 331.353 +  padding-top: 9px;
 331.354 +}
 331.355 +.head .logo:hover {
 331.356 +  text-decoration: underline;
 331.357 +}
 331.358 +.head .notifications {
 331.359 +  margin-left: 0.6em;
 331.360 +  text-decoration: none;
 331.361 +}
 331.362 +.head .notifications .count {
 331.363 +  background-color: #f00;
 331.364 +  color: #000;
 331.365 +  padding: 0.2ex 0.25em;
 331.366 +  border-radius: 1ex;
 331.367 +  vertical-align: top;
 331.368 +}
 331.369 +.head .notifications .icon {
 331.370 +  width: 24px;
 331.371 +  height: 24px;
 331.372 +}
 331.373 +.head .nav {
 331.374 +  float: right;
 331.375 +  padding-top: 6px;
 331.376 +}
 331.377 +.head .nav ul,
 331.378 +.head .nav > ul > li:first-child {
 331.379 +  display: inline;
 331.380 +}
 331.381 +.head .nav input[name=q] {
 331.382 +  width: 12em;
 331.383 +  border-radius: 2px;
 331.384 +  padding: 2px;
 331.385 +  background-color: #000000;
 331.386 +  color: #ffffff;
 331.387 +  border: 1px solid #397ab6;
 331.388 +  margin-right: 0.6em;
 331.389 +}
 331.390 +.head .nav input[name=q]:focus {
 331.391 +  outline: 2px solid #397ab6;
 331.392 +}
 331.393 +/*
 331.394 + * title
 331.395 + */
 331.396 +.slot_title {
 331.397 +  padding-left: 12pt;
 331.398 +  padding-right: 12pt;
 331.399 +  font: bold 12pt / 125% sans-serif;
 331.400 +  color: #ffffff;
 331.401 +  padding-top: 12pt;
 331.402 +}
 331.403 +.slot_title a {
 331.404 +  color: #ffffff;
 331.405 +  display: inline-block;
 331.406 +}
 331.407 +.slot_title a.home {
 331.408 +  margin-right: 4px;
 331.409 +}
 331.410 +.slot_title a.delegation_info {
 331.411 +  margin-right: 0;
 331.412 +}
 331.413 +.slot_title .initiative,
 331.414 +.slot_title a .label {
 331.415 +  display: none;
 331.416 +}
 331.417 +.slot_title .delegation_info {
 331.418 +  background-color: #ffffff;
 331.419 +  color: #000000;
 331.420 +  border-radius: 2px;
 331.421 +  padding-right: 3px;
 331.422 +  margin-bottom: 12pt;
 331.423 +}
 331.424 +.slot_title .delegation_info a {
 331.425 +  color: #000000;
 331.426 +}
 331.427 +.content {
 331.428 +  clear: both;
 331.429 +  margin: 0 12pt;
 331.430 +  margin-top: 12pt;
 331.431 +}
 331.432 +/*
 331.433 + * the sidebar
 331.434 + */
 331.435 +.sidebar {
 331.436 +  float: right;
 331.437 +  width: 30%;
 331.438 +}
 331.439 +.sidebarSection {
 331.440 +  background-color: #ffffff;
 331.441 +  border-radius: 2px;
 331.442 +  color: #000000;
 331.443 +  margin-bottom: 12pt;
 331.444 +  padding: 0;
 331.445 +}
 331.446 +.sidebarSection .sidebarHead {
 331.447 +  padding: 9px 9px 4.5px 9px;
 331.448 +  background: #ffffff;
 331.449 +  color: #000000;
 331.450 +  min-height: 20px;
 331.451 +}
 331.452 +.sidebarSection .sidebarHead a {
 331.453 +  color: #000000;
 331.454 +}
 331.455 +.sidebarSection .sidebarHead .icon24 {
 331.456 +  margin-top: -3.6px;
 331.457 +}
 331.458 +.sidebarSection .sidebarRow {
 331.459 +  clear: right;
 331.460 +  display: block;
 331.461 +  border-top: 1px solid #aaaaaa;
 331.462 +  padding: 4.5px 9px;
 331.463 +  min-height: 20px;
 331.464 +}
 331.465 +.sidebarSection .sidebarRow.highlighted {
 331.466 +  background-color: #e7f0ff;
 331.467 +}
 331.468 +.sidebarSection .sidebarRow.sidebarRowNarrow {
 331.469 +  padding: 2.25px 9px;
 331.470 +}
 331.471 +.sidebarSection .sidebarRow.moreLink {
 331.472 +  min-height: 0;
 331.473 +}
 331.474 +.sidebarSection h1,
 331.475 +.sidebarSection h1 a,
 331.476 +.sidebarSection h2,
 331.477 +.sidebarSection h2 a,
 331.478 +.sidebarSection h3,
 331.479 +.sidebarSection h3 a {
 331.480 +  color: #000000;
 331.481 +}
 331.482 +.sidebarSection a {
 331.483 +  color: #222277;
 331.484 +}
 331.485 +.sidebarSection .areas .whenfolded {
 331.486 +  display: none;
 331.487 +}
 331.488 +.sidebarSection .areas.folded .whenunfolded {
 331.489 +  display: none;
 331.490 +}
 331.491 +.sidebarSection .areas.folded .whenfolded {
 331.492 +  display: block;
 331.493 +}
 331.494 +.sidebarSection .areas.folded .disabled {
 331.495 +  display: none;
 331.496 +}
 331.497 +.sidebarSection a.issue {
 331.498 +  font: bold 12pt / 125% sans-serif;
 331.499 +  color: #000000;
 331.500 +}
 331.501 +.sidebarSection ul.initiatives li {
 331.502 +  padding: 4.5px 9px;
 331.503 +  border-top: 1px solid #aaaaaa;
 331.504 +}
 331.505 +.sidebarSection ul.initiatives li .bargraph {
 331.506 +  display: block;
 331.507 +}
 331.508 +.sidebarSection ul.initiatives li .supporterCount {
 331.509 +  white-space: nowrap;
 331.510 +}
 331.511 +.sidebarSection ul.initiatives .revoked .initiative_name {
 331.512 +  text-decoration: line-through;
 331.513 +}
 331.514 +.sidebarSection ul.initiatives li.highlighted {
 331.515 +  background-color: #e7f0ff;
 331.516 +}
 331.517 +.sidebarSection ul.initiatives li.highlighted:last-child {
 331.518 +  border-radius: 0 0 2px 2px;
 331.519 +}
 331.520 +.sidebarSection .supporters {
 331.521 +  line-height: 28.799999999999997px;
 331.522 +}
 331.523 +.sidebarSection .supportCount {
 331.524 +  color: #00c000;
 331.525 +  font: bold 12pt / 125% sans-serif;
 331.526 +  float: right;
 331.527 +}
 331.528 +.sidebarSection .member_list .member_thumb {
 331.529 +  white-space: nowrap;
 331.530 +  overflow: hidden;
 331.531 +  text-overflow: ellipsis;
 331.532 +}
 331.533 +.sidebarSection .member_list .member_thumb img.member_image {
 331.534 +  width: 24px;
 331.535 +  height: 24px;
 331.536 +  vertical-align: middle;
 331.537 +  margin-right: 0.2em;
 331.538 +}
 331.539 +.sidebarSection .member_list .member_thumb.in_delegation_chain {
 331.540 +  font-weight: bold;
 331.541 +}
 331.542 +.sidebarSection > div {
 331.543 +  position: relative;
 331.544 +}
 331.545 +.sidebarSection > div:first-child {
 331.546 +  margin-top: 0;
 331.547 +  border-radius: 2px 2px 0 0;
 331.548 +}
 331.549 +.sidebarSection > div:last-child {
 331.550 +  border-radius: 0 0 2px 2px;
 331.551 +}
 331.552 +.sidebarSection > div:last-child:first-child {
 331.553 +  border-radius: 2px;
 331.554 +}
 331.555 +.sidebarSection a.unit {
 331.556 +  font: normal 12pt / 125% sans-serif;
 331.557 +}
 331.558 +.sidebarSection a.area {
 331.559 +  margin-left: 25px;
 331.560 +  display: block;
 331.561 +}
 331.562 +.sidebarSection .star {
 331.563 +  float: left;
 331.564 +}
 331.565 +.sidebarSection .delegation_info {
 331.566 +  margin-top: -3.6px;
 331.567 +  margin-bottom: 1px;
 331.568 +}
 331.569 +.admitted_info h1 {
 331.570 +  color: #00aa00;
 331.571 +}
 331.572 +.not_admitted_info h1,
 331.573 +.revoked_info h1 {
 331.574 +  color: #aa0000;
 331.575 +}
 331.576 +.admitted_info .initiative_pie,
 331.577 +.not_admitted_info .initiative_pie {
 331.578 +  float: right;
 331.579 +}
 331.580 +.admitted_info table tr th,
 331.581 +.not_admitted_info table tr th {
 331.582 +  text-align: left;
 331.583 +}
 331.584 +.admitted_info table tr td,
 331.585 +.not_admitted_info table tr td {
 331.586 +  text-align: right;
 331.587 +  padding: 0.3ex 0.4em;
 331.588 +}
 331.589 +/*
 331.590 + * main area
 331.591 + */
 331.592 +.main_outer {
 331.593 +  width: 70%;
 331.594 +}
 331.595 +.main {
 331.596 +  clear: left;
 331.597 +  margin-right: 12pt;
 331.598 +  border-radius: 2px;
 331.599 +  /*
 331.600 +   * tabs und filter
 331.601 +   */
 331.602 +  /*
 331.603 +   * initiative
 331.604 +   */
 331.605 +  /* the draft */
 331.606 +}
 331.607 +.main .section .sectionHead,
 331.608 +.main .section .sectionRow {
 331.609 +  background-color: #ffffff;
 331.610 +  overflow: auto;
 331.611 +  padding: 9px;
 331.612 +}
 331.613 +.main .section .sectionHead {
 331.614 +  background-color: #ffffff;
 331.615 +  color: #000000;
 331.616 +  margin-top: 12pt;
 331.617 +  border-radius: 2px 2px 0 0;
 331.618 +}
 331.619 +.main .section .sectionHead:first-child {
 331.620 +  margin-top: 0;
 331.621 +}
 331.622 +.main .section .sectionHead:last-child {
 331.623 +  border-radius: 2px;
 331.624 +}
 331.625 +.main .section .sectionRow {
 331.626 +  margin-top: 4px;
 331.627 +}
 331.628 +.main .section .sectionRow:last-child {
 331.629 +  border-radius: 0 0 2px 2px;
 331.630 +  margin-bottom: 12pt;
 331.631 +}
 331.632 +.main > h1 {
 331.633 +  border-bottom: 1px solid #aaaaaa;
 331.634 +  padding: 9px;
 331.635 +}
 331.636 +.main .ui_filter .ui_filter_head {
 331.637 +  background: #ffffff;
 331.638 +  color: #000000;
 331.639 +  padding: 0 9px 9px 9px;
 331.640 +  vertical-align: middle;
 331.641 +}
 331.642 +.main .ui_filter .ui_filter_head a {
 331.643 +  white-space: nowrap;
 331.644 +  font: normal 10pt / 150% sans-serif;
 331.645 +  margin-right: 0.5em;
 331.646 +}
 331.647 +.main .ui_filter .ui_filter_head a.active {
 331.648 +  font: bold 10pt / 150% sans-serif;
 331.649 +  text-decoration: none;
 331.650 +  color: #000000;
 331.651 +}
 331.652 +.main .ui_filter .ui_filter_head select {
 331.653 +  background: #ffffff;
 331.654 +  color: #444444;
 331.655 +  font: normal 10pt / 150% sans-serif;
 331.656 +  border: none;
 331.657 +  padding: 0;
 331.658 +  margin: 0;
 331.659 +}
 331.660 +.main .ui_filter .ui_filter_head select option {
 331.661 +  color: #000000;
 331.662 +}
 331.663 +.main .ui_filter .ui_filter_head select option:first-child,
 331.664 +.main .ui_filter .ui_filter_head select option[value="interest_direct"],
 331.665 +.main .ui_filter .ui_filter_head select option[value="interest_delegated"],
 331.666 +.main .ui_filter .ui_filter_head select option[value="support_direct"],
 331.667 +.main .ui_filter .ui_filter_head select option[value="support_delegated"],
 331.668 +.main .ui_filter .ui_filter_head select option[value="potential_support_direct"],
 331.669 +.main .ui_filter .ui_filter_head select option[value="potential_support_delegated"] {
 331.670 +  color: #444444;
 331.671 +}
 331.672 +.main .ui_filter .ui_filter_head select.active {
 331.673 +  color: #000000;
 331.674 +}
 331.675 +.main .ui_filter .ui_filter_head:first-child {
 331.676 +  border-radius: 2px 2px 0 0;
 331.677 +  padding-top: 9px;
 331.678 +}
 331.679 +.main .ui_filter .ui_filter_head.filter_filter {
 331.680 +  padding-top: 9px;
 331.681 +}
 331.682 +.main .ui_filter .ui_filter_head.filter_mode {
 331.683 +  padding-top: 9px;
 331.684 +  margin-bottom: 0;
 331.685 +  padding-bottom: 0;
 331.686 +}
 331.687 +.main .ui_filter .ui_filter_head.subfilter a {
 331.688 +  font: normal 10pt / 150% sans-serif;
 331.689 +}
 331.690 +.main .ui_filter .ui_filter_head.subfilter a.active {
 331.691 +  font: bold 10pt / 150% sans-serif;
 331.692 +}
 331.693 +.main .filter {
 331.694 +  float: right;
 331.695 +}
 331.696 +.main .delegation_info.suspended {
 331.697 +  margin: 1ex -2px -2px -2px;
 331.698 +}
 331.699 +.main .issues .state_info {
 331.700 +  font: bold 10pt / 125% sans-serif;
 331.701 +  color: #007700;
 331.702 +}
 331.703 +.main .issues .state_info.negative {
 331.704 +  color: #aa0000;
 331.705 +}
 331.706 +.main ul.initiatives li {
 331.707 +  margin-top: 1ex;
 331.708 +}
 331.709 +.main ul.initiatives li .bargraph {
 331.710 +  float: left;
 331.711 +  margin-top: 5px;
 331.712 +  margin-right: 0.5em;
 331.713 +}
 331.714 +.main ul.initiatives li .initiative_name {
 331.715 +  display: block;
 331.716 +  margin-left: 110px;
 331.717 +}
 331.718 +.main ul.initiatives li .rank1 .initiative_name {
 331.719 +  margin-left: 0;
 331.720 +}
 331.721 +.main ul.initiatives li .revoked .initiative_name {
 331.722 +  text-decoration: line-through;
 331.723 +}
 331.724 +.main ul.initiatives li:first-child {
 331.725 +  margin-top: 0;
 331.726 +  clear: none;
 331.727 +}
 331.728 +.main .events .event ul.initiatives li .initiative_name {
 331.729 +  margin-left: 0;
 331.730 +}
 331.731 +.main .member_photo {
 331.732 +  float: right;
 331.733 +}
 331.734 +.main .member_thumb.in_delegation_chain {
 331.735 +  font-weight: bold;
 331.736 +}
 331.737 +.main .support {
 331.738 +  color: #aaa;
 331.739 +  line-height: 80%;
 331.740 +  float: right;
 331.741 +  width: 102px;
 331.742 +}
 331.743 +.main .initiativeInfo {
 331.744 +  font-family: normal 10pt / 125% sans-serif;
 331.745 +  line-height: 24px;
 331.746 +  overflow: auto;
 331.747 +}
 331.748 +.main .initiativeInfo .support {
 331.749 +  margin-top: 1ex;
 331.750 +  float: left;
 331.751 +  width: auto;
 331.752 +}
 331.753 +.main .initiativeInfo .mySupport {
 331.754 +  line-height: 125%;
 331.755 +  min-width: 12em;
 331.756 +  text-align: right;
 331.757 +}
 331.758 +.main .initiativeInfo .initiators {
 331.759 +  margin-top: 1.5ex;
 331.760 +  margin-bottom: -1ex;
 331.761 +  float: left;
 331.762 +}
 331.763 +.main .initiativeInfo .links {
 331.764 +  margin-top: 1.5ex;
 331.765 +  margin-bottom: -1ex;
 331.766 +  float: right;
 331.767 +  clear: right;
 331.768 +}
 331.769 +.main .initiativeInfo .initiator_links {
 331.770 +  clear: right;
 331.771 +}
 331.772 +.main .issueInfo .links {
 331.773 +  margin-top: 1.5ex;
 331.774 +  margin-bottom: -1ex;
 331.775 +  float: right;
 331.776 +  clear: both;
 331.777 +}
 331.778 +.main .draft_updated_info {
 331.779 +  color: #007700;
 331.780 +}
 331.781 +.main .draft_updated_info .info {
 331.782 +  font: bold 10pt / 125% sans-serif;
 331.783 +}
 331.784 +.main .draft {
 331.785 +  font: normal 10pt / 125% sans-serif;
 331.786 +}
 331.787 +.main .draft ul {
 331.788 +  margin-left: 1em;
 331.789 +  margin-bottom: 1.5ex;
 331.790 +  list-style: square;
 331.791 +  padding-left: 1em;
 331.792 +}
 331.793 +.main .draft h1 {
 331.794 +  font: italic 10pt / 125% sans-serif;
 331.795 +  font-size: 125%;
 331.796 +  border-bottom: 1px solid #444444;
 331.797 +  margin-bottom: 1ex;
 331.798 +}
 331.799 +.main .draft h2 {
 331.800 +  font: normal 10pt / 125% sans-serif;
 331.801 +  font-size: 125%;
 331.802 +}
 331.803 +.main .draft h3 {
 331.804 +  font: normal 10pt / 125% sans-serif;
 331.805 +  font-size: 125%;
 331.806 +}
 331.807 +.main .draft h4 {
 331.808 +  font: normal 10pt / 125% sans-serif;
 331.809 +}
 331.810 +.main .draft hr {
 331.811 +  border: none;
 331.812 +  border-top: 1px solid #000000;
 331.813 +}
 331.814 +.main .draft b,
 331.815 +.main .draft strong {
 331.816 +  font: italic 10pt / 125% sans-serif;
 331.817 +}
 331.818 +.main .draft i,
 331.819 +.main .draft em {
 331.820 +  font: normal 10pt / 125% sans-serif;
 331.821 +}
 331.822 +.main form,
 331.823 +.main .form {
 331.824 +  margin: 0;
 331.825 +  padding: 0;
 331.826 +}
 331.827 +.main form .ui_field_label,
 331.828 +.main .form .ui_field_label {
 331.829 +  display: inline-block;
 331.830 +  width: 25%;
 331.831 +  margin: 0;
 331.832 +  padding: 0;
 331.833 +  text-align: right;
 331.834 +  margin-bottom: 9px;
 331.835 +  padding-right: 0.5%;
 331.836 +  vertical-align: top;
 331.837 +  color: #444444;
 331.838 +}
 331.839 +.main form input[type=text],
 331.840 +.main .form input[type=text],
 331.841 +.main form input[type=password],
 331.842 +.main .form input[type=password],
 331.843 +.main form select,
 331.844 +.main .form select,
 331.845 +.main form textarea,
 331.846 +.main .form textarea {
 331.847 +  vertical-align: top;
 331.848 +  width: 73%;
 331.849 +  margin: 0;
 331.850 +  padding: 3px;
 331.851 +  border: 1px solid #444444;
 331.852 +  font: bold 10pt / 125% sans-serif;
 331.853 +  margin-bottom: 9px;
 331.854 +}
 331.855 +.main form input:focus,
 331.856 +.main .form input:focus {
 331.857 +  outline: 2px solid #397ab6;
 331.858 +}
 331.859 +.main form .actions,
 331.860 +.main .form .actions {
 331.861 +  margin-left: 26%;
 331.862 +}
 331.863 +.main form.wide input[type=text],
 331.864 +.main form.wide input[type=password],
 331.865 +.main form.wide select,
 331.866 +.main form.wide textarea {
 331.867 +  width: 100%;
 331.868 +}
 331.869 +.issues .event .initiative_pie,
 331.870 +.events .event .initiative_pie {
 331.871 +  clear: right;
 331.872 +  float: right;
 331.873 +}
 331.874 +.issues .event ul.initiatives .initiative_info_left,
 331.875 +.events .event ul.initiatives .initiative_info_left {
 331.876 +  display: inline;
 331.877 +  margin-right: 0.5em;
 331.878 +}
 331.879 +.issues .event ul.initiatives .initiative_info_right,
 331.880 +.events .event ul.initiatives .initiative_info_right {
 331.881 +  float: right;
 331.882 +}
 331.883 +.issues .event ul.initiatives .initiative_info_right .bargraph,
 331.884 +.events .event ul.initiatives .initiative_info_right .bargraph {
 331.885 +  float: right;
 331.886 +  margin-left: 0.5em;
 331.887 +}
 331.888 +.issues .event ul.initiatives .result,
 331.889 +.events .event ul.initiatives .result {
 331.890 +  color: #444444;
 331.891 +  margin-top: 0.5ex;
 331.892 +}
 331.893 +.issues .event ul.initiatives h3,
 331.894 +.events .event ul.initiatives h3 {
 331.895 +  margin-top: 1ex;
 331.896 +  margin-bottom: 0;
 331.897 +}
 331.898 +.issues .event ul.initiatives a.initiative,
 331.899 +.events .event ul.initiatives a.initiative {
 331.900 +  font: bold 10pt / 125% sans-serif;
 331.901 +}
 331.902 +.issues .event .event_info,
 331.903 +.events .event .event_info {
 331.904 +  font: bold 10pt / 125% sans-serif;
 331.905 +  color: #007700;
 331.906 +  margin-top: 0.66ex;
 331.907 +  margin-bottom: 1ex;
 331.908 +}
 331.909 +.issues .event .event_info:last-child,
 331.910 +.events .event .event_info:last-child {
 331.911 +  margin-bottom: 0;
 331.912 +}
 331.913 +.issues .event .event_info.negative,
 331.914 +.events .event .event_info.negative {
 331.915 +  color: #aa0000;
 331.916 +}
 331.917 +.issues .event .event_time,
 331.918 +.events .event .event_time {
 331.919 +  font: normal 10pt / 125% sans-serif;
 331.920 +  color: #444444;
 331.921 +}
 331.922 +.issues .event:hover .event_time,
 331.923 +.events .event:hover .event_time {
 331.924 +  visibility: visible;
 331.925 +}
 331.926 +.issues .event:hover ul.initiatives div,
 331.927 +.events .event:hover ul.initiatives div {
 331.928 +  visibility: visible;
 331.929 +}
 331.930 +.issues .issue_context,
 331.931 +.events .issue_context {
 331.932 +  line-height: 24px;
 331.933 +  margin-bottom: 0.66ex;
 331.934 +}
 331.935 +.issues .issue_context .unit,
 331.936 +.events .issue_context .unit {
 331.937 +  background-color: #777;
 331.938 +  color: #fff;
 331.939 +  padding: 1px 3px;
 331.940 +  border-radius: 2px;
 331.941 +  text-decoration: none;
 331.942 +}
 331.943 +.issues .issue_context .area,
 331.944 +.events .issue_context .area {
 331.945 +  background-color: #ddd;
 331.946 +  color: #000;
 331.947 +  padding: 1px 3px;
 331.948 +  border-radius: 2px;
 331.949 +  text-decoration: none;
 331.950 +}
 331.951 +.issues .issue_info .issue,
 331.952 +.events .issue_info .issue {
 331.953 +  font: bold 10pt / 125% sans-serif;
 331.954 +  color: #000000;
 331.955 +}
 331.956 +.issues img.star,
 331.957 +.events img.star {
 331.958 +  vertical-align: middle;
 331.959 +  float: right;
 331.960 +  margin-left: 0.5em;
 331.961 +}
 331.962 +.issues .event.suggestion ul.initiatives li,
 331.963 +.events .event.suggestion ul.initiatives li {
 331.964 +  margin-top: 0;
 331.965 +  margin-bottom: 1ex;
 331.966 +}
 331.967 +.issues .event.suggestion ul.initiatives li a,
 331.968 +.events .event.suggestion ul.initiatives li a {
 331.969 +  font: normal 10pt / 125% sans-serif;
 331.970 +}
 331.971 +.issues .event.suggestion .suggestion,
 331.972 +.events .event.suggestion .suggestion {
 331.973 +  font: bold 10pt / 125% sans-serif;
 331.974 +  overflow: hidden;
 331.975 +  text-overflow: ellipsis;
 331.976 +}
 331.977 +.suggestions .suggestion .opinion {
 331.978 +  float: right;
 331.979 +}
 331.980 +.suggestions .suggestion .opinion .must {
 331.981 +  background-color: #00cc00;
 331.982 +  color: #ffffff;
 331.983 +}
 331.984 +.suggestions .suggestion .opinion .should {
 331.985 +  background-color: #44aa44;
 331.986 +  color: #ffffff;
 331.987 +}
 331.988 +.suggestions .suggestion .opinion .shouldnot {
 331.989 +  background-color: #aa4444;
 331.990 +  color: #ffffff;
 331.991 +}
 331.992 +.suggestions .suggestion .opinion .mustnot {
 331.993 +  background-color: #cc0000;
 331.994 +  color: #ffffff;
 331.995 +}
 331.996 +.suggestions .suggestion .opinion .implemented {
 331.997 +  background-color: #00cc00;
 331.998 +  color: #ffffff;
 331.999 +}
331.1000 +.suggestions .suggestion .opinion .notimplemented {
331.1001 +  background-color: #cc0000;
331.1002 +  color: #ffffff;
331.1003 +}
331.1004 +.suggestions .suggestion .suggestion-rating {
331.1005 +  float: right;
331.1006 +}
331.1007 +.suggestions .suggestion .suggestion-text {
331.1008 +  margin-top: 9px;
331.1009 +  font: normal 10pt / 125% sans-serif;
331.1010 +  overflow: hidden;
331.1011 +  text-overflow: ellipsis;
331.1012 +  position: relative;
331.1013 +  z-index: 10;
331.1014 +}
331.1015 +.suggestions .suggestion .suggestion-more {
331.1016 +  display: none;
331.1017 +}
331.1018 +.suggestions .suggestion .suggestion-less {
331.1019 +  display: none;
331.1020 +}
331.1021 +.suggestions .suggestion .suggestionHead {
331.1022 +  overflow: hidden;
331.1023 +  text-overflow: ellipsis;
331.1024 +}
331.1025 +.suggestions .suggestion .rating {
331.1026 +  display: none;
331.1027 +  padding: 4.5px 0;
331.1028 +}
331.1029 +.suggestions .suggestion .rating .active-plus2 {
331.1030 +  background-color: #00cc00;
331.1031 +  color: #ffffff;
331.1032 +}
331.1033 +.suggestions .suggestion .rating .active-plus1 {
331.1034 +  background-color: #44aa44;
331.1035 +  color: #ffffff;
331.1036 +}
331.1037 +.suggestions .suggestion .rating .active-minus1 {
331.1038 +  background-color: #aa4444;
331.1039 +  color: #ffffff;
331.1040 +}
331.1041 +.suggestions .suggestion .rating .active-minus2 {
331.1042 +  background-color: #cc0000;
331.1043 +  color: #ffffff;
331.1044 +}
331.1045 +.suggestions .suggestion .rating .active-notfulfilled {
331.1046 +  background-color: #faa;
331.1047 +}
331.1048 +.suggestions .suggestion .rating .active-fulfilled {
331.1049 +  background-color: #afa;
331.1050 +}
331.1051 +.suggestions .suggestion.rateable .suggestion-more {
331.1052 +  display: block;
331.1053 +}
331.1054 +.suggestions .suggestion.rateable.unfolded .rating {
331.1055 +  border-top: 3px solid #397ab6;
331.1056 +}
331.1057 +.suggestions .suggestion.folded .suggestion-more {
331.1058 +  display: block;
331.1059 +  position: absolute;
331.1060 +  bottom: 0;
331.1061 +  left: 0;
331.1062 +  width: 100%;
331.1063 +  box-shadow: inset 0 -12ex 10ex -5ex #ffffff;
331.1064 +  padding-top: 5ex;
331.1065 +}
331.1066 +.suggestions .suggestion.unfolded .suggestion-more {
331.1067 +  display: none;
331.1068 +}
331.1069 +.suggestions .suggestion.unfolded .rating {
331.1070 +  display: block;
331.1071 +}
331.1072 +.suggestions .suggestion.unfolded .suggestion-less {
331.1073 +  margin-top: 1ex;
331.1074 +  display: block;
331.1075 +}
331.1076 +.suggestions .suggestion.highlighted {
331.1077 +  background-color: #e7f0ff;
331.1078 +}
331.1079 +.suggestions .suggestion.highlighted .suggestion-more {
331.1080 +  box-shadow: inset 0 -12ex 10ex -5ex #e7f0ff;
331.1081 +}
331.1082 +li.raw {
331.1083 +  list-style: none;
331.1084 +  padding: 0;
331.1085 +  margin: 0 !important;
331.1086 +}
331.1087 +.satisfiedSupporterCount {
331.1088 +  color: #070;
331.1089 +}
331.1090 +.potentialSupporterCount {
331.1091 +  color: #960;
331.1092 +}
331.1093 +.bargraph {
331.1094 +  display: inline-block;
331.1095 +  vertical-align: top;
331.1096 +  height: 9px;
331.1097 +}
331.1098 +.bargraph div {
331.1099 +  margin: 0;
331.1100 +  padding: 0;
331.1101 +  display: inline-block;
331.1102 +  height: 9px;
331.1103 +}
331.1104 +.diff .diff_added {
331.1105 +  background-color: #cfc;
331.1106 +}
331.1107 +.diff .diff_removed {
331.1108 +  text-decoration: line-through;
331.1109 +  background-color: #fcc;
331.1110 +}
331.1111 +.btn,
331.1112 +.ui_paginate_foot a {
331.1113 +  text-decoration: none;
331.1114 +  min-width: 2em;
331.1115 +  text-align: center;
331.1116 +  display: inline-block;
331.1117 +  border-radius: 5px;
331.1118 +  border: none;
331.1119 +  font: bold 10pt / 125% sans-serif;
331.1120 +  background-color: #999;
331.1121 +  color: #fff !important;
331.1122 +  margin-bottom: 5px;
331.1123 +}
331.1124 +.btn {
331.1125 +  padding: 1ex 1em;
331.1126 +}
331.1127 +.ui_paginate_foot a {
331.1128 +  padding: 0.5ex 0.5em;
331.1129 +  background-color: #eee;
331.1130 +  color: 000 !important;
331.1131 +}
331.1132 +.ui_paginate_foot a.active {
331.1133 +  background-color: #666;
331.1134 +  color: #fff !important;
331.1135 +}
331.1136 +.btn-default {
331.1137 +  background-color: #47a;
331.1138 +  color: #fff !important;
331.1139 +}
331.1140 +.btn:hover,
331.1141 +.btn:focus,
331.1142 +.ui_paginate_foot a:hover,
331.1143 +.ui_paginate_foot a:focus {
331.1144 +  background-color: #0a0;
331.1145 +  color: #fff !important;
331.1146 +  cursor: pointer;
331.1147 +}
331.1148 +.btn-dangerous:hover {
331.1149 +  background-color: #c00;
331.1150 +  color: #fff !important;
331.1151 +}
331.1152 +.btn-link {
331.1153 +  font: normal 10pt / 125% sans-serif;
331.1154 +  background-color: #ffffff;
331.1155 +  color: #222277;
331.1156 +  border: none;
331.1157 +  padding: 0;
331.1158 +  margin: 0;
331.1159 +  text-decoration: underline;
331.1160 +  cursor: pointer;
331.1161 +}
331.1162 +/*************************************************************************
331.1163 + * Voting
331.1164 + */
331.1165 +.main .section #voting_form .sectionRow:last-child {
331.1166 +  border-radius: 0;
331.1167 +  margin-bottom: 0;
331.1168 +}
331.1169 +#voting {
331.1170 +  background: #ddd;
331.1171 +  padding: 9px;
331.1172 +  margin-top: 4px;
331.1173 +  position: relative;
331.1174 +  margin-bottom: 2ex;
331.1175 +}
331.1176 +#voting .approval,
331.1177 +#voting .abstention,
331.1178 +#voting .disapproval {
331.1179 +  border: 2px black solid;
331.1180 +  margin-bottom: 2ex;
331.1181 +  padding: 1ex;
331.1182 +  padding-bottom: 2ex;
331.1183 +  border-radius: 2px;
331.1184 +}
331.1185 +#voting .disapproval {
331.1186 +  margin-bottom: 2ex;
331.1187 +}
331.1188 +#voting .approval {
331.1189 +  background-color: #9f9;
331.1190 +}
331.1191 +#voting .approval .movable {
331.1192 +  background-color: #dfd;
331.1193 +}
331.1194 +#voting .abstention {
331.1195 +  background-color: #ccc;
331.1196 +}
331.1197 +#voting .abstention .movable {
331.1198 +  background-color: #f2f2f2;
331.1199 +}
331.1200 +#voting .disapproval {
331.1201 +  background-color: #f88;
331.1202 +}
331.1203 +#voting .disapproval .movable {
331.1204 +  background-color: #fbb;
331.1205 +}
331.1206 +#voting .movable {
331.1207 +  position: relative;
331.1208 +  border: 1px black solid;
331.1209 +  margin-top: 1ex;
331.1210 +  padding: 0.5ex;
331.1211 +  border-radius: 2px;
331.1212 +}
331.1213 +#voting .voting_form_active .movable {
331.1214 +  cursor: pointer;
331.1215 +  vertical-align: middle;
331.1216 +  cursor: move;
331.1217 +}
331.1218 +#voting .voting_form_active .clickable {
331.1219 +  cursor: auto;
331.1220 +}
331.1221 +#voting .voting_form_active a.clickable {
331.1222 +  cursor: pointer;
331.1223 +}
331.1224 +/*
331.1225 + * footer
331.1226 + */
331.1227 +.footer {
331.1228 +  text-align: center;
331.1229 +  color: #ffffff;
331.1230 +  background-color: #000000;
331.1231 +  padding: 9px 0;
331.1232 +  border: 1px solid #000;
331.1233 +  border-top: none;
331.1234 +}
331.1235 +.footer a {
331.1236 +  color: #ffffff;
331.1237 +}
331.1238 +.ui_paginate_head {
331.1239 +  display: none;
331.1240 +}
331.1241 +.ui_paginate_foot {
331.1242 +  line-height: 180%;
331.1243 +}
331.1244 +.swiper_tabs {
331.1245 +  display: none;
331.1246 +}
331.1247 +#swiper_info {
331.1248 +  display: none;
331.1249 +}
331.1250 +.nav .searchLink {
331.1251 +  display: none;
331.1252 +}
331.1253 +@media (max-width: 767px) {
331.1254 +  html body {
331.1255 +    margin: 0;
331.1256 +    background: #255078;
331.1257 +  }
331.1258 +  html body .head {
331.1259 +    margin: 6pt;
331.1260 +    padding: 0;
331.1261 +  }
331.1262 +  html body .head .logo {
331.1263 +    display: block;
331.1264 +    padding: 0;
331.1265 +  }
331.1266 +  html body .head .logo .liquid,
331.1267 +  html body .head .logo .feedback {
331.1268 +    font: bold 12pt / 125% sans-serif;
331.1269 +  }
331.1270 +  html body .head .logo .instanceName {
331.1271 +    font: normal 10pt / 100% sans-serif;
331.1272 +    display: block;
331.1273 +    margin-left: 0;
331.1274 +  }
331.1275 +  html body .head .nav {
331.1276 +    padding: 0;
331.1277 +  }
331.1278 +  html body .initiativeInfo h1 {
331.1279 +    display: none;
331.1280 +  }
331.1281 +  html body .slot_title {
331.1282 +    font: normal 12pt / 125% sans-serif;
331.1283 +    padding: 0;
331.1284 +    margin: 0 6pt;
331.1285 +  }
331.1286 +  html body .slot_title .spacer {
331.1287 +    display: none;
331.1288 +  }
331.1289 +  html body .slot_title .unit,
331.1290 +  html body .slot_title .area,
331.1291 +  html body .slot_title .issue,
331.1292 +  html body .slot_title .initiative,
331.1293 +  html body .slot_title .member {
331.1294 +    display: block;
331.1295 +    margin-right: 0;
331.1296 +    padding: 4px 0;
331.1297 +    border-radius: 2px;
331.1298 +    overflow: auto;
331.1299 +  }
331.1300 +  html body .slot_title .unit:before,
331.1301 +  html body .slot_title .area:before,
331.1302 +  html body .slot_title .issue:before,
331.1303 +  html body .slot_title .initiative:before,
331.1304 +  html body .slot_title .member:before {
331.1305 +    content: "↳";
331.1306 +    position: relative;
331.1307 +    top: -2px;
331.1308 +  }
331.1309 +  html body .slot_title .area {
331.1310 +    margin-left: 10px;
331.1311 +  }
331.1312 +  html body .slot_title .issue {
331.1313 +    margin-left: 20px;
331.1314 +  }
331.1315 +  html body .slot_title .initiative {
331.1316 +    margin-left: 30px;
331.1317 +  }
331.1318 +  html body .slot_title a:last-child,
331.1319 +  html body .slot_title .issue:last-child,
331.1320 +  html body .slot_title .area:last-child,
331.1321 +  html body .slot_title .unit:last-child,
331.1322 +  html body .slot_title .initiative:last-child {
331.1323 +    margin-bottom: 6pt;
331.1324 +  }
331.1325 +  html body .slot_title .unit a,
331.1326 +  html body .slot_title .initiative a,
331.1327 +  html body .slot_title .issue a,
331.1328 +  html body .slot_title .area a {
331.1329 +    margin-bottom: 0;
331.1330 +    display: inline;
331.1331 +  }
331.1332 +  html body .slot_title a.home {
331.1333 +    display: none;
331.1334 +  }
331.1335 +  html body .slot_title .weight {
331.1336 +    float: right;
331.1337 +    margin: 0;
331.1338 +  }
331.1339 +  html body .slot_title .delegation_info {
331.1340 +    float: right;
331.1341 +    display: block;
331.1342 +    margin-top: -10px;
331.1343 +  }
331.1344 +  html body .slot_title a .label {
331.1345 +    display: inline;
331.1346 +  }
331.1347 +  html body .slot_title .star {
331.1348 +    float: right;
331.1349 +    margin-left: 0.5em;
331.1350 +    margin-top: -4.5px;
331.1351 +    margin-bottom: -4.5px;
331.1352 +  }
331.1353 +  html body .slot_title > span > *:last-child {
331.1354 +    font: bold 12pt / 125% sans-serif;
331.1355 +  }
331.1356 +  html body .page {
331.1357 +    background: none;
331.1358 +    margin: 0;
331.1359 +    box-shadow: none;
331.1360 +  }
331.1361 +  html body .nav #member_menu .text {
331.1362 +    display: none;
331.1363 +  }
331.1364 +  html body .nav form.search {
331.1365 +    display: none;
331.1366 +  }
331.1367 +  html body .nav .notifications,
331.1368 +  html body .nav .searchLink,
331.1369 +  html body .nav #member_menu a {
331.1370 +    vertical-align: middle;
331.1371 +    display: inline-block;
331.1372 +    height: 48px;
331.1373 +    min-width: 35px;
331.1374 +    text-align: center;
331.1375 +    background-color: #000;
331.1376 +    border: 1px solid #777;
331.1377 +    border-radius: 2px;
331.1378 +    margin: 0;
331.1379 +  }
331.1380 +  html body .nav .notifications img,
331.1381 +  html body .nav .searchLink img,
331.1382 +  html body .nav #member_menu a img {
331.1383 +    margin: 0;
331.1384 +    width: 48px;
331.1385 +    height: 48px;
331.1386 +  }
331.1387 +  html body .nav .notifications {
331.1388 +    padding: 12px 2px;
331.1389 +    height: 24px;
331.1390 +  }
331.1391 +  html body .nav #member_menu a :last-child {
331.1392 +    display: none;
331.1393 +  }
331.1394 +  html body .notifications span {
331.1395 +    margin-left: -5px;
331.1396 +  }
331.1397 +  html body .swiper_tabs {
331.1398 +    clear: both;
331.1399 +    display: block;
331.1400 +    overflow: auto;
331.1401 +    margin: 6pt;
331.1402 +  }
331.1403 +  html body .swiper_tabs div {
331.1404 +    display: block;
331.1405 +    float: left;
331.1406 +    width: 33.333%;
331.1407 +  }
331.1408 +  html body .swiper_tabs div a {
331.1409 +    padding: 8px 0;
331.1410 +    display: block;
331.1411 +    text-align: center;
331.1412 +    background-color: #eee;
331.1413 +  }
331.1414 +  html body .swiper_tabs div a.active {
331.1415 +    background-color: #abe;
331.1416 +  }
331.1417 +  html body .swiper_tabs div:first-child a {
331.1418 +    border-radius: 2px 0 0 2px;
331.1419 +  }
331.1420 +  html body .swiper_tabs div:last-child a {
331.1421 +    border-radius: 0 2px 2px 0;
331.1422 +  }
331.1423 +  html body #swiper_info.active {
331.1424 +    display: block;
331.1425 +    font: bold 10pt / 125% sans-serif;
331.1426 +    z-index: 1;
331.1427 +    text-align: center;
331.1428 +    width: 100%;
331.1429 +    background-color: #255078;
331.1430 +    color: #ffffff;
331.1431 +  }
331.1432 +  html body .sidebarSection {
331.1433 +    margin: 0 6pt 6pt 6pt;
331.1434 +  }
331.1435 +  html body .main,
331.1436 +  html body .extra > .section {
331.1437 +    clear: none;
331.1438 +    float: none;
331.1439 +    width: auto;
331.1440 +    margin: 0 6pt 6pt 6pt;
331.1441 +  }
331.1442 +  html body .main .section .sectionRow:last-child,
331.1443 +  html body .extra > .section .section .sectionRow:last-child {
331.1444 +    margin-bottom: 6pt;
331.1445 +  }
331.1446 +  html body .ui_filter_head.filter_mode {
331.1447 +    float: none !important;
331.1448 +    background: #ffffff !important;
331.1449 +    text-align: left !important;
331.1450 +    border-radius: 2px;
331.1451 +    margin-bottom: 6pt !important;
331.1452 +  }
331.1453 +  html body .member_photo {
331.1454 +    text-align: center;
331.1455 +    margin-bottom: 2ex;
331.1456 +  }
331.1457 +  html body .member_photo .member_image_photo {
331.1458 +    max-width: 600px;
331.1459 +  }
331.1460 +  html body #trace_content {
331.1461 +    margin: 6pt 0;
331.1462 +    border-radius: 0;
331.1463 +  }
331.1464 +  html body #trace_content ul li .trace_head {
331.1465 +    padding: 6px 5px;
331.1466 +  }
331.1467 +  html body #trace_content ul ul {
331.1468 +    padding: 5px 2px;
331.1469 +  }
331.1470 +}
331.1471 +.textCenter {
331.1472 +  text-align: center;
331.1473 +}
331.1474 +a.initiative {
331.1475 +  text-decoration: none;
331.1476 +  border-bottom: 1px solid #66c;
331.1477 +}
331.1478 +a.initiative:hover {
331.1479 +  border-bottom: 1px solid #007;
331.1480 +}
331.1481 +#trace_content {
331.1482 +  margin: 12pt;
331.1483 +  padding: 9px;
331.1484 +  border-radius: 2px;
331.1485 +  background-color: #ffffff;
331.1486 +}
331.1487 +#trace_content #system_error {
331.1488 +  font-family: monospace;
331.1489 +}
331.1490 +#trace_content ul li {
331.1491 +  margin-top: 10px;
331.1492 +}
331.1493 +#trace_content ul li .trace_head {
331.1494 +  padding: 3px 5px;
331.1495 +  border-radius: 2px 2px 0 0;
331.1496 +}
331.1497 +#trace_content ul li .trace_head:last-child {
331.1498 +  border-radius: 2px;
331.1499 +}
331.1500 +#trace_content ul li ul {
331.1501 +  border-radius: 0 0 2px 2px;
331.1502 +}
331.1503 +#trace_content ul li:first-child {
331.1504 +  margin-top: 0;
331.1505 +}
331.1506 +#trace_content ul ul {
331.1507 +  padding: 10px;
331.1508 +}
331.1509 +#trace_content .trace_config > ul {
331.1510 +  background-color: #eee;
331.1511 +  border: 1px solid #ccc;
331.1512 +}
331.1513 +#trace_content .trace_config > .trace_head {
331.1514 +  background-color: #ccc;
331.1515 +  color: #000;
331.1516 +}
331.1517 +#trace_content .trace_request > ul {
331.1518 +  background-color: #afa;
331.1519 +}
331.1520 +#trace_content .trace_request > .trace_head {
331.1521 +  background-color: #0c0;
331.1522 +}
331.1523 +#trace_content .trace_filter > ul {
331.1524 +  background-color: #ccf;
331.1525 +  border: 1px solid #00c;
331.1526 +  border-top: none;
331.1527 +}
331.1528 +#trace_content .trace_filter > .trace_head {
331.1529 +  background-color: #00c;
331.1530 +  color: #fff;
331.1531 +}
331.1532 +#trace_content .trace_view > ul {
331.1533 +  background-color: #cfc;
331.1534 +  border: 1px solid #0c0;
331.1535 +  border-top: none;
331.1536 +}
331.1537 +#trace_content .trace_view > .trace_head {
331.1538 +  background-color: #0c0;
331.1539 +  color: #000;
331.1540 +}
331.1541 +#trace_content .trace_action_neutral > ul {
331.1542 +  background-color: #ffa;
331.1543 +  border: 1px solid #fe0;
331.1544 +}
331.1545 +#trace_content .trace_action_neutral > .trace_head {
331.1546 +  background-color: #fe0;
331.1547 +  color: #000;
331.1548 +}
331.1549 +#trace_content .trace_sql {
331.1550 +  background-color: #fff;
331.1551 +  padding: 2px 4px;
331.1552 +  margin-top: 8px;
331.1553 +}
331.1554 +#trace_content .trace_error {
331.1555 +  background-color: #faa;
331.1556 +  color: #000;
331.1557 +  font-weight: bold;
331.1558 +  border: 1px solid #c00;
331.1559 +}
331.1560 +#trace_content .trace_exectime {
331.1561 +  background-color: #ccc;
331.1562 +  font-weight: bold;
331.1563 +  border-radius: 2px;
331.1564 +}
331.1565 +#trace_content .time {
331.1566 +  float: right;
331.1567 +}
331.1568 +#trace_content .total_duration {
331.1569 +  font-weight: bold;
331.1570 +}
   332.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   332.2 +++ b/static/lf3.less	Thu Jul 10 01:19:48 2014 +0200
   332.3 @@ -0,0 +1,1935 @@
   332.4 +html, body, div, span, applet, object, iframe,
   332.5 +h1, h2, h3, h4, h5, h6, p, blockquote, pre,
   332.6 +a, abbr, acronym, address, big, cite, code,
   332.7 +del, dfn, em, img, ins, kbd, q, s, samp,
   332.8 +small, strike, strong, sub, sup, tt, var,
   332.9 +b, u, i, center,
  332.10 +dl, dt, dd, ol, ul, li,
  332.11 +fieldset, form, label, legend,
  332.12 +table, caption, tbody, tfoot, thead, tr, th, td,
  332.13 +article, aside, canvas, details, embed, 
  332.14 +figure, figcaption, footer, header, hgroup, 
  332.15 +menu, nav, output, ruby, section, summary,
  332.16 +time, mark, audio, video {
  332.17 +        margin: 0;
  332.18 +        padding: 0;
  332.19 +        border: 0;
  332.20 +        font-size: 100%;
  332.21 +        font: inherit;
  332.22 +        vertical-align: baseline;
  332.23 +}
  332.24 +/* HTML5 display-role reset for older browsers */
  332.25 +article, aside, details, figcaption, figure, 
  332.26 +footer, header, hgroup, menu, nav, section {
  332.27 +        display: block;
  332.28 +}
  332.29 +body {
  332.30 +        line-height: 1;
  332.31 +}
  332.32 +ol, ul {
  332.33 +        list-style: none;
  332.34 +}
  332.35 +blockquote, q {
  332.36 +        quotes: none;
  332.37 +}
  332.38 +blockquote:before, blockquote:after,
  332.39 +q:before, q:after {
  332.40 +        content: '';
  332.41 +        content: none;
  332.42 +}
  332.43 +table {
  332.44 +        border-collapse: collapse;
  332.45 +        border-spacing: 0;
  332.46 +}
  332.47 +
  332.48 +/* end reset */
  332.49 +
  332.50 +
  332.51 +/* color, fonts, gaps and border radius settings */
  332.52 +
  332.53 +@body-bg-color: #397ab6;
  332.54 +@body-color: #fff;
  332.55 +@footer-bg-color: #000;
  332.56 +@footer-color: #fff;
  332.57 +@page-bg-color: #ddd;
  332.58 +@mobile-bg-color: #255078;
  332.59 +@head-bg-color: #000;
  332.60 +@head-color: #fff;
  332.61 +@head-second-color: #0e0;
  332.62 +@head-link-color: #fff;
  332.63 +@main-bg-color: #fff;
  332.64 +@main-color: #000;
  332.65 +@main-second-color: #444;
  332.66 +@main-event-color: #070;
  332.67 +@main-negative-event-color: #a00;
  332.68 +@main-head-bg-color: #fff;
  332.69 +@main-head-color: #000;
  332.70 +@main-link-color: #227;
  332.71 +@main-seperator-color: #aaa;
  332.72 +@main-highlight-bg-color: #e7f0ff;
  332.73 +@main-supported-bg-color: #fa2;
  332.74 +@main-satisfied-bg-color: #282;
  332.75 +@sidebar-bg-color: #fff;
  332.76 +@sidebar-color: #000;
  332.77 +@sidebar-head-bg-color: @main-head-bg-color;
  332.78 +@sidebar-head-color: @main-head-color;
  332.79 +@sidebar-link-color: #227;
  332.80 +@sidebar-hr-color: #777;
  332.81 +@disabled-color: #777;
  332.82 +@admitted-color: #0a0;
  332.83 +@not-admitted-color: #a00;
  332.84 +
  332.85 +@delegation-bg-color: #fff;
  332.86 +@delegation-color: #000;
  332.87 +@delegation-active-border-color: #f80;
  332.88 +
  332.89 +@must-bg-color: #0c0;
  332.90 +@must-color: #fff;
  332.91 +@should-bg-color: #4a4;
  332.92 +@should-color: #fff;
  332.93 +@shouldnot-bg-color: #a44;
  332.94 +@shouldnot-color: #fff;
  332.95 +@mustnot-bg-color: #c00;
  332.96 +@mustnot-color: #fff;
  332.97 +
  332.98 +@implemented-bg-color: #0c0;
  332.99 +@implemented-color: #fff;
 332.100 +@notimplemented-bg-color: #c00;
 332.101 +@notimplemented-color: #fff;
 332.102 +
 332.103 +@font:  sans-serif;
 332.104 +@size-normal: 10pt;
 332.105 +@size-big: 12pt;
 332.106 +@line-height: 125%;
 332.107 +
 332.108 +
 332.109 +
 332.110 +@logo-font:             bold @size-normal e('/') 100% @font;
 332.111 +@instance-font:         normal @size-normal e('/') 100% @font;
 332.112 +@mobile-logo-font:      bold @size-big e('/') @line-height @font;
 332.113 +@mobile-instance-font:  normal @size-normal e('/') 100% @font;
 332.114 +
 332.115 +@title-font:            bold @size-big e('/') @line-height @font;
 332.116 +
 332.117 +@main-font:             normal @size-normal e('/') @line-height @font;
 332.118 +@event-font:            bold @size-normal e('/') @line-height @font;
 332.119 +
 332.120 +@tabs-font:             normal @size-normal e('/') @line-height @font;
 332.121 +@tabs-active-font:      bold @size-big e('/') @line-height @font;
 332.122 +
 332.123 +@filter-font:           normal @size-normal e('/') 150% @font;
 332.124 +@filter-active-font:    bold @size-normal e('/') 150% @font;
 332.125 +
 332.126 +@subfilter-font:        @filter-font;
 332.127 +@subfilter-active-font: @filter-active-font;
 332.128 +
 332.129 +@head1-font:            bold @size-big e('/') @line-height @font;
 332.130 +@head2-font:            normal @size-big e('/') @line-height @font;
 332.131 +@head3-font:            bold @size-normal e('/') @line-height @font;
 332.132 +
 332.133 +@btn-font:              bold @size-normal e('/') @line-height @font;
 332.134 +
 332.135 +@usertext-font:         normal @size-normal e('/') @line-height @font;
 332.136 +@usertext-italic-font:  italic @size-normal e('/') @line-height @font;
 332.137 +@usertext-bold-font:    normal @size-normal e('/') @line-height @font;
 332.138 +
 332.139 +
 332.140 +
 332.141 +@main-width: 70%;
 332.142 +
 332.143 +@pad: 9px;
 332.144 +@grid: 12pt;
 332.145 +
 332.146 +@paragraph-margin: 1.5ex;
 332.147 +
 332.148 +@border-radius: 2px;
 332.149 +@btn-border-radius: 5px;
 332.150 +
 332.151 +.list-style {
 332.152 +  list-style: disc;
 332.153 +  padding-left: 20px;
 332.154 +}
 332.155 +
 332.156 +@micro-avatar-size: 24px;
 332.157 +
 332.158 +/*
 332.159 + * basic font settings
 332.160 + */
 332.161 +
 332.162 +html {
 332.163 +  overflow-y: scroll;
 332.164 +}
 332.165 +
 332.166 +body {
 332.167 +  font: @main-font;
 332.168 +  background-color: @body-bg-color;
 332.169 +  //background-image: url( "back2.png" );
 332.170 +  color: @main-color;
 332.171 +  background-attachment: fixed;
 332.172 +}
 332.173 +
 332.174 +.page {
 332.175 +  background-image: url( "back50.png" );
 332.176 +  max-width: 1240px;
 332.177 +  border-radius: 0 0 @border-radius @border-radius;
 332.178 +  margin: 0 auto;
 332.179 +  margin-bottom: 40px;
 332.180 +}
 332.181 +
 332.182 +/*
 332.183 + * messages
 332.184 + */
 332.185 +
 332.186 +.slot_notice,
 332.187 +.slot_warning,
 332.188 +.slot_error {
 332.189 +  font: @head1-font;
 332.190 +  padding: @grid;
 332.191 +}
 332.192 +
 332.193 +.slot_motd {
 332.194 +  background-color: #ccc;
 332.195 +  padding: @grid;
 332.196 +}
 332.197 +
 332.198 +.slot_notice {
 332.199 +  background-color: #0c0;
 332.200 +  color: #fff;
 332.201 +}
 332.202 +
 332.203 +.slot_warning {
 332.204 +  background-color: #f80;
 332.205 +  color: #000;
 332.206 +}
 332.207 +
 332.208 +.slot_error {
 332.209 +  background-color: #c00;
 332.210 +  color: #fff;
 332.211 +}
 332.212 +
 332.213 +/*
 332.214 + * global styles
 332.215 + */
 332.216 +
 332.217 +/* headlines */
 332.218 +h1 {
 332.219 +  font: @head1-font;
 332.220 +  margin-bottom: 1ex;
 332.221 +}
 332.222 +
 332.223 +h1:last-child {
 332.224 +  margin-bottom: 0;
 332.225 +}
 332.226 +
 332.227 +h2 {
 332.228 +  font: @head2-font;
 332.229 +}
 332.230 +
 332.231 +h3 {
 332.232 +  font: @head3-font;
 332.233 +}
 332.234 +
 332.235 +h1:first-child,
 332.236 +h2:first-child,
 332.237 +h3:first-child {
 332.238 +  margin-top: 0;
 332.239 +}
 332.240 +
 332.241 +.right {
 332.242 +  float: right;
 332.243 +}
 332.244 +
 332.245 +.left {
 332.246 +  float: left;
 332.247 +  margin-right: @pad;
 332.248 +}
 332.249 +
 332.250 +/* paragraphs */
 332.251 +p {
 332.252 +  margin-bottom: @paragraph-margin;
 332.253 +}
 332.254 +
 332.255 +p:last-child {
 332.256 +  margin-bottom: 0;
 332.257 +}
 332.258 +
 332.259 +/* lists */
 332.260 +ul.ul {
 332.261 +  margin-left: @pad;
 332.262 +  margin-bottom: @paragraph-margin;
 332.263 +  .list-style;
 332.264 +  li {
 332.265 +    margin: @pad/3 0;
 332.266 +  }
 332.267 +
 332.268 +  li:last-child {
 332.269 +    margin-bottom: 0;
 332.270 +  }
 332.271 +}
 332.272 +
 332.273 +ul.ul:last-child {
 332.274 +  margin-bottom: 0;
 332.275 +}
 332.276 +
 332.277 +
 332.278 +/* tables */
 332.279 +
 332.280 +table {
 332.281 +
 332.282 +  td {
 332.283 +  
 332.284 +    padding: 0.3ex 0.3em;
 332.285 +  
 332.286 +  }
 332.287 +
 332.288 +}
 332.289 +
 332.290 +/* links */
 332.291 +
 332.292 +a {
 332.293 +  color: @main-link-color;
 332.294 +}
 332.295 +  
 332.296 +a.disabled {
 332.297 +  color: @disabled-color;
 332.298 +  cursor: default;
 332.299 +}
 332.300 +
 332.301 +/* formulars */
 332.302 +form.inline {
 332.303 +  display: inline;
 332.304 +  div {
 332.305 +    display: inline;
 332.306 +  }
 332.307 +}
 332.308 +
 332.309 +img {
 332.310 +  vertical-align: middle;
 332.311 +}
 332.312 +
 332.313 +
 332.314 +.icon16 {
 332.315 +  width: 16px;
 332.316 +  height: 16px;
 332.317 +}
 332.318 +
 332.319 +.icon24 {
 332.320 +  width: 24px;
 332.321 +  height: 24px;
 332.322 +}
 332.323 +.icon32 {
 332.324 +  width: 32px;
 332.325 +  height: 32px;
 332.326 +}
 332.327 +.icon48 {
 332.328 +  width: 48px;
 332.329 +  height: 48px;
 332.330 +}
 332.331 +
 332.332 +
 332.333 +img.star {
 332.334 +  width: 24px;
 332.335 +  height: 24px;
 332.336 +}
 332.337 +  
 332.338 +/*
 332.339 + * Avatars
 332.340 + */
 332.341 +
 332.342 +.microAvatar {
 332.343 +  text-wrap: nowrap;
 332.344 +}
 332.345 +
 332.346 +.microAvatar img,
 332.347 +img.micro_avatar {
 332.348 +  vertical-align: middle;
 332.349 +  border-radius: 2px;
 332.350 +  width: @micro-avatar-size;
 332.351 +  height: @micro-avatar-size;
 332.352 +}
 332.353 +
 332.354 +img.micro_avatar.highlighted {
 332.355 +  margin: 0;
 332.356 +  border: 2px solid @delegation-active-border-color;
 332.357 +}
 332.358 +
 332.359 +
 332.360 +/*
 332.361 + * delegation info
 332.362 + */
 332.363 +
 332.364 +.vote_info,
 332.365 +.delegation_info {
 332.366 +  white-space: nowrap;
 332.367 +  float: right;
 332.368 +  text-decoration: none;
 332.369 +  img {
 332.370 +    vertical-align: middle;
 332.371 +  }
 332.372 +  margin: -2px;
 332.373 +}
 332.374 +
 332.375 +.delegation_info img {
 332.376 +  border-radius: @border-radius;
 332.377 +  margin: 2px;
 332.378 +}
 332.379 +
 332.380 +.delegation_info.suspended {
 332.381 +  opacity: 0.3;
 332.382 +}
 332.383 +
 332.384 +.slot_title .delegation_info.suspended {
 332.385 +  opacity: 1;
 332.386 +}
 332.387 +
 332.388 +/*
 332.389 + * generic attributes
 332.390 + */
 332.391 +
 332.392 +.hide {
 332.393 +  display: none;
 332.394 +}
 332.395 +.head_outer {
 332.396 +  background-color: @head-bg-color;
 332.397 +  color: @head-color;
 332.398 +  overflow: auto;
 332.399 +  margin: 0 auto;
 332.400 +  max-width: 1240px;
 332.401 +}
 332.402 +.head {
 332.403 +  padding: 0.3ex 0;
 332.404 +  margin: 0 @grid;
 332.405 +  a {
 332.406 +    color: @head-link-color;
 332.407 +  }
 332.408 +  
 332.409 +  /* 
 332.410 +  * the logo and instance name
 332.411 +  */
 332.412 +  .logo {
 332.413 +    display: block;
 332.414 +    padding: @pad 0;
 332.415 +    text-decoration: none;
 332.416 +    font: @logo-font;
 332.417 +      
 332.418 +    .liquid {
 332.419 +      color: @head-color;
 332.420 +    }
 332.421 +    
 332.422 +    .feedback {
 332.423 +      color: @head-second-color;
 332.424 +    }
 332.425 +    .instanceName {
 332.426 +      font: @instance-font;
 332.427 +      padding-top: @pad;
 332.428 +    }
 332.429 +  }
 332.430 +  .logo:hover {
 332.431 +    text-decoration: underline;
 332.432 +  }
 332.433 +    
 332.434 +
 332.435 +
 332.436 +  .notifications {
 332.437 +    margin-left: 0.6em;
 332.438 +    text-decoration: none;
 332.439 +  
 332.440 +    .count {
 332.441 +      background-color: #f00;
 332.442 +      color: #000;
 332.443 +      padding: 0.2ex 0.25em;
 332.444 +      border-radius: 1ex;
 332.445 +      vertical-align: top;
 332.446 +    }
 332.447 +    
 332.448 +    .icon {
 332.449 +      width: 24px;
 332.450 +      height: 24px;
 332.451 +    }
 332.452 +  }
 332.453 +  
 332.454 +  /*
 332.455 +  * navigation bar
 332.456 +  */
 332.457 +  .nav {
 332.458 +    float: right;
 332.459 +    padding-top: @pad - 3px;
 332.460 +    
 332.461 +    ul, > ul > li:first-child {
 332.462 +      display: inline;
 332.463 +    }
 332.464 +    
 332.465 +    input[name=q] {
 332.466 +      width: 12em;
 332.467 +      border-radius: @border-radius;
 332.468 +      padding: 2px;
 332.469 +      background-color: @head-bg-color;
 332.470 +      color: @head-color;
 332.471 +      border: 1px solid @body-bg-color;
 332.472 +      margin-right: 0.6em;
 332.473 +    }
 332.474 +    input[name=q]:focus {
 332.475 +      outline: 2px solid @body-bg-color;
 332.476 +    }
 332.477 +    
 332.478 +    #member_menu a span {
 332.479 +      margin-left: 5px;
 332.480 +    }
 332.481 +    
 332.482 +  }
 332.483 +
 332.484 +}
 332.485 +
 332.486 +/*
 332.487 + * title
 332.488 + */
 332.489 +.slot_title {
 332.490 +  
 332.491 +  padding-left: @grid;
 332.492 +  padding-right: @grid;
 332.493 +  font: @title-font;
 332.494 +  color: @body-color;
 332.495 +  padding-top: @grid;
 332.496 +
 332.497 +  a {
 332.498 +    color: @body-color;
 332.499 +    display: inline-block;
 332.500 +  }
 332.501 +  
 332.502 +  a.home {
 332.503 +    margin-right: 4px;
 332.504 +  }
 332.505 +  
 332.506 +  a.delegation_info {
 332.507 +    margin-right: 0;
 332.508 +  }
 332.509 +  
 332.510 +  .initiative,
 332.511 +  a .label {
 332.512 +    display: none;
 332.513 +  }
 332.514 +  
 332.515 +  .delegation_info {
 332.516 +    background-color: @main-bg-color;
 332.517 +    color: @main-color;
 332.518 +    border-radius: @border-radius;
 332.519 +    padding-right: 3px;
 332.520 +    margin-bottom: @grid;
 332.521 +    a {
 332.522 +      color: @main-color;
 332.523 +    }
 332.524 +  }
 332.525 +}
 332.526 + 
 332.527 +.content {
 332.528 +  clear: both;
 332.529 +  margin: 0 @grid;
 332.530 +  margin-top: @grid;
 332.531 +}
 332.532 + 
 332.533 +/*
 332.534 + * the sidebar
 332.535 + */
 332.536 +
 332.537 +.sidebar {
 332.538 +  float: right;
 332.539 +  width: 100% - @main-width;
 332.540 +}
 332.541 +
 332.542 +.sidebarSection {
 332.543 +  background-color: @sidebar-bg-color;
 332.544 +  border-radius: @border-radius;
 332.545 +  color: @sidebar-color;
 332.546 +  margin-bottom: @grid;
 332.547 +  padding: 0;
 332.548 +    
 332.549 +  .sidebarHead {
 332.550 +    padding: @pad @pad @pad / 2 @pad;
 332.551 +    background: @sidebar-head-bg-color;
 332.552 +    color: @sidebar-head-color;
 332.553 +    
 332.554 +    a {
 332.555 +      color: @sidebar-head-color;
 332.556 +    }
 332.557 +    min-height: 20px;
 332.558 +    
 332.559 +    .icon24 {
 332.560 +      margin-top: -@pad/2.5;
 332.561 +    }
 332.562 +  }
 332.563 +
 332.564 +  .sidebarRow {
 332.565 +    clear: right;
 332.566 +    display: block;
 332.567 +    border-top: 1px solid @main-seperator-color;
 332.568 +    padding: @pad/2 @pad;
 332.569 +    min-height: 20px;
 332.570 +  }
 332.571 +  .sidebarRow.highlighted {
 332.572 +    background-color: @main-highlight-bg-color;
 332.573 +  }
 332.574 +
 332.575 +  .sidebarRow.sidebarRowNarrow {
 332.576 +    padding: @pad / 4 @pad;
 332.577 +  }
 332.578 +
 332.579 +  .sidebarRow.moreLink {
 332.580 +    min-height: 0;
 332.581 +  }
 332.582 +
 332.583 +  h1, h1 a, 
 332.584 +  h2, h2 a,
 332.585 +  h3, h3 a {
 332.586 +    color: @sidebar-head-color;
 332.587 +  }
 332.588 +
 332.589 +  a {
 332.590 +    color: @sidebar-link-color;
 332.591 +  }
 332.592 +
 332.593 +  .areas {
 332.594 +    .whenfolded {
 332.595 +      display: none;
 332.596 +    }
 332.597 +  }
 332.598 +
 332.599 +  .areas.folded {
 332.600 +    .whenunfolded {
 332.601 +      display: none;
 332.602 +    }
 332.603 +    .whenfolded {
 332.604 +      display: block;
 332.605 +    }
 332.606 +    .disabled {
 332.607 +      display: none;
 332.608 +    }
 332.609 +  }
 332.610 +
 332.611 +  
 332.612 +  a.issue {
 332.613 +    font: @head1-font;
 332.614 +    color: @main-color;
 332.615 +  }
 332.616 +  
 332.617 +  ul.initiatives {
 332.618 +    li {
 332.619 +      padding: @pad/2 @pad;
 332.620 +      .bargraph {
 332.621 +        display: block;
 332.622 +      }
 332.623 +      .supporterCount {
 332.624 +        white-space: nowrap;
 332.625 +      }
 332.626 +      border-top: 1px solid @main-seperator-color;
 332.627 +    }
 332.628 +   .revoked .initiative_name {
 332.629 +      text-decoration: line-through;
 332.630 +    }
 332.631 +
 332.632 +    li.highlighted {
 332.633 +      background-color: @main-highlight-bg-color;
 332.634 +    }
 332.635 +    li.highlighted:last-child{
 332.636 +      border-radius: 0 0 @border-radius @border-radius;
 332.637 +    }
 332.638 +  }
 332.639 +
 332.640 +  .supporters {
 332.641 +    line-height: @micro-avatar-size * 1.2;
 332.642 +  }
 332.643 +
 332.644 +  .supportCount {
 332.645 +    color: #00c000;
 332.646 +    font: @head1-font;
 332.647 +    float: right;
 332.648 +  }
 332.649 +  
 332.650 +  .member_list {
 332.651 +    
 332.652 +    .member_thumb {
 332.653 +      white-space: nowrap;
 332.654 +      overflow: hidden;
 332.655 +      text-overflow: ellipsis;
 332.656 +    
 332.657 +      img.member_image {
 332.658 +        width: 24px;
 332.659 +        height: 24px;
 332.660 +        vertical-align: middle;
 332.661 +        margin-right: 0.2em;
 332.662 +      }
 332.663 +      
 332.664 +    }
 332.665 +    
 332.666 +    .member_thumb.in_delegation_chain {
 332.667 +      font-weight: bold;
 332.668 +    }
 332.669 +  }
 332.670 +  
 332.671 +  
 332.672 +  > div {
 332.673 +    position: relative;
 332.674 +  }
 332.675 +  
 332.676 +  > div:first-child {
 332.677 +    margin-top: 0;
 332.678 +    border-radius: @border-radius @border-radius 0 0;
 332.679 +  }
 332.680 +  
 332.681 +  > div:last-child {
 332.682 +    border-radius: 0 0 @border-radius @border-radius;
 332.683 +  }
 332.684 +  
 332.685 +  > div:last-child:first-child {
 332.686 +    border-radius: @border-radius;
 332.687 +  }
 332.688 +  
 332.689 +  
 332.690 +  a.unit {
 332.691 +    font: @head2-font;
 332.692 +  }
 332.693 +
 332.694 +  a.area {
 332.695 +    margin-left: 25px;
 332.696 +    display: block;
 332.697 +  }
 332.698 +  
 332.699 +  .star {
 332.700 +    float: left;
 332.701 +  }
 332.702 +  
 332.703 +  .delegation_info {
 332.704 +    margin-top: -@pad/2.5;
 332.705 +    margin-bottom: 1px;
 332.706 +  }
 332.707 +}
 332.708 +  
 332.709 +.admitted_info h1 {
 332.710 +  color: @admitted-color;
 332.711 +}
 332.712 +
 332.713 +.not_admitted_info, .revoked_info {
 332.714 +  h1 {
 332.715 +    color: @not-admitted-color;
 332.716 +  }
 332.717 +}
 332.718 +
 332.719 +.admitted_info, 
 332.720 +.not_admitted_info {
 332.721 +  
 332.722 +  .initiative_pie {
 332.723 +    float: right;
 332.724 +  }
 332.725 +
 332.726 +  table {
 332.727 +    tr {
 332.728 +      th {
 332.729 +        text-align: left;
 332.730 +      }
 332.731 +      td {
 332.732 +        text-align: right;
 332.733 +        padding: 0.3ex 0.4em;
 332.734 +      }
 332.735 +    }
 332.736 +  }
 332.737 +}
 332.738 +
 332.739 +
 332.740 +
 332.741 +
 332.742 +/*
 332.743 + * main area
 332.744 + */
 332.745 +
 332.746 +.main_outer {
 332.747 +  width: @main-width;
 332.748 +}
 332.749 + 
 332.750 + 
 332.751 +.main {
 332.752 +
 332.753 +  clear: left;
 332.754 +  margin-right: @grid;
 332.755 +  border-radius: @border-radius;
 332.756 +
 332.757 +  .section {
 332.758 +
 332.759 +    .sectionHead, .sectionRow {
 332.760 +      background-color: @main-bg-color;
 332.761 +      overflow: auto;
 332.762 +      padding: @pad;
 332.763 +    }
 332.764 +    
 332.765 +    .sectionHead {
 332.766 +      background-color: @main-head-bg-color;
 332.767 +      color: @main-head-color;
 332.768 +      margin-top: @grid;
 332.769 +      border-radius: @border-radius @border-radius 0 0;
 332.770 +    }
 332.771 +    
 332.772 +    .sectionHead:first-child {
 332.773 +      margin-top: 0;
 332.774 +    }
 332.775 +    
 332.776 +    .sectionHead:last-child {
 332.777 +      border-radius: @border-radius;
 332.778 +    }
 332.779 +
 332.780 +    
 332.781 +    .sectionRow {
 332.782 +      margin-top: 4px;
 332.783 +    }
 332.784 +
 332.785 +    .sectionRow:last-child {
 332.786 +      border-radius: 0 0 @border-radius @border-radius;
 332.787 +      margin-bottom: @grid;
 332.788 +    }
 332.789 +    
 332.790 +    
 332.791 +  }
 332.792 +  
 332.793 +  .ui_tabs_links {
 332.794 +  }
 332.795 +  
 332.796 +  > h1 {
 332.797 +    border-bottom: 1px solid @main-seperator-color;
 332.798 +    padding: @pad;
 332.799 +  }
 332.800 +  
 332.801 +  /*
 332.802 +   * tabs und filter
 332.803 +   */
 332.804 +
 332.805 +  .ui_filter {
 332.806 +    .ui_filter_head {
 332.807 +      background: @main-head-bg-color;
 332.808 +      color: @main-head-color;
 332.809 +      padding: 0 @pad @pad @pad;
 332.810 +      vertical-align: middle;
 332.811 +      a {
 332.812 +        white-space: nowrap;
 332.813 +        font: @filter-font;
 332.814 +        margin-right: 0.5em;
 332.815 +      }
 332.816 +      a.active {
 332.817 +        font: @filter-active-font;
 332.818 +        text-decoration: none;
 332.819 +        color: @main-head-color;
 332.820 +      }
 332.821 +      select {
 332.822 +        background: @main-bg-color;
 332.823 +        color: @main-second-color;
 332.824 +        font: @filter-font;
 332.825 +        border: none;
 332.826 +        padding: 0;
 332.827 +        margin: 0;
 332.828 +
 332.829 +        option {
 332.830 +          color: @main-color;
 332.831 +        }
 332.832 +        option:first-child,
 332.833 +        option[value="interest_direct"],
 332.834 +        option[value="interest_delegated"],
 332.835 +        option[value="support_direct"],
 332.836 +        option[value="support_delegated"],
 332.837 +        option[value="potential_support_direct"],
 332.838 +        option[value="potential_support_delegated"] {
 332.839 +          color: @main-second-color;
 332.840 +        }
 332.841 +      }
 332.842 +      select.active {
 332.843 +        color: @main-color;
 332.844 +      }
 332.845 +    }
 332.846 +    .ui_filter_head:first-child {
 332.847 +      border-radius: @border-radius @border-radius 0 0;
 332.848 +      padding-top: @pad;
 332.849 +    }
 332.850 +    .ui_filter_head.filter_filter {
 332.851 +      padding-top: @pad;
 332.852 +    }
 332.853 +
 332.854 +    .ui_filter_head.filter_mode {
 332.855 +      padding-top: @pad;
 332.856 +      margin-bottom: 0;
 332.857 +      padding-bottom: 0;
 332.858 +    }
 332.859 +    .ui_filter_head.subfilter  {
 332.860 +      a {
 332.861 +        font: @subfilter-font;
 332.862 +      }
 332.863 +      a.active {
 332.864 +        font: @subfilter-active-font;
 332.865 +      }
 332.866 +    }
 332.867 +  }
 332.868 +  
 332.869 +  .filter {
 332.870 +    float: right;
 332.871 +  }
 332.872 +
 332.873 +  .delegation_info.suspended {
 332.874 +    margin: 1ex -2px -2px -2px;
 332.875 +  }
 332.876 +
 332.877 +
 332.878 +  .issues {
 332.879 +    .state_info {
 332.880 +      font: @event-font;
 332.881 +      color: @main-event-color;
 332.882 +    }
 332.883 +    .state_info.negative {
 332.884 +      color: @main-negative-event-color;
 332.885 +    }
 332.886 +  }
 332.887 +
 332.888 +  ul.initiatives {
 332.889 +    li {
 332.890 +      margin-top: 1ex;
 332.891 +      
 332.892 +      .bargraph {
 332.893 +        float: left;
 332.894 +        margin-top: 5px;
 332.895 +        margin-right: 0.5em;
 332.896 +      }
 332.897 +    
 332.898 +      .initiative_name {
 332.899 +        display: block;
 332.900 +        margin-left: 110px;
 332.901 +      }
 332.902 +      
 332.903 +      .rank1 .initiative_name {
 332.904 +        margin-left: 0;
 332.905 +      }
 332.906 +
 332.907 +      .revoked .initiative_name {
 332.908 +        text-decoration: line-through;
 332.909 +      }
 332.910 +
 332.911 +    }
 332.912 +    
 332.913 +    li:first-child {
 332.914 +      margin-top: 0;
 332.915 +      clear: none;
 332.916 +    }
 332.917 +        
 332.918 +  }
 332.919 +  
 332.920 +  .events .event ul.initiatives li .initiative_name {
 332.921 +    margin-left: 0;
 332.922 +  }
 332.923 +    
 332.924 +  .member_photo {
 332.925 +    float: right;
 332.926 +  }
 332.927 +  
 332.928 +  .member_thumb.in_delegation_chain {
 332.929 +    font-weight: bold;
 332.930 +  }
 332.931 +
 332.932 +  
 332.933 +
 332.934 +  /*
 332.935 +   * initiative
 332.936 +   */
 332.937 +   
 332.938 +   
 332.939 +  .support {
 332.940 +    color: #aaa; 
 332.941 +    line-height: 80%;
 332.942 +    float: right; 
 332.943 +    width: 102px;
 332.944 +  }
 332.945 +
 332.946 +  .initiativeInfo {
 332.947 +    font-family: @main-font;
 332.948 +    line-height: @micro-avatar-size;
 332.949 +    overflow: auto;
 332.950 +
 332.951 +    .support {
 332.952 +      margin-top: 1ex;
 332.953 +      float: left;
 332.954 +      width: auto;
 332.955 +    }
 332.956 +    
 332.957 +    .mySupport {
 332.958 +      line-height: 125%;
 332.959 +      min-width: 12em;
 332.960 +      text-align: right;
 332.961 +    }
 332.962 +    
 332.963 +    .initiators {
 332.964 +      margin-top: 1.5ex;
 332.965 +      margin-bottom: -1ex;
 332.966 +      float: left;
 332.967 +    }
 332.968 +    
 332.969 +    .links {
 332.970 +      margin-top: 1.5ex;
 332.971 +      margin-bottom: -1ex;
 332.972 +      float: right;
 332.973 +      clear: right;
 332.974 +    }
 332.975 +    
 332.976 +    .initiator_links {
 332.977 +      clear: right;
 332.978 +    }
 332.979 +    
 332.980 +  }
 332.981 +  
 332.982 +  .issueInfo {
 332.983 +    .links {
 332.984 +      margin-top: 1.5ex;
 332.985 +      margin-bottom: -1ex;
 332.986 +      float: right;
 332.987 +      clear: both;
 332.988 +    }
 332.989 +  }
 332.990 +  
 332.991 +  .draft_updated_info {
 332.992 +    color: @main-event-color;
 332.993 +    
 332.994 +    .info {
 332.995 +      font: @head3-font;
 332.996 +    }
 332.997 +  }
 332.998 +  
 332.999 +  /* the draft */
332.1000 +  .draft {
332.1001 +    font: @usertext-font;
332.1002 +    
332.1003 +    ul {
332.1004 +      margin-left: 1em;
332.1005 +      margin-bottom: @paragraph-margin;
332.1006 +      list-style: square;
332.1007 +      padding-left: 1em;
332.1008 +    }
332.1009 +
332.1010 +    h1 {
332.1011 +      font: @usertext-italic-font;
332.1012 +      font-size: 125%;
332.1013 +      border-bottom: 1px solid @main-second-color;
332.1014 +      margin-bottom: 1ex;
332.1015 +    }
332.1016 +
332.1017 +    h2 {
332.1018 +      font: @usertext-bold-font;
332.1019 +      font-size: 125%;
332.1020 +    }
332.1021 +
332.1022 +    h3 {
332.1023 +      font: @usertext-font;
332.1024 +      font-size: 125%;
332.1025 +    }
332.1026 +
332.1027 +    h4 {
332.1028 +      font: @usertext-bold-font;
332.1029 +    }
332.1030 +    
332.1031 +    hr {
332.1032 +      border: none;
332.1033 +      border-top: 1px solid @main-color;
332.1034 +    }
332.1035 +    
332.1036 +    b, strong {
332.1037 +      font: @usertext-italic-font;
332.1038 +    }
332.1039 +    
332.1040 +    i, em {
332.1041 +      //font-style: italic;
332.1042 +      font: @usertext-bold-font;
332.1043 +    }
332.1044 +  }
332.1045 +  
332.1046 +  form, .form {
332.1047 +      margin: 0;
332.1048 +      padding: 0;
332.1049 +  
332.1050 +    .ui_field_label {
332.1051 +      display: inline-block;
332.1052 +      width: 25%;
332.1053 +      margin: 0;
332.1054 +      padding: 0;
332.1055 +      text-align: right;
332.1056 +      margin-bottom: @pad;
332.1057 +      padding-right: 0.5%;
332.1058 +      vertical-align: top;
332.1059 +      color: @main-second-color;
332.1060 +    }
332.1061 +    
332.1062 +    input[type=text],
332.1063 +    input[type=password],
332.1064 +    select,
332.1065 +    textarea {
332.1066 +      vertical-align: top;
332.1067 +      width: 73%;
332.1068 +      margin: 0;
332.1069 +      padding: 3px;
332.1070 +      border: 1px solid @main-second-color;
332.1071 +      font: @head3-font;
332.1072 +      margin-bottom: @pad;
332.1073 +    }
332.1074 +    
332.1075 +    input:focus {
332.1076 +      outline: 2px solid @body-bg-color;
332.1077 +    }
332.1078 +
332.1079 +
332.1080 +    
332.1081 +    .actions {
332.1082 +      margin-left: 26%;
332.1083 +    }
332.1084 +  
332.1085 +  }
332.1086 +  
332.1087 +  form.wide {
332.1088 +    input[type=text],
332.1089 +    input[type=password],
332.1090 +    select,
332.1091 +    textarea {
332.1092 +      width: 100%;
332.1093 +    }
332.1094 +
332.1095 +  }
332.1096 +  
332.1097 +}
332.1098 +
332.1099 +.issues, .events {
332.1100 +  
332.1101 +  .event {
332.1102 +  
332.1103 +    .initiative_pie {
332.1104 +      clear: right;
332.1105 +      float: right;
332.1106 +    }
332.1107 +  
332.1108 +    ul.initiatives {
332.1109 +  
332.1110 +      .initiative_info_left {
332.1111 +        display: inline;
332.1112 +        margin-right: 0.5em;
332.1113 +      }
332.1114 +    
332.1115 +      .initiative_info_right {
332.1116 +        float: right;
332.1117 +        
332.1118 +        .bargraph {
332.1119 +          float: right;
332.1120 +          margin-left: 0.5em;
332.1121 +        }
332.1122 +      }
332.1123 +      
332.1124 +      .result {
332.1125 +        color: @main-second-color;
332.1126 +        margin-top: 0.5ex;
332.1127 +      }
332.1128 +      
332.1129 +      h3 {
332.1130 +        margin-top: 1ex;
332.1131 +        margin-bottom: 0;
332.1132 +      }
332.1133 +    
332.1134 +      a.initiative {
332.1135 +        font: @head3-font;
332.1136 +      }
332.1137 +    }
332.1138 +  
332.1139 +    .event_info {
332.1140 +      font: @event-font;
332.1141 +      color: @main-event-color;
332.1142 +      margin-top: 0.66ex;
332.1143 +      margin-bottom: 1ex;
332.1144 +    }
332.1145 +    
332.1146 +    .event_info:last-child {
332.1147 +      margin-bottom: 0;
332.1148 +    }
332.1149 +
332.1150 +    .event_info.negative {
332.1151 +      color: @main-negative-event-color;
332.1152 +    }
332.1153 +
332.1154 +    .event_time {
332.1155 +      font: @main-font;
332.1156 +      color: @main-second-color;
332.1157 +    }
332.1158 +  }
332.1159 +  
332.1160 +  .event:hover {
332.1161 +    .event_time {
332.1162 +      visibility: visible;
332.1163 +    }
332.1164 +    ul.initiatives {
332.1165 +      div {
332.1166 +        visibility: visible;
332.1167 +      }
332.1168 +    }
332.1169 +  }
332.1170 +  .issue_context {
332.1171 +    line-height: 24px;
332.1172 +    margin-bottom: 0.66ex;
332.1173 +    .unit {
332.1174 +      background-color: #777;
332.1175 +      color: #fff;
332.1176 +      padding: 1px 3px;
332.1177 +      border-radius: @border-radius;
332.1178 +      text-decoration: none;
332.1179 +    }
332.1180 +    .area {
332.1181 +      background-color: #ddd;
332.1182 +      color: #000;
332.1183 +      padding: 1px 3px;
332.1184 +      border-radius: @border-radius;
332.1185 +      text-decoration: none;
332.1186 +    }
332.1187 +  }
332.1188 +  .issue_info {
332.1189 +    .issue {
332.1190 +      font: @head3-font;
332.1191 +      color: @main-color;
332.1192 +    }
332.1193 +  }
332.1194 +  img.star {
332.1195 +    vertical-align: middle;
332.1196 +    float: right;
332.1197 +    margin-left: 0.5em;
332.1198 +  }
332.1199 +  
332.1200 +  .draft_preview {
332.1201 +  }
332.1202 +  
332.1203 +  .event.suggestion {
332.1204 +  
332.1205 +    ul.initiatives li {
332.1206 +    
332.1207 +      margin-top: 0;
332.1208 +      margin-bottom: 1ex;
332.1209 +
332.1210 +      a {
332.1211 +    
332.1212 +        font: @main-font;
332.1213 +      }
332.1214 +      
332.1215 +    }
332.1216 +    
332.1217 +    .suggestion {
332.1218 +    
332.1219 +      font: @head3-font;
332.1220 +      overflow: hidden;
332.1221 +      text-overflow: ellipsis;
332.1222 +    }
332.1223 +    
332.1224 +  }
332.1225 +  
332.1226 +}
332.1227 +
332.1228 +.suggestions {
332.1229 +  
332.1230 +  .suggestion {
332.1231 +  
332.1232 +    .opinion {
332.1233 +      float: right;
332.1234 +      
332.1235 +      .must {
332.1236 +        background-color: @must-bg-color;
332.1237 +        color: @must-color
332.1238 +      }
332.1239 +      .should {
332.1240 +        background-color: @should-bg-color;
332.1241 +        color: @should-color
332.1242 +      }
332.1243 +      .shouldnot {
332.1244 +        background-color: @shouldnot-bg-color;
332.1245 +        color: @shouldnot-color
332.1246 +      }
332.1247 +      .mustnot {
332.1248 +        background-color: @mustnot-bg-color;
332.1249 +        color: @mustnot-color
332.1250 +      }
332.1251 +      .implemented {
332.1252 +        background-color: @implemented-bg-color;
332.1253 +        color: @implemented-color
332.1254 +      }
332.1255 +      .notimplemented {
332.1256 +        background-color: @notimplemented-bg-color;
332.1257 +        color: @notimplemented-color
332.1258 +      }
332.1259 +      
332.1260 +    }
332.1261 +  
332.1262 +    .suggestion-rating {
332.1263 +      float: right;
332.1264 +    }
332.1265 +    .suggestion-text {
332.1266 +      margin-top: @pad;
332.1267 +      font: @usertext-font;
332.1268 +      overflow: hidden;
332.1269 +      text-overflow: ellipsis;
332.1270 +      position: relative;
332.1271 +      z-index: 10;
332.1272 +    }
332.1273 +    
332.1274 +    .suggestion-more {
332.1275 +      display: none;
332.1276 +    }
332.1277 +    
332.1278 +    .suggestion-less {
332.1279 +      display: none;
332.1280 +    }
332.1281 +    
332.1282 +    .suggestionHead {
332.1283 +      overflow: hidden;
332.1284 +      text-overflow: ellipsis;
332.1285 +    }
332.1286 +      
332.1287 +    .rating {
332.1288 +      display: none;
332.1289 +        padding: @pad/2 0;
332.1290 +      .active-plus2 {
332.1291 +        background-color: @must-bg-color;;
332.1292 +        color: @must-color;;
332.1293 +      }
332.1294 +      .active-plus1 {
332.1295 +        background-color: @should-bg-color;
332.1296 +        color: @should-color;
332.1297 +      }
332.1298 +      .active-minus1 {
332.1299 +        background-color: @shouldnot-bg-color;
332.1300 +        color: @shouldnot-color;
332.1301 +      }
332.1302 +      .active-minus2 {
332.1303 +        background-color: @mustnot-bg-color;
332.1304 +        color: @mustnot-color;
332.1305 +      }
332.1306 +      .active-notfulfilled {
332.1307 +        background-color: #faa;
332.1308 +      }
332.1309 +      .active-fulfilled {
332.1310 +        background-color: #afa;
332.1311 +      }
332.1312 +    }
332.1313 +  }
332.1314 +  
332.1315 +  .suggestion.rateable {
332.1316 +    .suggestion-more {
332.1317 +      display: block;
332.1318 +    }
332.1319 +  }
332.1320 +
332.1321 +  .suggestion.rateable.unfolded {
332.1322 +    .rating {
332.1323 +      border-top: 3px solid @body-bg-color;
332.1324 +    }
332.1325 +  }
332.1326 +  
332.1327 +  .suggestion.folded {
332.1328 +    .suggestion-more {
332.1329 +      display: block;
332.1330 +      position: absolute;
332.1331 +      bottom: 0;
332.1332 +      left: 0;
332.1333 +      width: 100%;
332.1334 +      box-shadow: inset 0 -12ex 10ex -5ex #fff;
332.1335 +      padding-top: 5ex;
332.1336 +    }
332.1337 +  }
332.1338 +  
332.1339 +  .suggestion.unfolded {
332.1340 +    .suggestion-more {
332.1341 +      display: none;
332.1342 +    }
332.1343 +    .rating {
332.1344 +      display: block;
332.1345 +    }
332.1346 +    .suggestion-less {
332.1347 +      margin-top: 1ex;
332.1348 +      display: block;
332.1349 +    }
332.1350 +  }
332.1351 +  
332.1352 +  .suggestion.highlighted {
332.1353 +    background-color: @main-highlight-bg-color;
332.1354 +    
332.1355 +    .suggestion-more {
332.1356 +      box-shadow: inset 0 -12ex 10ex -5ex @main-highlight-bg-color;
332.1357 +    }
332.1358 +    
332.1359 +  }
332.1360 +
332.1361 +}
332.1362 +
332.1363 +li.raw {
332.1364 +  list-style: none;
332.1365 +  padding: 0;
332.1366 +  margin: 0 !important;
332.1367 +}
332.1368 +
332.1369 +
332.1370 +.satisfiedSupporterCount {
332.1371 +  color: #070;
332.1372 +}
332.1373 +.potentialSupporterCount {
332.1374 +  color: #960;
332.1375 +}
332.1376 +
332.1377 +.bargraph {
332.1378 +  display: inline-block;
332.1379 +  vertical-align: top;
332.1380 +  height: 9px;
332.1381 +  
332.1382 +  div {
332.1383 +    margin: 0;
332.1384 +    padding: 0;
332.1385 +    display: inline-block;
332.1386 +    height: 9px;
332.1387 +  }
332.1388 +  
332.1389 +}
332.1390 +
332.1391 +.diff {
332.1392 +  .diff_added {
332.1393 +    background-color: #cfc;
332.1394 +  }
332.1395 +
332.1396 +  .diff_removed {
332.1397 +    text-decoration: line-through;
332.1398 +    background-color: #fcc;
332.1399 +  }
332.1400 +}
332.1401 +
332.1402 +.btn, .ui_paginate_foot a {
332.1403 +  text-decoration: none;
332.1404 +  min-width: 2em;
332.1405 +  text-align: center;
332.1406 +  display: inline-block;
332.1407 +  border-radius: @btn-border-radius;
332.1408 +  border: none;
332.1409 +  font: @btn-font;
332.1410 +  background-color: #999;
332.1411 +  color: #fff !important;
332.1412 +  margin-bottom: 5px;
332.1413 +}
332.1414 +
332.1415 +.btn {
332.1416 +  padding: 1ex 1em;
332.1417 +}
332.1418 +
332.1419 +
332.1420 +
332.1421 +.ui_paginate_foot a {
332.1422 +  padding: 0.5ex 0.5em;
332.1423 +  background-color: #eee;
332.1424 +  color: 000 !important;
332.1425 +}
332.1426 +
332.1427 +.ui_paginate_foot a.active {
332.1428 +  background-color: #666;
332.1429 +  color: #fff !important;
332.1430 +}
332.1431 +
332.1432 +.btn-default {
332.1433 +  background-color: #47a;
332.1434 +  color: #fff !important;
332.1435 +}
332.1436 +
332.1437 +.btn:hover, .btn:focus, .ui_paginate_foot a:hover, .ui_paginate_foot a:focus {
332.1438 +  background-color: #0a0;
332.1439 +  color: #fff !important;
332.1440 +  cursor: pointer;
332.1441 +}
332.1442 +
332.1443 +.btn-dangerous:hover {
332.1444 +  background-color: #c00;
332.1445 +  color: #fff !important;
332.1446 +}
332.1447 +
332.1448 +.btn-link {
332.1449 +  font: @main-font;
332.1450 +  background-color: @main-bg-color;
332.1451 +  color: @main-link-color;
332.1452 +  border: none;
332.1453 +  padding: 0;
332.1454 +  margin: 0;
332.1455 +  text-decoration: underline;
332.1456 +  cursor: pointer;
332.1457 +}
332.1458 +
332.1459 +/*************************************************************************
332.1460 + * Voting
332.1461 + */
332.1462 +
332.1463 +.main .section #voting_form .sectionRow:last-child {
332.1464 +  border-radius: 0;
332.1465 +  margin-bottom: 0;
332.1466 +}
332.1467 +
332.1468 +#voting {
332.1469 +  background: #ddd;
332.1470 +  padding: @pad;
332.1471 +  margin-top: 4px;
332.1472 +  position: relative;
332.1473 +  margin-bottom: 2ex;
332.1474 +  
332.1475 +  .approval, 
332.1476 +  .abstention, 
332.1477 +  .disapproval {
332.1478 +    border: 2px black solid;
332.1479 +    margin-bottom: 2ex;
332.1480 +    padding: 1ex;
332.1481 +    padding-bottom: 2ex;
332.1482 +    border-radius: @border-radius;
332.1483 +  }
332.1484 +  
332.1485 +  .disapproval {
332.1486 +    margin-bottom: 2ex;
332.1487 +  }
332.1488 +
332.1489 +  .approval {
332.1490 +    background-color: #9f9;
332.1491 +  
332.1492 +    .movable {
332.1493 +      background-color: #dfd;
332.1494 +    }
332.1495 +  }
332.1496 +  
332.1497 +  .abstention {
332.1498 +    background-color: #ccc;
332.1499 +
332.1500 +    .movable {
332.1501 +      background-color: #f2f2f2;
332.1502 +    }
332.1503 +  }
332.1504 +  
332.1505 +  .disapproval {
332.1506 +    background-color: #f88;
332.1507 +  
332.1508 +    .movable {
332.1509 +      background-color: #fbb;
332.1510 +    }
332.1511 +  }
332.1512 +  
332.1513 +  .movable {
332.1514 +    position: relative;
332.1515 +    border: 1px black solid;
332.1516 +    margin-top: 1ex;
332.1517 +    padding: 0.5ex;
332.1518 +    border-radius: @border-radius;
332.1519 +  }
332.1520 +  
332.1521 +  .voting_form_active {
332.1522 +    .movable {
332.1523 +      cursor: pointer;
332.1524 +      vertical-align: middle;
332.1525 +      cursor: move;
332.1526 +    }
332.1527 +
332.1528 +    .clickable {
332.1529 +      cursor: auto;
332.1530 +    }
332.1531 +
332.1532 +    a.clickable {
332.1533 +      cursor: pointer;
332.1534 +    }
332.1535 +  }
332.1536 +}
332.1537 +
332.1538 +
332.1539 +/*
332.1540 + * footer
332.1541 + */
332.1542 +
332.1543 +.footer {
332.1544 +  text-align: center;
332.1545 +  color: @footer-color;
332.1546 +  background-color: @footer-bg-color;
332.1547 +  padding: @pad 0;
332.1548 +  border: 1px solid #000;
332.1549 +  border-top: none;
332.1550 +  
332.1551 +  a {
332.1552 +    color: @body-color;
332.1553 +  }
332.1554 +}
332.1555 +
332.1556 +
332.1557 +.ui_paginate_head {
332.1558 +  display: none;
332.1559 +}
332.1560 +
332.1561 +.ui_paginate_foot {
332.1562 +  line-height: 180%;
332.1563 +}
332.1564 +
332.1565 +
332.1566 +.swiper_tabs {
332.1567 +  display: none;
332.1568 +}
332.1569 +
332.1570 +#swiper_info {
332.1571 +  display: none;
332.1572 +}
332.1573 +
332.1574 +.nav .searchLink {
332.1575 +  display: none;
332.1576 +}
332.1577 +
332.1578 +
332.1579 +@media (max-width: 767px) {
332.1580 +
332.1581 +html {
332.1582 +
332.1583 +  body {
332.1584 +    margin: 0;
332.1585 +    background: @mobile-bg-color;
332.1586 +
332.1587 +    .head {
332.1588 +      margin: @grid/2;
332.1589 +      padding: 0;
332.1590 +      
332.1591 +      .logo {
332.1592 +        display: block;
332.1593 +        padding: 0;
332.1594 +        
332.1595 +        .liquid, .feedback {
332.1596 +          font: @mobile-logo-font;
332.1597 +        }
332.1598 +        
332.1599 +        .instanceName {
332.1600 +          font: @mobile-instance-font;
332.1601 +          display: block;
332.1602 +          margin-left: 0;
332.1603 +        }
332.1604 +      }
332.1605 +      .nav {
332.1606 +        padding: 0;
332.1607 +      }
332.1608 +    }
332.1609 +
332.1610 +    .initiativeInfo h1 {
332.1611 +      display: none;
332.1612 +    }
332.1613 +    
332.1614 +    .slot_title {
332.1615 +
332.1616 +      font: @head2-font;
332.1617 +      padding: 0;
332.1618 +      margin: 0 @grid/2;
332.1619 +
332.1620 +      .spacer {
332.1621 +        display: none;
332.1622 +      }
332.1623 +      
332.1624 +      .unit, .area, .issue, .initiative, .member {
332.1625 +        display: block;
332.1626 +        margin-right: 0;
332.1627 +        padding: 4px 0;
332.1628 +        border-radius: @border-radius;
332.1629 +        overflow: auto;
332.1630 +      }
332.1631 +      
332.1632 +      .unit:before, .area:before, .issue:before, .initiative:before, .member:before {
332.1633 +        content: "↳";
332.1634 +        position: relative;
332.1635 +        top: -2px;
332.1636 +      }
332.1637 +      
332.1638 +      .area {
332.1639 +        margin-left: 10px;
332.1640 +      }
332.1641 +      .issue {
332.1642 +        margin-left: 10px * 2;
332.1643 +      }
332.1644 +      .initiative {
332.1645 +        margin-left: 10px * 3;
332.1646 +      }
332.1647 +      
332.1648 +      a:last-child, .issue:last-child, .area:last-child, .unit:last-child, .initiative:last-child {
332.1649 +        margin-bottom: @grid/2;
332.1650 +      }
332.1651 +      
332.1652 +      .unit, .initiative, .issue, .area {
332.1653 +        a {
332.1654 +          margin-bottom: 0;
332.1655 +          display: inline;
332.1656 +        }
332.1657 +      }
332.1658 +      
332.1659 +      a.home {
332.1660 +        display: none;
332.1661 +      }
332.1662 +      
332.1663 +      .weight {
332.1664 +        float: right;
332.1665 +        margin: 0;
332.1666 +      }
332.1667 +
332.1668 +      .delegation_info {
332.1669 +        float: right;
332.1670 +        display: block;
332.1671 +        margin-top: -10px;
332.1672 +      }
332.1673 +      a .label {
332.1674 +        display: inline;
332.1675 +      }
332.1676 +      .star {
332.1677 +        float: right;
332.1678 +        margin-left: 0.5em;
332.1679 +        margin-top: -@pad/2;
332.1680 +        margin-bottom: -@pad/2;
332.1681 +      }
332.1682 +    }
332.1683 +    
332.1684 +    .slot_title > span > *:last-child {
332.1685 +      font: @head1-font;
332.1686 +    }
332.1687 +
332.1688 +        
332.1689 +    .page {
332.1690 +      background: none;
332.1691 +      margin: 0;
332.1692 +      box-shadow: none;
332.1693 +    }
332.1694 +    
332.1695 +    .nav #member_menu .text {
332.1696 +      display: none;
332.1697 +    }
332.1698 +    
332.1699 +    .nav form.search {
332.1700 +      display: none;
332.1701 +    }
332.1702 +
332.1703 +    .nav .notifications,
332.1704 +    .nav .searchLink,
332.1705 +    .nav #member_menu a {
332.1706 +      vertical-align: middle;
332.1707 +      display: inline-block;
332.1708 +      height: 48px;
332.1709 +      min-width: 35px;
332.1710 +      text-align: center;
332.1711 +      background-color: #000;
332.1712 +      border: 1px solid #777;
332.1713 +      border-radius: @border-radius;
332.1714 +      img {
332.1715 +        margin: 0;
332.1716 +        width: 48px;
332.1717 +        height: 48px;
332.1718 +      }
332.1719 +      margin: 0;
332.1720 +    }
332.1721 +    
332.1722 +    .nav .notifications {
332.1723 +      padding: 12px 2px;
332.1724 +      height: 24px;
332.1725 +    }
332.1726 +
332.1727 +    .nav #member_menu a :last-child {
332.1728 +      display: none;
332.1729 +    }
332.1730 +    
332.1731 +    .notifications span {
332.1732 +      margin-left: -5px;
332.1733 +    }
332.1734 +
332.1735 +    .swiper_tabs {
332.1736 +      clear: both;
332.1737 +      display: block;
332.1738 +      overflow: auto;
332.1739 +      margin: @grid/2;
332.1740 +
332.1741 +      div {
332.1742 +        display: block;
332.1743 +        float: left;
332.1744 +        width: 33.333%;
332.1745 +        
332.1746 +        a {
332.1747 +          padding: 8px 0;
332.1748 +          display: block;
332.1749 +          text-align: center;
332.1750 +          background-color: #eee;
332.1751 +        }
332.1752 +        
332.1753 +        a.active {
332.1754 +          background-color: #abe;
332.1755 +        }
332.1756 +      }
332.1757 +      div:first-child a {
332.1758 +        border-radius: @border-radius 0 0 @border-radius;
332.1759 +      }
332.1760 +
332.1761 +      div:last-child a {
332.1762 +        border-radius: 0 @border-radius @border-radius 0;
332.1763 +      }
332.1764 +    }
332.1765 +
332.1766 +    #swiper_info.active {
332.1767 +      display: block;
332.1768 +      font: @head3-font;
332.1769 +      z-index: 1;
332.1770 +      text-align: center;
332.1771 +      width: 100%;
332.1772 +      background-color: @mobile-bg-color;
332.1773 +      color: @body-color;
332.1774 +    }
332.1775 +    
332.1776 +    .sidebarSection {
332.1777 +      margin: 0 @grid/2 @grid/2 @grid/2;
332.1778 +    }
332.1779 +
332.1780 +    .main, .extra > .section {
332.1781 +      clear: none;
332.1782 +      float: none;
332.1783 +      width: auto;
332.1784 +      margin: 0 @grid/2 @grid/2 @grid/2;
332.1785 +      .section .sectionRow:last-child {
332.1786 +        margin-bottom: @grid/2;
332.1787 +      }
332.1788 +
332.1789 +    }
332.1790 +    
332.1791 +    .ui_filter_head.filter_mode {
332.1792 +      float: none !important;
332.1793 +      background: @main-bg-color !important;
332.1794 +      text-align: left !important;
332.1795 +      border-radius: @border-radius;
332.1796 +      margin-bottom: @grid/2 !important;
332.1797 +    }
332.1798 +    
332.1799 +    .member_photo {
332.1800 +      text-align: center;
332.1801 +      margin-bottom: 2ex;
332.1802 +      .member_image_photo {
332.1803 +        max-width: 600px;
332.1804 +      }
332.1805 +    }
332.1806 +
332.1807 +    #trace_content {
332.1808 +      margin: @grid/2 0;
332.1809 +      border-radius: 0;
332.1810 +    
332.1811 +      ul {
332.1812 +        li {
332.1813 +          .trace_head {
332.1814 +            padding: 6px 5px;
332.1815 +          }
332.1816 +        }
332.1817 +        ul {
332.1818 +          padding: 5px 2px;
332.1819 +        }
332.1820 +      }
332.1821 +    }
332.1822 +    
332.1823 +  }
332.1824 +} }
332.1825 +
332.1826 +.textCenter {
332.1827 +  text-align: center;
332.1828 +}
332.1829 +
332.1830 +a.initiative {
332.1831 +  text-decoration: none;
332.1832 +  border-bottom: 1px solid #66c;
332.1833 +}
332.1834 +
332.1835 +a.initiative:hover {
332.1836 +  border-bottom: 1px solid #007;
332.1837 +}
332.1838 +
332.1839 +
332.1840 +
332.1841 +#trace_content {
332.1842 +  margin: @grid;
332.1843 +  padding: @pad;
332.1844 +  border-radius: @border-radius;
332.1845 +  background-color: @main-bg-color;
332.1846 +
332.1847 +  #system_error {
332.1848 +    font-family: monospace;
332.1849 +  }
332.1850 +  
332.1851 +  ul {
332.1852 +    li {
332.1853 +      margin-top: 10px;
332.1854 +      .trace_head {
332.1855 +        padding: 3px 5px;
332.1856 +        border-radius: @border-radius @border-radius 0 0;
332.1857 +      }
332.1858 +      .trace_head:last-child {
332.1859 +        border-radius: @border-radius;
332.1860 +      }
332.1861 +      ul {
332.1862 +        border-radius: 0 0 @border-radius @border-radius;
332.1863 +      }
332.1864 +    }
332.1865 +    li:first-child {
332.1866 +      margin-top: 0;
332.1867 +    }
332.1868 +    ul {
332.1869 +      padding: 10px;
332.1870 +      }
332.1871 +  }
332.1872 +  
332.1873 +  .trace_config > ul {
332.1874 +    background-color: #eee;
332.1875 +    border: 1px solid #ccc;
332.1876 +  }
332.1877 +  .trace_config > .trace_head {
332.1878 +    background-color: #ccc;
332.1879 +    color: #000;
332.1880 +  }
332.1881 +  .trace_request > ul {
332.1882 +    background-color: #afa;
332.1883 +  }
332.1884 +  .trace_request > .trace_head {
332.1885 +    background-color: #0c0;
332.1886 +  }
332.1887 +  .trace_filter > ul {
332.1888 +    background-color: #ccf;
332.1889 +    border: 1px solid #00c;
332.1890 +    border-top: none;
332.1891 +  }
332.1892 +  .trace_filter > .trace_head {
332.1893 +    background-color: #00c;
332.1894 +    color: #fff;
332.1895 +  }
332.1896 +  .trace_view > ul {
332.1897 +    background-color: #cfc;
332.1898 +    border: 1px solid #0c0;
332.1899 +    border-top: none;
332.1900 +  }
332.1901 +  .trace_view > .trace_head {
332.1902 +    background-color: #0c0;
332.1903 +    color: #000;
332.1904 +  }
332.1905 +  .trace_action_neutral > ul {
332.1906 +    background-color: #ffa;
332.1907 +    border: 1px solid #fe0;
332.1908 +  }
332.1909 +  .trace_action_neutral > .trace_head {
332.1910 +    background-color: #fe0;
332.1911 +    color: #000;
332.1912 +  }
332.1913 +  .trace_sql {
332.1914 +    background-color: #fff;
332.1915 +    padding: 2px 4px;
332.1916 +    margin-top: 8px;
332.1917 +  }
332.1918 +  .trace_error {
332.1919 +    background-color: #faa;
332.1920 +    color: #000;
332.1921 +    font-weight: bold;
332.1922 +    border: 1px solid #c00;
332.1923 +  }
332.1924 +  .trace_exectime {
332.1925 +    background-color: #ccc;
332.1926 +    font-weight: bold;
332.1927 +    border-radius: @border-radius;
332.1928 +  }
332.1929 +  
332.1930 +  .time {
332.1931 +    float: right;
332.1932 +  }
332.1933 +  
332.1934 +  .total_duration {
332.1935 +    font-weight: bold;
332.1936 +  }
332.1937 +    
332.1938 +}
332.1939 \ No newline at end of file
   333.1 Binary file static/star.png has changed
   334.1 --- a/static/style.css	Thu Jul 10 01:02:43 2014 +0200
   334.2 +++ b/static/style.css	Thu Jul 10 01:19:48 2014 +0200
   334.3 @@ -139,6 +139,10 @@
   334.4    border-radius: 4px;
   334.5  }
   334.6  
   334.7 +.btn-default {
   334.8 +  
   334.9 +}
  334.10 +
  334.11  /*************************************************************************
  334.12   * Notices, warnings and errors
  334.13   */
  334.14 @@ -816,6 +820,11 @@
  334.15    margin-bottom: 0;
  334.16  }
  334.17  
  334.18 +.vertical .actions {
  334.19 +  margin-left: 33%;
  334.20 +}
  334.21 +
  334.22 +
  334.23  #voting_form input[type=submit],
  334.24  .login input[type=submit],
  334.25  .vertical input[type=submit] {
   335.1 --- a/utils/optparse.lua	Thu Jul 10 01:02:43 2014 +0200
   335.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   335.3 @@ -1,139 +0,0 @@
   335.4 --- Lua command line option parser.
   335.5 --- Interface based on Pythons optparse.
   335.6 --- http://docs.python.org/lib/module-optparse.html
   335.7 --- (c) 2008 David Manura, Licensed under the same terms as Lua (MIT license)
   335.8 ---
   335.9 --- To be used like this:                                                                  
  335.10 --- t={usage="<some usage message>", version="<version string>"}                           
  335.11 --- op=OptionParser(t)                                                                     
  335.12 --- op=add_option{"<opt>", action=<action>, dest=<dest>, help="<help message for this option>"}
  335.13 ---
  335.14 --- with :
  335.15 ---   <opt> the option string to be used (can be anything, if one letter opt, then should be -x val, more letters: -xy=val )
  335.16 ---   <action> one of
  335.17 ---   - store: store in options as key, val                                                  
  335.18 ---   - store_true: stores key, true                                                         
  335.19 ---   - store_false: stores key, false
  335.20 ---   <dest> is the key under which the option is saved
  335.21 ---                                      
  335.22 --- options,args = op.parse_args()
  335.23 ---
  335.24 --- now options is the table of options (key, val) and args is the table with non-option arguments.
  335.25 --- You can use op.fail(message) for failing and op.print_help() for printing the usage as you like.
  335.26 -
  335.27 ---module('utils.optparse')
  335.28 -
  335.29 -local function OptionParser(t)
  335.30 -  local usage = t.usage
  335.31 -  local version = t.version
  335.32 -  local commands = t.commands
  335.33 -
  335.34 -  local o = {}
  335.35 -  local option_descriptions = {}
  335.36 -  local option_of = {}
  335.37 -
  335.38 -  function o.fail(s) -- extension
  335.39 -    io.stderr:write(s .. '\n')
  335.40 -    os.exit(1)
  335.41 -  end
  335.42 -
  335.43 -  function o.add_option(optdesc)
  335.44 -    option_descriptions[#option_descriptions+1] = optdesc
  335.45 -    for _,v in pairs(optdesc) do
  335.46 -      option_of[v] = optdesc
  335.47 -    end
  335.48 -  end
  335.49 -  function o.parse_args()
  335.50 -    -- expand options (e.g. "--input=file" -> "--input", "file")
  335.51 -    local arg = {unpack(arg)}
  335.52 -    for i=#arg,1,-1 do local v = arg[i]
  335.53 -      local flag, val = v:match('^(%-%-%w+)=(.*)')
  335.54 -      if flag then
  335.55 -        arg[i] = flag
  335.56 -        table.insert(arg, i+1, val)
  335.57 -      end
  335.58 -    end
  335.59 -
  335.60 -    local options = {}
  335.61 -    for _,optdesc in ipairs(option_descriptions) do
  335.62 -      options[optdesc["dest"]] = optdesc.default
  335.63 -    end
  335.64 -    local args = {}
  335.65 -    local i = 1
  335.66 -    while i <= #arg do local v = arg[i]
  335.67 -      local optdesc = option_of[v]
  335.68 -      if optdesc then
  335.69 -        local action = optdesc.action
  335.70 -        local val
  335.71 -        if action == 'store' or action == nil then
  335.72 -          i = i + 1
  335.73 -          val = arg[i]
  335.74 -          if not val then o.fail('option requires an argument ' .. v) end
  335.75 -        elseif action == 'store_true' then
  335.76 -          val = true
  335.77 -        elseif action == 'store_false' then
  335.78 -          val = false
  335.79 -        end
  335.80 -        options[optdesc.dest] = val
  335.81 -      else
  335.82 -        if v:match('^%-') then o.fail('invalid option ' .. v) end
  335.83 -        args[#args+1] = v
  335.84 -      end
  335.85 -      i = i + 1
  335.86 -    end
  335.87 -    if options.help then
  335.88 -      o.print_help()
  335.89 -      os.exit()
  335.90 -    end
  335.91 -    if options.version then
  335.92 -      io.stdout:write(t.version .. "\n")
  335.93 -      os.exit()
  335.94 -    end
  335.95 -    return options, args
  335.96 -  end
  335.97 -
  335.98 -  local function flags_str(optdesc)
  335.99 -    local sflags = {}
 335.100 -    local action = optdesc.action
 335.101 -    for _,flag in ipairs(optdesc) do
 335.102 -      local sflagend
 335.103 -      if action == nil or action == 'store' then
 335.104 -        local metavar = optdesc.metavar or optdesc.dest:upper()
 335.105 -        sflagend = #flag == 2 and ' ' .. metavar
 335.106 -                              or  '=' .. metavar
 335.107 -      else
 335.108 -        sflagend = ''
 335.109 -      end
 335.110 -      sflags[#sflags+1] = flag .. sflagend
 335.111 -    end
 335.112 -    return table.concat(sflags, ', ')
 335.113 -  end
 335.114 -
 335.115 -  function o.print_help()
 335.116 -    io.stdout:write("Usage: " .. usage:gsub('%%prog', arg[0]) .. "\n")
 335.117 -    io.stdout:write("\n")
 335.118 -    io.stdout:write("Options:\n")
 335.119 -    for _,optdesc in ipairs(option_descriptions) do
 335.120 -      io.stdout:write("  " .. flags_str(optdesc) ..
 335.121 -                      "  " .. optdesc.help .. "\n")
 335.122 -    end
 335.123 -    if commands then
 335.124 -        io.stdout:write("\nCommands:\n")
 335.125 -        for _,command in ipairs(commands) do
 335.126 -              io.stdout:write("  " .. command[1] .. 
 335.127 -                              string.rep(" ", 30-#command[1]) ..
 335.128 -                              command[2] .. "\n")
 335.129 -        end
 335.130 -    end
 335.131 -
 335.132 -  end
 335.133 -  o.add_option{"--help", action="store_true", dest="help",
 335.134 -               help="show this help message and exit"}
 335.135 -  if t.version then
 335.136 -    o.add_option{"--version", action="store_true", dest="version",
 335.137 -                 help="output version info."}
 335.138 -  end
 335.139 -  return o
 335.140 -end
 335.141 -
 335.142 -return OptionParser
 335.143 \ No newline at end of file

Impressum / About Us